master
go 160 lines 4.53 KB
Raw
1 // SPDX-License-Identifier: GPL-3.0-or-later
2
3 package chartengine
4
5 import (
6 "testing"
7
8 "github.com/netdata/netdata/go/plugins/plugin/framework/chartengine/internal/program"
9 "github.com/stretchr/testify/assert"
10 "github.com/stretchr/testify/require"
11 )
12
13 func TestPlannerLifecycleScenarios(t *testing.T) {
14 tests := map[string]struct {
15 run func(t *testing.T)
16 }{
17 "enforce lifecycle caps dimension cap evicts lru": {
18 run: runTestEnforceLifecycleCapsDimensionCapEvictsLRU,
19 },
20 "collect expiry removals dimension and chart expiry": {
21 run: runTestCollectExpiryRemovalsDimensionAndChartExpiry,
22 },
23 }
24
25 for name, tc := range tests {
26 t.Run(name, tc.run)
27 }
28 }
29
30 func runTestEnforceLifecycleCapsDimensionCapEvictsLRU(t *testing.T) {
31 tests := map[string]struct {
32 currentSeq uint64
33 }{
34 "dimension cap evicts least-recently-seen inactive dimension first": {
35 currentSeq: 10,
36 },
37 }
38
39 for name, tc := range tests {
40 t.Run(name, func(t *testing.T) {
41 meta := program.ChartMeta{Title: "Requests", Context: "requests", Units: "requests/s"}
42 lifecycle := program.LifecyclePolicy{
43 Dimensions: program.DimensionLifecyclePolicy{MaxDims: 2},
44 }
45
46 state := newMaterializedState()
47 matChart, created := state.ensureChart("chart_a", "tpl.requests", meta, lifecycle)
48 require.True(t, created)
49
50 oldA, created := matChart.ensureDimension("old_a", dimensionState{
51 algorithm: program.AlgorithmAbsolute,
52 multiplier: 1,
53 divisor: 1,
54 })
55 require.True(t, created)
56 oldA.lastSeenSuccessSeq = 1
57
58 oldB, created := matChart.ensureDimension("old_b", dimensionState{
59 algorithm: program.AlgorithmAbsolute,
60 multiplier: 1,
61 divisor: 1,
62 })
63 require.True(t, created)
64 oldB.lastSeenSuccessSeq = 2
65
66 chartsByID := map[string]*chartState{
67 "chart_a": {
68 templateID: "tpl.requests",
69 chartID: "chart_a",
70 meta: meta,
71 lifecycle: lifecycle,
72 currentBuildSeq: tc.currentSeq,
73 observedCount: 1,
74 entries: map[string]*dimBuildEntry{
75 "new_c": {
76 seenSeq: tc.currentSeq,
77 dimensionState: dimensionState{
78 static: false,
79 order: 0,
80 algorithm: program.AlgorithmAbsolute,
81 multiplier: 1,
82 divisor: 1,
83 },
84 },
85 },
86 },
87 }
88
89 removeDims, removeCharts := enforceLifecycleCaps(tc.currentSeq, chartsByID, &state)
90
91 assert.Empty(t, removeCharts)
92 require.Len(t, removeDims, 1)
93 assert.Equal(t, "chart_a", removeDims[0].ChartID)
94 assert.Equal(t, "old_a", removeDims[0].Name)
95
96 assert.NotContains(t, matChart.dimensions, "old_a")
97 assert.Contains(t, matChart.dimensions, "old_b")
98 assert.Contains(t, chartsByID["chart_a"].entries, "new_c")
99 })
100 }
101 }
102
103 func runTestCollectExpiryRemovalsDimensionAndChartExpiry(t *testing.T) {
104 tests := map[string]struct {
105 currentSeq uint64
106 }{
107 "stale chart and stale dimension are removed in one pass": {
108 currentSeq: 5,
109 },
110 }
111
112 for name, tc := range tests {
113 t.Run(name, func(t *testing.T) {
114 state := newMaterializedState()
115
116 expiredMeta := program.ChartMeta{Title: "Expired", Context: "expired"}
117 expiredChart, created := state.ensureChart("chart_expired", "tpl.expired", expiredMeta, program.LifecyclePolicy{
118 ExpireAfterCycles: 2,
119 })
120 require.True(t, created)
121 expiredChart.lastSeenSuccessSeq = 3
122
123 liveMeta := program.ChartMeta{Title: "Live", Context: "live"}
124 liveChart, created := state.ensureChart("chart_live", "tpl.live", liveMeta, program.LifecyclePolicy{
125 Dimensions: program.DimensionLifecyclePolicy{ExpireAfterCycles: 2},
126 })
127 require.True(t, created)
128 liveChart.lastSeenSuccessSeq = tc.currentSeq
129
130 staleDim, created := liveChart.ensureDimension("stale_dim", dimensionState{
131 algorithm: program.AlgorithmAbsolute,
132 multiplier: 1,
133 divisor: 1,
134 })
135 require.True(t, created)
136 staleDim.lastSeenSuccessSeq = 2
137
138 freshDim, created := liveChart.ensureDimension("fresh_dim", dimensionState{
139 algorithm: program.AlgorithmAbsolute,
140 multiplier: 1,
141 divisor: 1,
142 })
143 require.True(t, created)
144 freshDim.lastSeenSuccessSeq = 4
145
146 removeDims, removeCharts := collectExpiryRemovals(tc.currentSeq, &state)
147
148 require.Len(t, removeDims, 1)
149 assert.Equal(t, "chart_live", removeDims[0].ChartID)
150 assert.Equal(t, "stale_dim", removeDims[0].Name)
151
152 require.Len(t, removeCharts, 1)
153 assert.Equal(t, "chart_expired", removeCharts[0].ChartID)
154
155 assert.NotContains(t, state.charts, "chart_expired")
156 assert.NotContains(t, liveChart.dimensions, "stale_dim")
157 assert.Contains(t, liveChart.dimensions, "fresh_dim")
158 })
159 }
160 }