Example #1
0
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)
}
Example #2
0
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
}
Example #3
0
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
}
Example #4
0
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)
}
Example #5
0
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)
}
Example #6
0
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))
}
Example #8
0
/*
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
		}
	}
}
Example #9
0
// 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
}
Example #10
0
func assertEof(t *testing.T, s *realScanner) {
	msg, err := s.ReadMessage()
	assert.True(t, util.HasErrCode(err, util.ConnectionResetError))
	assert.Nil(t, msg)
}