Пример #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)
}
Пример #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
}
Пример #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
}
Пример #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)
}
Пример #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)
}
Пример #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()
}
Пример #7
0
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))
}
Пример #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
		}
	}
}
Пример #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
}
Пример #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)
}