gobot.io/x/gobot/v2@v2.1.0/platforms/intel-iot/joule/joule_adaptor_test.go (about) 1 package joule 2 3 import ( 4 "errors" 5 "fmt" 6 "strings" 7 "testing" 8 9 "gobot.io/x/gobot/v2" 10 "gobot.io/x/gobot/v2/drivers/gpio" 11 "gobot.io/x/gobot/v2/drivers/i2c" 12 "gobot.io/x/gobot/v2/gobottest" 13 "gobot.io/x/gobot/v2/system" 14 ) 15 16 // make sure that this Adaptor fulfills all the required interfaces 17 var _ gobot.Adaptor = (*Adaptor)(nil) 18 var _ gobot.DigitalPinnerProvider = (*Adaptor)(nil) 19 var _ gobot.PWMPinnerProvider = (*Adaptor)(nil) 20 var _ gpio.DigitalReader = (*Adaptor)(nil) 21 var _ gpio.DigitalWriter = (*Adaptor)(nil) 22 var _ gpio.PwmWriter = (*Adaptor)(nil) 23 var _ i2c.Connector = (*Adaptor)(nil) 24 25 func initTestAdaptorWithMockedFilesystem() (*Adaptor, *system.MockFilesystem) { 26 a := NewAdaptor() 27 mockPaths := []string{ 28 "/sys/class/pwm/pwmchip0/export", 29 "/sys/class/pwm/pwmchip0/unexport", 30 "/sys/class/pwm/pwmchip0/pwm0/duty_cycle", 31 "/sys/class/pwm/pwmchip0/pwm0/period", 32 "/sys/class/pwm/pwmchip0/pwm0/enable", 33 "/sys/class/gpio/export", 34 "/sys/class/gpio/unexport", 35 "/sys/class/gpio/gpio13/value", 36 "/sys/class/gpio/gpio13/direction", 37 "/sys/class/gpio/gpio40/value", 38 "/sys/class/gpio/gpio40/direction", 39 "/sys/class/gpio/gpio446/value", 40 "/sys/class/gpio/gpio446/direction", 41 "/sys/class/gpio/gpio463/value", 42 "/sys/class/gpio/gpio463/direction", 43 "/sys/class/gpio/gpio421/value", 44 "/sys/class/gpio/gpio421/direction", 45 "/sys/class/gpio/gpio221/value", 46 "/sys/class/gpio/gpio221/direction", 47 "/sys/class/gpio/gpio243/value", 48 "/sys/class/gpio/gpio243/direction", 49 "/sys/class/gpio/gpio229/value", 50 "/sys/class/gpio/gpio229/direction", 51 "/sys/class/gpio/gpio253/value", 52 "/sys/class/gpio/gpio253/direction", 53 "/sys/class/gpio/gpio261/value", 54 "/sys/class/gpio/gpio261/direction", 55 "/sys/class/gpio/gpio214/value", 56 "/sys/class/gpio/gpio214/direction", 57 "/sys/class/gpio/gpio14/direction", 58 "/sys/class/gpio/gpio14/value", 59 "/sys/class/gpio/gpio165/direction", 60 "/sys/class/gpio/gpio165/value", 61 "/sys/class/gpio/gpio212/direction", 62 "/sys/class/gpio/gpio212/value", 63 "/sys/class/gpio/gpio213/direction", 64 "/sys/class/gpio/gpio213/value", 65 "/sys/class/gpio/gpio236/direction", 66 "/sys/class/gpio/gpio236/value", 67 "/sys/class/gpio/gpio237/direction", 68 "/sys/class/gpio/gpio237/value", 69 "/sys/class/gpio/gpio204/direction", 70 "/sys/class/gpio/gpio204/value", 71 "/sys/class/gpio/gpio205/direction", 72 "/sys/class/gpio/gpio205/value", 73 "/sys/class/gpio/gpio263/direction", 74 "/sys/class/gpio/gpio263/value", 75 "/sys/class/gpio/gpio262/direction", 76 "/sys/class/gpio/gpio262/value", 77 "/sys/class/gpio/gpio240/direction", 78 "/sys/class/gpio/gpio240/value", 79 "/sys/class/gpio/gpio241/direction", 80 "/sys/class/gpio/gpio241/value", 81 "/sys/class/gpio/gpio242/direction", 82 "/sys/class/gpio/gpio242/value", 83 "/sys/class/gpio/gpio218/direction", 84 "/sys/class/gpio/gpio218/value", 85 "/sys/class/gpio/gpio250/direction", 86 "/sys/class/gpio/gpio250/value", 87 "/sys/class/gpio/gpio451/direction", 88 "/sys/class/gpio/gpio451/value", 89 "/dev/i2c-0", 90 } 91 fs := a.sys.UseMockFilesystem(mockPaths) 92 fs.Files["/sys/class/pwm/pwmchip0/pwm0/period"].Contents = "5000" 93 if err := a.Connect(); err != nil { 94 panic(err) 95 } 96 return a, fs 97 } 98 99 func TestName(t *testing.T) { 100 a, _ := initTestAdaptorWithMockedFilesystem() 101 102 gobottest.Assert(t, strings.HasPrefix(a.Name(), "Joule"), true) 103 a.SetName("NewName") 104 gobottest.Assert(t, a.Name(), "NewName") 105 } 106 107 func TestFinalize(t *testing.T) { 108 a, _ := initTestAdaptorWithMockedFilesystem() 109 110 a.DigitalWrite("J12_1", 1) 111 a.PwmWrite("J12_26", 100) 112 113 gobottest.Assert(t, a.Finalize(), nil) 114 115 // assert finalize after finalize is working 116 gobottest.Assert(t, a.Finalize(), nil) 117 118 // assert re-connect is working 119 gobottest.Assert(t, a.Connect(), nil) 120 } 121 122 func TestDigitalIO(t *testing.T) { 123 a, fs := initTestAdaptorWithMockedFilesystem() 124 125 a.DigitalWrite("J12_1", 1) 126 gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio451/value"].Contents, "1") 127 128 a.DigitalWrite("J12_1", 0) 129 130 i, err := a.DigitalRead("J12_1") 131 gobottest.Assert(t, err, nil) 132 gobottest.Assert(t, i, 0) 133 134 _, err = a.DigitalRead("P9_99") 135 gobottest.Assert(t, err, errors.New("'P9_99' is not a valid id for a digital pin")) 136 } 137 138 func TestPwm(t *testing.T) { 139 a, fs := initTestAdaptorWithMockedFilesystem() 140 141 err := a.PwmWrite("J12_26", 100) 142 gobottest.Assert(t, err, nil) 143 gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm0/duty_cycle"].Contents, "3921568") 144 145 err = a.PwmWrite("4", 100) 146 gobottest.Assert(t, err, errors.New("'4' is not a valid id for a pin")) 147 148 err = a.PwmWrite("J12_1", 100) 149 gobottest.Assert(t, err, errors.New("'J12_1' is not a valid id for a PWM pin")) 150 } 151 152 func TestPwmPinExportError(t *testing.T) { 153 a, fs := initTestAdaptorWithMockedFilesystem() 154 delete(fs.Files, "/sys/class/pwm/pwmchip0/export") 155 156 err := a.PwmWrite("J12_26", 100) 157 gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/pwm/pwmchip0/export: no such file"), true) 158 } 159 160 func TestPwmPinEnableError(t *testing.T) { 161 a, fs := initTestAdaptorWithMockedFilesystem() 162 delete(fs.Files, "/sys/class/pwm/pwmchip0/pwm0/enable") 163 164 err := a.PwmWrite("J12_26", 100) 165 gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/pwm/pwmchip0/pwm0/enable: no such file"), true) 166 } 167 168 func TestI2cDefaultBus(t *testing.T) { 169 a := NewAdaptor() 170 gobottest.Assert(t, a.DefaultI2cBus(), 0) 171 } 172 173 func TestI2cFinalizeWithErrors(t *testing.T) { 174 // arrange 175 a := NewAdaptor() 176 a.sys.UseMockSyscall() 177 fs := a.sys.UseMockFilesystem([]string{"/dev/i2c-2"}) 178 gobottest.Assert(t, a.Connect(), nil) 179 con, err := a.GetI2cConnection(0xff, 2) 180 gobottest.Assert(t, err, nil) 181 _, err = con.Write([]byte{0xbf}) 182 gobottest.Assert(t, err, nil) 183 fs.WithCloseError = true 184 // act 185 err = a.Finalize() 186 // assert 187 gobottest.Assert(t, strings.Contains(err.Error(), "close error"), true) 188 } 189 190 func Test_validateI2cBusNumber(t *testing.T) { 191 var tests = map[string]struct { 192 busNr int 193 wantErr error 194 }{ 195 "number_negative_error": { 196 busNr: -1, 197 wantErr: fmt.Errorf("Bus number -1 out of range"), 198 }, 199 "number_0_ok": { 200 busNr: 0, 201 }, 202 "number_1_ok": { 203 busNr: 1, 204 }, 205 "number_2_ok": { 206 busNr: 2, 207 }, 208 "number_3_error": { 209 busNr: 3, 210 wantErr: fmt.Errorf("Bus number 3 out of range"), 211 }, 212 } 213 for name, tc := range tests { 214 t.Run(name, func(t *testing.T) { 215 // arrange 216 a := NewAdaptor() 217 // act 218 err := a.validateI2cBusNumber(tc.busNr) 219 // assert 220 gobottest.Assert(t, err, tc.wantErr) 221 }) 222 } 223 }