Skip to content

Commit 949738a

Browse files
Merge pull request #234 from numtide/code-coverage
test: increase coverage across all modules
2 parents c64e5a5 + ffb827f commit 949738a

File tree

7 files changed

+845
-1
lines changed

7 files changed

+845
-1
lines changed
Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
/*
2+
Copyright 2025.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1alpha1
18+
19+
import (
20+
"testing"
21+
22+
corev1 "k8s.io/api/core/v1"
23+
)
24+
25+
func TestBuildOTELEnvVars(t *testing.T) {
26+
// Clear all OTEL env vars so host environment doesn't interfere.
27+
otelEnvVars := []string{
28+
"OTEL_EXPORTER_OTLP_ENDPOINT",
29+
"OTEL_EXPORTER_OTLP_PROTOCOL",
30+
"OTEL_TRACES_EXPORTER",
31+
"OTEL_METRICS_EXPORTER",
32+
"OTEL_LOGS_EXPORTER",
33+
"OTEL_METRIC_EXPORT_INTERVAL",
34+
"OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE",
35+
"OTEL_TRACES_SAMPLER",
36+
}
37+
for _, env := range otelEnvVars {
38+
t.Setenv(env, "")
39+
}
40+
41+
tests := map[string]struct {
42+
cfg *ObservabilityConfig
43+
want []corev1.EnvVar
44+
}{
45+
"nil config returns nil": {
46+
cfg: nil,
47+
want: nil,
48+
},
49+
"empty config returns nil": {
50+
cfg: &ObservabilityConfig{},
51+
want: nil,
52+
},
53+
"disabled endpoint returns nil": {
54+
cfg: &ObservabilityConfig{OTLPEndpoint: "disabled"},
55+
want: nil,
56+
},
57+
"endpoint only": {
58+
cfg: &ObservabilityConfig{
59+
OTLPEndpoint: "http://tempo:4318",
60+
},
61+
want: []corev1.EnvVar{
62+
{Name: "OTEL_EXPORTER_OTLP_ENDPOINT", Value: "http://tempo:4318"},
63+
},
64+
},
65+
"all fields populated": {
66+
cfg: &ObservabilityConfig{
67+
OTLPEndpoint: "http://tempo:4318",
68+
OTLPProtocol: "grpc",
69+
TracesExporter: "otlp",
70+
MetricsExporter: "otlp",
71+
LogsExporter: "otlp",
72+
MetricExportInterval: "30s",
73+
MetricsTemporality: "cumulative",
74+
TracesSampler: "always_on",
75+
},
76+
want: []corev1.EnvVar{
77+
{Name: "OTEL_EXPORTER_OTLP_ENDPOINT", Value: "http://tempo:4318"},
78+
{Name: "OTEL_EXPORTER_OTLP_PROTOCOL", Value: "grpc"},
79+
{Name: "OTEL_TRACES_EXPORTER", Value: "otlp"},
80+
{Name: "OTEL_METRICS_EXPORTER", Value: "otlp"},
81+
{Name: "OTEL_LOGS_EXPORTER", Value: "otlp"},
82+
{Name: "OTEL_METRIC_EXPORT_INTERVAL", Value: "30s"},
83+
{Name: "OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE", Value: "cumulative"},
84+
{Name: "OTEL_TRACES_SAMPLER", Value: "always_on"},
85+
},
86+
},
87+
}
88+
89+
for name, tc := range tests {
90+
t.Run(name, func(t *testing.T) {
91+
got := BuildOTELEnvVars(tc.cfg)
92+
if len(got) != len(tc.want) {
93+
t.Fatalf(
94+
"len(BuildOTELEnvVars()) = %d, want %d\n got: %v\n want: %v",
95+
len(got),
96+
len(tc.want),
97+
got,
98+
tc.want,
99+
)
100+
}
101+
for i := range got {
102+
if got[i].Name != tc.want[i].Name || got[i].Value != tc.want[i].Value {
103+
t.Errorf("env[%d] = {%q, %q}, want {%q, %q}",
104+
i, got[i].Name, got[i].Value, tc.want[i].Name, tc.want[i].Value)
105+
}
106+
}
107+
})
108+
}
109+
}
110+
111+
func TestBuildOTELEnvVars_FallbackToEnv(t *testing.T) {
112+
t.Setenv("OTEL_EXPORTER_OTLP_ENDPOINT", "http://from-env:4318")
113+
t.Setenv("OTEL_EXPORTER_OTLP_PROTOCOL", "http/protobuf")
114+
115+
// nil config should fall back to env vars.
116+
got := BuildOTELEnvVars(nil)
117+
if len(got) < 2 {
118+
t.Fatalf("expected at least 2 env vars from fallback, got %d: %v", len(got), got)
119+
}
120+
if got[0].Value != "http://from-env:4318" {
121+
t.Errorf("endpoint = %q, want %q", got[0].Value, "http://from-env:4318")
122+
}
123+
if got[1].Value != "http/protobuf" {
124+
t.Errorf("protocol = %q, want %q", got[1].Value, "http/protobuf")
125+
}
126+
}
127+
128+
func TestBuildOTELEnvVars_CRDOverridesEnv(t *testing.T) {
129+
t.Setenv("OTEL_EXPORTER_OTLP_ENDPOINT", "http://from-env:4318")
130+
131+
cfg := &ObservabilityConfig{
132+
OTLPEndpoint: "http://from-crd:4318",
133+
}
134+
got := BuildOTELEnvVars(cfg)
135+
if len(got) == 0 {
136+
t.Fatal("expected at least 1 env var")
137+
}
138+
if got[0].Value != "http://from-crd:4318" {
139+
t.Errorf("endpoint = %q, want CRD value %q", got[0].Value, "http://from-crd:4318")
140+
}
141+
}
142+
143+
func TestEnvOrCRD(t *testing.T) {
144+
tests := map[string]struct {
145+
cfg *ObservabilityConfig
146+
envVal string
147+
crdVal string
148+
want string
149+
}{
150+
"nil config with env": {
151+
cfg: nil,
152+
envVal: "from-env",
153+
want: "from-env",
154+
},
155+
"nil config without env": {
156+
cfg: nil,
157+
want: "",
158+
},
159+
"config with value": {
160+
cfg: &ObservabilityConfig{OTLPEndpoint: "from-crd"},
161+
crdVal: "from-crd",
162+
want: "from-crd",
163+
},
164+
"config with empty value falls back to env": {
165+
cfg: &ObservabilityConfig{},
166+
envVal: "from-env",
167+
want: "from-env",
168+
},
169+
}
170+
171+
for name, tc := range tests {
172+
t.Run(name, func(t *testing.T) {
173+
t.Setenv("TEST_ENVORCRD", tc.envVal)
174+
got := envOrCRD(
175+
tc.cfg,
176+
func(c *ObservabilityConfig) string { return c.OTLPEndpoint },
177+
"TEST_ENVORCRD",
178+
)
179+
if got != tc.want {
180+
t.Errorf("envOrCRD() = %q, want %q", got, tc.want)
181+
}
182+
})
183+
}
184+
}

0 commit comments

Comments
 (0)