From 132481cb9226bcca74f88e00f45e62f5e19ccd33 Mon Sep 17 00:00:00 2001 From: Brad Sickles Date: Fri, 18 Sep 2026 09:21:41 -0400 Subject: [PATCH 1/4] fix(deps): bump google.golang.org/grpc to v1.84.0 Resolves Dependabot alerts: - GHSA-2v4p-qf9q-27wj gRPC-Go xDS servers: DoS via missing :authority/Host headers - GHSA-vp52-pcj8-j9qc gRPC-Go: heap memory exhaustion via HTTP/2 DATA frame fragmentation - GHSA-qc2q-p7wx-3px3 gRPC-Go: xDS RBAC HTTP filter bypass via mixed-case header matching --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index d9f4476..f6147e7 100644 --- a/go.mod +++ b/go.mod @@ -186,7 +186,7 @@ require ( google.golang.org/genproto v0.0.0-20260715232425-e75dac1f907d // indirect google.golang.org/genproto/googleapis/api v0.0.0-20260715232425-e75dac1f907d // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260715232425-e75dac1f907d // indirect - google.golang.org/grpc v1.82.1 // indirect + google.golang.org/grpc v1.84.0 // indirect gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 0e3ac47..a649c73 100644 --- a/go.sum +++ b/go.sum @@ -434,8 +434,8 @@ google.golang.org/genproto/googleapis/api v0.0.0-20260715232425-e75dac1f907d h1: google.golang.org/genproto/googleapis/api v0.0.0-20260715232425-e75dac1f907d/go.mod h1:WRrQ7/7N19PypuT0fxLOL5Lq0waoiRri4FbtHDEKrGE= google.golang.org/genproto/googleapis/rpc v0.0.0-20260715232425-e75dac1f907d h1:Jkpk39hlTZOIp3RbfvNX9R8Hv+Sw0X89nlU/xFOErsc= google.golang.org/genproto/googleapis/rpc v0.0.0-20260715232425-e75dac1f907d/go.mod h1:4Hqkh8ycfw05ld/3BWL7rJOSfebL2Q+DVDeRgYgxUU8= -google.golang.org/grpc v1.82.1 h1:NnAxzGRA0677vCa4BUkOAnO5+FfQqVl9iUXeD0IqcGE= -google.golang.org/grpc v1.82.1/go.mod h1:yzTZ1TB1Z3SG+LIYaI+WiE8D5+PZ3ArnrSp8zF3+/ZA= +google.golang.org/grpc v1.84.0 h1:soMyaPJ8pAak5PIQ0DGBUir0XRo2fRoMqhNWMLlLxO0= +google.golang.org/grpc v1.84.0/go.mod h1:ljCht0DrxQrXBDRTZp52Qxh3Ffk8CdYm2sj4O2QN2C0= google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af h1:+5/Sw3GsDNlEmu7TfklWKPdQ0Ykja5VEmq2i817+jbI= google.golang.org/protobuf v1.36.12-0.20260120151049-f2248ac996af/go.mod h1:HTf+CrKn2C3g5S8VImy6tdcUvCska2kB7j23XfzDpco= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= From e5dd3afc6ab7bebf7c81d1f376e0bd9cd12b2310 Mon Sep 17 00:00:00 2001 From: Brad Sickles Date: Fri, 18 Sep 2026 09:23:27 -0400 Subject: [PATCH 2/4] fix(deps): bump go.opentelemetry.io/otel to v1.46.0 Resolves Dependabot alert GHSA-8wmf-6v46-5gfg (OpenTelemetry-Go: exporter config logging may leak endpoint URLs in info logs), flagged on go.opentelemetry.io/otel/sdk, exporters/otlp/otlptrace and exporters/otlp/otlptrace/otlptracegrpc. --- go.mod | 17 ++++++++--------- go.sum | 37 ++++++++++++++++++------------------- 2 files changed, 26 insertions(+), 28 deletions(-) diff --git a/go.mod b/go.mod index f6147e7..4c18042 100644 --- a/go.mod +++ b/go.mod @@ -41,7 +41,7 @@ require ( github.com/moby/moby/client v0.5.1 github.com/nullstone-io/module v0.2.11 github.com/sethvargo/go-retry v0.3.0 - github.com/stretchr/testify v1.11.1 + github.com/stretchr/testify v1.12.1 github.com/tomnomnom/linkheader v0.0.0-20250811210735-e5fe3b51442e github.com/vmihailenco/tagparser v0.1.2 golang.org/x/oauth2 v0.36.0 @@ -159,7 +159,7 @@ require ( github.com/spf13/cobra v1.10.2 // indirect github.com/spf13/pflag v1.0.10 // indirect github.com/spiffe/go-spiffe/v2 v2.8.1 // indirect - github.com/stretchr/objx v0.5.2 // indirect + github.com/stretchr/objx v0.5.3 // indirect github.com/tmccombs/hcl2json v0.6.9 // indirect github.com/x448/float16 v0.8.4 // indirect github.com/xlab/treeprint v1.2.0 // indirect @@ -168,13 +168,13 @@ require ( go.opentelemetry.io/contrib/detectors/gcp v1.44.0 // indirect go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.70.0 // indirect - go.opentelemetry.io/otel v1.45.0 // indirect - go.opentelemetry.io/otel/metric v1.45.0 // indirect - go.opentelemetry.io/otel/sdk v1.45.0 // indirect - go.opentelemetry.io/otel/sdk/metric v1.45.0 // indirect - go.opentelemetry.io/otel/trace v1.45.0 // indirect + go.opentelemetry.io/otel v1.46.0 // indirect + go.opentelemetry.io/otel/metric v1.46.0 // indirect + go.opentelemetry.io/otel/sdk v1.46.0 // indirect + go.opentelemetry.io/otel/sdk/metric v1.46.0 // indirect + go.opentelemetry.io/otel/trace v1.46.0 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect - go.yaml.in/yaml/v3 v3.0.4 // indirect + go.yaml.in/yaml/v3 v3.0.5 // indirect golang.org/x/crypto v0.54.0 // indirect golang.org/x/mod v0.38.0 // indirect golang.org/x/net v0.57.0 // indirect @@ -190,7 +190,6 @@ require ( gopkg.in/evanphx/json-patch.v4 v4.13.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect k8s.io/cli-runtime v0.36.1 // indirect k8s.io/component-base v0.36.1 // indirect k8s.io/component-helpers v0.36.1 // indirect diff --git a/go.sum b/go.sum index a649c73..98d97d0 100644 --- a/go.sum +++ b/go.sum @@ -351,13 +351,13 @@ github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3A github.com/spiffe/go-spiffe/v2 v2.8.1 h1:eXZMLsu+3MLEPJyGJkolqtVrteZfQdUpOWj6LTiDl/E= github.com/spiffe/go-spiffe/v2 v2.8.1/go.mod h1:47Q0Q9/AqGha8QLHp+kxpH4Wca7X7EnOtlIJy3mxZ3U= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= -github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/objx v0.5.3 h1:jmXUvGomnU1o3W/V5h2VEradbpJDwGrzugQQvL0POH4= +github.com/stretchr/objx v0.5.3/go.mod h1:rDQraq+vQZU7Fde9LOZLr8Tax6zZvy4kuNKF+QYS+U0= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= -github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= +github.com/stretchr/testify v1.12.1 h1:EuwCh5fleGS7H32xRwO3wRGT7DxrDhLAT6FF8MpWDWE= +github.com/stretchr/testify v1.12.1/go.mod h1:MDEgiDPPsNp5cuIrHPPCyornHKgEVbtFUmoNlxoYthg= github.com/tmccombs/hcl2json v0.6.9 h1:Pvqe6XgLQ8WxuQWp/QPRmV+8uHvUIuCs5b+Q8jvbrdc= github.com/tmccombs/hcl2json v0.6.9/go.mod h1:JIcW8tgtY0DTxXAIXxfNYvBa6MvMptf6GabOCjiOOak= github.com/tomnomnom/linkheader v0.0.0-20250811210735-e5fe3b51442e h1:tD38/4xg4nuQCASJ/JxcvCHNb46w0cdAaJfkzQOO1bA= @@ -382,26 +382,27 @@ go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.6 go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.69.0/go.mod h1:D7J12YRapIekYyPWgGPlA/23pRmpSEZC5xJC/TTLI9U= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.70.0 h1:LMuyCAyfalSjDyjdC65nK6N0zoTT63+E/u95X0JovZI= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.70.0/go.mod h1:085m8qbm4hgc8rZWGDEa4vmyyo2c3nPxUslYUKUIU04= -go.opentelemetry.io/otel v1.45.0 h1:pdrWmLHofpubmArBv1LgFSv1Z0Ie/ppdZzu+kUN5EeU= -go.opentelemetry.io/otel v1.45.0/go.mod h1:XZxIqPapzEYnhNSScF5DIqXhm/rYi0FzCe2XddAwZfQ= +go.opentelemetry.io/otel v1.46.0 h1:FHt5/CDyVxi/8IM1CH7VE/rRgq3kLHa2mSTVMO8AWyc= +go.opentelemetry.io/otel v1.46.0/go.mod h1:Gj3SEScelsNC45tp4nSxRYlS+f5iez7W8XPMCt905kE= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.44.0 h1:hqxVTu/GtBF+vJ8d1fzW7fRxZFvgoDjWcxwwCaFDYpU= go.opentelemetry.io/otel/exporters/stdout/stdoutmetric v1.44.0/go.mod h1:z5fVEF4X5v0ESvlJqBrrFlBVoj5EQuefZpzsu7R+x5Q= -go.opentelemetry.io/otel/metric v1.45.0 h1:7Eg1uH7CJ5cXv9is6tnBe1FI6rj1nwUdbFypRm3br/M= -go.opentelemetry.io/otel/metric v1.45.0/go.mod h1:HAPbm1nd3p1PmFH7v2dR+6BjXxw+Lq4a2+pndMAm08s= -go.opentelemetry.io/otel/metric/x v0.67.0 h1:PcicCNZFkZ4bXfSooXdo3WN7RBOVOtjVdo1wD358Uns= -go.opentelemetry.io/otel/metric/x v0.67.0/go.mod h1:FBjCWZe6wgcqxcMtjdGiClDKXb2YxxXii0CXftE4QtI= -go.opentelemetry.io/otel/sdk v1.45.0 h1:4VVSMgQ83dUgW2aoX5f6JgLvHwIvzcuLnF9lUdCSpCw= -go.opentelemetry.io/otel/sdk v1.45.0/go.mod h1:Sr40LgXV7DsKMMJMKOhUWOgMWTfAaqvm2kF0g7ilwuA= -go.opentelemetry.io/otel/sdk/metric v1.45.0 h1:oVFszMfyj1Am6s24Vtc7wBb8BKLcwepJjNEYILuiE3o= -go.opentelemetry.io/otel/sdk/metric v1.45.0/go.mod h1:vUWUxDZvu1WVRj8JA8S0AdhsPrZoDpA2DdZauIh4mDA= -go.opentelemetry.io/otel/trace v1.45.0 h1:l/mP6Uv7oNO7/TblbhpbgMidxhq1uO/rPsikOyVhxag= -go.opentelemetry.io/otel/trace v1.45.0/go.mod h1:qoJJA2xNMnxRrdISU/kLtfUH2wNeQbiv+jhs/CxI8bc= +go.opentelemetry.io/otel/metric v1.46.0 h1:yBnkXvgV7AXFILZc5K6IZe/CBFF3OS7BJ8ov6/lj0K8= +go.opentelemetry.io/otel/metric v1.46.0/go.mod h1:iPmdWqifKUdzziPkvvzIJXITl56fQx2mGM/DHLB3/2o= +go.opentelemetry.io/otel/metric/x v0.68.0 h1:TA/cBT23D3MnxYPwHL7YFOdYGdx0A0v+s7Mzotpd1dU= +go.opentelemetry.io/otel/metric/x v0.68.0/go.mod h1:agudOmvWhwUTjgibWDzxD2PoWYnpw5Ht5jISYOD2Hd4= +go.opentelemetry.io/otel/sdk v1.46.0 h1:h5CNQQjEbuQXY/JfZtgt3i7HVFV3aHPO2OAwO2eTYPI= +go.opentelemetry.io/otel/sdk v1.46.0/go.mod h1:GAERFXFt5SYCEB+YiKUbMBeza6UaDH7GmGOZEfh2gSM= +go.opentelemetry.io/otel/sdk/metric v1.46.0 h1:0piZ26EG4RBfebb2jhDH6ERCYHoVWduc3kLgPCwSnSE= +go.opentelemetry.io/otel/sdk/metric v1.46.0/go.mod h1:I1PbKrdVc8Qu8HYVDNtqVIwLwjNrhsV/uFuxfwg8mO4= +go.opentelemetry.io/otel/trace v1.46.0 h1:OULy7ccdJnZtJ0UDYFOIGaCmiWzJ8Vi2G/Rsu60qs1c= +go.opentelemetry.io/otel/trace v1.46.0/go.mod h1:J7GAXweO77XSFkB/rmAqk9D6ihszhFjLU+d9WuUxDLI= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= -go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= +go.yaml.in/yaml/v3 v3.0.5 h1:N6y/pJk8buWs9NY5ERU2HSMfm+IuD/OtfdAnq6kESPw= +go.yaml.in/yaml/v3 v3.0.5/go.mod h1:HVTZu1O7/Vkt2N+BFy8Zza+lnLsABggaTM2ZpNIGuKg= golang.org/x/crypto v0.54.0 h1:YLIA59K4fiNzHzjnZt2tUJQjQtUWfWbeHBqKtk3eScw= golang.org/x/crypto v0.54.0/go.mod h1:KWL8ny2AZdGR2cWmzeHrp2azQPGogOv+HeQaVEXC2dk= golang.org/x/mod v0.38.0 h1:MECBjubtXD7yj4HrhIUcywNaGeNVUdfVnxmPajOk4yk= @@ -450,8 +451,6 @@ gopkg.in/nullstone-io/go-api-client.v0 v0.0.0-20260716142317-86afc1414450/go.mod gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q= gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA= k8s.io/api v0.36.1 h1:XbL/EMj8K2aJpJtePmqUyQMsM0D4QI2pvl7YKJ20FTY= From cfb8d54f4497d38bead480ea2e76580e3872cd45 Mon Sep 17 00:00:00 2001 From: Brad Sickles Date: Fri, 18 Sep 2026 09:23:36 -0400 Subject: [PATCH 3/4] docs: add AGENTS.md with release instructions --- AGENTS.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..b46b593 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,20 @@ +# deployment-sdk — agent guide + +## Releasing + +This module is a library. It has no version tags, GitHub releases, or deploy pipeline. +Consumers pin it by Go pseudo-version (commit sha) in their `go.mod`, so a change is +"released" when it lands on `master` through a reviewed PR and each consumer bumps to that +commit: + +``` +GOFLAGS=-mod=mod go get github.com/nullstone-io/deployment-sdk@ +go mod tidy +go mod vendor +``` + +Consumers: `nullstone` (CLI), `enigma`, `devtools`. + +Resolve the sha from git (`git rev-parse origin/master`), never with `@latest`: the Go module +proxy caches versions forever, so `@latest` can return a commit that is no longer on the +branch. Never commit directly to `master`. From d9803aa32103dc1cb2c244f7da44402ffd9f45a7 Mon Sep 17 00:00:00 2001 From: Brad Sickles Date: Fri, 18 Sep 2026 09:36:28 -0400 Subject: [PATCH 4/4] test(docker): sniff the client scheme on the wire TestClientOptionsScheme inferred http vs https from the ping error text, which only worked on Windows. On Linux the moby client collapses "connection refused" into "Cannot connect to the Docker daemon at tcp://..." and drops the URL, so the https cases have failed on every CI run since the test was added. Point each case at a local listener that reads the first byte and hangs up: a TLS handshake starts with record type 0x16, plaintext HTTP with an ASCII method. --- docker/docker_cli_test.go | 87 +++++++++++++++++++++++++++++++++------ 1 file changed, 74 insertions(+), 13 deletions(-) diff --git a/docker/docker_cli_test.go b/docker/docker_cli_test.go index f865e97..67ab956 100644 --- a/docker/docker_cli_test.go +++ b/docker/docker_cli_test.go @@ -9,7 +9,9 @@ import ( "crypto/x509" "crypto/x509/pkix" "encoding/pem" + "io" "math/big" + "net" "net/http" "net/http/httptest" "os" @@ -148,45 +150,104 @@ func TestClientOptionsScheme(t *testing.T) { }{ { name: "plain tcp stays http", - endpoint: Endpoint{Host: "tcp://127.0.0.1:2375"}, + endpoint: Endpoint{}, want: "http", }, { name: "tls material promotes to https", - endpoint: Endpoint{Host: "tcp://127.0.0.1:2376", CAFile: writeUnrelatedCA(t)}, + endpoint: Endpoint{CAFile: writeUnrelatedCA(t)}, want: "https", }, { name: "skip-tls-verify promotes to https", - endpoint: Endpoint{Host: "tcp://127.0.0.1:2376", SkipTLSVerify: true}, + endpoint: Endpoint{SkipTLSVerify: true}, want: "https", }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { + sniffer := newSchemeSniffer(t) + test.endpoint.Host = sniffer.host opts, err := clientOptions(test.endpoint) require.NoError(t, err) api, err := client.New(opts...) require.NoError(t, err) defer api.Close() - assert.Equal(t, test.want, schemeOf(t, api)) + // The sniffer closes the connection after the first byte, so the ping always + // fails; only the bytes that reached the wire matter. + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + _, _ = api.Ping(ctx, client.PingOptions{}) + + assert.Equal(t, test.want, sniffer.scheme(t)) }) } } -// schemeOf reports whether the client will talk http or https. The client does not -// expose its scheme, so we read it off the daemon host it reports. -func schemeOf(t *testing.T, api *client.Client) string { +// schemeSniffer reports whether a client talks http or https by looking at the first +// byte it sends. The client does not expose its scheme, and the ping error is no good +// as a signal: on Linux the moby client collapses "connection refused" into a generic +// "Cannot connect to the Docker daemon" message that drops the URL entirely. +// +// A TLS handshake always begins with a record of type 0x16; a plaintext HTTP request +// begins with an ASCII method. +type schemeSniffer struct { + host string + result chan string +} + +func newSchemeSniffer(t *testing.T) *schemeSniffer { + t.Helper() + ln, err := net.Listen("tcp", "127.0.0.1:0") + require.NoError(t, err) + t.Cleanup(func() { _ = ln.Close() }) + + s := &schemeSniffer{ + host: "tcp://" + ln.Addr().String(), + result: make(chan string, 1), + } + go func() { + for { + conn, err := ln.Accept() + if err != nil { + return + } + s.sniff(conn) + } + }() + return s +} + +// sniff reads one byte, classifies it, and hangs up. Only the first connection is +// reported; any later ones (client retries) are closed without a reading. +func (s *schemeSniffer) sniff(conn net.Conn) { + defer conn.Close() + _ = conn.SetReadDeadline(time.Now().Add(5 * time.Second)) + first := make([]byte, 1) + if _, err := io.ReadFull(conn, first); err != nil { + return + } + scheme := "http" + if first[0] == 0x16 { + scheme = "https" + } + select { + case s.result <- scheme: + default: + } +} + +func (s *schemeSniffer) scheme(t *testing.T) string { t.Helper() - // Ping against a closed port surfaces the scheme in the error string. - _, err := api.Ping(context.Background(), client.PingOptions{}) - require.Error(t, err) - if strings.Contains(err.Error(), "https://") { - return "https" + select { + case scheme := <-s.result: + return scheme + case <-time.After(5 * time.Second): + t.Fatal("client never sent a byte to the sniffer") + return "" } - return "http" } // writeUnrelatedCA generates a self-signed CA that has signed nothing. Note that we