55
66var debug = require ( 'debug' ) ( 'e2etests:throttledisconnect' ) ;
77var uuid = require ( 'uuid' ) ;
8+ var assert = require ( 'chai' ) . assert ;
89
910var deviceAmqp = require ( 'azure-iot-device-amqp' ) ;
1011var Message = require ( 'azure-iot-common' ) . Message ;
1112var createDeviceClient = require ( './testUtils.js' ) . createDeviceClient ;
1213var closeDeviceEventHubClients = require ( './testUtils.js' ) . closeDeviceEventHubClients ;
1314var eventHubClient = require ( 'azure-event-hubs' ) . Client ;
15+ var errors = require ( 'azure-iot-common' ) . errors ;
1416
1517var doConnectTest = function doConnectTest ( doIt ) {
1618 return doIt ? it : it . skip ;
1719} ;
1820
19- var numberOfD2CMessages = 4 ;
21+ var numberOfD2CMessages = 3 ;
2022var sendMessageTimeout = null ;
2123
2224var protocolAndTermination = [
@@ -25,31 +27,34 @@ var protocolAndTermination = [
2527 transport : deviceAmqp . Amqp ,
2628 operationType : 'InvokeThrottling' ,
2729 closeReason : ' throttle connection ' ,
28- durationInSeconds : 30 ,
29- delayInSeconds : 1
30+ durationInSeconds : 5 ,
31+ delayInSeconds : 0 ,
32+ expectedError : errors . ThrottlingError
3033 } ,
3134 {
3235 testEnabled : true ,
3336 transport : deviceAmqp . Amqp ,
3437 operationType : 'InvokeMaxMessageQuota' ,
3538 closeReason : ' exceed quota ' ,
36- durationInSeconds : 30 ,
37- delayInSeconds : 1
39+ durationInSeconds : 5 ,
40+ delayInSeconds : 0 ,
41+ expectedError : errors . IotHubQuotaExceededError
3842 } ,
3943 {
4044 testEnabled : true ,
4145 transport : deviceAmqp . Amqp ,
4246 operationType : 'InvokeAuthError' ,
4347 closeReason : ' authentication failure ' ,
44- durationInSeconds : 30 ,
45- delayInSeconds : 1
48+ durationInSeconds : 5 ,
49+ delayInSeconds : 0 ,
50+ expectedError : errors . UnauthorizedError
4651 } ,
4752] ;
4853
4954
5055var runTests = function ( hubConnectionString , provisionedDevice ) {
5156 protocolAndTermination . forEach ( function ( testConfiguration ) {
52- describe . skip ( 'Device utilizing ' + provisionedDevice . authenticationDescription + ' authentication, connected over ' + testConfiguration . transport . name + ' using device/eventhub clients - disconnect d2c' , function ( ) {
57+ describe ( 'Device utilizing ' + provisionedDevice . authenticationDescription + ' authentication, connected over ' + testConfiguration . transport . name + ' using device/eventhub clients - disconnect d2c' , function ( ) {
5358
5459 var deviceClient , ehClient , senderInterval ;
5560
@@ -68,101 +73,68 @@ var runTests = function (hubConnectionString, provisionedDevice) {
6873
6974 doConnectTest ( testConfiguration . testEnabled ) ( 'Device client sends ' + numberOfD2CMessages + ' messages, first causes' + testConfiguration . closeReason + 'which causes next ' + ( numberOfD2CMessages - 2 ) + ' to fail, final passes after ' + testConfiguration . durationInSeconds + ' seconds duration.' , function ( testCallback ) {
7075 this . timeout ( 80000 ) ;
71- var originalMessages = [ ] ;
72- var messagesReceived = 0 ;
73- var messagesSent = 0 ;
74- var d2cMessageSender = function ( ) {
75- debug ( 'Sending message number: ' + ( messagesSent + 1 ) + ' with messageId: ' + originalMessages [ messagesSent ] . messageId ) ;
76- if ( messagesSent >= numberOfD2CMessages ) {
77- testCallback ( new Error ( 'tried to send to many messages' ) ) ;
78- } else {
79- deviceClient . sendEvent ( originalMessages [ messagesSent ++ ] , function ( sendErr ) {
80- debug ( 'At device client send callback - error is: ' + sendErr ) ;
81- if ( sendErr ) {
82- if ( ( messagesSent >= 2 ) && ( messagesSent <= ( numberOfD2CMessages - 1 ) ) ) {
83- debug ( 'invoking the setTimeout in the sender callback with ' + 16000 + ' seconds timeout' ) ;
84- sendMessageTimeout = setTimeout ( d2cMessageSender . bind ( this ) , 16000 ) ;
85- } else {
86- testCallback ( sendErr ) ;
87- }
88- }
89- } ) ;
90- }
76+
77+ var onDisconnected = function ( err ) {
78+ debug ( 'unexpected disconnection of the device client' ) ;
79+ testCallback ( err ) ;
9180 } ;
92- var findMessage = function ( incomingMessage , storedMessages ) {
93- if ( incomingMessage . properties && incomingMessage . properties . messageId ) {
94- for ( var j = 0 ; j < storedMessages . length ; j ++ ) {
95- if ( incomingMessage . properties . messageId === storedMessages [ j ] . messageId ) {
96- if ( ! storedMessages [ j ] . alreadyReceived ) {
97- storedMessages . alreadyReceived = true ;
98- return true ;
99- } else {
100- testCallback ( new Error ( 'received a message more than once' ) ) ;
101- }
102- }
81+
82+ var onError = function ( err ) {
83+ debug ( 'unexpected error of the device client' ) ;
84+ testCallback ( err ) ;
85+ } ;
86+
87+ deviceClient . on ( 'disconnect' , onDisconnected ) ;
88+ deviceClient . on ( 'error' , onError ) ;
89+
90+ var injectFault = function ( callback ) {
91+ var terminateMessage = new Message ( '' ) ;
92+ terminateMessage . properties . add ( 'AzIoTHub_FaultOperationType' , testConfiguration . operationType ) ;
93+ terminateMessage . properties . add ( 'AzIoTHub_FaultOperationCloseReason' , testConfiguration . closeReason ) ;
94+ terminateMessage . properties . add ( 'AzIoTHub_FaultOperationDurationInSecs' , testConfiguration . durationInSeconds ) ;
95+ terminateMessage . properties . add ( 'AzIoTHub_FaultOperationDelayInSecs' , testConfiguration . delayInSeconds ) ;
96+ deviceClient . sendEvent ( terminateMessage , function ( sendErr ) {
97+ if ( sendErr ) {
98+ debug ( 'error during fault injection: ' + sendErr ) ;
99+ } else {
100+ debug ( 'fault injection successful' ) ;
103101 }
104- }
105- return false ;
102+ callback ( sendErr ) ;
103+ } ) ;
106104 } ;
107- for ( var i = 0 ; i < numberOfD2CMessages ; i ++ ) {
108- var uuidData = uuid . v4 ( ) ;
109- originalMessages [ i ] = new Message ( uuidData ) ;
110- originalMessages [ i ] . messageId = uuidData ;
111- originalMessages [ i ] . alreadyReceived = false ;
112- }
113- ehClient . open ( )
114- . then ( ehClient . getPartitionIds . bind ( ehClient ) )
115- . then ( function ( partitionIds ) {
116- return partitionIds . map ( function ( partitionId ) {
117- return ehClient . createReceiver ( '$Default' , partitionId , { 'startAfterTime' : Date . now ( ) } ) . then ( function ( receiver ) {
118- receiver . on ( 'errorReceived' , function ( err ) {
119- testCallback ( err ) ;
120- } ) ;
121- receiver . on ( 'message' , function ( eventData ) {
122- if ( eventData . annotations [ 'iothub-connection-device-id' ] === provisionedDevice . deviceId ) {
123- debug ( 'did get a message for this device.' ) ;
124- if ( findMessage ( eventData , originalMessages ) ) {
125- debug ( 'It was one of the messages we sent with message id: ' + eventData . properties . messageId ) ;
126- if ( messagesReceived ++ === 0 ) {
127- debug ( 'It was the first message.' ) ;
128- var terminateMessage = new Message ( '' ) ;
129- terminateMessage . properties . add ( 'AzIoTHub_FaultOperationType' , testConfiguration . operationType ) ;
130- terminateMessage . properties . add ( 'AzIoTHub_FaultOperationCloseReason' , testConfiguration . closeReason ) ;
131- terminateMessage . properties . add ( 'AzIoTHub_FaultOperationDurationInSecs' , testConfiguration . durationInSeconds ) ;
132- terminateMessage . properties . add ( 'AzIoTHub_FaultOperationDelayInSecs' , testConfiguration . delayInSeconds ) ;
133- deviceClient . sendEvent ( terminateMessage , function ( sendErr ) {
134- debug ( 'at the callback for the fault injection send, err is:' + sendErr ) ;
135- } ) ;
136- debug ( 'invoking the setTimeout in the eh receiver with ' + ( ( testConfiguration . delayInSeconds * 1000 ) + 2000 ) + ' seconds timeout' ) ;
137- sendMessageTimeout = setTimeout ( d2cMessageSender . bind ( this ) , ( testConfiguration . delayInSeconds * 1000 ) + 2000 ) ;
138- }
139- if ( ( messagesSent === numberOfD2CMessages ) && ( messagesReceived === numberOfD2CMessages ) ) {
140- testCallback ( ) ;
141- }
142- } else {
143- debug ( 'eventData message id doesn\'t match any stored message id' ) ;
144- }
145- } else {
146- debug ( 'Incoming device id is: ' + eventData . annotations [ 'iothub-connection-device-id' ] ) ;
147- }
148- } ) ;
149- } ) ;
150- } ) ;
151- } )
152- . then ( function ( ) {
153- deviceClient . open ( function ( openErr ) {
154- if ( openErr ) {
155- testCallback ( openErr ) ;
156- } else {
157- deviceClient . on ( 'disconnect' , function ( ) {
158- testCallback ( new Error ( 'unexpected disconnect' ) ) ;
159- } ) ;
160- d2cMessageSender ( ) ;
161- }
162- } ) ;
163- } )
164- . catch ( testCallback ) ;
105+
106+ var sendAndShouldSucceed = function ( when , callback ) {
107+ deviceClient . sendEvent ( new Message ( '' ) , function ( err ) {
108+ if ( err ) {
109+ debug ( 'error sending a message that should\'ve succeeded (' + when + '): ' + err . toString ( ) ) ;
110+ testCallback ( err ) ;
111+ } else {
112+ debug ( 'sendEvent success: ' + when ) ;
113+ callback ( ) ;
114+ }
115+ } ) ;
116+ } ;
117+
118+ var sendAndShouldFail = function ( when , callback ) {
119+ deviceClient . sendEvent ( new Message ( '' ) , function ( err ) {
120+ assert . instanceOf ( err , testConfiguration . expectedError ) ;
121+ debug ( 'got the right error: ' + testConfiguration . expectedError . name ) ;
122+ callback ( ) ;
123+ } ) ;
124+ } ;
125+
126+ sendAndShouldSucceed ( 'before fault injection' , function ( ) {
127+ injectFault ( function ( ) {
128+ sendAndShouldFail ( 'after fault injection' , function ( ) {
129+ setTimeout ( function ( ) {
130+ sendAndShouldSucceed ( 'fault injection is over' , function ( ) {
131+ testCallback ( ) ;
132+ } ) ;
133+ } , testConfiguration . durationInSeconds * 1500 ) ;
165134 } ) ;
135+ } ) ;
136+ } ) ;
137+ } ) ;
166138
167139 doConnectTest ( false ) ( 'Device client sends ' + numberOfD2CMessages + ' messages, first causes' + testConfiguration . closeReason + 'which is not seen by the iot hub device client' , function ( testCallback ) {
168140 this . timeout ( 80000 ) ;
0 commit comments