From d146e7ceeec7306681b520e332926984d583d6a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Fri, 12 Feb 2016 15:30:53 +0100 Subject: [PATCH 1/9] Move from statsd-node to node-statsd and use tags. --- loop/auth.js | 2 +- loop/index.js | 2 +- loop/routes/home.js | 9 ++++----- loop/simplepush.js | 18 ++++++------------ loop/tokbox.js | 2 +- package.json | 2 +- test/functional_test.js | 31 ++++++++++++------------------- test/fxa_oauth_tests.js | 9 ++++----- test/simplepush_test.js | 22 ++++++++-------------- test/tokbox_test.js | 4 ++-- 10 files changed, 40 insertions(+), 61 deletions(-) diff --git a/loop/auth.js b/loop/auth.js index a532020..74db1e8 100644 --- a/loop/auth.js +++ b/loop/auth.js @@ -76,7 +76,7 @@ module.exports = function(conf, logError, storage, statsdClient) { var hawkIdHmac = hmac(tokenId, conf.get("hawkIdSecret")); storage.setHawkSession(hawkIdHmac, authKey, function(err) { if (statsdClient && err === null) { - statsdClient.count('loop.activated-users', 1); + statsdClient.increment('loop.activated-users'); } callback(err); }); diff --git a/loop/index.js b/loop/index.js index 957149d..504ff15 100644 --- a/loop/index.js +++ b/loop/index.js @@ -24,7 +24,7 @@ var express = require('express'); var bodyParser = require('body-parser'); var raven = require('raven'); var cors = require('cors'); -var StatsdClient = require('statsd-node').client; +var StatsdClient = require('node-statsd'); var PubSub = require('./pubsub'); diff --git a/loop/routes/home.js b/loop/routes/home.js index dda8dda..830b97e 100644 --- a/loop/routes/home.js +++ b/loop/routes/home.js @@ -81,14 +81,13 @@ module.exports = function(app, conf, logError, storage, tokBox, statsdClient) { var pushStatus = (!error && statusCodes.every(isSuccess)); returnStatus(storageStatus, tokboxError, pushStatus, verifierStatus); if (statsdClient !== undefined) { - statsdClient.count('loop.simplepush.call', 1); - var counter_push_status_counter; + var tag; if (pushStatus) { - counter_push_status_counter = 'loop.simplepush.call.heartbeat.success'; + tag = 'success'; } else { - counter_push_status_counter = 'loop.simplepush.call.heartbeat.failures'; + tag = 'failure'; } - statsdClient.count(counter_push_status_counter, 1); + statsdClient.increment('loop.simplepush.call', 1, [tag]); } }); }); diff --git a/loop/simplepush.js b/loop/simplepush.js index bbbf6b9..c040081 100644 --- a/loop/simplepush.js +++ b/loop/simplepush.js @@ -26,23 +26,17 @@ SimplePush.prototype = { var self = this; urls.forEach(function(simplePushUrl) { - if (self.statsdClient !== undefined) { - self.statsdClient.count("loop.simplepush.call", 1); - self.statsdClient.count("loop.simplepush.call." + reason, 1); - } request.put({ url: simplePushUrl, form: { version: version } }, function(err) { + var status = 'success'; + if (err) { + self.logError(err); + status = 'failure'; + } if (self.statsdClient !== undefined) { - if (err) { - self.logError(err); - self.statsdClient.count("loop.simplepush.call.failures", 1); - self.statsdClient.count("loop.simplepush.call." + reason + ".failures", 1); - } else { - self.statsdClient.count("loop.simplepush.call.success", 1); - self.statsdClient.count("loop.simplepush.call." + reason + ".success", 1); - } + self.statsdClient.increment("loop.simplepush.call", 1, [reason, status]); } }); }); diff --git a/loop/tokbox.js b/loop/tokbox.js index 1153014..9a6bad0 100644 --- a/loop/tokbox.js +++ b/loop/tokbox.js @@ -72,7 +72,7 @@ TokBox.prototype = { return; } if (self.statsdClient !== undefined) { - self.statsdClient.count("loop.tokbox.createSession.count", 1); + self.statsdClient.increment("loop.tokbox.createSession.count"); self.statsdClient.timing( 'loop.tokbox.createSession', Date.now() - startTime diff --git a/package.json b/package.json index 7fb66e6..08e28cc 100644 --- a/package.json +++ b/package.json @@ -37,7 +37,7 @@ "redis": "0.12.1", "request": "2.45.0", "sodium": "1.0.13", - "statsd-node": "0.2.3", + "node-statsd": "0.1.1", "strftime": "0.8.2", "urlsafe-base64": "1.0.0", "ws": "1.0.1", diff --git a/test/functional_test.js b/test/functional_test.js index bb3b0d9..43c406b 100644 --- a/test/functional_test.js +++ b/test/functional_test.js @@ -393,7 +393,7 @@ function runOnPrefix(apiPrefix) { } }); - sandbox.stub(statsdClient, "count"); + sandbox.stub(statsdClient, "increment"); supertest(app) .get(apiPrefix + '/__heartbeat__') @@ -406,10 +406,8 @@ function runOnPrefix(apiPrefix) { 'push': false, 'fxaVerifier': true }); - assert.calledTwice(statsdClient.count); - assert.calledWithExactly(statsdClient.count, "loop.simplepush.call", 1); - assert.calledWithExactly(statsdClient.count, - "loop.simplepush.call.heartbeat.failures", 1); + assert.calledOnce(statsdClient.increment); + assert.calledWithExactly(statsdClient.increment, "loop.simplepush.call", 1, ['failure']); done(); }); }); @@ -464,7 +462,7 @@ function runOnPrefix(apiPrefix) { callback(null, {statusCode: 200}); }); - sandbox.stub(statsdClient, "count"); + sandbox.stub(statsdClient, "increment"); supertest(app) .get(apiPrefix + '/__heartbeat__') @@ -477,11 +475,8 @@ function runOnPrefix(apiPrefix) { 'push': true, 'fxaVerifier': true }); - assert.calledTwice(statsdClient.count); - assert.calledWithExactly(statsdClient.count, "loop.simplepush.call", 1); - assert.calledWithExactly(statsdClient.count, - "loop.simplepush.call.heartbeat.success", 1); - + assert.calledOnce(statsdClient.increment); + assert.calledWithExactly(statsdClient.increment, "loop.simplepush.call", 1, ['success']); done(); }); }); @@ -778,7 +773,7 @@ function runOnPrefix(apiPrefix) { }); it("should count new users if the session is created", function(done) { - sandbox.stub(statsdClient, "count"); + sandbox.stub(statsdClient, "increment"); supertest(app) .post(apiPrefix + '/registration') .type('json') @@ -786,25 +781,23 @@ function runOnPrefix(apiPrefix) { 'simplePushURL': pushURL }).expect(200).end(function(err) { if (err) throw err; - assert.calledOnce(statsdClient.count); + assert.calledOnce(statsdClient.increment); assert.calledWithExactly( - statsdClient.count, - "loop.activated-users", - 1 - ); + statsdClient.increment, + "loop.activated-users"); done(); }); }); it("shouldn't count a new user if the session already exists", function(done) { - sandbox.stub(statsdClient, "count"); + sandbox.stub(statsdClient, "increment"); jsonReq .send({ 'simple_push_url': pushURL }).expect(200).end(function(err) { if (err) throw err; - assert.notCalled(statsdClient.count); + assert.notCalled(statsdClient.increment); done(); }); }); diff --git a/test/fxa_oauth_tests.js b/test/fxa_oauth_tests.js index 07c12dc..76f943d 100644 --- a/test/fxa_oauth_tests.js +++ b/test/fxa_oauth_tests.js @@ -116,17 +116,16 @@ describe('/fxa-oauth', function () { }); it("should count new users if the session is created", function(done) { - sandbox.stub(statsdClient, "count"); + sandbox.stub(statsdClient, "increment"); supertest(app) .post(apiPrefix + '/fxa-oauth/params') .type('json') .send({}).expect(200).end(function(err) { if (err) throw err; - assert.calledOnce(statsdClient.count); + assert.calledOnce(statsdClient.increment); assert.calledWithExactly( - statsdClient.count, - "loop.activated-users", - 1 + statsdClient.increment, + "loop.activated-users" ); done(); }); diff --git a/test/simplepush_test.js b/test/simplepush_test.js index 9ae7ca7..8cf6aec 100644 --- a/test/simplepush_test.js +++ b/test/simplepush_test.js @@ -55,17 +55,14 @@ describe("simplePush object", function() { }); it("should notify using the statsd client if present", function() { - var statsdClient = { count: function() {} }; - var statsdSpy = sandbox.spy(statsdClient, "count"); + var statsdClient = { increment: function() {} }; + var statsdSpy = sandbox.spy(statsdClient, "increment"); var simplePush = new SimplePush(statsdClient); simplePush.notify("reason", "url1", 12345); - assert.callCount(statsdSpy, 4); - assert.calledWithExactly(statsdSpy, "loop.simplepush.call.reason", 1); - assert.calledWithExactly(statsdSpy, "loop.simplepush.call", 1); - assert.calledWithExactly(statsdSpy, "loop.simplepush.call.success", 1); - assert.calledWithExactly(statsdSpy, "loop.simplepush.call.reason.success", 1); + assert.calledOnce(statsdSpy); + assert.calledWithExactly(statsdSpy, "loop.simplepush.call", 1, ["reason", "success"]); }); it("should notify using the statsd client for errors if present", function() { @@ -78,16 +75,13 @@ describe("simplePush object", function() { callback("error"); }); - var statsdClient = { count: function() {} }; - var statsdSpy = sandbox.spy(statsdClient, "count"); + var statsdClient = { increment: function() {} }; + var statsdSpy = sandbox.spy(statsdClient, "increment"); var simplePush = new SimplePush(statsdClient); simplePush.notify("reason", "url1", 12345); - assert.callCount(statsdSpy, 4); - assert.calledWithExactly(statsdSpy, "loop.simplepush.call.reason", 1); - assert.calledWithExactly(statsdSpy, "loop.simplepush.call", 1); - assert.calledWithExactly(statsdSpy, "loop.simplepush.call.failures", 1); - assert.calledWithExactly(statsdSpy, "loop.simplepush.call.reason.failures", 1); + assert.calledOnce(statsdSpy); + assert.calledWithExactly(statsdSpy, "loop.simplepush.call", 1, ["reason", "failure"]); }); }); diff --git a/test/tokbox_test.js b/test/tokbox_test.js index e3e3480..5172658 100644 --- a/test/tokbox_test.js +++ b/test/tokbox_test.js @@ -74,9 +74,9 @@ describe("TokBox", function() { var tokBox, openTokSpy, statsdClient, statsdTimer, statsdCount; beforeEach(function() { - statsdClient = { timing: function() {}, count: function() {} }; + statsdClient = { timing: function() {}, increment: function() {} }; statsdTimer = sandbox.spy(statsdClient, "timing"); - statsdCount = sandbox.spy(statsdClient, "count"); + statsdCount = sandbox.spy(statsdClient, "increment"); openTokSpy = sandbox.spy(loopTokbox, "OpenTok"); openTokSpy.withArgs( From 045eb491fce95c6a6d076744eeeb722d9f57068a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Tue, 23 Feb 2016 13:37:02 +0100 Subject: [PATCH 2/9] @tarekziade review. --- loop/routes/home.js | 2 +- test/functional_test.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/loop/routes/home.js b/loop/routes/home.js index 830b97e..0604eb0 100644 --- a/loop/routes/home.js +++ b/loop/routes/home.js @@ -87,7 +87,7 @@ module.exports = function(app, conf, logError, storage, tokBox, statsdClient) { } else { tag = 'failure'; } - statsdClient.increment('loop.simplepush.call', 1, [tag]); + statsdClient.increment('loop.simplepush.call.heartbeat', 1, [tag]); } }); }); diff --git a/test/functional_test.js b/test/functional_test.js index 43c406b..bd52ca6 100644 --- a/test/functional_test.js +++ b/test/functional_test.js @@ -407,7 +407,7 @@ function runOnPrefix(apiPrefix) { 'fxaVerifier': true }); assert.calledOnce(statsdClient.increment); - assert.calledWithExactly(statsdClient.increment, "loop.simplepush.call", 1, ['failure']); + assert.calledWithExactly(statsdClient.increment, "loop.simplepush.call.heartbeat", 1, ['failure']); done(); }); }); @@ -476,7 +476,7 @@ function runOnPrefix(apiPrefix) { 'fxaVerifier': true }); assert.calledOnce(statsdClient.increment); - assert.calledWithExactly(statsdClient.increment, "loop.simplepush.call", 1, ['success']); + assert.calledWithExactly(statsdClient.increment, "loop.simplepush.call.heartbeat", 1, ['success']); done(); }); }); From 42734c03c2f232ac7ecdc58072fe94b0e8ec0260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Fri, 12 Feb 2016 16:58:42 +0100 Subject: [PATCH 3/9] Release 0.19.3 --- CHANGELOG | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a4499bb..115572b 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,10 +3,10 @@ Changelog This document describes changes between each past release. -0.20.0 (unreleased) +0.19.3 (2016-02-12) ------------------- -- No changes yet. +- Add a way to log the loop-client versions in use. (#362) 0.19.2 (2016-01-07) diff --git a/package.json b/package.json index 08e28cc..65ea3fc 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "mozilla-loop-server", "description": "The Mozilla Loop (WebRTC App) server", - "version": "0.19.2", + "version": "0.19.3", "author": "Mozilla (https://mozilla.org/)", "homepage": "https://github.com/mozilla-services/loop-server/", "bugs": "https://bugzilla.mozilla.org/enter_bug.cgi?product=Loop&component=Server", From f8950db38f933d1911e547ad0695093735cf015a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Fri, 12 Feb 2016 17:00:11 +0100 Subject: [PATCH 4/9] Back to development. --- CHANGELOG | 6 ++++++ package.json | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG b/CHANGELOG index 115572b..add66c6 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,12 @@ Changelog This document describes changes between each past release. +0.20.0 (unreleased) +------------------- + +- No changes yet. + + 0.19.3 (2016-02-12) ------------------- diff --git a/package.json b/package.json index 65ea3fc..8eec4a9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "mozilla-loop-server", "description": "The Mozilla Loop (WebRTC App) server", - "version": "0.19.3", + "version": "0.20.0-dev", "author": "Mozilla (https://mozilla.org/)", "homepage": "https://github.com/mozilla-services/loop-server/", "bugs": "https://bugzilla.mozilla.org/enter_bug.cgi?product=Loop&component=Server", From 3aa7025a93e1556cba7cfcf66440621eea4430a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Fri, 12 Feb 2016 17:41:45 +0100 Subject: [PATCH 5/9] Display pretty exception with Mocha when running tests. --- config/test.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/test.json b/config/test.json index 2700bc1..e511fe9 100644 --- a/config/test.json +++ b/config/test.json @@ -71,6 +71,7 @@ "hekaMetrics": { "activated": false, "debug": false, - "level": "DEBUG" + "level": "DEBUG", + "fmt": "pretty" } } From 2434e9acb3ea8dda29c4cec20da58d04a1fa10d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Fri, 12 Feb 2016 17:42:26 +0100 Subject: [PATCH 6/9] Add a handleLogDomain action. --- loop/index.js | 2 +- loop/routes/rooms.js | 44 +++++++++++++++++++++++++++++++++++++++++--- test/rooms_test.js | 4 ++-- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/loop/index.js b/loop/index.js index 504ff15..1e31526 100644 --- a/loop/index.js +++ b/loop/index.js @@ -142,7 +142,7 @@ if (conf.get("fxaOAuth").activated !== false) { var rooms = require("./routes/rooms"); rooms(apiRouter, conf, logError, storage, filestorage, auth, validators, tokBox, - simplePush, notifications); + simplePush, notifications, statsdClient); var session = require("./routes/session"); session(apiRouter, conf, storage, auth); diff --git a/loop/routes/rooms.js b/loop/routes/rooms.js index fc81791..fff24f2 100644 --- a/loop/routes/rooms.js +++ b/loop/routes/rooms.js @@ -20,7 +20,7 @@ var hmac = require('../hmac'); module.exports = function (apiRouter, conf, logError, storage, filestorage, auth, - validators, tokBox, simplePush, notifications) { + validators, tokBox, simplePush, notifications, statsdClient) { var roomsConf = conf.get("rooms"); @@ -331,14 +331,14 @@ module.exports = function (apiRouter, conf, logError, storage, filestorage, auth /** * Do an action on a room. * - * Actions are "join", "leave", "refresh". + * Actions are "join", "leave", "refresh", "status", "logDomain". **/ apiRouter.post('/rooms/:token', validators.validateRoomToken, auth.authenticateWithHawkOrToken, function(req, res) { var participantHmac = req.hawkIdHmac || req.participantTokenHmac; var roomOwnerHmac = req.roomStorageData.roomOwnerHmac; - var ROOM_ACTIONS = ["join", "refresh", "status", "leave"]; + var ROOM_ACTIONS = ["join", "refresh", "status", "leave", "logDomain"]; var action = req.body.action; var code; @@ -529,6 +529,42 @@ module.exports = function (apiRouter, conf, logError, storage, filestorage, auth }); }); }); + }, + handleLogDomain: function(req, res) { + // Log whitelisted domain count in statsd. + validators.requireParams('domains')( + req, res, function(req, res) { + var domains = req.body.domains; + var validDomains = domains.filter(function(domain) { + return domain.hasOwnProperty("domain") && domain.hasOwnProperty("count"); + }); + + if (validDomains.length !== domains.length) { + sendError(res, 400, errors.INVALID_PARAMETERS, + "Domains must be a list of objects with both a " + + "``domain`` and ``count`` property."); + return; + } + + storage.getRoomParticipant(req.token, participantHmac, + function(err, participant) { + if (res.serverError(err)) return; + if (participant === null) { + sendError(res, 400, errors.NOT_ROOM_PARTICIPANT, + "Can't update status for a room you aren't in."); + return; + } + if (statsdClient !== undefined) { + req.body.domains.forEach(function(domain) { + statsdClient.increment( + "loop.room.shared_domains", + domain.count, + [domain.domain]); + }); + } + res.status(204).json(); + }); + }); } }; @@ -540,6 +576,8 @@ module.exports = function (apiRouter, conf, logError, storage, filestorage, auth handlers.handleUpdateStatus(req, res); } else if (action === "leave") { handlers.handleLeave(req, res); + } else if (action === "logDomain") { + handlers.handleLogDomain(req, res); } }); diff --git a/test/rooms_test.js b/test/rooms_test.js index ccdc4e0..4a8c354 100644 --- a/test/rooms_test.js +++ b/test/rooms_test.js @@ -1287,7 +1287,7 @@ describe("/rooms", function() { .end(function(err, res) { if (err) throw err; expectFormattedError(res, 400, errors.MISSING_PARAMETERS, - "action should be one of join, refresh, status, leave"); + "action should be one of join, refresh, status, leave, logDomain"); done(); }); }); @@ -2038,7 +2038,7 @@ describe("/rooms", function() { .end(function(err, res) { if (err) throw err; expectFormattedError(res, 400, errors.MISSING_PARAMETERS, - "action should be one of join, refresh, status, leave"); + "action should be one of join, refresh, status, leave, logDomain"); done(); }); }); From 34598905281f2e391860a70544a3762aeacc0fee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Fri, 12 Feb 2016 18:06:13 +0100 Subject: [PATCH 7/9] Add tests. --- loop/routes/rooms.js | 2 +- test/rooms_test.js | 54 ++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 1 deletion(-) diff --git a/loop/routes/rooms.js b/loop/routes/rooms.js index fff24f2..982d5bd 100644 --- a/loop/routes/rooms.js +++ b/loop/routes/rooms.js @@ -533,7 +533,7 @@ module.exports = function (apiRouter, conf, logError, storage, filestorage, auth handleLogDomain: function(req, res) { // Log whitelisted domain count in statsd. validators.requireParams('domains')( - req, res, function(req, res) { + req, res, function() { var domains = req.body.domains; var validDomains = domains.filter(function(domain) { return domain.hasOwnProperty("domain") && domain.hasOwnProperty("count"); diff --git a/test/rooms_test.js b/test/rooms_test.js index 4a8c354..e7c253e 100644 --- a/test/rooms_test.js +++ b/test/rooms_test.js @@ -2006,6 +2006,60 @@ describe("/rooms", function() { }); }); }); + + describe("Handle 'logDomain'", function() { + + function createAndJoinRoom(callback) { + createRoom(hawkCredentials).end(function(err, res) { + if (err) throw err; + var roomToken = res.body.roomToken; + joinRoom(hawkCredentials, roomToken).end(function(err) { + if (err) throw err; + callback(roomToken); + }); + }); + } + + var postReq; + var roomToken; + + beforeEach(function(done) { + supertest(app) + .post('/rooms') + .type('json') + .hawk(hawkCredentials) + .send({ + roomOwner: "Alexis", + roomName: "UX discussion", + maxSize: "3", + expiresIn: "10" + }) + .expect(201) + .end(function(err, postRes) { + if (err) throw err; + roomToken = postRes.body.roomToken; + postReq = supertest(app) + .post('/rooms/' + roomToken) + .type('json'); + done(); + }); + }); + + it("should return empty body if successful.", function(done) { + joinRoom(hawkCredentials, roomToken).end(function(err) { + if (err) throw err; + postReq + .send({action: "logDomain", + domains: [{domain: "mozilla.org", count: 4}]}) + .expect(204) + .hawk(hawkCredentials) + .end(function(err, resp) { + if (err) throw err; + done(); + }); + }); + }); + }); }); describe("Using Token", function() { From e382d0002da5dca04bbc492feaa65cc0c02441cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Mon, 15 Feb 2016 15:04:10 +0100 Subject: [PATCH 8/9] Log domain stats in Heka and statsd. --- loop/routes/rooms.js | 20 ++++++-- test/rooms_test.js | 117 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 132 insertions(+), 5 deletions(-) diff --git a/loop/routes/rooms.js b/loop/routes/rooms.js index 982d5bd..d414f43 100644 --- a/loop/routes/rooms.js +++ b/loop/routes/rooms.js @@ -12,6 +12,7 @@ var decrypt = require('../encrypt').decrypt; var encrypt = require('../encrypt').encrypt; var errors = require('../errno.json'); var getUserAccount = require('../utils').getUserAccount; +var hekaLogger = require('../logger').hekaLogger; var sendError = require('../utils').sendError; var tokenlib = require('../tokenlib'); var time = require('../utils').time; @@ -554,12 +555,21 @@ module.exports = function (apiRouter, conf, logError, storage, filestorage, auth "Can't update status for a room you aren't in."); return; } - if (statsdClient !== undefined) { + + if (conf.get('hekaMetrics').activated === true) { req.body.domains.forEach(function(domain) { - statsdClient.increment( - "loop.room.shared_domains", - domain.count, - [domain.domain]); + var line = { + domain: domain.domain, + count: domain.count + }; + hekaLogger.info('domains.counters', line); + + if (statsdClient !== undefined) { + statsdClient.increment( + "loop.room.shared_domains", + domain.count); + } + }); } res.status(204).json(); diff --git a/test/rooms_test.js b/test/rooms_test.js index e7c253e..30fcdbd 100644 --- a/test/rooms_test.js +++ b/test/rooms_test.js @@ -8,6 +8,7 @@ var expect = require("chai").expect; var addHawk = require("superagent-hawk"); var supertest = addHawk(require("supertest")); var sinon = require("sinon"); +var assert = sinon.assert; var expectFormattedError = require("./support").expectFormattedError; var errors = require("../loop/errno.json"); var Token = require("express-hawkauth").Token; @@ -23,6 +24,7 @@ var auth = loop.auth; var validators = loop.validators; var apiRouter = loop.apiRouter; var conf = loop.conf; +var statsdClient = loop.statsdClient; var storage = loop.storage; var filestorage = loop.filestorage; var tokBox = loop.tokBox; @@ -2059,6 +2061,121 @@ describe("/rooms", function() { }); }); }); + + it("should count total domain metrics in statsd.", function(done) { + joinRoom(hawkCredentials, roomToken).end(function(err) { + if (err) throw err; + sandbox.stub(statsdClient, "increment"); + + postReq + .send({action: "logDomain", + domains: [{domain: "mozilla.org", count: 4}, + {domain: "ebay.fr", count: 2}]}) + .expect(204) + .hawk(hawkCredentials) + .end(function(err, resp) { + if (err) throw err; + assert.calledTwice(statsdClient.increment); + assert.calledWithExactly(statsdClient.increment, + "loop.room.shared_domains", 4); + assert.calledWithExactly(statsdClient.increment, + "loop.room.shared_domains", 2); + done(); + }); + }); + }); + + it("should reject if user had not joined the room", function(done) { + postReq + .send({action: "logDomain", + domains: [{domain: "mozilla.org", count: 4}]}) + .expect(400) + .hawk(hawkCredentials) + .end(function(err, res) { + if (err) throw err; + expectFormattedError( + res, 400, errors.NOT_ROOM_PARTICIPANT, + "Can't update status for a room you aren't in."); + done(); + }); + }); + + it("should return a 503 in case of storage error.", function(done) { + sandbox.stub(storage, "getRoomParticipant", + function(roomTokens, participantHmac, callback) { + callback("error"); + }); + + postReq + .send({action: "logDomain", + domains: [{domain: "mozilla.org", count: 4}]}) + .expect(503) + .hawk(hawkCredentials) + .end(function(err, res) { + if (err) throw err; + expectFormattedError(res, 503, errors.BACKEND, + "Service Unavailable"); + done(); + }); + }); + + it("should log domain count data if successful.", function(done) { + joinRoom(hawkCredentials, roomToken).end(function(err) { + if (err) throw err; + logs = []; // Reset hekaLogs. + postReq + .send({action: "logDomain", + domains: [{domain: "mozilla.org", count: 4}, + {domain: "ebay.fr", count: 2}]}) + .expect(204) + .hawk(hawkCredentials) + .end(function(err, resp) { + if (err) throw err; + expect(logs).to.length(3); + expect(logs[0]).to.eql({op: 'domains.counters', + domain: 'mozilla.org', + count: 4}); + expect(logs[1]).to.eql({op: 'domains.counters', + domain: 'ebay.fr', + count: 2}); + done(); + }); + }); + }); + + it("should reject if body is incomplete (domain property missing).", function(done) { + postReq + .send({action: "logDomain", + domains: [{domain: "mozilla.org"}]}) + .expect(400) + .hawk(hawkCredentials) + .end(function(err, res) { + if (err) throw err; + expectFormattedError( + res, 400, errors.INVALID_PARAMETERS, + "Domains must be a list of objects with both a " + + "``domain`` and ``count`` property." + ); + done(); + }); + }); + + it("should reject if body is incomplete (count property missing).", function(done) { + postReq + .send({action: "logDomain", + domains: [{domain: "mozilla.org", count: 4}, {count: 2}]}) + .expect(400) + .hawk(hawkCredentials) + .end(function(err, res) { + if (err) throw err; + expectFormattedError( + res, 400, errors.INVALID_PARAMETERS, + "Domains must be a list of objects with both a " + + "``domain`` and ``count`` property." + ); + done(); + }); + }); }); }); From 157313d5be0c81fe78404c6819a7b818749ee23b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20HUBSCHER?= Date: Mon, 15 Feb 2016 17:30:56 +0100 Subject: [PATCH 9/9] Fix linter. --- test/rooms_test.js | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/test/rooms_test.js b/test/rooms_test.js index 30fcdbd..57bcc7f 100644 --- a/test/rooms_test.js +++ b/test/rooms_test.js @@ -2010,18 +2010,6 @@ describe("/rooms", function() { }); describe("Handle 'logDomain'", function() { - - function createAndJoinRoom(callback) { - createRoom(hawkCredentials).end(function(err, res) { - if (err) throw err; - var roomToken = res.body.roomToken; - joinRoom(hawkCredentials, roomToken).end(function(err) { - if (err) throw err; - callback(roomToken); - }); - }); - } - var postReq; var roomToken; @@ -2055,7 +2043,7 @@ describe("/rooms", function() { domains: [{domain: "mozilla.org", count: 4}]}) .expect(204) .hawk(hawkCredentials) - .end(function(err, resp) { + .end(function(err) { if (err) throw err; done(); }); @@ -2073,7 +2061,7 @@ describe("/rooms", function() { {domain: "ebay.fr", count: 2}]}) .expect(204) .hawk(hawkCredentials) - .end(function(err, resp) { + .end(function(err) { if (err) throw err; assert.calledTwice(statsdClient.increment); assert.calledWithExactly(statsdClient.increment, @@ -2129,7 +2117,7 @@ describe("/rooms", function() { {domain: "ebay.fr", count: 2}]}) .expect(204) .hawk(hawkCredentials) - .end(function(err, resp) { + .end(function(err) { if (err) throw err; expect(logs).to.length(3); expect(logs[0]).to.eql({op: 'domains.counters',