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  }