From cd2eb26559f56e883921c018b645416b0e26a40d Mon Sep 17 00:00:00 2001 From: sergei_sergeev Date: Sun, 22 May 2016 19:18:28 +0300 Subject: [PATCH] Added performance tests. --- .gitignore | 2 + .vscode/launch.json | 4 +- package.json | 1 + src/core/FileSaver.ts | 2 +- src/core/SPSave.ts | 2 +- .../{ISPSaveOptions.ts => SPSaveOptions.ts} | 0 src/index.ts | 2 +- src/utils/ConsoleLogger.ts | 6 +- src/utils/OptionsParser.ts | 2 +- test/integration/integration.spec.ts | 2 +- test/performance/config.sample.ts | 21 ++ test/performance/index.ts | 210 ++++++++++++++++++ test/performance/legacy/package.json | 14 ++ 13 files changed, 260 insertions(+), 8 deletions(-) rename src/core/{ISPSaveOptions.ts => SPSaveOptions.ts} (100%) create mode 100644 test/performance/config.sample.ts create mode 100644 test/performance/index.ts create mode 100644 test/performance/legacy/package.json diff --git a/.gitignore b/.gitignore index 43b8605..b90696e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ demo node_modules reports test/integration/config.ts +test/performance/config.ts +test/performance/files/* /lib *.js *.js.map diff --git a/.vscode/launch.json b/.vscode/launch.json index fb48e32..e18d0ed 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,12 +5,12 @@ "configurations": [ { // Name of configuration; appears in the launch configuration drop down menu. - "name": "Run index.js", + "name": "Run performance test", // Type of configuration. Possible values: "node", "mono". "type": "node", "request": "launch", // Workspace relative or absolute path to the program. - "program": "${workspaceRoot}/demo/index.js", + "program": "${workspaceRoot}/lib/test/performance/index.js", // Automatically stop program after launch. "stopOnEntry": false, // Command line arguments passed to the program. diff --git a/package.json b/package.json index de3fcdd..d604c42 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ ], "devDependencies": { "chai": "^3.5.0", + "console.table": "^0.7.0", "coveralls": "^2.11.9", "del": "^2.2.0", "gulp": "^3.9.1", diff --git a/src/core/FileSaver.ts b/src/core/FileSaver.ts index 5baf7ff..e7f3b75 100644 --- a/src/core/FileSaver.ts +++ b/src/core/FileSaver.ts @@ -5,7 +5,7 @@ import * as url from 'url'; import * as _ from 'lodash'; import {IEnvironment, IUserCredentials} from 'sp-request'; -import {FileContentOptions, CheckinType} from './ISPSaveOptions'; +import {FileContentOptions, CheckinType} from './SPSaveOptions'; import {UrlHelper} from './../utils/UrlHelper'; import {FoldersCreator} from './../utils/FoldersCreator'; import {ILogger} from './../utils/ILogger'; diff --git a/src/core/SPSave.ts b/src/core/SPSave.ts index 871a8d2..9759c88 100644 --- a/src/core/SPSave.ts +++ b/src/core/SPSave.ts @@ -1,7 +1,7 @@ import * as Promise from 'bluebird'; import * as notifier from 'node-notifier'; -import {SPSaveOptions, FileContentOptions, isFileContentOptions} from './ISPSaveOptions'; +import {SPSaveOptions, FileContentOptions, isFileContentOptions} from './SPSaveOptions'; import {FileSaver} from './FileSaver'; import {ILogger} from './../utils/ILogger'; import {ConsoleLogger} from './../utils/ConsoleLogger'; diff --git a/src/core/ISPSaveOptions.ts b/src/core/SPSaveOptions.ts similarity index 100% rename from src/core/ISPSaveOptions.ts rename to src/core/SPSaveOptions.ts diff --git a/src/index.ts b/src/index.ts index 6c2ca71..af57dc1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,2 +1,2 @@ export * from './core/SPSave'; -export * from './core/ISPSaveOptions'; +export * from './core/SPSaveOptions'; diff --git a/src/utils/ConsoleLogger.ts b/src/utils/ConsoleLogger.ts index bd928ca..97192e9 100644 --- a/src/utils/ConsoleLogger.ts +++ b/src/utils/ConsoleLogger.ts @@ -1,5 +1,6 @@ import {ILogger} from './ILogger'; import * as colors from 'colors'; +import * as util from 'util'; export class ConsoleLogger implements ILogger { public error(message: string): void { @@ -22,6 +23,9 @@ export class ConsoleLogger implements ILogger { if (message === '') { console.log(''); } - console.log(colors[color](`spsave: ${message}`)); + let dateNow: Date = new Date(); + let dateString: string = util.format('[%s:%s:%s]', + ('0' + dateNow.getHours()).slice(-2), ('0' + dateNow.getMinutes()).slice(-2), ('0' + dateNow.getSeconds()).slice(-2)); + console.log(colors[color](`${dateString} spsave: ${message}`)); } } diff --git a/src/utils/OptionsParser.ts b/src/utils/OptionsParser.ts index fa156cc..40415c4 100644 --- a/src/utils/OptionsParser.ts +++ b/src/utils/OptionsParser.ts @@ -4,7 +4,7 @@ import * as path from 'path'; import * as globby from 'globby'; import * as fs from 'fs'; -import * as opts from './../core/ISPSaveOptions'; +import * as opts from './../core/SPSaveOptions'; import {UrlHelper} from './UrlHelper'; export class OptionsParser { diff --git a/test/integration/integration.spec.ts b/test/integration/integration.spec.ts index e25db06..5641cf8 100644 --- a/test/integration/integration.spec.ts +++ b/test/integration/integration.spec.ts @@ -9,7 +9,7 @@ import * as vfs from 'vinyl-fs'; import File = require('vinyl'); import {spsave} from './../../src/core/SPSave'; -import {FileContentOptions, VinylOptions, GlobOptions, CheckinType} from './../../src/core/ISPSaveOptions'; +import {FileContentOptions, VinylOptions, GlobOptions, CheckinType} from './../../src/core/SPSaveOptions'; import {UrlHelper} from './../../src/utils/UrlHelper'; let config: any = require('./config'); diff --git a/test/performance/config.sample.ts b/test/performance/config.sample.ts new file mode 100644 index 0000000..98cdc97 --- /dev/null +++ b/test/performance/config.sample.ts @@ -0,0 +1,21 @@ +import {IUserCredentials} from 'sp-request'; +import {IEnvironment} from 'sp-request'; + +export var onprem: IUserCredentials = { + username: '[user]', + password: '[pass]' +}; + +export var env: IEnvironment = { + domain: 'sp' +}; + +export var online: IUserCredentials = { + username: '[user]', + password: '[pass]' +}; + +export var url: any = { + online: 'https://[domain].sharepoint.com', + onprem: 'http://onprem/sharepoint/url' +}; diff --git a/test/performance/index.ts b/test/performance/index.ts new file mode 100644 index 0000000..47ea860 --- /dev/null +++ b/test/performance/index.ts @@ -0,0 +1,210 @@ +import * as globby from 'globby'; +import * as Promise from 'bluebird'; +import * as path from 'path'; +import * as fs from 'fs'; +import * as _ from 'lodash'; +require('console.table'); + +import {spsave} from './../../src/core/SPSave'; +import {FileContentOptions, CoreOptions} from './../../src/core/SPSaveOptions'; + +let config: any = require('./config'); +let spsaveLegacy: any = require(path.resolve('test/performance/legacy/node_modules/spsave/lib/spsave.js')); + +let filesToSave: string[] = globby.sync('test/performance/files/*.*'); +let folder: string = 'SiteAssets/files'; + +let onPremOptions: CoreOptions = { + username: config.onprem.username, + password: config.onprem.password, + domain: config.env.domain, + siteUrl: config.url.onprem +}; + +let onlineOptions: CoreOptions = { + username: config.online.username, + password: config.online.password, + domain: config.env.domain, + siteUrl: config.url.online +}; + +let legacyOnPremElapsedSeries: number; +let spsaveOnPremElapsedSeries: number; +let legacyOnPremElapsedParallel: number; +let spsaveOnPremElapsedParallel: number; + +let legacyOnlineElapsedSeries: number; +let spsaveOnlineElapsedSeries: number; +let legacyOnlineElapsedParallel: number; +let spsaveOnlineElapsedParallel: number; + +/* legacy: on-premise series run */ +Promise.all([new Date().getTime(), savesFileArraySeriesLegacy(filesToSave, onPremOptions)]) + .then((data) => { + legacyOnPremElapsedSeries = new Date().getTime() - data[0]; + + /* legacy: on-premise parallel run */ + return Promise.all([new Date().getTime(), saveFilesArrayInParallelLegacy(filesToSave, onPremOptions)]); + }) + .then((data) => { + legacyOnPremElapsedParallel = new Date().getTime() - data[0]; + + /* legacy: online series run */ + return Promise.all([new Date().getTime(), savesFileArraySeriesLegacy(filesToSave, onlineOptions)]); + }) + .then(data => { + legacyOnlineElapsedSeries = new Date().getTime() - data[0]; + + /* legacy: online parallel run */ + return Promise.all([new Date().getTime(), saveFilesArrayInParallelLegacy(filesToSave, onlineOptions)]); + }) + .then(data => { + legacyOnlineElapsedParallel = new Date().getTime() - data[0]; + + /* spsave 2.x: on-premise parallel run */ + return Promise.all([new Date().getTime(), saveFilesArrayInParallel(filesToSave, onPremOptions)]); + }) + .then((data) => { + spsaveOnPremElapsedParallel = new Date().getTime() - data[0]; + + /* spsave 2.x: on-premise series run */ + return Promise.all([new Date().getTime(), saveFilesArraySeries(filesToSave, onPremOptions)]); + }) + .then((data) => { + spsaveOnPremElapsedSeries = new Date().getTime() - data[0]; + + /* spsave 2.x: online parallel run */ + return Promise.all([new Date().getTime(), saveFilesArrayInParallel(filesToSave, onlineOptions)]); + }) + .then(data => { + spsaveOnlineElapsedParallel = new Date().getTime() - data[0]; + + /* spsave 2.x: online series run */ + return Promise.all([new Date().getTime(), saveFilesArraySeries(filesToSave, onlineOptions)]); + }) + .then(data => { + spsaveOnlineElapsedSeries = new Date().getTime() - data[0]; + }) + .then(printResults) + .catch(err => { + console.log(err); + }); + +function printResults(): void { + console.log(''); + console.log(''); + console.log(''); + (console).table(`${filesToSave.length} files upload: in series`, [ + { + 'spsave': 'spsave 1.x', + 'on-premise': `${legacyOnPremElapsedSeries / 1000}s`, + 'online': `${legacyOnlineElapsedSeries / 1000}s` + }, + { + 'spsave': 'spsave 2.x', + 'on-premise': `${spsaveOnPremElapsedSeries / 1000}s`, + 'online': `${spsaveOnlineElapsedSeries / 1000}s` + } + ]); + + (console).table(`${filesToSave.length} files upload: in parallel`, [ + { + 'spsave': 'spsave 1.x', + 'on-premise': `${legacyOnPremElapsedParallel / 1000}s`, + 'online': `${legacyOnlineElapsedParallel / 1000}s` + }, + { + 'spsave': 'spsave 2.x', + 'on-premise': `${spsaveOnPremElapsedParallel / 1000}s`, + 'online': `${spsaveOnlineElapsedParallel / 1000}s` + } + ]); +} + +function saveFilesArrayInParallelLegacy(files: string[], opts: any): Promise { + let promises: Promise[] = []; + + files.forEach(file => { + opts.fileName = path.basename(file); + opts.fileContent = fs.readFileSync(file); + opts.folder = folder; + let newOptions: any = _.extend({}, opts); + let deferred: Promise.Resolver = Promise.defer(); + + ((o) => { + spsaveLegacy(o, (err: any, data: any) => { + if (err) { + deferred.reject(err); + return; + } + deferred.resolve(); + }); + })(newOptions); + promises.push(deferred.promise); + }); + + return Promise.all(promises); +} + +function saveFilesArrayInParallel(files: string[], opts: any): Promise { + let promises: Promise[] = []; + + files.forEach(file => { + opts.fileName = path.basename(file); + opts.fileContent = fs.readFileSync(file); + opts.folder = folder; + promises.push(spsave(opts)); + }); + + return Promise.all(promises); +} + +function savesFileArraySeriesLegacy(files: string[], opts: any, deferred?: Promise.Resolver): Promise { + if (!deferred) { + deferred = Promise.defer(); + } + + if (files.length > 0) { + + opts.fileName = path.basename(files[0]); + opts.fileContent = fs.readFileSync(files[0]); + opts.folder = folder; + + spsaveLegacy(opts, (err: any, data: any) => { + if (err) { + deferred.reject(err); + return; + } + savesFileArraySeriesLegacy(files.slice(1, files.length), opts, deferred); + }); + } else { + deferred.resolve(); + } + + return deferred.promise; +} + +function saveFilesArraySeries(files: string[], opts: FileContentOptions, deferred?: Promise.Resolver): Promise { + if (!deferred) { + deferred = Promise.defer(); + } + + if (files.length > 0) { + + opts.fileName = path.basename(files[0]); + opts.fileContent = fs.readFileSync(files[0]); + opts.folder = folder; + + spsave(opts) + .then(() => { + saveFilesArraySeries(files.slice(1, files.length), opts, deferred); + }) + .catch(err => { + deferred.reject(err); + }); + } else { + deferred.resolve(); + } + + return deferred.promise; +} diff --git a/test/performance/legacy/package.json b/test/performance/legacy/package.json new file mode 100644 index 0000000..f35464a --- /dev/null +++ b/test/performance/legacy/package.json @@ -0,0 +1,14 @@ +{ + "name": "legacy", + "version": "1.0.0", + "description": "", + "main": "index.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "spsave": "^1.0.15" + } +}