You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
2.7 KiB
94 lines
2.7 KiB
package greenledsocket
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"io"
|
|
"net"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"tera-clone/services/tera-api/internal/hardware/greenled"
|
|
)
|
|
|
|
func TestServerRespondsToNewlineFramedRequestWithoutWaitingForEOF(t *testing.T) {
|
|
serverConnection, clientConnection := net.Pipe()
|
|
defer clientConnection.Close()
|
|
done := make(chan struct{})
|
|
go func() {
|
|
(Server{}).handleConnection(serverConnection)
|
|
close(done)
|
|
}()
|
|
if err := clientConnection.SetDeadline(time.Now().Add(time.Second)); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if _, err := io.WriteString(clientConnection, "{\"action\":\"unsupported\"}\n"); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var result response
|
|
if err := json.NewDecoder(clientConnection).Decode(&result); err != nil {
|
|
t.Fatalf("decode response before client EOF: %v", err)
|
|
}
|
|
if result.Code != "validation_failed" || result.Error != "hardware control action is not supported" {
|
|
t.Fatalf("response = %#v", result)
|
|
}
|
|
select {
|
|
case <-done:
|
|
case <-time.After(time.Second):
|
|
t.Fatal("server did not close the completed request")
|
|
}
|
|
}
|
|
|
|
func TestClientAndServerControlOnlyMappedGPIOLEDs(t *testing.T) {
|
|
root := t.TempDir()
|
|
for channel := 1; channel <= greenled.ChannelCount; channel++ {
|
|
name := "ch" + twoDigits(channel) + "-green-led-force"
|
|
if err := os.MkdirAll(filepath.Join(root, name), 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(root, name, "brightness"), []byte("0\n"), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
socketPath := filepath.Join(t.TempDir(), "green-leds.sock")
|
|
listener, err := net.Listen("unix", socketPath)
|
|
if err != nil {
|
|
t.Skipf("unix sockets unavailable: %v", err)
|
|
}
|
|
defer listener.Close()
|
|
|
|
server := Server{Controller: greenled.NewSysfsController(root)}
|
|
done := make(chan error, 1)
|
|
go func() { done <- server.Serve(listener) }()
|
|
client := NewClient(socketPath)
|
|
|
|
states, err := client.States(context.Background())
|
|
if err != nil || len(states) != greenled.ChannelCount || states[8].Channel != "CH09" || states[8].I2CAddress != "0x21" || states[8].GPIOOffset != 0 {
|
|
t.Fatalf("states = %#v, %v", states, err)
|
|
}
|
|
state, err := client.SetForce(context.Background(), "CH09", true)
|
|
if err != nil || !state.Forced {
|
|
t.Fatalf("set force = %#v, %v", state, err)
|
|
}
|
|
state, err = client.Pulse(context.Background(), "CH09", greenled.MinPulseDuration)
|
|
if err != nil || state.Forced {
|
|
t.Fatalf("pulse = %#v, %v", state, err)
|
|
}
|
|
if err := listener.Close(); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
select {
|
|
case err := <-done:
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
case <-time.After(time.Second):
|
|
t.Fatal("server did not stop")
|
|
}
|
|
}
|
|
|
|
func twoDigits(value int) string {
|
|
return string(rune('0'+value/10)) + string(rune('0'+value%10))
|
|
}
|
|
|