Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,11 @@ <h3>Continuous computations</h3>
<h3>One-off jobs</h3>
<h4>Current time: <[$ctrl.HUMAN_READABLE_CURRENT_TIME]></h4>
<table class="table table-striped">
<tr ng-repeat="job_spec in $ctrl.ONE_OFF_JOB_SPECS">
<td><[job_spec.job_type]></td>
<tr ng-repeat="job_spec in $ctrl.ONE_OFF_JOB_SPECS" class="protractor-test-one-off-jobs-rows">
<td class="protractor-test-one-off-jobs-name"><[job_spec.job_type]></td>
<td>
<button ng-click="$ctrl.startNewJob(job_spec.job_type)"
class="float-right">
class="float-right protractor-test-one-off-jobs-start-btn">
Start new job
</button>
<span ng-if="job_spec.is_queued_or_running"
Expand Down Expand Up @@ -76,25 +76,26 @@ <h4>Current time: <[$ctrl.HUMAN_READABLE_CURRENT_TIME]></h4>
</md-card>

<md-card ng-if="$ctrl.UNFINISHED_JOB_DATA.length > 0"
class="oppia-page-card oppia-long-text" style="max-width: 900px">
class="oppia-page-card oppia-long-text protractor-test-unfinished-jobs-card" style="max-width: 900px">
<h3>Unfinished jobs</h3>
<em>Note: This table may be stale; refresh to see the latest state.</em>
<table class="table">
<tr>
<th>Job ID</th>
<th class="protractor-test-unfinished-one-off-jobs-id-header">Job ID</th>
<th>Status</th>
<th>Time started</th>
<th>Time finished</th>
<th></th>
</tr>
<tr ng-repeat="job in $ctrl.UNFINISHED_JOB_DATA track by $index">
<td><[job.id]></td>
<tr ng-repeat="job in $ctrl.UNFINISHED_JOB_DATA track by $index" class="protractor-test-unfinished-one-off-jobs-rows">
<td class="protractor-test-unfinished-one-off-jobs-id"><[job.id]></td>
<td><[job.status_code]></td>
<td><[job.human_readable_time_started]></td>
<td><[job.human_readable_time_finished]></td>
<td>
<button ng-if="job.can_be_canceled"
ng-click="$ctrl.cancelJob(job.id, job.job_type)">
ng-click="$ctrl.cancelJob(job.id, job.job_type)"
class="protractor-test-one-off-jobs-stop-btn">
Cancel
</button>
</td>
Expand Down
24 changes: 23 additions & 1 deletion core/tests/protractor_desktop/adminTabFeatures.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ var general = require('../protractor_utils/general.js');
var users = require('../protractor_utils/users.js');
var AdminPage = require('../protractor_utils/AdminPage.js');

describe('Admin Tab', function() {
describe('Admin Page', function() {
var adminPage = null;

beforeAll(function() {
Expand Down Expand Up @@ -49,6 +49,28 @@ describe('Admin Tab', function() {
adminPage.updateRole('collectionEditor1', 'collection editor');
adminPage.getUsersAsssignedToRole('collection editor');
adminPage.expectUsernamesToMatch(['collectionEditor1']);
users.logout();
});

it('should run,verify and stop one-off jobs', function() {
users.createAndLoginAdminUser('adminA@adminTab.com', 'alphaMan');
adminPage.getJobsTab();

// The following jobs are selected arbitrarily.
adminPage.startOneOffJob('FeedbackThreadCacheOneOffJob');
adminPage.expectJobToBeRunning('FeedbackThreadCacheOneOffJob');
adminPage.expectNumberOfRunningOneOffJobs(1);

adminPage.startOneOffJob('ExplorationValidityJobManager');
adminPage.expectJobToBeRunning('ExplorationValidityJobManager');
adminPage.expectNumberOfRunningOneOffJobs(2);

adminPage.stopOneOffJob('FeedbackThreadCacheOneOffJob');
adminPage.expectJobToBeRunning('ExplorationValidityJobManager');
adminPage.expectNumberOfRunningOneOffJobs(1);

adminPage.stopOneOffJob('ExplorationValidityJobManager');
adminPage.expectNumberOfRunningOneOffJobs(0);
});

afterEach(function() {
Expand Down
65 changes: 65 additions & 0 deletions core/tests/protractor_utils/AdminPage.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,11 @@ var AdminPage = function() {
var roleUsernameOption = element(by.css(
'.protractor-test-username-value'));
var viewRoleButton = element(by.css('.protractor-test-role-success'));
var oneOffJobRows = element.all(by.css('.protractor-test-one-off-jobs-rows'));
var unfinishedOneOffJobRows = element.all(by.css(
'.protractor-test-unfinished-one-off-jobs-rows'));
var unfinishedOffJobIDs = element.all(by.css(
'.protractor-test-unfinished-one-off-jobs-id'));

// The reload functions are used for mobile testing
// done via Browserstack. These functions may cause
Expand Down Expand Up @@ -124,6 +129,11 @@ var AdminPage = function() {
return waitFor.pageToFullyLoad();
};

this.getJobsTab = function() {
browser.get(ADMIN_URL_SUFFIX + '#/jobs');
return waitFor.pageToFullyLoad();
};

this.editConfigProperty = function(
propertyName, objectType, editingInstructions) {
this.get();
Expand All @@ -142,6 +152,61 @@ var AdminPage = function() {
});
};

this.startOneOffJob = function(jobName) {
this._startOneOffJob(jobName, 0);
};

this._startOneOffJob = function(jobName, i) {
waitFor.visibilityOf(oneOffJobRows.first(),
'Starting one off jobs taking too long to appear.');
oneOffJobRows.get(i).getText().then((text) => {
if (text.toLowerCase().startsWith(jobName.toLowerCase())) {
oneOffJobRows.get(i).element(
by.css('.protractor-test-one-off-jobs-start-btn')).click();
} else {
this._startOneOffJob(jobName, ++i);
}
});
};

this.stopOneOffJob = function(jobName) {
this._stopOneOffJob(jobName, 0);
};

this._stopOneOffJob = function(jobName, i) {
unfinishedOneOffJobRows.get(i).getText().then((text) => {
if (text.toLowerCase().startsWith(jobName.toLowerCase())) {
unfinishedOneOffJobRows.get(i).element(
by.css('.protractor-test-one-off-jobs-stop-btn')).click();
} else {
this._stopOneOffJob(jobName, ++i);
}
});
};

this.expectNumberOfRunningOneOffJobs = function(count) {
element.all(by.css(
'.protractor-test-unfinished-one-off-jobs-id')).count().then((len) =>{
expect(len).toEqual(count);
});
};

this.expectJobToBeRunning = function(jobName) {
browser.refresh();
waitFor.pageToFullyLoad();
waitFor.visibilityOf(element(
by.css('.protractor-test-unfinished-jobs-card')),
'Unfinished Jobs taking too long to appear');
let unfinishedJobs = unfinishedOffJobIDs.filter((element) => {
return element.getText().then((job) => {
return job.toLowerCase().startsWith(jobName.toLowerCase());
});
});
unfinishedJobs.get(0).getText((job) => {
expect(job.toLowerCase().startsWith(jobName.toLowerCase())).toBeTrue();
});
};

this.updateRole = function(name, newRole) {
waitFor.elementToBeClickable(
adminRolesTab, 'Admin Roles tab is not clickable');
Expand Down