diff --git a/.project/golangci-lint.yml b/.project/golangci-lint.yml index 9a54c8e1..80119103 100644 --- a/.project/golangci-lint.yml +++ b/.project/golangci-lint.yml @@ -2,8 +2,6 @@ linters-settings: goconst: min-len: 2 min-occurrences: 4 - lll: - line-length: 120 issues: exclude-use-default: false @@ -34,7 +32,6 @@ linters: - gosimple - govet - ineffassign - - lll - misspell - nakedret - prealloc diff --git a/testjson/execution.go b/testjson/execution.go index 25d4be08..186cfe8e 100644 --- a/testjson/execution.go +++ b/testjson/execution.go @@ -262,12 +262,12 @@ func (p *Package) IsEmpty() bool { const neverFinished time.Duration = -1 -// end adds any tests that were missing an ActionFail TestEvent to the list of +// strays adds any tests that were missing an ActionFail TestEvent to the list of // Failed, and returns a slice of artificial TestEvent for the missing ones. // // This is done to work around 'go test' not sending the ActionFail TestEvents // in some cases, when a test panics. -func (p *Package) end() []TestEvent { +func (p *Package) strays() []TestEvent { result := make([]TestEvent, 0, len(p.running)) for k, tc := range p.running { if tc.Test.IsSubTest() && rootTestPassed(p, tc) { @@ -307,6 +307,10 @@ func rootTestPassed(p *Package, subtest TestCase) bool { continue } + // A TestCase name can exist more than once in an Execution due to + // the go test -count=n flag or when the input contains multiple separate + // test runs. + // Check the testcase has the correct ID for this subtest. for _, subID := range p.subTests[tc.ID] { if subID == subtest.ID { return true @@ -447,7 +451,11 @@ func (p *Package) addTestEvent(event TestEvent) { // If this is a subtest, mark the root test as having a failed subtest if tc.Test.IsSubTest() { root, _ := TestName(event.Test).Split() - rootTestCase := p.running[root] + rootTestCase, ok := p.running[root] + if !ok { + rootTestCase = p.newTestCaseFromEvent(event) + rootTestCase.Test = TestName(root) + } rootTestCase.hasSubTestFailed = true p.running[root] = rootTestCase } @@ -639,11 +647,10 @@ func (e *Execution) HasPanic() bool { return false } -func (e *Execution) end() []TestEvent { - e.done = true +func (e *Execution) Strays() []TestEvent { var result []TestEvent // nolint: prealloc for _, pkg := range e.packages { - result = append(result, pkg.end()...) + result = append(result, pkg.strays()...) } return result } @@ -726,11 +733,12 @@ func ScanTestOutput(config ScanConfig) (*Execution, error) { }) err := group.Wait() - for _, event := range execution.end() { + for _, event := range execution.Strays() { if err := config.Handler.Event(event, execution); err != nil { return execution, err } } + execution.done = true return execution, err } diff --git a/testjson/execution_test.go b/testjson/execution_test.go index 81f809dc..435af720 100644 --- a/testjson/execution_test.go +++ b/testjson/execution_test.go @@ -251,6 +251,38 @@ func (s *captureHandler) Err(text string) error { return nil } +func TestScanTestOuput_SubtestWithNoRunningRoot(t *testing.T) { + source := []byte(`{"Action":"start","Package":"k8s.io/kubernetes/test/integration/scheduler_perf"} +{"Action":"skip","Package":"k8s.io/kubernetes/test/integration/scheduler_perf","Test":"BenchmarkPerfScheduling/SchedulingBasic/500Nodes"} +{"Action":"skip","Package":"k8s.io/kubernetes/test/integration/scheduler_perf","Test":"BenchmarkPerfScheduling/SchedulingPodAntiAffinity/500Nodes"} +{"Action":"skip","Package":"k8s.io/kubernetes/test/integration/scheduler_perf","Test":"BenchmarkPerfScheduling/SchedulingSecrets/500Nodes"} +{"Action":"skip","Package":"k8s.io/kubernetes/test/integration/scheduler_perf","Test":"BenchmarkPerfScheduling/SchedulingPodAffinity/500Nodes"} +{"Action":"skip","Package":"k8s.io/kubernetes/test/integration/scheduler_perf","Test":"BenchmarkPerfScheduling/SchedulingPreferredPodAntiAffinity/500Nodes"} +{"Action":"fail","Package":"k8s.io/kubernetes/test/integration/scheduler_perf","Test":"BenchmarkPerfScheduling/SchedulingDaemonset/15000Nodes"} +{"Action":"fail","Package":"k8s.io/kubernetes/test/integration/scheduler_perf","Test":"BenchmarkPerfScheduling/SchedulingDaemonset"} +{"Action":"skip","Package":"k8s.io/kubernetes/test/integration/scheduler_perf","Test":"BenchmarkPerfScheduling/SchedulingNodeAffinity/500Nodes"} +{"Action":"fail","Package":"k8s.io/kubernetes/test/integration/scheduler_perf","Elapsed":660.472}`) + + handler := &captureHandler{} + cfg := ScanConfig{ + Stdout: bytes.NewReader(source), + Handler: handler, + } + exec, err := ScanTestOutput(cfg) + assert.NilError(t, err) + actual := FilterFailedUnique(exec.Failed()) + + expected := []TestCase{ + { + ID: 6, + Package: "k8s.io/kubernetes/test/integration/scheduler_perf", + Test: "BenchmarkPerfScheduling/SchedulingDaemonset/15000Nodes", + }, + } + cmpTestCase := cmp.AllowUnexported(TestCase{}) + assert.DeepEqual(t, expected, actual, cmpTestCase) +} + func TestFilterFailedUnique_MultipleNested(t *testing.T) { source := []byte(`{"Package": "pkg", "Action": "run"} {"Package": "pkg", "Test": "TestParent", "Action": "run"}