1// Copyright 2018 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package status
16
17import (
18	"testing"
19)
20
21type lastOutput struct {
22	counterOutput
23
24	action *Action
25	result ActionResult
26
27	msgLevel MsgLevel
28	msg      string
29}
30
31func (l *lastOutput) StartAction(a *Action, c Counts) {
32	l.action = a
33	l.counterOutput.StartAction(a, c)
34}
35func (l *lastOutput) FinishAction(r ActionResult, c Counts) {
36	l.result = r
37	l.counterOutput.FinishAction(r, c)
38}
39func (l *lastOutput) Message(level MsgLevel, msg string) {
40	l.msgLevel = level
41	l.msg = msg
42}
43func (l *lastOutput) Flush() {}
44
45func TestKatiNormalCase(t *testing.T) {
46	status := &Status{}
47	output := &lastOutput{}
48	status.AddOutput(output)
49
50	parser := &katiOutputParser{
51		st: status.StartTool(),
52	}
53
54	msg := "*kati*: verbose msg"
55	parser.parseLine(msg)
56	output.Expect(t, Counts{})
57
58	if output.msgLevel != VerboseLvl {
59		t.Errorf("Expected verbose message, but got %d", output.msgLevel)
60	}
61	if output.msg != msg {
62		t.Errorf("unexpected message contents:\nwant: %q\n got: %q\n", msg, output.msg)
63	}
64
65	parser.parseLine("out/build-aosp_arm.ninja is missing, regenerating...")
66	output.Expect(t, Counts{})
67
68	parser.parseLine("[1/1] initializing build system ...")
69	output.Expect(t, Counts{
70		TotalActions:    1,
71		RunningActions:  1,
72		StartedActions:  1,
73		FinishedActions: 0,
74	})
75
76	parser.parseLine("[2/5] including out/soong/Android-aosp_arm.mk ...")
77	output.Expect(t, Counts{
78		TotalActions:    5,
79		RunningActions:  1,
80		StartedActions:  2,
81		FinishedActions: 1,
82	})
83
84	parser.parseLine("[3/5] including a ...")
85	msg = "a random message"
86	parser.parseLine(msg)
87
88	// Start the next line to flush the previous result
89	parser.parseLine("[4/5] finishing build rules ...")
90
91	msg += "\n"
92	if output.result.Output != msg {
93		t.Errorf("output for action did not match:\nwant: %q\n got: %q\n", msg, output.result.Output)
94	}
95
96	parser.parseLine("[5/5] writing build rules ...")
97	parser.parseLine("*kati*: verbose msg")
98	parser.flushAction()
99
100	if output.result.Output != "" {
101		t.Errorf("expected no output for last action, but got %q", output.result.Output)
102	}
103
104	output.Expect(t, Counts{
105		TotalActions:    5,
106		RunningActions:  0,
107		StartedActions:  5,
108		FinishedActions: 5,
109	})
110}
111
112func TestKatiExtraIncludes(t *testing.T) {
113	status := &Status{}
114	output := &lastOutput{}
115	status.AddOutput(output)
116
117	parser := &katiOutputParser{
118		st: status.StartTool(),
119	}
120
121	parser.parseLine("[1/1] initializing build system ...")
122	parser.parseLine("[2/5] including out/soong/Android-aosp_arm.mk ...")
123	output.Expect(t, Counts{
124		TotalActions:    5,
125		RunningActions:  1,
126		StartedActions:  2,
127		FinishedActions: 1,
128	})
129
130	parser.parseLine("including a ...")
131
132	output.Expect(t, Counts{
133		TotalActions:    6,
134		RunningActions:  1,
135		StartedActions:  3,
136		FinishedActions: 2,
137	})
138
139	parser.parseLine("including b ...")
140
141	output.Expect(t, Counts{
142		TotalActions:    7,
143		RunningActions:  1,
144		StartedActions:  4,
145		FinishedActions: 3,
146	})
147
148	parser.parseLine("[3/5] finishing build rules ...")
149
150	output.Expect(t, Counts{
151		TotalActions:    7,
152		RunningActions:  1,
153		StartedActions:  5,
154		FinishedActions: 4,
155	})
156}
157
158func TestKatiFailOnError(t *testing.T) {
159	status := &Status{}
160	output := &lastOutput{}
161	status.AddOutput(output)
162
163	parser := &katiOutputParser{
164		st: status.StartTool(),
165	}
166
167	parser.parseLine("[1/1] initializing build system ...")
168	parser.parseLine("[2/5] inclduing out/soong/Android-aosp_arm.mk ...")
169	parser.parseLine("build/make/tools/Android.mk:19: error: testing")
170	parser.flushAction()
171
172	if output.result.Error == nil {
173		t.Errorf("Expected the last action to be marked as an error")
174	}
175}
176