blob: 31fe509b6286e2e49f8a2840c13218c32808b65f [file] [log] [blame]
package machine
import (
"fmt"
"os"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"go.skia.org/infra/go/executil"
"go.skia.org/infra/go/testutils/noop"
"go.skia.org/infra/go/testutils/unittest"
"go.skia.org/infra/machine/go/machine"
"go.skia.org/infra/machine/go/test_machine_monitor/adb"
"go.skia.org/infra/machine/go/test_machine_monitor/ssh"
)
const (
// For example values, see adb_test.go
getPropPlaceholder = "Placeholder get prop response"
dumpSysBatteryPlaceholder = "Placeholder dumpsys battery response"
dumpSysThermalPlaceholder = "Placeholder dumpsys thermal response"
// This formatting matters because it is processed in adb.go
adbUptimePlaceholder = "123.4 567.8"
testUserIP = "root@skia-foobar-01"
// This example was taken directly from a production ChromeOS device
sampleChromeOSlsbrelease = `CHROMEOS_DEVSERVER=
CHROMEOS_RELEASE_APPID={9A3BE5D2-C3DC-4AE6-9943-E2C113895DC5}
CHROMEOS_RELEASE_BOARD=octopus-signed-mp-v23keys
CHROMEOS_RELEASE_BRANCH_NUMBER=56
CHROMEOS_RELEASE_BUILDER_PATH=octopus-release/R89-13729.56.0
CHROMEOS_RELEASE_BUILD_NUMBER=13729
CHROMEOS_RELEASE_BUILD_TYPE=Official Build
CHROMEOS_RELEASE_CHROME_MILESTONE=89
CHROMEOS_RELEASE_DESCRIPTION=13729.56.0 (Official Build) stable-channel octopus
CHROMEOS_RELEASE_KEYSET=mp-v23
CHROMEOS_RELEASE_NAME=Chrome OS
CHROMEOS_RELEASE_PATCH_NUMBER=0
CHROMEOS_RELEASE_TRACK=stable-channel
CHROMEOS_RELEASE_UNIBUILD=1
CHROMEOS_RELEASE_VERSION=13729.56.0
DEVICETYPE=CHROMEBOOK
GOOGLE_RELEASE=13729.56.0`
// This example was taken directly from a production ChromeOS device
sampleChromeOSUptime = "1234.5 5678.9"
)
func TestTryInterrogatingAndroidDevice_DeviceAttached_Success(t *testing.T) {
unittest.SmallTest(t)
ctx := executil.FakeTestsContext(
"Test_FakeExe_ADBUptime_ReturnsPlaceholder",
"Test_FakeExe_AdbShellGetProp_ReturnsPlaceholder",
"Test_FakeExe_RawDumpSysBattery_ReturnsPlaceholder",
"Test_FakeExe_RawDumpSysThermal_ReturnsPlaceholder",
)
m := &Machine{adb: adb.New()}
actual, ok := m.tryInterrogatingAndroidDevice(ctx)
assert.True(t, ok)
assert.Equal(t, machine.Android{
GetProp: getPropPlaceholder,
DumpsysBattery: dumpSysBatteryPlaceholder,
DumpsysThermalService: dumpSysThermalPlaceholder,
Uptime: 123 * time.Second,
}, actual)
}
func TestTryInterrogatingAndroidDevice_UptimeFails_DeviceConsideredNotAttached(t *testing.T) {
unittest.SmallTest(t)
ctx := executil.FakeTestsContext(
"Test_FakeExe_ExitCodeOne",
)
m := &Machine{adb: adb.New()}
_, ok := m.tryInterrogatingAndroidDevice(ctx)
assert.False(t, ok)
}
func TestTryInterrogatingAndroidDevice_ThermalFails_PartialSuccess(t *testing.T) {
unittest.SmallTest(t)
ctx := executil.FakeTestsContext(
"Test_FakeExe_ADBUptime_ReturnsPlaceholder",
"Test_FakeExe_AdbShellGetProp_ReturnsPlaceholder",
"Test_FakeExe_RawDumpSysBattery_ReturnsPlaceholder",
"Test_FakeExe_ExitCodeOne",
)
m := &Machine{adb: adb.New()}
actual, ok := m.tryInterrogatingAndroidDevice(ctx)
assert.True(t, ok)
assert.Equal(t, machine.Android{
GetProp: getPropPlaceholder,
DumpsysBattery: dumpSysBatteryPlaceholder,
Uptime: 123 * time.Second,
}, actual)
}
func TestTryInterrogatingChromeOS_DeviceReachable_Success(t *testing.T) {
unittest.SmallTest(t)
ctx := executil.FakeTestsContext(
"Test_FakeExe_SSHLSBRelease_ReturnsPlaceholder",
"Test_FakeExe_SSHUptime_ReturnsPlaceholder",
)
m := &Machine{ssh: ssh.ExeImpl{}, description: machine.Description{SSHUserIP: testUserIP}}
actual, ok := m.tryInterrogatingChromeOSDevice(ctx)
assert.True(t, ok)
assert.Equal(t, machine.ChromeOS{
Channel: "stable-channel",
Milestone: "89",
ReleaseVersion: "13729.56.0",
Uptime: 1234500 * time.Millisecond,
}, actual)
}
func TestTryInterrogatingChromeOS_CatLSBReleaseFails_DeviceConsideredUnattached(t *testing.T) {
unittest.SmallTest(t)
ctx := executil.FakeTestsContext(
"Test_FakeExe_ExitCodeOne",
)
m := &Machine{ssh: ssh.ExeImpl{}, description: machine.Description{SSHUserIP: testUserIP}}
_, ok := m.tryInterrogatingChromeOSDevice(ctx)
assert.False(t, ok)
}
func TestTryInterrogatingChromeOS_NoSSHUserIP_ReturnFalse(t *testing.T) {
unittest.SmallTest(t)
ctx := executil.FakeTestsContext() // Any exe call will panic
m := &Machine{ssh: ssh.ExeImpl{}}
_, ok := m.tryInterrogatingChromeOSDevice(ctx)
assert.False(t, ok)
}
func TestTryInterrogatingChromeOS_PartialData_PartialSuccess(t *testing.T) {
unittest.SmallTest(t)
ctx := executil.FakeTestsContext(
"Test_FakeExe_SSHLSBRelease_ReturnsPlaceholder",
"Test_FakeExe_ExitCodeOne", // pretend uptime fails
)
m := &Machine{ssh: ssh.ExeImpl{}, description: machine.Description{SSHUserIP: testUserIP}}
actual, ok := m.tryInterrogatingChromeOSDevice(ctx)
assert.True(t, ok)
assert.Equal(t, machine.ChromeOS{
Channel: "stable-channel",
Milestone: "89",
ReleaseVersion: "13729.56.0",
// No uptime reported
}, actual)
}
func TestTryInterrogatingChromeOS_NoChromeOSData_AssumesNotAttached(t *testing.T) {
unittest.SmallTest(t)
ctx := executil.FakeTestsContext(
"Test_FakeExe_SSHLSBRelease_ReturnsNonChromeOS",
)
m := &Machine{ssh: ssh.ExeImpl{}, description: machine.Description{SSHUserIP: testUserIP}}
_, ok := m.tryInterrogatingChromeOSDevice(ctx)
assert.False(t, ok)
}
func TestInterrogate_NoDeviceAttached_Success(t *testing.T) {
unittest.SmallTest(t)
ctx := executil.FakeTestsContext(
"Test_FakeExe_ExitCodeOne", // No Android device
)
m := &Machine{
adb: adb.New(),
MachineID: "some-machine",
Hostname: "some-hostname",
KubernetesImage: "deprecated",
Version: "some-version",
runningTask: true,
startSwarming: true,
startTime: time.Date(2021, time.September, 2, 2, 2, 2, 2, time.UTC),
interrogateTimer: noop.Float64SummaryMetric{},
}
actual := m.interrogate(ctx)
assert.Equal(t, machine.Event{
EventType: machine.EventTypeRawState,
LaunchedSwarming: true,
RunningSwarmingTask: true,
Host: machine.Host{
Name: "some-machine",
PodName: "some-hostname",
KubernetesImage: "deprecated",
Version: "some-version",
StartTime: time.Date(2021, time.September, 2, 2, 2, 2, 2, time.UTC),
},
}, actual)
}
func TestInterrogate_AndroidDeviceAttached_Success(t *testing.T) {
unittest.SmallTest(t)
ctx := executil.FakeTestsContext(
"Test_FakeExe_ADBUptime_ReturnsPlaceholder",
"Test_FakeExe_AdbShellGetProp_ReturnsPlaceholder",
"Test_FakeExe_RawDumpSysBattery_ReturnsPlaceholder",
"Test_FakeExe_RawDumpSysThermal_ReturnsPlaceholder",
)
m := &Machine{
adb: adb.New(),
MachineID: "some-machine",
Hostname: "some-hostname",
KubernetesImage: "deprecated",
Version: "some-version",
runningTask: true,
startSwarming: true,
startTime: time.Date(2021, time.September, 2, 2, 2, 2, 2, time.UTC),
interrogateTimer: noop.Float64SummaryMetric{},
}
actual := m.interrogate(ctx)
assert.Equal(t, machine.Event{
EventType: machine.EventTypeRawState,
LaunchedSwarming: true,
RunningSwarmingTask: true,
Host: machine.Host{
Name: "some-machine",
PodName: "some-hostname",
KubernetesImage: "deprecated",
Version: "some-version",
StartTime: time.Date(2021, time.September, 2, 2, 2, 2, 2, time.UTC),
},
Android: machine.Android{
GetProp: getPropPlaceholder,
DumpsysBattery: dumpSysBatteryPlaceholder,
DumpsysThermalService: dumpSysThermalPlaceholder,
Uptime: 123 * time.Second,
},
}, actual)
}
func TestInterrogate_ChromeOSDeviceAttached_Success(t *testing.T) {
unittest.SmallTest(t)
ctx := executil.FakeTestsContext(
"Test_FakeExe_SSHLSBRelease_ReturnsPlaceholder",
"Test_FakeExe_SSHUptime_ReturnsPlaceholder",
// We found a device, no need to check for adb
)
m := &Machine{
ssh: ssh.ExeImpl{},
MachineID: "some-machine",
Hostname: "some-hostname",
description: machine.Description{
SSHUserIP: testUserIP,
},
KubernetesImage: "deprecated",
Version: "some-version",
runningTask: true,
startSwarming: true,
startTime: time.Date(2021, time.September, 2, 2, 2, 2, 2, time.UTC),
interrogateTimer: noop.Float64SummaryMetric{},
}
actual := m.interrogate(ctx)
assert.Equal(t, machine.Event{
EventType: machine.EventTypeRawState,
LaunchedSwarming: true,
RunningSwarmingTask: true,
Host: machine.Host{
Name: "some-machine",
PodName: "some-hostname",
KubernetesImage: "deprecated",
Version: "some-version",
StartTime: time.Date(2021, time.September, 2, 2, 2, 2, 2, time.UTC),
},
ChromeOS: machine.ChromeOS{
Channel: "stable-channel",
Milestone: "89",
ReleaseVersion: "13729.56.0",
Uptime: 1234500 * time.Millisecond,
},
}, actual)
}
func Test_FakeExe_ADBUptime_ReturnsPlaceholder(t *testing.T) {
unittest.FakeExeTest(t)
if os.Getenv(executil.OverrideEnvironmentVariable) == "" {
return
}
// Check the input arguments to make sure they were as expected.
args := executil.OriginalArgs()
require.Equal(t, []string{"adb", "shell", "cat", "/proc/uptime"}, args)
fmt.Print(adbUptimePlaceholder)
os.Exit(0)
}
func Test_FakeExe_AdbShellGetProp_ReturnsPlaceholder(t *testing.T) {
unittest.FakeExeTest(t)
if os.Getenv(executil.OverrideEnvironmentVariable) == "" {
return
}
// Check the input arguments to make sure they were as expected.
args := executil.OriginalArgs()
require.Equal(t, []string{"adb", "shell", "getprop"}, args)
fmt.Print(getPropPlaceholder)
os.Exit(0)
}
func Test_FakeExe_RawDumpSysBattery_ReturnsPlaceholder(t *testing.T) {
unittest.FakeExeTest(t)
if os.Getenv(executil.OverrideEnvironmentVariable) == "" {
return
}
// Check the input arguments to make sure they were as expected.
args := executil.OriginalArgs()
require.Equal(t, []string{"adb", "shell", "dumpsys", "battery"}, args)
fmt.Print(dumpSysBatteryPlaceholder)
os.Exit(0)
}
func Test_FakeExe_RawDumpSysThermal_ReturnsPlaceholder(t *testing.T) {
unittest.FakeExeTest(t)
if os.Getenv(executil.OverrideEnvironmentVariable) == "" {
return
}
// Check the input arguments to make sure they were as expected.
args := executil.OriginalArgs()
require.Equal(t, []string{"adb", "shell", "dumpsys", "thermalservice"}, args)
fmt.Print(dumpSysThermalPlaceholder)
os.Exit(0)
}
func Test_FakeExe_SSHLSBRelease_ReturnsPlaceholder(t *testing.T) {
unittest.FakeExeTest(t)
if os.Getenv(executil.OverrideEnvironmentVariable) == "" {
return
}
// Check the input arguments to make sure they were as expected.
args := executil.OriginalArgs()
require.Contains(t, args, "ssh")
require.Contains(t, args, testUserIP)
require.Contains(t, args, "/etc/lsb-release")
fmt.Print(sampleChromeOSlsbrelease)
os.Exit(0)
}
func Test_FakeExe_SSHLSBRelease_ReturnsNonChromeOS(t *testing.T) {
unittest.FakeExeTest(t)
if os.Getenv(executil.OverrideEnvironmentVariable) == "" {
return
}
// Check the input arguments to make sure they were as expected.
args := executil.OriginalArgs()
require.Contains(t, args, "ssh")
require.Contains(t, args, testUserIP)
require.Contains(t, args, "/etc/lsb-release")
fmt.Print("FOO=bar")
os.Exit(0)
}
func Test_FakeExe_SSHUptime_ReturnsPlaceholder(t *testing.T) {
unittest.FakeExeTest(t)
if os.Getenv(executil.OverrideEnvironmentVariable) == "" {
return
}
// Check the input arguments to make sure they were as expected.
args := executil.OriginalArgs()
require.Contains(t, args, "ssh")
require.Contains(t, args, testUserIP)
require.Contains(t, args, "/proc/uptime")
fmt.Print(sampleChromeOSUptime)
os.Exit(0)
}
func Test_FakeExe_ExitCodeOne(t *testing.T) {
unittest.FakeExeTest(t)
if os.Getenv(executil.OverrideEnvironmentVariable) == "" {
return
}
os.Exit(1)
}