Skip to content

Commit

Permalink
Refactored ClientConfig into a Server interface.
Browse files Browse the repository at this point in the history
* StartServer is now a method on Server.
* What used to be Dialer.Dial is now Server.Dial.
* Server.Dial handles trying to start the server if the initial connection fails.
* Dialer now dials a network address.
* All types that took a Dialer now take a Server.
* Server now has tests!
  • Loading branch information
zach-klippenstein committed Jan 10, 2016
1 parent 11dc26d commit 9f7d11a
Show file tree
Hide file tree
Showing 15 changed files with 420 additions and 278 deletions.
16 changes: 0 additions & 16 deletions client_config.go

This file was deleted.

17 changes: 13 additions & 4 deletions cmd/adb/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,18 @@ var (
pushRemoteArg = pushCommand.Arg("remote", "Path of destination file on device.").Required().String()
)

var server goadb.Server

func main() {
var exitCode int

var err error
server, err = goadb.NewServer(goadb.ServerConfig{})
if err != nil {
fmt.Fprintln(os.Stderr, "error:", err)
os.Exit(1)
}

switch kingpin.Parse() {
case "devices":
exitCode = listDevices(*devicesLongFlag)
Expand All @@ -62,7 +71,7 @@ func parseDevice() goadb.DeviceDescriptor {
}

func listDevices(long bool) int {
client := goadb.NewHostClient(goadb.ClientConfig{})
client := goadb.NewHostClient(server)
devices, err := client.ListDevices()
if err != nil {
fmt.Fprintln(os.Stderr, "error:", err)
Expand Down Expand Up @@ -99,7 +108,7 @@ func runShellCommand(commandAndArgs []string, device goadb.DeviceDescriptor) int
args = commandAndArgs[1:]
}

client := goadb.NewDeviceClient(goadb.ClientConfig{}, device)
client := goadb.NewDeviceClient(server, device)
output, err := client.RunCommand(command, args...)
if err != nil {
fmt.Fprintln(os.Stderr, "error:", err)
Expand All @@ -121,7 +130,7 @@ func pull(showProgress bool, remotePath, localPath string, device goadb.DeviceDe
localPath = filepath.Base(remotePath)
}

client := goadb.NewDeviceClient(goadb.ClientConfig{}, device)
client := goadb.NewDeviceClient(server, device)

info, err := client.Stat(remotePath)
if util.HasErrCode(err, util.FileNoExistError) {
Expand Down Expand Up @@ -194,7 +203,7 @@ func push(showProgress bool, localPath, remotePath string, device goadb.DeviceDe
}
defer localFile.Close()

client := goadb.NewDeviceClient(goadb.ClientConfig{}, device)
client := goadb.NewDeviceClient(server, device)
writer, err := client.OpenWrite(remotePath, perms, mtime)
if err != nil {
fmt.Fprintf(os.Stderr, "error opening remote file %s: %s\n", remotePath, err)
Expand Down
23 changes: 17 additions & 6 deletions cmd/demo/demo.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,26 @@ import (
"github.com/zach-klippenstein/goadb/util"
)

var port = flag.Int("p", adb.AdbPort, "")
var (
port = flag.Int("p", adb.AdbPort, "")

server adb.Server
)

func main() {
flag.Parse()

client := adb.NewHostClient(adb.ClientConfig{})

var err error
server, err = adb.NewServer(adb.ServerConfig{
Port: *port,
})
if err != nil {
log.Fatal(err)
}
fmt.Println("Starting server…")
adb.StartServer()
server.Start()

client := adb.NewHostClient(server)

serverVersion, err := client.GetServerVersion()
if err != nil {
Expand Down Expand Up @@ -51,7 +62,7 @@ func main() {

fmt.Println()
fmt.Println("Watching for device state changes.")
watcher := adb.NewDeviceWatcher(adb.ClientConfig{})
watcher := adb.NewDeviceWatcher(server)
for event := range watcher.C() {
fmt.Printf("\t[%s]%+v\n", time.Now(), event)
}
Expand All @@ -77,7 +88,7 @@ func printErr(err error) {
}

func PrintDeviceInfoAndError(descriptor adb.DeviceDescriptor) {
device := adb.NewDeviceClient(adb.ClientConfig{}, descriptor)
device := adb.NewDeviceClient(server, descriptor)
if err := PrintDeviceInfo(device); err != nil {
log.Println(err)
}
Expand Down
9 changes: 8 additions & 1 deletion cmd/raw-adb/raw-adb.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,14 @@ func readLine() string {
}

func doCommand(cmd string) error {
conn, err := goadb.NewDialer("", *port).Dial()
server, err := goadb.NewServer(goadb.ServerConfig{
Port: *port,
})
if err != nil {
log.Fatal(err)
}

conn, err := server.Dial()
if err != nil {
log.Fatal(err)
}
Expand Down
12 changes: 6 additions & 6 deletions device_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,18 @@ var MtimeOfClose = time.Time{}

// DeviceClient communicates with a specific Android device.
type DeviceClient struct {
config ClientConfig
server Server
descriptor DeviceDescriptor

// Used to get device info.
deviceListFunc func() ([]*DeviceInfo, error)
}

func NewDeviceClient(config ClientConfig, descriptor DeviceDescriptor) *DeviceClient {
func NewDeviceClient(server Server, descriptor DeviceDescriptor) *DeviceClient {
return &DeviceClient{
config: config.sanitized(),
server: server,
descriptor: descriptor,
deviceListFunc: NewHostClient(config).ListDevices,
deviceListFunc: NewHostClient(server).ListDevices,
}
}

Expand Down Expand Up @@ -194,7 +194,7 @@ func (c *DeviceClient) OpenWrite(path string, perms os.FileMode, mtime time.Time
// getAttribute returns the first message returned by the server by running
// <host-prefix>:<attr>, where host-prefix is determined from the DeviceDescriptor.
func (c *DeviceClient) getAttribute(attr string) (string, error) {
resp, err := roundTripSingleResponse(c.config.Dialer,
resp, err := roundTripSingleResponse(c.server,
fmt.Sprintf("%s:%s", c.descriptor.getHostPrefix(), attr))
if err != nil {
return "", err
Expand Down Expand Up @@ -222,7 +222,7 @@ func (c *DeviceClient) getSyncConn() (*wire.SyncConn, error) {
// dialDevice switches the connection to communicate directly with the device
// by requesting the transport defined by the DeviceDescriptor.
func (c *DeviceClient) dialDevice() (*wire.Conn, error) {
conn, err := c.config.Dialer.Dial()
conn, err := c.server.Dial()
if err != nil {
return nil, err
}
Expand Down
22 changes: 5 additions & 17 deletions device_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,7 @@ func TestGetAttribute(t *testing.T) {
Status: wire.StatusSuccess,
Messages: []string{"value"},
}
client := NewDeviceClient(
ClientConfig{
Dialer: s,
},
DeviceWithSerial("serial"),
)
client := NewDeviceClient(s, DeviceWithSerial("serial"))

v, err := client.getAttribute("attr")
assert.Equal(t, "host-serial:serial:attr", s.Requests[0])
Expand Down Expand Up @@ -60,11 +55,9 @@ func TestGetDeviceInfo(t *testing.T) {

func newDeviceClientWithDeviceLister(serial string, deviceLister func() ([]*DeviceInfo, error)) *DeviceClient {
client := NewDeviceClient(
ClientConfig{
Dialer: &MockServer{
Status: wire.StatusSuccess,
Messages: []string{serial},
},
&MockServer{
Status: wire.StatusSuccess,
Messages: []string{serial},
},
DeviceWithSerial(serial),
)
Expand All @@ -77,12 +70,7 @@ func TestRunCommandNoArgs(t *testing.T) {
Status: wire.StatusSuccess,
Messages: []string{"output"},
}
client := NewDeviceClient(
ClientConfig{
Dialer: s,
},
AnyDevice(),
)
client := NewDeviceClient(s, AnyDevice())

v, err := client.RunCommand("cmd")
assert.Equal(t, "host:transport-any", s.Requests[0])
Expand Down
22 changes: 9 additions & 13 deletions device_watcher.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package goadb

import (
"log"
"math/rand"
"runtime"
"strings"
"sync/atomic"
"math/rand"
"time"

"github.com/zach-klippenstein/goadb/util"
Expand Down Expand Up @@ -59,22 +59,18 @@ var deviceStateStrings = map[string]DeviceState{
}

type deviceWatcherImpl struct {
config ClientConfig
server Server

// If an error occurs, it is stored here and eventChan is close immediately after.
err atomic.Value

eventChan chan DeviceStateChangedEvent

// Function to start the server if it's not running or dies.
startServer func() error
}

func NewDeviceWatcher(config ClientConfig) *DeviceWatcher {
func NewDeviceWatcher(server Server) *DeviceWatcher {
watcher := &DeviceWatcher{&deviceWatcherImpl{
config: config.sanitized(),
eventChan: make(chan DeviceStateChangedEvent),
startServer: StartServer,
server: server,
eventChan: make(chan DeviceStateChangedEvent),
}}

runtime.SetFinalizer(watcher, func(watcher *DeviceWatcher) {
Expand Down Expand Up @@ -134,7 +130,7 @@ func publishDevices(watcher *deviceWatcherImpl) {
finished := false

for {
scanner, err := connectToTrackDevices(watcher.config.Dialer)
scanner, err := connectToTrackDevices(watcher.server)
if err != nil {
watcher.reportErr(err)
return
Expand All @@ -156,7 +152,7 @@ func publishDevices(watcher *deviceWatcherImpl) {

log.Printf("[DeviceWatcher] server died, restarting in %s…", delay)
time.Sleep(delay)
if err := watcher.startServer(); err != nil {
if err := watcher.server.Start(); err != nil {
log.Println("[DeviceWatcher] error restarting server, giving up")
watcher.reportErr(err)
return
Expand All @@ -169,8 +165,8 @@ func publishDevices(watcher *deviceWatcherImpl) {
}
}

func connectToTrackDevices(dialer Dialer) (wire.Scanner, error) {
conn, err := dialer.Dial()
func connectToTrackDevices(server Server) (wire.Scanner, error) {
conn, err := server.Dial()
if err != nil {
return nil, err
}
Expand Down
31 changes: 6 additions & 25 deletions device_watcher_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package goadb

import (
"log"
"testing"

"github.com/stretchr/testify/assert"
Expand Down Expand Up @@ -207,8 +206,7 @@ func TestWentOffline(t *testing.T) {
}

func TestPublishDevicesRestartsServer(t *testing.T) {
starter := &MockServerStarter{}
dialer := &MockServer{
server := &MockServer{
Status: wire.StatusSuccess,
Errs: []error{
nil, nil, nil, // Successful dial.
Expand All @@ -217,34 +215,17 @@ func TestPublishDevicesRestartsServer(t *testing.T) {
},
}
watcher := deviceWatcherImpl{
config: ClientConfig{dialer},
eventChan: make(chan DeviceStateChangedEvent),
startServer: starter.StartServer,
server: server,
eventChan: make(chan DeviceStateChangedEvent),
}

publishDevices(&watcher)

assert.Empty(t, dialer.Errs)
assert.Equal(t, []string{"host:track-devices"}, dialer.Requests)
assert.Equal(t, []string{"Dial", "SendMessage", "ReadStatus", "ReadMessage", "Dial"}, dialer.Trace)
assert.Empty(t, server.Errs)
assert.Equal(t, []string{"host:track-devices"}, server.Requests)
assert.Equal(t, []string{"Dial", "SendMessage", "ReadStatus", "ReadMessage", "Start", "Dial"}, server.Trace)
err := watcher.err.Load().(*util.Err)
assert.Equal(t, util.ServerNotAvailable, err.Code)
assert.Equal(t, 1, starter.startCount)
}

type MockServerStarter struct {
startCount int
err error
}

func (s *MockServerStarter) StartServer() error {
log.Printf("Starting mock server")
if s.err == nil {
s.startCount += 1
return nil
} else {
return s.err
}
}

func assertContainsOnly(t *testing.T, expected, actual []DeviceStateChangedEvent) {
Expand Down
Loading

0 comments on commit 9f7d11a

Please sign in to comment.