gobot.io/x/gobot/v2@v2.1.0/platforms/jetson/jetson_adaptor_test.go (about) 1 package jetson 2 3 import ( 4 "errors" 5 "fmt" 6 "strings" 7 "testing" 8 9 "runtime" 10 "strconv" 11 "sync" 12 13 "gobot.io/x/gobot/v2" 14 "gobot.io/x/gobot/v2/drivers/gpio" 15 "gobot.io/x/gobot/v2/drivers/i2c" 16 "gobot.io/x/gobot/v2/drivers/spi" 17 "gobot.io/x/gobot/v2/gobottest" 18 "gobot.io/x/gobot/v2/system" 19 ) 20 21 // make sure that this Adaptor fulfills all the required interfaces 22 var _ gobot.Adaptor = (*Adaptor)(nil) 23 var _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) 24 var _ gobot.PWMPinnerProvider = (*Adaptor)(nil) 25 var _ gpio.DigitalReader = (*Adaptor)(nil) 26 var _ gpio.DigitalWriter = (*Adaptor)(nil) 27 var _ i2c.Connector = (*Adaptor)(nil) 28 var _ spi.Connector = (*Adaptor)(nil) 29 30 func initTestAdaptorWithMockedFilesystem(mockPaths []string) (*Adaptor, *system.MockFilesystem) { 31 a := NewAdaptor() 32 fs := a.sys.UseMockFilesystem(mockPaths) 33 if err := a.Connect(); err != nil { 34 panic(err) 35 } 36 return a, fs 37 } 38 39 func TestNewAdaptor(t *testing.T) { 40 a := NewAdaptor() 41 42 gobottest.Assert(t, strings.HasPrefix(a.Name(), "JetsonNano"), true) 43 44 a.SetName("NewName") 45 gobottest.Assert(t, a.Name(), "NewName") 46 } 47 48 func TestFinalize(t *testing.T) { 49 mockPaths := []string{ 50 "/sys/class/gpio/export", 51 "/sys/class/gpio/unexport", 52 "/dev/i2c-1", 53 "/dev/i2c-0", 54 "/dev/spidev0.0", 55 "/dev/spidev0.1", 56 } 57 a, _ := initTestAdaptorWithMockedFilesystem(mockPaths) 58 59 a.DigitalWrite("3", 1) 60 61 a.GetI2cConnection(0xff, 0) 62 gobottest.Assert(t, a.Finalize(), nil) 63 } 64 65 func TestPWMPinsConnect(t *testing.T) { 66 a := NewAdaptor() 67 gobottest.Assert(t, a.pwmPins, (map[string]gobot.PWMPinner)(nil)) 68 69 err := a.PwmWrite("33", 1) 70 gobottest.Assert(t, err.Error(), "not connected") 71 72 err = a.Connect() 73 gobottest.Assert(t, err, nil) 74 gobottest.Refute(t, a.pwmPins, (map[string]gobot.PWMPinner)(nil)) 75 gobottest.Assert(t, len(a.pwmPins), 0) 76 } 77 78 func TestPWMPinsReConnect(t *testing.T) { 79 // arrange 80 mockPaths := []string{ 81 "/sys/class/pwm/pwmchip0/export", 82 "/sys/class/pwm/pwmchip0/unexport", 83 "/sys/class/pwm/pwmchip0/pwm2/duty_cycle", 84 "/sys/class/pwm/pwmchip0/pwm2/period", 85 "/sys/class/pwm/pwmchip0/pwm2/enable", 86 } 87 a, _ := initTestAdaptorWithMockedFilesystem(mockPaths) 88 gobottest.Assert(t, len(a.pwmPins), 0) 89 gobottest.Assert(t, a.PwmWrite("33", 1), nil) 90 gobottest.Assert(t, len(a.pwmPins), 1) 91 gobottest.Assert(t, a.Finalize(), nil) 92 // act 93 err := a.Connect() 94 // assert 95 gobottest.Assert(t, err, nil) 96 gobottest.Assert(t, len(a.pwmPins), 0) 97 } 98 99 func TestDigitalIO(t *testing.T) { 100 mockPaths := []string{ 101 "/sys/class/gpio/export", 102 "/sys/class/gpio/unexport", 103 "/sys/class/gpio/gpio216/value", 104 "/sys/class/gpio/gpio216/direction", 105 "/sys/class/gpio/gpio14/value", 106 "/sys/class/gpio/gpio14/direction", 107 } 108 a, fs := initTestAdaptorWithMockedFilesystem(mockPaths) 109 110 err := a.DigitalWrite("7", 1) 111 gobottest.Assert(t, err, nil) 112 gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio216/value"].Contents, "1") 113 114 err = a.DigitalWrite("13", 1) 115 gobottest.Assert(t, err, nil) 116 i, err := a.DigitalRead("13") 117 gobottest.Assert(t, err, nil) 118 gobottest.Assert(t, i, 1) 119 120 gobottest.Assert(t, a.DigitalWrite("notexist", 1), errors.New("'notexist' is not a valid id for a digital pin")) 121 gobottest.Assert(t, a.Finalize(), nil) 122 } 123 124 func TestDigitalPinConcurrency(t *testing.T) { 125 oldProcs := runtime.GOMAXPROCS(0) 126 runtime.GOMAXPROCS(8) 127 defer runtime.GOMAXPROCS(oldProcs) 128 129 for retry := 0; retry < 20; retry++ { 130 131 a := NewAdaptor() 132 var wg sync.WaitGroup 133 134 for i := 0; i < 20; i++ { 135 wg.Add(1) 136 pinAsString := strconv.Itoa(i) 137 go func(pin string) { 138 defer wg.Done() 139 a.DigitalPin(pin) 140 }(pinAsString) 141 } 142 143 wg.Wait() 144 } 145 } 146 147 func TestSpiDefaultValues(t *testing.T) { 148 a := NewAdaptor() 149 150 gobottest.Assert(t, a.SpiDefaultBusNumber(), 0) 151 gobottest.Assert(t, a.SpiDefaultChipNumber(), 0) 152 gobottest.Assert(t, a.SpiDefaultMode(), 0) 153 gobottest.Assert(t, a.SpiDefaultMaxSpeed(), int64(10000000)) 154 } 155 156 func TestI2cDefaultBus(t *testing.T) { 157 a := NewAdaptor() 158 gobottest.Assert(t, a.DefaultI2cBus(), 1) 159 } 160 161 func TestI2cFinalizeWithErrors(t *testing.T) { 162 // arrange 163 a := NewAdaptor() 164 a.sys.UseMockSyscall() 165 fs := a.sys.UseMockFilesystem([]string{"/dev/i2c-1"}) 166 gobottest.Assert(t, a.Connect(), nil) 167 con, err := a.GetI2cConnection(0xff, 1) 168 gobottest.Assert(t, err, nil) 169 _, err = con.Write([]byte{0xbf}) 170 gobottest.Assert(t, err, nil) 171 fs.WithCloseError = true 172 // act 173 err = a.Finalize() 174 // assert 175 gobottest.Assert(t, strings.Contains(err.Error(), "close error"), true) 176 } 177 178 func Test_validateSpiBusNumber(t *testing.T) { 179 var tests = map[string]struct { 180 busNr int 181 wantErr error 182 }{ 183 "number_negative_error": { 184 busNr: -1, 185 wantErr: fmt.Errorf("Bus number -1 out of range"), 186 }, 187 "number_0_ok": { 188 busNr: 0, 189 }, 190 "number_1_ok": { 191 busNr: 1, 192 }, 193 "number_2_error": { 194 busNr: 2, 195 wantErr: fmt.Errorf("Bus number 2 out of range"), 196 }, 197 } 198 for name, tc := range tests { 199 t.Run(name, func(t *testing.T) { 200 // arrange 201 a := NewAdaptor() 202 // act 203 err := a.validateSpiBusNumber(tc.busNr) 204 // assert 205 gobottest.Assert(t, err, tc.wantErr) 206 }) 207 } 208 } 209 210 func Test_validateI2cBusNumber(t *testing.T) { 211 var tests = map[string]struct { 212 busNr int 213 wantErr error 214 }{ 215 "number_negative_error": { 216 busNr: -1, 217 wantErr: fmt.Errorf("Bus number -1 out of range"), 218 }, 219 "number_0_ok": { 220 busNr: 0, 221 }, 222 "number_1_ok": { 223 busNr: 1, 224 }, 225 "number_2_not_ok": { 226 busNr: 2, 227 wantErr: fmt.Errorf("Bus number 2 out of range"), 228 }, 229 } 230 for name, tc := range tests { 231 t.Run(name, func(t *testing.T) { 232 // arrange 233 a := NewAdaptor() 234 // act 235 err := a.validateI2cBusNumber(tc.busNr) 236 // assert 237 gobottest.Assert(t, err, tc.wantErr) 238 }) 239 } 240 }