@@ -84,6 +84,10 @@ func TestAstSuccess(t *testing.T) {
8484 rule : testdata .TestSuccessChildScriptMultipleInputs ,
8585 expectedNodeTypes : []string {"machine_set" , "script" , "machine_seq" , "log_seq" , "log_set" },
8686 },
87+ "Success_ChildScriptPromQLInput" : {
88+ rule : testdata .TestSuccessChildScriptPromQLInput ,
89+ expectedNodeTypes : []string {"machine_set" , "script" , "promql" },
90+ },
8791 }
8892
8993 for name , test := range tests {
@@ -104,6 +108,10 @@ func TestAstSuccess(t *testing.T) {
104108 t .Fatalf ("No nodes found in AST" )
105109 }
106110
111+ if err = validateTree (ast .Nodes [0 ]); err != nil {
112+ t .Fatalf ("Error validating tree: %v" , err )
113+ }
114+
107115 var actualNodes []string
108116 gatherNodeTypes (ast .Nodes [0 ], & actualNodes )
109117
@@ -273,3 +281,45 @@ func TestFailureExamples(t *testing.T) {
273281 }
274282 }
275283}
284+
285+ // Validate the following invariants on the tree:
286+ // 1. No duplicate addresses
287+ // 2. Root node has no parent address
288+ // 3. Node ids are unique
289+ // 4. Depth is consistent with distance from root
290+
291+ func validateTree (node * AstNodeT ) error {
292+ if node == nil {
293+ return fmt .Errorf ("Root node is nil" )
294+ }
295+
296+ if node .Metadata .ParentAddress != nil {
297+ return fmt .Errorf ("Root node has parent address: %s" , node .Metadata .ParentAddress .String ())
298+ }
299+
300+ return _validateTree (node , 0 , make (map [uint32 ]struct {})) // start at depth 0 for root
301+ }
302+
303+ func _validateTree (node * AstNodeT , depth uint32 , ids map [uint32 ]struct {}) error {
304+
305+ if node == nil {
306+ return nil
307+ }
308+
309+ if node .Metadata .Address .Depth != depth {
310+ return fmt .Errorf ("Node %s has depth %d, expected %d" , node .Metadata .Address .String (), node .Metadata .Address .Depth , depth )
311+ }
312+
313+ if _ , exists := ids [node .Metadata .Address .NodeId ]; exists {
314+ return fmt .Errorf ("Duplicate node ID %d found" , node .Metadata .Address .NodeId )
315+ }
316+ ids [node .Metadata .Address .NodeId ] = struct {}{}
317+
318+ for _ , child := range node .Children {
319+ if err := _validateTree (child , depth + 1 , ids ); err != nil {
320+ return err
321+ }
322+ }
323+
324+ return nil
325+ }
0 commit comments