refactor: raise adb error

This commit is contained in:
lilong.129
2023-06-22 16:33:53 +08:00
parent 0d6da534ab
commit b5612c5632
5 changed files with 62 additions and 41 deletions
+5 -3
View File
@@ -61,9 +61,10 @@ var (
// android device related: [60, 70) // android device related: [60, 70)
var ( var (
AndroidDeviceConnectionError = errors.New("android device connection error") // 60 AndroidDeviceConnectionError = errors.New("android device general connection error") // 60
AndroidDeviceUSBDriverError = errors.New("android device USB driver error") // 61 AndroidDeviceConnectionRefusedError = errors.New("android device connection refused") // 61
AndroidShellExecError = errors.New("android adb shell exec error") // 62 AndroidShellExecError = errors.New("android adb shell exec error") // 62
AndroidDeviceOfflineError = errors.New("android device offline") // 63
AndroidScreenShotError = errors.New("android screenshot error") // 65 AndroidScreenShotError = errors.New("android screenshot error") // 65
AndroidCaptureLogError = errors.New("android capture log error") // 66 AndroidCaptureLogError = errors.New("android capture log error") // 66
) )
@@ -128,8 +129,9 @@ var errorsMap = map[error]int{
// android related // android related
AndroidDeviceConnectionError: 60, AndroidDeviceConnectionError: 60,
AndroidDeviceUSBDriverError: 61, AndroidDeviceConnectionRefusedError: 61,
AndroidShellExecError: 62, AndroidShellExecError: 62,
AndroidDeviceOfflineError: 63,
AndroidScreenShotError: 65, AndroidScreenShotError: 65,
AndroidCaptureLogError: 66, AndroidCaptureLogError: 66,
+9
View File
@@ -5,7 +5,10 @@ import (
"strconv" "strconv"
"strings" "strings"
"github.com/pkg/errors"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
"github.com/httprunner/httprunner/v4/hrp/internal/code"
) )
const ( const (
@@ -84,6 +87,12 @@ func (c Client) DeviceSerialList() (serials []string, err error) {
} }
func (c Client) DeviceList() (devices []*Device, err error) { func (c Client) DeviceList() (devices []*Device, err error) {
defer func() {
if err != nil && errors.Cause(err) == nil {
err = errors.Wrap(code.AndroidDeviceConnectionError, err.Error())
}
}()
var resp string var resp string
if resp, err = c.executeCommand("host:devices-l"); err != nil { if resp, err = c.executeCommand("host:devices-l"); err != nil {
return return
+11 -13
View File
@@ -36,11 +36,17 @@ const (
StateOnline DeviceState = "online" StateOnline DeviceState = "online"
StateOffline DeviceState = "offline" StateOffline DeviceState = "offline"
StateDisconnected DeviceState = "disconnected" StateDisconnected DeviceState = "disconnected"
StateBootloader DeviceState = "bootloader"
StateRecovery DeviceState = "recovery"
StateUnauthorized DeviceState = "unauthorized"
) )
var deviceStateStrings = map[string]DeviceState{ var deviceStateStrings = map[string]DeviceState{
"": StateDisconnected, "": StateDisconnected, // no devices/emulators found
"offline": StateOffline, "offline": StateOffline,
"bootloader": StateBootloader,
"recovery": StateRecovery,
"unauthorized": StateUnauthorized,
"device": StateOnline, "device": StateOnline,
} }
@@ -245,13 +251,10 @@ func (d *Device) ReverseForwardKillAll() error {
func (d *Device) RunShellCommand(cmd string, args ...string) (string, error) { func (d *Device) RunShellCommand(cmd string, args ...string) (string, error) {
raw, err := d.RunShellCommandWithBytes(cmd, args...) raw, err := d.RunShellCommandWithBytes(cmd, args...)
if err != nil { if err != nil && errors.Cause(err) == nil {
if errors.Is(err, code.AndroidDeviceConnectionError) { err = errors.Wrap(code.AndroidShellExecError, err.Error())
return "", err
} }
return "", errors.Wrap(code.AndroidShellExecError, err.Error()) return string(raw), err
}
return string(raw), nil
} }
func (d *Device) RunShellCommandWithBytes(cmd string, args ...string) ([]byte, error) { func (d *Device) RunShellCommandWithBytes(cmd string, args ...string) ([]byte, error) {
@@ -268,11 +271,6 @@ func (d *Device) RunShellCommandWithBytes(cmd string, args ...string) ([]byte, e
return raw, err return raw, err
} }
func (d *Device) RunShellCommandV2(cmd string, args ...string) (string, error) {
raw, err := d.RunShellCommandV2WithBytes(cmd, args...)
return string(raw), err
}
// RunShellCommandV2WithBytes shell v2, 支持后台运行而不会阻断 // RunShellCommandV2WithBytes shell v2, 支持后台运行而不会阻断
func (d *Device) RunShellCommandV2WithBytes(cmd string, args ...string) ([]byte, error) { func (d *Device) RunShellCommandV2WithBytes(cmd string, args ...string) ([]byte, error) {
if len(args) > 0 { if len(args) > 0 {
@@ -594,7 +592,7 @@ func (d *Device) Uninstall(packageName string, keepData ...bool) (string, error)
args = append(args, "-k") args = append(args, "-k")
} }
args = append(args, packageName) args = append(args, packageName)
return d.RunShellCommandV2("pm", args...) return d.RunShellCommand("pm", args...)
} }
func (d *Device) ScreenCap() ([]byte, error) { func (d *Device) ScreenCap() ([]byte, error) {
+22 -9
View File
@@ -7,6 +7,7 @@ import (
"net" "net"
"regexp" "regexp"
"strconv" "strconv"
"strings"
"time" "time"
"github.com/pkg/errors" "github.com/pkg/errors"
@@ -19,6 +20,8 @@ var ErrConnBroken = errors.New("socket connection broken")
var DefaultAdbReadTimeout time.Duration = 60 var DefaultAdbReadTimeout time.Duration = 60
var regexDeviceOffline = regexp.MustCompile("device .* not found")
type transport struct { type transport struct {
sock net.Conn sock net.Conn
readTimeout time.Duration readTimeout time.Duration
@@ -29,9 +32,26 @@ func newTransport(address string, readTimeout ...time.Duration) (tp transport, e
readTimeout = []time.Duration{DefaultAdbReadTimeout} readTimeout = []time.Duration{DefaultAdbReadTimeout}
} }
tp.readTimeout = readTimeout[0] tp.readTimeout = readTimeout[0]
if tp.sock, err = net.Dial("tcp", address); err != nil { tp.sock, err = net.Dial("tcp", address)
err = fmt.Errorf("adb transport: %w", err) if err == nil {
// dial success
return tp, nil
} }
// connection refused
if strings.Contains(err.Error(), "connect: connection refused") {
err = errors.Wrap(code.AndroidDeviceConnectionRefusedError, err.Error())
return
}
// device offline
if regexDeviceOffline.MatchString(err.Error()) {
err = errors.Wrap(code.AndroidDeviceOfflineError, err.Error())
return
}
// other connection errors
err = errors.Wrap(code.AndroidDeviceConnectionError, err.Error())
return return
} }
@@ -48,8 +68,6 @@ func (t transport) Conn() net.Conn {
return t.sock return t.sock
} }
var regexDeviceOffline = regexp.MustCompile("device .* not found")
func (t transport) VerifyResponse() (err error) { func (t transport) VerifyResponse() (err error) {
var status string var status string
if status, err = t.ReadStringN(4); err != nil { if status, err = t.ReadStringN(4); err != nil {
@@ -64,11 +82,6 @@ func (t transport) VerifyResponse() (err error) {
return err return err
} }
if regexDeviceOffline.MatchString(sError) {
// device offline
return errors.Wrap(code.AndroidDeviceConnectionError, sError)
}
log.Warn().Str("status", status).Str("err", sError). log.Warn().Str("status", status).Str("err", sError).
Msg("verify adb response failed") Msg("verify adb response failed")
return errors.New(sError) return errors.New(sError)
+6 -7
View File
@@ -91,7 +91,7 @@ func NewAndroidDevice(options ...AndroidDeviceOption) (device *AndroidDevice, er
deviceList, err := GetAndroidDevices(device.SerialNumber) deviceList, err := GetAndroidDevices(device.SerialNumber)
if err != nil { if err != nil {
return nil, errors.Wrap(code.AndroidDeviceConnectionError, err.Error()) return nil, err
} }
dev := deviceList[0] dev := deviceList[0]
@@ -106,12 +106,11 @@ func NewAndroidDevice(options ...AndroidDeviceOption) (device *AndroidDevice, er
func GetAndroidDevices(serial ...string) (devices []*gadb.Device, err error) { func GetAndroidDevices(serial ...string) (devices []*gadb.Device, err error) {
var adbClient gadb.Client var adbClient gadb.Client
if adbClient, err = gadb.NewClientWith(AdbServerHost, AdbServerPort); err != nil { if adbClient, err = gadb.NewClientWith(AdbServerHost, AdbServerPort); err != nil {
return nil, errors.Wrap(code.AndroidDeviceConnectionError, err.Error()) return nil, err
} }
if devices, err = adbClient.DeviceList(); err != nil { if devices, err = adbClient.DeviceList(); err != nil {
return nil, errors.Wrap(code.AndroidDeviceConnectionError, return nil, err
fmt.Sprintf("list android devices failed: %v", err))
} }
var deviceList []*gadb.Device var deviceList []*gadb.Device
@@ -190,11 +189,11 @@ func (dev *AndroidDevice) NewDriver(capabilities Capabilities) (driverExt *Drive
func (dev *AndroidDevice) NewUSBDriver(capabilities Capabilities) (driver WebDriver, err error) { func (dev *AndroidDevice) NewUSBDriver(capabilities Capabilities) (driver WebDriver, err error) {
var localPort int var localPort int
if localPort, err = getFreePort(); err != nil { if localPort, err = getFreePort(); err != nil {
return nil, errors.Wrap(code.AndroidDeviceUSBDriverError, return nil, errors.Wrap(code.AndroidDeviceConnectionError,
fmt.Sprintf("get free port failed: %v", err)) fmt.Sprintf("get free port failed: %v", err))
} }
if err = dev.d.Forward(localPort, UIA2ServerPort); err != nil { if err = dev.d.Forward(localPort, UIA2ServerPort); err != nil {
return nil, errors.Wrap(code.AndroidDeviceUSBDriverError, return nil, errors.Wrap(code.AndroidDeviceConnectionError,
fmt.Sprintf("forward port %d->%d failed: %v", fmt.Sprintf("forward port %d->%d failed: %v",
localPort, UIA2ServerPort, err)) localPort, UIA2ServerPort, err))
} }
@@ -204,7 +203,7 @@ func (dev *AndroidDevice) NewUSBDriver(capabilities Capabilities) (driver WebDri
uiaDriver, err := NewUIADriver(capabilities, rawURL) uiaDriver, err := NewUIADriver(capabilities, rawURL)
if err != nil { if err != nil {
_ = dev.d.ForwardKill(localPort) _ = dev.d.ForwardKill(localPort)
return nil, errors.Wrap(code.AndroidDeviceUSBDriverError, err.Error()) return nil, errors.Wrap(code.AndroidDeviceConnectionError, err.Error())
} }
uiaDriver.adbClient = dev.d uiaDriver.adbClient = dev.d
uiaDriver.logcat = dev.logcat uiaDriver.logcat = dev.logcat