blob: 5cf8c89e94a8a8930fa0ea3ce4fcf1d3ded05246 [file] [log] [blame]
// Copyright 2021 The ChromiumOS Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package driver
import (
"fmt"
"log"
"os"
"sort"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
"gopkg.in/yaml.v2"
"go.chromium.org/chromiumos/config/go/test/api"
"go.chromium.org/chromiumos/test/execution/cmd/cros-test/internal/device"
)
// TestNewTastArgs makes sure newTastArgs creates the correct arguments for tast.
func TestNewTastArgs(t *testing.T) {
primary := &device.DutInfo{Addr: dut1, Role: ""}
reportsServerValue := ":5555"
varsFileValue := "/tmp/test.yaml"
buildArtifactsURLValue := "gs://chromeos-image-archive/corsola-release/R119-15611.0.0/"
dutLabConfigFile := "dutlabconfig.jsonpb"
varName := "vn"
varValue := "vv"
expectedArgs := runArgs{
primary: primary,
patterns: []string{test1, test2, test3, test4, test5},
tastFlags: map[string]string{
verboseFlag: "true",
logTimeFlag: "false",
},
runFlags: []flagValue{
{sshRetriesFlag, "2"},
{buildFlag, "false"},
{downloadPrivateBundlesFlag, "true"},
{resultsDirFlag, workDir1},
{reportsServerFlag, reportsServerValue},
{varsFileFlag, varsFileValue},
{systemServicesTimeoutFlag, defaultSysServicesTimeout},
{dutLabConfigFlag, dutLabConfigFile},
{buildArtifactsURLFlag, buildArtifactsURLValue},
{varFlag, fmt.Sprintf("%s=%s", varName, varValue)},
{testRetriesFlag, "1"},
},
}
args := newTastArgs(
primary, nil, nil, expectedArgs.patterns,
workDir1, reportsServerValue,
varsFileValue,
[]*api.Arg{
{Flag: buildArtifactsURLFlag, Value: buildArtifactsURLValue},
},
[]*api.Arg{
{Flag: varName, Value: varValue},
},
dutLabConfigFile,
)
if diff := cmp.Diff(args, &expectedArgs,
cmp.AllowUnexported(runArgs{}, flagValue{}),
cmpopts.IgnoreUnexported(api.Arg{}),
cmpopts.EquateEmpty()); diff != "" {
t.Errorf("Got unexpected argument from newTastArgs (-got +want):\n%s\n%v\n--\n%v\n", diff, args, expectedArgs)
}
}
// TestNewTastArgsRepeatsAndRetries makes sure newTestArgs omit retries flag when
// the repeats flag is specified by the user.
func TestNewTastArgsRepeatsAndRetries(t *testing.T) {
primary := &device.DutInfo{Addr: dut1, Role: ""}
reportsServerValue := ":127.0.0.1:3333"
varsFileValue := "/tmp/test.yaml"
dutLabConfigFile := "dutlabconfig.jsonpb"
repeatsCount := "2"
expectedArgs := runArgs{
primary: primary,
patterns: []string{test1, test2, test3, test4, test5},
tastFlags: map[string]string{
verboseFlag: "true",
logTimeFlag: "false",
},
runFlags: []flagValue{
{sshRetriesFlag, "2"},
{buildFlag, "false"},
{downloadPrivateBundlesFlag, "true"},
{resultsDirFlag, workDir1},
{reportsServerFlag, reportsServerValue},
{varsFileFlag, varsFileValue},
{systemServicesTimeoutFlag, defaultSysServicesTimeout},
{dutLabConfigFlag, dutLabConfigFile},
{testRepeatsFlag, repeatsCount},
},
}
args := newTastArgs(
primary, nil, nil, expectedArgs.patterns,
workDir1, reportsServerValue,
varsFileValue,
[]*api.Arg{
{Flag: testRepeatsFlag, Value: repeatsCount},
},
[]*api.Arg{},
dutLabConfigFile,
)
if diff := cmp.Diff(args, &expectedArgs, cmp.AllowUnexported(runArgs{}, flagValue{}), cmpopts.EquateEmpty()); diff != "" {
t.Errorf("Got unexpected argument from newTastArgs (-got +want):\n%s", diff)
}
}
// TestNewTastArgsCompanions makes sure newTastArgs creates the correct arguments for tast with companion DUTs.
func TestNewTastArgsCompanions(t *testing.T) {
primary := &device.DutInfo{Addr: dut1, Role: ""}
reportsServerValue := ":127.0.0.1:3333"
varsFileValue := "/tmp/test.yaml"
buildArtifactsURLValue := "gs://chromeos-image-archive/corsola-release/R119-15611.0.0/"
companions := []*device.DutInfo{
{
Addr: "companion_dut1_address",
Role: "cd1",
},
{
Addr: "companion_dut2_address",
Role: "cd2",
},
}
androids := []*device.AndroidInfo{
{
AssoicateAddr: "host1",
Serial: "ABC123",
ModelName: "pixel7",
},
}
expectedArgs := runArgs{
primary: primary,
patterns: []string{test1, test2, test3, test4, test5},
tastFlags: map[string]string{
verboseFlag: "true",
logTimeFlag: "false",
},
runFlags: []flagValue{
{sshRetriesFlag, "2"},
{buildFlag, "false"},
{downloadPrivateBundlesFlag, "true"},
{resultsDirFlag, workDir1},
{reportsServerFlag, reportsServerValue},
{varsFileFlag, varsFileValue},
{systemServicesTimeoutFlag, defaultSysServicesTimeout},
{buildArtifactsURLFlag, buildArtifactsURLValue},
{testRetriesFlag, "1"},
},
companions: companions,
androids: androids,
}
args := newTastArgs(
primary, companions, androids, expectedArgs.patterns, workDir1,
reportsServerValue, varsFileValue,
[]*api.Arg{
{Flag: buildArtifactsURLFlag, Value: buildArtifactsURLValue},
},
nil,
"",
)
if diff := cmp.Diff(args, &expectedArgs, cmp.AllowUnexported(runArgs{}, flagValue{})); diff != "" {
t.Errorf("Got unexpected argument from newTastArgs (-got +want):\n%s", diff)
}
}
// TestGenArgList makes sure genArgList generates the correct list of argument for tast.
func TestGenArgList(t *testing.T) {
primary := &device.DutInfo{Addr: dut1, Role: ""}
reportsServerValue := ":5555"
varsFileValue := "/tmp/test.yaml"
buildArtifactsURLValue := "gs://chromeos-image-archive/corsola-release/R119-15611.0.0/"
companions := []*device.DutInfo{
{
Addr: "companion_dut1_address",
Role: "cd1",
},
{
Addr: "companion_dut2_address",
Role: "cd2",
},
}
androids := []*device.AndroidInfo{
{
AssoicateAddr: "host1",
Serial: "ABC123",
ModelName: "pixel6",
},
{
AssoicateAddr: "host1",
Serial: "DEF456",
ModelName: "pixel7",
},
}
args := runArgs{
primary: primary,
patterns: []string{test1, test2},
tastFlags: map[string]string{
verboseFlag: "true",
logTimeFlag: "false",
},
runFlags: []flagValue{
{sshRetriesFlag, "2"},
{buildFlag, "false"},
{downloadPrivateBundlesFlag, "true"},
{resultsDirFlag, workDir1},
{reportsServerFlag, reportsServerValue},
{varsFileFlag, varsFileValue},
{systemServicesTimeoutFlag, defaultSysServicesTimeout},
{buildArtifactsURLFlag, buildArtifactsURLValue},
{testRetriesFlag, "1"},
},
companions: companions,
androids: androids,
}
var expectedArgList []string
for key, value := range args.tastFlags {
expectedArgList = append(expectedArgList, fmt.Sprintf("%v=%v", key, value))
}
runIndex := len(expectedArgList)
expectedArgList = append(expectedArgList, "run")
for _, kv := range args.runFlags {
expectedArgList = append(expectedArgList, fmt.Sprintf("%v=%v", kv.flag, kv.value))
}
for i, c := range companions {
expectedArgList = append(expectedArgList, fmt.Sprintf("%v=cd%v:%v", companionDUTFlag, i+1, c.Addr))
}
var androidsInfo []string
for _, a := range androids {
androidsInfo = append(androidsInfo,
fmt.Sprintf("%s:%s:%s", a.AssoicateAddr, a.Serial, a.ModelName))
}
if len(androidsInfo) > 0 {
expectedArgList = append(expectedArgList,
fmt.Sprintf("-var=android.companions=%s", strings.Join(androidsInfo, ",")))
}
dutIndex := len(expectedArgList)
expectedArgList = append(expectedArgList, dut1)
expectedArgList = append(expectedArgList, test1)
expectedArgList = append(expectedArgList, test2)
argList := genArgList(&args)
// Sort both lists so that we can compare them.
sort.Strings(expectedArgList[0:runIndex])
sort.Strings(argList[0:runIndex])
sort.Strings(expectedArgList[runIndex+1 : dutIndex])
sort.Strings(argList[runIndex+1 : dutIndex])
if diff := cmp.Diff(argList, expectedArgList, cmp.AllowUnexported(runArgs{})); diff != "" {
t.Errorf("Got unexpected argument from genArgList (-got %v +want %v):\n%s", argList, expectedArgList, diff)
}
}
// TestGenArgListWithServers makes sure genArgList generates the correct list of argument for tast
// when various servers are defined.
func TestGenArgListWithServers(t *testing.T) {
primary := &device.DutInfo{
Addr: dut1,
Role: "",
Servo: "servo0",
DutServer: "dutserver0",
LibsServer: "libsserver0",
ProvisionServer: "provisionserver0",
}
reportsServerValue := ":127.0.0.1:3333"
companions := []*device.DutInfo{
{
Addr: "companion_dut1_address",
Role: "cd1",
Servo: "servo1",
DutServer: "dutserver1",
ProvisionServer: "provisionserver1",
},
{
Addr: "companion_dut2_address",
Role: "cd2",
Servo: "servo2",
DutServer: "dutserver2",
ProvisionServer: "provisionserver2",
},
}
args := runArgs{
primary: primary,
patterns: []string{test1, test2},
tastFlags: map[string]string{
verboseFlag: "true",
logTimeFlag: "false",
},
runFlags: []flagValue{
{sshRetriesFlag, "2"},
{buildFlag, "false"},
{downloadPrivateBundlesFlag, "true"},
{resultsDirFlag, workDir1},
{reportsServerFlag, reportsServerValue},
{systemServicesTimeoutFlag, defaultSysServicesTimeout},
{testRetriesFlag, "1"},
},
companions: companions,
}
var expectedArgList []string
for key, value := range args.tastFlags {
expectedArgList = append(expectedArgList, fmt.Sprintf("%v=%v", key, value))
}
runIndex := len(expectedArgList)
expectedArgList = append(expectedArgList, "run")
for _, kv := range args.runFlags {
expectedArgList = append(expectedArgList, fmt.Sprintf("%v=%v", kv.flag, kv.value))
}
for i, c := range companions {
expectedArgList = append(expectedArgList, fmt.Sprintf("%v=cd%v:%v", companionDUTFlag, i+1, c.Addr))
}
// Creates servo list.
servoStr := fmt.Sprintf(":%s", primary.Servo)
for _, c := range companions {
servoStr = fmt.Sprintf("%s,%s:%s", servoStr, c.Role, c.Servo)
}
expectedArgList = append(expectedArgList, fmt.Sprintf("-var=servers.servo=%v", servoStr))
expectedArgList = append(expectedArgList, fmt.Sprintf("-var=servo=%v", primary.Servo))
// Creates DUT server list.
dutServerStr := fmt.Sprintf(":%s", primary.DutServer)
for _, c := range companions {
dutServerStr = fmt.Sprintf("%s,%s:%s", dutServerStr, c.Role, c.DutServer)
}
expectedArgList = append(expectedArgList, fmt.Sprintf("-var=servers.dut=%v", dutServerStr))
// Creates Libsserver.
libsServerStr := fmt.Sprintf(":%s", primary.LibsServer)
expectedArgList = append(expectedArgList, fmt.Sprintf("-var=servers.libs=%v", libsServerStr))
// Creates DUT server list.
ProvisionServerStr := fmt.Sprintf(":%s", primary.ProvisionServer)
for _, c := range companions {
ProvisionServerStr = fmt.Sprintf("%s,%s:%s", ProvisionServerStr, c.Role, c.ProvisionServer)
}
expectedArgList = append(expectedArgList, fmt.Sprintf("-var=servers.provision=%v", ProvisionServerStr))
dutIndex := len(expectedArgList)
expectedArgList = append(expectedArgList, dut1)
expectedArgList = append(expectedArgList, test1)
expectedArgList = append(expectedArgList, test2)
argList := genArgList(&args)
// Sort both lists so that we can compare them.
sort.Strings(expectedArgList[0:runIndex])
sort.Strings(argList[0:runIndex])
sort.Strings(expectedArgList[runIndex+1 : dutIndex])
sort.Strings(argList[runIndex+1 : dutIndex])
if diff := cmp.Diff(argList, expectedArgList, cmp.AllowUnexported(runArgs{})); diff != "" {
t.Errorf("Got unexpected argument from genArgList (-got %v +want %v):\n%s", argList, expectedArgList, diff)
}
}
// TestGenArgListWithDevboard makes sure genArgList generates the correct list of argument for tast
// when various servers are defined.
func TestGenArgListWithDevboard(t *testing.T) {
primary := &device.DutInfo{
Addr: "",
Role: "",
DevboardServer: "devboardserver0",
}
reportsServerValue := ":127.0.0.1:3333"
companions := []*device.DutInfo{
{
Addr: "",
Role: "cd1",
DevboardServer: "devboardserver1",
},
}
args := runArgs{
primary: primary,
patterns: []string{test1, test2},
tastFlags: map[string]string{
verboseFlag: "true",
logTimeFlag: "false",
},
runFlags: []flagValue{
{sshRetriesFlag, "2"},
{buildFlag, "false"},
{downloadPrivateBundlesFlag, "true"},
{resultsDirFlag, workDir1},
{reportsServerFlag, reportsServerValue},
{systemServicesTimeoutFlag, defaultSysServicesTimeout},
{testRetriesFlag, "1"},
},
companions: companions,
}
var expectedArgList []string
for key, value := range args.tastFlags {
expectedArgList = append(expectedArgList, fmt.Sprintf("%v=%v", key, value))
}
runIndex := len(expectedArgList)
expectedArgList = append(expectedArgList, "run")
for _, kv := range args.runFlags {
expectedArgList = append(expectedArgList, fmt.Sprintf("%v=%v", kv.flag, kv.value))
}
// Creates devboard list.
devboardStr := fmt.Sprintf(":%s", primary.DevboardServer)
for _, c := range companions {
devboardStr = fmt.Sprintf("%s,%s:%s", devboardStr, c.Role, c.DevboardServer)
}
expectedArgList = append(expectedArgList, fmt.Sprintf("-var=servers.devboard=%v", devboardStr))
dutIndex := len(expectedArgList)
expectedArgList = append(expectedArgList, "-")
expectedArgList = append(expectedArgList, test1)
expectedArgList = append(expectedArgList, test2)
argList := genArgList(&args)
// Sort both lists so that we can compare them.
sort.Strings(expectedArgList[0:runIndex])
sort.Strings(argList[0:runIndex])
sort.Strings(expectedArgList[runIndex+1 : dutIndex])
sort.Strings(argList[runIndex+1 : dutIndex])
if diff := cmp.Diff(argList, expectedArgList, cmp.AllowUnexported(runArgs{})); diff != "" {
t.Errorf("Got unexpected argument from genArgList (-got %v +want %v):\n%s", argList, expectedArgList, diff)
}
}
// TestgenHostInfoYAML tests memes.
func TestGenHostInfoYAML(t *testing.T) {
primary := &device.DutInfo{
Addr: "foo",
Phase: "aphase",
Sku: "asku",
Model: "amodel",
Board: "aboard",
}
expected := make(map[string]string)
expected["phase"] = primary.Phase
expected["sku"] = primary.Sku
expected["model"] = primary.Model
expected["board"] = primary.Board
fn, err := genHostInfoYAML(primary)
if err != nil {
t.Errorf("Got unexpected err: %v", err)
}
fmt.Println(fn)
defer os.Remove(fn)
yfile, err := os.ReadFile(fn)
if err != nil {
t.Error(err)
}
var data Labels
err = yaml.Unmarshal(yfile, &data)
if err != nil {
log.Fatal(err)
}
for k, v := range expected {
testStr := fmt.Sprintf("\"%v:%v\"", k, v)
if !strings.Contains(data.AutotestHostInfoLabels, testStr) {
t.Errorf("Missing |%v| in: %v", testStr, data.AutotestHostInfoLabels)
}
}
}