Merge pull request #20 from zach-klippenstein/cleanup-errors
Moved error definitions to an internal package, deleted the confusing util package.
This commit is contained in:
commit
e87d5c6814
4
adb.go
4
adb.go
|
@ -3,7 +3,7 @@ package adb
|
||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
"github.com/zach-klippenstein/goadb/wire"
|
"github.com/zach-klippenstein/goadb/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ func (c *Adb) parseServerVersion(versionRaw []byte) (int, error) {
|
||||||
versionStr := string(versionRaw)
|
versionStr := string(versionRaw)
|
||||||
version, err := strconv.ParseInt(versionStr, 16, 32)
|
version, err := strconv.ParseInt(versionStr, 16, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, util.WrapErrorf(err, util.ParseError,
|
return 0, errors.WrapErrorf(err, errors.ParseError,
|
||||||
"error parsing server version: %s", versionStr)
|
"error parsing server version: %s", versionStr)
|
||||||
}
|
}
|
||||||
return int(version), nil
|
return int(version), nil
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
|
|
||||||
"github.com/cheggaaa/pb"
|
"github.com/cheggaaa/pb"
|
||||||
"github.com/zach-klippenstein/goadb"
|
"github.com/zach-klippenstein/goadb"
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
|
||||||
"gopkg.in/alecthomas/kingpin.v2"
|
"gopkg.in/alecthomas/kingpin.v2"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -162,7 +161,7 @@ func pull(showProgress bool, remotePath, localPath string, device adb.DeviceDesc
|
||||||
client := client.Device(device)
|
client := client.Device(device)
|
||||||
|
|
||||||
info, err := client.Stat(remotePath)
|
info, err := client.Stat(remotePath)
|
||||||
if util.HasErrCode(err, util.FileNoExistError) {
|
if adb.HasErrCode(err, adb.ErrCode(adb.FileNoExistError)) {
|
||||||
fmt.Fprintln(os.Stderr, "remote file does not exist:", remotePath)
|
fmt.Fprintln(os.Stderr, "remote file does not exist:", remotePath)
|
||||||
return 1
|
return 1
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
|
@ -172,7 +171,7 @@ func pull(showProgress bool, remotePath, localPath string, device adb.DeviceDesc
|
||||||
|
|
||||||
remoteFile, err := client.OpenRead(remotePath)
|
remoteFile, err := client.OpenRead(remotePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintf(os.Stderr, "error opening remote file %s: %s\n", remotePath, util.ErrorWithCauseChain(err))
|
fmt.Fprintf(os.Stderr, "error opening remote file %s: %s\n", remotePath, adb.ErrorWithCauseChain(err))
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
defer remoteFile.Close()
|
defer remoteFile.Close()
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
adb "github.com/zach-klippenstein/goadb"
|
adb "github.com/zach-klippenstein/goadb"
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -74,7 +74,7 @@ func main() {
|
||||||
|
|
||||||
func printErr(err error) {
|
func printErr(err error) {
|
||||||
switch err := err.(type) {
|
switch err := err.(type) {
|
||||||
case *util.Err:
|
case *errors.Err:
|
||||||
fmt.Println(err.Error())
|
fmt.Println(err.Error())
|
||||||
if err.Cause != nil {
|
if err.Cause != nil {
|
||||||
fmt.Print("caused by ")
|
fmt.Print("caused by ")
|
||||||
|
|
10
device.go
10
device.go
|
@ -7,7 +7,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
"github.com/zach-klippenstein/goadb/wire"
|
"github.com/zach-klippenstein/goadb/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ func (c *Device) DeviceInfo() (*DeviceInfo, error) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = util.Errorf(util.DeviceNotFound, "device list doesn't contain serial %s", serial)
|
err = errors.Errorf(errors.DeviceNotFound, "device list doesn't contain serial %s", serial)
|
||||||
return nil, wrapClientError(err, c, "DeviceInfo")
|
return nil, wrapClientError(err, c, "DeviceInfo")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -224,7 +224,7 @@ func (c *Device) dialDevice() (*wire.Conn, error) {
|
||||||
req := fmt.Sprintf("host:%s", c.descriptor.getTransportDescriptor())
|
req := fmt.Sprintf("host:%s", c.descriptor.getTransportDescriptor())
|
||||||
if err = wire.SendMessageString(conn, req); err != nil {
|
if err = wire.SendMessageString(conn, req); err != nil {
|
||||||
conn.Close()
|
conn.Close()
|
||||||
return nil, util.WrapErrf(err, "error connecting to device '%s'", c.descriptor)
|
return nil, errors.WrapErrf(err, "error connecting to device '%s'", c.descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err = conn.ReadStatus(req); err != nil {
|
if _, err = conn.ReadStatus(req); err != nil {
|
||||||
|
@ -239,12 +239,12 @@ func (c *Device) dialDevice() (*wire.Conn, error) {
|
||||||
// arguments if required, and joins them into a valid adb command string.
|
// arguments if required, and joins them into a valid adb command string.
|
||||||
func prepareCommandLine(cmd string, args ...string) (string, error) {
|
func prepareCommandLine(cmd string, args ...string) (string, error) {
|
||||||
if isBlank(cmd) {
|
if isBlank(cmd) {
|
||||||
return "", util.AssertionErrorf("command cannot be empty")
|
return "", errors.AssertionErrorf("command cannot be empty")
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, arg := range args {
|
for i, arg := range args {
|
||||||
if strings.ContainsRune(arg, '"') {
|
if strings.ContainsRune(arg, '"') {
|
||||||
return "", util.Errorf(util.ParseError, "arg at index %d contains an invalid double quote: %s", i, arg)
|
return "", errors.Errorf(errors.ParseError, "arg at index %d contains an invalid double quote: %s", i, arg)
|
||||||
}
|
}
|
||||||
if containsWhitespace(arg) {
|
if containsWhitespace(arg) {
|
||||||
args[i] = fmt.Sprintf("\"%s\"", arg)
|
args[i] = fmt.Sprintf("\"%s\"", arg)
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type DeviceInfo struct {
|
type DeviceInfo struct {
|
||||||
|
@ -27,7 +27,7 @@ func (d *DeviceInfo) IsUsb() bool {
|
||||||
|
|
||||||
func newDevice(serial string, attrs map[string]string) (*DeviceInfo, error) {
|
func newDevice(serial string, attrs map[string]string) (*DeviceInfo, error) {
|
||||||
if serial == "" {
|
if serial == "" {
|
||||||
return nil, util.AssertionErrorf("device serial cannot be blank")
|
return nil, errors.AssertionErrorf("device serial cannot be blank")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &DeviceInfo{
|
return &DeviceInfo{
|
||||||
|
@ -57,7 +57,7 @@ func parseDeviceList(list string, lineParseFunc func(string) (*DeviceInfo, error
|
||||||
func parseDeviceShort(line string) (*DeviceInfo, error) {
|
func parseDeviceShort(line string) (*DeviceInfo, error) {
|
||||||
fields := strings.Fields(line)
|
fields := strings.Fields(line)
|
||||||
if len(fields) != 2 {
|
if len(fields) != 2 {
|
||||||
return nil, util.Errorf(util.ParseError,
|
return nil, errors.Errorf(errors.ParseError,
|
||||||
"malformed device line, expected 2 fields but found %d", len(fields))
|
"malformed device line, expected 2 fields but found %d", len(fields))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ func parseDeviceShort(line string) (*DeviceInfo, error) {
|
||||||
func parseDeviceLong(line string) (*DeviceInfo, error) {
|
func parseDeviceLong(line string) (*DeviceInfo, error) {
|
||||||
fields := strings.Fields(line)
|
fields := strings.Fields(line)
|
||||||
if len(fields) < 5 {
|
if len(fields) < 5 {
|
||||||
return nil, util.Errorf(util.ParseError,
|
return nil, errors.Errorf(errors.ParseError,
|
||||||
"malformed device line, expected at least 5 fields but found %d", len(fields))
|
"malformed device line, expected at least 5 fields but found %d", len(fields))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package adb
|
package adb
|
||||||
|
|
||||||
import "github.com/zach-klippenstein/goadb/util"
|
import "github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
|
|
||||||
// DeviceState represents one of the 3 possible states adb will report devices.
|
// DeviceState represents one of the 3 possible states adb will report devices.
|
||||||
// A device can be communicated with when it's in StateOnline.
|
// A device can be communicated with when it's in StateOnline.
|
||||||
|
@ -26,7 +26,7 @@ var deviceStateStrings = map[string]DeviceState{
|
||||||
func parseDeviceState(str string) (DeviceState, error) {
|
func parseDeviceState(str string) (DeviceState, error) {
|
||||||
state, ok := deviceStateStrings[str]
|
state, ok := deviceStateStrings[str]
|
||||||
if !ok {
|
if !ok {
|
||||||
return StateInvalid, util.Errorf(util.ParseError, "invalid device state: %q", state)
|
return StateInvalid, errors.Errorf(errors.ParseError, "invalid device state: %q", state)
|
||||||
}
|
}
|
||||||
return state, nil
|
return state, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
"github.com/zach-klippenstein/goadb/wire"
|
"github.com/zach-klippenstein/goadb/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -47,8 +47,8 @@ func TestGetDeviceInfo(t *testing.T) {
|
||||||
|
|
||||||
client = newDeviceClientWithDeviceLister("serial", deviceLister)
|
client = newDeviceClientWithDeviceLister("serial", deviceLister)
|
||||||
device, err = client.DeviceInfo()
|
device, err = client.DeviceInfo()
|
||||||
assert.True(t, util.HasErrCode(err, util.DeviceNotFound))
|
assert.True(t, HasErrCode(err, DeviceNotFound))
|
||||||
assert.EqualError(t, err.(*util.Err).Cause,
|
assert.EqualError(t, err.(*errors.Err).Cause,
|
||||||
"DeviceNotFound: device list doesn't contain serial serial")
|
"DeviceNotFound: device list doesn't contain serial serial")
|
||||||
assert.Nil(t, device)
|
assert.Nil(t, device)
|
||||||
}
|
}
|
||||||
|
@ -84,13 +84,13 @@ func TestPrepareCommandLineNoArgs(t *testing.T) {
|
||||||
|
|
||||||
func TestPrepareCommandLineEmptyCommand(t *testing.T) {
|
func TestPrepareCommandLineEmptyCommand(t *testing.T) {
|
||||||
_, err := prepareCommandLine("")
|
_, err := prepareCommandLine("")
|
||||||
assert.Equal(t, util.AssertionError, code(err))
|
assert.Equal(t, errors.AssertionError, code(err))
|
||||||
assert.Equal(t, "command cannot be empty", message(err))
|
assert.Equal(t, "command cannot be empty", message(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPrepareCommandLineBlankCommand(t *testing.T) {
|
func TestPrepareCommandLineBlankCommand(t *testing.T) {
|
||||||
_, err := prepareCommandLine(" ")
|
_, err := prepareCommandLine(" ")
|
||||||
assert.Equal(t, util.AssertionError, code(err))
|
assert.Equal(t, errors.AssertionError, code(err))
|
||||||
assert.Equal(t, "command cannot be empty", message(err))
|
assert.Equal(t, "command cannot be empty", message(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,14 +108,14 @@ func TestPrepareCommandLineArgWithWhitespaceQuotes(t *testing.T) {
|
||||||
|
|
||||||
func TestPrepareCommandLineArgWithDoubleQuoteFails(t *testing.T) {
|
func TestPrepareCommandLineArgWithDoubleQuoteFails(t *testing.T) {
|
||||||
_, err := prepareCommandLine("cmd", "quoted\"arg")
|
_, err := prepareCommandLine("cmd", "quoted\"arg")
|
||||||
assert.Equal(t, util.ParseError, code(err))
|
assert.Equal(t, errors.ParseError, code(err))
|
||||||
assert.Equal(t, "arg at index 0 contains an invalid double quote: quoted\"arg", message(err))
|
assert.Equal(t, "arg at index 0 contains an invalid double quote: quoted\"arg", message(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
func code(err error) util.ErrCode {
|
func code(err error) errors.ErrCode {
|
||||||
return err.(*util.Err).Code
|
return err.(*errors.Err).Code
|
||||||
}
|
}
|
||||||
|
|
||||||
func message(err error) string {
|
func message(err error) string {
|
||||||
return err.(*util.Err).Message
|
return err.(*errors.Err).Message
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
"github.com/zach-klippenstein/goadb/wire"
|
"github.com/zach-klippenstein/goadb/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -124,7 +124,7 @@ func publishDevices(watcher *deviceWatcherImpl) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if util.HasErrCode(err, util.ConnectionResetError) {
|
if HasErrCode(err, ConnectionResetError) {
|
||||||
// The server died, restart and reconnect.
|
// The server died, restart and reconnect.
|
||||||
|
|
||||||
// Delay by a random [0ms, 500ms) in case multiple DeviceWatchers are trying to
|
// Delay by a random [0ms, 500ms) in case multiple DeviceWatchers are trying to
|
||||||
|
@ -194,7 +194,7 @@ func parseDeviceStates(msg string) (states map[string]DeviceState, err error) {
|
||||||
|
|
||||||
fields := strings.Split(line, "\t")
|
fields := strings.Split(line, "\t")
|
||||||
if len(fields) != 2 {
|
if len(fields) != 2 {
|
||||||
err = util.Errorf(util.ParseError, "invalid device state line %d: %s", lineNum, line)
|
err = errors.Errorf(errors.ParseError, "invalid device state line %d: %s", lineNum, line)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
"github.com/zach-klippenstein/goadb/wire"
|
"github.com/zach-klippenstein/goadb/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@ func TestParseDeviceStatesMalformed(t *testing.T) {
|
||||||
0x0x0x0x
|
0x0x0x0x
|
||||||
`)
|
`)
|
||||||
|
|
||||||
assert.True(t, util.HasErrCode(err, util.ParseError))
|
assert.True(t, HasErrCode(err, ParseError))
|
||||||
assert.Equal(t, "invalid device state line 1: 0x0x0x0x", err.(*util.Err).Message)
|
assert.Equal(t, "invalid device state line 1: 0x0x0x0x", err.(*errors.Err).Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCalculateStateDiffsUnchangedEmpty(t *testing.T) {
|
func TestCalculateStateDiffsUnchangedEmpty(t *testing.T) {
|
||||||
|
@ -210,8 +210,8 @@ func TestPublishDevicesRestartsServer(t *testing.T) {
|
||||||
Status: wire.StatusSuccess,
|
Status: wire.StatusSuccess,
|
||||||
Errs: []error{
|
Errs: []error{
|
||||||
nil, nil, nil, // Successful dial.
|
nil, nil, nil, // Successful dial.
|
||||||
util.Errorf(util.ConnectionResetError, "failed first read"),
|
errors.Errorf(errors.ConnectionResetError, "failed first read"),
|
||||||
util.Errorf(util.ServerNotAvailable, "failed redial"),
|
errors.Errorf(errors.ServerNotAvailable, "failed redial"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
watcher := deviceWatcherImpl{
|
watcher := deviceWatcherImpl{
|
||||||
|
@ -224,8 +224,8 @@ func TestPublishDevicesRestartsServer(t *testing.T) {
|
||||||
assert.Empty(t, server.Errs)
|
assert.Empty(t, server.Errs)
|
||||||
assert.Equal(t, []string{"host:track-devices"}, server.Requests)
|
assert.Equal(t, []string{"host:track-devices"}, server.Requests)
|
||||||
assert.Equal(t, []string{"Dial", "SendMessage", "ReadStatus", "ReadMessage", "Start", "Dial"}, server.Trace)
|
assert.Equal(t, []string{"Dial", "SendMessage", "ReadStatus", "ReadMessage", "Start", "Dial"}, server.Trace)
|
||||||
err := watcher.err.Load().(*util.Err)
|
err := watcher.err.Load().(*errors.Err)
|
||||||
assert.Equal(t, util.ServerNotAvailable, err.Code)
|
assert.Equal(t, errors.ServerNotAvailable, err.Code)
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertContainsOnly(t *testing.T, expected, actual []DeviceStateChangedEvent) {
|
func assertContainsOnly(t *testing.T, expected, actual []DeviceStateChangedEvent) {
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"net"
|
"net"
|
||||||
"runtime"
|
"runtime"
|
||||||
|
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
"github.com/zach-klippenstein/goadb/wire"
|
"github.com/zach-klippenstein/goadb/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ type tcpDialer struct{}
|
||||||
func (tcpDialer) Dial(address string) (*wire.Conn, error) {
|
func (tcpDialer) Dial(address string) (*wire.Conn, error) {
|
||||||
netConn, err := net.Dial("tcp", address)
|
netConn, err := net.Dial("tcp", address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, util.WrapErrorf(err, util.ServerNotAvailable, "error dialing %s", address)
|
return nil, errors.WrapErrorf(err, errors.ServerNotAvailable, "error dialing %s", address)
|
||||||
}
|
}
|
||||||
|
|
||||||
// net.Conn can't be closed more than once, but wire.Conn will try to close both sender and scanner
|
// net.Conn can't be closed more than once, but wire.Conn will try to close both sender and scanner
|
||||||
|
|
35
error.go
Normal file
35
error.go
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
package adb
|
||||||
|
|
||||||
|
import "github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
|
|
||||||
|
type ErrCode errors.ErrCode
|
||||||
|
|
||||||
|
const (
|
||||||
|
AssertionError = ErrCode(errors.AssertionError)
|
||||||
|
ParseError = ErrCode(errors.ParseError)
|
||||||
|
// The server was not available on the requested port.
|
||||||
|
ServerNotAvailable = ErrCode(errors.ServerNotAvailable)
|
||||||
|
// General network error communicating with the server.
|
||||||
|
NetworkError = ErrCode(errors.NetworkError)
|
||||||
|
// The connection to the server was reset in the middle of an operation. Server probably died.
|
||||||
|
ConnectionResetError = ErrCode(errors.ConnectionResetError)
|
||||||
|
// The server returned an error message, but we couldn't parse it.
|
||||||
|
AdbError = ErrCode(errors.AdbError)
|
||||||
|
// The server returned a "device not found" error.
|
||||||
|
DeviceNotFound = ErrCode(errors.DeviceNotFound)
|
||||||
|
// Tried to perform an operation on a path that doesn't exist on the device.
|
||||||
|
FileNoExistError = ErrCode(errors.FileNoExistError)
|
||||||
|
)
|
||||||
|
|
||||||
|
// HasErrCode returns true if err is an *errors.Err and err.Code == code.
|
||||||
|
func HasErrCode(err error, code ErrCode) bool {
|
||||||
|
return errors.HasErrCode(err, errors.ErrCode(code))
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ErrorWithCauseChain formats err and all its causes if it's an *errors.Err, else returns
|
||||||
|
err.Error().
|
||||||
|
*/
|
||||||
|
func ErrorWithCauseChain(err error) string {
|
||||||
|
return errors.ErrorWithCauseChain(err)
|
||||||
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
// Code generated by "stringer -type=ErrCode"; DO NOT EDIT
|
// Code generated by "stringer -type=ErrCode"; DO NOT EDIT
|
||||||
|
|
||||||
package util
|
package errors
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package util
|
package errors
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
@ -31,6 +31,7 @@ type Err struct {
|
||||||
|
|
||||||
var _ error = &Err{}
|
var _ error = &Err{}
|
||||||
|
|
||||||
|
// Keep this in sync with ../error.go.
|
||||||
//go:generate stringer -type=ErrCode
|
//go:generate stringer -type=ErrCode
|
||||||
type ErrCode byte
|
type ErrCode byte
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package util
|
package errors
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
14
server.go
14
server.go
|
@ -1,13 +1,13 @@
|
||||||
package adb
|
package adb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
stderrors "errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
"github.com/zach-klippenstein/goadb/wire"
|
"github.com/zach-klippenstein/goadb/wire"
|
||||||
"golang.org/x/sys/unix"
|
"golang.org/x/sys/unix"
|
||||||
)
|
)
|
||||||
|
@ -76,12 +76,12 @@ func newServer(config ServerConfig) (server, error) {
|
||||||
if config.PathToAdb == "" {
|
if config.PathToAdb == "" {
|
||||||
path, err := config.fs.LookPath(AdbExecutableName)
|
path, err := config.fs.LookPath(AdbExecutableName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, util.WrapErrorf(err, util.ServerNotAvailable, "could not find %s in PATH", AdbExecutableName)
|
return nil, errors.WrapErrorf(err, errors.ServerNotAvailable, "could not find %s in PATH", AdbExecutableName)
|
||||||
}
|
}
|
||||||
config.PathToAdb = path
|
config.PathToAdb = path
|
||||||
}
|
}
|
||||||
if err := config.fs.IsExecutableFile(config.PathToAdb); err != nil {
|
if err := config.fs.IsExecutableFile(config.PathToAdb); err != nil {
|
||||||
return nil, util.WrapErrorf(err, util.ServerNotAvailable, "invalid adb executable: %s", config.PathToAdb)
|
return nil, errors.WrapErrorf(err, errors.ServerNotAvailable, "invalid adb executable: %s", config.PathToAdb)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &realServer{
|
return &realServer{
|
||||||
|
@ -97,7 +97,7 @@ func (s *realServer) Dial() (*wire.Conn, error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// Attempt to start the server and try again.
|
// Attempt to start the server and try again.
|
||||||
if err = s.Start(); err != nil {
|
if err = s.Start(); err != nil {
|
||||||
return nil, util.WrapErrorf(err, util.ServerNotAvailable, "error starting server for dial")
|
return nil, errors.WrapErrorf(err, errors.ServerNotAvailable, "error starting server for dial")
|
||||||
}
|
}
|
||||||
|
|
||||||
conn, err = s.config.Dial(s.address)
|
conn, err = s.config.Dial(s.address)
|
||||||
|
@ -112,7 +112,7 @@ func (s *realServer) Dial() (*wire.Conn, error) {
|
||||||
func (s *realServer) Start() error {
|
func (s *realServer) Start() error {
|
||||||
output, err := s.config.fs.CmdCombinedOutput(s.config.PathToAdb, "start-server")
|
output, err := s.config.fs.CmdCombinedOutput(s.config.PathToAdb, "start-server")
|
||||||
outputStr := strings.TrimSpace(string(output))
|
outputStr := strings.TrimSpace(string(output))
|
||||||
return util.WrapErrorf(err, util.ServerNotAvailable, "error starting server: %s\noutput:\n%s", err, outputStr)
|
return errors.WrapErrorf(err, errors.ServerNotAvailable, "error starting server: %s\noutput:\n%s", err, outputStr)
|
||||||
}
|
}
|
||||||
|
|
||||||
// filesystem abstracts interactions with the local filesystem for testability.
|
// filesystem abstracts interactions with the local filesystem for testability.
|
||||||
|
@ -135,7 +135,7 @@ var localFilesystem = &filesystem{
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if !info.Mode().IsRegular() {
|
if !info.Mode().IsRegular() {
|
||||||
return errors.New("not a regular file")
|
return stderrors.New("not a regular file")
|
||||||
}
|
}
|
||||||
return unix.Access(path, unix.X_OK)
|
return unix.Access(path, unix.X_OK)
|
||||||
},
|
},
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
"github.com/zach-klippenstein/goadb/wire"
|
"github.com/zach-klippenstein/goadb/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ func (s *MockServer) ReadMessage() ([]byte, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if s.nextMsgIndex >= len(s.Messages) {
|
if s.nextMsgIndex >= len(s.Messages) {
|
||||||
return nil, util.WrapErrorf(io.EOF, util.NetworkError, "")
|
return nil, errors.WrapErrorf(io.EOF, errors.NetworkError, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
s.nextMsgIndex++
|
s.nextMsgIndex++
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
"github.com/zach-klippenstein/goadb/wire"
|
"github.com/zach-klippenstein/goadb/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,7 +24,7 @@ func stat(conn *wire.SyncConn, path string) (*DirEntry, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if id != "STAT" {
|
if id != "STAT" {
|
||||||
return nil, util.Errorf(util.AssertionError, "expected stat ID 'STAT', but got '%s'", id)
|
return nil, errors.Errorf(errors.AssertionError, "expected stat ID 'STAT', but got '%s'", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
return readStat(conn)
|
return readStat(conn)
|
||||||
|
@ -71,24 +71,24 @@ func sendFile(conn *wire.SyncConn, path string, mode os.FileMode, mtime time.Tim
|
||||||
func readStat(s wire.SyncScanner) (entry *DirEntry, err error) {
|
func readStat(s wire.SyncScanner) (entry *DirEntry, err error) {
|
||||||
mode, err := s.ReadFileMode()
|
mode, err := s.ReadFileMode()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = util.WrapErrf(err, "error reading file mode: %v", err)
|
err = errors.WrapErrf(err, "error reading file mode: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
size, err := s.ReadInt32()
|
size, err := s.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = util.WrapErrf(err, "error reading file size: %v", err)
|
err = errors.WrapErrf(err, "error reading file size: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
mtime, err := s.ReadTime()
|
mtime, err := s.ReadTime()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = util.WrapErrf(err, "error reading file time: %v", err)
|
err = errors.WrapErrf(err, "error reading file time: %v", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// adb doesn't indicate when a file doesn't exist, but will return all zeros.
|
// adb doesn't indicate when a file doesn't exist, but will return all zeros.
|
||||||
// Theoretically this could be an actual file, but that's very unlikely.
|
// Theoretically this could be an actual file, but that's very unlikely.
|
||||||
if mode == os.FileMode(0) && size == 0 && mtime == zeroTime {
|
if mode == os.FileMode(0) && size == 0 && mtime == zeroTime {
|
||||||
return nil, util.Errorf(util.FileNoExistError, "file doesn't exist")
|
return nil, errors.Errorf(errors.FileNoExistError, "file doesn't exist")
|
||||||
}
|
}
|
||||||
|
|
||||||
entry = &DirEntry{
|
entry = &DirEntry{
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
"github.com/zach-klippenstein/goadb/wire"
|
"github.com/zach-klippenstein/goadb/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -57,5 +57,5 @@ func TestStatNoExist(t *testing.T) {
|
||||||
|
|
||||||
entry, err := stat(conn, "/")
|
entry, err := stat(conn, "/")
|
||||||
assert.Nil(t, entry)
|
assert.Nil(t, entry)
|
||||||
assert.Equal(t, util.FileNoExistError, err.(*util.Err).Code)
|
assert.Equal(t, errors.FileNoExistError, err.(*errors.Err).Code)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ package adb
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
"github.com/zach-klippenstein/goadb/wire"
|
"github.com/zach-klippenstein/goadb/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ func readNextChunk(r wire.SyncScanner) (io.Reader, error) {
|
||||||
status, err := r.ReadStatus("read-chunk")
|
status, err := r.ReadStatus("read-chunk")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if wire.IsAdbServerErrorMatching(err, readFileNotFoundPredicate) {
|
if wire.IsAdbServerErrorMatching(err, readFileNotFoundPredicate) {
|
||||||
return nil, util.Errorf(util.FileNoExistError, "no such file or directory")
|
return nil, errors.Errorf(errors.FileNoExistError, "no such file or directory")
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ func readNextChunk(r wire.SyncScanner) (io.Reader, error) {
|
||||||
case wire.StatusSyncDone:
|
case wire.StatusSyncDone:
|
||||||
return nil, io.EOF
|
return nil, io.EOF
|
||||||
default:
|
default:
|
||||||
return nil, util.Errorf(util.AssertionError, "expected chunk id '%s' or '%s', but got '%s'",
|
return nil, errors.Errorf(errors.AssertionError, "expected chunk id '%s' or '%s', but got '%s'",
|
||||||
wire.StatusSyncData, wire.StatusSyncDone, []byte(status))
|
wire.StatusSyncData, wire.StatusSyncDone, []byte(status))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,12 @@ package adb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
|
||||||
"github.com/zach-klippenstein/goadb/wire"
|
"github.com/zach-klippenstein/goadb/wire"
|
||||||
"io/ioutil"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestReadNextChunk(t *testing.T) {
|
func TestReadNextChunk(t *testing.T) {
|
||||||
|
@ -110,6 +109,6 @@ func TestReadErrorNotFound(t *testing.T) {
|
||||||
s := wire.NewSyncScanner(strings.NewReader(
|
s := wire.NewSyncScanner(strings.NewReader(
|
||||||
"FAIL\031\000\000\000No such file or directory"))
|
"FAIL\031\000\000\000No such file or directory"))
|
||||||
_, err := newSyncFileReader(s)
|
_, err := newSyncFileReader(s)
|
||||||
assert.True(t, util.HasErrCode(err, util.FileNoExistError))
|
assert.True(t, HasErrCode(err, FileNoExistError))
|
||||||
assert.EqualError(t, err, "FileNoExistError: no such file or directory")
|
assert.EqualError(t, err, "FileNoExistError: no such file or directory")
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
"github.com/zach-klippenstein/goadb/wire"
|
"github.com/zach-klippenstein/goadb/wire"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -76,11 +76,11 @@ func (w *syncFileWriter) Close() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := w.sender.SendOctetString(wire.StatusSyncDone); err != nil {
|
if err := w.sender.SendOctetString(wire.StatusSyncDone); err != nil {
|
||||||
return util.WrapErrf(err, "error sending done chunk to close stream")
|
return errors.WrapErrf(err, "error sending done chunk to close stream")
|
||||||
}
|
}
|
||||||
if err := w.sender.SendTime(w.mtime); err != nil {
|
if err := w.sender.SendTime(w.mtime); err != nil {
|
||||||
return util.WrapErrf(err, "error writing file modification time")
|
return errors.WrapErrf(err, "error writing file modification time")
|
||||||
}
|
}
|
||||||
|
|
||||||
return util.WrapErrf(w.sender.Close(), "error closing FileWriter")
|
return errors.WrapErrf(w.sender.Close(), "error closing FileWriter")
|
||||||
}
|
}
|
||||||
|
|
10
util.go
10
util.go
|
@ -6,7 +6,7 @@ import (
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -25,14 +25,14 @@ func wrapClientError(err error, client interface{}, operation string, args ...in
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if _, ok := err.(*util.Err); !ok {
|
if _, ok := err.(*errors.Err); !ok {
|
||||||
panic("err is not a *util.Err: " + err.Error())
|
panic("err is not a *Err: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
clientType := reflect.TypeOf(client)
|
clientType := reflect.TypeOf(client)
|
||||||
|
|
||||||
return &util.Err{
|
return &errors.Err{
|
||||||
Code: err.(*util.Err).Code,
|
Code: err.(*errors.Err).Code,
|
||||||
Cause: err,
|
Cause: err,
|
||||||
Message: fmt.Sprintf("error performing %s on %s", fmt.Sprintf(operation, args...), clientType),
|
Message: fmt.Sprintf("error performing %s on %s", fmt.Sprintf(operation, args...), clientType),
|
||||||
Details: client,
|
Details: client,
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
/*
|
|
||||||
Contains code shared between the different sub-packages in this project.
|
|
||||||
*/
|
|
||||||
package util
|
|
|
@ -1,6 +1,6 @@
|
||||||
package wire
|
package wire
|
||||||
|
|
||||||
import "github.com/zach-klippenstein/goadb/util"
|
import "github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// The official implementation of adb imposes an undocumented 255-byte limit
|
// The official implementation of adb imposes an undocumented 255-byte limit
|
||||||
|
@ -72,8 +72,8 @@ func (conn *Conn) Close() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
if errs.ScannerErr != nil || errs.SenderErr != nil {
|
if errs.ScannerErr != nil || errs.SenderErr != nil {
|
||||||
return &util.Err{
|
return &errors.Err{
|
||||||
Code: util.NetworkError,
|
Code: errors.NetworkError,
|
||||||
Message: "error closing connection",
|
Message: "error closing connection",
|
||||||
Details: errs,
|
Details: errs,
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO(zach): All EOF errors returned from networoking calls should use ConnectionResetError.
|
// TODO(zach): All EOF errors returned from networoking calls should use ConnectionResetError.
|
||||||
|
@ -28,7 +28,7 @@ func isFailureStatus(status string) bool {
|
||||||
type StatusReader interface {
|
type StatusReader interface {
|
||||||
// Reads a 4-byte status string and returns it.
|
// Reads a 4-byte status string and returns it.
|
||||||
// If the status string is StatusFailure, reads the error message from the server
|
// If the status string is StatusFailure, reads the error message from the server
|
||||||
// and returns it as an util.AdbError.
|
// and returns it as an AdbError.
|
||||||
ReadStatus(req string) (string, error)
|
ReadStatus(req string) (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ func (s *realScanner) ReadMessage() ([]byte, error) {
|
||||||
func (s *realScanner) ReadUntilEof() ([]byte, error) {
|
func (s *realScanner) ReadUntilEof() ([]byte, error) {
|
||||||
data, err := ioutil.ReadAll(s.reader)
|
data, err := ioutil.ReadAll(s.reader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, util.WrapErrorf(err, util.NetworkError, "error reading until EOF")
|
return nil, errors.WrapErrorf(err, errors.NetworkError, "error reading until EOF")
|
||||||
}
|
}
|
||||||
return data, nil
|
return data, nil
|
||||||
}
|
}
|
||||||
|
@ -82,7 +82,7 @@ func (s *realScanner) NewSyncScanner() SyncScanner {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *realScanner) Close() error {
|
func (s *realScanner) Close() error {
|
||||||
return util.WrapErrorf(s.reader.Close(), util.NetworkError, "error closing scanner")
|
return errors.WrapErrorf(s.reader.Close(), errors.NetworkError, "error closing scanner")
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Scanner = &realScanner{}
|
var _ Scanner = &realScanner{}
|
||||||
|
@ -98,13 +98,13 @@ type lengthReader func(io.Reader) (int, error)
|
||||||
func readStatusFailureAsError(r io.Reader, req string, messageLengthReader lengthReader) (string, error) {
|
func readStatusFailureAsError(r io.Reader, req string, messageLengthReader lengthReader) (string, error) {
|
||||||
status, err := readOctetString(req, r)
|
status, err := readOctetString(req, r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", util.WrapErrorf(err, util.NetworkError, "error reading status for %s", req)
|
return "", errors.WrapErrorf(err, errors.NetworkError, "error reading status for %s", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
if isFailureStatus(status) {
|
if isFailureStatus(status) {
|
||||||
msg, err := readMessage(r, messageLengthReader)
|
msg, err := readMessage(r, messageLengthReader)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", util.WrapErrorf(err, util.NetworkError,
|
return "", errors.WrapErrorf(err, errors.NetworkError,
|
||||||
"server returned error for %s, but couldn't read the error message", req)
|
"server returned error for %s, but couldn't read the error message", req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ func readOctetString(description string, r io.Reader) (string, error) {
|
||||||
if err == io.ErrUnexpectedEOF {
|
if err == io.ErrUnexpectedEOF {
|
||||||
return "", errIncompleteMessage(description, n, 4)
|
return "", errIncompleteMessage(description, n, 4)
|
||||||
} else if err != nil {
|
} else if err != nil {
|
||||||
return "", util.WrapErrorf(err, util.NetworkError, "error reading "+description)
|
return "", errors.WrapErrorf(err, errors.NetworkError, "error reading "+description)
|
||||||
}
|
}
|
||||||
|
|
||||||
return string(octet), nil
|
return string(octet), nil
|
||||||
|
@ -143,7 +143,7 @@ func readMessage(r io.Reader, lengthReader lengthReader) ([]byte, error) {
|
||||||
n, err := io.ReadFull(r, data)
|
n, err := io.ReadFull(r, data)
|
||||||
|
|
||||||
if err != nil && err != io.ErrUnexpectedEOF {
|
if err != nil && err != io.ErrUnexpectedEOF {
|
||||||
return data, util.WrapErrorf(err, util.NetworkError, "error reading message data")
|
return data, errors.WrapErrorf(err, errors.NetworkError, "error reading message data")
|
||||||
} else if err == io.ErrUnexpectedEOF {
|
} else if err == io.ErrUnexpectedEOF {
|
||||||
return data, errIncompleteMessage("message data", n, length)
|
return data, errIncompleteMessage("message data", n, length)
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ func readHexLength(r io.Reader) (int, error) {
|
||||||
|
|
||||||
length, err := strconv.ParseInt(string(lengthHex), 16, 64)
|
length, err := strconv.ParseInt(string(lengthHex), 16, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, util.WrapErrorf(err, util.NetworkError, "could not parse hex length %v", lengthHex)
|
return 0, errors.WrapErrorf(err, errors.NetworkError, "could not parse hex length %v", lengthHex)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clip the length to 255, as per the Google implementation.
|
// Clip the length to 255, as per the Google implementation.
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestReadStatusOkay(t *testing.T) {
|
func TestReadStatusOkay(t *testing.T) {
|
||||||
|
@ -23,7 +23,7 @@ func TestReadIncompleteStatus(t *testing.T) {
|
||||||
s := newEofReader("oka")
|
s := newEofReader("oka")
|
||||||
_, err := readStatusFailureAsError(s, "", readHexLength)
|
_, err := readStatusFailureAsError(s, "", readHexLength)
|
||||||
assert.EqualError(t, err, "NetworkError: error reading status for ")
|
assert.EqualError(t, err, "NetworkError: error reading status for ")
|
||||||
assert.Equal(t, errIncompleteMessage("", 3, 4), err.(*util.Err).Cause)
|
assert.Equal(t, errIncompleteMessage("", 3, 4), err.(*errors.Err).Cause)
|
||||||
assertEof(t, s)
|
assertEof(t, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ func TestReadFailureIncompleteStatus(t *testing.T) {
|
||||||
s := newEofReader("FAIL")
|
s := newEofReader("FAIL")
|
||||||
_, err := readStatusFailureAsError(s, "req", readHexLength)
|
_, err := readStatusFailureAsError(s, "req", readHexLength)
|
||||||
assert.EqualError(t, err, "NetworkError: server returned error for req, but couldn't read the error message")
|
assert.EqualError(t, err, "NetworkError: server returned error for req, but couldn't read the error message")
|
||||||
assert.Error(t, err.(*util.Err).Cause)
|
assert.Error(t, err.(*errors.Err).Cause)
|
||||||
assertEof(t, s)
|
assertEof(t, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,7 +39,7 @@ func TestReadFailureEmptyStatus(t *testing.T) {
|
||||||
s := newEofReader("FAIL0000")
|
s := newEofReader("FAIL0000")
|
||||||
_, err := readStatusFailureAsError(s, "", readHexLength)
|
_, err := readStatusFailureAsError(s, "", readHexLength)
|
||||||
assert.EqualError(t, err, "AdbError: server error: ({Request: ServerMsg:})")
|
assert.EqualError(t, err, "AdbError: server error: ({Request: ServerMsg:})")
|
||||||
assert.NoError(t, err.(*util.Err).Cause)
|
assert.NoError(t, err.(*errors.Err).Cause)
|
||||||
assertEof(t, s)
|
assertEof(t, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ func TestReadFailureStatus(t *testing.T) {
|
||||||
s := newEofReader("FAIL0004fail")
|
s := newEofReader("FAIL0004fail")
|
||||||
_, err := readStatusFailureAsError(s, "", readHexLength)
|
_, err := readStatusFailureAsError(s, "", readHexLength)
|
||||||
assert.EqualError(t, err, "AdbError: server error: fail ({Request: ServerMsg:fail})")
|
assert.EqualError(t, err, "AdbError: server error: fail ({Request: ServerMsg:fail})")
|
||||||
assert.NoError(t, err.(*util.Err).Cause)
|
assert.NoError(t, err.(*errors.Err).Cause)
|
||||||
assertEof(t, s)
|
assertEof(t, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ func TestReadLengthIncompleteLength(t *testing.T) {
|
||||||
|
|
||||||
func assertEof(t *testing.T, r io.Reader) {
|
func assertEof(t *testing.T, r io.Reader) {
|
||||||
msg, err := readMessage(r, readHexLength)
|
msg, err := readMessage(r, readHexLength)
|
||||||
assert.True(t, util.HasErrCode(err, util.ConnectionResetError))
|
assert.True(t, errors.HasErrCode(err, errors.ConnectionResetError))
|
||||||
assert.Nil(t, msg)
|
assert.Nil(t, msg)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Sender sends messages to the server.
|
// Sender sends messages to the server.
|
||||||
|
@ -30,7 +30,7 @@ func SendMessageString(s Sender, msg string) error {
|
||||||
|
|
||||||
func (s *realSender) SendMessage(msg []byte) error {
|
func (s *realSender) SendMessage(msg []byte) error {
|
||||||
if len(msg) > MaxMessageLength {
|
if len(msg) > MaxMessageLength {
|
||||||
return util.AssertionErrorf("message length exceeds maximum: %d", len(msg))
|
return errors.AssertionErrorf("message length exceeds maximum: %d", len(msg))
|
||||||
}
|
}
|
||||||
|
|
||||||
lengthAndMsg := fmt.Sprintf("%04x%s", len(msg), msg)
|
lengthAndMsg := fmt.Sprintf("%04x%s", len(msg), msg)
|
||||||
|
@ -42,7 +42,7 @@ func (s *realSender) NewSyncSender() SyncSender {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *realSender) Close() error {
|
func (s *realSender) Close() error {
|
||||||
return util.WrapErrorf(s.writer.Close(), util.NetworkError, "error closing sender")
|
return errors.WrapErrorf(s.writer.Close(), errors.NetworkError, "error closing sender")
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ Sender = &realSender{}
|
var _ Sender = &realSender{}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
package wire
|
package wire
|
||||||
|
|
||||||
import "github.com/zach-klippenstein/goadb/util"
|
import "github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
|
|
||||||
const (
|
const (
|
||||||
// Chunks cannot be longer than 64k.
|
// Chunks cannot be longer than 64k.
|
||||||
|
@ -32,6 +32,6 @@ type SyncConn struct {
|
||||||
|
|
||||||
// Close closes both the sender and the scanner, and returns any errors.
|
// Close closes both the sender and the scanner, and returns any errors.
|
||||||
func (c SyncConn) Close() error {
|
func (c SyncConn) Close() error {
|
||||||
return util.CombineErrs("error closing SyncConn", util.NetworkError,
|
return errors.CombineErrs("error closing SyncConn", errors.NetworkError,
|
||||||
c.SyncScanner.Close(), c.SyncSender.Close())
|
c.SyncScanner.Close(), c.SyncSender.Close())
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SyncScanner interface {
|
type SyncScanner interface {
|
||||||
|
@ -39,13 +39,13 @@ func (s *realSyncScanner) ReadStatus(req string) (string, error) {
|
||||||
|
|
||||||
func (s *realSyncScanner) ReadInt32() (int32, error) {
|
func (s *realSyncScanner) ReadInt32() (int32, error) {
|
||||||
value, err := readInt32(s.Reader)
|
value, err := readInt32(s.Reader)
|
||||||
return int32(value), util.WrapErrorf(err, util.NetworkError, "error reading int from sync scanner")
|
return int32(value), errors.WrapErrorf(err, errors.NetworkError, "error reading int from sync scanner")
|
||||||
}
|
}
|
||||||
func (s *realSyncScanner) ReadFileMode() (os.FileMode, error) {
|
func (s *realSyncScanner) ReadFileMode() (os.FileMode, error) {
|
||||||
var value uint32
|
var value uint32
|
||||||
err := binary.Read(s.Reader, binary.LittleEndian, &value)
|
err := binary.Read(s.Reader, binary.LittleEndian, &value)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, util.WrapErrorf(err, util.NetworkError, "error reading filemode from sync scanner")
|
return 0, errors.WrapErrorf(err, errors.NetworkError, "error reading filemode from sync scanner")
|
||||||
}
|
}
|
||||||
return ParseFileModeFromAdb(value), nil
|
return ParseFileModeFromAdb(value), nil
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ func (s *realSyncScanner) ReadFileMode() (os.FileMode, error) {
|
||||||
func (s *realSyncScanner) ReadTime() (time.Time, error) {
|
func (s *realSyncScanner) ReadTime() (time.Time, error) {
|
||||||
seconds, err := s.ReadInt32()
|
seconds, err := s.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return time.Time{}, util.WrapErrorf(err, util.NetworkError, "error reading time from sync scanner")
|
return time.Time{}, errors.WrapErrorf(err, errors.NetworkError, "error reading time from sync scanner")
|
||||||
}
|
}
|
||||||
|
|
||||||
return time.Unix(int64(seconds), 0).UTC(), nil
|
return time.Unix(int64(seconds), 0).UTC(), nil
|
||||||
|
@ -62,13 +62,13 @@ func (s *realSyncScanner) ReadTime() (time.Time, error) {
|
||||||
func (s *realSyncScanner) ReadString() (string, error) {
|
func (s *realSyncScanner) ReadString() (string, error) {
|
||||||
length, err := s.ReadInt32()
|
length, err := s.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", util.WrapErrorf(err, util.NetworkError, "error reading length from sync scanner")
|
return "", errors.WrapErrorf(err, errors.NetworkError, "error reading length from sync scanner")
|
||||||
}
|
}
|
||||||
|
|
||||||
bytes := make([]byte, length)
|
bytes := make([]byte, length)
|
||||||
n, rawErr := io.ReadFull(s.Reader, bytes)
|
n, rawErr := io.ReadFull(s.Reader, bytes)
|
||||||
if rawErr != nil && rawErr != io.ErrUnexpectedEOF {
|
if rawErr != nil && rawErr != io.ErrUnexpectedEOF {
|
||||||
return "", util.WrapErrorf(rawErr, util.NetworkError, "error reading string from sync scanner")
|
return "", errors.WrapErrorf(rawErr, errors.NetworkError, "error reading string from sync scanner")
|
||||||
} else if rawErr == io.ErrUnexpectedEOF {
|
} else if rawErr == io.ErrUnexpectedEOF {
|
||||||
return "", errIncompleteMessage("bytes", n, int(length))
|
return "", errIncompleteMessage("bytes", n, int(length))
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ func (s *realSyncScanner) ReadString() (string, error) {
|
||||||
func (s *realSyncScanner) ReadBytes() (io.Reader, error) {
|
func (s *realSyncScanner) ReadBytes() (io.Reader, error) {
|
||||||
length, err := s.ReadInt32()
|
length, err := s.ReadInt32()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, util.WrapErrorf(err, util.NetworkError, "error reading bytes from sync scanner")
|
return nil, errors.WrapErrorf(err, errors.NetworkError, "error reading bytes from sync scanner")
|
||||||
}
|
}
|
||||||
|
|
||||||
return io.LimitReader(s.Reader, int64(length)), nil
|
return io.LimitReader(s.Reader, int64(length)), nil
|
||||||
|
@ -86,7 +86,7 @@ func (s *realSyncScanner) ReadBytes() (io.Reader, error) {
|
||||||
|
|
||||||
func (s *realSyncScanner) Close() error {
|
func (s *realSyncScanner) Close() error {
|
||||||
if closer, ok := s.Reader.(io.Closer); ok {
|
if closer, ok := s.Reader.(io.Closer); ok {
|
||||||
return util.WrapErrorf(closer.Close(), util.NetworkError, "error closing sync scanner")
|
return errors.WrapErrorf(closer.Close(), errors.NetworkError, "error closing sync scanner")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SyncSender interface {
|
type SyncSender interface {
|
||||||
|
@ -33,28 +33,28 @@ func NewSyncSender(w io.Writer) SyncSender {
|
||||||
|
|
||||||
func (s *realSyncSender) SendOctetString(str string) error {
|
func (s *realSyncSender) SendOctetString(str string) error {
|
||||||
if len(str) != 4 {
|
if len(str) != 4 {
|
||||||
return util.AssertionErrorf("octet string must be exactly 4 bytes: '%s'", str)
|
return errors.AssertionErrorf("octet string must be exactly 4 bytes: '%s'", str)
|
||||||
}
|
}
|
||||||
|
|
||||||
wrappedErr := util.WrapErrorf(writeFully(s.Writer, []byte(str)),
|
wrappedErr := errors.WrapErrorf(writeFully(s.Writer, []byte(str)),
|
||||||
util.NetworkError, "error sending octet string on sync sender")
|
errors.NetworkError, "error sending octet string on sync sender")
|
||||||
|
|
||||||
return wrappedErr
|
return wrappedErr
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *realSyncSender) SendInt32(val int32) error {
|
func (s *realSyncSender) SendInt32(val int32) error {
|
||||||
return util.WrapErrorf(binary.Write(s.Writer, binary.LittleEndian, val),
|
return errors.WrapErrorf(binary.Write(s.Writer, binary.LittleEndian, val),
|
||||||
util.NetworkError, "error sending int on sync sender")
|
errors.NetworkError, "error sending int on sync sender")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *realSyncSender) SendFileMode(mode os.FileMode) error {
|
func (s *realSyncSender) SendFileMode(mode os.FileMode) error {
|
||||||
return util.WrapErrorf(binary.Write(s.Writer, binary.LittleEndian, mode),
|
return errors.WrapErrorf(binary.Write(s.Writer, binary.LittleEndian, mode),
|
||||||
util.NetworkError, "error sending filemode on sync sender")
|
errors.NetworkError, "error sending filemode on sync sender")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *realSyncSender) SendTime(t time.Time) error {
|
func (s *realSyncSender) SendTime(t time.Time) error {
|
||||||
return util.WrapErrorf(s.SendInt32(int32(t.Unix())),
|
return errors.WrapErrorf(s.SendInt32(int32(t.Unix())),
|
||||||
util.NetworkError, "error sending time on sync sender")
|
errors.NetworkError, "error sending time on sync sender")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *realSyncSender) SendBytes(data []byte) error {
|
func (s *realSyncSender) SendBytes(data []byte) error {
|
||||||
|
@ -62,18 +62,18 @@ func (s *realSyncSender) SendBytes(data []byte) error {
|
||||||
if length > SyncMaxChunkSize {
|
if length > SyncMaxChunkSize {
|
||||||
// This limit might not apply to filenames, but it's big enough
|
// This limit might not apply to filenames, but it's big enough
|
||||||
// that I don't think it will be a problem.
|
// that I don't think it will be a problem.
|
||||||
return util.AssertionErrorf("data must be <= %d in length", SyncMaxChunkSize)
|
return errors.AssertionErrorf("data must be <= %d in length", SyncMaxChunkSize)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.SendInt32(int32(length)); err != nil {
|
if err := s.SendInt32(int32(length)); err != nil {
|
||||||
return util.WrapErrorf(err, util.NetworkError, "error sending data length on sync sender")
|
return errors.WrapErrorf(err, errors.NetworkError, "error sending data length on sync sender")
|
||||||
}
|
}
|
||||||
return writeFully(s.Writer, data)
|
return writeFully(s.Writer, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *realSyncSender) Close() error {
|
func (s *realSyncSender) Close() error {
|
||||||
if closer, ok := s.Writer.(io.Closer); ok {
|
if closer, ok := s.Writer.(io.Closer); ok {
|
||||||
return util.WrapErrorf(closer.Close(), util.NetworkError, "error closing sync sender")
|
return errors.WrapErrorf(closer.Close(), errors.NetworkError, "error closing sync sender")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -29,7 +29,7 @@ func TestSyncSendOctetStringTooLong(t *testing.T) {
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
s := NewSyncSender(&buf)
|
s := NewSyncSender(&buf)
|
||||||
err := s.SendOctetString("hello")
|
err := s.SendOctetString("hello")
|
||||||
assert.Equal(t, util.AssertionErrorf("octet string must be exactly 4 bytes: 'hello'"), err)
|
assert.Equal(t, errors.AssertionErrorf("octet string must be exactly 4 bytes: 'hello'"), err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSyncReadTime(t *testing.T) {
|
func TestSyncReadTime(t *testing.T) {
|
||||||
|
|
21
wire/util.go
21
wire/util.go
|
@ -4,10 +4,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ErrorResponseDetails is an error message returned by the server for a particular request.
|
// ErrorResponseDetails is an error message returned by the server for a particular request.
|
||||||
|
@ -17,7 +16,7 @@ type ErrorResponseDetails struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
// deviceNotFoundMessagePattern matches all possible error messages returned by adb servers to
|
// deviceNotFoundMessagePattern matches all possible error messages returned by adb servers to
|
||||||
// report that a matching device was not found. Used to set the util.DeviceNotFound error code on
|
// report that a matching device was not found. Used to set the DeviceNotFound error code on
|
||||||
// error values.
|
// error values.
|
||||||
//
|
//
|
||||||
// Old servers send "device not found", and newer ones "device 'serial' not found".
|
// Old servers send "device not found", and newer ones "device 'serial' not found".
|
||||||
|
@ -31,12 +30,12 @@ func adbServerError(request string, serverMsg string) error {
|
||||||
msg = fmt.Sprintf("server error for %s request: %s", request, serverMsg)
|
msg = fmt.Sprintf("server error for %s request: %s", request, serverMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
errCode := util.AdbError
|
errCode := errors.AdbError
|
||||||
if deviceNotFoundMessagePattern.MatchString(serverMsg) {
|
if deviceNotFoundMessagePattern.MatchString(serverMsg) {
|
||||||
errCode = util.DeviceNotFound
|
errCode = errors.DeviceNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
return &util.Err{
|
return &errors.Err{
|
||||||
Code: errCode,
|
Code: errCode,
|
||||||
Message: msg,
|
Message: msg,
|
||||||
Details: ErrorResponseDetails{
|
Details: ErrorResponseDetails{
|
||||||
|
@ -46,18 +45,18 @@ func adbServerError(request string, serverMsg string) error {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsAdbServerErrorMatching returns true if err is an *util.Err with code AdbError and for which
|
// IsAdbServerErrorMatching returns true if err is an *Err with code AdbError and for which
|
||||||
// predicate returns true when passed Details.ServerMsg.
|
// predicate returns true when passed Details.ServerMsg.
|
||||||
func IsAdbServerErrorMatching(err error, predicate func(string) bool) bool {
|
func IsAdbServerErrorMatching(err error, predicate func(string) bool) bool {
|
||||||
if err, ok := err.(*util.Err); ok && err.Code == util.AdbError {
|
if err, ok := err.(*errors.Err); ok && err.Code == errors.AdbError {
|
||||||
return predicate(err.Details.(ErrorResponseDetails).ServerMsg)
|
return predicate(err.Details.(ErrorResponseDetails).ServerMsg)
|
||||||
}
|
}
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func errIncompleteMessage(description string, actual int, expected int) error {
|
func errIncompleteMessage(description string, actual int, expected int) error {
|
||||||
return &util.Err{
|
return &errors.Err{
|
||||||
Code: util.ConnectionResetError,
|
Code: errors.ConnectionResetError,
|
||||||
Message: fmt.Sprintf("incomplete %s: read %d bytes, expecting %d", description, actual, expected),
|
Message: fmt.Sprintf("incomplete %s: read %d bytes, expecting %d", description, actual, expected),
|
||||||
Details: struct {
|
Details: struct {
|
||||||
ActualReadBytes int
|
ActualReadBytes int
|
||||||
|
@ -76,7 +75,7 @@ func writeFully(w io.Writer, data []byte) error {
|
||||||
for offset < len(data) {
|
for offset < len(data) {
|
||||||
n, err := w.Write(data[offset:])
|
n, err := w.Write(data[offset:])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return util.WrapErrorf(err, util.NetworkError, "error writing %d bytes at offset %d", len(data), offset)
|
return errors.WrapErrorf(err, errors.NetworkError, "error writing %d bytes at offset %d", len(data), offset)
|
||||||
}
|
}
|
||||||
offset += n
|
offset += n
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,53 +4,53 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"github.com/zach-klippenstein/goadb/util"
|
"github.com/zach-klippenstein/goadb/internal/errors"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestAdbServerError_NoRequest(t *testing.T) {
|
func TestAdbServerError_NoRequest(t *testing.T) {
|
||||||
err := adbServerError("", "fail")
|
err := adbServerError("", "fail")
|
||||||
assert.Equal(t, util.Err{
|
assert.Equal(t, errors.Err{
|
||||||
Code: util.AdbError,
|
Code: errors.AdbError,
|
||||||
Message: "server error: fail",
|
Message: "server error: fail",
|
||||||
Details: ErrorResponseDetails{
|
Details: ErrorResponseDetails{
|
||||||
Request: "",
|
Request: "",
|
||||||
ServerMsg: "fail",
|
ServerMsg: "fail",
|
||||||
},
|
},
|
||||||
}, *(err.(*util.Err)))
|
}, *(err.(*errors.Err)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAdbServerError_WithRequest(t *testing.T) {
|
func TestAdbServerError_WithRequest(t *testing.T) {
|
||||||
err := adbServerError("polite", "fail")
|
err := adbServerError("polite", "fail")
|
||||||
assert.Equal(t, util.Err{
|
assert.Equal(t, errors.Err{
|
||||||
Code: util.AdbError,
|
Code: errors.AdbError,
|
||||||
Message: "server error for polite request: fail",
|
Message: "server error for polite request: fail",
|
||||||
Details: ErrorResponseDetails{
|
Details: ErrorResponseDetails{
|
||||||
Request: "polite",
|
Request: "polite",
|
||||||
ServerMsg: "fail",
|
ServerMsg: "fail",
|
||||||
},
|
},
|
||||||
}, *(err.(*util.Err)))
|
}, *(err.(*errors.Err)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAdbServerError_DeviceNotFound(t *testing.T) {
|
func TestAdbServerError_DeviceNotFound(t *testing.T) {
|
||||||
err := adbServerError("", "device not found")
|
err := adbServerError("", "device not found")
|
||||||
assert.Equal(t, util.Err{
|
assert.Equal(t, errors.Err{
|
||||||
Code: util.DeviceNotFound,
|
Code: errors.DeviceNotFound,
|
||||||
Message: "server error: device not found",
|
Message: "server error: device not found",
|
||||||
Details: ErrorResponseDetails{
|
Details: ErrorResponseDetails{
|
||||||
Request: "",
|
Request: "",
|
||||||
ServerMsg: "device not found",
|
ServerMsg: "device not found",
|
||||||
},
|
},
|
||||||
}, *(err.(*util.Err)))
|
}, *(err.(*errors.Err)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAdbServerError_DeviceSerialNotFound(t *testing.T) {
|
func TestAdbServerError_DeviceSerialNotFound(t *testing.T) {
|
||||||
err := adbServerError("", "device 'LGV4801c74eccd' not found")
|
err := adbServerError("", "device 'LGV4801c74eccd' not found")
|
||||||
assert.Equal(t, util.Err{
|
assert.Equal(t, errors.Err{
|
||||||
Code: util.DeviceNotFound,
|
Code: errors.DeviceNotFound,
|
||||||
Message: "server error: device 'LGV4801c74eccd' not found",
|
Message: "server error: device 'LGV4801c74eccd' not found",
|
||||||
Details: ErrorResponseDetails{
|
Details: ErrorResponseDetails{
|
||||||
Request: "",
|
Request: "",
|
||||||
ServerMsg: "device 'LGV4801c74eccd' not found",
|
ServerMsg: "device 'LGV4801c74eccd' not found",
|
||||||
},
|
},
|
||||||
}, *(err.(*util.Err)))
|
}, *(err.(*errors.Err)))
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue