@@ -22,125 +22,166 @@ func TestConvertResources(t *testing.T) {
22
22
t .Parallel ()
23
23
// nolint:dogsled
24
24
_ , filename , _ , _ := runtime .Caller (0 )
25
+ type testCase struct {
26
+ resources []* proto.Resource
27
+ parameters []* proto.Parameter
28
+ }
25
29
// nolint:paralleltest
26
- for folderName , expected := range map [string ][] * proto. Resource {
30
+ for folderName , expected := range map [string ]testCase {
27
31
// When a resource depends on another, the shortest route
28
32
// to a resource should always be chosen for the agent.
29
- "chaining-resources" : {{
30
- Name : "a" ,
31
- Type : "null_resource" ,
32
- }, {
33
- Name : "b" ,
34
- Type : "null_resource" ,
35
- Agents : []* proto.Agent {{
36
- Name : "main" ,
37
- OperatingSystem : "linux" ,
38
- Architecture : "amd64" ,
39
- Auth : & proto.Agent_Token {},
33
+ "chaining-resources" : {
34
+ resources : []* proto.Resource {{
35
+ Name : "a" ,
36
+ Type : "null_resource" ,
37
+ }, {
38
+ Name : "b" ,
39
+ Type : "null_resource" ,
40
+ Agents : []* proto.Agent {{
41
+ Name : "main" ,
42
+ OperatingSystem : "linux" ,
43
+ Architecture : "amd64" ,
44
+ Auth : & proto.Agent_Token {},
45
+ }},
40
46
}},
41
- }} ,
47
+ },
42
48
// This can happen when resources hierarchically conflict.
43
49
// When multiple resources exist at the same level, the first
44
50
// listed in state will be chosen.
45
- "conflicting-resources" : {{
46
- Name : "first" ,
47
- Type : "null_resource" ,
48
- Agents : []* proto.Agent {{
49
- Name : "main" ,
50
- OperatingSystem : "linux" ,
51
- Architecture : "amd64" ,
52
- Auth : & proto.Agent_Token {},
51
+ "conflicting-resources" : {
52
+ resources : []* proto.Resource {{
53
+ Name : "first" ,
54
+ Type : "null_resource" ,
55
+ Agents : []* proto.Agent {{
56
+ Name : "main" ,
57
+ OperatingSystem : "linux" ,
58
+ Architecture : "amd64" ,
59
+ Auth : & proto.Agent_Token {},
60
+ }},
61
+ }, {
62
+ Name : "second" ,
63
+ Type : "null_resource" ,
53
64
}},
54
- }, {
55
- Name : "second" ,
56
- Type : "null_resource" ,
57
- }},
65
+ },
58
66
// Ensures the instance ID authentication type surfaces.
59
- "instance-id" : {{
60
- Name : "main" ,
61
- Type : "null_resource" ,
62
- Agents : []* proto.Agent {{
63
- Name : "main" ,
64
- OperatingSystem : "linux" ,
65
- Architecture : "amd64" ,
66
- Auth : & proto.Agent_InstanceId {},
67
+ "instance-id" : {
68
+ resources : []* proto.Resource {{
69
+ Name : "main" ,
70
+ Type : "null_resource" ,
71
+ Agents : []* proto.Agent {{
72
+ Name : "main" ,
73
+ OperatingSystem : "linux" ,
74
+ Architecture : "amd64" ,
75
+ Auth : & proto.Agent_InstanceId {},
76
+ }},
67
77
}},
68
- }} ,
78
+ },
69
79
// Ensures that calls to resources through modules work
70
80
// as expected.
71
- "calling-module" : {{
72
- Name : "example" ,
73
- Type : "null_resource" ,
74
- Agents : []* proto.Agent {{
75
- Name : "main" ,
76
- OperatingSystem : "linux" ,
77
- Architecture : "amd64" ,
78
- Auth : & proto.Agent_Token {},
81
+ "calling-module" : {
82
+ resources : []* proto.Resource {{
83
+ Name : "example" ,
84
+ Type : "null_resource" ,
85
+ Agents : []* proto.Agent {{
86
+ Name : "main" ,
87
+ OperatingSystem : "linux" ,
88
+ Architecture : "amd64" ,
89
+ Auth : & proto.Agent_Token {},
90
+ }},
79
91
}},
80
- }} ,
92
+ },
81
93
// Ensures the attachment of multiple agents to a single
82
94
// resource is successful.
83
- "multiple-agents" : {{
84
- Name : "dev" ,
85
- Type : "null_resource" ,
86
- Agents : []* proto.Agent {{
87
- Name : "dev1" ,
88
- OperatingSystem : "linux" ,
89
- Architecture : "amd64" ,
90
- Auth : & proto.Agent_Token {},
91
- }, {
92
- Name : "dev2" ,
93
- OperatingSystem : "darwin" ,
94
- Architecture : "amd64" ,
95
- Auth : & proto.Agent_Token {},
96
- }, {
97
- Name : "dev3" ,
98
- OperatingSystem : "windows" ,
99
- Architecture : "arm64" ,
100
- Auth : & proto.Agent_Token {},
95
+ "multiple-agents" : {
96
+ resources : []* proto.Resource {{
97
+ Name : "dev" ,
98
+ Type : "null_resource" ,
99
+ Agents : []* proto.Agent {{
100
+ Name : "dev1" ,
101
+ OperatingSystem : "linux" ,
102
+ Architecture : "amd64" ,
103
+ Auth : & proto.Agent_Token {},
104
+ }, {
105
+ Name : "dev2" ,
106
+ OperatingSystem : "darwin" ,
107
+ Architecture : "amd64" ,
108
+ Auth : & proto.Agent_Token {},
109
+ }, {
110
+ Name : "dev3" ,
111
+ OperatingSystem : "windows" ,
112
+ Architecture : "arm64" ,
113
+ Auth : & proto.Agent_Token {},
114
+ }},
101
115
}},
102
- }} ,
116
+ },
103
117
// Ensures multiple applications can be set for a single agent.
104
- "multiple-apps" : {{
105
- Name : "dev" ,
106
- Type : "null_resource" ,
107
- Agents : []* proto.Agent {{
108
- Name : "dev1" ,
109
- OperatingSystem : "linux" ,
110
- Architecture : "amd64" ,
111
- Apps : []* proto.App {{
112
- Name : "app1" ,
113
- }, {
114
- Name : "app2" ,
115
- Healthcheck : & proto.Healthcheck {
116
- Url : "http://localhost:13337/healthz" ,
117
- Interval : 5 ,
118
- Threshold : 6 ,
119
- },
118
+ "multiple-apps" : {
119
+ resources : []* proto.Resource {{
120
+ Name : "dev" ,
121
+ Type : "null_resource" ,
122
+ Agents : []* proto.Agent {{
123
+ Name : "dev1" ,
124
+ OperatingSystem : "linux" ,
125
+ Architecture : "amd64" ,
126
+ Apps : []* proto.App {{
127
+ Name : "app1" ,
128
+ }, {
129
+ Name : "app2" ,
130
+ Healthcheck : & proto.Healthcheck {
131
+ Url : "http://localhost:13337/healthz" ,
132
+ Interval : 5 ,
133
+ Threshold : 6 ,
134
+ },
135
+ }},
136
+ Auth : & proto.Agent_Token {},
120
137
}},
121
- Auth : & proto.Agent_Token {},
122
138
}},
123
- }} ,
139
+ },
124
140
// Tests fetching metadata about workspace resources.
125
- "resource-metadata" : {{
126
- Name : "about" ,
127
- Type : "null_resource" ,
128
- Hide : true ,
129
- Icon : "/icon/server.svg" ,
130
- Metadata : []* proto.Resource_Metadata {{
131
- Key : "hello" ,
132
- Value : "world" ,
133
- }, {
134
- Key : "null" ,
135
- IsNull : true ,
136
- }, {
137
- Key : "empty" ,
138
- }, {
139
- Key : "secret" ,
140
- Value : "squirrel" ,
141
- Sensitive : true ,
141
+ "resource-metadata" : {
142
+ resources : []* proto.Resource {{
143
+ Name : "about" ,
144
+ Type : "null_resource" ,
145
+ Hide : true ,
146
+ Icon : "/icon/server.svg" ,
147
+ Metadata : []* proto.Resource_Metadata {{
148
+ Key : "hello" ,
149
+ Value : "world" ,
150
+ }, {
151
+ Key : "null" ,
152
+ IsNull : true ,
153
+ }, {
154
+ Key : "empty" ,
155
+ }, {
156
+ Key : "secret" ,
157
+ Value : "squirrel" ,
158
+ Sensitive : true ,
159
+ }},
160
+ }},
161
+ },
162
+ "parameters" : {
163
+ resources : []* proto.Resource {{
164
+ Name : "dev" ,
165
+ Type : "null_resource" ,
166
+ Agents : []* proto.Agent {{
167
+ Name : "dev" ,
168
+ OperatingSystem : "windows" ,
169
+ Architecture : "arm64" ,
170
+ Auth : & proto.Agent_Token {},
171
+ }},
142
172
}},
143
- }},
173
+ parameters : []* proto.Parameter {{
174
+ Name : "Example" ,
175
+ Type : "string" ,
176
+ Options : []* proto.ParameterOption {{
177
+ Name : "First Option" ,
178
+ Value : "first" ,
179
+ }, {
180
+ Name : "Second Option" ,
181
+ Value : "second" ,
182
+ }},
183
+ }},
184
+ },
144
185
} {
145
186
folderName := folderName
146
187
expected := expected
@@ -158,13 +199,18 @@ func TestConvertResources(t *testing.T) {
158
199
tfPlanGraph , err := os .ReadFile (filepath .Join (dir , folderName + ".tfplan.dot" ))
159
200
require .NoError (t , err )
160
201
161
- resources , parameters , err := terraform .ConvertResourcesAndParameters (tfPlan .PlannedValues .RootModule , string (tfPlanGraph ))
202
+ modules := []* tfjson.StateModule {}
203
+ if tfPlan .PriorState != nil {
204
+ modules = append (modules , tfPlan .PriorState .Values .RootModule )
205
+ }
206
+ modules = append (modules , tfPlan .PlannedValues .RootModule )
207
+ resources , parameters , err := terraform .ConvertResourcesAndParameters (modules , string (tfPlanGraph ))
162
208
require .NoError (t , err )
163
209
sortResources (resources )
164
210
sortParameters (parameters )
165
211
166
- var expectedNoMetadata []* proto.Resource
167
- for _ , resource := range expected {
212
+ expectedNoMetadata := make ( []* proto.Resource , 0 )
213
+ for _ , resource := range expected . resources {
168
214
resourceCopy , _ := protobuf .Clone (resource ).(* proto.Resource )
169
215
// plan cannot know whether values are null or not
170
216
for _ , metadata := range resourceCopy .Metadata {
@@ -178,6 +224,15 @@ func TestConvertResources(t *testing.T) {
178
224
resourcesGot , err := json .Marshal (resources )
179
225
require .NoError (t , err )
180
226
require .Equal (t , string (resourcesWant ), string (resourcesGot ))
227
+
228
+ if expected .parameters == nil {
229
+ expected .parameters = []* proto.Parameter {}
230
+ }
231
+ parametersWant , err := json .Marshal (expected .parameters )
232
+ require .NoError (t , err )
233
+ parametersGot , err := json .Marshal (parameters )
234
+ require .NoError (t , err )
235
+ require .Equal (t , string (parametersWant ), string (parametersGot ))
181
236
})
182
237
t .Run ("Provision" , func (t * testing.T ) {
183
238
t .Parallel ()
@@ -189,7 +244,7 @@ func TestConvertResources(t *testing.T) {
189
244
tfStateGraph , err := os .ReadFile (filepath .Join (dir , folderName + ".tfstate.dot" ))
190
245
require .NoError (t , err )
191
246
192
- resources , parameters , err := terraform .ConvertResourcesAndParameters (tfState .Values .RootModule , string (tfStateGraph ))
247
+ resources , parameters , err := terraform .ConvertResourcesAndParameters ([] * tfjson. StateModule { tfState .Values .RootModule } , string (tfStateGraph ))
193
248
require .NoError (t , err )
194
249
sortResources (resources )
195
250
sortParameters (parameters )
@@ -204,7 +259,7 @@ func TestConvertResources(t *testing.T) {
204
259
}
205
260
}
206
261
}
207
- resourcesWant , err := json .Marshal (expected )
262
+ resourcesWant , err := json .Marshal (expected . resources )
208
263
require .NoError (t , err )
209
264
resourcesGot , err := json .Marshal (resources )
210
265
require .NoError (t , err )
@@ -248,7 +303,7 @@ func TestInstanceIDAssociation(t *testing.T) {
248
303
t .Parallel ()
249
304
instanceID , err := cryptorand .String (12 )
250
305
require .NoError (t , err )
251
- resources , _ , err := terraform .ConvertResourcesAndParameters (& tfjson.StateModule {
306
+ resources , _ , err := terraform .ConvertResourcesAndParameters ([] * tfjson.StateModule { {
252
307
Resources : []* tfjson.StateResource {{
253
308
Address : "coder_agent.dev" ,
254
309
Type : "coder_agent" ,
@@ -269,7 +324,7 @@ func TestInstanceIDAssociation(t *testing.T) {
269
324
},
270
325
}},
271
326
// This is manually created to join the edges.
272
- }, `digraph {
327
+ }} , `digraph {
273
328
compound = "true"
274
329
newrank = "true"
275
330
subgraph "root" {
0 commit comments