1 | var assert = require ('assert'),
|
2 | sinon = require ('sinon');
|
3 |
|
4 | describe ('scheduler', function(){
|
5 | var scheduler = require('../lib/scheduler')();
|
6 | var widgets;
|
7 |
|
8 | var stub;
|
9 | var clock;
|
10 | var mockJobWorker;
|
11 |
|
12 | beforeEach(function(done){
|
13 | clock = sinon.useFakeTimers();
|
14 | widgets = {sendData: function(){}};
|
15 | mockJobWorker = {
|
16 | config:{interval: 3000},
|
17 | task : function(){},
|
18 | dependencies : {
|
19 | logger : {
|
20 | warn: function (){},
|
21 | error: function (){},
|
22 | log: function (){}
|
23 | }
|
24 | }
|
25 | };
|
26 |
|
27 | stub = sinon.stub(mockJobWorker, "task", function(config, dependencies, cb) {
|
28 | cb(null, {});
|
29 | });
|
30 | done();
|
31 | });
|
32 |
|
33 | afterEach(function(done){
|
34 | stub.restore();
|
35 | clock.restore();
|
36 | done();
|
37 | });
|
38 |
|
39 | it('should execute the job then it is run', function(done){
|
40 | this.timeout(50);
|
41 | mockJobWorker.task = function (config, dependencies, cb){
|
42 | done();
|
43 | };
|
44 | scheduler.schedule(mockJobWorker, widgets);
|
45 | });
|
46 |
|
47 | it('should schedule a job to be executed in the future in intervals of time', function(done){
|
48 | scheduler.schedule(mockJobWorker, widgets);
|
49 | clock.tick(3000);
|
50 | clock.tick(3000);
|
51 | assert.ok(stub.calledThrice);
|
52 | done();
|
53 | });
|
54 |
|
55 | it('should set 1 sec as the minimum interval period', function(done){
|
56 | mockJobWorker.config.interval = 10;
|
57 | scheduler.schedule(mockJobWorker, widgets);
|
58 | clock.tick(1000);
|
59 | clock.tick(1000);
|
60 | assert.ok(stub.calledThrice);
|
61 | done();
|
62 | });
|
63 |
|
64 | it('should allow job workers to maintain state across calls', function(done){
|
65 | mockJobWorker.task = function (config, dependencies, cb){
|
66 | this.counter = (this.counter || 0) + 1;
|
67 | cb(null, {});
|
68 | };
|
69 | scheduler.schedule(mockJobWorker, widgets);
|
70 | clock.tick(3000);
|
71 | clock.tick(3000);
|
72 | assert.equal(3, mockJobWorker.counter);
|
73 | done();
|
74 | });
|
75 |
|
76 | it('should schedule an empty data parameter', function(done){
|
77 | mockJobWorker.task = function (config, dependencies, cb){
|
78 | cb(null);
|
79 | };
|
80 | widgets.sendData = function(data){
|
81 | done();
|
82 | };
|
83 | scheduler.schedule(mockJobWorker, widgets);
|
84 | });
|
85 |
|
86 | it('should handle and log asynchronous errors', function(done){
|
87 | mockJobWorker.task = function (config, dependencies, cb){
|
88 | cb('error');
|
89 | };
|
90 | mockJobWorker.dependencies.logger.error = function(error){
|
91 | assert.ok(error);
|
92 | done();
|
93 | };
|
94 | scheduler.schedule(mockJobWorker, widgets);
|
95 | });
|
96 |
|
97 | it('should notify client on asynchronous errors', function(done){
|
98 | mockJobWorker.task = function (config, dependencies, cb){
|
99 | cb('error');
|
100 | };
|
101 | widgets.sendData = function(data){
|
102 | assert.ok(data.error);
|
103 | done();
|
104 | };
|
105 | scheduler.schedule(mockJobWorker, widgets);
|
106 | });
|
107 |
|
108 | it('should allow a grace period to raise errors if retryOnErrorTimes is defined', function(done){
|
109 | mockJobWorker.config.retryOnErrorTimes = 3;
|
110 | var numberCalls = 0;
|
111 | mockJobWorker.task = function (config, dependencies, cb){
|
112 | numberCalls++;
|
113 | cb('err');
|
114 | };
|
115 | scheduler.schedule(mockJobWorker, widgets);
|
116 | clock.tick(3000/3);
|
117 | clock.tick(3000/3);
|
118 | assert.equal(3, numberCalls);
|
119 | done();
|
120 | });
|
121 |
|
122 | it('should handle synchronous errors in job execution', function(done){
|
123 | mockJobWorker.task = sinon.stub().throws('err');
|
124 | scheduler.schedule(mockJobWorker, widgets);
|
125 | assert.ok(mockJobWorker.task.calledOnce);
|
126 | done();
|
127 | });
|
128 |
|
129 | it('should notify client when synchronous error occurred during job execution', function(done){
|
130 | mockJobWorker.task = sinon.stub().throws('err');
|
131 | widgets.sendData = function(data){
|
132 | assert.ok(data.error);
|
133 | done();
|
134 | };
|
135 | scheduler.schedule(mockJobWorker, widgets);
|
136 | assert.ok(mockJobWorker.task.calledOnce);
|
137 | });
|
138 |
|
139 | it('should notify client on first synchronous error during job execution even when retryAttempts are configured', function(done){
|
140 | mockJobWorker.task = sinon.stub().throws('err');
|
141 | mockJobWorker.config.retryOnErrorTimes = 3;
|
142 | widgets.sendData = function(data){
|
143 | assert.ok(data.error);
|
144 | done();
|
145 | };
|
146 | scheduler.schedule(mockJobWorker, widgets);
|
147 | assert.ok(mockJobWorker.task.calledOnce);
|
148 | });
|
149 |
|
150 | it('should schedule task even if there was a synchronous error', function (done) {
|
151 | mockJobWorker.task = sinon.stub().throws('err');
|
152 |
|
153 | scheduler.schedule(mockJobWorker, widgets);
|
154 | clock.tick(3000);
|
155 |
|
156 | assert.equal(4, mockJobWorker.task.callCount);
|
157 | done();
|
158 | });
|
159 |
|
160 | it('should not schedule more than one job when job execution takes long time', function(done) {
|
161 | mockJobWorker.task = function() {};
|
162 | var stub = sinon.stub(mockJobWorker, "task", function (config, dependencies, cb) {
|
163 | setTimeout(function() {
|
164 | cb(null, {});
|
165 | }, 10000);
|
166 | });
|
167 | scheduler.schedule(mockJobWorker, widgets);
|
168 | clock.tick(13000);
|
169 | clock.tick(13000);
|
170 | assert.ok(stub.calledThrice);
|
171 | done();
|
172 | });
|
173 |
|
174 | }); |
\ | No newline at end of file |