Skip to content

Commit

Permalink
Merge pull request #3769 from johncowen/f-componentize-placement-fail…
Browse files Browse the repository at this point in the history
…ures

Component-ize UI for placement failures
  • Loading branch information
DingoEatingFuzz authored Jan 19, 2018
2 parents 7fe2993 + 74b14d0 commit 31a02f7
Show file tree
Hide file tree
Showing 5 changed files with 194 additions and 46 deletions.
40 changes: 40 additions & 0 deletions ui/app/templates/components/placement-failure.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
{{#if taskGroup.placementFailures}}
{{#with taskGroup.placementFailures as |failures|}}
<h3 class="title is-5" data-test-placement-failure-task-group>
{{taskGroup.name}}
<span class="badge is-light" data-test-placement-failure-coalesced-failures>{{inc failures.coalescedFailures}} unplaced</span>
</h3>
<ul class="simple-list">
{{#if (eq failures.nodesEvaluated 0)}}
<li data-test-placement-failure-no-evaluated-nodes>No nodes were eligible for evaluation</li>
{{/if}}
{{#each-in failures.nodesAvailable as |datacenter available|}}
{{#if (eq available 0)}}
<li data-test-placement-failure-no-nodes-available="{{datacenter}}">No nodes are available in datacenter {{datacenter}}</li>
{{/if}}
{{/each-in}}
{{#each-in failures.classFiltered as |class count|}}
<li data-test-placement-failure-class-filtered="{{class}}">Class {{class}} filtered {{count}} {{pluralize "node" count}}</li>
{{/each-in}}
{{#each-in failures.constraintFiltered as |constraint count|}}
<li data-test-placement-failure-constraint-filtered="{{constraint}}">Constraint <code>{{constraint}}</code> filtered {{count}} {{pluralize "node" count}}</li>
{{/each-in}}
{{#if failures.nodesExhausted}}
<li data-test-placement-failure-nodes-exhausted>Resources exhausted on {{failures.nodesExhausted}} {{pluralize "node" failures.nodesExhausted}}</li>
{{/if}}
{{#each-in failures.classExhausted as |class count|}}
<li data-test-placement-failure-class-exhausted="{{class}}">Class {{class}} exhausted on {{count}} {{pluralize "node" count}}</li>
{{/each-in}}
{{#each-in failures.dimensionExhausted as |dimension count|}}
<li data-test-placement-failure-dimension-exhausted="{{dimension}}">Dimension {{dimension}} exhausted on {{count}} {{pluralize "node" count}}</li>
{{/each-in}}
{{#each-in failures.quotaExhausted as |quota dimension|}}
<li data-test-placement-failure-quota-exhausted="{{quota}}">Quota limit hit {{dimension}}</li>
{{/each-in}}
{{#each-in failures.scores as |name score|}}
<li data-test-placement-failure-scores="{{name}}">Score {{name}} = {{score}}</li>
{{/each-in}}
</ul>
{{/with}}
{{/if}}

40 changes: 1 addition & 39 deletions ui/app/templates/jobs/job/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -56,45 +56,7 @@
</div>
<div class="boxed-section-body">
{{#each model.taskGroups as |taskGroup|}}
{{#if taskGroup.placementFailures}}
{{#with taskGroup.placementFailures as |failures|}}
<h3 class="title is-5" data-test-placement-failure-task-group>
{{taskGroup.name}}
<span class="badge is-light">{{inc failures.coalescedFailures}} unplaced</span>
</h3>
<ul class="simple-list">
{{#if (eq failures.nodesEvaluated 0)}}
<li>No nodes were eligible for evaluation</li>
{{/if}}
{{#each-in failures.nodesAvailable as |datacenter available|}}
{{#if (eq available 0)}}
<li>No nodes are available in datacenter {{datacenter}}</li>
{{/if}}
{{/each-in}}
{{#each-in failures.classFiltered as |class count|}}
<li>Class {{class}} filtered {{count}} {{pluralize "node" count}}</li>
{{/each-in}}
{{#each-in failures.constraintFiltered as |constraint count|}}
<li>Constraint <code>{{constraint}}</code> filtered {{count}} {{pluralize "node" count}}</li>
{{/each-in}}
{{#if failures.nodesExhausted}}
<li>Resources exhausted on {{failures.nodesExhausted}} {{pluralize "node" failures.nodesExhausted}}</li>
{{/if}}
{{#each-in failures.classExhausted as |class count|}}
<li>Class {{class}} exhausted on {{count}} {{pluralize "node" count}}</li>
{{/each-in}}
{{#each-in failures.dimensionExhausted as |dimension count|}}
<li>Dimension {{dimension}} exhausted on {{count}} {{pluralize "node" count}}</li>
{{/each-in}}
{{#each-in failures.quotaExhausted as |quota dimension|}}
<li>Quota limit hit {{dimension}}</li>
{{/each-in}}
{{#each-in failures.scores as |name score|}}
<li>Score {{name}} = {{score}}</li>
{{/each-in}}
</ul>
{{/with}}
{{/if}}
{{placement-failure taskGroup=taskGroup}}
{{/each}}
</div>
</div>
Expand Down
8 changes: 1 addition & 7 deletions ui/tests/integration/job-diff-test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { findAll, find } from 'ember-native-dom-helpers';
import { test, moduleForComponent } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';
import cleanWhitespace from '../utils/clean-whitespace';

moduleForComponent('job-diff', 'Integration | Component | job diff', {
integration: true,
Expand Down Expand Up @@ -192,10 +193,3 @@ function field(name, type, newVal, oldVal) {
Name: name,
};
}

function cleanWhitespace(string) {
return string
.replace(/\n/g, '')
.replace(/ +/g, ' ')
.trim();
}
144 changes: 144 additions & 0 deletions ui/tests/integration/placement-failure-test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { find, findAll } from 'ember-native-dom-helpers';
import { test, moduleForComponent } from 'ember-qunit';
import { assign } from '@ember/polyfills';
import hbs from 'htmlbars-inline-precompile';
import cleanWhitespace from '../utils/clean-whitespace';

moduleForComponent('placement-failure', 'Integration | Component | placement failures', {
integration: true,
});

const commonTemplate = hbs`
{{placement-failure taskGroup=taskGroup}}
`;

test('should render the placement failure (basic render)', function(assert) {
const name = 'Placement Failure';
const failures = 11;
this.set(
'taskGroup',
createFixture(
{
coalescedFailures: failures - 1
},
name
)
);

this.render(commonTemplate);

assert.equal(
cleanWhitespace(find('[data-test-placement-failure-task-group]').firstChild.wholeText),
name,
'Title is rendered with the name of the placement failure'
);
assert.equal(
parseInt(find('[data-test-placement-failure-coalesced-failures]').textContent),
failures,
'Title is rendered correctly with a count of unplaced'
);
assert.equal(
findAll('[data-test-placement-failure-no-evaluated-nodes]').length,
1,
'No evaluated nodes message shown'
);
assert.equal(
findAll('[data-test-placement-failure-no-nodes-available]').length,
1,
'No nodes in datacenter message shown'
);
assert.equal(
findAll('[data-test-placement-failure-class-filtered]').length,
1,
'Class filtered message shown'
);
assert.equal(
findAll('[data-test-placement-failure-constraint-filtered]').length,
1,
'Constraint filtered message shown'
);
assert.equal(
findAll('[data-test-placement-failure-nodes-exhausted]').length,
1,
'Node exhausted message shown'
);
assert.equal(
findAll('[data-test-placement-failure-class-exhausted]').length,
1,
'Class exhausted message shown'
);
assert.equal(
findAll('[data-test-placement-failure-dimension-exhausted]').length,
1,
'Dimension exhausted message shown'
);
assert.equal(
findAll('[data-test-placement-failure-quota-exhausted]').length,
1,
'Quota exhausted message shown'
);
assert.equal(
findAll('[data-test-placement-failure-scores]').length,
1,
'Scores message shown'
);
});

test('should render correctly when a node is not evaluated', function(assert) {
this.set(
'taskGroup',
createFixture(
{
nodesEvaluated: 1,
nodesExhausted: 0
}
)
);

this.render(commonTemplate);

assert.equal(
findAll('[data-test-placement-failure-no-evaluated-nodes]').length,
0,
'No evaluated nodes message shown'
);
assert.equal(
findAll('[data-test-placement-failure-nodes-exhausted]').length,
0,
'Nodes exhausted message NOT shown when there are no nodes exausted'
);
});

function createFixture(obj = {}, name = 'Placement Failure') {
return {
name: name,
placementFailures: assign({
coalescedFailures: 10,
nodesEvaluated: 0,
nodesAvailable: {
datacenter: 0,
},
classFiltered: {
filtered: 1,
},
constraintFiltered: {
'prop = val': 1,
},
nodesExhausted: 3,
classExhausted: {
class: 3,
},
dimensionExhausted: {
iops: 3,
},
quotaExhausted: {
quota: 'dimension',
},
scores: {
name: 3,
},
},
obj
)
};
}
8 changes: 8 additions & 0 deletions ui/tests/utils/clean-whitespace.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// cleans whitespace from a string, for example for cleaning
// textContent in DOM nodes with indentation
export default function cleanWhitespace(string) {
return string
.replace(/\n/g, '')
.replace(/ +/g, ' ')
.trim();
}

0 comments on commit 31a02f7

Please sign in to comment.