From 186c065484e92010162f6dedfacfff299dfb3f48 Mon Sep 17 00:00:00 2001 From: jaredevantabor Date: Fri, 16 Dec 2016 16:12:49 -0800 Subject: [PATCH 1/5] adding elapsed time for a running job --- .../src/job-results/job-results.controller.js | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/awx/ui/client/src/job-results/job-results.controller.js b/awx/ui/client/src/job-results/job-results.controller.js index a11e7cf7be..c3cd22e851 100644 --- a/awx/ui/client/src/job-results/job-results.controller.js +++ b/awx/ui/client/src/job-results/job-results.controller.js @@ -1,4 +1,5 @@ -export default ['jobData', 'jobDataOptions', 'jobLabels', 'jobFinished', 'count', '$scope', 'ParseTypeChange', 'ParseVariableString', 'jobResultsService', 'eventQueue', '$compile', '$log', 'Dataset', '$q', 'Rest', '$state', 'QuerySet', '$rootScope', function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, $log, Dataset, $q, Rest, $state, QuerySet, $rootScope) { +export default ['jobData', 'jobDataOptions', 'jobLabels', 'jobFinished', 'count', '$scope', 'ParseTypeChange', 'ParseVariableString', 'jobResultsService', 'eventQueue', '$compile', '$log', 'Dataset', '$q', 'Rest', '$state', 'QuerySet', '$rootScope', 'moment', +function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, $log, Dataset, $q, Rest, $state, QuerySet, $rootScope, moment) { // used for tag search $scope.job_event_dataset = Dataset.data; @@ -169,6 +170,17 @@ export default ['jobData', 'jobDataOptions', 'jobLabels', 'jobFinished', 'count' $scope.events = {}; + // For elapsed time while a job is running, compute the differnce in seconds, + // from the time the job started until now. Moment() returns the current + // time as a moment object. + var start = ($scope.job.started === null) ? moment() : moment($scope.job.started); + if(jobFinished === false){ + var elapsedInterval = setInterval(function(){ + let now = moment(); + $scope.job.elapsed = now.diff(start, 'seconds'); + }, 1000); + } + // EVENT STUFF BELOW // This is where the async updates to the UI actually happen. @@ -442,6 +454,13 @@ export default ['jobData', 'jobDataOptions', 'jobLabels', 'jobFinished', 'count' parseInt($scope.job.id,10)) { // controller is defined, so set the job_status $scope.job_status = data.status; + if (data.status === "successful" || + data.status === "failed" || + data.status === "error" || + data.status === "canceled") { + clearInterval(elapsedInterval); + $state.go('.', null, { reload: true }); + } } else if (parseInt(data.project_id, 10) === parseInt($scope.job.project,10)) { // this is a project status update message, so set the From 439b699e733b1ef6472028424eac0cbe0baffc03 Mon Sep 17 00:00:00 2001 From: jaredevantabor Date: Fri, 16 Dec 2016 17:14:23 -0800 Subject: [PATCH 2/5] adding moment for unit tests, but they're still failing :( --- .../job-results/job-results.controller-test.js | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/awx/ui/tests/spec/job-results/job-results.controller-test.js b/awx/ui/tests/spec/job-results/job-results.controller-test.js index aec74d8edc..56333fab6a 100644 --- a/awx/ui/tests/spec/job-results/job-results.controller-test.js +++ b/awx/ui/tests/spec/job-results/job-results.controller-test.js @@ -4,7 +4,7 @@ describe('Controller: jobResultsController', () => { // Setup let jobResultsController; - let jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, eventResolve, populateResolve, $rScope, q, $log, Dataset, Rest, $state, QuerySet; + let jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, eventResolve, populateResolve, $rScope, q, $log, Dataset, Rest, $state, QuerySet, moment; jobData = { related: {} @@ -29,6 +29,8 @@ describe('Controller: jobResultsController', () => { data: {foo: "bar"} }; + moment = function(){}; + let provideVals = () => { angular.mock.module('jobResults', ($provide) => { ParseTypeChange = jasmine.createSpy('ParseTypeChange'); @@ -58,6 +60,10 @@ describe('Controller: jobResultsController', () => { 'encodeQueryset' ]); + moment = jasmine.createSpyObj('moment', [ + 'diff' + ]); + $provide.value('jobData', jobData); $provide.value('jobDataOptions', jobDataOptions); $provide.value('jobLabels', jobLabels); @@ -71,11 +77,12 @@ describe('Controller: jobResultsController', () => { $provide.value('Rest', Rest); $provide.value('$state', $state); $provide.value('QuerySet', QuerySet); + $provide.value('moment', moment); }); }; let injectVals = () => { - angular.mock.inject((_jobData_, _jobDataOptions_, _jobLabels_, _jobFinished_, _count_, _ParseTypeChange_, _ParseVariableString_, _jobResultsService_, _eventQueue_, _$compile_, $rootScope, $controller, $q, $httpBackend, _$log_, _Dataset_, _Rest_, _$state_, _QuerySet_) => { + angular.mock.inject((_jobData_, _jobDataOptions_, _jobLabels_, _jobFinished_, _count_, _ParseTypeChange_, _ParseVariableString_, _jobResultsService_, _eventQueue_, _$compile_, $rootScope, $controller, $q, $httpBackend, _$log_, _Dataset_, _Rest_, _$state_, _QuerySet_, _moment_) => { // when you call $scope.$apply() (which you need to do to // to get inside of .then blocks to test), something is // causing a request for all static files. @@ -110,6 +117,7 @@ describe('Controller: jobResultsController', () => { Rest = _Rest_; $state = _$state_; QuerySet = _QuerySet_; + moment = _moment_; jobResultsService.getEvents.and .returnValue(eventResolve); @@ -134,7 +142,8 @@ describe('Controller: jobResultsController', () => { Dataset: Dataset, Rest: Rest, $state: $state, - QuerySet: QuerySet + QuerySet: QuerySet, + moment: moment }); }); }; From 5de93aa05cb46cba0b4f1ac233b80ab768a37e66 Mon Sep 17 00:00:00 2001 From: jaredevantabor Date: Mon, 19 Dec 2016 11:37:17 -0800 Subject: [PATCH 3/5] removing reload call when a job ends from the socket listener on the job results page --- .../src/job-results/job-results.controller.js | 6 ++++- .../src/job-results/job-results.route.js | 22 ++---------------- .../src/job-results/job-results.service.js | 23 ++++++++++++++++++- 3 files changed, 29 insertions(+), 22 deletions(-) diff --git a/awx/ui/client/src/job-results/job-results.controller.js b/awx/ui/client/src/job-results/job-results.controller.js index c3cd22e851..b4e6793f2c 100644 --- a/awx/ui/client/src/job-results/job-results.controller.js +++ b/awx/ui/client/src/job-results/job-results.controller.js @@ -459,7 +459,11 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy data.status === "error" || data.status === "canceled") { clearInterval(elapsedInterval); - $state.go('.', null, { reload: true }); + // When the fob is finished retrieve the job data to + // correct anything that was out of sync from the job run + jobResultsService.getJobData($scope.job.id).then(function(data){ + $scope.job = data; + }) } } else if (parseInt(data.project_id, 10) === parseInt($scope.job.project,10)) { diff --git a/awx/ui/client/src/job-results/job-results.route.js b/awx/ui/client/src/job-results/job-results.route.js index 161f8db587..88154d3114 100644 --- a/awx/ui/client/src/job-results/job-results.route.js +++ b/awx/ui/client/src/job-results/job-results.route.js @@ -34,26 +34,8 @@ export default { }, resolve: { // the GET for the particular job - jobData: ['Rest', 'GetBasePath', '$stateParams', '$q', '$state', 'Alert', function(Rest, GetBasePath, $stateParams, $q, $state, Alert) { - var val = $q.defer(); - - Rest.setUrl(GetBasePath('jobs') + $stateParams.id); - Rest.get() - .then(function(data) { - val.resolve(data.data); - }, function(data) { - val.reject(data); - - if (data.status === 404) { - Alert('Job Not Found', 'Cannot find job.', 'alert-info'); - } else if (data.status === 403) { - Alert('Insufficient Permissions', 'You do not have permission to view this job.', 'alert-info'); - } - - $state.go('jobs'); - }); - - return val.promise; + jobData: ['Rest', 'GetBasePath', '$stateParams', '$q', '$state', 'Alert', 'jobResultsService', function(Rest, GetBasePath, $stateParams, $q, $state, Alert, jobResultsService) { + return jobResultsService.getJobData($stateParams.id); }], Dataset: ['QuerySet', '$stateParams', 'jobData', function(qs, $stateParams, jobData) { diff --git a/awx/ui/client/src/job-results/job-results.service.js b/awx/ui/client/src/job-results/job-results.service.js index 07d442f3d7..1a5210cff7 100644 --- a/awx/ui/client/src/job-results/job-results.service.js +++ b/awx/ui/client/src/job-results/job-results.service.js @@ -5,7 +5,7 @@ *************************************************/ -export default ['$q', 'Prompt', '$filter', 'Wait', 'Rest', '$state', 'ProcessErrors', 'InitiatePlaybookRun', function ($q, Prompt, $filter, Wait, Rest, $state, ProcessErrors, InitiatePlaybookRun) { +export default ['$q', 'Prompt', '$filter', 'Wait', 'Rest', '$state', 'ProcessErrors', 'InitiatePlaybookRun', 'GetBasePath', function ($q, Prompt, $filter, Wait, Rest, $state, ProcessErrors, InitiatePlaybookRun, GetBasePath) { var val = { // the playbook_on_stats event returns the count data in a weird format. // format to what we need! @@ -191,6 +191,27 @@ export default ['$q', 'Prompt', '$filter', 'Wait', 'Rest', '$state', 'ProcessErr relaunchJob: function(scope) { InitiatePlaybookRun({ scope: scope, id: scope.job.id, relaunch: true }); + }, + getJobData: function(id){ + var val = $q.defer(); + + Rest.setUrl(GetBasePath('jobs') + id ); + Rest.get() + .then(function(data) { + val.resolve(data.data); + }, function(data) { + val.reject(data); + + if (data.status === 404) { + Alert('Job Not Found', 'Cannot find job.', 'alert-info'); + } else if (data.status === 403) { + Alert('Insufficient Permissions', 'You do not have permission to view this job.', 'alert-info'); + } + + $state.go('jobs'); + }); + + return val.promise; } }; return val; From bd95aebe36d129d803be4d0755bd0eb824fff160 Mon Sep 17 00:00:00 2001 From: jaredevantabor Date: Mon, 19 Dec 2016 11:42:48 -0800 Subject: [PATCH 4/5] more unit test code that doens't work and fixing jshint --- .../src/job-results/job-results.controller.js | 2 +- .../client/src/job-results/job-results.service.js | 3 ++- .../spec/job-results/job-results.controller-test.js | 13 ++++++++----- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/awx/ui/client/src/job-results/job-results.controller.js b/awx/ui/client/src/job-results/job-results.controller.js index b4e6793f2c..56aed6ce5b 100644 --- a/awx/ui/client/src/job-results/job-results.controller.js +++ b/awx/ui/client/src/job-results/job-results.controller.js @@ -463,7 +463,7 @@ function(jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTy // correct anything that was out of sync from the job run jobResultsService.getJobData($scope.job.id).then(function(data){ $scope.job = data; - }) + }); } } else if (parseInt(data.project_id, 10) === parseInt($scope.job.project,10)) { diff --git a/awx/ui/client/src/job-results/job-results.service.js b/awx/ui/client/src/job-results/job-results.service.js index 1a5210cff7..02f4a31548 100644 --- a/awx/ui/client/src/job-results/job-results.service.js +++ b/awx/ui/client/src/job-results/job-results.service.js @@ -5,7 +5,8 @@ *************************************************/ -export default ['$q', 'Prompt', '$filter', 'Wait', 'Rest', '$state', 'ProcessErrors', 'InitiatePlaybookRun', 'GetBasePath', function ($q, Prompt, $filter, Wait, Rest, $state, ProcessErrors, InitiatePlaybookRun, GetBasePath) { +export default ['$q', 'Prompt', '$filter', 'Wait', 'Rest', '$state', 'ProcessErrors', 'InitiatePlaybookRun', 'GetBasePath', 'Alert', +function ($q, Prompt, $filter, Wait, Rest, $state, ProcessErrors, InitiatePlaybookRun, GetBasePath, Alert) { var val = { // the playbook_on_stats event returns the count data in a weird format. // format to what we need! diff --git a/awx/ui/tests/spec/job-results/job-results.controller-test.js b/awx/ui/tests/spec/job-results/job-results.controller-test.js index 56333fab6a..aa70041f8a 100644 --- a/awx/ui/tests/spec/job-results/job-results.controller-test.js +++ b/awx/ui/tests/spec/job-results/job-results.controller-test.js @@ -29,8 +29,6 @@ describe('Controller: jobResultsController', () => { data: {foo: "bar"} }; - moment = function(){}; - let provideVals = () => { angular.mock.module('jobResults', ($provide) => { ParseTypeChange = jasmine.createSpy('ParseTypeChange'); @@ -60,10 +58,15 @@ describe('Controller: jobResultsController', () => { 'encodeQueryset' ]); - moment = jasmine.createSpyObj('moment', [ - 'diff' + moment = jasmine.createSpyObj('momentStub', [ + 'diff' ]); - + spyOn(window, 'moment').andReturn(momentStub); + // spyOn(window, 'moment').and.callFake(function (date) { + // return { + // diff: function (diff) { /* your format implementation */ } + // }; + // }); $provide.value('jobData', jobData); $provide.value('jobDataOptions', jobDataOptions); $provide.value('jobLabels', jobLabels); From fc4c16465ae69f14eb7484c2ef90b04dab67035b Mon Sep 17 00:00:00 2001 From: John Mitchell Date: Mon, 19 Dec 2016 15:51:46 -0500 Subject: [PATCH 5/5] fixed job results controller unit tests w moment dep --- awx/ui/client/src/job-results/main.js | 2 +- .../job-results/job-results.controller-test.js | 18 +++--------------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/awx/ui/client/src/job-results/main.js b/awx/ui/client/src/job-results/main.js index 3747da4158..f0aedc7c43 100644 --- a/awx/ui/client/src/job-results/main.js +++ b/awx/ui/client/src/job-results/main.js @@ -17,7 +17,7 @@ import eventQueueService from './event-queue.service'; import parseStdoutService from './parse-stdout.service'; export default - angular.module('jobResults', [hostStatusBar.name, jobResultsStdOut.name, hostEvent.name]) + angular.module('jobResults', [hostStatusBar.name, jobResultsStdOut.name, hostEvent.name, 'angularMoment']) .run(['$stateExtender', function($stateExtender) { $stateExtender.addState(route); }]) diff --git a/awx/ui/tests/spec/job-results/job-results.controller-test.js b/awx/ui/tests/spec/job-results/job-results.controller-test.js index aa70041f8a..aec74d8edc 100644 --- a/awx/ui/tests/spec/job-results/job-results.controller-test.js +++ b/awx/ui/tests/spec/job-results/job-results.controller-test.js @@ -4,7 +4,7 @@ describe('Controller: jobResultsController', () => { // Setup let jobResultsController; - let jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, eventResolve, populateResolve, $rScope, q, $log, Dataset, Rest, $state, QuerySet, moment; + let jobData, jobDataOptions, jobLabels, jobFinished, count, $scope, ParseTypeChange, ParseVariableString, jobResultsService, eventQueue, $compile, eventResolve, populateResolve, $rScope, q, $log, Dataset, Rest, $state, QuerySet; jobData = { related: {} @@ -58,15 +58,6 @@ describe('Controller: jobResultsController', () => { 'encodeQueryset' ]); - moment = jasmine.createSpyObj('momentStub', [ - 'diff' - ]); - spyOn(window, 'moment').andReturn(momentStub); - // spyOn(window, 'moment').and.callFake(function (date) { - // return { - // diff: function (diff) { /* your format implementation */ } - // }; - // }); $provide.value('jobData', jobData); $provide.value('jobDataOptions', jobDataOptions); $provide.value('jobLabels', jobLabels); @@ -80,12 +71,11 @@ describe('Controller: jobResultsController', () => { $provide.value('Rest', Rest); $provide.value('$state', $state); $provide.value('QuerySet', QuerySet); - $provide.value('moment', moment); }); }; let injectVals = () => { - angular.mock.inject((_jobData_, _jobDataOptions_, _jobLabels_, _jobFinished_, _count_, _ParseTypeChange_, _ParseVariableString_, _jobResultsService_, _eventQueue_, _$compile_, $rootScope, $controller, $q, $httpBackend, _$log_, _Dataset_, _Rest_, _$state_, _QuerySet_, _moment_) => { + angular.mock.inject((_jobData_, _jobDataOptions_, _jobLabels_, _jobFinished_, _count_, _ParseTypeChange_, _ParseVariableString_, _jobResultsService_, _eventQueue_, _$compile_, $rootScope, $controller, $q, $httpBackend, _$log_, _Dataset_, _Rest_, _$state_, _QuerySet_) => { // when you call $scope.$apply() (which you need to do to // to get inside of .then blocks to test), something is // causing a request for all static files. @@ -120,7 +110,6 @@ describe('Controller: jobResultsController', () => { Rest = _Rest_; $state = _$state_; QuerySet = _QuerySet_; - moment = _moment_; jobResultsService.getEvents.and .returnValue(eventResolve); @@ -145,8 +134,7 @@ describe('Controller: jobResultsController', () => { Dataset: Dataset, Rest: Rest, $state: $state, - QuerySet: QuerySet, - moment: moment + QuerySet: QuerySet }); }); };