blob: 981694278a3612a4b8d608796b1aab3d0a42b285 [file] [log] [blame]
// Copyright 2021 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
package coveragerules_test
import (
"chromiumos/test/plan/internal/coveragerules"
"strings"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/google/go-cmp/cmp/cmpopts"
buildpb "go.chromium.org/chromiumos/config/go/build/api"
testpb "go.chromium.org/chromiumos/config/go/test/api"
"go.chromium.org/chromiumos/config/go/test/plan"
)
// buildSummary is a convenience to reduce boilerplate when creating
// SystemImage_BuildSummary in test cases.
func buildSummary(overlay, kernelVersion, chipsetOverlay, arcVersion string) *buildpb.SystemImage_BuildSummary {
return &buildpb.SystemImage_BuildSummary{
BuildTarget: &buildpb.SystemImage_BuildTarget{
PortageBuildTarget: &buildpb.Portage_BuildTarget{
OverlayName: overlay,
},
},
Kernel: &buildpb.SystemImage_BuildSummary_Kernel{
Version: kernelVersion,
},
Chipset: &buildpb.SystemImage_BuildSummary_Chipset{
Overlay: chipsetOverlay,
},
Arc: &buildpb.SystemImage_BuildSummary_Arc{
Version: arcVersion,
},
}
}
var buildSummaryList = &buildpb.SystemImage_BuildSummaryList{
Values: []*buildpb.SystemImage_BuildSummary{
buildSummary("project1", "4.14", "chipsetA", ""),
buildSummary("project2", "4.14", "chipsetB", ""),
buildSummary("project3", "5.4", "chipsetA", ""),
buildSummary("project4", "3.18", "chipsetC", "R"),
buildSummary("project5", "4.14", "chipsetA", ""),
buildSummary("project6", "4.14", "chipsetB", "P"),
},
}
var dutAttributeList = &testpb.DutAttributeList{
DutAttributes: []*testpb.DutAttribute{
{
Id: &testpb.DutAttribute_Id{Value: "fingerprint_location"},
FieldPath: "design_list.configs.hardware_features.fingerprint.location",
},
{
Id: &testpb.DutAttribute_Id{Value: "system_build_target"},
FieldPath: "software_configs.system_build_target.portage_build_target.overlay_name",
},
},
}
func TestGenerate(t *testing.T) {
tests := []struct {
name string
input *plan.SourceTestPlan
expected []*testpb.CoverageRule
}{
{
name: "kernel versions",
input: &plan.SourceTestPlan{
Requirements: &plan.SourceTestPlan_Requirements{
KernelVersions: &plan.SourceTestPlan_Requirements_KernelVersions{},
},
TestTags: []string{"kernel"},
TestTagExcludes: []string{"flaky"},
},
expected: []*testpb.CoverageRule{
{
Name: "kernel:3.18",
DutCriteria: []*testpb.DutCriterion{
{
AttributeId: &testpb.DutAttribute_Id{
Value: "system_build_target",
},
Values: []string{"project4"},
},
},
TestSuites: []*testpb.TestSuite{
{
TestCaseTagCriteria: &testpb.TestSuite_TestCaseTagCriteria{
Tags: []string{"kernel"},
TagExcludes: []string{"flaky"},
},
},
},
},
{
Name: "kernel:4.14",
DutCriteria: []*testpb.DutCriterion{
{
AttributeId: &testpb.DutAttribute_Id{
Value: "system_build_target",
},
Values: []string{"project1", "project2", "project5", "project6"},
},
},
TestSuites: []*testpb.TestSuite{
{
TestCaseTagCriteria: &testpb.TestSuite_TestCaseTagCriteria{
Tags: []string{"kernel"},
TagExcludes: []string{"flaky"},
},
},
},
},
{
Name: "kernel:5.4",
DutCriteria: []*testpb.DutCriterion{
{
AttributeId: &testpb.DutAttribute_Id{
Value: "system_build_target",
},
Values: []string{"project3"},
},
},
TestSuites: []*testpb.TestSuite{
{
TestCaseTagCriteria: &testpb.TestSuite_TestCaseTagCriteria{
Tags: []string{"kernel"},
TagExcludes: []string{"flaky"},
},
},
},
},
},
},
{
name: "soc families",
input: &plan.SourceTestPlan{
Requirements: &plan.SourceTestPlan_Requirements{
SocFamilies: &plan.SourceTestPlan_Requirements_SocFamilies{},
},
TestTagExcludes: []string{"flaky"},
},
expected: []*testpb.CoverageRule{
{
Name: "soc:chipsetA",
DutCriteria: []*testpb.DutCriterion{
{
AttributeId: &testpb.DutAttribute_Id{
Value: "system_build_target",
},
Values: []string{"project1", "project3", "project5"},
},
},
TestSuites: []*testpb.TestSuite{
{
TestCaseTagCriteria: &testpb.TestSuite_TestCaseTagCriteria{
TagExcludes: []string{"flaky"},
},
},
},
},
{
Name: "soc:chipsetB",
DutCriteria: []*testpb.DutCriterion{
{
AttributeId: &testpb.DutAttribute_Id{
Value: "system_build_target",
},
Values: []string{"project2", "project6"},
},
},
TestSuites: []*testpb.TestSuite{
{
TestCaseTagCriteria: &testpb.TestSuite_TestCaseTagCriteria{
TagExcludes: []string{"flaky"},
},
},
},
},
{
Name: "soc:chipsetC",
DutCriteria: []*testpb.DutCriterion{
{
AttributeId: &testpb.DutAttribute_Id{
Value: "system_build_target",
},
Values: []string{"project4"},
},
},
TestSuites: []*testpb.TestSuite{
{
TestCaseTagCriteria: &testpb.TestSuite_TestCaseTagCriteria{
TagExcludes: []string{"flaky"},
},
},
},
},
},
},
{
name: "build targets and designs",
input: &plan.SourceTestPlan{
Requirements: &plan.SourceTestPlan_Requirements{
KernelVersions: &plan.SourceTestPlan_Requirements_KernelVersions{},
Fingerprint: &plan.SourceTestPlan_Requirements_Fingerprint{},
},
TestTags: []string{"kernel", "fingerprint"},
},
expected: []*testpb.CoverageRule{
{
Name: "fp:present",
DutCriteria: []*testpb.DutCriterion{
{
AttributeId: &testpb.DutAttribute_Id{
Value: "fingerprint_location",
},
Values: []string{
"POWER_BUTTON_TOP_LEFT",
"KEYBOARD_BOTTOM_LEFT",
"KEYBOARD_BOTTOM_RIGHT",
"KEYBOARD_TOP_RIGHT",
"RIGHT_SIDE",
"LEFT_SIDE",
"PRESENT",
},
},
},
TestSuites: []*testpb.TestSuite{
{
TestCaseTagCriteria: &testpb.TestSuite_TestCaseTagCriteria{
Tags: []string{"kernel", "fingerprint"},
},
},
},
},
{
Name: "kernel:3.18",
DutCriteria: []*testpb.DutCriterion{
{
AttributeId: &testpb.DutAttribute_Id{
Value: "system_build_target",
},
Values: []string{"project4"},
},
},
TestSuites: []*testpb.TestSuite{
{
TestCaseTagCriteria: &testpb.TestSuite_TestCaseTagCriteria{
Tags: []string{"kernel", "fingerprint"},
},
},
},
},
{
Name: "kernel:4.14",
DutCriteria: []*testpb.DutCriterion{
{
AttributeId: &testpb.DutAttribute_Id{
Value: "system_build_target",
},
Values: []string{"project1", "project2", "project5", "project6"},
},
},
TestSuites: []*testpb.TestSuite{
{
TestCaseTagCriteria: &testpb.TestSuite_TestCaseTagCriteria{
Tags: []string{"kernel", "fingerprint"},
},
},
},
},
{
Name: "kernel:5.4",
DutCriteria: []*testpb.DutCriterion{
{
AttributeId: &testpb.DutAttribute_Id{
Value: "system_build_target",
},
Values: []string{"project3"},
},
},
TestSuites: []*testpb.TestSuite{
{
TestCaseTagCriteria: &testpb.TestSuite_TestCaseTagCriteria{
Tags: []string{"kernel", "fingerprint"},
},
},
},
},
},
},
{
name: "multiple requirements",
input: &plan.SourceTestPlan{
Requirements: &plan.SourceTestPlan_Requirements{
KernelVersions: &plan.SourceTestPlan_Requirements_KernelVersions{},
SocFamilies: &plan.SourceTestPlan_Requirements_SocFamilies{},
ArcVersions: &plan.SourceTestPlan_Requirements_ArcVersions{},
},
TestTags: []string{"kernel", "arc"},
},
expected: []*testpb.CoverageRule{
{
Name: "kernel:4.14_soc:chipsetA",
DutCriteria: []*testpb.DutCriterion{
{
AttributeId: &testpb.DutAttribute_Id{
Value: "system_build_target",
},
Values: []string{"project1", "project5"},
},
},
TestSuites: []*testpb.TestSuite{
{
TestCaseTagCriteria: &testpb.TestSuite_TestCaseTagCriteria{
Tags: []string{"kernel", "arc"},
},
},
},
},
{
Name: "kernel:4.14_soc:chipsetB_arc:P",
DutCriteria: []*testpb.DutCriterion{
{
AttributeId: &testpb.DutAttribute_Id{
Value: "system_build_target",
},
Values: []string{"project6"},
},
},
TestSuites: []*testpb.TestSuite{
{
TestCaseTagCriteria: &testpb.TestSuite_TestCaseTagCriteria{
Tags: []string{"kernel", "arc"},
},
},
},
},
{
Name: "kernel:5.4_soc:chipsetA",
DutCriteria: []*testpb.DutCriterion{
{
AttributeId: &testpb.DutAttribute_Id{
Value: "system_build_target",
},
Values: []string{"project3"},
},
},
TestSuites: []*testpb.TestSuite{
{
TestCaseTagCriteria: &testpb.TestSuite_TestCaseTagCriteria{
Tags: []string{"kernel", "arc"},
},
},
},
},
{
Name: "kernel:3.18_soc:chipsetC_arc:R",
DutCriteria: []*testpb.DutCriterion{
{
AttributeId: &testpb.DutAttribute_Id{
Value: "system_build_target",
},
Values: []string{"project4"},
},
},
TestSuites: []*testpb.TestSuite{
{
TestCaseTagCriteria: &testpb.TestSuite_TestCaseTagCriteria{
Tags: []string{"kernel", "arc"},
},
},
},
},
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
outputs, err := coveragerules.Generate(test.input, buildSummaryList, dutAttributeList)
if err != nil {
t.Fatalf("coveragerules.Generate failed: %s", err)
}
if diff := cmp.Diff(
test.expected,
outputs,
cmpopts.SortSlices(func(i, j *testpb.CoverageRule) bool {
return i.Name < j.Name
}),
cmpopts.SortSlices(func(i, j string) bool {
return i < j
}),
); diff != "" {
t.Errorf("coveragerules.Generate returned unexpected diff (-want +got):\n%s", diff)
}
})
}
}
func TestGenerateErrors(t *testing.T) {
tests := []struct {
name string
input *plan.SourceTestPlan
dutAttributeList *testpb.DutAttributeList
expectedError string
}{
{
name: "no requirements",
input: &plan.SourceTestPlan{
EnabledTestEnvironments: []plan.SourceTestPlan_TestEnvironment{
plan.SourceTestPlan_HARDWARE,
},
},
dutAttributeList: dutAttributeList,
expectedError: "at least one requirement must be set in SourceTestPlan",
},
{
name: "empty requirements",
input: &plan.SourceTestPlan{
EnabledTestEnvironments: []plan.SourceTestPlan_TestEnvironment{
plan.SourceTestPlan_HARDWARE,
},
Requirements: &plan.SourceTestPlan_Requirements{},
},
dutAttributeList: dutAttributeList,
expectedError: "at least one requirement must be set in SourceTestPlan",
},
{
name: "unimplemented requirement",
input: &plan.SourceTestPlan{
Requirements: &plan.SourceTestPlan_Requirements{
ChromeosConfig: &plan.SourceTestPlan_Requirements_ChromeOSConfig{},
},
},
dutAttributeList: dutAttributeList,
expectedError: `unimplemented requirement "SourceTestPlan_Requirements_ChromeOSConfig"`,
},
{
name: "invalid dut attributes",
input: &plan.SourceTestPlan{
EnabledTestEnvironments: []plan.SourceTestPlan_TestEnvironment{
plan.SourceTestPlan_HARDWARE,
},
Requirements: &plan.SourceTestPlan_Requirements{
KernelVersions: &plan.SourceTestPlan_Requirements_KernelVersions{},
},
},
dutAttributeList: &testpb.DutAttributeList{
DutAttributes: []*testpb.DutAttribute{
{
Id: &testpb.DutAttribute_Id{
Value: "miscdutattr",
},
FieldPath: "a.b.c",
},
},
},
expectedError: "CoverageRule contains invalid DutAttributes",
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if _, err := coveragerules.Generate(
test.input, buildSummaryList, test.dutAttributeList,
); err == nil {
t.Errorf("Expected error from coveragerules.Generate")
} else if !strings.Contains(err.Error(), test.expectedError) {
t.Errorf("Got error %q, wanted error to contain %q", err.Error(), test.expectedError)
}
})
}
}