Skip to content

Commit 38f0712

Browse files
authoredJan 15, 2025··
feat: Enables the ignored pipeline template test to be used [5] (#3265)
1 parent f8258b7 commit 38f0712

File tree

2 files changed

+243
-21
lines changed

2 files changed

+243
-21
lines changed
 

‎features/pipeline-templates.feature

+24-12
Original file line numberDiff line numberDiff line change
@@ -95,16 +95,28 @@ Feature: Pipeline Templates
9595
| test-trusted-pipeline-template | trusted | publish-trusted |
9696
| test-distrusted-pipeline-template | distrusted | publish-distrusted |
9797

98-
@ignore
99-
Scenario: Merges pipeline template into user's config
100-
Given a "second" pipeline using a "test-pipeline-template" @ "1.0.0" pipeline template
101-
When user starts the pipeline that uses pipeline template
102-
Then the pipeline executes what is specified in the pipeline template
103-
104-
@ignore
105-
Scenario: Pipeline config takes precedence over template config
98+
Scenario: Use pipeline template
10699
Given a "third" pipeline using a "test-pipeline-template" @ "1.0.0" pipeline template
107-
And user has some pipeline settings defined
108-
And the pipeline template has the same settings with different values
109-
When user starts the pipeline that uses pipeline template
110-
Then pipeline settings are the user settings.
100+
When user starts the job that uses pipeline template
101+
And the pipeline executes what is specified in the pipeline template
102+
103+
Scenario: Pipeline shared config takes precedence over template config
104+
Given a "fourth" pipeline using a "test-pipeline-template" @ "1.0.0" pipeline template
105+
And user defined shared settings
106+
And the pipeline template has overwritten shared settings
107+
When user starts the job that uses pipeline template
108+
Then job settings are the template command
109+
110+
Scenario: Pipeline exists job config takes precedence over template config
111+
Given a "fifth" pipeline using a "test-pipeline-template" @ "1.0.0" pipeline template
112+
And user defined exists jobs settings
113+
And the pipeline template has overwritten jobs settings
114+
When user starts the job that uses pipeline template
115+
Then job settings are the user command
116+
117+
Scenario: Pipeline user defined job config takes precedence over template config
118+
Given a "sixth" pipeline using a "test-pipeline-template" @ "1.0.0" pipeline template
119+
And user defined additional jobs settings
120+
And the pipeline template has additional jobs settings
121+
When user starts the additional job that uses pipeline template
122+
Then additional job settings are the user command

‎features/step_definitions/pipeline-template.js

+219-9
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Before(
2222
this.jwt = null;
2323
this.template = null;
2424
this.jobName = 'main';
25+
this.additionalJobName = 'test';
2526

2627
this.startJob = jobName => {
2728
return this.ensurePipelineExists({
@@ -164,6 +165,18 @@ Given(
164165
shouldNotDeletePipeline: true
165166
})
166167
)
168+
.then(() =>
169+
request({
170+
url: `${this.instance}/${this.namespace}/pipelines/${this.pipelineId}`,
171+
method: 'GET',
172+
context: {
173+
token: this.jwt
174+
}
175+
})
176+
)
177+
.then(response => {
178+
Assert.equal(response.body.templateVersionId, this.templateId);
179+
})
167180
.then(() =>
168181
request({
169182
url: `${this.instance}/${this.namespace}/pipelines/${this.pipelineId}/jobs`,
@@ -174,20 +187,79 @@ Given(
174187
})
175188
)
176189
.then(response => {
177-
Assert.equal(response.body.length, 1);
178-
Assert.equal(response.body[0].templateId, this.templateId);
190+
this.jobs = Object.fromEntries(response.body.map(job => [job.name, job]));
179191
});
180192
}
181193
);
182194

183-
Given(/^user has some pipeline settings defined$/, function step() {
184-
Assert.equal(this.job.permutations[0].commands.length, 3);
185-
Assert.equal(this.job.permutations[0].image, 'node:20');
195+
Given(/^user defined shared settings$/, function step() {
196+
const job = this.jobs[this.jobName];
197+
198+
Assert.equal(Object.keys(this.jobs).length, 1);
199+
Assert.equal(job.permutations[0].image, 'node:20');
200+
Assert.equal(job.permutations[0].environment.FOO, 'bar');
201+
Assert.equal(job.permutations[0].environment.BAR, 'baz');
202+
Assert.equal(job.permutations[0].commands.length, 2);
203+
});
204+
205+
Given(/^the pipeline template has overwritten shared settings$/, function step() {
206+
const job = this.jobs[this.jobName];
207+
208+
Assert.notEqual(job.permutations[0].image, this.templateConfig.jobs[this.jobName].image);
209+
Assert.equal(Object.hasOwn(this.templateConfig.jobs[this.jobName].environment, 'BAR'), false);
186210
});
187211

188-
Given(/^the pipeline template has the same settings with different values$/, function step() {
189-
Assert.notEqual(this.job.permutations[0].commands.length, this.templateConfig.jobs[this.jobName].steps.length);
190-
Assert.notEqual(this.job.permutations[0].image, this.templateConfig.shared.image);
212+
Given(/^user defined exists jobs settings$/, function step() {
213+
const job = this.jobs[this.jobName];
214+
215+
Assert.equal(Object.keys(this.jobs).length, 1);
216+
Assert.equal(job.permutations[0].image, 'node:22');
217+
Assert.equal(job.permutations[0].annotations['screwdriver.cd/displayName'], 'foo-bar');
218+
Assert.equal(job.permutations[0].environment.FOO, 'bar');
219+
Assert.equal(job.permutations[0].environment.BAR, 'baz');
220+
Assert.equal(job.permutations[0].environment.BAZ, 'qux');
221+
Assert.equal(job.permutations[0].commands.length, 2);
222+
});
223+
224+
Given(/^the pipeline template has overwritten jobs settings$/, function step() {
225+
const job = this.jobs[this.jobName];
226+
227+
Assert.notEqual(job.permutations[0].image, this.templateConfig.jobs[this.jobName].image);
228+
Assert.isFalse(Object.hasOwn(this.templateConfig.jobs[this.jobName].environment, 'BAR'));
229+
Assert.isFalse(Object.hasOwn(this.templateConfig.jobs[this.jobName].environment, 'BAZ'));
230+
});
231+
232+
Given(/^user defined additional jobs settings$/, function step() {
233+
const existsJob = this.jobs[this.jobName];
234+
const userDefinedJob = this.jobs[this.additionalJobName];
235+
236+
Assert.equal(Object.keys(this.jobs).length, 2);
237+
Assert.equal(existsJob.permutations[0].image, 'node:22');
238+
Assert.equal(existsJob.permutations[0].annotations['screwdriver.cd/displayName'], 'foo-bar');
239+
Assert.equal(existsJob.permutations[0].environment.FOO, 'bar');
240+
Assert.equal(existsJob.permutations[0].environment.BAR, 'baz');
241+
Assert.equal(existsJob.permutations[0].environment.BAZ, 'qux');
242+
Assert.equal(existsJob.permutations[0].commands.length, 2);
243+
Assert.isFalse(Object.hasOwn(existsJob.permutations[0].environment, 'QUX'));
244+
245+
Assert.equal(userDefinedJob.permutations[0].image, 'node:23');
246+
Assert.equal(userDefinedJob.permutations[0].annotations['screwdriver.cd/displayName'], 'baz-qux');
247+
Assert.equal(userDefinedJob.permutations[0].environment.BAR, 'baz');
248+
Assert.equal(userDefinedJob.permutations[0].environment.QUX, 'quux');
249+
Assert.equal(userDefinedJob.permutations[0].commands.length, 3);
250+
Assert.isFalse(Object.hasOwn(userDefinedJob.permutations[0].environment, 'FOO'));
251+
Assert.isFalse(Object.hasOwn(userDefinedJob.permutations[0].environment, 'BAZ'));
252+
});
253+
254+
Given(/^the pipeline template has additional jobs settings$/, function step() {
255+
const existsJob = this.jobs[this.jobName];
256+
257+
Assert.notEqual(existsJob.permutations[0].image, this.templateConfig.jobs[this.jobName].image);
258+
Assert.isFalse(Object.hasOwn(this.templateConfig.jobs[this.jobName].environment, 'BAR'));
259+
Assert.isFalse(Object.hasOwn(this.templateConfig.jobs[this.jobName].environment, 'BAZ'));
260+
Assert.isFalse(Object.hasOwn(this.templateConfig.jobs[this.jobName].annotations, 'screwdriver.cd/displayName'));
261+
262+
Assert.isFalse(Object.hasOwn(this.templateConfig.jobs, this.additionalJobName));
191263
});
192264

193265
When(
@@ -242,7 +314,7 @@ When(
242314
);
243315

244316
When(
245-
/^user starts the pipeline that uses pipeline template$/,
317+
/^user starts the job that uses pipeline template$/,
246318
{
247319
timeout: TIMEOUT
248320
},
@@ -253,6 +325,144 @@ When(
253325
}
254326
);
255327

328+
When(
329+
/^user starts the additional job that uses pipeline template$/,
330+
{
331+
timeout: TIMEOUT
332+
},
333+
function step() {
334+
return this.startJob(this.additionalJobName).then(result => {
335+
Assert.oneOf(result, ['SUCCESS', 'FAILURE']);
336+
});
337+
}
338+
);
339+
340+
Then(
341+
/^job settings are the template command$/,
342+
{
343+
timeout: TIMEOUT
344+
},
345+
function step() {
346+
return request({
347+
url: `${this.instance}/${this.namespace}/builds/${this.buildId}/steps`,
348+
method: 'GET',
349+
context: {
350+
token: this.jwt
351+
}
352+
}).then(response => {
353+
Assert.equal(response.statusCode, 200);
354+
const steps = Object.fromEntries(
355+
response.body
356+
.filter(s => !s.name.startsWith('sd-setup') && !s.name.startsWith('sd-teardown'))
357+
.map(job => [job.name, job])
358+
);
359+
360+
const expectedSteps = [
361+
{
362+
name: 'pretest',
363+
command: "echo 'pretest'"
364+
},
365+
{
366+
name: 'test',
367+
command: 'echo $FOO'
368+
}
369+
];
370+
371+
Assert.equal(Object.keys(steps).length, expectedSteps.length);
372+
expectedSteps.forEach(expectedStep => {
373+
const result = steps[expectedStep.name];
374+
375+
Assert.equal(result.name, expectedStep.name);
376+
Assert.equal(result.command, expectedStep.command);
377+
});
378+
});
379+
}
380+
);
381+
382+
Then(
383+
/^job settings are the user command$/,
384+
{
385+
timeout: TIMEOUT
386+
},
387+
function step() {
388+
return request({
389+
url: `${this.instance}/${this.namespace}/builds/${this.buildId}/steps`,
390+
method: 'GET',
391+
context: {
392+
token: this.jwt
393+
}
394+
}).then(response => {
395+
Assert.equal(response.statusCode, 200);
396+
const steps = Object.fromEntries(
397+
response.body
398+
.filter(s => !s.name.startsWith('sd-setup') && !s.name.startsWith('sd-teardown'))
399+
.map(job => [job.name, job])
400+
);
401+
402+
const expectedSteps = [
403+
{
404+
name: 'pretest',
405+
command: "echo 'pretest'"
406+
},
407+
{
408+
name: 'test',
409+
command: 'echo $FOO'
410+
}
411+
];
412+
413+
Assert.equal(Object.keys(steps).length, expectedSteps.length);
414+
expectedSteps.forEach(expectedStep => {
415+
const result = steps[expectedStep.name];
416+
417+
Assert.equal(result.name, expectedStep.name);
418+
Assert.equal(result.command, expectedStep.command);
419+
});
420+
});
421+
}
422+
);
423+
424+
Then(
425+
/^additional job settings are the user command$/,
426+
{
427+
timeout: TIMEOUT
428+
},
429+
function step() {
430+
return request({
431+
url: `${this.instance}/${this.namespace}/builds/${this.buildId}/steps`,
432+
method: 'GET',
433+
context: {
434+
token: this.jwt
435+
}
436+
}).then(response => {
437+
Assert.equal(response.statusCode, 200);
438+
439+
const expectedSteps = [
440+
{
441+
name: 'pretest',
442+
command: "echo 'pretest'"
443+
},
444+
{
445+
name: 'test',
446+
command: 'echo $QUX'
447+
},
448+
{
449+
name: 'posttest',
450+
command: "echo 'posttest'"
451+
}
452+
];
453+
454+
expectedSteps.forEach(expectedStep => {
455+
const result = response.body.filter(s => {
456+
return s.name === expectedStep.name;
457+
})[0];
458+
459+
Assert.equal(result.name, expectedStep.name);
460+
Assert.include(result.command, expectedStep.command);
461+
});
462+
});
463+
}
464+
);
465+
256466
Then(/^they are notified pipeline template has (no|some) errors$/, function step(quantity) {
257467
switch (quantity) {
258468
case 'no':

0 commit comments

Comments
 (0)
Please sign in to comment.