4
4
"context"
5
5
"database/sql"
6
6
"testing"
7
+ "time"
7
8
8
9
"github.com/google/uuid"
9
10
"github.com/stretchr/testify/assert"
@@ -12,111 +13,139 @@ import (
12
13
"github.com/coder/coder/v2/coderd/database/dbtime"
13
14
"github.com/coder/coder/v2/coderd/healthcheck"
14
15
"github.com/coder/coder/v2/coderd/healthcheck/health"
16
+ "github.com/coder/coder/v2/coderd/util/apiversion"
17
+ "github.com/coder/coder/v2/provisionersdk"
15
18
)
16
19
17
20
func TestProvisionerDaemonReport (t * testing.T ) {
18
21
t .Parallel ()
19
22
20
- var ()
21
-
22
23
for _ , tt := range []struct {
23
24
name string
24
25
currentVersion string
25
- currentAPIVersion string
26
+ currentAPIVersion * apiversion. APIVersion
26
27
provisionerDaemonsFn func (context.Context ) ([]database.ProvisionerDaemon , error )
27
28
expectedSeverity health.Severity
28
29
expectedWarningCode health.Code
30
+ expectedError string
29
31
}{
30
32
{
31
- name : "current version empty" ,
32
- currentVersion : "" ,
33
- expectedSeverity : health .SeverityError ,
34
- expectedWarningCode : health . CodeUnknown ,
33
+ name : "current version empty" ,
34
+ currentVersion : "" ,
35
+ expectedSeverity : health .SeverityError ,
36
+ expectedError : "Developer error: CurrentVersion is empty" ,
35
37
},
36
38
{
37
- name : "current api version empty " ,
38
- currentVersion : "v1.2.3" ,
39
- currentAPIVersion : "" ,
40
- expectedSeverity : health .SeverityError ,
41
- expectedWarningCode : health . CodeUnknown ,
39
+ name : "provisionerdaemonsfn nil " ,
40
+ currentVersion : "v1.2.3" ,
41
+ currentAPIVersion : provisionersdk . VersionCurrent ,
42
+ expectedSeverity : health .SeverityError ,
43
+ expectedError : "Developer error: ProvisionerDaemonsFn is nil" ,
42
44
},
43
45
{
44
- name : "provisionerdaemonsfn nil" ,
45
- currentVersion : "v1.2.3" ,
46
- currentAPIVersion : "v1.0" ,
47
- expectedSeverity : health .SeverityError ,
48
- expectedWarningCode : health .CodeUnknown ,
46
+ name : "no daemons" ,
47
+ currentVersion : "v1.2.3" ,
48
+ currentAPIVersion : provisionersdk .VersionCurrent ,
49
+ provisionerDaemonsFn : fakeProvisionerDaemonsFn (),
50
+ expectedSeverity : health .SeverityError ,
51
+ expectedError : "No provisioner daemons found!" ,
49
52
},
50
53
{
51
- name : "no daemons" ,
54
+ name : "error fetching daemons" ,
52
55
currentVersion : "v1.2.3" ,
53
- currentAPIVersion : "v1.0" ,
56
+ currentAPIVersion : provisionersdk .VersionCurrent ,
57
+ provisionerDaemonsFn : fakeProvisionerDaemonsFnErr (assert .AnError ),
54
58
expectedSeverity : health .SeverityError ,
55
- expectedWarningCode : health .CodeProvisionerDaemonsNoProvisionerDaemons ,
56
- provisionerDaemonsFn : fakeProvisionerDaemonsFn (),
59
+ expectedError : assert .AnError .Error (),
57
60
},
58
61
{
59
62
name : "one daemon up to date" ,
60
63
currentVersion : "v1.2.3" ,
61
- currentAPIVersion : "v1.0" ,
64
+ currentAPIVersion : provisionersdk . VersionCurrent ,
62
65
expectedSeverity : health .SeverityOK ,
63
- provisionerDaemonsFn : fakeProvisionerDaemonsFn (fakeProvisionerDaemon (t , "pd-ok" , "v1.2.3" , "v1 .0" )),
66
+ provisionerDaemonsFn : fakeProvisionerDaemonsFn (fakeProvisionerDaemon (t , "pd-ok" , "v1.2.3" , "1 .0" )),
64
67
},
65
68
{
66
69
name : "one daemon out of date" ,
67
70
currentVersion : "v1.2.3" ,
68
- currentAPIVersion : "v1.0" ,
71
+ currentAPIVersion : provisionersdk . VersionCurrent ,
69
72
expectedSeverity : health .SeverityWarning ,
70
- expectedWarningCode : health .CodeProvisionerDaemonVersionOutOfDate ,
71
- provisionerDaemonsFn : fakeProvisionerDaemonsFn (fakeProvisionerDaemon (t , "pd-old" , "v1.1.2" , "v1 .0" )),
73
+ expectedWarningCode : health .CodeProvisionerDaemonVersionMismatch ,
74
+ provisionerDaemonsFn : fakeProvisionerDaemonsFn (fakeProvisionerDaemon (t , "pd-old" , "v1.1.2" , "1 .0" )),
72
75
},
73
76
{
74
77
name : "major api version not available" ,
75
78
currentVersion : "v1.2.3" ,
76
- currentAPIVersion : "v1.0" ,
79
+ currentAPIVersion : provisionersdk . VersionCurrent ,
77
80
expectedSeverity : health .SeverityError ,
78
- expectedWarningCode : health .CodeProvisionerDaemonAPIMajorVersionNotAvailable ,
79
- provisionerDaemonsFn : fakeProvisionerDaemonsFn (fakeProvisionerDaemon (t , "pd-new-major" , "v1.2.3" , "v2 .0" )),
81
+ expectedWarningCode : health .CodeProvisionerDaemonAPIVersionIncompatible ,
82
+ provisionerDaemonsFn : fakeProvisionerDaemonsFn (fakeProvisionerDaemon (t , "pd-new-major" , "v1.2.3" , "2 .0" )),
80
83
},
81
84
{
82
85
name : "minor api version not available" ,
83
86
currentVersion : "v1.2.3" ,
84
- currentAPIVersion : "v1.0" ,
85
- expectedSeverity : health .SeverityWarning ,
86
- expectedWarningCode : health .CodeProvisionerDaemonAPIMinorVersionNotAvailable ,
87
- provisionerDaemonsFn : fakeProvisionerDaemonsFn (fakeProvisionerDaemon (t , "pd-new-minor" , "v1.2.3" , "v1.1" )),
87
+ currentAPIVersion : provisionersdk .VersionCurrent ,
88
+ expectedSeverity : health .SeverityError ,
89
+ expectedWarningCode : health .CodeProvisionerDaemonAPIVersionIncompatible ,
90
+ provisionerDaemonsFn : fakeProvisionerDaemonsFn (fakeProvisionerDaemon (t , "pd-new-minor" , "v1.2.3" , "1.1" )),
91
+ },
92
+ {
93
+ name : "api version backward compat" ,
94
+ currentVersion : "v2.3.4" ,
95
+ currentAPIVersion : apiversion .New ([]int {2 , 1 }, 0 ),
96
+ expectedSeverity : health .SeverityOK ,
97
+ provisionerDaemonsFn : fakeProvisionerDaemonsFn (
98
+ fakeProvisionerDaemon (t , "pd-old-api" , "v2.3.4" , "1.0" )),
88
99
},
89
100
{
90
101
name : "one up to date, one out of date" ,
91
102
currentVersion : "v1.2.3" ,
92
- currentAPIVersion : "v1.0" ,
103
+ currentAPIVersion : provisionersdk . VersionCurrent ,
93
104
expectedSeverity : health .SeverityWarning ,
94
- expectedWarningCode : health .CodeProvisionerDaemonVersionOutOfDate ,
105
+ expectedWarningCode : health .CodeProvisionerDaemonVersionMismatch ,
95
106
provisionerDaemonsFn : fakeProvisionerDaemonsFn (
96
- fakeProvisionerDaemon (t , "pd-ok" , "v1.2.3" , "v1 .0" ),
97
- fakeProvisionerDaemon (t , "pd-old" , "v1.1.2" , "v1 .0" )),
107
+ fakeProvisionerDaemon (t , "pd-ok" , "v1.2.3" , "1 .0" ),
108
+ fakeProvisionerDaemon (t , "pd-old" , "v1.1.2" , "1 .0" )),
98
109
},
99
110
{
100
- name : "one up to date, one newer" ,
101
- currentVersion : "v1.2.3" ,
102
- currentAPIVersion : "v1.0" ,
111
+ name : "one up to date, one newer" ,
112
+ currentVersion : "v1.2.3" ,
113
+ currentAPIVersion : provisionersdk .VersionCurrent ,
114
+ expectedSeverity : health .SeverityWarning ,
115
+ expectedWarningCode : health .CodeProvisionerDaemonVersionMismatch ,
116
+ provisionerDaemonsFn : fakeProvisionerDaemonsFn (
117
+ fakeProvisionerDaemon (t , "pd-ok" , "v1.2.3" , "1.0" ),
118
+ fakeProvisionerDaemon (t , "pd-new" , "v2.3.4" , "1.0" )),
119
+ },
120
+ {
121
+ name : "one up to date, one stale older" ,
122
+ currentVersion : "v2.3.4" ,
123
+ currentAPIVersion : provisionersdk .VersionCurrent ,
103
124
expectedSeverity : health .SeverityOK ,
104
125
provisionerDaemonsFn : fakeProvisionerDaemonsFn (
105
- fakeProvisionerDaemon (t , "pd-ok" , "v1.2.3" , "v1.0" ),
106
- fakeProvisionerDaemon (t , "pd-new" , "v2.3.4" , "v1 .0" )),
126
+ fakeProvisionerDaemonStale (t , "pd-ok" , "v1.2.3" , "0.9" , dbtime . Now (). Add ( - 5 * time . Minute ) ),
127
+ fakeProvisionerDaemon (t , "pd-new" , "v2.3.4" , "1 .0" )),
107
128
},
108
129
} {
109
130
tt := tt
110
131
t .Run (tt .name , func (t * testing.T ) {
111
132
t .Parallel ()
112
133
113
- var rpt healthcheck.ProvisionerDaemonReport
114
- var opts healthcheck.ProvisionerDaemonReportOptions
134
+ var rpt healthcheck.ProvisionerDaemonsReport
135
+ var opts healthcheck.ProvisionerDaemonsReportOptions
115
136
opts .CurrentVersion = tt .currentVersion
116
- opts .CurrentAPIVersion = tt .currentAPIVersion
137
+ if tt .currentAPIVersion == nil {
138
+ opts .CurrentAPIVersion = provisionersdk .VersionCurrent
139
+ } else {
140
+ opts .CurrentAPIVersion = tt .currentAPIVersion
141
+ }
117
142
if tt .provisionerDaemonsFn != nil {
118
143
opts .ProvisionerDaemonsFn = tt .provisionerDaemonsFn
119
144
}
145
+ now := dbtime .Now ()
146
+ opts .TimeNowFn = func () time.Time {
147
+ return now
148
+ }
120
149
121
150
rpt .Run (context .Background (), & opts )
122
151
@@ -133,6 +162,9 @@ func TestProvisionerDaemonReport(t *testing.T) {
133
162
} else {
134
163
assert .Empty (t , rpt .Warnings )
135
164
}
165
+ if tt .expectedError != "" && assert .NotNil (t , rpt .Error ) {
166
+ assert .Contains (t , * rpt .Error , tt .expectedError )
167
+ }
136
168
})
137
169
}
138
170
}
@@ -163,3 +195,11 @@ func fakeProvisionerDaemonsFnErr(err error) func(context.Context) ([]database.Pr
163
195
return nil , err
164
196
}
165
197
}
198
+
199
+ func fakeProvisionerDaemonStale (t * testing.T , name , version , apiVersion string , lastSeenAt time.Time ) database.ProvisionerDaemon {
200
+ t .Helper ()
201
+ d := fakeProvisionerDaemon (t , name , version , apiVersion )
202
+ d .LastSeenAt .Valid = true
203
+ d .LastSeenAt .Time = lastSeenAt
204
+ return d
205
+ }
0 commit comments