]> git.giacomolli.uk - onehouse/blob - driver/m31/output_request_test.go
Keep interrupted Modbus work a context stop
[onehouse] / driver / m31 / output_request_test.go
1 package m31
2
3 import (
4 "testing"
5 "time"
6
7 "github.com/stretchr/testify/require"
8 )
9
10 func TestOutputRequestRejectsUnsafeValuesAndAccess(t *testing.T) {
11 d, _, _, _ := testAssembly(t)
12 testCases := []struct {
13 name string
14 point string
15 value string
16 batch bool
17 }{
18 {name: "rejects null Boolean", point: "m0.do0", value: "null"},
19 {name: "rejects numeric Boolean", point: "m0.do0", value: "1"},
20 {name: "rejects string Boolean", point: "m0.do0", value: `"true"`},
21 {name: "rejects input writes", point: "m0.di0", value: "true"},
22 {name: "rejects unknown points", point: "m8.do0", value: "true"},
23 {name: "rejects false pulses", point: "m0.do2", value: "false"},
24 {name: "rejects pulses in batches", point: "m0.do2", value: "true", batch: true},
25 {name: "rejects analog in batches", point: "m2.ao0", value: "5", batch: true},
26 {name: "rejects negative voltage", point: "m2.ao0", value: "-0.00000000000000001"},
27 {name: "rejects excessive voltage without float rounding", point: "m2.ao0", value: "10.00000000000000001"},
28 {name: "rejects string voltage", point: "m2.ao0", value: `"5"`},
29 {name: "rejects null voltage", point: "m2.ao0", value: "null"},
30 {name: "rejects malformed voltage", point: "m2.ao0", value: "5x"},
31 {name: "rejects missing voltage", point: "m2.ao0"},
32 {name: "rejects object voltage", point: "m2.ao0", value: "{}"},
33 }
34
35 for _, tc := range testCases {
36 t.Run(tc.name, func(t *testing.T) {
37 command := testCommand(t, tc.point, tc.value)
38 _, reason := newOutputRequest(command, d.topology, testDeviceID, tc.batch)
39 require.NotEmpty(t, reason)
40 })
41 }
42
43 command := testCommand(t, "m0.do0", "true")
44 command.DeviceID = "01ARZ3NDEKTSV4RRFFQ69G5FAW"
45 _, reason := newOutputRequest(command, d.topology, testDeviceID, false)
46 require.Contains(t, reason, "another device")
47
48 command.DeviceID = testDeviceID
49 expires := time.Now()
50 command.Metadata.ExpiresAt = &expires
51 _, reason = newOutputRequest(command, d.topology, testDeviceID, false)
52 require.Contains(t, reason, "expired")
53 }
54
55 func TestOutputRequestRoundsValidVoltageToMillivolts(t *testing.T) {
56 d, _, _, _ := testAssembly(t)
57 testCases := []struct {
58 name string
59 value string
60 want uint16
61 }{
62 {name: "accepts zero", value: "0"},
63 {name: "accepts full range", value: "10", want: 10000},
64 {name: "rounds half millivolt up", value: "5.5005", want: 5501},
65 {name: "accepts exponent notation", value: "55e-1", want: 5500},
66 {name: "accepts surrounding whitespace", value: " 5.5 ", want: 5500},
67 }
68
69 for _, tc := range testCases {
70 t.Run(tc.name, func(t *testing.T) {
71 request, reason := newOutputRequest(testCommand(t, "m2.ao0", tc.value), d.topology, testDeviceID, false)
72 require.Empty(t, reason)
73 require.Equal(t, tc.want, request.value)
74 })
75 }
76 }