| // Copyright 2019 The Chromium 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 enumeration_test |
| |
| import ( |
| "sort" |
| "testing" |
| |
| "infra/cmd/cros_test_platform/internal/enumeration" |
| |
| "github.com/kylelemons/godebug/pretty" |
| "go.chromium.org/chromiumos/infra/proto/go/chromite/api" |
| "go.chromium.org/chromiumos/infra/proto/go/test_platform" |
| "go.chromium.org/chromiumos/infra/proto/go/test_platform/steps" |
| "go.chromium.org/luci/common/data/stringset" |
| ) |
| |
| func TestGetForTests(t *testing.T) { |
| var cases = []struct { |
| requestName string |
| want stringset.Set |
| }{ |
| {"selected", stringset.NewFromSlice("selected")}, |
| {"non_existent", stringset.New(0)}, |
| } |
| |
| m := &api.AutotestTestMetadata{} |
| addTestMetadata(m, "ignored", "selected") |
| for _, c := range cases { |
| t.Run(c.requestName, func(t *testing.T) { |
| tests, err := enumeration.GetForTests(m, []*test_platform.Request_Test{ |
| {Harness: &test_platform.Request_Test_Autotest_{Autotest: &test_platform.Request_Test_Autotest{Name: c.requestName}}}}, |
| ) |
| if err != nil { |
| t.Errorf("unexpected error %s", err.Error()) |
| } |
| got := extractTestNames(tests) |
| if diff := pretty.Compare(c.want, got); diff != "" { |
| t.Errorf("enumerated tests differ, -want +got: %s", diff) |
| } |
| }) |
| } |
| } |
| |
| func TestGetForTestsWithArgs(t *testing.T) { |
| var cases = []struct { |
| testArgs string |
| expectArgs string |
| }{ |
| {"foo-test-args", "foo-test-args"}, |
| {"", ""}, |
| } |
| m := &api.AutotestTestMetadata{} |
| addTestMetadata(m, "foo-test") |
| for _, c := range cases { |
| t.Run(c.testArgs, func(t *testing.T) { |
| tests, err := enumeration.GetForTests(m, []*test_platform.Request_Test{ |
| {Harness: &test_platform.Request_Test_Autotest_{Autotest: &test_platform.Request_Test_Autotest{Name: "foo-test", TestArgs: c.testArgs}}}}) |
| if err != nil { |
| t.Errorf("unexpected error %s", err.Error()) |
| } |
| if len(tests) != 1 { |
| t.Fatalf("expected 1 result, got %d", len(tests)) |
| } |
| if tests[0].TestArgs != c.expectArgs { |
| t.Errorf("expected test args %s, got %s", c.expectArgs, tests[0].TestArgs) |
| } |
| }) |
| } |
| |
| } |
| |
| func TestGetForTestsWithDisplayName(t *testing.T) { |
| wantName := "some_other_name" |
| m := &api.AutotestTestMetadata{} |
| addTestMetadata(m, "a_test") |
| tests, err := enumeration.GetForTests(m, []*test_platform.Request_Test{ |
| { |
| Harness: &test_platform.Request_Test_Autotest_{ |
| Autotest: &test_platform.Request_Test_Autotest{ |
| Name: "a_test", |
| DisplayName: wantName, |
| }, |
| }, |
| }, |
| }) |
| if err != nil { |
| t.Errorf("unexpected error %s", err.Error()) |
| } |
| if len(tests) != 1 { |
| t.Fatalf("expected 1 result, got %d", len(tests)) |
| } |
| if tests[0].DisplayName != wantName { |
| t.Errorf("display name differs, want %s, got %s", wantName, tests[0].DisplayName) |
| } |
| } |
| |
| // addTestMetadata adds tests to m with given names. |
| func addTestMetadata(m *api.AutotestTestMetadata, tNames ...string) { |
| for _, t := range tNames { |
| m.Tests = append(m.Tests, &api.AutotestTest{Name: t}) |
| } |
| } |
| |
| func extractTestNames(ts []*steps.EnumerationResponse_AutotestInvocation) stringset.Set { |
| ns := make([]string, 0, len(ts)) |
| for _, t := range ts { |
| ns = append(ns, t.Test.GetName()) |
| } |
| return stringset.NewFromSlice(ns...) |
| } |
| |
| func TestGetForSuites(t *testing.T) { |
| var cases = []struct { |
| tag string |
| metadata *api.AutotestTestMetadata |
| request []*test_platform.Request_Suite |
| want stringset.Set |
| }{ |
| { |
| tag: "select single suite", |
| metadata: autotestMetadata( |
| []string{"included", "ignored"}, |
| map[string][]string{ |
| "selected": {"included"}, |
| "unselected": {"ignored"}, |
| }, |
| ), |
| request: suiteRequest("selected"), |
| want: stringset.NewFromSlice("included"), |
| }, |
| { |
| tag: "select both suite", |
| metadata: autotestMetadata( |
| []string{"included", "another_included"}, |
| map[string][]string{ |
| "selected": {"included"}, |
| "another_selected": {"another_included"}, |
| }, |
| ), |
| request: suiteRequest("selected", "another_selected"), |
| want: stringset.NewFromSlice("included", "another_included"), |
| }, |
| { |
| tag: "select suite with missing test", |
| metadata: autotestMetadata( |
| []string{}, |
| map[string][]string{ |
| "selected": {"missing"}, |
| }, |
| ), |
| request: suiteRequest("selected"), |
| want: stringset.New(0), |
| }, |
| } |
| |
| for _, c := range cases { |
| t.Run(c.tag, func(t *testing.T) { |
| tests := enumeration.GetForSuites(c.metadata, c.request) |
| got := extractTestNames(tests) |
| if diff := pretty.Compare(c.want, got); diff != "" { |
| t.Errorf("enumerated tests differ, -want +got: %s", diff) |
| } |
| }) |
| } |
| } |
| |
| func TestGetForSuitesSetsSuiteKeyval(t *testing.T) { |
| tests := enumeration.GetForSuites( |
| autotestMetadata( |
| []string{"included"}, |
| map[string][]string{ |
| "selected": {"included"}, |
| }, |
| ), |
| suiteRequest("selected"), |
| ) |
| if len(tests) != 1 { |
| t.Errorf("Want 1 test, got %d: %s", len(tests), tests) |
| } |
| want := map[string]string{"suite": "selected"} |
| got := tests[0].GetResultKeyvals() |
| if diff := pretty.Compare(want, got); diff != "" { |
| t.Errorf("Result keyvals differ, -want +got: %s", diff) |
| } |
| |
| } |
| |
| func TestGetForSuitesSetsSuiteKeyvalsForTestSelectedTwice(t *testing.T) { |
| tests := enumeration.GetForSuites( |
| autotestMetadata( |
| []string{"included"}, |
| map[string][]string{ |
| "selected": {"included"}, |
| "another_selected": {"included"}, |
| }, |
| ), |
| suiteRequest("selected", "another_selected"), |
| ) |
| if len(tests) != 2 { |
| t.Errorf("Want 2 test, got %d: %s", len(tests), tests) |
| } |
| got := stringset.New(len(tests)) |
| for _, t := range tests { |
| got.Add(t.GetResultKeyvals()["suite"]) |
| } |
| want := stringset.NewFromSlice("selected", "another_selected") |
| if diff := pretty.Compare(want, got); diff != "" { |
| t.Errorf("Result keyvals differ, -want +got: %s", diff) |
| } |
| } |
| |
| func suiteRequest(ns ...string) []*test_platform.Request_Suite { |
| req := make([]*test_platform.Request_Suite, 0, len(ns)) |
| for _, n := range ns { |
| req = append(req, &test_platform.Request_Suite{Name: n}) |
| } |
| return req |
| } |
| |
| // autotestMetadata creates a new AutotestTestMetadata containing tests with |
| // specified names and suites with specified names and contained tests. |
| func autotestMetadata(tests []string, suites map[string][]string) *api.AutotestTestMetadata { |
| m := &api.AutotestTestMetadata{} |
| addTestMetadata(m, tests...) |
| for s, ts := range suites { |
| addSuiteMetadata(m, s, ts...) |
| } |
| return m |
| } |
| |
| // addSuiteMetadata adds a suite to m named sName and including tests named tNames. |
| func addSuiteMetadata(m *api.AutotestTestMetadata, sName string, tNames ...string) { |
| suite := &api.AutotestSuite{Name: sName} |
| for _, tName := range tNames { |
| suite.Tests = append(suite.Tests, &api.AutotestSuite_TestReference{Name: tName}) |
| } |
| m.Suites = append(m.Suites, suite) |
| } |
| |
| func TestGetForSuitesSetsSuiteDependency(t *testing.T) { |
| cases := []struct { |
| Tag string |
| SuiteChildDependencies []string |
| TestDependencies []string |
| WantDependencies []string |
| }{ |
| { |
| Tag: "suite dependency", |
| SuiteChildDependencies: []string{"suitedep"}, |
| TestDependencies: []string{}, |
| WantDependencies: []string{"suitedep"}, |
| }, |
| { |
| Tag: "suite and test dependencies", |
| SuiteChildDependencies: []string{"suitedep"}, |
| TestDependencies: []string{"testdep"}, |
| WantDependencies: []string{"suitedep", "testdep"}, |
| }, |
| { |
| Tag: "same dependency in suite and test", |
| SuiteChildDependencies: []string{"commondep"}, |
| TestDependencies: []string{"commondep"}, |
| WantDependencies: []string{"commondep"}, |
| }, |
| } |
| |
| for _, c := range cases { |
| t.Run(c.Tag, func(t *testing.T) { |
| mytest := &api.AutotestTest{Name: "mytest"} |
| for _, d := range c.TestDependencies { |
| mytest.Dependencies = append(mytest.Dependencies, &api.AutotestTaskDependency{Label: d}) |
| } |
| mysuite := &api.AutotestSuite{ |
| Name: "mysuite", |
| Tests: []*api.AutotestSuite_TestReference{ |
| {Name: "mytest"}, |
| }, |
| } |
| for _, d := range c.SuiteChildDependencies { |
| mysuite.ChildDependencies = append(mysuite.ChildDependencies, &api.AutotestTaskDependency{Label: d}) |
| } |
| m := &api.AutotestTestMetadata{ |
| Tests: []*api.AutotestTest{mytest}, |
| Suites: []*api.AutotestSuite{mysuite}, |
| } |
| |
| tests := enumeration.GetForSuites(m, suiteRequest("mysuite")) |
| if diff := pretty.Compare(stringset.NewFromSlice("mytest"), extractTestNames(tests)); diff != "" { |
| t.Fatalf("enumerated tests differ, -want +got: %s", diff) |
| } |
| |
| gotDeps := []string{} |
| for _, d := range tests[0].GetTest().GetDependencies() { |
| gotDeps = append(gotDeps, d.Label) |
| } |
| sort.Strings(c.WantDependencies) |
| sort.Strings(gotDeps) |
| if diff := pretty.Compare(c.WantDependencies, gotDeps); diff != "" { |
| t.Errorf("test dependencies differ, -want +got: %s", diff) |
| } |
| }) |
| } |
| } |
| |
| func TestGetForEnumeration(t *testing.T) { |
| var cases = []struct { |
| Tag string |
| Request *test_platform.Request_Enumeration |
| Want stringset.Set |
| }{ |
| { |
| Tag: "nil input", |
| Request: nil, |
| Want: stringset.New(0), |
| }, |
| { |
| Tag: "some input", |
| Request: enumerationRequest("some_test"), |
| Want: stringset.NewFromSlice("some_test"), |
| }, |
| } |
| |
| for _, c := range cases { |
| t.Run(c.Tag, func(t *testing.T) { |
| tests := enumeration.GetForEnumeration(c.Request) |
| got := extractTestNames(tests) |
| if diff := pretty.Compare(c.Want, got); diff != "" { |
| t.Errorf("enumerated tests differ, -want +got: %s", diff) |
| } |
| }) |
| } |
| } |
| |
| func enumerationRequest(ns ...string) *test_platform.Request_Enumeration { |
| inv := make([]*test_platform.Request_Enumeration_AutotestInvocation, 0, len(ns)) |
| for _, n := range ns { |
| inv = append(inv, &test_platform.Request_Enumeration_AutotestInvocation{ |
| Test: &api.AutotestTest{Name: n}, |
| }) |
| } |
| return &test_platform.Request_Enumeration{ |
| AutotestInvocations: inv, |
| } |
| } |