Skip to content

Commit 1780735

Browse files
authored
Merge pull request #27 from projectsyn/feat/add-nodeinfo-test-cases
Add more nodes and classes in the test inventory
2 parents 66a2905 + dd64364 commit 1780735

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+989
-239
lines changed

src/inventory.rs

Lines changed: 78 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,21 @@ impl Inventory {
4848
.and_modify(|nodes: &mut Vec<String>| nodes.push(name.clone()))
4949
.or_insert(vec![name.clone()]);
5050
}
51+
// Ensure application and classes values are sorted. We need to consume the iterator,
52+
// but we don't care about the vec of unit types which results from calling sort on the
53+
// values_mut() elements, so we directly drop the resulting Vec.
54+
drop(
55+
inv.classes
56+
.values_mut()
57+
.map(|v| v.sort())
58+
.collect::<Vec<()>>(),
59+
);
60+
drop(
61+
inv.applications
62+
.values_mut()
63+
.map(|v| v.sort())
64+
.collect::<Vec<()>>(),
65+
);
5166
inv.nodes.insert(name.clone(), info);
5267
}
5368
Ok(inv)
@@ -87,7 +102,8 @@ mod inventory_tests {
87102
let r = Reclass::new(
88103
"./tests/inventory/nodes",
89104
"./tests/inventory/classes",
90-
false,
105+
// n18 includes a nonexistent class
106+
true,
91107
)
92108
.unwrap();
93109
let inv = Inventory::render(&r).unwrap();
@@ -96,34 +112,82 @@ mod inventory_tests {
96112
// have individual tests for each NodeInfo in `src/node`.
97113
let mut nodes = inv.nodes.keys().cloned().collect::<Vec<String>>();
98114
nodes.sort();
99-
assert_eq!(
100-
nodes,
101-
(1..=4).map(|n| format!("n{n}")).collect::<Vec<String>>()
102-
);
103115

104-
// applications should contain app[1-2]
116+
let mut expected_nodes = (1..=23).map(|n| format!("n{n}")).collect::<Vec<String>>();
117+
expected_nodes.sort();
118+
119+
assert_eq!(nodes, expected_nodes);
120+
121+
// applications should contain app[1-2], [a-d]
105122
let mut expected_applications = HashMap::<String, Vec<String>>::new();
106123
expected_applications.insert("app1".into(), vec!["n1".into()]);
107124
expected_applications.insert("app2".into(), vec!["n1".into()]);
125+
expected_applications.insert("a".into(), vec!["n12".into(), "n13".into()]);
126+
expected_applications.insert("b".into(), vec!["n13".into()]);
127+
expected_applications.insert("c".into(), vec!["n12".into()]);
128+
expected_applications.insert("d".into(), vec!["n13".into()]);
129+
108130
assert_eq!(inv.applications, expected_applications);
109131

110-
// classes should contain:
111-
// * cls[1-8]
112-
// * ${qux} -- interpolated as cls1 for n4, but both Python reclass and our implementation
113-
// have the uninterpolated class name in the classes list.
114-
// * nested.cls[1-2]
132+
// classes should match the hash map defined below.
133+
// Note that classes with parameter references are tracked unrendered and the rendered
134+
// variants aren't added to the classes list for the node. Here's the expected
135+
// rendered values:
136+
// * ${cls9} -- rendered as cls9 for n15
137+
// * ${qux} -- rendered as cls1 for n4
138+
// * ${tenant}.${cluster} -- rendered as foo.bar for n16
139+
// * \${baz} -- rendered as `${baz}` for n17
140+
// * cluster.${dist} -- rendered as cluster.foo for n19
141+
115142
let mut expected_classes = HashMap::<String, Vec<String>>::new();
143+
expected_classes.insert("${cls9}".into(), vec!["n15".into()]);
144+
expected_classes.insert("${qux}".into(), vec!["n4".into()]);
145+
expected_classes.insert("${tenant}.${cluster}".into(), vec!["n16".into()]);
146+
expected_classes.insert("\\${baz}".into(), vec!["n17".into()]);
147+
expected_classes.insert("app1".into(), vec!["n12".into()]);
148+
expected_classes.insert("app2".into(), vec!["n13".into()]);
116149
expected_classes.insert("cls1".into(), vec!["n1".into()]);
117150
expected_classes.insert("cls2".into(), vec!["n1".into()]);
118-
expected_classes.insert("nested.cls1".into(), vec!["n2".into()]);
119-
expected_classes.insert("nested.cls2".into(), vec!["n2".into()]);
120151
expected_classes.insert("cls3".into(), vec!["n3".into()]);
121152
expected_classes.insert("cls4".into(), vec!["n3".into()]);
122153
expected_classes.insert("cls5".into(), vec!["n3".into()]);
123154
expected_classes.insert("cls6".into(), vec!["n3".into()]);
124155
expected_classes.insert("cls7".into(), vec!["n4".into()]);
125156
expected_classes.insert("cls8".into(), vec!["n4".into()]);
126-
expected_classes.insert("${qux}".into(), vec!["n4".into()]);
157+
expected_classes.insert(
158+
"cls9".into(),
159+
vec![
160+
"n10".into(),
161+
"n12".into(),
162+
"n13".into(),
163+
"n14".into(),
164+
"n18".into(),
165+
"n5".into(),
166+
"n6".into(),
167+
"n7".into(),
168+
"n9".into(),
169+
],
170+
);
171+
expected_classes.insert("cls9_meta".into(), vec!["n15".into()]);
172+
expected_classes.insert("cls10".into(), vec!["n13".into(), "n5".into(), "n9".into()]);
173+
expected_classes.insert("cls11".into(), vec!["n6".into()]);
174+
expected_classes.insert("cls12".into(), vec!["n9".into()]);
175+
expected_classes.insert("cls13".into(), vec!["n14".into()]);
176+
expected_classes.insert("cls14".into(), vec!["n23".into()]);
177+
expected_classes.insert("cls15".into(), vec!["n23".into()]);
178+
expected_classes.insert("cluster.${dist}".into(), vec!["n19".into()]);
179+
expected_classes.insert("cluster.default".into(), vec!["n19".into()]);
180+
expected_classes.insert("cluster.facts".into(), vec!["n19".into()]);
181+
expected_classes.insert("cluster.global".into(), vec!["n19".into()]);
182+
expected_classes.insert("config".into(), vec!["n16".into()]);
183+
expected_classes.insert("foo-indirect".into(), vec!["n20".into()]);
184+
expected_classes.insert("nested.a".into(), vec!["n8".into()]);
185+
expected_classes.insert("nested.a_sub".into(), vec!["n8".into(), "n9".into()]);
186+
expected_classes.insert("nested.b".into(), vec!["n10".into()]);
187+
expected_classes.insert("nested.cls1".into(), vec!["n2".into()]);
188+
expected_classes.insert("nested.cls2".into(), vec!["n2".into()]);
189+
expected_classes.insert("nonexisting".into(), vec!["n18".into()]);
190+
expected_classes.insert("yaml-anchor".into(), vec!["n21".into()]);
127191

128192
assert_eq!(inv.classes, expected_classes);
129193
}

src/node/mod.rs

Lines changed: 17 additions & 183 deletions
Original file line numberDiff line numberDiff line change
@@ -299,20 +299,24 @@ impl Node {
299299
}
300300
}
301301

302+
#[cfg(test)]
303+
fn make_reclass() -> Reclass {
304+
Reclass::new(
305+
"./tests/inventory/nodes",
306+
"./tests/inventory/classes",
307+
false,
308+
)
309+
.unwrap()
310+
}
311+
302312
#[cfg(test)]
303313
mod node_tests {
304314
use super::*;
305-
use crate::types::Value;
306315
use std::str::FromStr;
307316

308317
#[test]
309318
fn test_parse() {
310-
let r = Reclass::new(
311-
"./tests/inventory/nodes",
312-
"./tests/inventory/classes",
313-
false,
314-
)
315-
.unwrap();
319+
let r = make_reclass();
316320
let n = Node::parse(&r, "n1").unwrap();
317321
assert_eq!(
318322
n.classes,
@@ -335,12 +339,7 @@ mod node_tests {
335339
#[test]
336340
#[should_panic(expected = "Unknown node n0")]
337341
fn test_parse_error() {
338-
let r = Reclass::new(
339-
"./tests/inventory/nodes",
340-
"./tests/inventory/classes",
341-
false,
342-
)
343-
.unwrap();
342+
let r = make_reclass();
344343
Node::parse(&r, "n0").unwrap();
345344
}
346345

@@ -528,12 +527,7 @@ mod node_tests {
528527

529528
#[test]
530529
fn test_read_class() {
531-
let r = Reclass::new(
532-
"./tests/inventory/nodes",
533-
"./tests/inventory/classes",
534-
false,
535-
)
536-
.unwrap();
530+
let r = make_reclass();
537531
let n = Node::parse(&r, "n1").unwrap();
538532
let c = n.read_class(&r, "cls1").unwrap().unwrap();
539533
let expected = r#"
@@ -548,12 +542,7 @@ mod node_tests {
548542

549543
#[test]
550544
fn test_read_class_relative() {
551-
let r = Reclass::new(
552-
"./tests/inventory/nodes",
553-
"./tests/inventory/classes",
554-
false,
555-
)
556-
.unwrap();
545+
let r = make_reclass();
557546
let n = Node::parse(&r, "n1").unwrap();
558547
let c1 = n.read_class(&r, "nested.cls1").unwrap().unwrap();
559548
let c2 = c1.read_class(&r, ".cls2").unwrap().unwrap();
@@ -564,162 +553,7 @@ mod node_tests {
564553
let expected = Mapping::from_str(expected).unwrap();
565554
assert_eq!(c2.parameters, expected);
566555
}
567-
568-
#[test]
569-
fn test_render_n1() {
570-
let r = Reclass::new(
571-
"./tests/inventory/nodes",
572-
"./tests/inventory/classes",
573-
false,
574-
)
575-
.unwrap();
576-
let mut n = Node::parse(&r, "n1").unwrap();
577-
assert_eq!(
578-
n.classes,
579-
UniqueList::from(vec!["cls1".to_owned(), "cls2".to_owned()])
580-
);
581-
assert_eq!(
582-
n.applications,
583-
RemovableList::from(vec!["app1".to_owned(), "app2".to_owned()])
584-
);
585-
586-
n.render(&r).unwrap();
587-
588-
let expected = r#"
589-
foo:
590-
foo: foo
591-
bar: cls2
592-
baz: cls1
593-
bar:
594-
foo: foo
595-
_reclass_:
596-
environment: base
597-
name:
598-
short: n1
599-
parts: ["n1"]
600-
full: n1
601-
path: n1
602-
"#;
603-
let mut expected: Value = Mapping::from_str(expected).unwrap().into();
604-
expected.render(&Mapping::new()).unwrap();
605-
let params: Value = n.parameters.into();
606-
607-
assert_eq!(params, expected);
608-
}
609-
610-
#[test]
611-
fn test_render_n2() {
612-
let r = Reclass::new(
613-
"./tests/inventory/nodes",
614-
"./tests/inventory/classes",
615-
false,
616-
)
617-
.unwrap();
618-
let mut n = Node::parse(&r, "n2").unwrap();
619-
assert_eq!(n.classes, UniqueList::from(vec!["nested.cls1".to_owned()]));
620-
assert_eq!(n.applications, RemovableList::from(vec![]));
621-
622-
n.render(&r).unwrap();
623-
624-
assert_eq!(
625-
n.classes,
626-
UniqueList::from(vec!["nested.cls2".to_owned(), "nested.cls1".to_owned()])
627-
);
628-
629-
let expected = r#"
630-
foo:
631-
foo: nested.cls1
632-
bar: n2
633-
bar: bar
634-
_reclass_:
635-
environment: base
636-
name:
637-
short: n2
638-
parts: ["n2"]
639-
full: n2
640-
path: n2
641-
"#;
642-
let mut expected: Value = Mapping::from_str(expected).unwrap().into();
643-
expected.render(&Mapping::new()).unwrap();
644-
let params: Value = n.parameters.into();
645-
646-
dbg!(&params);
647-
648-
assert_eq!(params, expected);
649-
}
650-
651-
#[test]
652-
fn test_render_n3() {
653-
let r = Reclass::new(
654-
"./tests/inventory/nodes",
655-
"./tests/inventory/classes",
656-
false,
657-
)
658-
.unwrap();
659-
let mut n = Node::parse(&r, "n3").unwrap();
660-
n.render(&r).unwrap();
661-
let params: Value = n.parameters.into();
662-
663-
let expected = r#"
664-
cluster:
665-
name: c-test-cluster-1234
666-
openshift:
667-
infraID: c-test-cluster-1234-xlk3f
668-
clusterID: 2888efd2-8a1b-4846-82ec-3a99506e2c70
669-
baseDomain: c-test-cluster-1234.example.org
670-
appsDomain: apps.c-test-cluster-1234.example.org
671-
apiURL: api.c-test-cluster-1234.example.org
672-
ssh_key: ""
673-
_reclass_:
674-
environment: base
675-
name:
676-
short: n3
677-
parts: ["n3"]
678-
full: n3
679-
path: n3
680-
"#;
681-
let mut expected: Value = Mapping::from_str(expected).unwrap().into();
682-
expected.render(&Mapping::new()).unwrap();
683-
684-
assert_eq!(params, expected);
685-
}
686-
687-
#[test]
688-
fn test_render_n4() {
689-
// Test case to cover class name with references
690-
let r = Reclass::new(
691-
"./tests/inventory/nodes",
692-
"./tests/inventory/classes",
693-
false,
694-
)
695-
.unwrap();
696-
697-
let mut n = Node::parse(&r, "n4").unwrap();
698-
n.render(&r).unwrap();
699-
assert_eq!(
700-
n.classes,
701-
UniqueList::from(vec!["cls8".into(), "${qux}".into(), "cls7".into()])
702-
);
703-
assert_eq!(n.applications, RemovableList::from(vec![]));
704-
705-
let params: Value = n.parameters.into();
706-
let expected = r#"
707-
foo:
708-
foo: cls1
709-
bar: cls1
710-
baz: cls1
711-
qux: cls1
712-
_reclass_:
713-
environment: base
714-
name:
715-
short: n4
716-
parts: ["n4"]
717-
full: n4
718-
path: n4
719-
"#;
720-
let mut expected: Value = Mapping::from_str(expected).unwrap().into();
721-
expected.render(&Mapping::new()).unwrap();
722-
723-
assert_eq!(params, expected);
724-
}
725556
}
557+
558+
#[cfg(test)]
559+
mod node_render_tests;

0 commit comments

Comments
 (0)