From 9d706d64ee6cb90df3d4b88de63bd4fc6e468b99 Mon Sep 17 00:00:00 2001 From: ldstein Date: Fri, 6 Dec 2013 19:07:48 +0800 Subject: [PATCH 01/14] Removed \n from static file test (\r\n in Windows) --- test/static/test | 2 +- test/websocket_secure_spec.js | 2 +- test/websocket_spec.js | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/static/test b/test/static/test index d81cc07..f70d7bb 100644 --- a/test/static/test +++ b/test/static/test @@ -1 +1 @@ -42 +42 \ No newline at end of file diff --git a/test/websocket_secure_spec.js b/test/websocket_secure_spec.js index 30d0c68..965b6f6 100644 --- a/test/websocket_secure_spec.js +++ b/test/websocket_secure_spec.js @@ -53,7 +53,7 @@ describe("mosca.Server - Secure Websocket", function() { var curPort = nextPort() - 1; var req = request("https://localhost:" + curPort); - req.get('/test').expect(200, "42\n").end(done); + req.get('/test').expect(200, "42").end(done); }); it("should serve a browserify bundle", function(done) { diff --git a/test/websocket_spec.js b/test/websocket_spec.js index 7b956e0..648c6b1 100644 --- a/test/websocket_spec.js +++ b/test/websocket_spec.js @@ -34,7 +34,7 @@ describe("mosca.Server - Websocket", function() { var curPort = nextPort() - 1; var req = request("http://localhost:" + curPort); - req.get('/test').expect(200, "42\n").end(done); + req.get('/test').expect(200, "42").end(done); }); it("should serve a browserify bundle", function(done) { From add79a66e70f39554ba8dc666e14740dedba9a37 Mon Sep 17 00:00:00 2001 From: ldstein Date: Fri, 6 Dec 2013 19:09:47 +0800 Subject: [PATCH 02/14] Bumped microtime to 0.5 (Win compatible) Moved async_bench to optionalDepencies (not Win compatible) --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 987dcc3..f490537 100644 --- a/package.json +++ b/package.json @@ -36,9 +36,8 @@ "chai": "~1.8.0", "sinon": "~1.4.2", "sinon-chai": "~2.1.2", - "async_bench": "0.2.1", "underscore": "~1.4.4", - "microtime": "~0.3.3", + "microtime": "~0.5.0", "dox-foundation": "~0.4.4", "jshint": "~1.0.0", "js-beautify": "~0.4.2", @@ -68,8 +67,9 @@ "json-buffer": "~2.0.7" }, "optionalDependencies": { - "leveldown": "~0.9.0", - "zmq": "~2.4.0", + "async_bench": "0.2.1", + "leveldown": "~0.9.0", + "zmq": "~2.4.0", "amqp": "~0.1.4", "redis": "~0.8.2", "mongodb": "~1.3.10" From 03ff36abd374689c75cb6f0875b8b6e8b4076d48 Mon Sep 17 00:00:00 2001 From: ldstein Date: Fri, 6 Dec 2013 19:13:26 +0800 Subject: [PATCH 03/14] Fixed spaces --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index f490537..76a5814 100644 --- a/package.json +++ b/package.json @@ -68,8 +68,8 @@ }, "optionalDependencies": { "async_bench": "0.2.1", - "leveldown": "~0.9.0", - "zmq": "~2.4.0", + "leveldown": "~0.9.0", + "zmq": "~2.4.0", "amqp": "~0.1.4", "redis": "~0.8.2", "mongodb": "~1.3.10" From 4d7b19b768b7a50a98ec31cc2ffc3e5d63900185 Mon Sep 17 00:00:00 2001 From: ldstein Date: Mon, 9 Dec 2013 12:37:11 +0800 Subject: [PATCH 04/14] Added test for single retained message --- test/persistence/abstract.js | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/test/persistence/abstract.js b/test/persistence/abstract.js index 45d0d3b..7b02d1e 100644 --- a/test/persistence/abstract.js +++ b/test/persistence/abstract.js @@ -84,6 +84,39 @@ module.exports = function(create, buildOpts) { ], done); }); + it("should match and load a single retained message", function(done) { + + var packetMessageId = 0; + + var getPacket = function(){ + + packetMessageId++; + + return { + topic: "hello", + qos: 0, + payload: new Buffer("world"), + messageId: packetMessageId, + retain: true + }; + }; + + var instance = this.instance; + + async.parallel([ + function(cb) { instance.storeRetained(getPacket(), cb); }, + function(cb) { instance.storeRetained(getPacket(), cb); }, + function(cb) { instance.storeRetained(getPacket(), cb); }, + function(cb) { instance.storeRetained(getPacket(), cb); }, + function(cb) { instance.storeRetained(getPacket(), cb); } + ], function(err, results) { + instance.lookupRetained("hello", function(err, results) { + expect(results.length).to.be.eql(1); + done(); + }); + }); + }); + it("should overwrite a retained message", function(done) { var packet = { topic: "hello", From 5d88fb432cf33e1a22dc91ceddc99df52dc01122 Mon Sep 17 00:00:00 2001 From: ldstein Date: Mon, 9 Dec 2013 15:39:58 +0800 Subject: [PATCH 05/14] Ignore SIGHUP test on Windows --- test/cli_spec.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/cli_spec.js b/test/cli_spec.js index 5b8ed74..66676af 100644 --- a/test/cli_spec.js +++ b/test/cli_spec.js @@ -2,6 +2,7 @@ var async = require("async"); var tmp = require('tmp'); var fs = require("fs"); var mqtt = require("mqtt"); +var os = require("os"); var SECURE_KEY = __dirname + '/secure/tls-key.pem'; var SECURE_CERT = __dirname + '/secure/tls-cert.pem'; @@ -318,12 +319,16 @@ describe("mosca.cli", function() { }); }); - it("should reload the config using if killed with SIGHUP", function(done) { + //Todo: Fix for windows + it("should reload the current config if killed with SIGHUP on a Linux-based OS", function(done) { + + if(os.platform() === "win32") return done(); + args.push("adduser"); args.push("myuser"); args.push("mypass"); args.push("--credentials"); - + var cloned = null; async.waterfall([ From 374631dd71b766fe85b3b1d20ab2fa6a82ee19e3 Mon Sep 17 00:00:00 2001 From: ldstein Date: Mon, 9 Dec 2013 18:01:55 +0800 Subject: [PATCH 06/14] Removed Redis (not used in module) --- test/persistence/mongo_spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/persistence/mongo_spec.js b/test/persistence/mongo_spec.js index f0ce6b2..553ca61 100644 --- a/test/persistence/mongo_spec.js +++ b/test/persistence/mongo_spec.js @@ -2,7 +2,6 @@ var abstract = require("./abstract"); var Mongo = require("../../").persistence.Mongo; -var redis = require("redis"); var MongoClient = require('mongodb').MongoClient; var async = require("async"); From 05a9aae7d606c82f1ee3f9a5b0e50d0bdc8994b5 Mon Sep 17 00:00:00 2001 From: ldstein Date: Mon, 9 Dec 2013 18:03:18 +0800 Subject: [PATCH 07/14] Fixed multiple retained messages being returned on Subscribe when Persistence is set to MongoDB. --- lib/persistence/mongo.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/lib/persistence/mongo.js b/lib/persistence/mongo.js index 628997f..3e903cb 100644 --- a/lib/persistence/mongo.js +++ b/lib/persistence/mongo.js @@ -155,14 +155,24 @@ MongoPersistence.prototype.lookupSubscriptions = function(client, done) { }; MongoPersistence.prototype.storeRetained = function(packet, cb) { - var that = this; - this._retained.remove({ topic: packet.topic }, function(err) { - that._retained.insert(packet, function(err) { - if (cb) { + + this._retained.findAndModify( + { topic: packet.topic }, + [], + packet, + { + upsert: true, + new: true + }, + function(err, result){ + if(!err) { + packet._id = result._id; + } + if(cb) { return cb(err); } }); - }); + }; MongoPersistence.prototype.lookupRetained = function(pattern, cb) { From bbe73460515eb98bbb14aa5ec6acc164dc48dfaa Mon Sep 17 00:00:00 2001 From: ldstein Date: Mon, 9 Dec 2013 18:03:51 +0800 Subject: [PATCH 08/14] Added unit test "should return a single retained message" --- test/abstract_server.js | 105 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/test/abstract_server.js b/test/abstract_server.js index 0540900..f3bc045 100644 --- a/test/abstract_server.js +++ b/test/abstract_server.js @@ -1240,6 +1240,111 @@ module.exports = function(moscaSettings, createConnection) { ], done); }); + it("should return only a single retained message", function(done) { + var pers = new mosca.persistence.Memory({},function(){ + + pers.wire(instance); + + async.waterfall([ + + function(cb) { + var client = createConnection(settings.port, settings.host); + + var defaultMessage = { + topic: "hello", + qos: 0, + payload: null, + messageId: null, + retain: true + } + + client.on("connected", function() { + var opts = buildOpts(); + opts.clean = true; + + var totalMessages = 10; + var publishCount = 0; + + client.connect(opts); + + client.on('publish', function(packet){ + publishCount++; + if(publishCount == totalMessages) + { + client.stream.end(); + cb(); + } + + }); + + client.on('connack', function(packet) { + + var subscriptions = [{ + topic: "hello", + qos: 0 + }]; + + client.subscribe({ + subscriptions: subscriptions, + messageId: 20 + }); + + for(var c = 1 ; c <= 10 ; c++) + { + defaultMessage.payload = (c == totalMessages) ? new Buffer("Final Message") : new Buffer("Message " + c); + defaultMessage.messageId = 40 + c; + client.publish(defaultMessage); + } + + }); + }); + }, + + function(cb) { + var client = createConnection(settings.port, settings.host); + + var retainedReceivedCount = 0; + + client.on("connected", function() { + var opts = buildOpts(); + opts.clean = true; + + client.connect(opts); + + client.on('connack', function(packet) { + var subscriptions = [{ + topic: "hello", + qos: 0 + } + ]; + + client.subscribe({ + subscriptions: subscriptions, + messageId: 20 + }); + }); + + var handleTimeout = function(){ + expect(retainedReceivedCount).to.be.equal(1); + client.stream.end(); + cb(); + } + + var timeout; + + client.on("publish", function(packet) { + clearInterval(timeout); + timeout = setTimeout(handleTimeout, 100); + retainedReceivedCount ++; + }); + + }); + } + ], done); + + }); + }); + it("should support unclean clients", function(done) { var pers = new mosca.persistence.Memory(); var opts = buildOpts(); From a48acfb47e212faf92f32ca9fb7dbb56f46c7a50 Mon Sep 17 00:00:00 2001 From: ldstein Date: Mon, 9 Dec 2013 18:05:48 +0800 Subject: [PATCH 09/14] Replaced tabs with spaces in package.json --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 76a5814..d88c3d2 100644 --- a/package.json +++ b/package.json @@ -68,8 +68,8 @@ }, "optionalDependencies": { "async_bench": "0.2.1", - "leveldown": "~0.9.0", - "zmq": "~2.4.0", + "leveldown": "~0.9.0", + "zmq": "~2.4.0", "amqp": "~0.1.4", "redis": "~0.8.2", "mongodb": "~1.3.10" From c24cd221ab4ea5e77145087959909a64ce0729dd Mon Sep 17 00:00:00 2001 From: ldstein Date: Tue, 10 Dec 2013 16:05:47 +0800 Subject: [PATCH 10/14] Removed a closure from "should return only a single retained message" --- test/abstract_server.js | 154 ++++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 78 deletions(-) diff --git a/test/abstract_server.js b/test/abstract_server.js index f3bc045..f24af2b 100644 --- a/test/abstract_server.js +++ b/test/abstract_server.js @@ -1218,10 +1218,9 @@ module.exports = function(moscaSettings, createConnection) { client.on('connack', function(packet) { var subscriptions = [{ - topic: "hello", - qos: 0 - } - ]; + topic: "hello", + qos: 0 + }]; client.subscribe({ subscriptions: subscriptions, @@ -1241,108 +1240,107 @@ module.exports = function(moscaSettings, createConnection) { }); it("should return only a single retained message", function(done) { - var pers = new mosca.persistence.Memory({},function(){ - pers.wire(instance); + var pers = new mosca.persistence.Memory(); - async.waterfall([ + pers.wire(instance); - function(cb) { - var client = createConnection(settings.port, settings.host); + async.waterfall([ - var defaultMessage = { - topic: "hello", - qos: 0, - payload: null, - messageId: null, - retain: true - } + function(cb) { + var client = createConnection(settings.port, settings.host); + client.name = "Phase 1"; + var defaultMessage = { + topic: "hello", + qos: 0, + payload: null, + messageId: null, + retain: true + } - client.on("connected", function() { - var opts = buildOpts(); - opts.clean = true; + client.on("connected", function() { + var opts = buildOpts(); + opts.clean = true; - var totalMessages = 10; - var publishCount = 0; + var totalMessages = 10; + var publishCount = 0; - client.connect(opts); + client.connect(opts); - client.on('publish', function(packet){ - publishCount++; - if(publishCount == totalMessages) - { + client.on('publish', function(packet){ + publishCount++; + if(publishCount == totalMessages) + { client.stream.end(); - cb(); - } + cb(); + } - }); + }); - client.on('connack', function(packet) { + client.on('connack', function(packet) { - var subscriptions = [{ - topic: "hello", - qos: 0 - }]; + var subscriptions = [{ + topic: "hello", + qos: 0 + }]; - client.subscribe({ - subscriptions: subscriptions, - messageId: 20 - }); + client.subscribe({ + subscriptions: subscriptions, + messageId: 20 + }); - for(var c = 1 ; c <= 10 ; c++) - { - defaultMessage.payload = (c == totalMessages) ? new Buffer("Final Message") : new Buffer("Message " + c); - defaultMessage.messageId = 40 + c; - client.publish(defaultMessage); - } + for(var c = 1 ; c <= 10 ; c++) + { + defaultMessage.payload = (c == totalMessages) ? new Buffer("Final Message") : new Buffer("Message " + c); + defaultMessage.messageId = 40 + c; + client.publish(defaultMessage); + } - }); }); - }, + }); + }, - function(cb) { - var client = createConnection(settings.port, settings.host); + function(cb) { + var client = createConnection(settings.port, settings.host); - var retainedReceivedCount = 0; + var retainedReceivedCount = 0; - client.on("connected", function() { - var opts = buildOpts(); - opts.clean = true; + client.on("connected", function() { + var opts = buildOpts(); + opts.clean = true; - client.connect(opts); + client.connect(opts); - client.on('connack', function(packet) { - var subscriptions = [{ - topic: "hello", - qos: 0 - } - ]; + client.on('connack', function(packet) { + var subscriptions = [{ + topic: "hello", + qos: 0 + } + ]; - client.subscribe({ - subscriptions: subscriptions, - messageId: 20 - }); + client.subscribe({ + subscriptions: subscriptions, + messageId: 20 }); + }); - var handleTimeout = function(){ - expect(retainedReceivedCount).to.be.equal(1); - client.stream.end(); - cb(); - } + var handleTimeout = function(){ + expect(retainedReceivedCount).to.be.equal(1); + client.stream.end(); + cb(); + } - var timeout; - - client.on("publish", function(packet) { - clearInterval(timeout); - timeout = setTimeout(handleTimeout, 100); - retainedReceivedCount ++; - }); + var timeout; + client.on("publish", function(packet) { + clearInterval(timeout); + timeout = setTimeout(handleTimeout, 100); + retainedReceivedCount ++; }); - } - ], done); - }); + }); + } + ], done); }); it("should support unclean clients", function(done) { From 3d85359b8dd65cacfc46ef565836d875dd9e9aea Mon Sep 17 00:00:00 2001 From: ldstein Date: Tue, 10 Dec 2013 16:12:44 +0800 Subject: [PATCH 11/14] Fixed callback not firing on Client.close when stream is previously destroyed. --- lib/client.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/lib/client.js b/lib/client.js index d4987d2..548f392 100644 --- a/lib/client.js +++ b/lib/client.js @@ -513,8 +513,14 @@ Client.prototype.close = function(callback) { that._closing = true; async.parallel(Object.keys(that.subscriptions).map(that.unsubscribeMapTo.bind(that)), function() { that.server.persistClient(that); - that.connection.stream.on('end', cleanup); - that.connection.stream.end(); + if(that.connection.stream.destroyed){ + if(callback) { + callback(); + } + } else { + that.connection.stream.on('end', cleanup); + that.connection.stream.end(); + } }); }; From 2dbfab842ee9f30ac45b43bd1e90b8c706bd330c Mon Sep 17 00:00:00 2001 From: ldstein Date: Tue, 10 Dec 2013 16:19:12 +0800 Subject: [PATCH 12/14] Removed TODO --- test/cli_spec.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/cli_spec.js b/test/cli_spec.js index 66676af..206f699 100644 --- a/test/cli_spec.js +++ b/test/cli_spec.js @@ -319,7 +319,6 @@ describe("mosca.cli", function() { }); }); - //Todo: Fix for windows it("should reload the current config if killed with SIGHUP on a Linux-based OS", function(done) { if(os.platform() === "win32") return done(); From d20bdc96511017b4c4a7a23d0b9dbaee2885764c Mon Sep 17 00:00:00 2001 From: ldstein Date: Tue, 10 Dec 2013 18:58:51 +0800 Subject: [PATCH 13/14] Modified Client.close to handle streams which have already ended. --- lib/client.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/lib/client.js b/lib/client.js index 548f392..d874635 100644 --- a/lib/client.js +++ b/lib/client.js @@ -510,13 +510,16 @@ Client.prototype.close = function(callback) { } }; + that.connection.stream.on('end' , function(){ + that._streamClosedRequiresCleanup = true; + }); + that._closing = true; + async.parallel(Object.keys(that.subscriptions).map(that.unsubscribeMapTo.bind(that)), function() { that.server.persistClient(that); - if(that.connection.stream.destroyed){ - if(callback) { - callback(); - } + if(that._streamClosedRequiresCleanup){ + cleanup(); } else { that.connection.stream.on('end', cleanup); that.connection.stream.end(); From ad6b5461cbd99276fb05e0d6948bf21ede424add Mon Sep 17 00:00:00 2001 From: Matteo Collina Date: Tue, 10 Dec 2013 14:33:48 +0100 Subject: [PATCH 14/14] Bumped back mongodb dependency to 1.3.19. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index e66294d..f5d949f 100644 --- a/package.json +++ b/package.json @@ -86,6 +86,6 @@ "zmq": "~2.4.0", "amqp": "~0.1.8", "redis": "~0.8.2", - "mongodb": "~1.3.20" + "mongodb": "~1.3.19" } }