Skip to content

Commit dc2690e

Browse files
committed
Iceberg test fails openly instead of silently skipping
Per request: a skip-on-missing-env-vars path hides two failure modes that matter more than the test itself running on a given PR. 1. CI misconfiguration. A rotated secret, renamed bucket, or dropped env var renders as "missing env vars — skip". The job reports SUCCESS, nobody notices, and the test silently stops running on the iceberg lane until someone happens to look. 2. A real iceberg regression that lands during an env-var gap is invisible — it hides behind the same "skipped" line that a misconfigured lane produces. Replace t.Skipf with t.Fatalf. Diagnostic spells out the missing vars, explains why the test refuses to skip, and walks through the sandbox bucket setup. Empty env vars are treated as missing (a rotated CI secret often renders as empty rather than absent). Tradeoff worth noting: PR CI's k8s-integration-tests job will fail until the iceberg env vars are wired into every lane that runs the suite. If keeping default PR CI green matters more than uniform coverage, the follow-up is to split this test behind a build tag (`//go:build k8s_iceberg`) so it only compiles into a dedicated iceberg lane.
1 parent 0935927 commit dc2690e

1 file changed

Lines changed: 42 additions & 14 deletions

File tree

tests/k8s/iceberg_test.go

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,20 @@ import (
2424
// derived from the ARN's region and goes straight to AWS; no environment
2525
// flag overrides it.
2626
//
27-
// CI mechanics: the test is hard-gated on a persistent sandbox S3 Tables
28-
// bucket (the recommended setup — see below). Skips locally and in any
29-
// CI job that doesn't set DUCKGRES_K8S_ICEBERG_TABLE_BUCKET_ARN, so PR CI
30-
// stays fast and free; a dedicated job (nightly or "iceberg" lane) sets
31-
// the env vars and gets the real signal.
27+
// This test is INTENTIONALLY NOT SKIPPABLE. If the required env vars
28+
// aren't set in whatever CI lane runs the k8s integration suite, the
29+
// test fails openly with a clear diagnostic. A silent skip would hide
30+
// two failure modes that matter more than the test itself:
3231
//
33-
// Required env vars (test skips with a clear message when any is empty):
32+
// 1. CI misconfiguration — a secret rotates, an env var name changes,
33+
// the sandbox bucket gets renamed, and the test silently stops
34+
// running. With a skip, nobody notices until someone actively
35+
// looks at the test output; with a fatal, the next PR catches it.
36+
// 2. A real iceberg regression that happens to coincide with an
37+
// env-var gap — even worse, because the regression hides behind
38+
// the same "skipped — missing env vars" line.
39+
//
40+
// Required env vars (test fails the whole job when any is empty):
3441
//
3542
// DUCKGRES_K8S_ICEBERG_TABLE_BUCKET_ARN — arn:aws:s3tables:<region>:<acct>:bucket/<name>
3643
// DUCKGRES_K8S_ICEBERG_REGION — must match the ARN's region
@@ -57,10 +64,7 @@ import (
5764
// - DO NOT reuse a production bucket. The test creates and drops tables;
5865
// a leaked DROP would target whatever bucket the env var pointed at.
5966
func TestK8sIcebergRoundTrip(t *testing.T) {
60-
cfg, ok := loadIcebergTestConfigOrSkip(t)
61-
if !ok {
62-
return
63-
}
67+
cfg := loadIcebergTestConfig(t)
6468

6569
if err := seedIcebergTenantFixture(cfg); err != nil {
6670
t.Fatalf("seed iceberg tenant fixture: %v", err)
@@ -139,7 +143,16 @@ type icebergTestConfig struct {
139143
sessionToken string
140144
}
141145

142-
func loadIcebergTestConfigOrSkip(t *testing.T) (icebergTestConfig, bool) {
146+
// loadIcebergTestConfig reads the required env vars and fails the test
147+
// loudly if any are missing. There is no skip path — see the
148+
// TestK8sIcebergRoundTrip godoc for the rationale.
149+
//
150+
// Note that the env vars must be present *and non-empty*; an empty
151+
// value is treated as missing. This matters when CI passes secrets
152+
// through templated workflow files: a rotated-out secret typically
153+
// renders as empty rather than absent, and an empty value here would
154+
// silently fail the AWS call rather than the env check.
155+
func loadIcebergTestConfig(t *testing.T) icebergTestConfig {
143156
t.Helper()
144157
required := map[string]string{
145158
"DUCKGRES_K8S_ICEBERG_TABLE_BUCKET_ARN": os.Getenv("DUCKGRES_K8S_ICEBERG_TABLE_BUCKET_ARN"),
@@ -155,8 +168,23 @@ func loadIcebergTestConfigOrSkip(t *testing.T) (icebergTestConfig, bool) {
155168
}
156169
}
157170
if len(missing) > 0 {
158-
t.Skipf("real-AWS iceberg test skipped — missing env vars: %s. Set them in the iceberg CI lane against a sandbox S3 Tables bucket; see TestK8sIcebergRoundTrip godoc for setup.", strings.Join(missing, ", "))
159-
return icebergTestConfig{}, false
171+
t.Fatalf(`iceberg integration test cannot run — required env vars are unset or empty: %s.
172+
173+
This test is intentionally NOT skippable: a silent skip would hide CI
174+
misconfiguration (rotated secret, renamed bucket, dropped env var) and,
175+
worse, would mask any real iceberg regression that happened to land at
176+
the same time as the env-var gap.
177+
178+
To wire the iceberg CI lane:
179+
- provision a persistent sandbox S3 Tables bucket + companion data bucket
180+
in your sandbox AWS account
181+
- grant the CI IAM principal s3tables:* on the table bucket and
182+
s3:GetObject/PutObject on the data bucket
183+
- set all of the env vars above as CI secrets
184+
185+
See TestK8sIcebergRoundTrip godoc for the full setup notes. Until the
186+
iceberg lane is wired, this failure is the correct signal that work
187+
remains.`, strings.Join(missing, ", "))
160188
}
161189
ns := os.Getenv("DUCKGRES_K8S_ICEBERG_NAMESPACE")
162190
if ns == "" {
@@ -170,7 +198,7 @@ func loadIcebergTestConfigOrSkip(t *testing.T) (icebergTestConfig, bool) {
170198
accessKeyID: required["AWS_ACCESS_KEY_ID"],
171199
secretKey: required["AWS_SECRET_ACCESS_KEY"],
172200
sessionToken: os.Getenv("AWS_SESSION_TOKEN"),
173-
}, true
201+
}
174202
}
175203

176204
// seedIcebergTenantFixture installs everything the iceberg tenant needs:

0 commit comments

Comments
 (0)