diff --git a/.github/workflows/detect-internal-config-changes.yml b/.github/workflows/detect-internal-config-changes.yml index d9ceb9b391..17a21ea6b9 100644 --- a/.github/workflows/detect-internal-config-changes.yml +++ b/.github/workflows/detect-internal-config-changes.yml @@ -11,14 +11,20 @@ jobs: steps: - name: Warn run: | - curl --include --verbose --fail \ - -H "Accept: application/json" \ - -H "Content-Type:application/json" \ - -H "Authorization: token ${GITHUB_TOKEN}" \ - --request POST \ - --data "{\"body\": \"**[WARNING]** Changes in \`interal/config\` may require you to change Helm charts. Please check.\"}" \ - ${API_URL} + PR_COMMENTS=`curl ${API_URL}?per_page=10000` + BODY=`echo -E $PR_COMMENTS | jq 'last(.[] | select(.user.login == "vdaas-ci") | select(.body | test("^\\\\*\\\\*\\\\[WARNING:INTCFG")) | .body)' -r` + + if [ "$BODY" = "null" ]; then + curl --include --verbose --fail \ + -H "Accept: application/json" \ + -H "Content-Type:application/json" \ + -H "Authorization: token ${GITHUB_TOKEN}" \ + --request POST \ + --data "{\"body\": \"**[WARNING:INTCFG]** Changes in \`interal/config\` may require you to change Helm charts. Please check.\"}" \ + ${API_URL} + fi env: GITHUB_TOKEN: ${{ secrets.DISPATCH_TOKEN }} API_URL: ${{ github.event.pull_request.comments_url }} PR_USER: ${{ github.event.pull_request.user.login }} + PR_NUM: ${{ github.event.issue.number }} diff --git a/charts/vald/templates/_helpers.tpl b/charts/vald/templates/_helpers.tpl index 8441630669..efd0bf2df0 100755 --- a/charts/vald/templates/_helpers.tpl +++ b/charts/vald/templates/_helpers.tpl @@ -444,7 +444,15 @@ tls: gRPC client configuration */}} {{- define "vald.grpc.client" -}} -addrs: {{ default .default.addrs .Values.addrs }} +{{- if .Values.addrs }} +addrs: + {{- toYaml .Values.addrs | nindent 2 }} +{{- else if .default.addrs }} +addrs: + {{- toYaml .default.addrs | nindent 2 }} +{{- else }} +addrs: [] +{{- end }} health_check_duration: {{ default .default.health_check_duration .Values.health_check_duration | quote }} connection_pool: {{- if .Values.connection_pool }} @@ -549,10 +557,19 @@ collector: duration: {{ default .default.collector.duration .Values.collector.duration }} metrics: {{- if .Values.collector.metrics }} - enable_version_info: {{ default .default.collector.metrics.enable_version_info .Values.collector.metrics.enable_version_info }} - enable_memory: {{ default .default.collector.metrics.enable_memory .Values.collector.metrics.enable_memory }} - enable_goroutine: {{ default .default.collector.metrics.enable_goroutine .Values.collector.metrics.enable_goroutine }} - enable_cgo: {{ default .default.collector.metrics.enable_cgo .Values.collector.metrics.enable_cgo }} + enable_version_info: {{ default .default.collector.metrics.enable_version_info .Values.collector.metrics.enable_version_info }} + {{- if .Values.collector.metrics.version_info_labels }} + version_info_labels: + {{- toYaml .Values.collector.metrics.version_info_labels | nindent 6 }} + {{- else if .default.collector.metrics.version_info_labels }} + version_info_labels: + {{- toYaml .default.collector.metrics.version_info_labels | nindent 6 }} + {{- else }} + version_info_labels: [] + {{- end }} + enable_memory: {{ default .default.collector.metrics.enable_memory .Values.collector.metrics.enable_memory }} + enable_goroutine: {{ default .default.collector.metrics.enable_goroutine .Values.collector.metrics.enable_goroutine }} + enable_cgo: {{ default .default.collector.metrics.enable_cgo .Values.collector.metrics.enable_cgo }} {{- else }} {{- toYaml .default.collector.metrics | nindent 4 }} {{- end }} @@ -568,22 +585,94 @@ trace: {{- end }} prometheus: {{- if .Values.prometheus }} - enabled: {{ default .default.prometheus.enabled .Values.prometheus.enabled }} + enabled: {{ default .default.prometheus.enabled .Values.prometheus.enabled }} {{- else }} {{- toYaml .default.prometheus | nindent 2 }} {{- end }} jaeger: {{- if .Values.jaeger }} - enabled: {{ default .default.jaeger.enabled .Values.jaeger.enabled }} - collector_endpoint: {{ default .default.jaeger.collector_endpoint .Values.jaeger.collector_endpoint | quote }} - agent_endpoint: {{ default .default.jaeger.agent_endpoint .Values.jaeger.agent_endpoint | quote }} - username: {{ default .default.jaeger.username .Values.jaeger.username | quote }} - password: {{ default .default.jaeger.password .Values.jaeger.password | quote }} - service_name: {{ default .default.jaeger.service_name .Values.jaeger.service_name | quote }} - buffer_max_count: {{ default .default.jaeger.buffer_max_count .Values.jaeger.buffer_max_count }} + enabled: {{ default .default.jaeger.enabled .Values.jaeger.enabled }} + collector_endpoint: {{ default .default.jaeger.collector_endpoint .Values.jaeger.collector_endpoint | quote }} + agent_endpoint: {{ default .default.jaeger.agent_endpoint .Values.jaeger.agent_endpoint | quote }} + username: {{ default .default.jaeger.username .Values.jaeger.username | quote }} + password: {{ default .default.jaeger.password .Values.jaeger.password | quote }} + service_name: {{ default .default.jaeger.service_name .Values.jaeger.service_name | quote }} + buffer_max_count: {{ default .default.jaeger.buffer_max_count .Values.jaeger.buffer_max_count }} {{- else }} {{- toYaml .default.jaeger | nindent 2 }} {{- end }} +stackdriver: + {{- if .Values.stackdriver }} + project_id: {{ default .default.stackdriver.project_id .Values.stackdriver.project_id | quote }} + client: + {{- if .Values.stackdriver.client }} + api_key: {{ default .default.stackdriver.client.api_key .Values.stackdriver.client.api_key | quote }} + {{- if .Values.stackdriver.client.audiences }} + audiences: + {{- toYaml .Values.stackdriver.client.audiences | nindent 6 }} + {{- else if .default.stackdriver.client.audiences }} + audiences: + {{- toYaml .default.stackdriver.client.audiences | nindent 6 }} + {{- else }} + audiences: [] + {{- end }} + credentials_file: {{ default .default.stackdriver.client.credentials_file .Values.stackdriver.client.credentials_file | quote }} + credentials_json: {{ default .default.stackdriver.client.credentials_json .Values.stackdriver.client.credentials_json | quote }} + endpoint: {{ default .default.stackdriver.client.endpoint .Values.stackdriver.client.endpoint | quote }} + quota_project: {{ default .default.stackdriver.client.quota_project .Values.stackdriver.client.quota_project | quote }} + request_reason: {{ default .default.stackdriver.client.request_reason .Values.stackdriver.client.request_reason | quote }} + {{- if .Values.stackdriver.client.scopes }} + scopes: + {{- toYaml .Values.stackdriver.client.scopes | nindent 6 }} + {{- else if .default.stackdriver.client.scopes }} + scopes: + {{- toYaml .default.stackdriver.client.scopes | nindent 6 }} + {{- else }} + scopes: [] + {{- end }} + user_agent: {{ default .default.stackdriver.client.user_agent .Values.stackdriver.client.user_agent | quote }} + telemetry_enabled: {{ default .default.stackdriver.client.telemetry_enabled .Values.stackdriver.client.telemetry_enabled }} + authentication_enabled: {{ default .default.stackdriver.client.authentication_enabled .Values.stackdriver.client.authentication_enabled }} + {{- else }} + {{- toYaml .default.stackdriver.client | nindent 4 }} + {{- end }} + exporter: + {{- if .Values.stackdriver.exporter }} + monitoring_enabled: {{ default .default.stackdriver.exporter.monitoring_enabled .Values.stackdriver.exporter.monitoring_enabled }} + tracing_enabled: {{ default .default.stackdriver.exporter.tracing_enabled .Values.stackdriver.exporter.tracing_enabled }} + location: {{ default .default.stackdriver.exporter.location .Values.stackdriver.exporter.location | quote }} + bundle_delay_threshold: {{ default .default.stackdriver.exporter.bundle_delay_threshold .Values.stackdriver.exporter.bundle_delay_threshold | quote }} + bundle_count_threshold: {{ default .default.stackdriver.exporter.bundle_count_threshold .Values.stackdriver.exporter.bundle_count_threshold }} + trace_spans_buffer_max_bytes: {{ default .default.stackdriver.exporter.trace_spans_buffer_max_bytes .Values.stackdriver.exporter.trace_spans_buffer_max_bytes }} + metric_prefix: {{ default .default.stackdriver.exporter.metric_prefix .Values.stackdriver.exporter.metric_prefix | quote }} + skip_cmd: {{ default .default.stackdriver.exporter.skip_cmd .Values.stackdriver.exporter.skip_cmd }} + timeout: {{ default .default.stackdriver.exporter.timeout .Values.stackdriver.exporter.timeout | quote }} + reporting_interval: {{ default .default.stackdriver.exporter.reporting_interval .Values.stackdriver.exporter.reporting_interval | quote }} + number_of_workers: {{ default .default.stackdriver.exporter.number_of_workers .Values.stackdriver.exporter.number_of_workers }} + {{- else }} + {{- toYaml .default.stackdriver.exporter | nindent 4 }} + {{- end }} + profiler: + {{- if .Values.stackdriver.profiler }} + enabled: {{ default .default.stackdriver.profiler.enabled .Values.stackdriver.profiler.enabled }} + service: {{ default .default.stackdriver.profiler.service .Values.stackdriver.profiler.service | quote }} + service_version: {{ default .default.stackdriver.profiler.service_version .Values.stackdriver.profiler.service_version | quote }} + debug_logging: {{ default .default.stackdriver.profiler.debug_logging .Values.stackdriver.profiler.debug_logging }} + mutex_profiling: {{ default .default.stackdriver.profiler.mutex_profiling .Values.stackdriver.profiler.mutex_profiling }} + cpu_profiling: {{ default .default.stackdriver.profiler.cpu_profiling .Values.stackdriver.profiler.cpu_profiling }} + alloc_profiling: {{ default .default.stackdriver.profiler.alloc_profiling .Values.stackdriver.profiler.alloc_profiling }} + heap_profiling: {{ default .default.stackdriver.profiler.heap_profiling .Values.stackdriver.profiler.heap_profiling }} + goroutine_profiling: {{ default .default.stackdriver.profiler.goroutine_profiling .Values.stackdriver.profiler.goroutine_profiling }} + alloc_force_gc: {{ default .default.stackdriver.profiler.alloc_force_gc .Values.stackdriver.profiler.alloc_force_gc }} + api_addr: {{ default .default.stackdriver.profiler.api_addr .Values.stackdriver.profiler.api_addr | quote }} + instance: {{ default .default.stackdriver.profiler.instance .Values.stackdriver.profiler.instance | quote }} + zone: {{ default .default.stackdriver.profiler.zone .Values.stackdriver.profiler.zone | quote }} + {{- else }} + {{- toYaml .default.stackdriver.profiler | nindent 4 }} + {{- end }} + {{- else }} + {{- toYaml .default.stackdriver | nindent 2 }} + {{- end }} {{- end -}} {{/* diff --git a/charts/vald/values.yaml b/charts/vald/values.yaml index 57a40f100a..8d24f8f383 100644 --- a/charts/vald/values.yaml +++ b/charts/vald/values.yaml @@ -568,6 +568,17 @@ defaults: # @schema {"name": "defaults.observability.collector.metrics.enable_version_info", "type": "boolean"} # defaults.observability.collector.metrics.enable_version_info -- version info metrics enabled enable_version_info: true + # @schema {"name": "defaults.observability.collector.metrics.version_info_labels", "type": "array", "items": {"type": "string", "enum": ["vald_version", "server_name", "git_commit", "build_time", "go_version", "go_os", "go_arch", "cgo_enabled", "ngt_version", "build_cpu_info_flags"]}} + # defaults.observability.collector.metrics.version_info_labels -- enabled label names of version info + version_info_labels: + - "vald_version" + - "server_name" + - "git_commit" + - "build_time" + - "go_version" + - "go_os" + - "go_arch" + - "ngt_version" # @schema {"name": "defaults.observability.collector.metrics.enable_memory", "type": "boolean"} # defaults.observability.collector.metrics.enable_memory -- memory metrics enabled enable_memory: true @@ -620,6 +631,124 @@ defaults: # @schema {"name": "defaults.observability.jaeger.buffer_max_count", "type": "integer"} # defaults.observability.jaeger.buffer_max_count -- Jaeger buffer max count buffer_max_count: 10 + # @schema {"name": "defaults.observability.stackdriver", "type": "object"} + stackdriver: + # @schema {"name": "defaults.observability.stackdriver.project_id", "type": "string"} + # defaults.observability.stackdriver.project_id -- project id for uploading the stats data + project_id: "" + # @schema {"name": "defaults.observability.stackdriver.client", "type": "object"} + client: + # @schema {"name": "defaults.observability.stackdriver.client.api_key", "type": "string"} + # defaults.observability.stackdriver.client.api_key -- API key to be used as the basis for authentication. + api_key: "" + # @schema {"name": "defaults.observability.stackdriver.client.audiences", "type": "array", "items": {"type": "string"}} + # defaults.observability.stackdriver.client.audiences -- to be used as the audience field ("aud") for the JWT token authentication. + audiences: [] + # @schema {"name": "defaults.observability.stackdriver.client.credentials_file", "type": "string"} + # defaults.observability.stackdriver.client.credentials_file -- service account or refresh token JSON credentials file. + credentials_file: "" + # @schema {"name": "defaults.observability.stackdriver.client.credentials_json", "type": "string"} + # defaults.observability.stackdriver.client.credentials_json -- service account or refresh token JSON credentials. + credentials_json: "" + # @schema {"name": "defaults.observability.stackdriver.client.endpoint", "type": "string"} + # defaults.observability.stackdriver.client.endpoint -- overrides the default endpoint to be used for a service. + endpoint: "" + # @schema {"name": "defaults.observability.stackdriver.client.quota_project", "type": "string"} + # defaults.observability.stackdriver.client.quota_project -- the project used for quota and billing purposes. + quota_project: "" + # @schema {"name": "defaults.observability.stackdriver.client.request_reason", "type": "string"} + # defaults.observability.stackdriver.client.request_reason -- a reason for making the request, which is intended to be recorded in audit logging. + request_reason: "" + # @schema {"name": "defaults.observability.stackdriver.client.scopes", "type": "array", "items": {"type": "string"}} + # defaults.observability.stackdriver.client.scopes -- overrides the default OAuth2 scopes to be used for a service. + scopes: [] + # @schema {"name": "defaults.observability.stackdriver.client.user_agent", "type": "string"} + # defaults.observability.stackdriver.client.user_agent -- sets the User-Agent. + user_agent: "" + # @schema {"name": "defaults.observability.stackdriver.client.telemetry_enabled", "type": "boolean"} + # defaults.observability.stackdriver.client.telemetry_enabled -- enables default telemetry settings on gRPC and HTTP clients. + telemetry_enabled: true + # @schema {"name": "defaults.observability.stackdriver.client.authentication_enabled", "type": "boolean"} + # defaults.observability.stackdriver.client.authentication_enabled -- enables authentication. + authentication_enabled: true + # @schema {"name": "defaults.observability.stackdriver.exporter", "type": "object"} + exporter: + # @schema {"name": "defaults.observability.stackdriver.exporter.monitoring_enabled", "type": "boolean"} + # defaults.observability.stackdriver.exporter.monitoring_enabled -- stackdriver monitoring enabled + monitoring_enabled: false + # @schema {"name": "defaults.observability.stackdriver.exporter.tracing_enabled", "type": "boolean"} + # defaults.observability.stackdriver.exporter.tracing_enabled -- stackdriver tracing enabled + tracing_enabled: false + # @schema {"name": "defaults.observability.stackdriver.exporter.location", "type": "string"} + # defaults.observability.stackdriver.exporter.location -- identifier of the GCP or AWS cloud region/zone the data is stored. + location: "" + # @schema {"name": "defaults.observability.stackdriver.exporter.bundle_delay_threshold", "type": "string"} + # defaults.observability.stackdriver.exporter.bundle_delay_threshold -- the max amount of time the exporter can wait before uploading data. + bundle_delay_threshold: "0" + # @schema {"name": "defaults.observability.stackdriver.exporter.bundle_count_threshold", "type": "integer"} + # defaults.observability.stackdriver.exporter.bundle_count_threshold -- how many view data events or trace spans can be buffered. + bundle_count_threshold: 0 + # @schema {"name": "defaults.observability.stackdriver.exporter.trace_spans_buffer_max_bytes", "type": "integer"} + # defaults.observability.stackdriver.exporter.trace_spans_buffer_max_bytes -- maximum size of spans that will be buffered. + trace_spans_buffer_max_bytes: 0 + # @schema {"name": "defaults.observability.stackdriver.exporter.metric_prefix", "type": "string"} + # defaults.observability.stackdriver.exporter.metric_prefix -- the prefix of a stackdriver metric names. + metric_prefix: "vald.vdaas.org" + # @schema {"name": "defaults.observability.stackdriver.exporter.skip_cmd", "type": "boolean"} + # defaults.observability.stackdriver.exporter.skip_cmd -- skip all the CreateMetricDescriptor calls + skip_cmd: false + # @schema {"name": "defaults.observability.stackdriver.exporter.timeout", "type": "string"} + # defaults.observability.stackdriver.exporter.timeout -- timeout for all API calls + timeout: "5s" + # @schema {"name": "defaults.observability.stackdriver.exporter.reporting_interval", "type": "string"} + # defaults.observability.stackdriver.exporter.reporting_interval -- interval between reporting metrics + reporting_interval: "1m" + # @schema {"name": "defaults.observability.stackdriver.exporter.number_of_workers", "type": "integer"} + # defaults.observability.stackdriver.exporter.number_of_workers -- number of workers + number_of_workers: 1 + # @schema {"name": "defaults.observability.stackdriver.profiler", "type": "object"} + profiler: + # @schema {"name": "defaults.observability.stackdriver.profiler.enabled", "type": "boolean"} + # defaults.observability.stackdriver.profiler.enabled -- stackdriver profiler enabled. + enabled: false + # @schema {"name": "defaults.observability.stackdriver.profiler.service", "type": "string"} + # defaults.observability.stackdriver.profiler.service -- the name of the service. + service: "" + # @schema {"name": "defaults.observability.stackdriver.profiler.service_version", "type": "string"} + # defaults.observability.stackdriver.profiler.service_version -- the version of the service. + service_version: "" + # @schema {"name": "defaults.observability.stackdriver.profiler.debug_logging", "type": "boolean"} + # defaults.observability.stackdriver.profiler.debug_logging -- enables detailed logging from profiler. + debug_logging: false + # @schema {"name": "defaults.observability.stackdriver.profiler.mutex_profiling", "type": "boolean"} + # defaults.observability.stackdriver.profiler.mutex_profiling -- enables mutex profiling. + mutex_profiling: true + # @schema {"name": "defaults.observability.stackdriver.profiler.cpu_profiling", "type": "boolean"} + # defaults.observability.stackdriver.profiler.cpu_profiling -- enables CPU profiling. + cpu_profiling: true + # @schema {"name": "defaults.observability.stackdriver.profiler.alloc_profiling", "type": "boolean"} + # defaults.observability.stackdriver.profiler.alloc_profiling -- enables allocation profiling. + alloc_profiling: true + # @schema {"name": "defaults.observability.stackdriver.profiler.heap_profiling", "type": "boolean"} + # defaults.observability.stackdriver.profiler.heap_profiling -- enables heap profiling. + heap_profiling: true + # @schema {"name": "defaults.observability.stackdriver.profiler.goroutine_profiling", "type": "boolean"} + # defaults.observability.stackdriver.profiler.goroutine_profiling -- enables goroutine profiling. + goroutine_profiling: true + # @schema {"name": "defaults.observability.stackdriver.profiler.alloc_force_gc", "type": "boolean"} + # defaults.observability.stackdriver.profiler.alloc_force_gc -- forces GC before the collection of each heap profile. + alloc_force_gc: false + # @schema {"name": "defaults.observability.stackdriver.profiler.api_addr", "type": "string"} + # defaults.observability.stackdriver.profiler.api_addr -- HTTP endpoint to use to connect to the profiler agent API. + api_addr: "" + # @schema {"name": "defaults.observability.stackdriver.profiler.instance", "type": "string"} + # defaults.observability.stackdriver.profiler.instance -- the name of Compute Engine instance. + # This is normally determined from the Compute Engine metadata server and doesn't need to be initialized. + instance: "" + # @schema {"name": "defaults.observability.stackdriver.profiler.zone", "type": "string"} + # defaults.observability.stackdriver.profiler.zone -- the zone of Compute Engine instance. + # This is normally determined from the Compute Engine metadata server and doesn't need to be initialized. + zone: "" # @schema {"name": "gateway", "type": "object"} gateway: @@ -822,6 +951,9 @@ gateway: observability: jaeger: service_name: vald-gateway + stackdriver: + profiler: + service: vald-gateway # @schema {"name": "gateway.filter", "type": "object"} filter: # @schema {"name": "gateway.filter.egress", "type": "array", "items": {"type": "string"}} @@ -1076,6 +1208,9 @@ agent: observability: jaeger: service_name: vald-agent-ngt + stackdriver: + profiler: + service: vald-agent-ngt # @schema {"name": "agent.resources", "alias": "resources"} # agent.resources -- compute resources. # recommended setting of memory requests = cluster memory * 0.4 / number of agent pods @@ -1223,6 +1358,9 @@ agent: observability: jaeger: service_name: vald-agent-sidecar + stackdriver: + profiler: + service: vald-agent-sidecar # @schema {"name": "agent.sidecar.resources", "alias": "resources"} # agent.sidecar.resources -- compute resources. resources: @@ -1571,6 +1709,9 @@ discoverer: observability: jaeger: service_name: vald-discoverer + stackdriver: + profiler: + service: vald-discoverer # @schema {"name": "discoverer.resources", "alias": "resources"} # discoverer.resources -- compute resources resources: @@ -1771,6 +1912,9 @@ compressor: observability: jaeger: service_name: vald-manager-compressor + stackdriver: + profiler: + service: vald-manager-compressor # @schema {"name": "compressor.resources", "alias": "resources"} # compressor.resources -- compute resources resources: @@ -2016,6 +2160,9 @@ backupManager: observability: jaeger: service_name: vald-manager-backup + stackdriver: + profiler: + service: vald-manager-backup # @schema {"name": "backupManager.resources", "alias": "resources"} # backupManager.resources -- compute resources resources: @@ -2415,6 +2562,9 @@ indexManager: observability: jaeger: service_name: vald-manager-index + stackdriver: + profiler: + service: vald-manager-index # @schema {"name": "indexManager.resources", "alias": "resources"} # indexManager.resources -- compute resources resources: @@ -2659,6 +2809,9 @@ meta: observability: jaeger: service_name: vald-meta + stackdriver: + profiler: + service: vald-meta # @schema {"name": "meta.resources", "alias": "resources"} # meta.resources -- compute resources resources: diff --git a/go.mod b/go.mod index 8fe031b291..2ef09dfdcc 100755 --- a/go.mod +++ b/go.mod @@ -25,10 +25,12 @@ replace ( ) require ( + cloud.google.com/go v0.58.0 code.cloudfoundry.org/bytefmt v0.0.0-20190710193110-1eb035ffe2b6 contrib.go.opencensus.io/exporter/jaeger v0.2.0 - contrib.go.opencensus.io/exporter/prometheus v0.1.0 - github.com/aws/aws-sdk-go v1.31.4 + contrib.go.opencensus.io/exporter/prometheus v0.2.0 + contrib.go.opencensus.io/exporter/stackdriver v0.13.1 + github.com/aws/aws-sdk-go v1.32.2 github.com/cespare/xxhash/v2 v2.1.1 github.com/cockroachdb/errors v0.0.0-00010101000000-000000000000 github.com/danielvladco/go-proto-gql/pb v0.6.1 @@ -59,12 +61,14 @@ require ( go.uber.org/goleak v1.0.0 gocloud.dev v0.19.0 golang.org/x/mod v0.3.0 // indirect - golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 + golang.org/x/net v0.0.0-20200602114024-627f9648deb9 + golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 golang.org/x/tools v0.0.0-20200610052024-8d7dbee4c8ae // indirect gonum.org/v1/hdf5 v0.0.0-20200504100616-496fefe91614 gonum.org/v1/netlib v0.0.0-20200317120129-c5a04cffd98a // indirect gonum.org/v1/plot v0.7.0 - google.golang.org/genproto v0.0.0-20200521103424-e9a78aa275b7 + google.golang.org/api v0.26.0 + google.golang.org/genproto v0.0.0-20200615140333-fd031eab31e7 google.golang.org/grpc v1.29.1 gopkg.in/yaml.v2 v2.3.0 k8s.io/api v0.18.3 diff --git a/go.sum b/go.sum index 22374937e8..7d00c9df1d 100644 --- a/go.sum +++ b/go.sum @@ -4,20 +4,50 @@ cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMT cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= cloud.google.com/go v0.39.0/go.mod h1:rVLT6fkc8chs9sfPtFc1SBH6em7n+ZoXaG+87tDISts= 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.44.3 h1:0sMegbmn/8uTwpNkB0q9cLEpZ2W5a6kl+wtBQgPWBJQ= cloud.google.com/go v0.44.3/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/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= +cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= +cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= +cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= +cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= +cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= +cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= +cloud.google.com/go v0.58.0 h1:vtAfVc723K3xKq1BQydk/FyCldnaNFhGhpJxaJzgRMQ= +cloud.google.com/go v0.58.0/go.mod h1:W+9FnSUw6nhVwXlFcp1eL+krq5+HQUJeUogSeJZZiWg= +cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= +cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= +cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= +cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= +cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= +cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= +cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= +cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= +cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= +cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= +cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= +cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= +cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= +cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= +cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= code.cloudfoundry.org/bytefmt v0.0.0-20190710193110-1eb035ffe2b6 h1:tW+ztA4A9UT9xnco5wUjW1oNi35k22eUEn9tNpPYVwE= code.cloudfoundry.org/bytefmt v0.0.0-20190710193110-1eb035ffe2b6/go.mod h1:wN/zk7mhREp/oviagqUXY3EwuHhWyOvAdsn5Y4CzOrc= contrib.go.opencensus.io/exporter/aws v0.0.0-20181029163544-2befc13012d0/go.mod h1:uu1P0UCM/6RbsMrgPa98ll8ZcHM858i/AD06a9aLRCA= contrib.go.opencensus.io/exporter/jaeger v0.2.0 h1:nhTv/Ry3lGmqbJ/JGvCjWxBl5ozRfqo86Ngz59UAlfk= contrib.go.opencensus.io/exporter/jaeger v0.2.0/go.mod h1:ukdzwIYYHgZ7QYtwVFQUjiT28BJHiMhTERo32s6qVgM= contrib.go.opencensus.io/exporter/ocagent v0.5.0/go.mod h1:ImxhfLRpxoYiSq891pBrLVhN+qmP8BTVvdH2YLs7Gl0= -contrib.go.opencensus.io/exporter/prometheus v0.1.0 h1:SByaIoWwNgMdPSgl5sMqM2KDE5H/ukPWBRo314xiDvg= -contrib.go.opencensus.io/exporter/prometheus v0.1.0/go.mod h1:cGFniUXGZlKRjzOyuZJ6mgB+PgBcCIa79kEKR8YCW+A= +contrib.go.opencensus.io/exporter/prometheus v0.2.0 h1:9PUk0/8V0LGoPqVCrf8fQZJkFGBxudu8jOjQSMwoD6w= +contrib.go.opencensus.io/exporter/prometheus v0.2.0/go.mod h1:TYmVAyE8Tn1lyPcltF5IYYfWp2KHu7lQGIZnj8iZMys= contrib.go.opencensus.io/exporter/stackdriver v0.12.1/go.mod h1:iwB6wGarfphGGe/e5CWqyUk/cLzKnWsOKPVW3no6OTw= +contrib.go.opencensus.io/exporter/stackdriver v0.13.1 h1:RX9W6FelAqTVnBi/bRXJLXr9n18v4QkQwZYIdnNS51I= +contrib.go.opencensus.io/exporter/stackdriver v0.13.1/go.mod h1:z2tyTZtPmQ2HvWH4cOmVDgtY+1lomfKdbLnkJvZdc8c= contrib.go.opencensus.io/integrations/ocsql v0.1.4/go.mod h1:8DsSdjz3F+APR+0z0WkU1aRorQCFfRxvqjUUPMbF3fE= contrib.go.opencensus.io/resource v0.1.1/go.mod h1:F361eGI91LCmW1I/Saf+rX0+OFcigGlFvXwEGEnkRLA= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/Azure/azure-amqp-common-go/v2 v2.1.0/go.mod h1:R8rea+gJRuJR6QxTir/XuEd+YuKoUiazDC/N96FiDEU= github.com/Azure/azure-pipeline-go v0.2.1 h1:OLBdZJ3yvOn2MezlWvbrBMTEUQC72zAftRZOMdj5HYo= @@ -64,7 +94,11 @@ github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af h1:wVe6/Ea46ZMeNkQjjBW6xcqyQA/j5e0D6GytH95g0gQ= github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= +github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4 h1:Hs82Z41s6SdL1CELW+XaDYmOH4hkBN4/N9og/AsOv7E= +github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= github.com/asaskevich/govalidator v0.0.0-20180720115003-f9ffefc3facf/go.mod h1:lB+ZfQJz7igIIfQNfa7Ml4HSf2uFQQRzpGGRXenZAgY= @@ -72,12 +106,17 @@ github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a/go.mod h1:l github.com/aws/aws-sdk-go v1.15.27/go.mod h1:mFuSZ37Z9YOHbQEwBWztmVzqXrEkub65tZoCYDt7FT0= github.com/aws/aws-sdk-go v1.19.18/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.19.45/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= +github.com/aws/aws-sdk-go v1.23.20/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo= github.com/aws/aws-sdk-go v1.31.4 h1:YZ0uEYIWeanGuAomElHmRWMAbXVqrQixxgf2vtIjO6M= github.com/aws/aws-sdk-go v1.31.4/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= +github.com/aws/aws-sdk-go v1.32.2 h1:X5/tQ4cuqCCUZgeOh41WFh9Eq5xe32JzWe4PSE2i1ME= +github.com/aws/aws-sdk-go v1.32.2/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0= github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= +github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932 h1:mXoPYz/Ul5HYEDvkta6I8/rnYM5gSdSV2tJ6XbZuEtY= github.com/bitly/go-hostpool v0.0.0-20171023180738-a3a6125de932/go.mod h1:NOuUCSz6Q9T7+igc/hlvDOUdtWKryOrtFyIVABv/p7k= @@ -87,9 +126,14 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dR github.com/boltdb/bolt v1.3.1 h1:JQmyP4ZBrce+ZQu0dY660FMfatumYDLun9hBCUVIkF4= github.com/boltdb/bolt v1.3.1/go.mod h1:clJnj/oiGkjum5o1McbSZDSLxVThjynRyGBgiAx27Ps= github.com/census-instrumentation/opencensus-proto v0.2.0/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/cespare/xxhash/v2 v2.1.0/go.mod h1:dgIUBU3pDso/gPgZ1osOZ0iQf77oPR28Tjxl5dIMyVM= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= +github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= +github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa/go.mod h1:zn76sxSg3SzpJ0PPJaLDCu+Bu0Lg3sKTORVIj19EIF8= @@ -165,9 +209,14 @@ github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0 github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= github.com/go-ini/ini v1.25.4/go.mod h1:ByCAeIL28uOIIG0E3PJtZPDL8WnHpFKFOtgjp+3Ies8= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= +github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= +github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= github.com/go-logr/logr v0.1.0 h1:M1Tv3VzNlEHg6uyACnRdtrploV2P7wZqH8BoQMtz0cg= github.com/go-logr/logr v0.1.0/go.mod h1:ixOQHD9gLJUVQQ2ZOR7zLEifBX6tGkNJF4QyIY7sIas= github.com/go-logr/zapr v0.1.0 h1:h+WVe9j6HAA01niTJPA/kKH0i7e0rLZBCwauQFcRE54= @@ -242,14 +291,23 @@ github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4er github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= 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/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e h1:1r7pUrabqp18hOBcwBwiTsbnFeTZHV9eER/QT5JVZxY= +github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/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/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= +github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/protobuf v0.0.0-20161109072736-4bd1920723d7/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= 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/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= +github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= @@ -257,6 +315,8 @@ github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:W github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= github.com/golang/protobuf v1.4.1 h1:ZFgWrT+bLgsYPirOnRfKLYJLvssAegOj/hgyMFdJZe0= github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.0-20170215233205-553a64147049/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= @@ -269,6 +329,8 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/go-replayers/grpcreplay v0.1.0 h1:eNb1y9rZFmY4ax45uEEECSa8fsxGRU+8Bil52ASAwic= github.com/google/go-replayers/grpcreplay v0.1.0/go.mod h1:8Ig2Idjpr6gifRd6pNVggX6TC1Zw6Jx74AKp7QNH2QE= @@ -282,6 +344,12 @@ github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+incompatible h1:x github.com/google/martian v2.1.1-0.20190517191504-25dcb96d9e51+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/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= +github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c h1:lIC98ZUNah83ky7d9EXktLFe4H7Nwus59dTOLXr8xAI= +github.com/google/pprof v0.0.0-20200507031123-427632fa3b1c/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk= github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= @@ -320,6 +388,7 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= github.com/imdario/mergo v0.3.6 h1:xTNEAn+kxVO7dTZGu0CegyqKZmoWFI0rF8UxjlB2d28= github.com/imdario/mergo v0.3.6/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= @@ -343,6 +412,7 @@ github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/u github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= +github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= @@ -469,6 +539,8 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v0.9.2/go.mod h1:OsXs2jCmiKlQ1lTBmv21f2mNfw4xf/QclQDMrYNZzcM= github.com/prometheus/client_golang v1.0.0 h1:vrDKnkGzuGvhNAL56c7DBz29ZL+KxnoR0x7enabFceM= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= +github.com/prometheus/client_golang v1.2.1 h1:JnMpQc6ppsNgw9QPAGF6Dod479itz7lvlsMzzNayLOI= +github.com/prometheus/client_golang v1.2.1/go.mod h1:XMU6Z2MjaRKVu/dC1qupJI9SiNkDYzz3xecMgSW/F+U= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= @@ -477,10 +549,17 @@ github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6T github.com/prometheus/common v0.0.0-20181126121408-4724e9255275/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= github.com/prometheus/common v0.4.1 h1:K0MGApIoQvMw27RTdJkPbr3JZ7DNbtxQNyi5STVM6Kw= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= +github.com/prometheus/common v0.7.0 h1:L+1lyG48J1zAQXA3RBX/nG/B3gjlHq0zTt2tlbJLyCY= +github.com/prometheus/common v0.7.0/go.mod h1:DjGbpBbp5NYNiECxcL/VnbXCCaQpKd3tt26CguLLsqA= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.0-20181204211112-1dc9a6cbc91a/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2 h1:6LJUbpNm42llc4HRCuvApCSWB/WfhuNo9K98Q9sNGfs= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= +github.com/prometheus/procfs v0.0.5/go.mod h1:4A/X28fw3Fc593LaREMrKMqOKvUAntwMDaekg4FpcdQ= +github.com/prometheus/procfs v0.0.6 h1:0qbH+Yqu/cj1ViVLvEWCP6qMQ4efWUj6bQqOEA0V0U4= +github.com/prometheus/procfs v0.0.6/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/statsd_exporter v0.15.0 h1:UiwC1L5HkxEPeapXdm2Ye0u1vUJfTj7uwT5yydYpa1E= +github.com/prometheus/statsd_exporter v0.15.0/go.mod h1:Dv8HnkoLQkeEjkIE4/2ndAA7WL1zHKK7WMqFQqu72rw= github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= @@ -498,6 +577,7 @@ github.com/scylladb/gocqlx v1.5.0/go.mod h1:QarZcw5kpYh31MXfxiN2JWWvF1cgZbYqfTfX github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo= github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= +github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= @@ -555,6 +635,7 @@ github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmv github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/zeebo/xxh3 v0.0.0-20191227220208-65f423c10688 h1:C5YYdD+oJh6KoLMePMeA/+PPy2vgsEb6UBBMIy4ug+s= github.com/zeebo/xxh3 v0.0.0-20191227220208-65f423c10688/go.mod h1:e/zZObEJWtkq6f+bAzme0xQJSGI75oxoeqS+f2I7YVI= @@ -568,6 +649,7 @@ go.mongodb.org/mongo-driver v1.1.2/go.mod h1:u7ryQJ+DOzQmeO7zB6MHyr8jkEQvC8vH7qL go.opencensus.io v0.15.0/go.mod h1:UffZAU+4sDEINUGP/B7UfBBkq4fqLu9zXAX7ke6CHW0= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= +go.opencensus.io v0.22.1/go.mod h1:Ap50jQcDJrx6rB6VgeeFPtuPIf3wMRvRfrfYDO6+BmA= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.3 h1:8sGtKOrtQqkN1bp2AtX+misvLIlOmsEsNd+9NIcPEm8= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -598,22 +680,38 @@ golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/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-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= 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/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= +golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= +golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067 h1:KYGJGHOQy8oSi1fDlSpcZF0+juKwk/hEMv5SiwHogR0= 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/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f h1:J5lckAjkw6qYlOZNj90mLYNTEKDvWeuc1yieZ8qUzUE= golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= +golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= +golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= 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/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= @@ -639,19 +737,34 @@ golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190619014844-b5b0513f8c1b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190813141303-74dc4d7220e7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191004110552-13f9640d40b9/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20191126235420-ef20fe5d7933/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b h1:0mm1VjtFUOIlE1SbDlwjYaDxZVDP2S5ou6y0gSgXHu8= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9 h1:pNX+40auqi2JqRfOP1akLGtYcn15TUbkhwuCO3foqqM= +golang.org/x/net v0.0.0-20200602114024-627f9648deb9/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= 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-20190402181905-9f3314589c9a/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/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw= +golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/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= @@ -681,15 +794,34 @@ golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20190620070143-6f217b454f45/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190826190057-c7b8b68b1456/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191010194322-b09406accb47/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191113165036-4c7a9d0fe056/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191128015809-6d18c012aee9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5 h1:LfCXLvNmTYH9kEmVgqbnsWfruoXZIrh4YBgqVHtDvw0= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1 h1:ogLJMz+qpzav7lGMh10LMvAkM/fAoGlaiiHYiFYdm80= +golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/text v0.0.0-20160726164857-2910a502d2bf/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 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= @@ -698,6 +830,7 @@ golang.org/x/time v0.0.0-20180412165947-fbb02b2291d2/go.mod h1:tRJNPiyCQ0inRvYxb 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/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20181011042414-1f849cf54d09/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= @@ -721,15 +854,39 @@ golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgw golang.org/x/tools v0.0.0-20190617190820-da514acc4774/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/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191010075000-0337d82405ff/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-20191029041327-9cc4af7d6b2c/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191029190741-b9c20aec41a5/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191203134012-c197fd4bf371/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= +golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= +golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375 h1:SjQ2+AKWgZLc1xej6WSzL+Dfs5Uyd5xcZH1mGC411IA= golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= +golang.org/x/tools v0.0.0-20200606014950-c42cb6316fb6/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200610052024-8d7dbee4c8ae h1:Tzc/wv256GkBNOkrWbHBeV3T08mrVevgo/q5KSGltr0= golang.org/x/tools v0.0.0-20200610052024-8d7dbee4c8ae/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -758,11 +915,29 @@ google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E 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.10.0 h1:7tmAxx3oKE98VMZ+SBZzvYYWRQ9HODBxmC8mXUsraSQ= +google.golang.org/api v0.10.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= +google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= +google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= +google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= +google.golang.org/api v0.26.0 h1:VJZ8h6E8ip82FRpQl848c5vAadxlTXrUh8RzQzSRm08= +google.golang.org/api v0.26.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= 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.2 h1:j8RI1yW0SkI+paT6uGwMlrMI/6zwYA6/CFil8rxOzGI= +google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= +google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= +google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= +google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= 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= @@ -774,8 +949,29 @@ google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dT google.golang.org/genproto v0.0.0-20190620144150-6af8c5fc6601/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= 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/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= +google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= +google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= +google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= google.golang.org/genproto v0.0.0-20200521103424-e9a78aa275b7 h1:JUs1uIDQ46c7iI0QuMPzAHqXaSmqKF0f9freFMk2ivs= google.golang.org/genproto v0.0.0-20200521103424-e9a78aa275b7/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= +google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/genproto v0.0.0-20200608115520-7c474a2e3482/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= +google.golang.org/genproto v0.0.0-20200615140333-fd031eab31e7 h1:1N7l1PuXZwEK7OhHdmKQROOM75PnUjABGwvVRbLBgFk= +google.golang.org/genproto v0.0.0-20200615140333-fd031eab31e7/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= @@ -786,6 +982,8 @@ google.golang.org/grpc v1.23.1/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyac google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= google.golang.org/grpc v1.29.1 h1:EC2SB8S04d2r73uptxphDSUG+kTKVgjRPF+N3xpxRB4= google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= @@ -795,6 +993,11 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0 h1:cJv5/xdbk1NnMPR1VP9+HU6gupuG9MLBoH1r6RHZ2MY= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.24.0 h1:UhZDfRO8JRQru4/+LlLE0BRKGF8L+PICnvYZmx/fEGA= +google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= +gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -830,6 +1033,8 @@ honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWh 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= +honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= +honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= k8s.io/api v0.18.2 h1:wG5g5ZmSVgm5B+eHMIbI9EGATS2L8Z72rda19RIEgY8= k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78= k8s.io/apiextensions-apiserver v0.18.2 h1:I4v3/jAuQC+89L3Z7dDgAiN4EOjN6sbm6iBqQwHTah8= @@ -864,6 +1069,8 @@ pack.ag/amqp v0.11.2/go.mod h1:4/cbmt4EJXSKlG6LCfWHoqmN0uFdy5i/+YFz+fTfhV4= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/pdf v0.1.1 h1:k1MczvYDUvJBe93bYd7wrZLLUEcLZAuF824/I4e5Xr4= rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= +rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= +rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= sigs.k8s.io/controller-runtime v0.6.0 h1:Fzna3DY7c4BIP6KwfSlrfnj20DJ+SeMBK8HSFvOk9NM= sigs.k8s.io/controller-runtime v0.6.0/go.mod h1:CpYf5pdNY/B352A1TFLAS2JVSlnGQ5O2cftPHndTroo= diff --git a/internal/config/observability.go b/internal/config/observability.go index 90f080f36a..9b0671970d 100644 --- a/internal/config/observability.go +++ b/internal/config/observability.go @@ -18,11 +18,12 @@ package config type Observability struct { - Enabled bool `json:"enabled" yaml:"enabled"` - Collector *Collector `json:"collector" yaml:"collector"` - Trace *Trace `json:"trace" yaml:"trace"` - Prometheus *Prometheus `json:"prometheus" yaml:"prometheus"` - Jaeger *Jaeger `json:"jaeger" yaml:"jaeger"` + Enabled bool `json:"enabled" yaml:"enabled"` + Collector *Collector `json:"collector" yaml:"collector"` + Trace *Trace `json:"trace" yaml:"trace"` + Prometheus *Prometheus `json:"prometheus" yaml:"prometheus"` + Jaeger *Jaeger `json:"jaeger" yaml:"jaeger"` + Stackdriver *Stackdriver `json:"stackdriver" yaml:"stackdriver"` } type Collector struct { @@ -36,10 +37,11 @@ type Trace struct { } type Metrics struct { - EnableVersionInfo bool `json:"enable_version_info" yaml:"enable_version_info"` - EnableMemory bool `json:"enable_memory" yaml:"enable_memory"` - EnableGoroutine bool `json:"enable_goroutine" yaml:"enable_goroutine"` - EnableCGO bool `json:"enable_cgo" yaml:"enable_cgo"` + EnableVersionInfo bool `json:"enable_version_info" yaml:"enable_version_info"` + VersionInfoLabels []string `json:"version_info_labels" yaml:"version_info_labels"` + EnableMemory bool `json:"enable_memory" yaml:"enable_memory"` + EnableGoroutine bool `json:"enable_goroutine" yaml:"enable_goroutine"` + EnableCGO bool `json:"enable_cgo" yaml:"enable_cgo"` } type Prometheus struct { @@ -62,11 +64,72 @@ type Jaeger struct { BufferMaxCount int `json:"buffer_max_count" yaml:"buffer_max_count"` } +type Stackdriver struct { + ProjectID string `json:"project_id" yaml:"project_id"` + + Client *StackdriverClient `json:"client" yaml:"client"` + + Exporter *StackdriverExporter `json:"exporter" yaml:"exporter"` + Profiler *StackdriverProfiler `json:"profiler" yaml:"profiler"` +} + +type StackdriverClient struct { + APIKey string `json:"api_key" yaml:"api_key"` + Audiences []string `json:"audiences" yaml:"audiences"` + CredentialsFile string `json:"credentials_file" yaml:"credentials_file"` + CredentialsJSON string `json:"credentials_json" yaml:"credentials_json"` + Endpoint string `json:"endpoint" yaml:"endpoint"` + QuotaProject string `json:"quota_project" yaml:"quota_project"` + RequestReason string `json:"request_reason" yaml:"request_reason"` + Scopes []string `json:"scopes" yaml:"scopes"` + UserAgent string `json:"user_agent" yaml:"user_agent"` + TelemetryEnabled bool `json:"telemetry_enabled" yaml:"telemetry_enabled"` + AuthenticationEnabled bool `json:"authentication_enabled" yaml:"authentication_enabled"` +} + +type StackdriverExporter struct { + MonitoringEnabled bool `json:"monitoring_enabled" yaml:"monitoring_enabled"` + TracingEnabled bool `json:"tracing_enabled" yaml:"tracing_enabled"` + + Location string `json:"location" yaml:"location"` + BundleDelayThreshold string `json:"bundle_delay_threshold" yaml:"bundle_delay_threshold"` + BundleCountThreshold int `json:"bundle_count_threshold" yaml:"bundle_count_threshold"` + TraceSpansBufferMaxBytes int `json:"trace_spans_buffer_max_bytes" yaml:"trace_spans_buffer_max_bytes"` + + MetricPrefix string `json:"metric_prefix" yaml:"metric_prefix"` + + SkipCMD bool `json:"skip_cmd" yaml:"skip_cmd"` + Timeout string `json:"timeout" yaml:"timeout"` + ReportingInterval string `json:"reporting_interval" yaml:"reporting_interval"` + NumberOfWorkers int `json:"number_of_workers" yaml:"number_of_workers"` +} + +type StackdriverProfiler struct { + Enabled bool `json:"enabled" yaml:"enabled"` + Service string `json:"service" yaml:"service"` + ServiceVersion string `json:"service_version" yaml:"service_version"` + DebugLogging bool `json:"debug_logging" yaml:"debug_logging"` + + MutexProfiling bool `json:"mutex_profiling" yaml:"mutex_profiling"` + CPUProfiling bool `json:"cpu_profiling" yaml:"cpu_profiling"` + AllocProfiling bool `json:"alloc_profiling" yaml:"alloc_profiling"` + HeapProfiling bool `json:"heap_profiling" yaml:"heap_profiling"` + GoroutineProfiling bool `json:"goroutine_profiling" yaml:"goroutine_profiling"` + + AllocForceGC bool `json:"alloc_force_gc" yaml:"alloc_force_gc"` + + APIAddr string `json:"api_addr" yaml:"api_addr"` + + Instance string `json:"instance" yaml:"instance"` + Zone string `json:"zone" yaml:"zone"` +} + func (o *Observability) Bind() *Observability { if o.Collector != nil { - o.Collector.Duration = GetActualValue(o.Collector.Duration) + o.Collector = o.Collector.Bind() } else { o.Collector = new(Collector) + o.Collector.Metrics = new(Metrics) } if o.Trace == nil { @@ -90,5 +153,66 @@ func (o *Observability) Bind() *Observability { o.Jaeger = new(Jaeger) } + if o.Stackdriver != nil { + o.Stackdriver = o.Stackdriver.Bind() + } else { + o.Stackdriver = new(Stackdriver) + o.Stackdriver.Client = new(StackdriverClient) + o.Stackdriver.Exporter = new(StackdriverExporter) + o.Stackdriver.Profiler = new(StackdriverProfiler) + } + return o } + +func (c *Collector) Bind() *Collector { + c.Duration = GetActualValue(c.Duration) + + if c.Metrics != nil { + c.Metrics.VersionInfoLabels = GetActualValues(c.Metrics.VersionInfoLabels) + } else { + c.Metrics = new(Metrics) + } + + return c +} + +func (sd *Stackdriver) Bind() *Stackdriver { + sd.ProjectID = GetActualValue(sd.ProjectID) + + if sd.Client != nil { + sd.Client.APIKey = GetActualValue(sd.Client.APIKey) + sd.Client.Audiences = GetActualValues(sd.Client.Audiences) + sd.Client.CredentialsFile = GetActualValue(sd.Client.CredentialsFile) + sd.Client.CredentialsJSON = GetActualValue(sd.Client.CredentialsJSON) + sd.Client.Endpoint = GetActualValue(sd.Client.Endpoint) + sd.Client.QuotaProject = GetActualValue(sd.Client.QuotaProject) + sd.Client.RequestReason = GetActualValue(sd.Client.RequestReason) + sd.Client.Scopes = GetActualValues(sd.Client.Scopes) + sd.Client.UserAgent = GetActualValue(sd.Client.UserAgent) + } else { + sd.Client = new(StackdriverClient) + } + + if sd.Exporter != nil { + sd.Exporter.Location = GetActualValue(sd.Exporter.Location) + sd.Exporter.BundleDelayThreshold = GetActualValue(sd.Exporter.BundleDelayThreshold) + sd.Exporter.MetricPrefix = GetActualValue(sd.Exporter.MetricPrefix) + sd.Exporter.Timeout = GetActualValue(sd.Exporter.Timeout) + sd.Exporter.ReportingInterval = GetActualValue(sd.Exporter.ReportingInterval) + } else { + sd.Exporter = new(StackdriverExporter) + } + + if sd.Profiler != nil { + sd.Profiler.Service = GetActualValue(sd.Profiler.Service) + sd.Profiler.ServiceVersion = GetActualValue(sd.Profiler.ServiceVersion) + sd.Profiler.APIAddr = GetActualValue(sd.Profiler.APIAddr) + sd.Profiler.Instance = GetActualValue(sd.Profiler.Instance) + sd.Profiler.Zone = GetActualValue(sd.Profiler.Zone) + } else { + sd.Profiler = new(StackdriverProfiler) + } + + return sd +} diff --git a/internal/config/observability_test.go b/internal/config/observability_test.go index 27258ba2ef..d109f9cc5e 100644 --- a/internal/config/observability_test.go +++ b/internal/config/observability_test.go @@ -22,6 +22,7 @@ import ( "testing" "github.com/vdaas/vald/internal/errors" + "go.uber.org/goleak" ) func TestObservability_Bind(t *testing.T) { @@ -112,3 +113,85 @@ func TestObservability_Bind(t *testing.T) { }) } } + +func TestStackdriver_Bind(t *testing.T) { + type fields struct { + ProjectID string + Exporter *StackdriverExporter + Profiler *StackdriverProfiler + } + type want struct { + want *Stackdriver + } + type test struct { + name string + fields fields + want want + checkFunc func(want, *Stackdriver) error + beforeFunc func() + afterFunc func() + } + defaultCheckFunc := func(w want, got *Stackdriver) error { + if !reflect.DeepEqual(got, w.want) { + return errors.Errorf("got = %v, want %v", got, w.want) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + fields: fields { + ProjectID: "", + Exporter: StackdriverExporter{}, + Profiler: StackdriverProfiler{}, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + fields: fields { + ProjectID: "", + Exporter: StackdriverExporter{}, + Profiler: StackdriverProfiler{}, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc() + } + if test.afterFunc != nil { + defer test.afterFunc() + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + sd := &Stackdriver{ + ProjectID: test.fields.ProjectID, + Exporter: test.fields.Exporter, + Profiler: test.fields.Profiler, + } + + got := sd.Bind() + if err := test.checkFunc(test.want, got); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} diff --git a/internal/observability/client/google/option.go b/internal/observability/client/google/option.go new file mode 100644 index 0000000000..4ec89161d4 --- /dev/null +++ b/internal/observability/client/google/option.go @@ -0,0 +1,119 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Package google provides a google API client options. +package google + +import ( + "google.golang.org/api/option" +) + +type Option = option.ClientOption + +// WithClientCertSource(s ClientCertSource) ClientOption +// WithCredentials(creds *google.Credentials) ClientOption +// WithGRPCConn(conn *grpc.ClientConn) ClientOption +// WithGRPCConnectionPool(size int) ClientOption +// WithGRPCDialOption(opt grpc.DialOption) ClientOption +// WithHTTPClient(client *http.Client) ClientOption +// WithTokenSource(s oauth2.TokenSource) ClientOption + +func WithAPIKey(apiKey string) Option { + if apiKey == "" { + return nil + } + return option.WithAPIKey(apiKey) +} + +func WithAudiences(audiences ...string) Option { + if len(audiences) == 0 { + return nil + } + + return option.WithAudiences(audiences...) +} + +func WithCredentialsFile(path string) Option { + if path == "" { + return nil + } + + return option.WithCredentialsFile(path) +} + +func WithEndpoint(endpoint string) Option { + if endpoint == "" { + return nil + } + + return option.WithEndpoint(endpoint) +} + +func WithQuotaProject(qp string) Option { + if qp == "" { + return nil + } + + return option.WithQuotaProject(qp) +} + +func WithRequestReason(rr string) Option { + if rr == "" { + return nil + } + + return option.WithRequestReason(rr) +} + +func WithScopes(scopes ...string) Option { + if len(scopes) == 0 { + return nil + } + + return option.WithScopes(scopes...) +} + +func WithUserAgent(ua string) Option { + if ua == "" { + return nil + } + + return option.WithUserAgent(ua) +} + +func WithCredentialsJSON(json string) Option { + if json != "" { + return option.WithCredentialsJSON([]byte(json)) + } + + return nil +} + +func WithTelemetry(enabled bool) Option { + if !enabled { + return option.WithTelemetryDisabled() + } + + return nil +} + +func WithAuthentication(enabled bool) Option { + if !enabled { + return option.WithoutAuthentication() + } + + return nil +} diff --git a/internal/observability/collector/collector_option.go b/internal/observability/collector/collector_option.go index 91a7605b6a..9549b45fa8 100644 --- a/internal/observability/collector/collector_option.go +++ b/internal/observability/collector/collector_option.go @@ -73,12 +73,12 @@ func WithMetrics(metrics ...metrics.Metric) CollectorOption { } } -func WithVersionInfo(enabled bool) CollectorOption { +func WithVersionInfo(enabled bool, labels ...string) CollectorOption { return func(c *collector) error { if !enabled { return nil } - versionInfo, err := version.New() + versionInfo, err := version.New(labels...) if err != nil { return err } diff --git a/internal/observability/exporter/exporter.go b/internal/observability/exporter/exporter.go new file mode 100644 index 0000000000..562223829d --- /dev/null +++ b/internal/observability/exporter/exporter.go @@ -0,0 +1,27 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Package exporter provides exporters. +package exporter + +import ( + "context" +) + +type Exporter interface { + Start(ctx context.Context) error + Stop(ctx context.Context) +} diff --git a/internal/observability/exporter/jaeger/jaeger.go b/internal/observability/exporter/jaeger/jaeger.go index 18943767f3..7978cfaa54 100644 --- a/internal/observability/exporter/jaeger/jaeger.go +++ b/internal/observability/exporter/jaeger/jaeger.go @@ -21,18 +21,17 @@ import ( "context" "contrib.go.opencensus.io/exporter/jaeger" + "github.com/vdaas/vald/internal/observability/exporter" "go.opencensus.io/trace" ) type jaegerOptions = jaeger.Options type Jaeger interface { - Start(ctx context.Context) error - Stop(ctx context.Context) - Exporter() *jaeger.Exporter + exporter.Exporter } -type exporter struct { +type exp struct { exporter *jaeger.Exporter options jaegerOptions } @@ -47,12 +46,12 @@ func New(opts ...JaegerOption) (j Jaeger, err error) { } } - return &exporter{ + return &exp{ options: *jo, }, nil } -func (e *exporter) Start(ctx context.Context) (err error) { +func (e *exp) Start(ctx context.Context) (err error) { e.exporter, err = jaeger.NewExporter(e.options) if err != nil { return err @@ -63,12 +62,8 @@ func (e *exporter) Start(ctx context.Context) (err error) { return nil } -func (e *exporter) Stop(ctx context.Context) { +func (e *exp) Stop(ctx context.Context) { if e.exporter != nil { e.exporter.Flush() } } - -func (e *exporter) Exporter() *jaeger.Exporter { - return e.exporter -} diff --git a/internal/observability/exporter/jaeger/jaeger_test.go b/internal/observability/exporter/jaeger/jaeger_test.go index 244ad0efa8..edacacd50f 100644 --- a/internal/observability/exporter/jaeger/jaeger_test.go +++ b/internal/observability/exporter/jaeger/jaeger_test.go @@ -273,81 +273,3 @@ func Test_exporter_Stop(t *testing.T) { }) } } - -func Test_exporter_Exporter(t *testing.T) { - type fields struct { - exporter *jaeger.Exporter - options jaegerOptions - } - type want struct { - want *jaeger.Exporter - } - type test struct { - name string - fields fields - want want - checkFunc func(want, *jaeger.Exporter) error - beforeFunc func() - afterFunc func() - } - defaultCheckFunc := func(w want, got *jaeger.Exporter) error { - if !reflect.DeepEqual(got, w.want) { - return errors.Errorf("got = %v, want %v", got, w.want) - } - return nil - } - tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - fields: fields { - exporter: nil, - options: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - fields: fields { - exporter: nil, - options: nil, - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ - } - - for _, test := range tests { - t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) - if test.beforeFunc != nil { - test.beforeFunc() - } - if test.afterFunc != nil { - defer test.afterFunc() - } - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - e := &exporter{ - exporter: test.fields.exporter, - options: test.fields.options, - } - - got := e.Exporter() - if err := test.checkFunc(test.want, got); err != nil { - tt.Errorf("error = %v", err) - } - - }) - } -} diff --git a/internal/observability/exporter/prometheus/prometheus.go b/internal/observability/exporter/prometheus/prometheus.go index 74309b383e..7e31f3a583 100644 --- a/internal/observability/exporter/prometheus/prometheus.go +++ b/internal/observability/exporter/prometheus/prometheus.go @@ -23,10 +23,11 @@ import ( "sync" "contrib.go.opencensus.io/exporter/prometheus" + "github.com/vdaas/vald/internal/observability/exporter" ) var ( - instance *exporter + instance *exp once sync.Once ) @@ -36,13 +37,11 @@ type prometheusOptions struct { } type Prometheus interface { - Start(ctx context.Context) error - Stop(ctx context.Context) - Exporter() *prometheus.Exporter + exporter.Exporter NewHTTPHandler() http.Handler } -type exporter struct { +type exp struct { exporter *prometheus.Exporter options prometheusOptions } @@ -63,7 +62,7 @@ func New(opts ...PrometheusOption) (Prometheus, error) { return nil, err } - e := exporter{ + e := exp{ exporter: ex, options: *po, } @@ -75,18 +74,14 @@ func New(opts ...PrometheusOption) (Prometheus, error) { return &e, nil } -func (e *exporter) Start(ctx context.Context) error { +func (e *exp) Start(ctx context.Context) error { return nil } -func (e *exporter) Stop(ctx context.Context) { +func (e *exp) Stop(ctx context.Context) { } -func (e *exporter) Exporter() *prometheus.Exporter { - return e.exporter -} - -func (e *exporter) NewHTTPHandler() http.Handler { +func (e *exp) NewHTTPHandler() http.Handler { mux := http.NewServeMux() mux.Handle(e.options.endpoint, e.exporter) return mux diff --git a/internal/observability/exporter/prometheus/prometheus_test.go b/internal/observability/exporter/prometheus/prometheus_test.go index 3d8c4aea48..b489fd9150 100644 --- a/internal/observability/exporter/prometheus/prometheus_test.go +++ b/internal/observability/exporter/prometheus/prometheus_test.go @@ -25,7 +25,6 @@ import ( "contrib.go.opencensus.io/exporter/prometheus" "github.com/vdaas/vald/internal/errors" - "go.uber.org/goleak" ) @@ -275,84 +274,6 @@ func Test_exporter_Stop(t *testing.T) { } } -func Test_exporter_Exporter(t *testing.T) { - type fields struct { - exporter *prometheus.Exporter - options prometheusOptions - } - type want struct { - want *prometheus.Exporter - } - type test struct { - name string - fields fields - want want - checkFunc func(want, *prometheus.Exporter) error - beforeFunc func() - afterFunc func() - } - defaultCheckFunc := func(w want, got *prometheus.Exporter) error { - if !reflect.DeepEqual(got, w.want) { - return errors.Errorf("got = %v, want %v", got, w.want) - } - return nil - } - tests := []test{ - // TODO test cases - /* - { - name: "test_case_1", - fields: fields { - exporter: nil, - options: prometheusOptions{}, - }, - want: want{}, - checkFunc: defaultCheckFunc, - }, - */ - - // TODO test cases - /* - func() test { - return test { - name: "test_case_2", - fields: fields { - exporter: nil, - options: prometheusOptions{}, - }, - want: want{}, - checkFunc: defaultCheckFunc, - } - }(), - */ - } - - for _, test := range tests { - t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) - if test.beforeFunc != nil { - test.beforeFunc() - } - if test.afterFunc != nil { - defer test.afterFunc() - } - if test.checkFunc == nil { - test.checkFunc = defaultCheckFunc - } - e := &exporter{ - exporter: test.fields.exporter, - options: test.fields.options, - } - - got := e.Exporter() - if err := test.checkFunc(test.want, got); err != nil { - tt.Errorf("error = %v", err) - } - - }) - } -} - func Test_exporter_NewHTTPHandler(t *testing.T) { type fields struct { exporter *prometheus.Exporter @@ -407,7 +328,7 @@ func Test_exporter_NewHTTPHandler(t *testing.T) { for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt) if test.beforeFunc != nil { test.beforeFunc() } @@ -476,7 +397,7 @@ func TestExporter(t *testing.T) { for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt) if test.beforeFunc != nil { test.beforeFunc() } diff --git a/internal/observability/exporter/stackdriver/stackdriver.go b/internal/observability/exporter/stackdriver/stackdriver.go new file mode 100644 index 0000000000..a8610e51a8 --- /dev/null +++ b/internal/observability/exporter/stackdriver/stackdriver.go @@ -0,0 +1,85 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Package stackdriver provides a stackdriver exporter. +package stackdriver + +import ( + "context" + + "contrib.go.opencensus.io/exporter/stackdriver" + "github.com/vdaas/vald/internal/observability/exporter" + "go.opencensus.io/trace" +) + +type Stackdriver interface { + exporter.Exporter +} + +type exp struct { + exporter *stackdriver.Exporter + + monitoringEnabled bool + tracingEnabled bool + + *stackdriver.Options +} + +func New(opts ...Option) (s Stackdriver, err error) { + e := new(exp) + e.Options = new(stackdriver.Options) + + for _, opt := range append(defaultOpts, opts...) { + err = opt(e) + if err != nil { + return nil, err + } + } + + return e, nil +} + +func (e *exp) Start(ctx context.Context) (err error) { + e.Options.Context = ctx + + e.exporter, err = stackdriver.NewExporter(*e.Options) + if err != nil { + return err + } + + if e.monitoringEnabled { + err = e.exporter.StartMetricsExporter() + if err != nil { + return err + } + } + + if e.tracingEnabled { + trace.RegisterExporter(e.exporter) + } + + return nil +} + +func (e *exp) Stop(ctx context.Context) { + if e.exporter != nil { + if e.monitoringEnabled { + e.exporter.StopMetricsExporter() + } + + e.exporter.Flush() + } +} diff --git a/internal/observability/exporter/stackdriver/stackdriver_option.go b/internal/observability/exporter/stackdriver/stackdriver_option.go new file mode 100644 index 0000000000..2c69058771 --- /dev/null +++ b/internal/observability/exporter/stackdriver/stackdriver_option.go @@ -0,0 +1,262 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Package stackdriver provides a stackdriver exporter. +package stackdriver + +import ( + "contrib.go.opencensus.io/exporter/stackdriver" + "contrib.go.opencensus.io/exporter/stackdriver/monitoredresource" + "github.com/vdaas/vald/internal/log" + "github.com/vdaas/vald/internal/observability/client/google" + "github.com/vdaas/vald/internal/observability/metrics" + "github.com/vdaas/vald/internal/timeutil" +) + +type Option func(e *exp) error + +var ( + defaultOpts = []Option{ + WithOnErrorFunc(func(err error) { + if err != nil { + log.Warnf("Error when uploading stats or spans to Stackdriver: %v", err) + } + }), + WithMonitoredResource(monitoredresource.Autodetect()), + WithMetricPrefix("vald.vdaas.org/"), + WithTimeout("5s"), + WithReportingInterval("0"), + WithNumberOfWorkers(1), + } +) + +func WithMonitoring(enabled bool) Option { + return func(e *exp) error { + e.monitoringEnabled = enabled + + return nil + } +} + +func WithTracing(enabled bool) Option { + return func(e *exp) error { + e.tracingEnabled = enabled + + return nil + } +} + +func WithProjectID(pid string) Option { + return func(e *exp) error { + if pid != "" { + e.ProjectID = pid + } + + return nil + } +} + +func WithLocation(loc string) Option { + return func(e *exp) error { + if loc != "" { + e.Location = loc + } + + return nil + } +} + +func WithOnErrorFunc(f func(error)) Option { + return func(e *exp) error { + if f != nil { + e.OnError = f + } + + return nil + } +} + +func WithMonitoringClientOptions(copts ...google.Option) Option { + return func(e *exp) error { + opts := make([]google.Option, 0, len(copts)) + for _, opt := range copts { + if opt != nil { + opts = append(opts, opt) + } + } + + if e.MonitoringClientOptions == nil { + e.MonitoringClientOptions = opts + return nil + } + + e.MonitoringClientOptions = append(e.MonitoringClientOptions, opts...) + + return nil + } +} + +func WithTraceClientOptions(copts ...google.Option) Option { + return func(e *exp) error { + opts := make([]google.Option, 0, len(copts)) + for _, opt := range copts { + if opt != nil { + opts = append(opts, opt) + } + } + + if e.TraceClientOptions == nil { + e.TraceClientOptions = opts + return nil + } + + e.TraceClientOptions = append(e.TraceClientOptions, opts...) + + return nil + } +} + +func WithBundleDelayThreshold(dur string) Option { + return func(e *exp) error { + if dur == "" { + return nil + } + + d, err := timeutil.Parse(dur) + if err != nil { + return err + } + + e.BundleDelayThreshold = d + + return nil + } +} + +func WithBundleCountThreshold(cnt int) Option { + return func(e *exp) error { + e.BundleCountThreshold = cnt + + return nil + } +} + +func WithTraceSpansBufferMaxBytes(bs int) Option { + return func(e *exp) error { + e.TraceSpansBufferMaxBytes = bs + + return nil + } +} + +func WithMonitoredResource(mr monitoredresource.Interface) Option { + return func(e *exp) error { + if mr != nil { + e.MonitoredResource = mr + } + + return nil + } +} + +func WithMetricPrefix(prefix string) Option { + return func(e *exp) error { + if prefix != "" { + e.MetricPrefix = prefix + } + + return nil + } +} + +func WithGetMetricDisplayName(f func(view *metrics.View) string) Option { + return func(e *exp) error { + if f != nil { + e.GetMetricDisplayName = f + } + + return nil + } +} + +func WithGetMetricPrefix(f func(name string) string) Option { + return func(e *exp) error { + if f != nil { + e.GetMetricPrefix = f + } + + return nil + } +} + +func WithDefaultMonitoringLabels(lbs *stackdriver.Labels) Option { + return func(e *exp) error { + if lbs != nil { + e.DefaultMonitoringLabels = lbs + } + return nil + } +} + +func WithSkipCMD(skip bool) Option { + return func(e *exp) error { + e.SkipCMD = skip + + return nil + } +} + +func WithTimeout(dur string) Option { + return func(e *exp) error { + if dur == "" { + return nil + } + + d, err := timeutil.Parse(dur) + if err != nil { + return err + } + + e.Timeout = d + + return nil + } +} + +func WithReportingInterval(dur string) Option { + return func(e *exp) error { + if dur == "" { + return nil + } + + d, err := timeutil.Parse(dur) + if err != nil { + return err + } + + e.ReportingInterval = d + + return nil + } +} + +func WithNumberOfWorkers(n int) Option { + return func(e *exp) error { + e.NumberOfWorkers = n + + return nil + } +} diff --git a/internal/observability/exporter/stackdriver/stackdriver_option_test.go b/internal/observability/exporter/stackdriver/stackdriver_option_test.go new file mode 100644 index 0000000000..f527d2183e --- /dev/null +++ b/internal/observability/exporter/stackdriver/stackdriver_option_test.go @@ -0,0 +1,2194 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Package stackdriver provides a stackdriver exporter. +package stackdriver + +import ( + "testing" + + "contrib.go.opencensus.io/exporter/stackdriver" + "contrib.go.opencensus.io/exporter/stackdriver/monitoredresource" + "github.com/vdaas/vald/internal/observability/metrics" + "go.uber.org/goleak" + "google.golang.org/api/option" +) + +func TestWithMonitoring(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + enabled bool + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + enabled: false, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + enabled: false, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithMonitoring(test.args.enabled) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithMonitoring(test.args.enabled) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithTracing(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + enabled bool + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + enabled: false, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + enabled: false, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithTracing(test.args.enabled) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithTracing(test.args.enabled) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithProjectID(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + pid string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + pid: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + pid: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithProjectID(test.args.pid) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithProjectID(test.args.pid) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithLocation(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + loc string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + loc: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + loc: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithLocation(test.args.loc) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithLocation(test.args.loc) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithOnErrorFunc(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + f func(error) + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithOnErrorFunc(test.args.f) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithOnErrorFunc(test.args.f) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithMonitoringClientOptions(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + copts []option.ClientOption + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + copts: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + copts: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithMonitoringClientOptions(test.args.copts...) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithMonitoringClientOptions(test.args.copts...) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithTraceClientOptions(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + copts []option.ClientOption + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + copts: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + copts: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithTraceClientOptions(test.args.copts...) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithTraceClientOptions(test.args.copts...) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithBundleDelayThreshold(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + dur string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + dur: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + dur: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithBundleDelayThreshold(test.args.dur) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithBundleDelayThreshold(test.args.dur) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithBundleCountThreshold(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + cnt int + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + cnt: 0, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + cnt: 0, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithBundleCountThreshold(test.args.cnt) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithBundleCountThreshold(test.args.cnt) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithTraceSpansBufferMaxBytes(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + bs int + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + bs: 0, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + bs: 0, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithTraceSpansBufferMaxBytes(test.args.bs) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithTraceSpansBufferMaxBytes(test.args.bs) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithMonitoredResource(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + mr monitoredresource.Interface + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + mr: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + mr: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithMonitoredResource(test.args.mr) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithMonitoredResource(test.args.mr) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithMetricPrefix(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + prefix string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + prefix: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + prefix: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithMetricPrefix(test.args.prefix) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithMetricPrefix(test.args.prefix) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithGetMetricDisplayName(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + f func(view *metrics.View) string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithGetMetricDisplayName(test.args.f) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithGetMetricDisplayName(test.args.f) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithGetMetricPrefix(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + f func(name string) string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + f: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithGetMetricPrefix(test.args.f) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithGetMetricPrefix(test.args.f) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithDefaultMonitoringLabels(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + lbs *stackdriver.Labels + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + lbs: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + lbs: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithDefaultMonitoringLabels(test.args.lbs) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithDefaultMonitoringLabels(test.args.lbs) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithSkipCMD(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + skip bool + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + skip: false, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + skip: false, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithSkipCMD(test.args.skip) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithSkipCMD(test.args.skip) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithTimeout(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + dur string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + dur: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + dur: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithTimeout(test.args.dur) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithTimeout(test.args.dur) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithReportingInterval(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + dur string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + dur: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + dur: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithReportingInterval(test.args.dur) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithReportingInterval(test.args.dur) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithNumberOfWorkers(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + n int + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + n: 0, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + n: 0, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithNumberOfWorkers(test.args.n) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithNumberOfWorkers(test.args.n) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} diff --git a/internal/observability/exporter/stackdriver/stackdriver_test.go b/internal/observability/exporter/stackdriver/stackdriver_test.go new file mode 100644 index 0000000000..da47934467 --- /dev/null +++ b/internal/observability/exporter/stackdriver/stackdriver_test.go @@ -0,0 +1,290 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Package stackdriver provides a stackdriver exporter. +package stackdriver + +import ( + "context" + "reflect" + "testing" + + "contrib.go.opencensus.io/exporter/stackdriver" + "github.com/vdaas/vald/internal/errors" + "go.uber.org/goleak" +) + +func TestNew(t *testing.T) { + type args struct { + opts []Option + } + type want struct { + wantS Stackdriver + err error + } + type test struct { + name string + args args + want want + checkFunc func(want, Stackdriver, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, gotS Stackdriver, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(gotS, w.wantS) { + return errors.Errorf("got = %v, want %v", gotS, w.wantS) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + opts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + opts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + gotS, err := New(test.args.opts...) + if err := test.checkFunc(test.want, gotS, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_exporter_Start(t *testing.T) { + type args struct { + ctx context.Context + } + type fields struct { + exporter *stackdriver.Exporter + monitoringEnabled bool + tracingEnabled bool + Options *stackdriver.Options + } + type want struct { + err error + } + type test struct { + name string + args args + fields fields + want want + checkFunc func(want, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + ctx: nil, + }, + fields: fields { + exporter: nil, + monitoringEnabled: false, + tracingEnabled: false, + Options: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + ctx: nil, + }, + fields: fields { + exporter: nil, + monitoringEnabled: false, + tracingEnabled: false, + Options: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + e := &exporter{ + exporter: test.fields.exporter, + monitoringEnabled: test.fields.monitoringEnabled, + tracingEnabled: test.fields.tracingEnabled, + Options: test.fields.Options, + } + + err := e.Start(test.args.ctx) + if err := test.checkFunc(test.want, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_exporter_Stop(t *testing.T) { + type args struct { + ctx context.Context + } + type fields struct { + exporter *stackdriver.Exporter + monitoringEnabled bool + tracingEnabled bool + Options *stackdriver.Options + } + type want struct { + } + type test struct { + name string + args args + fields fields + want want + checkFunc func(want) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want) error { + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + ctx: nil, + }, + fields: fields { + exporter: nil, + monitoringEnabled: false, + tracingEnabled: false, + Options: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + ctx: nil, + }, + fields: fields { + exporter: nil, + monitoringEnabled: false, + tracingEnabled: false, + Options: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + e := &exporter{ + exporter: test.fields.exporter, + monitoringEnabled: test.fields.monitoringEnabled, + tracingEnabled: test.fields.tracingEnabled, + Options: test.fields.Options, + } + + e.Stop(test.args.ctx) + if err := test.checkFunc(test.want); err != nil { + tt.Errorf("error = %v", err) + } + }) + } +} diff --git a/internal/observability/metrics/version/version.go b/internal/observability/metrics/version/version.go index 92941fdf67..e22dd5e66c 100644 --- a/internal/observability/metrics/version/version.go +++ b/internal/observability/metrics/version/version.go @@ -36,8 +36,8 @@ type version struct { kvs map[metrics.Key]string } -func New() (metrics.Metric, error) { - kvs, err := labelKVs() +func New(labels ...string) (metrics.Metric, error) { + kvs, err := labelKVs(labels...) if err != nil { return nil, err } @@ -48,17 +48,27 @@ func New() (metrics.Metric, error) { }, nil } -func labelKVs() (map[metrics.Key]string, error) { +func labelKVs(labels ...string) (map[metrics.Key]string, error) { + labelMap := make(map[string]struct{}, len(labels)) + for _, label := range labels { + labelMap[reps.Replace(label)] = struct{}{} + } + d := info.Get() rt, rv := reflect.TypeOf(d), reflect.ValueOf(d) info := make(map[metrics.Key]string, rt.NumField()) for i := 0; i < rt.NumField(); i++ { + keyName := reps.Replace(rt.Field(i).Tag.Get("json")) + if _, ok := labelMap[keyName]; !ok { + continue + } + v := rv.Field(i).Interface() value, ok := v.(string) if !ok { ss, ok := v.([]string) if ok { - k, err := metrics.NewKey(reps.Replace(rt.Field(i).Tag.Get("json"))) + k, err := metrics.NewKey(keyName) if err != nil { return nil, err } @@ -68,7 +78,7 @@ func labelKVs() (map[metrics.Key]string, error) { continue } if value != "" { - k, err := metrics.NewKey(reps.Replace(rt.Field(i).Tag.Get("json"))) + k, err := metrics.NewKey(keyName) if err != nil { return nil, err } diff --git a/internal/observability/observability.go b/internal/observability/observability.go index 0cacb1283e..c6e3ed7468 100644 --- a/internal/observability/observability.go +++ b/internal/observability/observability.go @@ -23,11 +23,16 @@ import ( "github.com/vdaas/vald/internal/config" "github.com/vdaas/vald/internal/errgroup" "github.com/vdaas/vald/internal/errors" + "github.com/vdaas/vald/internal/observability/client/google" "github.com/vdaas/vald/internal/observability/collector" + "github.com/vdaas/vald/internal/observability/exporter" "github.com/vdaas/vald/internal/observability/exporter/jaeger" "github.com/vdaas/vald/internal/observability/exporter/prometheus" + "github.com/vdaas/vald/internal/observability/exporter/stackdriver" "github.com/vdaas/vald/internal/observability/metrics" "github.com/vdaas/vald/internal/observability/metrics/grpc" + "github.com/vdaas/vald/internal/observability/profiler" + pstackdriver "github.com/vdaas/vald/internal/observability/profiler/stackdriver" "github.com/vdaas/vald/internal/observability/trace" "github.com/vdaas/vald/internal/safety" ) @@ -39,19 +44,25 @@ type Observability interface { } type observability struct { - eg errgroup.Group - collector collector.Collector - tracer trace.Tracer - prometheus prometheus.Prometheus - jaeger jaeger.Jaeger + eg errgroup.Group + collector collector.Collector + tracer trace.Tracer + + exporters []exporter.Exporter + profilers []profiler.Profiler } func NewWithConfig(cfg *config.Observability, metrics ...metrics.Metric) (Observability, error) { opts := make([]Option, 0) + exps := make([]exporter.Exporter, 0) + profs := make([]profiler.Profiler, 0) col, err := collector.New( collector.WithDuration(cfg.Collector.Duration), - collector.WithVersionInfo(cfg.Collector.Metrics.EnableVersionInfo), + collector.WithVersionInfo( + cfg.Collector.Metrics.EnableVersionInfo, + cfg.Collector.Metrics.VersionInfoLabels..., + ), collector.WithMemoryMetrics(cfg.Collector.Metrics.EnableMemory), collector.WithGoroutineMetrics(cfg.Collector.Metrics.EnableGoroutine), collector.WithCGOMetrics(cfg.Collector.Metrics.EnableCGO), @@ -77,7 +88,7 @@ func NewWithConfig(cfg *config.Observability, metrics ...metrics.Metric) (Observ return nil, err } - opts = append(opts, WithPrometheus(prom)) + exps = append(exps, prom) } if cfg.Jaeger.Enabled { @@ -93,9 +104,77 @@ func NewWithConfig(cfg *config.Observability, metrics ...metrics.Metric) (Observ return nil, err } - opts = append(opts, WithJaeger(jae)) + exps = append(exps, jae) + } + + sdClientOpts := []google.Option{ + google.WithAPIKey(cfg.Stackdriver.Client.APIKey), + google.WithAudiences(cfg.Stackdriver.Client.Audiences...), + google.WithCredentialsFile(cfg.Stackdriver.Client.CredentialsFile), + google.WithCredentialsJSON(cfg.Stackdriver.Client.CredentialsJSON), + google.WithEndpoint(cfg.Stackdriver.Client.Endpoint), + google.WithQuotaProject(cfg.Stackdriver.Client.QuotaProject), + google.WithRequestReason(cfg.Stackdriver.Client.RequestReason), + google.WithScopes(cfg.Stackdriver.Client.Scopes...), + google.WithUserAgent(cfg.Stackdriver.Client.UserAgent), + google.WithTelemetry(cfg.Stackdriver.Client.TelemetryEnabled), + google.WithAuthentication(cfg.Stackdriver.Client.AuthenticationEnabled), } + if cfg.Stackdriver.Exporter.MonitoringEnabled || cfg.Stackdriver.Exporter.TracingEnabled { + sdex, err := stackdriver.New( + stackdriver.WithProjectID(cfg.Stackdriver.ProjectID), + stackdriver.WithMonitoring(cfg.Stackdriver.Exporter.MonitoringEnabled), + stackdriver.WithTracing(cfg.Stackdriver.Exporter.TracingEnabled), + stackdriver.WithLocation(cfg.Stackdriver.Exporter.Location), + stackdriver.WithBundleDelayThreshold(cfg.Stackdriver.Exporter.BundleDelayThreshold), + stackdriver.WithBundleCountThreshold(cfg.Stackdriver.Exporter.BundleCountThreshold), + stackdriver.WithTraceSpansBufferMaxBytes(cfg.Stackdriver.Exporter.TraceSpansBufferMaxBytes), + stackdriver.WithMetricPrefix(cfg.Stackdriver.Exporter.MetricPrefix), + stackdriver.WithSkipCMD(cfg.Stackdriver.Exporter.SkipCMD), + stackdriver.WithTimeout(cfg.Stackdriver.Exporter.Timeout), + stackdriver.WithReportingInterval(cfg.Stackdriver.Exporter.ReportingInterval), + stackdriver.WithNumberOfWorkers(cfg.Stackdriver.Exporter.NumberOfWorkers), + stackdriver.WithMonitoringClientOptions(sdClientOpts...), + stackdriver.WithTraceClientOptions(sdClientOpts...), + ) + if err != nil { + return nil, err + } + + exps = append(exps, sdex) + } + + if cfg.Stackdriver.Profiler.Enabled { + sdp, err := pstackdriver.New( + pstackdriver.WithProjectID(cfg.Stackdriver.ProjectID), + pstackdriver.WithService(cfg.Stackdriver.Profiler.Service), + pstackdriver.WithServiceVersion(cfg.Stackdriver.Profiler.ServiceVersion), + pstackdriver.WithDebugLogging(cfg.Stackdriver.Profiler.DebugLogging), + pstackdriver.WithMutexProfiling(cfg.Stackdriver.Profiler.MutexProfiling), + pstackdriver.WithCPUProfiling(cfg.Stackdriver.Profiler.CPUProfiling), + pstackdriver.WithAllocProfiling(cfg.Stackdriver.Profiler.AllocProfiling), + pstackdriver.WithHeapProfiling(cfg.Stackdriver.Profiler.HeapProfiling), + pstackdriver.WithGoroutineProfiling(cfg.Stackdriver.Profiler.GoroutineProfiling), + pstackdriver.WithAllocForceGC(cfg.Stackdriver.Profiler.AllocForceGC), + pstackdriver.WithAPIAddr(cfg.Stackdriver.Profiler.APIAddr), + pstackdriver.WithInstance(cfg.Stackdriver.Profiler.Instance), + pstackdriver.WithZone(cfg.Stackdriver.Profiler.Zone), + pstackdriver.WithClientOptions(sdClientOpts...), + ) + if err != nil { + return nil, err + } + + profs = append(profs, sdp) + } + + opts = append( + opts, + WithExporters(exps...), + WithProfilers(profs...), + ) + return New(opts...) } @@ -133,16 +212,25 @@ func (o *observability) PreStart(ctx context.Context) (err error) { return err } - if o.prometheus != nil { - err = o.prometheus.Start(ctx) + for i, ex := range o.exporters { + err = ex.Start(ctx) if err != nil { + for _, ex = range o.exporters[:i] { + ex.Stop(ctx) + } return err } } - if o.jaeger != nil { - err = o.jaeger.Start(ctx) + for i, prof := range o.profilers { + err = prof.Start(ctx) if err != nil { + for _, ex := range o.exporters { + ex.Stop(ctx) + } + for _, prof = range o.profilers[:i] { + prof.Stop(ctx) + } return err } } @@ -150,6 +238,7 @@ func (o *observability) PreStart(ctx context.Context) (err error) { if o.tracer != nil { o.tracer.Start(ctx) } + return nil } @@ -180,10 +269,12 @@ func (o *observability) Start(ctx context.Context) <-chan error { func (o *observability) Stop(ctx context.Context) { o.collector.Stop(ctx) - if o.prometheus != nil { - o.prometheus.Stop(ctx) + + for _, ex := range o.exporters { + ex.Stop(ctx) } - if o.jaeger != nil { - o.jaeger.Stop(ctx) + + for _, prof := range o.profilers { + prof.Stop(ctx) } } diff --git a/internal/observability/observability_option.go b/internal/observability/observability_option.go index cc1d2e1dfd..41d219e168 100644 --- a/internal/observability/observability_option.go +++ b/internal/observability/observability_option.go @@ -20,8 +20,8 @@ package observability import ( "github.com/vdaas/vald/internal/errgroup" "github.com/vdaas/vald/internal/observability/collector" - "github.com/vdaas/vald/internal/observability/exporter/jaeger" - "github.com/vdaas/vald/internal/observability/exporter/prometheus" + "github.com/vdaas/vald/internal/observability/exporter" + "github.com/vdaas/vald/internal/observability/profiler" "github.com/vdaas/vald/internal/observability/trace" ) @@ -60,19 +60,28 @@ func WithTracer(t trace.Tracer) Option { } } -func WithPrometheus(p prometheus.Prometheus) Option { +func WithExporters(exps ...exporter.Exporter) Option { return func(o *observability) error { - if p != nil { - o.prometheus = p + if o.exporters == nil { + o.exporters = exps + return nil } + + o.exporters = append(o.exporters, exps...) + return nil } } -func WithJaeger(j jaeger.Jaeger) Option { + +func WithProfilers(profs ...profiler.Profiler) Option { return func(o *observability) error { - if j != nil { - o.jaeger = j + if o.profilers == nil { + o.profilers = profs + return nil } + + o.profilers = append(o.profilers, profs...) + return nil } } diff --git a/internal/observability/observability_option_test.go b/internal/observability/observability_option_test.go index c84c8fecca..32b875c592 100644 --- a/internal/observability/observability_option_test.go +++ b/internal/observability/observability_option_test.go @@ -22,10 +22,9 @@ import ( "github.com/vdaas/vald/internal/errgroup" "github.com/vdaas/vald/internal/observability/collector" - "github.com/vdaas/vald/internal/observability/exporter/jaeger" - "github.com/vdaas/vald/internal/observability/exporter/prometheus" + "github.com/vdaas/vald/internal/observability/exporter" + "github.com/vdaas/vald/internal/observability/profiler" "github.com/vdaas/vald/internal/observability/trace" - "go.uber.org/goleak" ) @@ -368,10 +367,11 @@ func TestWithTracer(t *testing.T) { } } -func TestWithPrometheus(t *testing.T) { +func TestWithExporters(t *testing.T) { + // Change interface type to the type of object you are testing type T = interface{} type args struct { - p prometheus.Prometheus + exps []exporter.Exporter } type want struct { obj *T @@ -406,7 +406,7 @@ func TestWithPrometheus(t *testing.T) { /* defaultCheckFunc := func(w want, obj *T) error { if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) + return errors.Errorf("got = %v, want %v", obj, w.obj) } return nil } @@ -418,7 +418,7 @@ func TestWithPrometheus(t *testing.T) { { name: "test_case_1", args: args { - p: nil, + exps: nil, }, want: want { obj: new(T), @@ -432,7 +432,7 @@ func TestWithPrometheus(t *testing.T) { return test { name: "test_case_2", args: args { - p: nil, + exps: nil, }, want: want { obj: new(T), @@ -444,7 +444,7 @@ func TestWithPrometheus(t *testing.T) { for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -458,22 +458,22 @@ func TestWithPrometheus(t *testing.T) { test.checkFunc = defaultCheckFunc } - got := WithPrometheus(test.args.p) + got := WithExporters(test.args.exps...) obj := new(T) if err := test.checkFunc(test.want, obj, got(obj)); err != nil { tt.Errorf("error = %v", err) } */ - // Uncomment this block if the option returns an error, otherwise delete it + // Uncomment this block if the option do not return an error, otherwise delete it /* if test.checkFunc == nil { test.checkFunc = defaultCheckFunc } - got := WithPrometheus(test.args.p) + got := WithExporters(test.args.exps...) obj := new(T) got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { + if err := test.checkFunc(test.want, obj); err != nil { tt.Errorf("error = %v", err) } */ @@ -481,10 +481,11 @@ func TestWithPrometheus(t *testing.T) { } } -func TestWithJaeger(t *testing.T) { +func TestWithProfilers(t *testing.T) { + // Change interface type to the type of object you are testing type T = interface{} type args struct { - j jaeger.Jaeger + profs []profiler.Profiler } type want struct { obj *T @@ -519,7 +520,7 @@ func TestWithJaeger(t *testing.T) { /* defaultCheckFunc := func(w want, obj *T) error { if !reflect.DeepEqual(obj, w.obj) { - return errors.Errorf("got = %v, want %v", obj, w.c) + return errors.Errorf("got = %v, want %v", obj, w.obj) } return nil } @@ -531,7 +532,7 @@ func TestWithJaeger(t *testing.T) { { name: "test_case_1", args: args { - j: nil, + profs: nil, }, want: want { obj: new(T), @@ -545,7 +546,7 @@ func TestWithJaeger(t *testing.T) { return test { name: "test_case_2", args: args { - j: nil, + profs: nil, }, want: want { obj: new(T), @@ -557,7 +558,7 @@ func TestWithJaeger(t *testing.T) { for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -571,22 +572,22 @@ func TestWithJaeger(t *testing.T) { test.checkFunc = defaultCheckFunc } - got := WithJaeger(test.args.j) + got := WithProfilers(test.args.profs...) obj := new(T) if err := test.checkFunc(test.want, obj, got(obj)); err != nil { tt.Errorf("error = %v", err) } */ - // Uncomment this block if the option returns an error, otherwise delete it + // Uncomment this block if the option do not return an error, otherwise delete it /* if test.checkFunc == nil { test.checkFunc = defaultCheckFunc } - got := WithJaeger(test.args.j) + got := WithProfilers(test.args.profs...) obj := new(T) got(obj) - if err := test.checkFunc(tt.want, obj); err != nil { + if err := test.checkFunc(test.want, obj); err != nil { tt.Errorf("error = %v", err) } */ diff --git a/internal/observability/observability_test.go b/internal/observability/observability_test.go index 270c118d19..0cbd620f2e 100644 --- a/internal/observability/observability_test.go +++ b/internal/observability/observability_test.go @@ -26,11 +26,10 @@ import ( "github.com/vdaas/vald/internal/errgroup" "github.com/vdaas/vald/internal/errors" "github.com/vdaas/vald/internal/observability/collector" - "github.com/vdaas/vald/internal/observability/exporter/jaeger" - "github.com/vdaas/vald/internal/observability/exporter/prometheus" + "github.com/vdaas/vald/internal/observability/exporter" "github.com/vdaas/vald/internal/observability/metrics" + "github.com/vdaas/vald/internal/observability/profiler" "github.com/vdaas/vald/internal/observability/trace" - "go.uber.org/goleak" ) @@ -192,11 +191,11 @@ func Test_observability_PreStart(t *testing.T) { ctx context.Context } type fields struct { - eg errgroup.Group - collector collector.Collector - tracer trace.Tracer - prometheus prometheus.Prometheus - jaeger jaeger.Jaeger + eg errgroup.Group + collector collector.Collector + tracer trace.Tracer + exporters []exporter.Exporter + profilers []profiler.Profiler } type want struct { err error @@ -228,8 +227,8 @@ func Test_observability_PreStart(t *testing.T) { eg: nil, collector: nil, tracer: nil, - prometheus: nil, - jaeger: nil, + exporters: nil, + profilers: nil, }, want: want{}, checkFunc: defaultCheckFunc, @@ -248,8 +247,8 @@ func Test_observability_PreStart(t *testing.T) { eg: nil, collector: nil, tracer: nil, - prometheus: nil, - jaeger: nil, + exporters: nil, + profilers: nil, }, want: want{}, checkFunc: defaultCheckFunc, @@ -260,7 +259,7 @@ func Test_observability_PreStart(t *testing.T) { for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -271,11 +270,11 @@ func Test_observability_PreStart(t *testing.T) { test.checkFunc = defaultCheckFunc } o := &observability{ - eg: test.fields.eg, - collector: test.fields.collector, - tracer: test.fields.tracer, - prometheus: test.fields.prometheus, - jaeger: test.fields.jaeger, + eg: test.fields.eg, + collector: test.fields.collector, + tracer: test.fields.tracer, + exporters: test.fields.exporters, + profilers: test.fields.profilers, } err := o.PreStart(test.args.ctx) @@ -292,11 +291,11 @@ func Test_observability_Start(t *testing.T) { ctx context.Context } type fields struct { - eg errgroup.Group - collector collector.Collector - tracer trace.Tracer - prometheus prometheus.Prometheus - jaeger jaeger.Jaeger + eg errgroup.Group + collector collector.Collector + tracer trace.Tracer + exporters []exporter.Exporter + profilers []profiler.Profiler } type want struct { want <-chan error @@ -328,8 +327,8 @@ func Test_observability_Start(t *testing.T) { eg: nil, collector: nil, tracer: nil, - prometheus: nil, - jaeger: nil, + exporters: nil, + profilers: nil, }, want: want{}, checkFunc: defaultCheckFunc, @@ -348,8 +347,8 @@ func Test_observability_Start(t *testing.T) { eg: nil, collector: nil, tracer: nil, - prometheus: nil, - jaeger: nil, + exporters: nil, + profilers: nil, }, want: want{}, checkFunc: defaultCheckFunc, @@ -360,7 +359,7 @@ func Test_observability_Start(t *testing.T) { for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -371,11 +370,11 @@ func Test_observability_Start(t *testing.T) { test.checkFunc = defaultCheckFunc } o := &observability{ - eg: test.fields.eg, - collector: test.fields.collector, - tracer: test.fields.tracer, - prometheus: test.fields.prometheus, - jaeger: test.fields.jaeger, + eg: test.fields.eg, + collector: test.fields.collector, + tracer: test.fields.tracer, + exporters: test.fields.exporters, + profilers: test.fields.profilers, } got := o.Start(test.args.ctx) @@ -392,11 +391,11 @@ func Test_observability_Stop(t *testing.T) { ctx context.Context } type fields struct { - eg errgroup.Group - collector collector.Collector - tracer trace.Tracer - prometheus prometheus.Prometheus - jaeger jaeger.Jaeger + eg errgroup.Group + collector collector.Collector + tracer trace.Tracer + exporters []exporter.Exporter + profilers []profiler.Profiler } type want struct { } @@ -424,8 +423,8 @@ func Test_observability_Stop(t *testing.T) { eg: nil, collector: nil, tracer: nil, - prometheus: nil, - jaeger: nil, + exporters: nil, + profilers: nil, }, want: want{}, checkFunc: defaultCheckFunc, @@ -444,8 +443,8 @@ func Test_observability_Stop(t *testing.T) { eg: nil, collector: nil, tracer: nil, - prometheus: nil, - jaeger: nil, + exporters: nil, + profilers: nil, }, want: want{}, checkFunc: defaultCheckFunc, @@ -456,7 +455,7 @@ func Test_observability_Stop(t *testing.T) { for _, test := range tests { t.Run(test.name, func(tt *testing.T) { - defer goleak.VerifyNone(t) + defer goleak.VerifyNone(tt) if test.beforeFunc != nil { test.beforeFunc(test.args) } @@ -467,11 +466,11 @@ func Test_observability_Stop(t *testing.T) { test.checkFunc = defaultCheckFunc } o := &observability{ - eg: test.fields.eg, - collector: test.fields.collector, - tracer: test.fields.tracer, - prometheus: test.fields.prometheus, - jaeger: test.fields.jaeger, + eg: test.fields.eg, + collector: test.fields.collector, + tracer: test.fields.tracer, + exporters: test.fields.exporters, + profilers: test.fields.profilers, } o.Stop(test.args.ctx) diff --git a/internal/observability/profiler/profiler.go b/internal/observability/profiler/profiler.go new file mode 100644 index 0000000000..7d4abf1998 --- /dev/null +++ b/internal/observability/profiler/profiler.go @@ -0,0 +1,27 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES 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 provides profilers. +package profiler + +import ( + "context" +) + +type Profiler interface { + Start(ctx context.Context) error + Stop(ctx context.Context) +} diff --git a/internal/observability/profiler/stackdriver/stackdriver.go b/internal/observability/profiler/stackdriver/stackdriver.go new file mode 100644 index 0000000000..454b511c02 --- /dev/null +++ b/internal/observability/profiler/stackdriver/stackdriver.go @@ -0,0 +1,56 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Package stackdriver provides a stackdriver exporter. +package stackdriver + +import ( + "context" + + "cloud.google.com/go/profiler" + "github.com/vdaas/vald/internal/observability/client/google" + vprof "github.com/vdaas/vald/internal/observability/profiler" +) + +type Stackdriver interface { + vprof.Profiler +} + +type prof struct { + *profiler.Config + clientOpts []google.Option +} + +func New(opts ...Option) (s Stackdriver, err error) { + p := new(prof) + p.Config = new(profiler.Config) + + for _, opt := range append(defaultOpts, opts...) { + err = opt(p) + if err != nil { + return nil, err + } + } + + return p, nil +} + +func (p *prof) Start(ctx context.Context) (err error) { + return profiler.Start(*p.Config, p.clientOpts...) +} + +func (p *prof) Stop(ctx context.Context) { +} diff --git a/internal/observability/profiler/stackdriver/stackdriver_option.go b/internal/observability/profiler/stackdriver/stackdriver_option.go new file mode 100644 index 0000000000..734cc60004 --- /dev/null +++ b/internal/observability/profiler/stackdriver/stackdriver_option.go @@ -0,0 +1,171 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Package stackdriver provides a stackdriver exporter. +package stackdriver + +import ( + "github.com/vdaas/vald/internal/info" + "github.com/vdaas/vald/internal/observability/client/google" +) + +type Option func(p *prof) error + +var ( + defaultOpts = []Option{ + WithCPUProfiling(true), + WithAllocProfiling(true), + WithHeapProfiling(true), + WithGoroutineProfiling(true), + WithServiceVersion(info.Version), + } +) + +func WithProjectID(pid string) Option { + return func(p *prof) error { + if pid != "" { + p.ProjectID = pid + } + + return nil + } +} + +func WithService(name string) Option { + return func(p *prof) error { + if name != "" { + p.Service = name + } + + return nil + } +} + +func WithServiceVersion(version string) Option { + return func(p *prof) error { + if version != "" { + p.ServiceVersion = version + } + + return nil + } +} + +func WithDebugLogging(enabled bool) Option { + return func(p *prof) error { + p.DebugLogging = enabled + + return nil + } +} + +func WithMutexProfiling(enabled bool) Option { + return func(p *prof) error { + p.MutexProfiling = enabled + + return nil + } +} + +func WithCPUProfiling(enabled bool) Option { + return func(p *prof) error { + p.NoCPUProfiling = !enabled + + return nil + } +} + +func WithAllocProfiling(enabled bool) Option { + return func(p *prof) error { + p.NoAllocProfiling = !enabled + + return nil + } +} + +func WithHeapProfiling(enabled bool) Option { + return func(p *prof) error { + p.NoHeapProfiling = !enabled + + return nil + } +} + +func WithGoroutineProfiling(enabled bool) Option { + return func(p *prof) error { + p.NoGoroutineProfiling = !enabled + + return nil + } +} + +func WithAllocForceGC(enabled bool) Option { + return func(p *prof) error { + p.AllocForceGC = enabled + + return nil + } +} + +func WithAPIAddr(addr string) Option { + return func(p *prof) error { + if addr != "" { + p.APIAddr = addr + } + + return nil + } +} + +func WithInstance(instance string) Option { + return func(p *prof) error { + if instance != "" { + p.Instance = instance + } + + return nil + } +} + +func WithZone(zone string) Option { + return func(p *prof) error { + if zone != "" { + p.Zone = zone + } + + return nil + } +} + +func WithClientOptions(copts ...google.Option) Option { + return func(p *prof) error { + opts := make([]google.Option, 0, len(copts)) + for _, opt := range copts { + if opt != nil { + opts = append(opts, opt) + } + } + + if p.clientOpts == nil { + p.clientOpts = opts + return nil + } + + p.clientOpts = append(p.clientOpts, opts...) + + return nil + } +} diff --git a/internal/observability/profiler/stackdriver/stackdriver_option_test.go b/internal/observability/profiler/stackdriver/stackdriver_option_test.go new file mode 100644 index 0000000000..3b0ec73509 --- /dev/null +++ b/internal/observability/profiler/stackdriver/stackdriver_option_test.go @@ -0,0 +1,1621 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Package stackdriver provides a stackdriver exporter. +package stackdriver + +import ( + "testing" + + "go.uber.org/goleak" + "google.golang.org/api/option" +) + +func TestWithProjectID(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + pid string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + pid: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + pid: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithProjectID(test.args.pid) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithProjectID(test.args.pid) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithService(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + name string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + name: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + name: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithService(test.args.name) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithService(test.args.name) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithServiceVersion(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + version string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + version: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + version: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithServiceVersion(test.args.version) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithServiceVersion(test.args.version) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithDebugLogging(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + enabled bool + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + enabled: false, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + enabled: false, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithDebugLogging(test.args.enabled) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithDebugLogging(test.args.enabled) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithMutexProfiling(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + enabled bool + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + enabled: false, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + enabled: false, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithMutexProfiling(test.args.enabled) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithMutexProfiling(test.args.enabled) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithCPUProfiling(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + enabled bool + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + enabled: false, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + enabled: false, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithCPUProfiling(test.args.enabled) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithCPUProfiling(test.args.enabled) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithAllocProfiling(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + enabled bool + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + enabled: false, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + enabled: false, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithAllocProfiling(test.args.enabled) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithAllocProfiling(test.args.enabled) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithHeapProfiling(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + enabled bool + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + enabled: false, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + enabled: false, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithHeapProfiling(test.args.enabled) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithHeapProfiling(test.args.enabled) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithGoroutineProfiling(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + enabled bool + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + enabled: false, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + enabled: false, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithGoroutineProfiling(test.args.enabled) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithGoroutineProfiling(test.args.enabled) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithAllocForceGC(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + enabled bool + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + enabled: false, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + enabled: false, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithAllocForceGC(test.args.enabled) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithAllocForceGC(test.args.enabled) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithAPIAddr(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + addr string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + addr: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + addr: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithAPIAddr(test.args.addr) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithAPIAddr(test.args.addr) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithInstance(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + instance string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + instance: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + instance: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithInstance(test.args.instance) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithInstance(test.args.instance) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithZone(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + zone string + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + zone: "", + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + zone: "", + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithZone(test.args.zone) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithZone(test.args.zone) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} + +func TestWithClientOptions(t *testing.T) { + // Change interface type to the type of object you are testing + type T = interface{} + type args struct { + opts []option.ClientOption + } + type want struct { + obj *T + // Uncomment this line if the option returns an error, otherwise delete it + // err error + } + type test struct { + name string + args args + want want + // Use the first line if the option returns an error. otherwise use the second line + // checkFunc func(want, *T, error) error + // checkFunc func(want, *T) error + beforeFunc func(args) + afterFunc func(args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + // Uncomment this block if the option do not returns an error, otherwise delete it + /* + defaultCheckFunc := func(w want, obj *T) error { + if !reflect.DeepEqual(obj, w.obj) { + return errors.Errorf("got = %v, want %v", obj, w.obj) + } + return nil + } + */ + + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + opts: nil, + }, + want: want { + obj: new(T), + }, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + opts: nil, + }, + want: want { + obj: new(T), + }, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + + // Uncomment this block if the option returns an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + got := WithClientOptions(test.args.opts...) + obj := new(T) + if err := test.checkFunc(test.want, obj, got(obj)); err != nil { + tt.Errorf("error = %v", err) + } + */ + + // Uncomment this block if the option do not return an error, otherwise delete it + /* + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + got := WithClientOptions(test.args.opts...) + obj := new(T) + got(obj) + if err := test.checkFunc(test.want, obj); err != nil { + tt.Errorf("error = %v", err) + } + */ + }) + } +} diff --git a/internal/observability/profiler/stackdriver/stackdriver_test.go b/internal/observability/profiler/stackdriver/stackdriver_test.go new file mode 100644 index 0000000000..627a264998 --- /dev/null +++ b/internal/observability/profiler/stackdriver/stackdriver_test.go @@ -0,0 +1,192 @@ +// +// Copyright (C) 2019-2020 Vdaas.org Vald team ( kpango, rinx, kmrmt ) +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +// Package stackdriver provides a stackdriver exporter. +package stackdriver + +import ( + "context" + "reflect" + "testing" + + "cloud.google.com/go/profiler" + "github.com/vdaas/vald/internal/errors" + "go.uber.org/goleak" + "google.golang.org/api/option" +) + +func TestNew(t *testing.T) { + type args struct { + opts []Option + } + type want struct { + wantS Stackdriver + err error + } + type test struct { + name string + args args + want want + checkFunc func(want, Stackdriver, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, gotS Stackdriver, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + if !reflect.DeepEqual(gotS, w.wantS) { + return errors.Errorf("got = %v, want %v", gotS, w.wantS) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + opts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + opts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + + gotS, err := New(test.args.opts...) + if err := test.checkFunc(test.want, gotS, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +} + +func Test_prof_Start(t *testing.T) { + type args struct { + ctx context.Context + } + type fields struct { + Config *profiler.Config + clientOpts []option.ClientOption + } + type want struct { + err error + } + type test struct { + name string + args args + fields fields + want want + checkFunc func(want, error) error + beforeFunc func(args) + afterFunc func(args) + } + defaultCheckFunc := func(w want, err error) error { + if !errors.Is(err, w.err) { + return errors.Errorf("got error = %v, want %v", err, w.err) + } + return nil + } + tests := []test{ + // TODO test cases + /* + { + name: "test_case_1", + args: args { + ctx: nil, + }, + fields: fields { + Config: nil, + clientOpts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + }, + */ + + // TODO test cases + /* + func() test { + return test { + name: "test_case_2", + args: args { + ctx: nil, + }, + fields: fields { + Config: nil, + clientOpts: nil, + }, + want: want{}, + checkFunc: defaultCheckFunc, + } + }(), + */ + } + + for _, test := range tests { + t.Run(test.name, func(tt *testing.T) { + defer goleak.VerifyNone(tt) + if test.beforeFunc != nil { + test.beforeFunc(test.args) + } + if test.afterFunc != nil { + defer test.afterFunc(test.args) + } + if test.checkFunc == nil { + test.checkFunc = defaultCheckFunc + } + p := &prof{ + Config: test.fields.Config, + clientOpts: test.fields.clientOpts, + } + + err := p.Start(test.args.ctx) + if err := test.checkFunc(test.want, err); err != nil { + tt.Errorf("error = %v", err) + } + + }) + } +}