X-Git-Url: https://git.giacomolli.uk/onehouse/blobdiff_plain/f9e4f329fbb3381ad8f16ade26a62560e3c2b951..920de226fe0914003a350a93e311039a02b684d7:/driver/m31/fake_helper_test.go?ds=sidebyside diff --git a/driver/m31/fake_helper_test.go b/driver/m31/fake_helper_test.go index c53dbac..6b5a1d4 100644 --- a/driver/m31/fake_helper_test.go +++ b/driver/m31/fake_helper_test.go @@ -18,27 +18,30 @@ import ( const testDeviceID = "01ARZ3NDEKTSV4RRFFQ69G5FAV" type fakeClient struct { - mu sync.Mutex - inputs []bool - coils []bool - analog []uint16 - registers map[uint16]uint16 - writes []coilWrite - registerWrites []uint16 - attempts []time.Time - closes int - coilReads int - connectErrors []error - inputErr error - readErr error - writeErr error - registerErr error - closeErr error - wrongConfig bool - shortRead bool - mismatch int - writeDelay time.Duration - inputDelay time.Duration + registerReadErr error + wrongRegister uint16 + failAfterWrites int + mu sync.Mutex + inputs []bool + coils []bool + analog []uint16 + registers map[uint16]uint16 + writes []coilWrite + registerWrites []uint16 + attempts []time.Time + closes int + coilReads int + connectErrors []error + inputErr error + readErr error + writeErr error + registerErr error + closeErr error + wrongConfig bool + shortRead bool + mismatch int + writeDelay time.Duration + inputDelay time.Duration } func (c *fakeClient) Connect(ctx context.Context, _ string, _ byte) error { @@ -98,13 +101,13 @@ func (c *fakeClient) ReadRegisters(ctx context.Context, address uint16, count ui c.mu.Lock() defer c.mu.Unlock() - if c.registerErr != nil || ctx.Err() != nil { - return nil, errors.Join(c.registerErr, ctx.Err()) + if c.registerErr != nil || c.registerReadErr != nil || ctx.Err() != nil { + return nil, errors.Join(c.registerErr, c.registerReadErr, ctx.Err()) } if address >= pulseWidthBase { value := c.registers[address] - if c.wrongConfig { + if c.wrongConfig || address == c.wrongRegister { value++ } @@ -128,7 +131,7 @@ func (c *fakeClient) write(ctx context.Context, address uint16, values []bool, m time.Sleep(c.writeDelay) - if c.writeErr != nil || ctx.Err() != nil { + if c.writeErr != nil && len(c.writes) >= c.failAfterWrites || ctx.Err() != nil { return errors.Join(c.writeErr, ctx.Err()) } @@ -182,6 +185,7 @@ type fakeTransport struct { mu sync.Mutex messages []protocol.Message[any] failKind protocol.Kind + failOnce bool err error } @@ -195,7 +199,12 @@ func (f *fakeTransport) Publish(ctx context.Context, publication protocol.Public } if message.Address.Kind == f.failKind && f.err != nil { - return f.err + err = f.err + if f.failOnce { + f.err = nil + } + + return err } if ctx.Err() != nil { @@ -229,11 +238,14 @@ func (f *fakeTransport) all() []protocol.Message[any] { return slices.Clone(f.messages) } -func testAssembly(t *testing.T) (*Driver, *fakeClient, *fakeTransport) { +func testAssembly(t *testing.T) (*Driver, *fakeClient, *fakeTransport, *driver.Router) { t.Helper() transport := &fakeTransport{} publisher := driver.NewPublisher(transport) + router, err := driver.NewRouter([]string{testDeviceID}) + require.NoError(t, err) + client := &fakeClient{ inputs: make([]bool, 16), coils: make([]bool, 32), @@ -253,16 +265,35 @@ func testAssembly(t *testing.T) (*Driver, *fakeClient, *fakeTransport) { {Model: MixedModel}, }, } - d, err := New(settings, publisher, client) + d, err := New(settings, publisher, router, client) + require.NoError(t, err) + + return d, client, transport, router +} + +func testCommand(t *testing.T, capability string, value string) driver.Command { + t.Helper() + + id, err := protocol.NewID(time.Now()) require.NoError(t, err) - return d, client, transport + expires := time.Now().UTC().Add(time.Minute) + + return driver.Command{ + DeviceID: testDeviceID, + Capability: capability, + Metadata: protocol.Metadata{ + MessageID: id, + ExpiresAt: &expires, + }, + Payload: protocol.ValuePayload{Value: []byte(value)}, + } } func testConnection(t *testing.T) (*connection, *fakeClient, *fakeTransport) { t.Helper() - d, client, transport := testAssembly(t) + d, client, transport, _ := testAssembly(t) connection := &connection{owner: d} require.NoError(t, connection.start(t.Context())) @@ -272,3 +303,32 @@ func testConnection(t *testing.T) (*connection, *fakeClient, *fakeTransport) { return connection, client, transport } + +func queueCommands(t *testing.T, router *driver.Router, commands []driver.Command) { + t.Helper() + + var ( + publication protocol.Publication + err error + ) + + if len(commands) == 1 { + command := commands[0] + publication, err = protocol.BuildCommand(command.DeviceID, command.Capability, command.Metadata, command.Payload) + } else { + members := make([]protocol.BatchCommand, len(commands)) + + for index, command := range commands { + members[index] = protocol.BatchCommand{ + Capability: command.Capability, + Metadata: command.Metadata, + Payload: command.Payload, + } + } + + publication, err = protocol.BuildCommandBatch(testDeviceID, commands[0].Metadata, protocol.BatchPayload{Commands: members}) + } + + require.NoError(t, err) + require.NoError(t, router.Handle(t.Context(), publication.Topic, publication.Data, false)) +}