From 42fac3ca3da00f4d87c877f09fce6e013c312931 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20T=C3=B6rnstr=C3=B6m=20Andersson?= Date: Tue, 5 Sep 2017 19:54:29 +0200 Subject: [PATCH 1/8] NODEJS-375 Overloaded Uuid.random() to allow callback --- lib/types/uuid.js | 48 +++++++++++++++++++++++++++++------------ test/unit/uuid-tests.js | 47 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 14 deletions(-) diff --git a/lib/types/uuid.js b/lib/types/uuid.js index 259537596..07e01b6a4 100644 --- a/lib/types/uuid.js +++ b/lib/types/uuid.js @@ -34,17 +34,18 @@ Uuid.fromString = function (value) { * Creates a new random (version 4) Uuid. * @returns {Uuid} */ -Uuid.random = function () { - var buffer = getRandomBytes(); - //clear the version - buffer[6] &= 0x0f; - //set the version 4 - buffer[6] |= 0x40; - //clear the variant - buffer[8] &= 0x3f; - //set the IETF variant - buffer[8] |= 0x80; - return new Uuid(buffer); +Uuid.random = function (cb) { + if (cb) { + getRandomBytes(function(err, buffer) { + if (err) { + return cb(err); + } + return cb(null, createUuidFromBuffer(buffer)); + }); + } else { + var buffer = getRandomBytes(); + return createUuidFromBuffer(buffer); + } }; /** @@ -95,6 +96,19 @@ Uuid.prototype.toJSON = function () { return this.toString(); }; + +function createUuidFromBuffer (buffer) { + //clear the version + buffer[6] &= 0x0f; + //set the version 4 + buffer[6] |= 0x40; + //clear the variant + buffer[8] &= 0x3f; + //set the IETF variant + buffer[8] |= 0x80; + return new Uuid(buffer); +} + /** * @private * @returns {String} 32 hex representation of the instance, without separators @@ -108,8 +122,14 @@ function getHex (uuid) { * @private * @returns {Buffer} */ -function getRandomBytes() { - return crypto.randomBytes(16); -} +function getRandomBytes (cb) { + if (cb) { + crypto.randomBytes(16, (err, buf) => { + return cb(err, buf); + }); + } else { + return crypto.randomBytes(16); + } +}; module.exports = Uuid; diff --git a/test/unit/uuid-tests.js b/test/unit/uuid-tests.js index f14cb0702..5094c6c36 100644 --- a/test/unit/uuid-tests.js +++ b/test/unit/uuid-tests.js @@ -105,6 +105,53 @@ describe('Uuid', function () { assert.strictEqual(Object.keys(values).length, length); }); }); + + describe('random(cb)', function () { + this.timeout(5000); + it('should return a Uuid instance', function (done) { + Uuid.random(function(err, uuid) { + helper.assertInstanceOf(Uuid.random(), Uuid); + done(); + }); + + }); + it('should contain the version bits and IETF variant', function (done) { + Uuid.random(function(err, val) { + assert.strictEqual(val.toString().charAt(14), '4'); + assert.ok(['8', '9', 'a', 'b'].indexOf(val.toString().charAt(19)) >= 0); + val = Uuid.random(); + assert.strictEqual(val.toString().charAt(14), '4'); + assert.ok(['8', '9', 'a', 'b'].indexOf(val.toString().charAt(19)) >= 0); + val = Uuid.random(); + assert.strictEqual(val.toString().charAt(14), '4'); + assert.ok(['8', '9', 'a', 'b'].indexOf(val.toString().charAt(19)) >= 0); + done(); + }); + }); + it('should generate v4 uuids that do not collide', function (done) { + var values = {}; + var promises = []; + var length = 100000; + for (var i = 0; i < length; i++) { + promises.push(new Promise(function(resolve, reject) { + Uuid.random(function(err, val) { + if (err) { + return reject(err); + } + values[val.toString()] = true; + resolve(); + }); + })); + } + Promise.all(promises).then(function() { + assert.strictEqual(Object.keys(values).length, length); + done(); + }).catch(function(err) { + assert.fail(err); + }); + + }); + }); }); describe('TimeUuid', function () { describe('constructor()', function () { From 8a7e0f047d4cf4a550cd91861efca644b7f7610d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20T=C3=B6rnstr=C3=B6m=20Andersson?= Date: Tue, 5 Sep 2017 19:56:31 +0200 Subject: [PATCH 2/8] NODEJS-375 Fixed indentation --- test/unit/uuid-tests.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/unit/uuid-tests.js b/test/unit/uuid-tests.js index 5094c6c36..789ebf885 100644 --- a/test/unit/uuid-tests.js +++ b/test/unit/uuid-tests.js @@ -147,7 +147,7 @@ describe('Uuid', function () { assert.strictEqual(Object.keys(values).length, length); done(); }).catch(function(err) { - assert.fail(err); + assert.fail(err); }); }); From 78956ef33097e30d1c2ad24ae4fa11ccde26a221 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20T=C3=B6rnstr=C3=B6m=20Andersson?= Date: Tue, 5 Sep 2017 20:05:50 +0200 Subject: [PATCH 3/8] NODEJS-375 Cleanup and documentation --- lib/types/uuid.js | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/lib/types/uuid.js b/lib/types/uuid.js index 07e01b6a4..2e6fa1aa1 100644 --- a/lib/types/uuid.js +++ b/lib/types/uuid.js @@ -32,15 +32,17 @@ Uuid.fromString = function (value) { /** * Creates a new random (version 4) Uuid. + * @param {function} [callback] Optional callback to be invoked with the error as first parameter and the created Uuid as + * second parameter. * @returns {Uuid} */ -Uuid.random = function (cb) { +Uuid.random = function (callback) { if (cb) { getRandomBytes(function(err, buffer) { if (err) { - return cb(err); + return callback(err); } - return cb(null, createUuidFromBuffer(buffer)); + return callback(null, createUuidFromBuffer(buffer)); }); } else { var buffer = getRandomBytes(); @@ -97,6 +99,11 @@ Uuid.prototype.toJSON = function () { }; +/** + * Returns new Uuid + * @private + * @returns {Uuid} + */ function createUuidFromBuffer (buffer) { //clear the version buffer[6] &= 0x0f; @@ -124,12 +131,9 @@ function getHex (uuid) { */ function getRandomBytes (cb) { if (cb) { - crypto.randomBytes(16, (err, buf) => { - return cb(err, buf); - }); - } else { - return crypto.randomBytes(16); - } + return crypto.randomBytes(16, cb); + } + return crypto.randomBytes(16); }; module.exports = Uuid; From 47a160693088e2d5e807d2b88e40b3ac31064157 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20T=C3=B6rnstr=C3=B6m=20Andersson?= Date: Tue, 5 Sep 2017 20:28:37 +0200 Subject: [PATCH 4/8] NODEJS-375 Fixed stupid error when refactoring code --- lib/types/uuid.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/types/uuid.js b/lib/types/uuid.js index 2e6fa1aa1..4bebbe148 100644 --- a/lib/types/uuid.js +++ b/lib/types/uuid.js @@ -37,7 +37,7 @@ Uuid.fromString = function (value) { * @returns {Uuid} */ Uuid.random = function (callback) { - if (cb) { + if (callback) { getRandomBytes(function(err, buffer) { if (err) { return callback(err); From 34be9bbae3660220dc6bb2fff6bfe98bcc2fa7f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20T=C3=B6rnstr=C3=B6m=20Andersson?= Date: Tue, 5 Sep 2017 20:39:12 +0200 Subject: [PATCH 5/8] NODEJS-375 Removed promise to support old node version --- test/unit/uuid-tests.js | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/test/unit/uuid-tests.js b/test/unit/uuid-tests.js index 789ebf885..e535d8c23 100644 --- a/test/unit/uuid-tests.js +++ b/test/unit/uuid-tests.js @@ -132,24 +132,20 @@ describe('Uuid', function () { var values = {}; var promises = []; var length = 100000; + var count = length; for (var i = 0; i < length; i++) { - promises.push(new Promise(function(resolve, reject) { - Uuid.random(function(err, val) { - if (err) { - return reject(err); - } - values[val.toString()] = true; - resolve(); - }); - })); + Uuid.random(function(err, val) { + if (err) { + return assert.fail(err); + } + values[val.toString()] = true; + --count; + if (count == 0) { + assert.strictEqual(Object.keys(values).length, length); + done(); + } + }); } - Promise.all(promises).then(function() { - assert.strictEqual(Object.keys(values).length, length); - done(); - }).catch(function(err) { - assert.fail(err); - }); - }); }); }); From e208ea4293d1e3964b49443039770b5257b3e700 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20T=C3=B6rnstr=C3=B6m=20Andersson?= Date: Tue, 5 Sep 2017 20:45:31 +0200 Subject: [PATCH 6/8] NODEJS-375 fixed linting --- lib/types/uuid.js | 2 +- test/unit/uuid-tests.js | 26 ++++++++++++++------------ 2 files changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/types/uuid.js b/lib/types/uuid.js index 4bebbe148..346afb4f3 100644 --- a/lib/types/uuid.js +++ b/lib/types/uuid.js @@ -134,6 +134,6 @@ function getRandomBytes (cb) { return crypto.randomBytes(16, cb); } return crypto.randomBytes(16); -}; +} module.exports = Uuid; diff --git a/test/unit/uuid-tests.js b/test/unit/uuid-tests.js index e535d8c23..7c9c04657 100644 --- a/test/unit/uuid-tests.js +++ b/test/unit/uuid-tests.js @@ -130,21 +130,23 @@ describe('Uuid', function () { }); it('should generate v4 uuids that do not collide', function (done) { var values = {}; - var promises = []; var length = 100000; var count = length; + + function callback(err, val) { + if (err) { + return assert.fail(err); + } + values[val.toString()] = true; + --count; + if (count === 0) { + assert.strictEqual(Object.keys(values).length, length); + done(); + } + } + for (var i = 0; i < length; i++) { - Uuid.random(function(err, val) { - if (err) { - return assert.fail(err); - } - values[val.toString()] = true; - --count; - if (count == 0) { - assert.strictEqual(Object.keys(values).length, length); - done(); - } - }); + Uuid.random(callback); } }); }); From 2006ca047815ef08ceb0bdf837b655fd3f9956da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20T=C3=B6rnstr=C3=B6m=20Andersson?= Date: Wed, 6 Sep 2017 20:11:21 +0200 Subject: [PATCH 7/8] NODEJS-375 fixed tests --- test/unit/uuid-tests.js | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/test/unit/uuid-tests.js b/test/unit/uuid-tests.js index 7c9c04657..dad77f845 100644 --- a/test/unit/uuid-tests.js +++ b/test/unit/uuid-tests.js @@ -110,7 +110,7 @@ describe('Uuid', function () { this.timeout(5000); it('should return a Uuid instance', function (done) { Uuid.random(function(err, uuid) { - helper.assertInstanceOf(Uuid.random(), Uuid); + helper.assertInstanceOf(uuid, Uuid); done(); }); @@ -119,13 +119,15 @@ describe('Uuid', function () { Uuid.random(function(err, val) { assert.strictEqual(val.toString().charAt(14), '4'); assert.ok(['8', '9', 'a', 'b'].indexOf(val.toString().charAt(19)) >= 0); - val = Uuid.random(); - assert.strictEqual(val.toString().charAt(14), '4'); - assert.ok(['8', '9', 'a', 'b'].indexOf(val.toString().charAt(19)) >= 0); - val = Uuid.random(); - assert.strictEqual(val.toString().charAt(14), '4'); - assert.ok(['8', '9', 'a', 'b'].indexOf(val.toString().charAt(19)) >= 0); - done(); + Uuid.random(function(err, val) { + assert.strictEqual(val.toString().charAt(14), '4'); + assert.ok(['8', '9', 'a', 'b'].indexOf(val.toString().charAt(19)) >= 0); + Uuid.random(function(err, val) { + assert.strictEqual(val.toString().charAt(14), '4'); + assert.ok(['8', '9', 'a', 'b'].indexOf(val.toString().charAt(19)) >= 0); + done(); + }); + }); }); }); it('should generate v4 uuids that do not collide', function (done) { @@ -144,7 +146,7 @@ describe('Uuid', function () { done(); } } - + for (var i = 0; i < length; i++) { Uuid.random(callback); } From de34e07defa6068316cdeac7256cc3bdd04d4f6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20T=C3=B6rnstr=C3=B6m=20Andersson?= Date: Fri, 8 Sep 2017 19:10:13 +0200 Subject: [PATCH 8/8] NODEJS-375 fixed review comments --- lib/types/uuid.js | 5 +---- test/unit/uuid-tests.js | 33 +++++++++++++++------------------ 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/lib/types/uuid.js b/lib/types/uuid.js index 346afb4f3..88cc7b9bb 100644 --- a/lib/types/uuid.js +++ b/lib/types/uuid.js @@ -130,10 +130,7 @@ function getHex (uuid) { * @returns {Buffer} */ function getRandomBytes (cb) { - if (cb) { - return crypto.randomBytes(16, cb); - } - return crypto.randomBytes(16); + return crypto.randomBytes(16, cb); } module.exports = Uuid; diff --git a/test/unit/uuid-tests.js b/test/unit/uuid-tests.js index dad77f845..fdbceb54d 100644 --- a/test/unit/uuid-tests.js +++ b/test/unit/uuid-tests.js @@ -1,7 +1,7 @@ 'use strict'; var assert = require('assert'); var helper = require('../test-helper'); - +var utils = require('../../lib/utils'); var Uuid = require('../../lib/types').Uuid; var TimeUuid = require('../../lib/types').TimeUuid; @@ -133,23 +133,20 @@ describe('Uuid', function () { it('should generate v4 uuids that do not collide', function (done) { var values = {}; var length = 100000; - var count = length; - - function callback(err, val) { - if (err) { - return assert.fail(err); - } - values[val.toString()] = true; - --count; - if (count === 0) { - assert.strictEqual(Object.keys(values).length, length); - done(); - } - } - - for (var i = 0; i < length; i++) { - Uuid.random(callback); - } + + utils.times(length, function eachTime(n, next) { + Uuid.random(function (err, val) { + if (err) { + return next(err); + } + values[val.toString()] = true; + next(); + }); + }, function finish(err) { + assert.ifError(err); + assert.strictEqual(Object.keys(values).length, length); + done(); + }); }); }); });