diff --git a/sync_client.go b/sync_client.go index 92b53d9..ac40470 100644 --- a/sync_client.go +++ b/sync_client.go @@ -4,10 +4,14 @@ package goadb import ( "fmt" "io" + "os" + "time" "github.com/zach-klippenstein/goadb/wire" ) +var zeroTime = time.Unix(0, 0).UTC() + func stat(conn *wire.SyncConn, path string) (*DirEntry, error) { if err := conn.SendOctetString("STAT"); err != nil { return nil, err @@ -66,6 +70,12 @@ func readStat(s wire.SyncScanner) (entry *DirEntry, err error) { return } + // 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. + if mode == os.FileMode(0) && size == 0 && mtime == zeroTime { + return nil, os.ErrNotExist + } + entry = &DirEntry{ Mode: mode, Size: size, diff --git a/sync_client_test.go b/sync_client_test.go index d1fde95..f01220b 100644 --- a/sync_client_test.go +++ b/sync_client_test.go @@ -1,2 +1,58 @@ // TODO(z): Implement tests for sync_client functions. package goadb + +import ( + "bytes" + "os" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/zach-klippenstein/goadb/wire" +) + +var someTime = time.Date(2015, 5, 3, 8, 8, 8, 0, time.UTC) + +func TestStatValid(t *testing.T) { + var buf bytes.Buffer + conn := &wire.SyncConn{wire.NewSyncScanner(&buf), wire.NewSyncSender(&buf)} + + var mode os.FileMode = 0777 + + conn.SendOctetString("STAT") + conn.SendFileMode(mode) + conn.SendInt32(4) + conn.SendTime(someTime) + + entry, err := stat(conn, "/thing") + assert.NoError(t, err) + assert.Equal(t, mode, entry.Mode, "expected os.FileMode %s, got %s", mode, entry.Mode) + assert.Equal(t, 4, entry.Size) + assert.Equal(t, someTime, entry.ModifiedAt) + assert.Equal(t, "", entry.Name) +} + +func TestStatBadResponse(t *testing.T) { + var buf bytes.Buffer + conn := &wire.SyncConn{wire.NewSyncScanner(&buf), wire.NewSyncSender(&buf)} + + conn.SendOctetString("SPAT") + + entry, err := stat(conn, "/") + assert.Nil(t, entry) + assert.Error(t, err) +} + +func TestStatNoExist(t *testing.T) { + var buf bytes.Buffer + conn := &wire.SyncConn{wire.NewSyncScanner(&buf), wire.NewSyncSender(&buf)} + + conn.SendOctetString("STAT") + conn.SendFileMode(0) + conn.SendInt32(0) + conn.SendTime(time.Unix(0, 0).UTC()) + + entry, err := stat(conn, "/") + assert.Nil(t, entry) + assert.Equal(t, os.ErrNotExist, err) +}