gobot.io/x/gobot/v2@v2.1.0/system/digitalpin_sysfs_test.go (about) 1 package system 2 3 import ( 4 "errors" 5 "os" 6 "syscall" 7 "testing" 8 9 "gobot.io/x/gobot/v2" 10 "gobot.io/x/gobot/v2/gobottest" 11 ) 12 13 var _ gobot.DigitalPinner = (*digitalPinSysfs)(nil) 14 var _ gobot.DigitalPinValuer = (*digitalPinSysfs)(nil) 15 var _ gobot.DigitalPinOptioner = (*digitalPinSysfs)(nil) 16 var _ gobot.DigitalPinOptionApplier = (*digitalPinSysfs)(nil) 17 18 func initTestDigitalPinSysFsWithMockedFilesystem(mockPaths []string) (*digitalPinSysfs, *MockFilesystem) { 19 fs := newMockFilesystem(mockPaths) 20 pin := newDigitalPinSysfs(fs, "10") 21 return pin, fs 22 } 23 24 func TestDigitalPin(t *testing.T) { 25 mockPaths := []string{ 26 "/sys/class/gpio/export", 27 "/sys/class/gpio/unexport", 28 "/sys/class/gpio/gpio10/value", 29 "/sys/class/gpio/gpio10/direction", 30 } 31 pin, fs := initTestDigitalPinSysFsWithMockedFilesystem(mockPaths) 32 33 gobottest.Assert(t, pin.pin, "10") 34 gobottest.Assert(t, pin.label, "gpio10") 35 gobottest.Assert(t, pin.valFile, nil) 36 37 err := pin.Unexport() 38 gobottest.Assert(t, err, nil) 39 gobottest.Assert(t, fs.Files["/sys/class/gpio/unexport"].Contents, "10") 40 41 err = pin.Export() 42 gobottest.Assert(t, err, nil) 43 gobottest.Assert(t, fs.Files["/sys/class/gpio/export"].Contents, "10") 44 gobottest.Refute(t, pin.valFile, nil) 45 46 err = pin.Write(1) 47 gobottest.Assert(t, err, nil) 48 gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio10/value"].Contents, "1") 49 50 err = pin.ApplyOptions(WithPinDirectionInput()) 51 gobottest.Assert(t, err, nil) 52 gobottest.Assert(t, fs.Files["/sys/class/gpio/gpio10/direction"].Contents, "in") 53 54 data, _ := pin.Read() 55 gobottest.Assert(t, 1, data) 56 57 pin2 := newDigitalPinSysfs(fs, "30") 58 err = pin2.Write(1) 59 gobottest.Assert(t, err.Error(), "pin has not been exported") 60 61 data, err = pin2.Read() 62 gobottest.Assert(t, err.Error(), "pin has not been exported") 63 gobottest.Assert(t, data, 0) 64 65 writeFile = func(File, []byte) (int, error) { 66 return 0, &os.PathError{Err: syscall.EINVAL} 67 } 68 69 err = pin.Unexport() 70 gobottest.Assert(t, err, nil) 71 72 writeFile = func(File, []byte) (int, error) { 73 return 0, &os.PathError{Err: errors.New("write error")} 74 } 75 76 err = pin.Unexport() 77 gobottest.Assert(t, err.(*os.PathError).Err, errors.New("write error")) 78 79 // assert a busy error is dropped (just means "already exported") 80 cnt := 0 81 writeFile = func(File, []byte) (int, error) { 82 cnt++ 83 if cnt == 1 { 84 return 0, &os.PathError{Err: syscall.EBUSY} 85 } 86 return 0, nil 87 } 88 err = pin.Export() 89 gobottest.Assert(t, err, nil) 90 91 // assert write error on export 92 writeFile = func(File, []byte) (int, error) { 93 return 0, &os.PathError{Err: errors.New("write error")} 94 } 95 err = pin.Export() 96 gobottest.Assert(t, err.(*os.PathError).Err, errors.New("write error")) 97 } 98 99 func TestDigitalPinExportError(t *testing.T) { 100 mockPaths := []string{ 101 "/sys/class/gpio/export", 102 "/sys/class/gpio/gpio11/direction", 103 } 104 pin, _ := initTestDigitalPinSysFsWithMockedFilesystem(mockPaths) 105 106 writeFile = func(File, []byte) (int, error) { 107 return 0, &os.PathError{Err: syscall.EBUSY} 108 } 109 110 err := pin.Export() 111 gobottest.Assert(t, err.Error(), " : /sys/class/gpio/gpio10/direction: no such file") 112 } 113 114 func TestDigitalPinUnexportError(t *testing.T) { 115 mockPaths := []string{ 116 "/sys/class/gpio/unexport", 117 } 118 pin, _ := initTestDigitalPinSysFsWithMockedFilesystem(mockPaths) 119 120 writeFile = func(File, []byte) (int, error) { 121 return 0, &os.PathError{Err: syscall.EBUSY} 122 } 123 124 err := pin.Unexport() 125 gobottest.Assert(t, err.Error(), " : device or resource busy") 126 }