...
1
16
17 package timer
18
19 import (
20 "time"
21
22 "bytes"
23 "fmt"
24
25 "sync"
26
27 "k8s.io/kubernetes/test/e2e/framework"
28 "k8s.io/kubernetes/test/e2e/perftype"
29 )
30
31 var now = time.Now
32
33
34 type Phase struct {
35 sequenceNumber int
36 name string
37 startTime time.Time
38 endTime time.Time
39 }
40
41 func (phase *Phase) ended() bool {
42 return !phase.endTime.IsZero()
43 }
44
45
46 func (phase *Phase) End() {
47 if !phase.ended() {
48 phase.endTime = now()
49 }
50 }
51
52 func (phase *Phase) label() string {
53 return fmt.Sprintf("%03d-%s", phase.sequenceNumber, phase.name)
54 }
55
56 func (phase *Phase) duration() time.Duration {
57 endTime := phase.endTime
58 if !phase.ended() {
59 endTime = now()
60 }
61 return endTime.Sub(phase.startTime)
62 }
63
64 func (phase *Phase) humanReadable() string {
65 if phase.ended() {
66 return fmt.Sprintf("Phase %s: %v\n", phase.label(), phase.duration())
67 }
68 return fmt.Sprintf("Phase %s: %v so far\n", phase.label(), phase.duration())
69 }
70
71
72
73 type TestPhaseTimer struct {
74 lock sync.Mutex
75 phases []*Phase
76 }
77
78
79 func NewTestPhaseTimer() *TestPhaseTimer {
80 return &TestPhaseTimer{}
81 }
82
83
84
85
86
87
88 func (timer *TestPhaseTimer) StartPhase(sequenceNumber int, phaseName string) *Phase {
89 timer.lock.Lock()
90 defer timer.lock.Unlock()
91 newPhase := &Phase{sequenceNumber: sequenceNumber, name: phaseName, startTime: now()}
92 timer.phases = append(timer.phases, newPhase)
93 return newPhase
94 }
95
96
97 func (timer *TestPhaseTimer) SummaryKind() string {
98 return "TestPhaseTimer"
99 }
100
101
102 func (timer *TestPhaseTimer) PrintHumanReadable() string {
103 buf := bytes.Buffer{}
104 timer.lock.Lock()
105 defer timer.lock.Unlock()
106 for _, phase := range timer.phases {
107 buf.WriteString(phase.humanReadable())
108 }
109 return buf.String()
110 }
111
112
113 func (timer *TestPhaseTimer) PrintJSON() string {
114 data := perftype.PerfData{
115 Version: "v1",
116 DataItems: []perftype.DataItem{{
117 Unit: "s",
118 Labels: map[string]string{"test": "phases"},
119 Data: make(map[string]float64)}}}
120 timer.lock.Lock()
121 defer timer.lock.Unlock()
122 for _, phase := range timer.phases {
123 data.DataItems[0].Data[phase.label()] = phase.duration().Seconds()
124 if !phase.ended() {
125 data.DataItems[0].Labels["ended"] = "false"
126 }
127 }
128 return framework.PrettyPrintJSON(data)
129 }
130
View as plain text