@@ -6,41 +6,124 @@ import (
66
77 "github.com/stretchr/testify/require"
88
9- "github.com/cortexproject/cortex/pkg/util/logical_plan "
9+ "github.com/cortexproject/cortex/pkg/distributed_execution "
1010)
1111
12+ // Tests fragmentation of logical plans, verifying that the fragments contain correct metadata.
13+ // Note: The number of fragments is determined by the distributed optimizer's strategy -
14+ // if the optimizer logic changes, this test will need to be updated accordingly.
1215func TestFragmenter (t * testing.T ) {
1316 type testCase struct {
14- name string
15- query string
16- start time.Time
17- end time.Time
18- expectedFragments int
17+ name string
18+ query string
19+ start time.Time
20+ end time.Time
21+ expectedFragmentsCnt int
22+ expectedFragments []Fragment
1923 }
2024
2125 now := time .Now ()
22-
23- // more tests will be added when distributed optimizer and fragmenter are implemented
2426 tests := []testCase {
2527 {
26- name : "simple logical query plan - no fragmentation" ,
27- query : "up" ,
28- start : now ,
29- end : now ,
30- expectedFragments : 1 ,
28+ name : "simple logical query plan - no fragmentation" ,
29+ query : "up" ,
30+ start : now ,
31+ end : now ,
32+ expectedFragmentsCnt : 1 ,
33+ },
34+ {
35+ name : "binary operation with aggregations" ,
36+ query : "sum(rate(node_cpu_seconds_total{mode!=\" idle\" }[5m])) + sum(rate(node_memory_Active_bytes[5m]))" ,
37+ start : now ,
38+ end : now ,
39+ expectedFragmentsCnt : 3 ,
40+ },
41+ {
42+ name : "multiple binary operation with aggregations" ,
43+ query : "sum(rate(http_requests_total{job=\" api\" }[5m])) + sum(rate(http_requests_total{job=\" web\" }[5m])) + sum(rate(http_requests_total{job=\" cache\" }[5m]))" ,
44+ start : now ,
45+ end : now ,
46+ expectedFragmentsCnt : 5 ,
47+ },
48+ {
49+ name : "multiple binary operation with aggregations" ,
50+ query : "sum(rate(http_requests_total{job=\" api\" }[5m])) + sum(rate(http_requests_total{job=\" web\" }[5m])) + sum(rate(http_requests_total{job=\" cache\" }[5m])) + sum(rate(http_requests_total{job=\" db\" }[5m]))" ,
51+ start : now ,
52+ end : now ,
53+ expectedFragmentsCnt : 7 ,
3154 },
3255 }
3356
3457 for _ , tc := range tests {
3558 t .Run (tc .name , func (t * testing.T ) {
36- lp , err := logical_plan .CreateTestLogicalPlan (tc .query , tc .start , tc .end , 0 )
59+ lp , err := distributed_execution .CreateTestLogicalPlan (tc .query , tc .start , tc .end , 0 )
3760 require .NoError (t , err )
3861
39- fragmenter := NewDummyFragmenter ()
40- res , err := fragmenter .Fragment ((* lp ).Root ())
62+ fragmenter := NewPlanFragmenter ()
63+ res , err := fragmenter .Fragment (uint64 ( 1 ), (* lp ).Root ())
4164
4265 require .NoError (t , err )
43- require .Equal (t , tc .expectedFragments , len (res ))
66+
67+ // first check the number of fragments
68+ require .Equal (t , tc .expectedFragmentsCnt , len (res ))
69+
70+ // check the fragments returned by comparing child IDs, ensuring correct hierarchy
71+ if len (res ) == 3 { // 3 fragment cases
72+ // current binary split:
73+ // (due to the design of the distributed optimizer)
74+ // 2
75+ // / \
76+ // 0 1
77+ require .Empty (t , res [0 ].ChildIDs )
78+ require .Empty (t , res [1 ].ChildIDs )
79+ require .Equal (t , []uint64 {res [0 ].FragmentID , res [1 ].FragmentID }, res [2 ].ChildIDs )
80+
81+ } else if len (res ) == 5 {
82+ // current binary split:
83+ // 4
84+ // / \
85+ // 2 3
86+ // / \
87+ // 0 1
88+ require .Empty (t , res [0 ].ChildIDs )
89+ require .Empty (t , res [1 ].ChildIDs )
90+ require .Empty (t , res [3 ].ChildIDs )
91+
92+ require .Containsf (t , res [2 ].ChildIDs , res [0 ].FragmentID , "child ID of fragment 0 not found in layer 2" )
93+ require .Containsf (t , res [2 ].ChildIDs , res [1 ].FragmentID , "child ID of fragment 1 not found in layer 2" )
94+ require .Equal (t , len (res [2 ].ChildIDs ), 2 ) // binary check
95+
96+ require .Containsf (t , res [4 ].ChildIDs , res [3 ].FragmentID , "child ID of fragment 3 not found in layer 3" )
97+ require .Containsf (t , res [4 ].ChildIDs , res [2 ].FragmentID , "child ID of fragment 4 not found in layer 3" )
98+ require .Equal (t , len (res [4 ].ChildIDs ), 2 ) // binary check
99+
100+ } else if len (res ) == 7 { // 7 fragment cases
101+ // current binary split:
102+ // 6
103+ // / \
104+ // 4 5
105+ // / \
106+ // 2 3
107+ // / \
108+ // 0 1
109+
110+ require .Empty (t , res [0 ].ChildIDs )
111+ require .Empty (t , res [1 ].ChildIDs )
112+ require .Empty (t , res [3 ].ChildIDs )
113+ require .Empty (t , res [5 ].ChildIDs )
114+
115+ require .Containsf (t , res [2 ].ChildIDs , res [0 ].FragmentID , "child ID of fragment 0 not found in layer 2" )
116+ require .Containsf (t , res [2 ].ChildIDs , res [1 ].FragmentID , "child ID of fragment 1 not found in layer 2" )
117+ require .Equal (t , len (res [2 ].ChildIDs ), 2 ) // binary check
118+
119+ require .Containsf (t , res [4 ].ChildIDs , res [3 ].FragmentID , "child ID of fragment 3 not found in layer 3" )
120+ require .Containsf (t , res [4 ].ChildIDs , res [2 ].FragmentID , "child ID of fragment 4 not found in layer 3" )
121+ require .Equal (t , len (res [4 ].ChildIDs ), 2 ) // binary check
122+
123+ require .Containsf (t , res [6 ].ChildIDs , res [4 ].FragmentID , "child ID of fragment 4 not found in layer 4" )
124+ require .Containsf (t , res [6 ].ChildIDs , res [5 ].FragmentID , "child ID of fragment 5 not found in layer 4" )
125+ require .Equal (t , len (res [6 ].ChildIDs ), 2 ) // binary check
126+ }
44127 })
45128 }
46129}
0 commit comments