Skip to content

Commit 155858f

Browse files
committed
test: add unit tests
1 parent 6f188de commit 155858f

5 files changed

Lines changed: 181 additions & 0 deletions

File tree

rust/operator-binary/src/controller/build/properties/config_json.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,4 +224,31 @@ mod tests {
224224
// Role-group-level addition is applied on top.
225225
assert_eq!(config["labels"]["rolegroup"], "default");
226226
}
227+
228+
#[test]
229+
fn decision_logs_follow_decision_logger_level() {
230+
// Decision logging is enabled when the `decision` logger is set above `NONE`.
231+
let enabled = config_json_for(json!({
232+
"image": { "productVersion": "1.2.3" },
233+
"servers": {
234+
"config": { "logging": { "containers": {
235+
"opa": { "loggers": { "decision": { "level": "INFO" } } }
236+
} } },
237+
"roleGroups": { "default": {} },
238+
},
239+
}));
240+
assert_eq!(enabled["decision_logs"]["console"], true);
241+
242+
// An explicit `NONE` level keeps decision logging disabled (field omitted).
243+
let disabled = config_json_for(json!({
244+
"image": { "productVersion": "1.2.3" },
245+
"servers": {
246+
"config": { "logging": { "containers": {
247+
"opa": { "loggers": { "decision": { "level": "NONE" } } }
248+
} } },
249+
"roleGroups": { "default": {} },
250+
},
251+
}));
252+
assert!(disabled.get("decision_logs").is_none_or(Value::is_null));
253+
}
227254
}

rust/operator-binary/src/controller/build/properties/product_logging/mod.rs

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,4 +47,21 @@ mod tests {
4747
assert!(content.contains("files_opa_json"));
4848
assert!(content.contains("files_tracing_rs"));
4949
}
50+
51+
#[test]
52+
fn bundle_builder_log_level_maps_and_renders_uppercase() {
53+
// The sidecar only understands these five levels, so FATAL and NONE collapse onto ERROR.
54+
let cases = [
55+
(LogLevel::TRACE, "TRACE"),
56+
(LogLevel::DEBUG, "DEBUG"),
57+
(LogLevel::INFO, "INFO"),
58+
(LogLevel::WARN, "WARN"),
59+
(LogLevel::ERROR, "ERROR"),
60+
(LogLevel::FATAL, "ERROR"),
61+
(LogLevel::NONE, "ERROR"),
62+
];
63+
for (level, expected) in cases {
64+
assert_eq!(BundleBuilderLogLevel::from(level).to_string(), expected);
65+
}
66+
}
5067
}

rust/operator-binary/src/controller/build/resource/config_map.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,38 @@ mod tests {
132132
assert!(data.contains_key("config.json"));
133133
assert!(data.contains_key("user-info-fetcher.json"));
134134
}
135+
136+
#[test]
137+
fn renders_vector_yaml_when_agent_enabled() {
138+
let cm = build_config_map(json!({
139+
"image": { "productVersion": "1.2.3" },
140+
"clusterConfig": { "vectorAggregatorConfigMapName": "vector-aggregator-discovery" },
141+
"servers": {
142+
"config": { "logging": { "enableVectorAgent": true } },
143+
"roleGroups": { "default": {} },
144+
},
145+
}));
146+
147+
assert!(
148+
cm.data
149+
.as_ref()
150+
.expect("config map data")
151+
.contains_key(VECTOR_CONFIG_FILE)
152+
);
153+
}
154+
155+
#[test]
156+
fn omits_vector_yaml_when_agent_disabled() {
157+
let cm = build_config_map(json!({
158+
"image": { "productVersion": "1.2.3" },
159+
"servers": { "roleGroups": { "default": {} } },
160+
}));
161+
162+
assert!(
163+
!cm.data
164+
.as_ref()
165+
.expect("config map data")
166+
.contains_key(VECTOR_CONFIG_FILE)
167+
);
168+
}
135169
}

rust/operator-binary/src/controller/build/resource/daemonset.rs

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,4 +1048,87 @@ mod tests {
10481048

10491049
assert!(volume_names(&ds).contains(&"tls".to_owned()));
10501050
}
1051+
1052+
#[test]
1053+
fn opa_container_serves_https_when_tls_enabled() {
1054+
let ds = build(&validated_cluster_from_spec(json!({
1055+
"image": { "productVersion": "1.2.3" },
1056+
"clusterConfig": { "tls": { "serverSecretClass": "tls" } },
1057+
"servers": { "roleGroups": { "default": {} } },
1058+
})));
1059+
let pod_spec = ds.spec.as_ref().unwrap().template.spec.as_ref().unwrap();
1060+
let opa = pod_spec
1061+
.containers
1062+
.iter()
1063+
.find(|c| c.name == "opa")
1064+
.expect("opa container should exist");
1065+
1066+
// The single container port is the HTTPS data port.
1067+
let ports = opa.ports.as_ref().unwrap();
1068+
assert_eq!(ports.len(), 1);
1069+
assert_eq!(ports[0].name.as_deref(), Some("https"));
1070+
assert_eq!(ports[0].container_port, 8443);
1071+
1072+
// The probe must speak HTTPS, otherwise it would fail against the TLS-only server.
1073+
let scheme = opa
1074+
.liveness_probe
1075+
.as_ref()
1076+
.unwrap()
1077+
.http_get
1078+
.as_ref()
1079+
.unwrap()
1080+
.scheme
1081+
.clone();
1082+
assert_eq!(scheme.as_deref(), Some("HTTPS"));
1083+
1084+
// The start command binds the HTTPS port and passes the TLS cert/key flags.
1085+
let args = opa.args.as_ref().unwrap();
1086+
assert!(args[0].contains("-a 0.0.0.0:8443"));
1087+
assert!(args[0].contains("--tls-cert-file"));
1088+
}
1089+
1090+
#[test]
1091+
fn bundle_builder_start_command_silences_console_only_when_none() {
1092+
let role_group_config = |spec: serde_json::Value| {
1093+
let cluster = validated_cluster_from_spec(spec);
1094+
cluster.role_group_configs[&OpaRole::Server]
1095+
.values()
1096+
.next()
1097+
.expect("the default role group should exist")
1098+
.config
1099+
.clone()
1100+
};
1101+
1102+
// Console level NONE redirects bundle-builder output to /dev/null (no `tee`).
1103+
let silenced = role_group_config(json!({
1104+
"image": { "productVersion": "1.2.3" },
1105+
"servers": {
1106+
"config": { "logging": { "containers": {
1107+
"bundle-builder": { "console": { "level": "NONE" } }
1108+
} } },
1109+
"roleGroups": { "default": {} },
1110+
},
1111+
}));
1112+
// The redirect is appended directly after the bundle-builder invocation. (`/dev/null` also
1113+
// appears in the shared bash trap helpers, so match the specific redirect.)
1114+
assert!(
1115+
build_bundle_builder_start_command(&silenced, "bundle-builder")
1116+
.contains("stackable-opa-bundle-builder > /dev/null")
1117+
);
1118+
1119+
// With a console level above NONE, output is not discarded.
1120+
let logging = role_group_config(json!({
1121+
"image": { "productVersion": "1.2.3" },
1122+
"servers": {
1123+
"config": { "logging": { "containers": {
1124+
"bundle-builder": { "console": { "level": "INFO" } }
1125+
} } },
1126+
"roleGroups": { "default": {} },
1127+
},
1128+
}));
1129+
assert!(
1130+
build_bundle_builder_start_command(&logging, "bundle-builder")
1131+
.contains("stackable-opa-bundle-builder &")
1132+
);
1133+
}
10511134
}

rust/operator-binary/src/controller/build/resource/service.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,4 +292,24 @@ mod tests {
292292
Some("8081")
293293
);
294294
}
295+
296+
#[test]
297+
fn metrics_service_uses_https_scheme_and_port_with_tls() {
298+
let cluster = cluster(true);
299+
let rg = default_role_group(&cluster);
300+
let service = build_rolegroup_metrics_service(&cluster, &rg);
301+
302+
// The metrics endpoint follows the data port, so it serves on the HTTPS port over `https`.
303+
assert_eq!(single_port(&service), ("metrics".to_owned(), 8443));
304+
305+
let annotations = service.metadata.annotations.unwrap();
306+
assert_eq!(
307+
annotations.get("prometheus.io/scheme").map(String::as_str),
308+
Some("https")
309+
);
310+
assert_eq!(
311+
annotations.get("prometheus.io/port").map(String::as_str),
312+
Some("8443")
313+
);
314+
}
295315
}

0 commit comments

Comments
 (0)