xref: /aosp_15_r20/build/soong/ui/status/ninja_test.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker// Copyright 2019 Google Inc. All rights reserved.
2*333d2b36SAndroid Build Coastguard Worker//
3*333d2b36SAndroid Build Coastguard Worker// Licensed under the Apache License, Version 2.0 (the "License");
4*333d2b36SAndroid Build Coastguard Worker// you may not use this file except in compliance with the License.
5*333d2b36SAndroid Build Coastguard Worker// You may obtain a copy of the License at
6*333d2b36SAndroid Build Coastguard Worker//
7*333d2b36SAndroid Build Coastguard Worker//     http://www.apache.org/licenses/LICENSE-2.0
8*333d2b36SAndroid Build Coastguard Worker//
9*333d2b36SAndroid Build Coastguard Worker// Unless required by applicable law or agreed to in writing, software
10*333d2b36SAndroid Build Coastguard Worker// distributed under the License is distributed on an "AS IS" BASIS,
11*333d2b36SAndroid Build Coastguard Worker// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*333d2b36SAndroid Build Coastguard Worker// See the License for the specific language governing permissions and
13*333d2b36SAndroid Build Coastguard Worker// limitations under the License.
14*333d2b36SAndroid Build Coastguard Worker
15*333d2b36SAndroid Build Coastguard Workerpackage status
16*333d2b36SAndroid Build Coastguard Worker
17*333d2b36SAndroid Build Coastguard Workerimport (
18*333d2b36SAndroid Build Coastguard Worker	"io/ioutil"
19*333d2b36SAndroid Build Coastguard Worker	"os"
20*333d2b36SAndroid Build Coastguard Worker	"path/filepath"
21*333d2b36SAndroid Build Coastguard Worker	"testing"
22*333d2b36SAndroid Build Coastguard Worker	"time"
23*333d2b36SAndroid Build Coastguard Worker
24*333d2b36SAndroid Build Coastguard Worker	"android/soong/ui/logger"
25*333d2b36SAndroid Build Coastguard Worker)
26*333d2b36SAndroid Build Coastguard Worker
27*333d2b36SAndroid Build Coastguard Worker// Tests that closing the ninja reader when nothing has opened the other end of the fifo is fast.
28*333d2b36SAndroid Build Coastguard Workerfunc TestNinjaReader_Close(t *testing.T) {
29*333d2b36SAndroid Build Coastguard Worker	tempDir, err := ioutil.TempDir("", "ninja_test")
30*333d2b36SAndroid Build Coastguard Worker	if err != nil {
31*333d2b36SAndroid Build Coastguard Worker		t.Fatal(err)
32*333d2b36SAndroid Build Coastguard Worker	}
33*333d2b36SAndroid Build Coastguard Worker	defer os.RemoveAll(tempDir)
34*333d2b36SAndroid Build Coastguard Worker
35*333d2b36SAndroid Build Coastguard Worker	stat := &Status{}
36*333d2b36SAndroid Build Coastguard Worker	nr := NewNinjaReader(logger.New(ioutil.Discard), stat.StartTool(), filepath.Join(tempDir, "fifo"))
37*333d2b36SAndroid Build Coastguard Worker
38*333d2b36SAndroid Build Coastguard Worker	start := time.Now()
39*333d2b36SAndroid Build Coastguard Worker
40*333d2b36SAndroid Build Coastguard Worker	nr.Close()
41*333d2b36SAndroid Build Coastguard Worker
42*333d2b36SAndroid Build Coastguard Worker	if g, w := time.Since(start), NINJA_READER_CLOSE_TIMEOUT; g >= w {
43*333d2b36SAndroid Build Coastguard Worker		t.Errorf("nr.Close timed out, %s > %s", g, w)
44*333d2b36SAndroid Build Coastguard Worker	}
45*333d2b36SAndroid Build Coastguard Worker}
46*333d2b36SAndroid Build Coastguard Worker
47*333d2b36SAndroid Build Coastguard Worker// Test that error hint is added to output if available
48*333d2b36SAndroid Build Coastguard Workerfunc TestNinjaReader_CorrectErrorHint(t *testing.T) {
49*333d2b36SAndroid Build Coastguard Worker	errorPattern1 := "pattern-1 in input"
50*333d2b36SAndroid Build Coastguard Worker	errorHint1 := "\n Fix by doing task 1"
51*333d2b36SAndroid Build Coastguard Worker	errorPattern2 := "pattern-2 in input"
52*333d2b36SAndroid Build Coastguard Worker	errorHint2 := "\n Fix by doing task 2"
53*333d2b36SAndroid Build Coastguard Worker	mockErrorHints := make(map[string]string)
54*333d2b36SAndroid Build Coastguard Worker	mockErrorHints[errorPattern1] = errorHint1
55*333d2b36SAndroid Build Coastguard Worker	mockErrorHints[errorPattern2] = errorHint2
56*333d2b36SAndroid Build Coastguard Worker
57*333d2b36SAndroid Build Coastguard Worker	errorHintGenerator := *newErrorHintGenerator(mockErrorHints)
58*333d2b36SAndroid Build Coastguard Worker	testCases := []struct {
59*333d2b36SAndroid Build Coastguard Worker		rawOutput            string
60*333d2b36SAndroid Build Coastguard Worker		buildExitCode        int
61*333d2b36SAndroid Build Coastguard Worker		expectedFinalOutput  string
62*333d2b36SAndroid Build Coastguard Worker		testCaseErrorMessage string
63*333d2b36SAndroid Build Coastguard Worker	}{
64*333d2b36SAndroid Build Coastguard Worker		{
65*333d2b36SAndroid Build Coastguard Worker			rawOutput:            "ninja build was successful",
66*333d2b36SAndroid Build Coastguard Worker			buildExitCode:        0,
67*333d2b36SAndroid Build Coastguard Worker			expectedFinalOutput:  "ninja build was successful",
68*333d2b36SAndroid Build Coastguard Worker			testCaseErrorMessage: "raw output changed when build was successful",
69*333d2b36SAndroid Build Coastguard Worker		},
70*333d2b36SAndroid Build Coastguard Worker		{
71*333d2b36SAndroid Build Coastguard Worker			rawOutput:            "ninja build failed",
72*333d2b36SAndroid Build Coastguard Worker			buildExitCode:        1,
73*333d2b36SAndroid Build Coastguard Worker			expectedFinalOutput:  "ninja build failed",
74*333d2b36SAndroid Build Coastguard Worker			testCaseErrorMessage: "raw output changed even when no error hint pattern was found",
75*333d2b36SAndroid Build Coastguard Worker		},
76*333d2b36SAndroid Build Coastguard Worker		{
77*333d2b36SAndroid Build Coastguard Worker			rawOutput:            "ninja build failed: " + errorPattern1 + "some footnotes",
78*333d2b36SAndroid Build Coastguard Worker			buildExitCode:        1,
79*333d2b36SAndroid Build Coastguard Worker			expectedFinalOutput:  "ninja build failed: " + errorPattern1 + "some footnotes" + errorHint1,
80*333d2b36SAndroid Build Coastguard Worker			testCaseErrorMessage: "error hint not added despite pattern match",
81*333d2b36SAndroid Build Coastguard Worker		},
82*333d2b36SAndroid Build Coastguard Worker		{
83*333d2b36SAndroid Build Coastguard Worker			rawOutput:            "ninja build failed: " + errorPattern2 + errorPattern1,
84*333d2b36SAndroid Build Coastguard Worker			buildExitCode:        1,
85*333d2b36SAndroid Build Coastguard Worker			expectedFinalOutput:  "ninja build failed: " + errorPattern2 + errorPattern1 + errorHint2,
86*333d2b36SAndroid Build Coastguard Worker			testCaseErrorMessage: "error hint should be added for first pattern match in raw output",
87*333d2b36SAndroid Build Coastguard Worker		},
88*333d2b36SAndroid Build Coastguard Worker	}
89*333d2b36SAndroid Build Coastguard Worker	for _, testCase := range testCases {
90*333d2b36SAndroid Build Coastguard Worker		actualFinalOutput := errorHintGenerator.GetOutputWithErrorHint(testCase.rawOutput, testCase.buildExitCode)
91*333d2b36SAndroid Build Coastguard Worker		if actualFinalOutput != testCase.expectedFinalOutput {
92*333d2b36SAndroid Build Coastguard Worker			t.Errorf(testCase.testCaseErrorMessage+"\nexpected: %s\ngot: %s", testCase.expectedFinalOutput, actualFinalOutput)
93*333d2b36SAndroid Build Coastguard Worker		}
94*333d2b36SAndroid Build Coastguard Worker	}
95*333d2b36SAndroid Build Coastguard Worker}
96