From da9559fd1f0f50ef57900b8aee53dfd4a3f8ee60 Mon Sep 17 00:00:00 2001 From: Gabriel Schulhof Date: Wed, 4 Nov 2015 10:39:11 +0200 Subject: [PATCH] OicServer: Reject notify() if there are no observers and test onrequest Fixes gh-22 Fixes gh-24 --- lib/OicServer.js | 5 +- tests/tests/API Observation/client.js | 6 +-- tests/tests/API Observation/server.js | 74 ++++++++++++++++++++------- 3 files changed, 60 insertions(+), 25 deletions(-) diff --git a/lib/OicServer.js b/lib/OicServer.js index f764ffa1..f6035f2f 100644 --- a/lib/OicServer.js +++ b/lib/OicServer.js @@ -83,7 +83,7 @@ _.extend( OicServer.prototype, { }, _createEntityHandler: function( resource ) { - return _.bind( function( flag, request/*, url*/ ) { + return _.bind( function( flag, request /*, url*/ ) { // Handle the request and raise events accordingly var i, @@ -303,6 +303,9 @@ _.extend( OicServer.prototype, { } ) ); return; } + } else { + reject( _.extend( new Error( "notify: There are no observers" ), + { noObservers: true } ) ); } fulfill(); diff --git a/tests/tests/API Observation/client.js b/tests/tests/API Observation/client.js index e07cffde..47bbd672 100644 --- a/tests/tests/API Observation/client.js +++ b/tests/tests/API Observation/client.js @@ -12,11 +12,7 @@ function discoverResources() { resourceFound = true; device.client.addEventListener( "resourcechange", function( event ) { if ( ++observationCount >= 10 ) { - device.client.cancelObserving( event.resource.id ).then( - function() { - console.log( JSON.stringify( { killPeer: true } ) ); - process.exit( 0 ); - }, + device.client.cancelObserving( event.resource.id ).catch( function( error ) { utils.die( "Client: cancelObserving() failed with " + error + " and result " + error.result ); diff --git a/tests/tests/API Observation/server.js b/tests/tests/API Observation/server.js index d62173fd..dd41a6e3 100644 --- a/tests/tests/API Observation/server.js +++ b/tests/tests/API Observation/server.js @@ -1,14 +1,22 @@ var lightResource, + onRequestCalls = 0, uuid = process.argv[ 2 ], utils = require( "../../assert-to-console" ), - sensor = require( "../../../js/mock-sensor" )(), device = require( "../../../index" )(), settings = { role: "server", connectionMode: "acked" }; -console.log( JSON.stringify( { assertionCount: 2 } ) ); +console.log( JSON.stringify( { assertionCount: 5 } ) ); + +function cleanup() { + utils.assert( "ok", onRequestCalls > 0, "Server: device.server.onrequest has been called" ); + utils.assert( "strictEqual", lightResource.properties.increment, 11, + "Exactly 11 notifications were delivered (the last one with noObservers)" ); + console.log( JSON.stringify( { killPeer: true } ) ); + process.exit( 0 ); +} function lightResourceOnRequest( request ) { if ( request.type === "retrieve" || request.type === "observe" ) { @@ -16,6 +24,28 @@ function lightResourceOnRequest( request ) { } } +function testOnRequest() { + onRequestCalls++; +} + +// After we've sent out ten notifications, we wait for the client to remove itself from the list of +// observers, and then we send out a final notification which we expect to fail in a certain way. +function assertNotifyFailure() { + var waitForObserverListToEmpty = setInterval( function() { + if ( device.server._interestedObservers.length === 0 ) { + clearInterval( waitForObserverListToEmpty ); + lightResource.properties.increment++; + device.server.notify( lightResource.id, "update", [ "increment" ] ).catch( + function( error ) { + utils.assert( "strictEqual", error.noObservers, true, + "Server: device.server.notify() fails with noObservers when there are " + + "no observers" ); + cleanup(); + } ); + } + }, 500 ); +} + device.configure( settings ).then( function() { utils.assert( "ok", true, "device.configure() successful" ); @@ -28,12 +58,13 @@ device.configure( settings ).then( interfaces: [ "oic.if.baseline" ], discoverable: true, observable: true, - properties: { someValue: 0, someOtherValue: "Helsinki" } + properties: { increment: 0 } } ).then( function( resource ) { utils.assert( "ok", true, "registerResource() successful" ); lightResource = resource; device.server.addEventListener( "request", lightResourceOnRequest ); + device.server.onrequest = testOnRequest; console.log( JSON.stringify( { ready: true } ) ); }, function( error ) { @@ -46,25 +77,30 @@ device.configure( settings ).then( "device.configure() failed with " + error + " and result " + error.result ); } ); -sensor.on( "change", function( newData ) { - var index, - updates = []; +// Notify ten times and then stop this interval +var notifyIntervalId = setInterval( function() { + var haveObservers = false; if ( !lightResource ) { return; } - for ( index in newData ) { - if ( newData[ index ] !== lightResource.properties[ index ] ) { - lightResource.properties[ index ] = newData[ index ]; - updates.push( index ); - } - } - if ( updates.length > 0 ) { - device.server.notify( lightResource.id, "update", updates ).then( - function() {}, - function( error ) { + device.server.notify( lightResource.id, "update", [ "increment" ] ).then( + function() { + + haveObservers = true; + lightResource.properties.increment++; + if ( lightResource.properties.increment === 10 ) { + + // After ten notifications we wait for the list of observers to go empty so we can + // assert that notify() fails with noObservers: true + clearInterval( notifyIntervalId ); + assertNotifyFailure(); + } + }, + function( error ) { + if ( haveObservers ) { utils.die( "notify() failed with " + error + " and result " + error.result ); - } ); - } -} ); + } + } ); +}, 1000 );