func TestGetDeviceInfo(t *testing.T) { deviceLister := func() ([]*DeviceInfo, error) { return []*DeviceInfo{ &DeviceInfo{ Serial: "abc", Product: "Foo", }, &DeviceInfo{ Serial: "def", Product: "Bar", }, }, nil } client := newDeviceClientWithDeviceLister("abc", deviceLister) device, err := client.GetDeviceInfo() assert.NoError(t, err) assert.Equal(t, "Foo", device.Product) client = newDeviceClientWithDeviceLister("def", deviceLister) device, err = client.GetDeviceInfo() assert.NoError(t, err) assert.Equal(t, "Bar", device.Product) client = newDeviceClientWithDeviceLister("serial", deviceLister) device, err = client.GetDeviceInfo() assert.True(t, util.HasErrCode(err, util.DeviceNotFound)) assert.EqualError(t, err.(*util.Err).Cause, "DeviceNotFound: device list doesn't contain serial serial") assert.Nil(t, device) }
func (c goadbDeviceClient) Stat(path string, _ *LogEntry) (*goadb.DirEntry, error) { e, err := c.DeviceClient.Stat(path) if util.HasErrCode(err, util.DeviceNotFound) { return nil, c.handleDeviceNotFound(err) } return e, err }
func (c goadbDeviceClient) OpenRead(path string, _ *LogEntry) (io.ReadCloser, error) { r, err := c.DeviceClient.OpenRead(path) if util.HasErrCode(err, util.DeviceNotFound) { return nil, c.handleDeviceNotFound(err) } return r, err }
func TestParseDeviceStatesMalformed(t *testing.T) { _, err := parseDeviceStates(`192.168.56.101:5555 offline 0x0x0x0x `) assert.True(t, util.HasErrCode(err, util.ParseError)) assert.Equal(t, "invalid device state line 1: 0x0x0x0x", err.(*util.Err).Message) }
func TestNewFileBuffer_RdonlyNoExistFailure(t *testing.T) { file, err := NewFileBuffer(O_RDONLY, FileBufferOptions{ Path: "/file", Client: &delegateDeviceClient{ stat: statFiles(), }, }, &LogEntry{}) assert.True(t, util.HasErrCode(err, util.FileNoExistError)) assert.Nil(t, file) }
func (c goadbDeviceClient) ListDirEntries(path string, _ *LogEntry) ([]*goadb.DirEntry, error) { entries, err := c.DeviceClient.ListDirEntries(path) if err != nil { if util.HasErrCode(err, util.DeviceNotFound) { c.handleDeviceNotFound(err) } return nil, err } return entries.ReadAll() }
func TestCachingDeviceClientStat_HitNotExists(t *testing.T) { client := &CachingDeviceClient{ DeviceClient: &delegateDeviceClient{}, Cache: &delegateDirEntryCache{ DoGet: func(path string) (entries *CachedDirEntries, found bool) { return NewCachedDirEntries([]*goadb.DirEntry{ &goadb.DirEntry{Name: "baz"}, }), true }, }, } _, err := client.Stat("/foo/bar", &LogEntry{}) assert.True(t, util.HasErrCode(err, util.FileNoExistError)) }
/* publishDevices reads device lists from scanner, calculates diffs, and publishes events on eventChan. Returns when scanner returns an error. Doesn't refer directly to a *DeviceWatcher so it can be GCed (which will, in turn, close Scanner and stop this goroutine). TODO: to support shutdown, spawn a new goroutine each time a server connection is established. This goroutine should read messages and send them to a message channel. Can write errors directly to errVal. publishDevicesUntilError should take the msg chan and the scanner and select on the msg chan and stop chan, and if the stop chan sends, close the scanner and return true. If the msg chan closes, just return false. publishDevices can look at ret val: if false and err == EOF, reconnect. If false and other error, report err and abort. If true, report no error and stop. */ func publishDevices(watcher *deviceWatcherImpl) { defer close(watcher.eventChan) var lastKnownStates map[string]DeviceState finished := false for { scanner, err := connectToTrackDevices(watcher.config.Dialer) if err != nil { watcher.reportErr(err) return } finished, err = publishDevicesUntilError(scanner, watcher.eventChan, &lastKnownStates) if finished { scanner.Close() return } if util.HasErrCode(err, util.ConnectionResetError) { // The server died, restart and reconnect. // Delay by a random [0ms, 500ms) in case multiple DeviceWatchers are trying to // start the same server. delay := time.Duration(rand.Intn(500)) * time.Millisecond log.Printf("[DeviceWatcher] server died, restarting in %s…", delay) time.Sleep(delay) if err := watcher.startServer(); err != nil { log.Println("[DeviceWatcher] error restarting server, giving up") watcher.reportErr(err) return } // Else server should be running, continue listening. } else { // Unknown error, don't retry. watcher.reportErr(err) return } } }
// toErrno converts a known error to an Errno, or EIO if the error is not known. func toErrno(err error) syscall.Errno { switch { case err == nil: return OK case err == ErrLinkTooDeep: return syscall.ELOOP case err == ErrNotALink: return syscall.EINVAL case err == ErrNoPermission || err == os.ErrPermission: // See http://blog.unclesniper.org/archives/2-Linux-programmers,-learn-the-difference-between-EACCES-and-EPERM-already!.html return syscall.EACCES case err == ErrNotPermitted: return syscall.EPERM case util.HasErrCode(err, util.FileNoExistError): return syscall.ENOENT } if err, ok := err.(syscall.Errno); ok { return err } return syscall.EIO }
func assertEof(t *testing.T, s *realScanner) { msg, err := s.ReadMessage() assert.True(t, util.HasErrCode(err, util.ConnectionResetError)) assert.Nil(t, msg) }