Separate OSTF tests running
Closes-bp: https://blueprints.launchpad.net/fuel/+spec/ui-ostf-separate-test-run Change-Id: I712abb487f990380c2f7c3a82b6403a894fc12ec
This commit is contained in:
parent
8e50e545b2
commit
fd42047aef
@ -4126,6 +4126,7 @@ input.input-append {
|
||||
.healthcheck-table {margin: 0px 0px 30px 0px; }
|
||||
.healthcheck-table th {font-weight: normal;}
|
||||
.healthcheck-table th label {margin: 0;}
|
||||
.healthcheck-table th label.testset-name {font-weight: bold;}
|
||||
.healthcheck-name {font-size: 15px; margin: 5px 0px 5px 0px;}
|
||||
.healthcheck-duration {font-size: 15px; margin: 5px 0px 5px 0px; text-align: center; color: #777777}
|
||||
.healthcheck-status {font-size: 20px; margin-top: 3px; text-align: center;}
|
||||
@ -4136,9 +4137,11 @@ input.input-append {
|
||||
.healthcheck-status-stopped, .healthcheck-status-unknown, .healthcheck-status-wait_running {color: #999999;}
|
||||
.healthcheck-status-success {color: #2e8701;}
|
||||
.healthcheck-status-failure, .healthcheck-status-error {color: #890000;}
|
||||
.healthcheck-table .healthcheck-col-select {width: 24px;}
|
||||
.healthcheck-table .healthcheck-col-status {width: 50px; text-align: center;}
|
||||
.healthcheck-table .healthcheck-col-duration {width: 120px; text-align: center;}
|
||||
.healthcheck-table th.healthcheck-col-duration, .healthcheck-table th.healthcheck-col-status {padding: 12px 0 12px 0;}
|
||||
.healthcheck-table th {padding-top: 12px; padding-bottom: 12px;}
|
||||
.healthcheck-table th.healthcheck-col-select {padding-top: 0; padding-bottom: 10px;}
|
||||
|
||||
/* Cluster toolbar */
|
||||
.cluster-toolbar {
|
||||
|
@ -26,39 +26,31 @@ define(
|
||||
function(utils, models, commonViews, dialogViews, healthcheckTabTemplate, healthcheckTestSetTemplate, healthcheckTestsTemplate) {
|
||||
'use strict';
|
||||
|
||||
var HealthCheckTab, TestSet;
|
||||
var HealthCheckTab, TestSet, Test;
|
||||
|
||||
HealthCheckTab = commonViews.Tab.extend({
|
||||
template: _.template(healthcheckTabTemplate),
|
||||
updateInterval: 3000,
|
||||
events: {
|
||||
'change input.testset-select': 'testSetSelected',
|
||||
'change input.select-all-tumbler': 'allTestSetsSelected',
|
||||
'click .run-tests-btn:not(:disabled)': 'runTests',
|
||||
'click .stop-tests-btn:not(:disabled)': 'stopTests'
|
||||
},
|
||||
getNumberOfCheckedTests: function() {
|
||||
return this.tests.where({checked: true}).length;
|
||||
},
|
||||
isLocked: function() {
|
||||
return this.model.get('status') == 'new' || this.hasRunningTests() || !!this.model.task('deploy', 'running') ;
|
||||
},
|
||||
disableControls: function(disable) {
|
||||
this.$('.btn, input').prop('disabled', disable || this.isLocked());
|
||||
var disabledState = disable || this.isLocked();
|
||||
this.runTestsButton.set({disabled: disabledState || !this.getNumberOfCheckedTests()});
|
||||
this.stopTestsButton.set({disabled: !this.hasRunningTests()});
|
||||
this.selectAllCheckbox.set({disabled: disabledState});
|
||||
},
|
||||
calculateTestControlButtonsState: function() {
|
||||
toggleTestsVisibility: function() {
|
||||
var hasRunningTests = this.hasRunningTests();
|
||||
this.$('.run-tests-btn').prop('disabled', !this.$('input.testset-select:checked').length || hasRunningTests).toggle(!hasRunningTests);
|
||||
this.$('.stop-tests-btn').prop('disabled', !hasRunningTests).toggle(hasRunningTests);
|
||||
},
|
||||
calculateSelectAllTumblerState: function() {
|
||||
this.$('.select-all-tumbler').prop('checked', this.$('input.testset-select:checked').length == this.$('input.testset-select').length);
|
||||
},
|
||||
allTestSetsSelected: function(e) {
|
||||
var checked = $(e.currentTarget).is(':checked');
|
||||
this.$('input.testset-select').prop('checked', checked);
|
||||
this.calculateTestControlButtonsState();
|
||||
},
|
||||
testSetSelected: function() {
|
||||
this.calculateSelectAllTumblerState();
|
||||
this.calculateTestControlButtonsState();
|
||||
this.runTestsButton.set({visible: !hasRunningTests});
|
||||
this.stopTestsButton.set({visible: hasRunningTests});
|
||||
},
|
||||
getActiveTestRuns: function() {
|
||||
return this.testruns.where({status: 'running'});
|
||||
@ -70,36 +62,60 @@ function(utils, models, commonViews, dialogViews, healthcheckTabTemplate, health
|
||||
if (this.hasRunningTests()) {
|
||||
this.registerDeferred(this.timeout = $.timeout(this.updateInterval).done(_.bind(this.update, this)));
|
||||
}
|
||||
this.toggleTestsVisibility();
|
||||
this.disableControls();
|
||||
},
|
||||
update: function() {
|
||||
this.registerDeferred(
|
||||
this.testruns.fetch()
|
||||
.done(_.bind(function() {
|
||||
if (!this.hasRunningTests()) {
|
||||
this.$('input[type=checkbox]').prop('checked', false);
|
||||
this.disableControls(false);
|
||||
}
|
||||
this.calculateTestControlButtonsState();
|
||||
}, this))
|
||||
.always(_.bind(this.scheduleUpdate, this))
|
||||
);
|
||||
},
|
||||
runTests: function() {
|
||||
this.disableControls(true);
|
||||
var testruns = new models.TestRuns();
|
||||
var testruns = new models.TestRuns(),
|
||||
oldTestruns = new models.TestRuns();
|
||||
_.each(this.subViews, function(subView) {
|
||||
if (subView instanceof TestSet && subView.$('input.testset-select:checked').length) {
|
||||
var testrun = new models.TestRun({
|
||||
var selectedTests = subView.tests.where({checked: true});
|
||||
if (selectedTests.length) {
|
||||
var selectedTestIds = _.pluck(selectedTests, 'id');
|
||||
var currentTestrun = new models.TestRun({
|
||||
testset: subView.testset.id,
|
||||
metadata: {
|
||||
config: {},
|
||||
cluster_id: this.model.id
|
||||
}
|
||||
},
|
||||
tests: selectedTestIds
|
||||
});
|
||||
testruns.add(testrun);
|
||||
var currentTestForReRun = new models.TestRun({
|
||||
id: subView.testrun.id,
|
||||
tests: selectedTestIds,
|
||||
status: 'restarted'
|
||||
});
|
||||
if (this.testruns.length != 0) {
|
||||
if (this.testruns.where({testset: subView.testset.id}).length) {
|
||||
oldTestruns.add(currentTestForReRun);
|
||||
} else {
|
||||
testruns.add(currentTestrun);
|
||||
}
|
||||
} else {
|
||||
testruns.add(currentTestrun);
|
||||
}
|
||||
}
|
||||
}, this);
|
||||
Backbone.sync('create', testruns).done(_.bind(this.update, this));
|
||||
var requests = [];
|
||||
if (testruns.models.length) {
|
||||
requests.push(Backbone.sync('create', testruns));
|
||||
}
|
||||
if (oldTestruns.models.length) {
|
||||
requests.push(Backbone.sync('update', oldTestruns));
|
||||
}
|
||||
$.when.apply($, requests).done(_.bind(this.update, this));
|
||||
},
|
||||
stopTests: function() {
|
||||
var testruns = new models.TestRuns(this.getActiveTestRuns());
|
||||
@ -137,9 +153,27 @@ function(utils, models, commonViews, dialogViews, healthcheckTabTemplate, health
|
||||
},
|
||||
initialize: function(options) {
|
||||
_.defaults(this, options);
|
||||
this.runTestsButton = new Backbone.Model({
|
||||
visible: true,
|
||||
disabled: true
|
||||
});
|
||||
this.stopTestsButton = new Backbone.Model({
|
||||
visible: false,
|
||||
disabled: true
|
||||
});
|
||||
this.selectAllCheckbox = new Backbone.Model({
|
||||
checked: false,
|
||||
disabled: false
|
||||
});
|
||||
this.model.on('change:status', this.render, this);
|
||||
this.model.get('tasks').each(this.bindTaskEvents, this);
|
||||
this.model.get('tasks').on('add', this.onNewTask, this);
|
||||
this.selectAllCheckbox.on('change:disabled', _.bind(function(model, value) {
|
||||
_.each(this.subViews, function(testSetView) {
|
||||
testSetView.selectAllCheckbox.set({disabled: value});
|
||||
}, this);
|
||||
this.tests.invoke('set', {disabled: value});
|
||||
}, this));
|
||||
if (!this.model.get('ostf')) {
|
||||
var ostf = {};
|
||||
ostf.testsets = new models.TestSets();
|
||||
@ -154,7 +188,7 @@ function(utils, models, commonViews, dialogViews, healthcheckTabTemplate, health
|
||||
this.tests.fetch(),
|
||||
this.testruns.fetch()
|
||||
).done(_.bind(function() {
|
||||
this.model.set({'ostf': ostf}, {silent: true});
|
||||
this.model.set({ostf: ostf}, {silent: true});
|
||||
this.render();
|
||||
this.scheduleUpdate();
|
||||
}, this)
|
||||
@ -170,6 +204,40 @@ function(utils, models, commonViews, dialogViews, healthcheckTabTemplate, health
|
||||
}
|
||||
this.testruns.on('sync', this.updateTestRuns, this);
|
||||
},
|
||||
initStickitBindings: function() {
|
||||
var visibleBindings = {
|
||||
observe: 'visible',
|
||||
visible: true
|
||||
};
|
||||
var disabledBindings = {
|
||||
attributes: [
|
||||
{
|
||||
name: 'disabled',
|
||||
observe: 'disabled'
|
||||
}
|
||||
]
|
||||
};
|
||||
this.stickit(this.runTestsButton, {'.run-tests-btn': _.extend({}, visibleBindings, disabledBindings)});
|
||||
this.stickit(this.stopTestsButton, {'.stop-tests-btn': _.extend({}, visibleBindings, disabledBindings)});
|
||||
var bindings = {
|
||||
'.select-all-tumbler': {
|
||||
observe: 'checked',
|
||||
onSet: _.bind(function(value) {
|
||||
_.each(this.subViews, function(testSetView) {
|
||||
testSetView.selectAllCheckbox.set({checked: value});
|
||||
});
|
||||
this.tests.invoke('set', {checked: value});
|
||||
}, this),
|
||||
attributes: [
|
||||
{
|
||||
name: 'disabled',
|
||||
observe: 'disabled'
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
this.stickit(this.selectAllCheckbox, bindings);
|
||||
},
|
||||
render: function() {
|
||||
this.tearDownRegisteredSubViews();
|
||||
this.$el.html(this.template({cluster: this.model})).i18n();
|
||||
@ -186,16 +254,15 @@ function(utils, models, commonViews, dialogViews, healthcheckTabTemplate, health
|
||||
this.registerSubView(testsetView);
|
||||
this.$('.testsets').append(testsetView.render().el);
|
||||
}, this);
|
||||
this.disableControls();
|
||||
}
|
||||
this.disableControls(false);
|
||||
this.calculateTestControlButtonsState();
|
||||
this.initStickitBindings();
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
TestSet = Backbone.View.extend({
|
||||
template: _.template(healthcheckTestSetTemplate),
|
||||
testsTemplate: _.template(healthcheckTestsTemplate),
|
||||
templateHelpers: _.extend(_.pick(utils, 'linebreaks'), {highlightStep: function(text, step) {
|
||||
var lines = text.split('\n');
|
||||
var rx = new RegExp('^\\s*' + step + '\\.');
|
||||
@ -206,16 +273,85 @@ function(utils, models, commonViews, dialogViews, healthcheckTabTemplate, health
|
||||
});
|
||||
return lines.join('\n');
|
||||
}}),
|
||||
calculateSelectAllCheckedState: function() {
|
||||
this.selectAllCheckbox.set({checked: this.tests.where({checked: true}).length == this.tests.length});
|
||||
this.tab.selectAllCheckbox.set({checked: this.tab.getNumberOfCheckedTests() == this.tab.tests.length});
|
||||
},
|
||||
initialize: function(options) {
|
||||
_.defaults(this, options);
|
||||
this.selectAllCheckbox = new Backbone.Model({
|
||||
checked: false,
|
||||
disabled: false
|
||||
});
|
||||
this.testrun.on('change', this.renderTests, this);
|
||||
this.tests.invoke('set', {disabled: false});
|
||||
this.tests.on('change:checked', _.bind(function() {
|
||||
this.calculateSelectAllCheckedState();
|
||||
this.tab.disableControls();
|
||||
}, this));
|
||||
},
|
||||
renderTests: function() {
|
||||
this.$('tbody').html(this.testsTemplate(_.extend({testrun: this.testrun, tests: this.tests}, this.templateHelpers))).i18n();
|
||||
this.$('tbody').empty();
|
||||
this.tests.each(function(test, index) {
|
||||
var testView = new Test({
|
||||
testset: this,
|
||||
tab: this.tab,
|
||||
testrun: this.testrun,
|
||||
model: test,
|
||||
testIndex: index
|
||||
});
|
||||
this.$('tbody').append(testView.render().el);
|
||||
}, this);
|
||||
},
|
||||
initStickitBindings: function() {
|
||||
var bindings = {
|
||||
'.testset-select': {
|
||||
observe: 'checked',
|
||||
onSet: _.bind(function(value) {
|
||||
this.tests.invoke('set', {checked: value});
|
||||
}, this),
|
||||
attributes: [{
|
||||
name: 'disabled',
|
||||
observe: 'disabled'
|
||||
}]
|
||||
}
|
||||
};
|
||||
this.stickit(this.selectAllCheckbox, bindings);
|
||||
},
|
||||
render: function() {
|
||||
this.$el.html(this.template({testset: this.testset})).i18n();
|
||||
this.renderTests();
|
||||
this.initStickitBindings();
|
||||
this.calculateSelectAllCheckedState();
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
||||
Test = Backbone.View.extend({
|
||||
template: _.template(healthcheckTestsTemplate),
|
||||
tagName: 'tr',
|
||||
initStickitBindings: function() {
|
||||
var bindings = {
|
||||
'.test-select': {
|
||||
observe: 'checked',
|
||||
attributes: [{
|
||||
name: 'disabled',
|
||||
observe: 'disabled'
|
||||
}]
|
||||
}
|
||||
};
|
||||
this.stickit(this.model, bindings);
|
||||
},
|
||||
initialize: function(options) {
|
||||
_.defaults(this, options);
|
||||
},
|
||||
render: function() {
|
||||
this.$el.html(this.template(_.extend({
|
||||
testrun: this.testrun,
|
||||
test: this.model,
|
||||
testIndex: this.testIndex
|
||||
}, this.testset.templateHelpers))).i18n();
|
||||
this.initStickitBindings();
|
||||
return this;
|
||||
}
|
||||
});
|
||||
|
@ -7,7 +7,7 @@
|
||||
</label>
|
||||
</div>
|
||||
<div class="span2">
|
||||
<button class="btn btn-success pull-right action-btn run-tests-btn" data-i18n="cluster_page.healthcheck_tab.run_tests_button" disabled> </button>
|
||||
<button class="btn btn-success pull-right action-btn run-tests-btn" data-i18n="cluster_page.healthcheck_tab.run_tests_button"></button>
|
||||
<button class="btn btn-danger pull-right action-btn stop-tests-btn hide" data-i18n="cluster_page.healthcheck_tab.stop_tests_button"></button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,9 +1,17 @@
|
||||
<% tests.each(function(test) { %>
|
||||
<% var result = testrun && _.find(testrun.get('tests'), {id: test.id}) %>
|
||||
<% var status = result && result.status || 'unknown' %>
|
||||
<tr>
|
||||
<td class="healthcheck-col-select">
|
||||
<div class="custom-tumbler">
|
||||
<label>
|
||||
<input type="checkbox" class="test-select" id="test-select-<%- test.get('testset') %>-<%= testIndex %>">
|
||||
<!-- [if !IE |(gte IE 9)]> --><span> </span><!-- <![endif] -->
|
||||
</label>
|
||||
</div>
|
||||
</td>
|
||||
<td>
|
||||
<div class="healthcheck-name"><%- test.get('name') %></div>
|
||||
<div class="healthcheck-name">
|
||||
<label for="test-select-<%- test.get('testset') %>-<%= testIndex %>"><%- test.get('name') %></label>
|
||||
</div>
|
||||
<% if (status == 'failure' || status == 'error' || status == 'skipped') { %>
|
||||
<div class="healthcheck-msg healthcheck-status-failure">
|
||||
<% if (result && result.message) { %>
|
||||
@ -44,5 +52,3 @@
|
||||
<% } %>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
<% }) %>
|
@ -2,16 +2,16 @@
|
||||
<table class="table table-bordered healthcheck-table enable-selection">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>
|
||||
<label class="parameter-box clearfix">
|
||||
<div class="parameter-control">
|
||||
<th class="healthcheck-col-select">
|
||||
<div class="custom-tumbler">
|
||||
<input type="checkbox" class="testset-select" name="<%- testset.id %>" />
|
||||
<label>
|
||||
<input type="checkbox" class="testset-select" id="testset-select-<%- testset.id %>">
|
||||
<!-- [if !IE |(gte IE 9)]> --><span> </span><!-- <![endif] -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="parameter-name" style="cursor: pointer"><%- testset.get('name') %></div>
|
||||
</label>
|
||||
</div>
|
||||
</th>
|
||||
<th>
|
||||
<label class="testset-name" for="testset-select-<%- testset.id %>"><%- testset.get('name') %></label>
|
||||
</th>
|
||||
<th class="healthcheck-col-duration" data-i18n="cluster_page.healthcheck_tab.expected_duration"></th>
|
||||
<th class="healthcheck-col-duration" data-i18n="cluster_page.healthcheck_tab.actual_duration"></th>
|
||||
|
Loading…
Reference in New Issue
Block a user