@@ -141,4 +141,112 @@ func TestEMADifferentIntervals(t *testing.T) {
141141 }
142142 })
143143 }
144+ }
145+
146+ func TestDiskEMAs (t * testing.T ) {
147+ // Create a monitor with a 60-second interval
148+ monitor , err := NewSystemMonitor ("http://test.com" , 60 , 90.0 , 90.0 , 90.0 )
149+ if err != nil {
150+ t .Fatalf ("Failed to create monitor: %v" , err )
151+ }
152+
153+ // Test case 1: Verify root disk EMA updates correctly
154+ t .Run ("RootDiskEMA" , func (t * testing.T ) {
155+ rootPath := "/"
156+
157+ // Simulate initial usage
158+ monitor .diskEMAs [rootPath ] = 50.0
159+
160+ // Simulate a series of measurements
161+ values := []float64 {60.0 , 70.0 , 80.0 , 90.0 }
162+ for _ , v := range values {
163+ monitor .diskEMAs [rootPath ] = monitor .calculateEMA (v , monitor .diskEMAs [rootPath ])
164+ }
165+
166+ // EMA should be between 70% and 90%
167+ if monitor .diskEMAs [rootPath ] < 70.0 || monitor .diskEMAs [rootPath ] > 90.0 {
168+ t .Errorf ("Expected root disk EMA to be between 70%% and 90%%, got %.2f%%" , monitor .diskEMAs [rootPath ])
169+ }
170+ })
171+
172+ // Test case 2: Verify multiple mount points are tracked independently
173+ t .Run ("MultipleMountEMAs" , func (t * testing.T ) {
174+ // Setup test mounts with different starting values
175+ mounts := map [string ]float64 {
176+ "/mnt/data1" : 30.0 ,
177+ "/mnt/data2" : 50.0 ,
178+ "/mnt/logs" : 70.0 ,
179+ }
180+
181+ // Initialize starting values
182+ for path , value := range mounts {
183+ monitor .diskEMAs [path ] = value
184+ }
185+
186+ // Apply the same change to all mounts (+20%)
187+ for path := range mounts {
188+ currentValue := monitor .diskEMAs [path ]
189+ newValue := currentValue + 20.0
190+ if newValue > 100.0 {
191+ newValue = 100.0
192+ }
193+ monitor .diskEMAs [path ] = monitor .calculateEMA (newValue , currentValue )
194+ }
195+
196+ // Verify each mount's EMA updated independently
197+ for path , initialValue := range mounts {
198+ expectedMinimum := initialValue
199+ expectedMaximum := initialValue + 20.0 // Full change would be +20%
200+ if expectedMaximum > 100.0 {
201+ expectedMaximum = 100.0
202+ }
203+
204+ // With our alpha, the EMA should be approximately between the initial value and the initial + 7% (1/3 of 20%)
205+ expectedMinimum = initialValue
206+ expectedMaximum = initialValue + 7.0
207+
208+ actualValue := monitor .diskEMAs [path ]
209+ if actualValue < expectedMinimum || actualValue > expectedMaximum {
210+ t .Errorf ("Mount %s: Expected EMA between %.2f%% and %.2f%%, got %.2f%%" ,
211+ path , expectedMinimum , expectedMaximum , actualValue )
212+ }
213+ }
214+
215+ // Extract just the mount values we're testing
216+ mountValues := make ([]float64 , 0 , len (mounts ))
217+ for path := range mounts {
218+ mountValues = append (mountValues , monitor .diskEMAs [path ])
219+ }
220+
221+ // Verify mount points have different values (they're independent)
222+ if len (unique (mountValues )) != len (mounts ) {
223+ t .Errorf ("Expected all mount EMAs to be different, got: %v" , mountValues )
224+ }
225+ })
226+ }
227+
228+ // Helper functions for the disk EMA tests
229+
230+ // Return values from a map as a slice
231+ func getValues (m map [string ]float64 ) []float64 {
232+ values := make ([]float64 , 0 , len (m ))
233+ for _ , v := range m {
234+ values = append (values , v )
235+ }
236+ return values
237+ }
238+
239+ // Return unique values from a slice
240+ func unique (values []float64 ) []float64 {
241+ seen := make (map [float64 ]bool )
242+ unique := make ([]float64 , 0 )
243+
244+ for _ , v := range values {
245+ if ! seen [v ] {
246+ seen [v ] = true
247+ unique = append (unique , v )
248+ }
249+ }
250+
251+ return unique
144252}
0 commit comments