blob: 965e0ad136ec848f0eaa0feaced5dece81f50d21 [file] [log] [blame]
Colin Cross7b624532019-06-21 15:08:30 -07001// Copyright 2019 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 "reflect"
19 "testing"
20 "time"
21)
22
23type testCriticalPath struct {
24 *criticalPath
25 Counts
26
27 actions map[int]*Action
28}
29
30type testClock time.Time
31
32func (t testClock) Now() time.Time { return time.Time(t) }
33
34func (t *testCriticalPath) start(id int, startTime time.Duration, outputs, inputs []string) {
35 t.clock = testClock(time.Unix(0, 0).Add(startTime))
36 action := &Action{
37 Description: outputs[0],
38 Outputs: outputs,
39 Inputs: inputs,
40 }
41
42 t.actions[id] = action
43 t.StartAction(action, t.Counts)
44}
45
46func (t *testCriticalPath) finish(id int, endTime time.Duration) {
47 t.clock = testClock(time.Unix(0, 0).Add(endTime))
48 t.FinishAction(ActionResult{
49 Action: t.actions[id],
50 }, t.Counts)
51}
52
53func TestCriticalPath(t *testing.T) {
54 tests := []struct {
55 name string
56 msgs func(*testCriticalPath)
57 want []string
58 wantTime time.Duration
59 }{
60 {
61 name: "empty",
62 msgs: func(cp *testCriticalPath) {},
63 },
64 {
65 name: "duplicate",
66 msgs: func(cp *testCriticalPath) {
67 cp.start(0, 0, []string{"a"}, nil)
68 cp.start(1, 0, []string{"a"}, nil)
69 cp.finish(0, 1000)
70 cp.finish(0, 2000)
71 },
72 want: []string{"a"},
73 wantTime: 1000,
74 },
75 {
76 name: "linear",
77 // a
78 // |
79 // b
80 // |
81 // c
82 msgs: func(cp *testCriticalPath) {
83 cp.start(0, 0, []string{"a"}, nil)
84 cp.finish(0, 1000)
85 cp.start(1, 1000, []string{"b"}, []string{"a"})
86 cp.finish(1, 2000)
87 cp.start(2, 3000, []string{"c"}, []string{"b"})
88 cp.finish(2, 4000)
89 },
90 want: []string{"c", "b", "a"},
91 wantTime: 3000,
92 },
93 {
94 name: "diamond",
95 // a
96 // |\
97 // b c
98 // |/
99 // d
100 msgs: func(cp *testCriticalPath) {
101 cp.start(0, 0, []string{"a"}, nil)
102 cp.finish(0, 1000)
103 cp.start(1, 1000, []string{"b"}, []string{"a"})
104 cp.start(2, 1000, []string{"c"}, []string{"a"})
105 cp.finish(1, 2000)
106 cp.finish(2, 3000)
107 cp.start(3, 3000, []string{"d"}, []string{"b", "c"})
108 cp.finish(3, 4000)
109 },
110 want: []string{"d", "c", "a"},
111 wantTime: 4000,
112 },
113 {
114 name: "multiple",
115 // a d
116 // | |
117 // b e
118 // |
119 // c
120 msgs: func(cp *testCriticalPath) {
121 cp.start(0, 0, []string{"a"}, nil)
122 cp.start(3, 0, []string{"d"}, nil)
123 cp.finish(0, 1000)
124 cp.finish(3, 1000)
125 cp.start(1, 1000, []string{"b"}, []string{"a"})
126 cp.start(4, 1000, []string{"e"}, []string{"d"})
127 cp.finish(1, 2000)
128 cp.start(2, 2000, []string{"c"}, []string{"b"})
129 cp.finish(2, 3000)
130 cp.finish(4, 4000)
131
132 },
133 want: []string{"e", "d"},
134 wantTime: 4000,
135 },
136 }
137 for _, tt := range tests {
138 t.Run(tt.name, func(t *testing.T) {
139 cp := &testCriticalPath{
140 criticalPath: NewCriticalPath(nil).(*criticalPath),
141 actions: make(map[int]*Action),
142 }
143
144 tt.msgs(cp)
145
146 criticalPath := cp.criticalPath.criticalPath()
147
148 var descs []string
149 for _, x := range criticalPath {
150 descs = append(descs, x.action.Description)
151 }
152
153 if !reflect.DeepEqual(descs, tt.want) {
154 t.Errorf("criticalPath.criticalPath() = %v, want %v", descs, tt.want)
155 }
156
157 var gotTime time.Duration
158 if len(criticalPath) > 0 {
159 gotTime = criticalPath[0].cumulativeDuration
160 }
161 if gotTime != tt.wantTime {
162 t.Errorf("cumulativeDuration[0].cumulativeDuration = %v, want %v", gotTime, tt.wantTime)
163 }
164 })
165 }
166}