Skip to content

Commit 2fb92b6

Browse files
authored
fix(rds): render ModifyDBCluster fields in DescribeDBClusters (#1797)
2 parents 8eb5dc5 + 3c444ea commit 2fb92b6

2 files changed

Lines changed: 107 additions & 0 deletions

File tree

crates/fakecloud-rds/src/extras/tests.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,46 @@ fn modify_db_cluster_persists_extended_fields() {
10761076
assert_eq!(logs, vec!["audit", "general"]);
10771077
}
10781078

1079+
#[test]
1080+
fn describe_db_clusters_renders_modified_fields() {
1081+
// ModifyDBCluster persisted these, but the DescribeDBClusters renderer
1082+
// omitted them, so a describe echoed the create-time defaults
1083+
// (bug-audit 2026-06-20, 1.17).
1084+
let svc = svc();
1085+
create_cluster(&svc, "c1");
1086+
svc.handle_extra_action(&req(
1087+
"ModifyDBCluster",
1088+
&[
1089+
("DBClusterIdentifier", "c1"),
1090+
("StorageType", "io1"),
1091+
("Iops", "3000"),
1092+
("BacktrackWindow", "86400"),
1093+
("EnableIAMDatabaseAuthentication", "true"),
1094+
("ServerlessV2ScalingConfiguration.MinCapacity", "0.5"),
1095+
("ServerlessV2ScalingConfiguration.MaxCapacity", "8.0"),
1096+
],
1097+
))
1098+
.expect("ModifyDBCluster");
1099+
1100+
let resp = svc
1101+
.handle_extra_action(&req("DescribeDBClusters", &[]))
1102+
.expect("DescribeDBClusters");
1103+
let xml = String::from_utf8(resp.body.expect_bytes().to_vec()).unwrap();
1104+
assert!(xml.contains("<StorageType>io1</StorageType>"), "{xml}");
1105+
assert!(xml.contains("<Iops>3000</Iops>"), "{xml}");
1106+
assert!(
1107+
xml.contains("<BacktrackWindow>86400</BacktrackWindow>"),
1108+
"{xml}"
1109+
);
1110+
assert!(
1111+
xml.contains("<IAMDatabaseAuthenticationEnabled>true</IAMDatabaseAuthenticationEnabled>"),
1112+
"{xml}"
1113+
);
1114+
assert!(xml.contains("<ServerlessV2ScalingConfiguration>"), "{xml}");
1115+
assert!(xml.contains("<MinCapacity>0.5</MinCapacity>"), "{xml}");
1116+
assert!(xml.contains("<MaxCapacity>8.0</MaxCapacity>"), "{xml}");
1117+
}
1118+
10791119
#[test]
10801120
fn failover_db_cluster_picks_replica_when_no_target() {
10811121
let svc = svc();

crates/fakecloud-rds/src/extras/xml_renderers.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,73 @@ pub(super) fn db_cluster_member_xml(v: &Value) -> String {
194194
}
195195
out.push_str(" </DBClusterMembers>\n");
196196
}
197+
198+
// Scalar fields ModifyDBCluster (and CreateDBCluster) persist that the
199+
// hand-written renderer above omitted, so DescribeDBClusters reflects a
200+
// modify instead of always echoing the create-time defaults (bug-audit
201+
// 2026-06-20, 1.17). Keys already rendered above are deliberately excluded.
202+
for key in [
203+
"StorageType",
204+
"DBClusterInstanceClass",
205+
"EngineMode",
206+
"NetworkType",
207+
"MonitoringRoleArn",
208+
"PerformanceInsightsKMSKeyId",
209+
"Domain",
210+
"DomainIAMRoleName",
211+
"CACertificateIdentifier",
212+
"MasterUserSecretKmsKeyId",
213+
"AwsBackupRecoveryPointArn",
214+
"GlobalWriteForwardingStatus",
215+
"LocalWriteForwardingStatus",
216+
] {
217+
if let Some(s) = v[key].as_str() {
218+
out.push_str(&format!(" <{key}>{}</{key}>\n", xml_escape(s)));
219+
}
220+
}
221+
for key in [
222+
"Iops",
223+
"BacktrackWindow",
224+
"MonitoringInterval",
225+
"PerformanceInsightsRetentionPeriod",
226+
] {
227+
if let Some(n) = v[key].as_i64() {
228+
out.push_str(&format!(" <{key}>{n}</{key}>\n"));
229+
}
230+
}
231+
for key in [
232+
"IAMDatabaseAuthenticationEnabled",
233+
"CopyTagsToSnapshot",
234+
"AutoMinorVersionUpgrade",
235+
"HttpEndpointEnabled",
236+
"PerformanceInsightsEnabled",
237+
"ManageMasterUserPassword",
238+
] {
239+
if let Some(b) = v[key].as_bool() {
240+
out.push_str(&format!(" <{key}>{b}</{key}>\n"));
241+
}
242+
}
243+
// ServerlessV2ScalingConfiguration is stored as flattened
244+
// `ServerlessV2ScalingConfiguration.{Min,Max}Capacity` keys; render it back
245+
// as the nested element AWS returns.
246+
let v2_min = v["ServerlessV2ScalingConfiguration.MinCapacity"].as_str();
247+
let v2_max = v["ServerlessV2ScalingConfiguration.MaxCapacity"].as_str();
248+
if v2_min.is_some() || v2_max.is_some() {
249+
out.push_str(" <ServerlessV2ScalingConfiguration>\n");
250+
if let Some(m) = v2_min {
251+
out.push_str(&format!(
252+
" <MinCapacity>{}</MinCapacity>\n",
253+
xml_escape(m)
254+
));
255+
}
256+
if let Some(m) = v2_max {
257+
out.push_str(&format!(
258+
" <MaxCapacity>{}</MaxCapacity>\n",
259+
xml_escape(m)
260+
));
261+
}
262+
out.push_str(" </ServerlessV2ScalingConfiguration>\n");
263+
}
197264
out
198265
}
199266

0 commit comments

Comments
 (0)