From 5e8229fe4df08d952bfbf4cf0bcefbc69a3be7b0 Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 11:33:59 +0200 Subject: [PATCH 01/22] added test --- internal/util/math_test.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/internal/util/math_test.go b/internal/util/math_test.go index 7dae1fb..50ec285 100644 --- a/internal/util/math_test.go +++ b/internal/util/math_test.go @@ -74,3 +74,30 @@ func TestFindClosest(t *testing.T) { assert.Equal(t, 90, closest) } + +func TestCoerce(t *testing.T) { + // GIVEN + min := 0.0 + max := 10.0 + + // WHEN + resultMin := Coerce(-10, min, max) + // THEN + assert.Equal(t, min, resultMin) + + // WHEN + resultValueLow := Coerce(0, min, max) + // THEN + assert.Equal(t, resultValueLow, resultValueLow) + + // WHEN + resultValueHigh := Coerce(10, min, max) + + // THEN + assert.Equal(t, resultValueHigh, resultValueHigh) + + // WHEN + resultMax := Coerce(20, min, max) + // THEN + assert.Equal(t, max, resultMax) +} From d4515be9bd3d5f10e90b5555a9e33c46909e4f0c Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 11:36:05 +0200 Subject: [PATCH 02/22] added test --- internal/util/math_test.go | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/internal/util/math_test.go b/internal/util/math_test.go index 50ec285..6cea9ac 100644 --- a/internal/util/math_test.go +++ b/internal/util/math_test.go @@ -101,3 +101,16 @@ func TestCoerce(t *testing.T) { // THEN assert.Equal(t, max, resultMax) } + +func TestUpdateSimpleMovingAvg(t *testing.T) { + // GIVEN + avg := 0.0 + n := 2 + newValue := 10.0 + + // WHEN + result := UpdateSimpleMovingAvg(avg, n, newValue) + + // THEN + assert.Equal(t, 5.0, result) +} From 13842dcd571f7192ad3cb1669a97ae4318c6a25b Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 11:54:21 +0200 Subject: [PATCH 03/22] added test --- internal/util/math_test.go | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/internal/util/math_test.go b/internal/util/math_test.go index 6cea9ac..2ee08d8 100644 --- a/internal/util/math_test.go +++ b/internal/util/math_test.go @@ -114,3 +114,24 @@ func TestUpdateSimpleMovingAvg(t *testing.T) { // THEN assert.Equal(t, 5.0, result) } + +func TestInterpolateLinearly(t *testing.T) { + // GIVEN + data := map[int]float64{ + 0: 0.0, + 100: 100.0, + } + start := 0 + stop := 100 + + expectedResult := map[int]float64{} + for i := 0; i <= 100; i++ { + expectedResult[i] = float64(i) + } + + // WHEN + result := InterpolateLinearly(&data, start, stop) + + // THEN + assert.Equal(t, expectedResult, result) +} From 250920aec68c54cfe9076ab6bb257ee3fe9ffde9 Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 12:12:09 +0200 Subject: [PATCH 04/22] fix rounding issues, added tests --- internal/util/math.go | 8 ++++---- internal/util/math_test.go | 11 ++++++++++- 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/internal/util/math.go b/internal/util/math.go index 4a197cb..605c7a8 100644 --- a/internal/util/math.go +++ b/internal/util/math.go @@ -42,12 +42,12 @@ func HexString(hex string) string { return fmt.Sprintf("%X", value) } -// Ratio calculates the ration that target has in comparison to rangeMin and rangeMax +// Ratio calculates the ratio that target has in comparison to rangeMin and rangeMax // Make sure that: // rangeMin <= target <= rangeMax // rangeMax - rangeMin != 0 func Ratio(target float64, rangeMin float64, rangeMax float64) float64 { - return (target - rangeMin) / (rangeMax - rangeMin) + return ((target - rangeMin) / (rangeMax - rangeMin) * 100) / 100 } // UpdateSimpleMovingAvg calculates the new moving average, based on an existing average and buffer size @@ -98,7 +98,7 @@ func CalculateInterpolatedCurveValue(steps map[int]float64, interpolationType st nextY := steps[nextX] ratio := Ratio(input, float64(currentX), float64(nextX)) - interpolation := currentY + ratio*(nextY-currentY) + interpolation := float64(float32(currentY + (ratio * (nextY - currentY)))) return interpolation } } @@ -128,7 +128,7 @@ func FindClosest(target int, arr []int) int { mid = (i + j) / 2 if arr[mid] == target { - return arr[mid] + break } /* If target is less than array element, diff --git a/internal/util/math_test.go b/internal/util/math_test.go index 2ee08d8..f170d65 100644 --- a/internal/util/math_test.go +++ b/internal/util/math_test.go @@ -57,6 +57,16 @@ func TestFindClosest(t *testing.T) { // THEN assert.Equal(t, 10, closest) + // WHEN + closest = FindClosest(11, options) + // THEN + assert.Equal(t, 10, closest) + + // WHEN + closest = FindClosest(50, options) + // THEN + assert.Equal(t, 50, closest) + // WHEN closest = FindClosest(54, options) // THEN @@ -64,7 +74,6 @@ func TestFindClosest(t *testing.T) { // WHEN closest = FindClosest(55, options) - // THEN assert.Equal(t, 60, closest) From 6565021fd9be5aa0645f8fd70d65c84cbd039801 Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 12:14:25 +0200 Subject: [PATCH 05/22] add test --- internal/util/math_test.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/internal/util/math_test.go b/internal/util/math_test.go index f170d65..e23ae79 100644 --- a/internal/util/math_test.go +++ b/internal/util/math_test.go @@ -77,6 +77,11 @@ func TestFindClosest(t *testing.T) { // THEN assert.Equal(t, 60, closest) + // WHEN + closest = FindClosest(75, options) + // THEN + assert.Equal(t, 80, closest) + // WHEN closest = FindClosest(100, options) // THEN From fef37c5b37e280a8212a0eef03e8c87ec55af012 Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 12:27:58 +0200 Subject: [PATCH 06/22] added tests --- internal/util/file_test.go | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/internal/util/file_test.go b/internal/util/file_test.go index cad6988..073034d 100644 --- a/internal/util/file_test.go +++ b/internal/util/file_test.go @@ -113,3 +113,41 @@ func TestFileHasPermissionsOtherHasWritePermission(t *testing.T) { assert.Equal(t, false, result) assert.Error(t, err) } + +func TestReadIntFromFile_Success(t *testing.T) { + // GIVEN + filePath := "../../test/file_fan_rpm" + + // WHEN + result, err := ReadIntFromFile(filePath) + + // THEN + assert.Equal(t, 2150, result) + assert.NoError(t, err) +} + +func TestReadIntFromFile_FileNotFound(t *testing.T) { + // GIVEN + filePath := "../../not exists" + + // WHEN + result, err := ReadIntFromFile(filePath) + + // THEN + assert.Equal(t, -1, result) + assert.Error(t, err) +} + +func TestReadIntFromFile_FileEmpty(t *testing.T) { + // GIVEN + filePath := "./empty_file" + os.Create(filePath) + defer os.Remove(filePath) + + // WHEN + result, err := ReadIntFromFile(filePath) + + // THEN + assert.Equal(t, -1, result) + assert.Error(t, err) +} From 3a83e13abbe12b15e35b41757c4cce1ae8e0093c Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 12:31:01 +0200 Subject: [PATCH 07/22] added tests --- internal/util/file.go | 2 +- internal/util/file_test.go | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/internal/util/file.go b/internal/util/file.go index 8a48188..5060153 100644 --- a/internal/util/file.go +++ b/internal/util/file.go @@ -55,7 +55,7 @@ func ReadIntFromFile(path string) (value int, err error) { } text := string(data) if len(text) <= 0 { - return 0, fmt.Errorf("file is empty: %s", path) + return -1, fmt.Errorf("file is empty: %s", path) } text = strings.TrimSpace(text) value, err = strconv.Atoi(text) diff --git a/internal/util/file_test.go b/internal/util/file_test.go index 073034d..8a30667 100644 --- a/internal/util/file_test.go +++ b/internal/util/file_test.go @@ -151,3 +151,22 @@ func TestReadIntFromFile_FileEmpty(t *testing.T) { assert.Equal(t, -1, result) assert.Error(t, err) } + +func TestWriteIntToFile(t *testing.T) { + // GIVEN + filePath := "./testfile" + defer os.Remove(filePath) + value := 123 + + // WHEN + err := WriteIntToFile(value, filePath) + + // THEN + assert.NoError(t, err) + + // WHEN + result, err := ReadIntFromFile(filePath) + + // THEN + assert.Equal(t, value, result) +} From 4284599844bb4c4ad79884737b23d04579a45e03 Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 12:32:22 +0200 Subject: [PATCH 08/22] added tests --- internal/util/file_test.go | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/internal/util/file_test.go b/internal/util/file_test.go index 8a30667..77b0ad0 100644 --- a/internal/util/file_test.go +++ b/internal/util/file_test.go @@ -152,7 +152,7 @@ func TestReadIntFromFile_FileEmpty(t *testing.T) { assert.Error(t, err) } -func TestWriteIntToFile(t *testing.T) { +func TestWriteIntToFile_Success(t *testing.T) { // GIVEN filePath := "./testfile" defer os.Remove(filePath) @@ -170,3 +170,15 @@ func TestWriteIntToFile(t *testing.T) { // THEN assert.Equal(t, value, result) } + +func TestWriteIntToFile_InvalidPath(t *testing.T) { + // GIVEN + filePath := ".////" + value := 123 + + // WHEN + err := WriteIntToFile(value, filePath) + + // THEN + assert.Error(t, err) +} From a7cd911d7185545a752ef044027a383f0f201862 Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 12:47:17 +0200 Subject: [PATCH 09/22] added tests --- internal/persistence/persistence_test.go | 18 ++++- internal/util/pid_test.go | 90 ++++++++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 internal/util/pid_test.go diff --git a/internal/persistence/persistence_test.go b/internal/persistence/persistence_test.go index 976f289..b5d2813 100644 --- a/internal/persistence/persistence_test.go +++ b/internal/persistence/persistence_test.go @@ -1,6 +1,7 @@ package persistence import ( + "os" "testing" "github.com/markusressel/fan2go/internal/configuration" @@ -10,7 +11,7 @@ import ( ) const ( - dbTestingPath = "./test.db" + dbTestingPath = "../testing/test.db" ) var ( @@ -26,6 +27,21 @@ var ( } ) +func TestMain(m *testing.M) { + beforeEach() + code := m.Run() + afterEach() + os.Exit(code) +} + +func beforeEach() { + NewPersistence(dbTestingPath).Init() +} + +func afterEach() { + defer os.Remove(dbTestingPath) +} + func TestPersistence_DeleteFanPwmData(t *testing.T) { // GIVEN p := NewPersistence(dbTestingPath) diff --git a/internal/util/pid_test.go b/internal/util/pid_test.go new file mode 100644 index 0000000..a55e1f2 --- /dev/null +++ b/internal/util/pid_test.go @@ -0,0 +1,90 @@ +package util + +import ( + "github.com/stretchr/testify/assert" + "testing" + "time" +) + +func TestNewPidLoop(t *testing.T) { + // GIVEN + p, i, d := 1.0, 2.0, 3.0 + + // WHEN + pidLoop := NewPidLoop(p, i, d) + + // THEN + assert.Equal(t, p, pidLoop.p) + assert.Equal(t, i, pidLoop.i) + assert.Equal(t, d, pidLoop.d) +} + +func TestPidLoop_Advance(t *testing.T) { + // GIVEN + p, i, d := 1.0, 2.0, 3.0 + pidLoop := NewPidLoop(p, i, d) + + // WHEN + output := pidLoop.Loop(10.0, 5.0) + // THEN + assert.Equal(t, 0.0, output) + + // WHEN + output = pidLoop.Loop(10.0, 5.0) + // THEN + assert.Equal(t, 5, int(output)) +} + +func TestPidLoop_P(t *testing.T) { + // GIVEN + p, i, d := 0.01, 0.0, 0.0 + pidLoop := NewPidLoop(p, i, d) + + // WHEN + output := pidLoop.Loop(10.0, 5.0) + // THEN + assert.Equal(t, 0.0, output) + + time.Sleep(1 * time.Second) + + // WHEN + output = pidLoop.Loop(10.0, 5.0) + // THEN + assert.Equal(t, 0.05, output) +} + +func TestPidLoop_I(t *testing.T) { + // GIVEN + p, i, d := 0.0, 0.01, 0.0 + pidLoop := NewPidLoop(p, i, d) + + // WHEN + output := pidLoop.Loop(10.0, 5.0) + // THEN + assert.Equal(t, 0.0, output) + + time.Sleep(1 * time.Second) + + // WHEN + output = pidLoop.Loop(10.0, 5.0) + // THEN + assert.InDelta(t, 0.05, output, 0.01) +} + +func TestPidLoop_D(t *testing.T) { + // GIVEN + p, i, d := 0.0, 0.0, 0.01 + pidLoop := NewPidLoop(p, i, d) + + // WHEN + output := pidLoop.Loop(10.0, 5.0) + // THEN + assert.Equal(t, 0.0, output) + + time.Sleep(1 * time.Second) + + // WHEN + output = pidLoop.Loop(10.0, 8.0) + // THEN + assert.InDelta(t, -0.03, output, 0.01) +} From 8788e7dba885d1d388b235a9d9e21a2b44183ddd Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 12:49:20 +0200 Subject: [PATCH 10/22] added tests --- internal/util/slice_test.go | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/internal/util/slice_test.go b/internal/util/slice_test.go index 3c2cbbf..9d48e22 100644 --- a/internal/util/slice_test.go +++ b/internal/util/slice_test.go @@ -34,3 +34,37 @@ func TestContainsString_Invalid(t *testing.T) { // THEN assert.False(t, result) } + +func TestSortSlice(t *testing.T) { + // GIVEN + list := []float64{ + 3.0, + 1.0, + 2.0, + } + + // WHEN + sortSlice(list) + + // THEN + assert.Equal(t, 1.0, list[0]) + assert.Equal(t, 2.0, list[1]) + assert.Equal(t, 3.0, list[2]) +} + +func TestSortedKeys(t *testing.T) { + // GIVEN + m := map[int]string{ + 3: "three", + 1: "one", + 2: "two", + } + + // WHEN + result := SortedKeys(m) + + // THEN + assert.Equal(t, 1, result[0]) + assert.Equal(t, 2, result[1]) + assert.Equal(t, 3, result[2]) +} From 314a0108b768fb2a517ececd119ed7abcefed2cf Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 12:51:27 +0200 Subject: [PATCH 11/22] added tests --- internal/util/window_test.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 internal/util/window_test.go diff --git a/internal/util/window_test.go b/internal/util/window_test.go new file mode 100644 index 0000000..a63c33f --- /dev/null +++ b/internal/util/window_test.go @@ -0,0 +1,20 @@ +package util + +import ( + "github.com/stretchr/testify/assert" + "testing" +) + +func TestGetWindowMax(t *testing.T) { + // GIVEN + window := CreateRollingWindow(3) + window.Append(1) + window.Append(2) + window.Append(3) + + // WHEN + maximumm := GetWindowMax(window) + + // THEN + assert.Equal(t, 3.0, maximumm) +} From 06ba4ad98ab64c0d092043d0f3ddb08f4b5bab87 Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 12:52:26 +0200 Subject: [PATCH 12/22] added tests --- internal/util/window_test.go | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/internal/util/window_test.go b/internal/util/window_test.go index a63c33f..982f31b 100644 --- a/internal/util/window_test.go +++ b/internal/util/window_test.go @@ -18,3 +18,14 @@ func TestGetWindowMax(t *testing.T) { // THEN assert.Equal(t, 3.0, maximumm) } + +func TestFillWindow(t *testing.T) { + // GIVEN + window := CreateRollingWindow(10) + + // WHEN + FillWindow(window, 3, 10) + + // THEN + assert.Equal(t, 10.0, GetWindowMax(window)) +} From 4f8c4dec62c91f865c3e6750db1df6f5c72590e9 Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 13:09:19 +0200 Subject: [PATCH 13/22] added tests --- internal/controller/controller_test.go | 106 +++++++++++++++++++++---- 1 file changed, 91 insertions(+), 15 deletions(-) diff --git a/internal/controller/controller_test.go b/internal/controller/controller_test.go index 1dab39a..e0a4e2d 100644 --- a/internal/controller/controller_test.go +++ b/internal/controller/controller_test.go @@ -1,6 +1,7 @@ package controller import ( + "errors" "sort" "testing" "time" @@ -58,6 +59,7 @@ func (c MockCurve) Evaluate() (value int, err error) { type MockFan struct { ID string + ControlMode fans.ControlMode PWM int MinPWM int RPM int @@ -121,11 +123,12 @@ func (fan *MockFan) AttachFanCurveData(curveData *map[int]float64) (err error) { } func (fan MockFan) GetPwmEnabled() (int, error) { - panic("implement me") + return int(fan.ControlMode), nil } func (fan *MockFan) SetPwmEnabled(value fans.ControlMode) (err error) { - panic("implement me") + fan.ControlMode = value + return nil } func (fan MockFan) IsPwmAuto() (bool, error) { @@ -201,20 +204,31 @@ var ( } ) -type mockPersistence struct{} +type mockPersistence struct { + hasPwmMap bool + hasSavedPwmData bool +} func (p mockPersistence) Init() (err error) { return nil } func (p mockPersistence) SaveFanPwmData(fan fans.Fan) (err error) { return nil } func (p mockPersistence) LoadFanPwmData(fan fans.Fan) (map[int]float64, error) { - fanCurveDataMap := map[int]float64{} - return fanCurveDataMap, nil + if p.hasSavedPwmData { + fanCurveDataMap := map[int]float64{} + return fanCurveDataMap, nil + } else { + return nil, errors.New("no pwm data found") + } } func (p mockPersistence) DeleteFanPwmData(fan fans.Fan) (err error) { return nil } func (p mockPersistence) LoadFanPwmMap(fanId string) (map[int]int, error) { - pwmMap := map[int]int{} - return pwmMap, nil + if p.hasPwmMap { + pwmMap := map[int]int{} + return pwmMap, nil + } else { + return nil, errors.New("no pwm map found") + } } func (p mockPersistence) SaveFanPwmMap(fanId string, pwmMap map[int]int) (err error) { return nil } func (p mockPersistence) DeleteFanPwmMap(fanId string) (err error) { return nil } @@ -370,10 +384,11 @@ func TestCalculateTargetSpeedNeverStop(t *testing.T) { fans.FanMap[fan.GetId()] = fan controller := PidFanController{ - persistence: mockPersistence{}, fan: fan, - curve: curve, - updateRate: time.Duration(100), - pwmMap: createOneToOnePwmMap(), + persistence: mockPersistence{}, + fan: fan, + curve: curve, + updateRate: time.Duration(100), + pwmMap: createOneToOnePwmMap(), } controller.updateDistinctPwmValues() @@ -456,10 +471,11 @@ func TestFanController_UpdateFanSpeed_FanCurveGaps(t *testing.T) { } controller := PidFanController{ - persistence: mockPersistence{}, fan: fan, - curve: curve, - updateRate: time.Duration(100), - pwmMap: pwmMap, + persistence: mockPersistence{}, + fan: fan, + curve: curve, + updateRate: time.Duration(100), + pwmMap: pwmMap, } controller.updateDistinctPwmValues() @@ -472,3 +488,63 @@ func TestFanController_UpdateFanSpeed_FanCurveGaps(t *testing.T) { closestTarget := controller.findClosestDistinctTarget(targetPwm) assert.Equal(t, 58, closestTarget) } + +func TestFanController_ComputePwmMap_FullRange(t *testing.T) { + // GIVEN + avgTmp := 40000.0 + + s := MockSensor{ + ID: "sensor", + Name: "sensor", + MovingAvg: avgTmp, + } + sensors.SensorMap[s.GetId()] = &s + + curveValue := 5 + curve := &MockCurve{ + ID: "curve", + Value: curveValue, + } + curves.SpeedCurveMap[curve.GetId()] = curve + + fan := &MockFan{ + ID: "fan", + PWM: 0, + RPM: 100, + MinPWM: 50, + curveId: curve.GetId(), + shouldNeverStop: true, + speedCurve: &DutyCycleFan, + } + fans.FanMap[fan.GetId()] = fan + + var keys []int + for pwm := range DutyCycleFan { + keys = append(keys, pwm) + } + sort.Ints(keys) + + expectedPwmMap := map[int]int{} + for i := 0; i <= 255; i++ { + expectedPwmMap[i] = i + } + + controller := PidFanController{ + persistence: mockPersistence{ + hasPwmMap: false, + }, + fan: fan, + curve: curve, + updateRate: time.Duration(100), + pwmMap: map[int]int{}, + } + controller.updateDistinctPwmValues() + + // WHEN + err := controller.computePwmMap() + // controller.computePwmMapAutomatically() + + // THEN + assert.NoError(t, err) + assert.Equal(t, expectedPwmMap, controller.pwmMap) +} From 8dbda849158725e70502fb94986f733321250858 Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 13:10:35 +0200 Subject: [PATCH 14/22] remove comment --- internal/controller/controller_test.go | 1 - 1 file changed, 1 deletion(-) diff --git a/internal/controller/controller_test.go b/internal/controller/controller_test.go index e0a4e2d..d6dc394 100644 --- a/internal/controller/controller_test.go +++ b/internal/controller/controller_test.go @@ -542,7 +542,6 @@ func TestFanController_ComputePwmMap_FullRange(t *testing.T) { // WHEN err := controller.computePwmMap() - // controller.computePwmMapAutomatically() // THEN assert.NoError(t, err) From ce8dcde8761c561775de3c1b2cc42ee779f96878 Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 14:29:00 +0200 Subject: [PATCH 15/22] added tests --- internal/fans/file_test.go | 142 +++++++++++++++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 internal/fans/file_test.go diff --git a/internal/fans/file_test.go b/internal/fans/file_test.go new file mode 100644 index 0000000..1ade775 --- /dev/null +++ b/internal/fans/file_test.go @@ -0,0 +1,142 @@ +package fans + +import ( + "github.com/markusressel/fan2go/internal/configuration" + "github.com/stretchr/testify/assert" + "testing" +) + +func TestFileFan_GetId(t *testing.T) { + // GIVEN + id := "test" + config := configuration.FanConfig{ + ID: id, + File: &configuration.FileFanConfig{ + Path: "/path/to/pwm", + RpmPath: "/path/to/rpm", + }, + } + fan, err := NewFan(config) + assert.NoError(t, err) + + // WHEN + result := fan.GetId() + + assert.Equal(t, id, result) +} + +func TestFileFan_GetStartPwm(t *testing.T) { + // GIVEN + config := configuration.FanConfig{ + File: &configuration.FileFanConfig{ + Path: "/path/to/pwm", + RpmPath: "/path/to/rpm", + }, + } + fan, err := NewFan(config) + assert.NoError(t, err) + + // WHEN + result := fan.GetStartPwm() + + // THEN + assert.Equal(t, 1, result) +} + +func TestFileFan_SetStartPwm(t *testing.T) { + // GIVEN + config := configuration.FanConfig{ + File: &configuration.FileFanConfig{ + Path: "/path/to/pwm", + RpmPath: "/path/to/rpm", + }, + } + + fan, err := NewFan(config) + assert.NoError(t, err) + + // WHEN + fan.SetStartPwm(100, false) + + // THEN + // NOTE: file fan does not support setting start pwm + assert.Equal(t, 1, fan.GetStartPwm()) +} + +func TestFileFan_GetMinPwm(t *testing.T) { + // GIVEN + config := configuration.FanConfig{ + File: &configuration.FileFanConfig{ + Path: "/path/to/pwm", + RpmPath: "/path/to/rpm", + }, + } + + fan, err := NewFan(config) + assert.NoError(t, err) + + // WHEN + result := fan.GetMinPwm() + + // THEN + assert.Equal(t, 0, result) +} + +func TestFileFan_SetMinPwm(t *testing.T) { + // GIVEN + config := configuration.FanConfig{ + File: &configuration.FileFanConfig{ + Path: "/path/to/pwm", + RpmPath: "/path/to/rpm", + }, + } + + fan, err := NewFan(config) + assert.NoError(t, err) + + // WHEN + fan.SetMinPwm(100, false) + + // THEN + // NOTE: file fan does not support setting start pwm + assert.Equal(t, 0, fan.GetMinPwm()) +} + +func TestFileFan_GetMaxPwm(t *testing.T) { + // GIVEN + config := configuration.FanConfig{ + File: &configuration.FileFanConfig{ + Path: "/path/to/pwm", + RpmPath: "/path/to/rpm", + }, + } + + fan, err := NewFan(config) + assert.NoError(t, err) + + // WHEN + result := fan.GetMaxPwm() + + // THEN + assert.Equal(t, 255, result) +} + +func TestFileFan_SetMaxPwm(t *testing.T) { + // GIVEN + config := configuration.FanConfig{ + File: &configuration.FileFanConfig{ + Path: "/path/to/pwm", + RpmPath: "/path/to/rpm", + }, + } + + fan, err := NewFan(config) + assert.NoError(t, err) + + // WHEN + fan.SetMaxPwm(100, false) + + // THEN + // NOTE: file fan does not support setting max pwm + assert.Equal(t, 255, fan.GetMaxPwm()) +} From 6199d809eede72ef178de77fdd53495e261c745a Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 14:40:32 +0200 Subject: [PATCH 16/22] added tests --- internal/fans/file_test.go | 207 ++++++++++++++++++++++++++++++++----- 1 file changed, 180 insertions(+), 27 deletions(-) diff --git a/internal/fans/file_test.go b/internal/fans/file_test.go index 1ade775..80ae125 100644 --- a/internal/fans/file_test.go +++ b/internal/fans/file_test.go @@ -6,18 +6,36 @@ import ( "testing" ) -func TestFileFan_GetId(t *testing.T) { +func TestFileFan_NewFan(t *testing.T) { // GIVEN id := "test" config := configuration.FanConfig{ ID: id, File: &configuration.FileFanConfig{ - Path: "/path/to/pwm", - RpmPath: "/path/to/rpm", + Path: "../../test/file_fan_pwm", + RpmPath: "../../test/file_fan_rpm", }, } + + // WHEN fan, err := NewFan(config) + + // THEN assert.NoError(t, err) + assert.NotNil(t, fan) +} + +func TestFileFan_GetId(t *testing.T) { + // GIVEN + id := "test" + config := configuration.FanConfig{ + ID: id, + File: &configuration.FileFanConfig{ + Path: "../../test/file_fan_pwm", + RpmPath: "../../test/file_fan_rpm", + }, + } + fan, _ := NewFan(config) // WHEN result := fan.GetId() @@ -29,12 +47,11 @@ func TestFileFan_GetStartPwm(t *testing.T) { // GIVEN config := configuration.FanConfig{ File: &configuration.FileFanConfig{ - Path: "/path/to/pwm", - RpmPath: "/path/to/rpm", + Path: "../../test/file_fan_pwm", + RpmPath: "../../test/file_fan_rpm", }, } - fan, err := NewFan(config) - assert.NoError(t, err) + fan, _ := NewFan(config) // WHEN result := fan.GetStartPwm() @@ -47,13 +64,12 @@ func TestFileFan_SetStartPwm(t *testing.T) { // GIVEN config := configuration.FanConfig{ File: &configuration.FileFanConfig{ - Path: "/path/to/pwm", - RpmPath: "/path/to/rpm", + Path: "../../test/file_fan_pwm", + RpmPath: "../../test/file_fan_rpm", }, } - fan, err := NewFan(config) - assert.NoError(t, err) + fan, _ := NewFan(config) // WHEN fan.SetStartPwm(100, false) @@ -67,13 +83,12 @@ func TestFileFan_GetMinPwm(t *testing.T) { // GIVEN config := configuration.FanConfig{ File: &configuration.FileFanConfig{ - Path: "/path/to/pwm", - RpmPath: "/path/to/rpm", + Path: "../../test/file_fan_pwm", + RpmPath: "../../test/file_fan_rpm", }, } - fan, err := NewFan(config) - assert.NoError(t, err) + fan, _ := NewFan(config) // WHEN result := fan.GetMinPwm() @@ -86,13 +101,12 @@ func TestFileFan_SetMinPwm(t *testing.T) { // GIVEN config := configuration.FanConfig{ File: &configuration.FileFanConfig{ - Path: "/path/to/pwm", - RpmPath: "/path/to/rpm", + Path: "../../test/file_fan_pwm", + RpmPath: "../../test/file_fan_rpm", }, } - fan, err := NewFan(config) - assert.NoError(t, err) + fan, _ := NewFan(config) // WHEN fan.SetMinPwm(100, false) @@ -106,13 +120,12 @@ func TestFileFan_GetMaxPwm(t *testing.T) { // GIVEN config := configuration.FanConfig{ File: &configuration.FileFanConfig{ - Path: "/path/to/pwm", - RpmPath: "/path/to/rpm", + Path: "../../test/file_fan_pwm", + RpmPath: "../../test/file_fan_rpm", }, } - fan, err := NewFan(config) - assert.NoError(t, err) + fan, _ := NewFan(config) // WHEN result := fan.GetMaxPwm() @@ -125,13 +138,12 @@ func TestFileFan_SetMaxPwm(t *testing.T) { // GIVEN config := configuration.FanConfig{ File: &configuration.FileFanConfig{ - Path: "/path/to/pwm", - RpmPath: "/path/to/rpm", + Path: "../../test/file_fan_pwm", + RpmPath: "../../test/file_fan_rpm", }, } - fan, err := NewFan(config) - assert.NoError(t, err) + fan, _ := NewFan(config) // WHEN fan.SetMaxPwm(100, false) @@ -140,3 +152,144 @@ func TestFileFan_SetMaxPwm(t *testing.T) { // NOTE: file fan does not support setting max pwm assert.Equal(t, 255, fan.GetMaxPwm()) } + +func TestFileFan_GetRpm(t *testing.T) { + // GIVEN + config := configuration.FanConfig{ + File: &configuration.FileFanConfig{ + Path: "../../test/file_fan_pwm", + RpmPath: "../../test/file_fan_rpm", + }, + } + + fan, _ := NewFan(config) + + // WHEN + result, err := fan.GetRpm() + + // THEN + assert.NoError(t, err) + assert.Equal(t, 2150, result) +} + +func TestFileFan_GetRpm_InvalidPath(t *testing.T) { + // GIVEN + config := configuration.FanConfig{ + File: &configuration.FileFanConfig{ + Path: "../../test/non_existent_file", + RpmPath: "../../test/non_existent_file", + }, + } + + fan, _ := NewFan(config) + + // WHEN + result, err := fan.GetRpm() + + // THEN + assert.Error(t, err) + assert.Equal(t, 0, result) +} + +func TestFileFan_SetRpmAvg(t *testing.T) { + // GIVEN + config := configuration.FanConfig{ + File: &configuration.FileFanConfig{ + Path: "../../test/non_existent_file", + RpmPath: "../../test/non_existent_file", + }, + } + + fan, _ := NewFan(config) + + rpmAvg := 1000.5 + + // WHEN + fan.SetRpmAvg(rpmAvg) + + // THEN + assert.Equal(t, float64(int(rpmAvg)), fan.GetRpmAvg()) +} + +func TestFileFan_GetRpmAvg(t *testing.T) { + // GIVEN + config := configuration.FanConfig{ + File: &configuration.FileFanConfig{ + Path: "../../test/non_existent_file", + RpmPath: "../../test/non_existent_file", + }, + } + + fan, _ := NewFan(config) + + rpmAvg := 1234.5 + fan.SetRpmAvg(rpmAvg) + + // WHEN + result := fan.GetRpmAvg() + + // THEN + assert.Equal(t, float64(int(rpmAvg)), result) +} + +func TestFileFan_GetPwm(t *testing.T) { + // GIVEN + config := configuration.FanConfig{ + File: &configuration.FileFanConfig{ + Path: "../../test/file_fan_pwm", + RpmPath: "../../test/file_fan_rpm", + }, + } + + fan, _ := NewFan(config) + + // WHEN + result, err := fan.GetPwm() + + // THEN + assert.NoError(t, err) + assert.Equal(t, 152, result) +} + +func TestFileFan_GetPwm_InvalidPath(t *testing.T) { + // GIVEN + config := configuration.FanConfig{ + File: &configuration.FileFanConfig{ + Path: "../../test/non_existent_file", + RpmPath: "../../test/non_existent_file", + }, + } + + fan, _ := NewFan(config) + + // WHEN + result, err := fan.GetPwm() + + // THEN + assert.Error(t, err) + assert.Equal(t, 0, result) +} + +func TestFileFan_SetPwm(t *testing.T) { + // GIVEN + config := configuration.FanConfig{ + File: &configuration.FileFanConfig{ + Path: "../../test/file_fan_pwm", + RpmPath: "../../test/file_fan_rpm", + }, + } + + fan, _ := NewFan(config) + targetPwm := 100 + + // WHEN + err := fan.SetPwm(targetPwm) + + // THEN + assert.NoError(t, err) + + result, err := fan.GetPwm() + + assert.NoError(t, err) + assert.Equal(t, targetPwm, result) +} From bdd65bb6fb5b1147a5ba87df7667e530141e0b3c Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 14:46:38 +0200 Subject: [PATCH 17/22] fix tests affecting each other --- internal/fans/file_test.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/internal/fans/file_test.go b/internal/fans/file_test.go index 80ae125..9a3a175 100644 --- a/internal/fans/file_test.go +++ b/internal/fans/file_test.go @@ -3,6 +3,7 @@ package fans import ( "github.com/markusressel/fan2go/internal/configuration" "github.com/stretchr/testify/assert" + "os" "testing" ) @@ -272,9 +273,11 @@ func TestFileFan_GetPwm_InvalidPath(t *testing.T) { func TestFileFan_SetPwm(t *testing.T) { // GIVEN + defer os.Remove("./file_fan_pwm") + config := configuration.FanConfig{ File: &configuration.FileFanConfig{ - Path: "../../test/file_fan_pwm", + Path: "./file_fan_pwm", RpmPath: "../../test/file_fan_rpm", }, } From aed718b60ffd9f9b54afd38fcd94b9d08a735372 Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 14:49:55 +0200 Subject: [PATCH 18/22] lint fixes --- internal/persistence/persistence_test.go | 9 +++-- internal/util/file_test.go | 42 +++++++++++++++++------- 2 files changed, 38 insertions(+), 13 deletions(-) diff --git a/internal/persistence/persistence_test.go b/internal/persistence/persistence_test.go index b5d2813..4f26e09 100644 --- a/internal/persistence/persistence_test.go +++ b/internal/persistence/persistence_test.go @@ -35,11 +35,16 @@ func TestMain(m *testing.M) { } func beforeEach() { - NewPersistence(dbTestingPath).Init() + err := NewPersistence(dbTestingPath).Init() + if err != nil { + panic(err) + } } func afterEach() { - defer os.Remove(dbTestingPath) + defer func() { + _ = os.Remove(dbTestingPath) + }() } func TestPersistence_DeleteFanPwmData(t *testing.T) { diff --git a/internal/util/file_test.go b/internal/util/file_test.go index 77b0ad0..501ae94 100644 --- a/internal/util/file_test.go +++ b/internal/util/file_test.go @@ -22,8 +22,12 @@ func TestFileHasPermissionsUserIsRoot(t *testing.T) { err = os.Chmod(filePath, filePerm) assert.NoError(t, err) - defer file.Close() - defer os.Remove(filePath) + defer func(file *os.File) { + _ = file.Close() + }(file) + defer func(name string) { + _ = os.Remove(name) + }(filePath) // WHEN result, err := CheckFilePermissionsForExecution(filePath) @@ -49,8 +53,12 @@ func TestFileHasPermissionsGroupIsRootAndHasWrite(t *testing.T) { err = os.Chmod(filePath, filePerm) assert.NoError(t, err) - defer file.Close() - defer os.Remove(filePath) + defer func(file *os.File) { + _ = file.Close() + }(file) + defer func(name string) { + _ = os.Remove(name) + }(filePath) // WHEN result, err := CheckFilePermissionsForExecution(filePath) @@ -76,8 +84,12 @@ func TestFileHasPermissionsGroupOtherThanRootHasWritePermission(t *testing.T) { err = os.Chmod(filePath, filePerm) assert.NoError(t, err) - defer file.Close() - defer os.Remove(filePath) + defer func(file *os.File) { + _ = file.Close() + }(file) + defer func(name string) { + _ = os.Remove(name) + }(filePath) // WHEN result, err := CheckFilePermissionsForExecution(filePath) @@ -103,8 +115,12 @@ func TestFileHasPermissionsOtherHasWritePermission(t *testing.T) { err = os.Chmod(filePath, filePerm) assert.NoError(t, err) - defer file.Close() - defer os.Remove(filePath) + defer func(file *os.File) { + _ = file.Close() + }(file) + defer func(name string) { + _ = os.Remove(name) + }(filePath) // WHEN result, err := CheckFilePermissionsForExecution(filePath) @@ -141,8 +157,10 @@ func TestReadIntFromFile_FileNotFound(t *testing.T) { func TestReadIntFromFile_FileEmpty(t *testing.T) { // GIVEN filePath := "./empty_file" - os.Create(filePath) - defer os.Remove(filePath) + _, _ = os.Create(filePath) + defer func(name string) { + _ = os.Remove(name) + }(filePath) // WHEN result, err := ReadIntFromFile(filePath) @@ -155,7 +173,9 @@ func TestReadIntFromFile_FileEmpty(t *testing.T) { func TestWriteIntToFile_Success(t *testing.T) { // GIVEN filePath := "./testfile" - defer os.Remove(filePath) + defer func(name string) { + _ = os.Remove(name) + }(filePath) value := 123 // WHEN From 54d7258ffcad85082c02814b10ac79c068aab6b4 Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 14:50:51 +0200 Subject: [PATCH 19/22] lint fixes --- internal/util/file_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/internal/util/file_test.go b/internal/util/file_test.go index 501ae94..b261bc9 100644 --- a/internal/util/file_test.go +++ b/internal/util/file_test.go @@ -189,6 +189,7 @@ func TestWriteIntToFile_Success(t *testing.T) { // THEN assert.Equal(t, value, result) + assert.NoError(t, err) } func TestWriteIntToFile_InvalidPath(t *testing.T) { From 60a94914d47088386ae6f0c53bb7e1f6910aea9e Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 15:07:38 +0200 Subject: [PATCH 20/22] added test --- internal/fans/file.go | 1 + internal/fans/file_test.go | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/internal/fans/file.go b/internal/fans/file.go index 653eeba..1c0e825 100644 --- a/internal/fans/file.go +++ b/internal/fans/file.go @@ -109,6 +109,7 @@ func (fan *FileFan) SetPwm(pwm int) (err error) { err = util.WriteIntToFile(pwm, filePath) if err != nil { ui.Error("Unable to write to file: %v", fan.Config.File.Path) + return err } return nil } diff --git a/internal/fans/file_test.go b/internal/fans/file_test.go index 9a3a175..7de3bcd 100644 --- a/internal/fans/file_test.go +++ b/internal/fans/file_test.go @@ -296,3 +296,21 @@ func TestFileFan_SetPwm(t *testing.T) { assert.NoError(t, err) assert.Equal(t, targetPwm, result) } + +func TestFileFan_SetPwm_InvalidPath(t *testing.T) { + // GIVEN + config := configuration.FanConfig{ + File: &configuration.FileFanConfig{ + Path: "../..////", + RpmPath: "../../test/non_existent_file", + }, + } + + fan, _ := NewFan(config) + + // WHEN + err := fan.SetPwm(100) + + // THEN + assert.Error(t, err) +} From 1ac0df81639d98e83a2e974d192f183d76bf8c1a Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 15:12:55 +0200 Subject: [PATCH 21/22] added test --- internal/fans/file_test.go | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/internal/fans/file_test.go b/internal/fans/file_test.go index 7de3bcd..e98821d 100644 --- a/internal/fans/file_test.go +++ b/internal/fans/file_test.go @@ -2,6 +2,7 @@ package fans import ( "github.com/markusressel/fan2go/internal/configuration" + "github.com/markusressel/fan2go/internal/util" "github.com/stretchr/testify/assert" "os" "testing" @@ -314,3 +315,29 @@ func TestFileFan_SetPwm_InvalidPath(t *testing.T) { // THEN assert.Error(t, err) } + +func TestFileFan_GetFanCurveData(t *testing.T) { + // GIVEN + config := configuration.FanConfig{ + File: &configuration.FileFanConfig{ + Path: "../..////", + RpmPath: "../../test/non_existent_file", + }, + } + + fan, _ := NewFan(config) + + expectedFanCurve := util.InterpolateLinearly( + &map[int]float64{ + 0: 0.0, + 255: 255.0, + }, + 0, 255, + ) + + // WHEN + result := fan.GetFanCurveData() + + // THEN + assert.Equal(t, expectedFanCurve, *result) +} From 7a27aa5c6e6537d03ff8ebd3783a494700675e3d Mon Sep 17 00:00:00 2001 From: Markus Ressel Date: Sat, 21 Sep 2024 15:24:10 +0200 Subject: [PATCH 22/22] added test --- internal/fans/file_test.go | 43 ++++++++++++++++++++++++++++++++++++-- 1 file changed, 41 insertions(+), 2 deletions(-) diff --git a/internal/fans/file_test.go b/internal/fans/file_test.go index e98821d..76191ba 100644 --- a/internal/fans/file_test.go +++ b/internal/fans/file_test.go @@ -320,8 +320,8 @@ func TestFileFan_GetFanCurveData(t *testing.T) { // GIVEN config := configuration.FanConfig{ File: &configuration.FileFanConfig{ - Path: "../..////", - RpmPath: "../../test/non_existent_file", + Path: "../../test/file_fan_pwm", + RpmPath: "../../test/file_fan_rpm", }, } @@ -341,3 +341,42 @@ func TestFileFan_GetFanCurveData(t *testing.T) { // THEN assert.Equal(t, expectedFanCurve, *result) } + +func TestFileFan_GetCurveId(t *testing.T) { + // GIVEN + curveId := "curveId" + config := configuration.FanConfig{ + Curve: curveId, + File: &configuration.FileFanConfig{ + Path: "../../test/file_fan_pwm", + RpmPath: "../../test/file_fan_rpm", + }, + } + + fan, _ := NewFan(config) + + // WHEN + result := fan.GetCurveId() + + // THEN + assert.Equal(t, curveId, result) +} + +func TestFileFan_ShouldNeverStop(t *testing.T) { + // GIVEN + config := configuration.FanConfig{ + NeverStop: true, + File: &configuration.FileFanConfig{ + Path: "../../test/file_fan_pwm", + RpmPath: "../../test/file_fan_rpm", + }, + } + + fan, _ := NewFan(config) + + // WHEN + result := fan.ShouldNeverStop() + + // THEN + assert.Equal(t, true, result) +}