gobot.io/x/gobot@v1.16.0/platforms/intel-iot/edison/edison_adaptor_test.go (about) 1 package edison 2 3 import ( 4 "errors" 5 "strings" 6 "testing" 7 8 "gobot.io/x/gobot" 9 "gobot.io/x/gobot/drivers/aio" 10 "gobot.io/x/gobot/drivers/gpio" 11 "gobot.io/x/gobot/drivers/i2c" 12 "gobot.io/x/gobot/gobottest" 13 "gobot.io/x/gobot/sysfs" 14 ) 15 16 // make sure that this Adaptor fullfills all the required interfaces 17 var _ gobot.Adaptor = (*Adaptor)(nil) 18 var _ gpio.DigitalReader = (*Adaptor)(nil) 19 var _ gpio.DigitalWriter = (*Adaptor)(nil) 20 var _ aio.AnalogReader = (*Adaptor)(nil) 21 var _ gpio.PwmWriter = (*Adaptor)(nil) 22 var _ sysfs.DigitalPinnerProvider = (*Adaptor)(nil) 23 var _ sysfs.PWMPinnerProvider = (*Adaptor)(nil) 24 var _ i2c.Connector = (*Adaptor)(nil) 25 26 var testPinFiles = []string{ 27 "/sys/bus/iio/devices/iio:device1/in_voltage0_raw", 28 "/sys/kernel/debug/gpio_debug/gpio111/current_pinmux", 29 "/sys/kernel/debug/gpio_debug/gpio115/current_pinmux", 30 "/sys/kernel/debug/gpio_debug/gpio114/current_pinmux", 31 "/sys/kernel/debug/gpio_debug/gpio109/current_pinmux", 32 "/sys/kernel/debug/gpio_debug/gpio131/current_pinmux", 33 "/sys/kernel/debug/gpio_debug/gpio129/current_pinmux", 34 "/sys/kernel/debug/gpio_debug/gpio40/current_pinmux", 35 "/sys/kernel/debug/gpio_debug/gpio13/current_pinmux", 36 "/sys/kernel/debug/gpio_debug/gpio28/current_pinmux", 37 "/sys/kernel/debug/gpio_debug/gpio27/current_pinmux", 38 "/sys/class/pwm/pwmchip0/export", 39 "/sys/class/pwm/pwmchip0/unexport", 40 "/sys/class/pwm/pwmchip0/pwm1/duty_cycle", 41 "/sys/class/pwm/pwmchip0/pwm1/period", 42 "/sys/class/pwm/pwmchip0/pwm1/enable", 43 "/sys/class/gpio/export", 44 "/sys/class/gpio/unexport", 45 "/sys/class/gpio/gpio13/value", 46 "/sys/class/gpio/gpio13/direction", 47 "/sys/class/gpio/gpio40/value", 48 "/sys/class/gpio/gpio40/direction", 49 "/sys/class/gpio/gpio128/value", 50 "/sys/class/gpio/gpio128/direction", 51 "/sys/class/gpio/gpio221/value", 52 "/sys/class/gpio/gpio221/direction", 53 "/sys/class/gpio/gpio243/value", 54 "/sys/class/gpio/gpio243/direction", 55 "/sys/class/gpio/gpio229/value", 56 "/sys/class/gpio/gpio229/direction", 57 "/sys/class/gpio/gpio253/value", 58 "/sys/class/gpio/gpio253/direction", 59 "/sys/class/gpio/gpio261/value", 60 "/sys/class/gpio/gpio261/direction", 61 "/sys/class/gpio/gpio214/value", 62 "/sys/class/gpio/gpio214/direction", 63 "/sys/class/gpio/gpio14/direction", 64 "/sys/class/gpio/gpio14/value", 65 "/sys/class/gpio/gpio165/direction", 66 "/sys/class/gpio/gpio165/value", 67 "/sys/class/gpio/gpio212/direction", 68 "/sys/class/gpio/gpio212/value", 69 "/sys/class/gpio/gpio213/direction", 70 "/sys/class/gpio/gpio213/value", 71 "/sys/class/gpio/gpio236/direction", 72 "/sys/class/gpio/gpio236/value", 73 "/sys/class/gpio/gpio237/direction", 74 "/sys/class/gpio/gpio237/value", 75 "/sys/class/gpio/gpio204/direction", 76 "/sys/class/gpio/gpio204/value", 77 "/sys/class/gpio/gpio205/direction", 78 "/sys/class/gpio/gpio205/value", 79 "/sys/class/gpio/gpio263/direction", 80 "/sys/class/gpio/gpio263/value", 81 "/sys/class/gpio/gpio262/direction", 82 "/sys/class/gpio/gpio262/value", 83 "/sys/class/gpio/gpio240/direction", 84 "/sys/class/gpio/gpio240/value", 85 "/sys/class/gpio/gpio241/direction", 86 "/sys/class/gpio/gpio241/value", 87 "/sys/class/gpio/gpio242/direction", 88 "/sys/class/gpio/gpio242/value", 89 "/sys/class/gpio/gpio218/direction", 90 "/sys/class/gpio/gpio218/value", 91 "/sys/class/gpio/gpio250/direction", 92 "/sys/class/gpio/gpio250/value", 93 "/dev/i2c-6", 94 } 95 96 func initTestAdaptor() (*Adaptor, *sysfs.MockFilesystem) { 97 a := NewAdaptor() 98 fs := sysfs.NewMockFilesystem(testPinFiles) 99 sysfs.SetFilesystem(fs) 100 fs.Files["/sys/class/pwm/pwmchip0/pwm1/period"].Contents = "5000" 101 a.Connect() 102 return a, fs 103 } 104 105 func TestEdisonAdaptorName(t *testing.T) { 106 a, _ := initTestAdaptor() 107 gobottest.Assert(t, strings.HasPrefix(a.Name(), "Edison"), true) 108 a.SetName("NewName") 109 gobottest.Assert(t, a.Name(), "NewName") 110 } 111 112 func TestAdaptorConnect(t *testing.T) { 113 a, _ := initTestAdaptor() 114 gobottest.Assert(t, a.Connect(), nil) 115 gobottest.Assert(t, a.GetDefaultBus(), 6) 116 gobottest.Assert(t, a.Board(), "arduino") 117 118 gobottest.Assert(t, a.Connect(), nil) 119 } 120 121 func TestAdaptorArduinoSetupFail263(t *testing.T) { 122 a, fs := initTestAdaptor() 123 delete(fs.Files, "/sys/class/gpio/gpio263/direction") 124 125 err := a.arduinoSetup() 126 gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/gpio/gpio263/direction: No such file"), true) 127 } 128 129 func TestAdaptorArduinoSetupFail240(t *testing.T) { 130 a, fs := initTestAdaptor() 131 delete(fs.Files, "/sys/class/gpio/gpio240/direction") 132 133 err := a.arduinoSetup() 134 gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/gpio/gpio240/direction: No such file"), true) 135 } 136 137 func TestAdaptorArduinoSetupFail111(t *testing.T) { 138 a, fs := initTestAdaptor() 139 delete(fs.Files, "/sys/kernel/debug/gpio_debug/gpio111/current_pinmux") 140 141 err := a.arduinoSetup() 142 gobottest.Assert(t, strings.Contains(err.Error(), "/sys/kernel/debug/gpio_debug/gpio111/current_pinmux: No such file"), true) 143 } 144 145 func TestAdaptorArduinoSetupFail131(t *testing.T) { 146 a, fs := initTestAdaptor() 147 delete(fs.Files, "/sys/kernel/debug/gpio_debug/gpio131/current_pinmux") 148 149 err := a.arduinoSetup() 150 gobottest.Assert(t, strings.Contains(err.Error(), "/sys/kernel/debug/gpio_debug/gpio131/current_pinmux: No such file"), true) 151 } 152 153 func TestAdaptorArduinoI2CSetupFailTristate(t *testing.T) { 154 a, fs := initTestAdaptor() 155 156 gobottest.Assert(t, a.arduinoSetup(), nil) 157 158 fs.WithWriteError = true 159 err := a.arduinoI2CSetup() 160 gobottest.Assert(t, err, errors.New("write error")) 161 } 162 163 func TestAdaptorArduinoI2CSetupFail14(t *testing.T) { 164 a, fs := initTestAdaptor() 165 166 gobottest.Assert(t, a.arduinoSetup(), nil) 167 delete(fs.Files, "/sys/class/gpio/gpio14/direction") 168 169 err := a.arduinoI2CSetup() 170 gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/gpio/gpio14/direction: No such file"), true) 171 } 172 173 func TestAdaptorArduinoI2CSetupUnexportFail(t *testing.T) { 174 a, fs := initTestAdaptor() 175 176 gobottest.Assert(t, a.arduinoSetup(), nil) 177 delete(fs.Files, "/sys/class/gpio/unexport") 178 179 err := a.arduinoI2CSetup() 180 gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/gpio/unexport: No such file"), true) 181 } 182 183 func TestAdaptorArduinoI2CSetupFail236(t *testing.T) { 184 a, fs := initTestAdaptor() 185 186 gobottest.Assert(t, a.arduinoSetup(), nil) 187 delete(fs.Files, "/sys/class/gpio/gpio236/direction") 188 189 err := a.arduinoI2CSetup() 190 gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/gpio/gpio236/direction: No such file"), true) 191 } 192 193 func TestAdaptorArduinoI2CSetupFail28(t *testing.T) { 194 a, fs := initTestAdaptor() 195 196 gobottest.Assert(t, a.arduinoSetup(), nil) 197 delete(fs.Files, "/sys/kernel/debug/gpio_debug/gpio28/current_pinmux") 198 199 err := a.arduinoI2CSetup() 200 gobottest.Assert(t, strings.Contains(err.Error(), "/sys/kernel/debug/gpio_debug/gpio28/current_pinmux: No such file"), true) 201 } 202 203 func TestAdaptorConnectArduinoError(t *testing.T) { 204 a, _ := initTestAdaptor() 205 a.writeFile = func(string, []byte) (int, error) { 206 return 0, errors.New("write error") 207 } 208 209 err := a.Connect() 210 gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true) 211 } 212 213 func TestAdaptorConnectArduinoWriteError(t *testing.T) { 214 a, fs := initTestAdaptor() 215 fs.WithWriteError = true 216 err := a.Connect() 217 gobottest.Assert(t, strings.Contains(err.Error(), "write error"), true) 218 } 219 220 func TestAdaptorConnectSparkfun(t *testing.T) { 221 a, _ := initTestAdaptor() 222 a.SetBoard("sparkfun") 223 gobottest.Assert(t, a.Connect(), nil) 224 gobottest.Assert(t, a.GetDefaultBus(), 1) 225 gobottest.Assert(t, a.Board(), "sparkfun") 226 } 227 228 func TestAdaptorConnectMiniboard(t *testing.T) { 229 a, _ := initTestAdaptor() 230 a.SetBoard("miniboard") 231 gobottest.Assert(t, a.Connect(), nil) 232 gobottest.Assert(t, a.GetDefaultBus(), 1) 233 gobottest.Assert(t, a.Board(), "miniboard") 234 } 235 236 func TestAdaptorConnectUnknown(t *testing.T) { 237 a, _ := initTestAdaptor() 238 a.SetBoard("wha") 239 gobottest.Refute(t, a.Connect(), nil) 240 } 241 242 func TestAdaptorFinalize(t *testing.T) { 243 a, _ := initTestAdaptor() 244 a.DigitalWrite("3", 1) 245 a.PwmWrite("5", 100) 246 247 sysfs.SetSyscall(&sysfs.MockSyscall{}) 248 a.GetConnection(0xff, 6) 249 250 gobottest.Assert(t, a.Finalize(), nil) 251 252 sysfs.SetFilesystem(sysfs.NewMockFilesystem([]string{})) 253 gobottest.Refute(t, a.Finalize(), nil) 254 } 255 256 func TestAdaptorFinalizeError(t *testing.T) { 257 a, fs := initTestAdaptor() 258 a.PwmWrite("5", 100) 259 260 fs.WithWriteError = true 261 gobottest.Refute(t, a.Finalize(), nil) 262 } 263 264 func TestAdaptorDigitalIO(t *testing.T) { 265 a, fs := initTestAdaptor() 266 267 a.DigitalWrite("13", 1) 268 gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio40/value"].Contents, "1") 269 270 a.DigitalWrite("2", 0) 271 i, err := a.DigitalRead("2") 272 gobottest.Assert(t, err, nil) 273 gobottest.Assert(t, i, 0) 274 } 275 276 func TestAdaptorDigitalPinInFileError(t *testing.T) { 277 a := NewAdaptor() 278 fs := sysfs.NewMockFilesystem([]string{ 279 "/sys/kernel/debug/gpio_debug/gpio40/current_pinmux", 280 "/sys/class/gpio/export", 281 "/sys/class/gpio/unexport", 282 // "/sys/class/gpio/gpio40/value", 283 // "/sys/class/gpio/gpio40/direction", 284 "/sys/class/gpio/gpio229/value", // resistor 285 "/sys/class/gpio/gpio229/direction", 286 "/sys/class/gpio/gpio243/value", 287 "/sys/class/gpio/gpio243/direction", 288 "/sys/class/gpio/gpio261/value", // level shifter 289 "/sys/class/gpio/gpio261/direction", 290 }) 291 sysfs.SetFilesystem(fs) 292 293 a.Connect() 294 295 _, err := a.DigitalPin("13", "in") 296 gobottest.Assert(t, strings.Contains(err.Error(), "No such file"), true) 297 298 } 299 300 func TestAdaptorDigitalPinInResistorFileError(t *testing.T) { 301 a := NewAdaptor() 302 fs := sysfs.NewMockFilesystem([]string{ 303 "/sys/kernel/debug/gpio_debug/gpio40/current_pinmux", 304 "/sys/class/gpio/export", 305 "/sys/class/gpio/unexport", 306 "/sys/class/gpio/gpio40/value", 307 "/sys/class/gpio/gpio40/direction", 308 // "/sys/class/gpio/gpio229/value", // resistor 309 // "/sys/class/gpio/gpio229/direction", 310 "/sys/class/gpio/gpio243/value", 311 "/sys/class/gpio/gpio243/direction", 312 "/sys/class/gpio/gpio261/value", // level shifter 313 "/sys/class/gpio/gpio261/direction", 314 }) 315 sysfs.SetFilesystem(fs) 316 317 a.Connect() 318 319 _, err := a.DigitalPin("13", "in") 320 gobottest.Assert(t, strings.Contains(err.Error(), "No such file"), true) 321 } 322 323 func TestAdaptorDigitalPinInLevelShifterFileError(t *testing.T) { 324 a := NewAdaptor() 325 fs := sysfs.NewMockFilesystem([]string{ 326 "/sys/kernel/debug/gpio_debug/gpio40/current_pinmux", 327 "/sys/class/gpio/export", 328 "/sys/class/gpio/unexport", 329 "/sys/class/gpio/gpio40/value", 330 "/sys/class/gpio/gpio40/direction", 331 "/sys/class/gpio/gpio229/value", // resistor 332 "/sys/class/gpio/gpio229/direction", 333 "/sys/class/gpio/gpio243/value", 334 "/sys/class/gpio/gpio243/direction", 335 // "/sys/class/gpio/gpio261/value", // level shifter 336 // "/sys/class/gpio/gpio261/direction", 337 }) 338 sysfs.SetFilesystem(fs) 339 340 a.Connect() 341 342 _, err := a.DigitalPin("13", "in") 343 gobottest.Assert(t, strings.Contains(err.Error(), "No such file"), true) 344 } 345 346 func TestAdaptorDigitalPinInMuxFileError(t *testing.T) { 347 a := NewAdaptor() 348 fs := sysfs.NewMockFilesystem([]string{ 349 "/sys/kernel/debug/gpio_debug/gpio40/current_pinmux", 350 "/sys/class/gpio/export", 351 "/sys/class/gpio/unexport", 352 "/sys/class/gpio/gpio40/value", 353 "/sys/class/gpio/gpio40/direction", 354 "/sys/class/gpio/gpio229/value", // resistor 355 "/sys/class/gpio/gpio229/direction", 356 // "/sys/class/gpio/gpio243/value", 357 // "/sys/class/gpio/gpio243/direction", 358 "/sys/class/gpio/gpio261/value", // level shifter 359 "/sys/class/gpio/gpio261/direction", 360 }) 361 sysfs.SetFilesystem(fs) 362 363 a.Connect() 364 365 _, err := a.DigitalPin("13", "in") 366 gobottest.Assert(t, strings.Contains(err.Error(), "No such file"), true) 367 } 368 369 func TestAdaptorDigitalWriteError(t *testing.T) { 370 a, fs := initTestAdaptor() 371 fs.WithWriteError = true 372 373 err := a.DigitalWrite("13", 1) 374 gobottest.Assert(t, err, errors.New("write error")) 375 } 376 377 func TestAdaptorDigitalReadWriteError(t *testing.T) { 378 a, fs := initTestAdaptor() 379 fs.WithWriteError = true 380 381 _, err := a.DigitalRead("13") 382 gobottest.Assert(t, err, errors.New("write error")) 383 } 384 385 func TestAdaptorI2c(t *testing.T) { 386 a, _ := initTestAdaptor() 387 388 sysfs.SetSyscall(&sysfs.MockSyscall{}) 389 con, err := a.GetConnection(0xff, 6) 390 gobottest.Assert(t, err, nil) 391 392 con.Write([]byte{0x00, 0x01}) 393 data := []byte{42, 42} 394 con.Read(data) 395 gobottest.Assert(t, data, []byte{0x00, 0x01}) 396 397 gobottest.Assert(t, a.Finalize(), nil) 398 } 399 400 func TestAdaptorI2cInvalidBus(t *testing.T) { 401 a, _ := initTestAdaptor() 402 _, err := a.GetConnection(0xff, 3) 403 gobottest.Assert(t, err, errors.New("Unsupported I2C bus")) 404 } 405 406 func TestAdaptorPwm(t *testing.T) { 407 a, fs := initTestAdaptor() 408 409 err := a.PwmWrite("5", 100) 410 gobottest.Assert(t, err, nil) 411 gobottest.Assert(t, fs.Files["/sys/class/pwm/pwmchip0/pwm1/duty_cycle"].Contents, "1960") 412 413 err = a.PwmWrite("7", 100) 414 gobottest.Assert(t, err, errors.New("Not a PWM pin")) 415 } 416 417 func TestAdaptorPwmExportError(t *testing.T) { 418 a := NewAdaptor() 419 fs := sysfs.NewMockFilesystem([]string{ 420 "/sys/kernel/debug/gpio_debug/gpio13/current_pinmux", 421 "/sys/class/gpio/export", 422 "/sys/class/gpio/gpio13/direction", 423 "/sys/class/gpio/gpio13/value", 424 "/sys/class/gpio/gpio221/direction", 425 "/sys/class/gpio/gpio221/value", 426 "/sys/class/gpio/gpio253/direction", 427 "/sys/class/gpio/gpio253/value", 428 //"/sys/class/pwm/pwmchip0/export", 429 "/sys/class/pwm/pwmchip0/unexport", 430 "/sys/class/pwm/pwmchip0/pwm1/duty_cycle", 431 "/sys/class/pwm/pwmchip0/pwm1/period", 432 "/sys/class/pwm/pwmchip0/pwm1/enable", 433 }) 434 sysfs.SetFilesystem(fs) 435 a.Connect() 436 437 err := a.PwmWrite("5", 100) 438 gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/pwm/pwmchip0/export: No such file"), true) 439 } 440 441 func TestAdaptorPwmEnableError(t *testing.T) { 442 a := NewAdaptor() 443 fs := sysfs.NewMockFilesystem([]string{ 444 "/sys/kernel/debug/gpio_debug/gpio13/current_pinmux", 445 "/sys/class/gpio/export", 446 "/sys/class/gpio/gpio13/direction", 447 "/sys/class/gpio/gpio13/value", 448 "/sys/class/gpio/gpio221/direction", 449 "/sys/class/gpio/gpio221/value", 450 "/sys/class/gpio/gpio253/direction", 451 "/sys/class/gpio/gpio253/value", 452 "/sys/class/pwm/pwmchip0/export", 453 "/sys/class/pwm/pwmchip0/unexport", 454 "/sys/class/pwm/pwmchip0/pwm1/duty_cycle", 455 "/sys/class/pwm/pwmchip0/pwm1/period", 456 //"/sys/class/pwm/pwmchip0/pwm1/enable", 457 }) 458 sysfs.SetFilesystem(fs) 459 a.Connect() 460 461 err := a.PwmWrite("5", 100) 462 gobottest.Assert(t, strings.Contains(err.Error(), "/sys/class/pwm/pwmchip0/pwm1/enable: No such file"), true) 463 } 464 465 func TestAdaptorPwmWritePinError(t *testing.T) { 466 a, _ := initTestAdaptor() 467 468 a.writeFile = func(string, []byte) (int, error) { 469 return 0, errors.New("write error") 470 } 471 472 err := a.PwmWrite("5", 100) 473 gobottest.Assert(t, err, errors.New("write error")) 474 } 475 476 func TestAdaptorPwmWriteError(t *testing.T) { 477 a, fs := initTestAdaptor() 478 479 fs.WithWriteError = true 480 481 err := a.PwmWrite("5", 100) 482 gobottest.Assert(t, err, errors.New("write error")) 483 } 484 485 func TestAdaptorPwmReadError(t *testing.T) { 486 a, fs := initTestAdaptor() 487 488 fs.WithReadError = true 489 490 err := a.PwmWrite("5", 100) 491 gobottest.Assert(t, err, errors.New("read error")) 492 } 493 494 func TestAdaptorAnalog(t *testing.T) { 495 a, fs := initTestAdaptor() 496 497 fs.Files["/sys/bus/iio/devices/iio:device1/in_voltage0_raw"].Contents = "1000\n" 498 i, _ := a.AnalogRead("0") 499 gobottest.Assert(t, i, 250) 500 } 501 502 func TestAdaptorAnalogError(t *testing.T) { 503 a, _ := initTestAdaptor() 504 505 a.readFile = func(string) ([]byte, error) { 506 return nil, errors.New("read error") 507 } 508 _, err := a.AnalogRead("0") 509 gobottest.Assert(t, err, errors.New("read error")) 510 }