Skip to content

Commit 94df7bc

Browse files
Integration tests for the various reschedule events timeline permutations
1 parent 658c842 commit 94df7bc

File tree

5 files changed

+213
-14
lines changed

5 files changed

+213
-14
lines changed

ui/app/components/allocation-row.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ export default Component.extend({
2424
stats: null,
2525
statsError: false,
2626

27-
// enablePolling: computed(() => !Ember.testing),
28-
enablePolling: false,
27+
enablePolling: computed(() => !Ember.testing),
2928

3029
onClick() {},
3130

ui/app/templates/components/reschedule-event-row.hbs

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
<li class="timeline-note">
2+
{{#if label}}
3+
<strong data-test-reschedule-label>{{label}}</strong>
4+
{{/if}}
25
{{moment-format time "MMMM D, YYYY HH:mm:ss"}}
36
</li>
4-
<li class="timeline-object">
7+
<li class="timeline-object" data-test-allocation={{allocation.id}}>
58
<div class="boxed-section">
69
{{#unless linkToAllocation}}
7-
<div class="boxed-section-head">
10+
<div class="boxed-section-head" data-test-row-heading>
811
This Allocation
912
</div>
1013
{{/unless}}
1114
<div class="boxed-section-body inline-definitions">
1215
<div class="columns">
1316
<div class="column is-centered is-minimum">
14-
<span class="tag {{allocation.statusClass}}">
17+
<span data-test-allocation-status class="tag {{allocation.statusClass}}">
1518
{{allocation.clientStatus}}
1619
</span>
1720
</div>
@@ -21,16 +24,16 @@
2124
<span class="term">Allocation</span>
2225
{{#if linkToAllocation}}
2326
{{#link-to "allocations.allocation" allocation.id}}
24-
<code>{{allocation.shortId}}</code>
27+
<code data-test-allocation-link>{{allocation.shortId}}</code>
2528
{{/link-to}}
2629
{{else}}
27-
<code>{{allocation.shortId}}</code>
30+
<code data-test-allocation-link>{{allocation.shortId}}</code>
2831
{{/if}}
2932
</span>
3033
<span class="pair">
3134
<span class="term">Client</span>
3235
<span>
33-
{{#link-to "clients.client" allocation.node.id}}
36+
{{#link-to "clients.client" data-test-node-link allocation.node.id}}
3437
<code>{{allocation.node.id}}</code>
3538
{{/link-to}}
3639
</span>

ui/app/templates/components/reschedule-event-timeline.hbs

+2-3
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,17 @@
66
time=allocation.nextAllocation.modifyTime}}
77
{{/if}}
88
{{#if allocation.hasStoppedRescheduling}}
9-
<li class="timeline-note">
9+
<li class="timeline-note" data-test-stop-warning>
1010
{{x-icon "warning" class="is-warning is-text"}} Nomad has stopped attempting to reschedule this allocation.
1111
</li>
1212
{{/if}}
1313
{{#if (and allocation.followUpEvaluation.waitUntil (not allocation.nextAllocation))}}
14-
<li class="timeline-note">
14+
<li class="timeline-note" data-test-attempt-notice>
1515
{{x-icon "clock" class="is-info is-text"}} Nomad will attempt to reschedule
1616
{{moment-from-now allocation.followUpEvaluation.waitUntil interval=1000}}
1717
</li>
1818
{{/if}}
1919
{{reschedule-event-row
20-
label="This Allocation"
2120
allocation=allocation
2221
linkToAllocation=false
2322
time=allocation.modifyTime}}

ui/mirage/factories/allocation.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ export default Factory.extend({
6666
// After rescheduleAttempts hits zero, a final allocation is made with no nextAllocation and
6767
// a clientStatus of failed or running, depending on rescheduleSuccess
6868
afterCreate(allocation, server) {
69-
const attempts = allocation.rescheduleAttempts;
69+
const attempts = allocation.rescheduleAttempts - 1;
7070
const previousEvents =
7171
(allocation.rescheduleTracker && allocation.rescheduleTracker.Events) || [];
7272

@@ -91,9 +91,9 @@ export default Factory.extend({
9191
};
9292

9393
let nextAllocation;
94-
if (attempts) {
94+
if (attempts > 0) {
9595
nextAllocation = server.create('allocation', 'rescheduled', {
96-
rescheduleAttempts: Math.max(attempts - 1, 0),
96+
rescheduleAttempts: Math.max(attempts, 0),
9797
rescheduleSuccess: allocation.rescheduleSuccess,
9898
previousAllocation: allocation.id,
9999
clientStatus: 'failed',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
import { getOwner } from '@ember/application';
2+
import { test, moduleForComponent } from 'ember-qunit';
3+
import { find, findAll } from 'ember-native-dom-helpers';
4+
import { startMirage } from 'nomad-ui/initializers/ember-cli-mirage';
5+
import wait from 'ember-test-helpers/wait';
6+
import hbs from 'htmlbars-inline-precompile';
7+
import moment from 'moment';
8+
9+
moduleForComponent(
10+
'reschedule-event-timeline',
11+
'Integration | Component | reschedule event timeline',
12+
{
13+
integration: true,
14+
beforeEach() {
15+
this.store = getOwner(this).lookup('service:store');
16+
this.server = startMirage();
17+
this.server.create('namespace');
18+
this.server.create('node');
19+
this.server.create('job', { createAllocations: false });
20+
},
21+
afterEach() {
22+
this.server.shutdown();
23+
},
24+
}
25+
);
26+
27+
const commonTemplate = hbs`
28+
{{reschedule-event-timeline allocation=allocation}}
29+
`;
30+
31+
test('when the allocation is running, the timeline shows past allocations', function(assert) {
32+
const attempts = 2;
33+
34+
this.server.create('allocation', 'rescheduled', {
35+
rescheduleAttempts: attempts,
36+
rescheduleSuccess: true,
37+
});
38+
39+
this.store.findAll('allocation');
40+
let allocation;
41+
42+
return wait()
43+
.then(() => {
44+
allocation = this.store
45+
.peekAll('allocation')
46+
.find(alloc => !alloc.get('nextAllocation.content'));
47+
48+
this.set('allocation', allocation);
49+
this.render(commonTemplate);
50+
51+
return wait();
52+
})
53+
.then(() => {
54+
assert.equal(
55+
findAll('[data-test-allocation]').length,
56+
attempts + 1,
57+
'Total allocations equals current allocation plus all past allocations'
58+
);
59+
assert.equal(
60+
find('[data-test-allocation]'),
61+
find(`[data-test-allocation="${allocation.id}"]`),
62+
'First allocation is the current allocation'
63+
);
64+
65+
assert.notOk(find('[data-test-stop-warning]'), 'No stop warning');
66+
assert.notOk(find('[data-test-attempt-notice]'), 'No attempt notice');
67+
68+
assert.equal(
69+
find(
70+
`[data-test-allocation="${allocation.id}"] [data-test-allocation-link]`
71+
).textContent.trim(),
72+
allocation.get('shortId'),
73+
'The "this" allocation is correct'
74+
);
75+
assert.equal(
76+
find(
77+
`[data-test-allocation="${allocation.id}"] [data-test-allocation-status]`
78+
).textContent.trim(),
79+
allocation.get('clientStatus'),
80+
'Allocation shows the status'
81+
);
82+
});
83+
});
84+
85+
test('when the allocation has failed and there is a follow up evaluation, a note with a time is shown', function(assert) {
86+
const attempts = 2;
87+
88+
this.server.create('allocation', 'rescheduled', {
89+
rescheduleAttempts: attempts,
90+
rescheduleSuccess: false,
91+
});
92+
93+
this.store.findAll('allocation');
94+
let allocation;
95+
96+
return wait()
97+
.then(() => {
98+
allocation = this.store
99+
.peekAll('allocation')
100+
.find(alloc => !alloc.get('nextAllocation.content'));
101+
102+
this.set('allocation', allocation);
103+
this.render(commonTemplate);
104+
105+
return wait();
106+
})
107+
.then(() => {
108+
assert.ok(
109+
find('[data-test-stop-warning]'),
110+
'Stop warning is shown since the last allocation failed'
111+
);
112+
assert.notOk(find('[data-test-attempt-notice]'), 'Reschdule attempt notice is not shown');
113+
});
114+
});
115+
116+
test('when the allocation has failed and there is no follow up evaluation, a warning is shown', function(assert) {
117+
const attempts = 2;
118+
119+
this.server.create('allocation', 'rescheduled', {
120+
rescheduleAttempts: attempts,
121+
rescheduleSuccess: false,
122+
});
123+
124+
const lastAllocation = server.schema.allocations.findBy({ nextAllocation: undefined });
125+
lastAllocation.update({
126+
followupEvalId: server.create('evaluation', {
127+
waitUntil: moment()
128+
.add(2, 'hours')
129+
.toDate(),
130+
}).id,
131+
});
132+
133+
this.store.findAll('allocation');
134+
let allocation;
135+
136+
return wait()
137+
.then(() => {
138+
allocation = this.store
139+
.peekAll('allocation')
140+
.find(alloc => !alloc.get('nextAllocation.content'));
141+
142+
this.set('allocation', allocation);
143+
this.render(commonTemplate);
144+
145+
return wait();
146+
})
147+
.then(() => {
148+
assert.ok(
149+
find('[data-test-attempt-notice]'),
150+
'Reschedule notice is shown since the follow up eval says so'
151+
);
152+
assert.notOk(find('[data-test-stop-warning]'), 'Stop warning is not shown');
153+
});
154+
});
155+
156+
test('when the allocation has a next allocation already, it is shown in the timeline', function(assert) {
157+
const attempts = 2;
158+
159+
const originalAllocation = this.server.create('allocation', 'rescheduled', {
160+
rescheduleAttempts: attempts,
161+
rescheduleSuccess: true,
162+
});
163+
164+
this.store.findAll('allocation');
165+
let allocation;
166+
167+
return wait()
168+
.then(() => {
169+
allocation = this.store.peekAll('allocation').findBy('id', originalAllocation.id);
170+
171+
this.set('allocation', allocation);
172+
this.render(commonTemplate);
173+
174+
return wait();
175+
})
176+
.then(() => {
177+
assert.ok(
178+
find('[data-test-reschedule-label]').textContent.trim(),
179+
'Next Allocation',
180+
'The first allocation is the next allocation and labeled as such'
181+
);
182+
183+
assert.equal(
184+
find('[data-test-allocation] [data-test-allocation-link]').textContent.trim(),
185+
allocation.get('nextAllocation.shortId'),
186+
'The next allocation item is for the correct allocation'
187+
);
188+
189+
assert.equal(
190+
findAll('[data-test-allocation]')[1],
191+
find(`[data-test-allocation="${allocation.id}"]`),
192+
'Second allocation is the current allocation'
193+
);
194+
195+
assert.notOk(find('[data-test-stop-warning]'), 'No stop warning');
196+
assert.notOk(find('[data-test-attempt-notice]'), 'No attempt notice');
197+
});
198+
});

0 commit comments

Comments
 (0)