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