Files
compute-blade-agent/pkg/ledengine/ledengine_test.go
Cedric Kienzler 631ddfedd4 chore: update repository references from uptime-industries to computeblade-community (#70)
* chore: update repository references from uptime-industries to compute-blade-community

chore: update repository references from uptime-industries to compute-blade-community for consistency and clarity across all files
fix: update links in CHANGELOG.md and README.md to point to the new repository location for accurate documentation
fix: update Dockerfile and systemd service file to reflect the new repository URL for proper source tracking
refactor: change import paths in Go files to use the new repository name for correct package referencing

* chore: Add CODEOWNERS

* feat: add auto-labeling

---------

Co-authored-by: Cedric Kienzler <cedric@specht-labs.de>
2025-06-06 14:40:06 +02:00

257 lines
6.1 KiB
Go

package ledengine_test
import (
"context"
"errors"
"reflect"
"sync"
"testing"
"time"
"github.com/compute-blade-community/compute-blade-agent/pkg/hal"
"github.com/compute-blade-community/compute-blade-agent/pkg/hal/led"
"github.com/compute-blade-community/compute-blade-agent/pkg/ledengine"
"github.com/compute-blade-community/compute-blade-agent/pkg/util"
"github.com/stretchr/testify/assert"
)
func TestNewStaticPattern(t *testing.T) {
t.Parallel()
type args struct {
color led.Color
}
tests := []struct {
name string
args args
want ledengine.BlinkPattern
}{
{
"Green",
args{led.Color{Green: 255}},
ledengine.BlinkPattern{
BaseColor: led.Color{Green: 255},
ActiveColor: led.Color{Green: 255},
Delays: []time.Duration{time.Hour},
},
},
{
"Red",
args{led.Color{Red: 255}},
ledengine.BlinkPattern{
BaseColor: led.Color{Red: 255},
ActiveColor: led.Color{Red: 255},
Delays: []time.Duration{time.Hour},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := ledengine.NewStaticPattern(tt.args.color); !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewStaticPattern() = %v, want %v", got, tt.want)
}
})
}
}
func TestNewBurstPattern(t *testing.T) {
t.Parallel()
type args struct {
baseColor led.Color
burstColor led.Color
}
tests := []struct {
name string
args args
want ledengine.BlinkPattern
}{
{
"Green <-> Red",
args{
baseColor: led.Color{Green: 255},
burstColor: led.Color{Red: 255},
},
ledengine.BlinkPattern{
BaseColor: led.Color{Green: 255},
ActiveColor: led.Color{Red: 255},
Delays: []time.Duration{
500 * time.Millisecond, // 750ms off
100 * time.Millisecond, // 100ms on
100 * time.Millisecond, // 100ms off
100 * time.Millisecond, // 100ms on
100 * time.Millisecond, // 100ms off
100 * time.Millisecond, // 100ms on
},
},
},
{
"Green <-> Green (valid, but no visual effect)",
args{
baseColor: led.Color{Green: 255},
burstColor: led.Color{Green: 255},
},
ledengine.BlinkPattern{
BaseColor: led.Color{Green: 255},
ActiveColor: led.Color{Green: 255},
Delays: []time.Duration{
500 * time.Millisecond, // 750ms off
100 * time.Millisecond, // 100ms on
100 * time.Millisecond, // 100ms off
100 * time.Millisecond, // 100ms on
100 * time.Millisecond, // 100ms off
100 * time.Millisecond, // 100ms on
},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := ledengine.NewBurstPattern(tt.args.baseColor, tt.args.burstColor); !reflect.DeepEqual(got, tt.want) {
t.Errorf("NewBurstPattern() = %v, want %v", got, tt.want)
}
})
}
}
func TestNewLedEngine(t *testing.T) {
t.Parallel()
engine := ledengine.Options{
Clock: util.RealClock{},
LedIdx: 0,
Hal: &hal.ComputeBladeHalMock{},
}
assert.NotNil(t, engine)
}
func Test_LedEngine_SetPattern_WhileRunning(t *testing.T) {
t.Parallel()
clk := util.MockClock{}
clkAfterChan := make(chan time.Time)
clk.On("After", time.Hour).Times(2).Return(clkAfterChan)
cbMock := hal.ComputeBladeHalMock{}
cbMock.On("SetLed", uint(0), led.Color{Green: 0, Blue: 0, Red: 0}).Once().Return(nil)
cbMock.On("SetLed", uint(0), led.Color{Green: 0, Blue: 0, Red: 255}).Once().Return(nil)
opts := ledengine.Options{
Hal: &cbMock,
Clock: &clk,
LedIdx: 0,
}
engine := ledengine.NewLedEngine(opts)
ctx, cancel := context.WithCancel(context.Background())
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
defer wg.Done()
t.Log("LedEngine.Run() started")
err := engine.Run(ctx)
assert.ErrorIs(t, err, context.Canceled)
t.Log("LedEngine.Run() exited")
}()
// We want to change the pattern while the engine is running
time.Sleep(5 * time.Millisecond)
// Set pattern
t.Log("Setting pattern")
err := engine.SetPattern(ledengine.NewStaticPattern(led.Color{Red: 255}))
assert.NoError(t, err)
t.Log("Canceling context")
cancel()
wg.Wait()
clk.AssertExpectations(t)
cbMock.AssertExpectations(t)
}
func Test_LedEngine_SetPattern_BeforeRun(t *testing.T) {
t.Parallel()
clk := util.MockClock{}
clkAfterChan := make(chan time.Time)
clk.On("After", time.Hour).Once().Return(clkAfterChan)
cbMock := hal.ComputeBladeHalMock{}
cbMock.On("SetLed", uint(0), led.Color{Green: 0, Blue: 0, Red: 255}).Once().Return(nil)
opts := ledengine.Options{
Hal: &cbMock,
Clock: &clk,
LedIdx: 0,
}
engine := ledengine.NewLedEngine(opts)
// We want to change the pattern BEFORE the engine is started
t.Log("Setting pattern")
err := engine.SetPattern(ledengine.NewStaticPattern(led.Color{Red: 255}))
assert.NoError(t, err)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)
defer cancel()
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
defer wg.Done()
t.Log("LedEngine.Run() started")
err := engine.Run(ctx)
assert.ErrorIs(t, err, context.DeadlineExceeded)
t.Log("LedEngine.Run() exited")
}()
t.Log("Waiting for context to timeout")
wg.Wait()
clk.AssertExpectations(t)
cbMock.AssertExpectations(t)
}
func Test_LedEngine_SetPattern_SetLedFailureInPattern(t *testing.T) {
t.Parallel()
clk := util.MockClock{}
clkAfterChan := make(chan time.Time)
clk.On("After", time.Hour).Once().Return(clkAfterChan)
cbMock := hal.ComputeBladeHalMock{}
call0 := cbMock.On("SetLed", uint(0), led.Color{Green: 0, Blue: 0, Red: 0}).Once().Return(nil)
cbMock.On("SetLed", uint(0), led.Color{Green: 0, Blue: 0, Red: 0}).Once().Return(errors.New("failure")).NotBefore(call0)
opts := ledengine.Options{
Hal: &cbMock,
Clock: &clk,
LedIdx: 0,
}
engine := ledengine.NewLedEngine(opts)
ctx, cancel := context.WithTimeout(context.Background(), 10*time.Millisecond)
defer cancel()
wg := sync.WaitGroup{}
wg.Add(1)
go func() {
defer wg.Done()
t.Log("LedEngine.Run() started")
err := engine.Run(ctx)
assert.Error(t, err)
t.Log("LedEngine.Run() exited")
}()
time.Sleep(5 * time.Millisecond)
// Time tick -> SetLed() fails
clkAfterChan <- time.Now()
t.Log("Waiting for context to timeout")
wg.Wait()
clk.AssertExpectations(t)
cbMock.AssertExpectations(t)
}