donal
2018-04-23 2b7788c7ee327ead2660b3378ba94f1dff00731d
commit | author | age
c382ab 1 const request = require('request');
D 2 const benchrest = require('bench-rest');
3 const grunt = require("grunt");
4 const Q = require('q');
6ef0cc 5
D 6
7 // INFO ABOUT THE STATS
8 // stats.main.histogram.min - the minimum time any iteration took (milliseconds)
9 // stats.main.histogram.max - the maximum time any iteration took (milliseconds)
10 // stats.main.histogram.mean - the average time any iteration took (milliseconds)
11 // stats.main.histogram.p95 - the amount of time that 95% of all iterations completed within (milliseconds)
12
c382ab 13 const options = {
6ef0cc 14   limit: 10,     // concurrent connections
D 15   iterations: 10000  // number of iterations to perform
16 };
c382ab 17 const test = {
6ef0cc 18   domain : 'http://localhost:9000',
D 19   dir : './reports/server/perf/',
20   route : '/api/todos/',
21   nfr : 60
22 };
2b7788 23 const dev = {
D 24   domain : 'http://' + process.env.E2E_TEST_ROUTE,
6ef0cc 25   dir : './reports/server/perf/',
D 26   route : '/api/todos/',
27   nfr : 60
28 };
c382ab 29 const production = {
6ef0cc 30   domain : 'http://localhost:80',
D 31   dir : './reports/server/perf/',
32   route : '/api/todos/',
33   nfr : 50
34 };
35
c382ab 36 const test_endpoint = function (flow, options) {
D 37   const wait = Q.defer();
6ef0cc 38
D 39   benchrest(flow, options)
40     .on('error', function (err, ctxName) {
41       console.error('Failed in %s with err: ', ctxName, err);
42     })
43     .on('end', function (stats, errorCount) {
44       console.log('\n\n###### ' +flow.filename +' - ' +flow.env.domain + flow.env.route);
45       console.log('Error Count', errorCount);
46       console.log('Stats', stats);
c382ab 47       const mean_score = stats.main.histogram.mean;
D 48       const fs = require('fs-extra');
49       const file = flow.env.dir + flow.filename + '-perf-score.csv';
6ef0cc 50       fs.outputFileSync(file, 'mean,max,mix,p95\n'+  stats.main.histogram.mean +','
D 51         + stats.main.histogram.max +','+ stats.main.histogram.min +','+ stats.main.histogram.p95);
52       if (mean_score > flow.env.nfr){
53         console.error('NFR EXCEEDED - ' +mean_score +' > '+flow.env.nfr);
54         wait.resolve(false);
55       } else {
56         wait.resolve(true);
57       }
58     });
59   return wait.promise
60 };
61
62
63 module.exports = function () {
64   grunt.task.registerTask('perf-test', 'Runs the performance tests against the target env', function(target, api) {
65     if (target === undefined || api === undefined){
66       grunt.fail.fatal('Required param not set - use grunt perf-test\:\<target\>\:\<api\>');
67     } else {
c382ab 68       const done = this.async();
D 69       const create = {
6ef0cc 70         filename: 'create',
D 71         env: {},
72         main: [{
2b7788 73           post: dev.domain + dev.route,
6ef0cc 74           json: {
D 75             title: 'Run perf-test',
76             completed: false
77           }
78         }]
79       };
80
c382ab 81       const show = {
6ef0cc 82         filename: 'show',
D 83         env: {},
84         main: [{
2b7788 85           get: dev.domain + dev.route
6ef0cc 86         }]
D 87       };
88
2b7788 89       if (target === 'dev') {
D 90         show.env = dev;
91         create.env = dev;
6ef0cc 92       }
D 93       else if (target === 'production') {
94         show.env = production;
95         create.env = production;
96       }
97       else if (target === 'test') {
98         show.env = test;
99         create.env = test;
100       } else {
101         grunt.fail.fatal('Invalid target - ' + target);
102         done();
103       }
104
105       grunt.log.ok("Perf tests running against " + target);
106       grunt.log.ok("This may take some time .... ");
107
c382ab 108       const all_tests = [];
6ef0cc 109
D 110       // console.log(create)
111       // console.log(show)
112       request(show.env.domain + show.env.route, function (error, response, body) {
113         if (error) {
114           grunt.log.error(error);
115         } else if(response.statusCode == 200) {
116           if (api === 'create'){
117             all_tests.push(test_endpoint(create, options));
118           }
119           else {
c382ab 120             const mongoid = JSON.parse(body)[0]._id;
2b7788 121             show.main[0].get = dev.domain + dev.route + mongoid;
6ef0cc 122             all_tests.push(test_endpoint(show, options));
D 123           }
124
125           Q.all(all_tests).then(function (data) {
126             grunt.log.ok(data);
127             if (data.indexOf(false) > -1){
128               grunt.fail.fatal('FAILURE - NFR NOT ACHIEVED');
129             } else {
130               grunt.log.ok('SUCCESS - All NFR ACHIEVED');
131               return done();
132             }
133           });
134         } else {
135           grunt.fail.fatal('FAILURE: something bad happened... there was no error from mongo but the response code was not 200')
136         }
137       });
138     }
139   });
140 };