1
1
from typing import List
2
2
import unittest
3
+ import json
4
+ from unittest .mock import patch
5
+ from datetime import datetime
3
6
4
7
import azure .functions as func
5
8
import azure .functions .eventhub as azf_eh
9
+ import azure .functions .meta as meta
10
+
11
+
12
+ class CollectionBytes :
13
+ def __init__ (self , data : List [bytes ]):
14
+ self .bytes = data
15
+
16
+
17
+ class CollectionString :
18
+ def __init__ (self , data : List [str ]):
19
+ self .string = list (map (lambda x : x .encode ('utf-8' ), data ))
6
20
7
21
8
22
class TestEventHub (unittest .TestCase ):
23
+ MOCKED_ENQUEUE_TIME = datetime .utcnow ()
24
+
9
25
def test_eventhub_input_type (self ):
10
26
check_input_type = (
11
27
azf_eh .EventHubConverter .check_input_type_annotation
@@ -26,3 +42,187 @@ def test_eventhub_output_type(self):
26
42
self .assertFalse (check_output_type (func .EventHubEvent ))
27
43
self .assertFalse (check_output_type (List [bytes ]))
28
44
self .assertFalse (check_output_type (List [func .EventHubEvent ]))
45
+
46
+ @patch ('azure.functions.eventhub.EventHubTriggerConverter'
47
+ '.decode_single_event' )
48
+ @patch ('azure.functions.eventhub.EventHubTriggerConverter'
49
+ '.decode_multiple_events' )
50
+ def test_eventhub_decode_single_event (self , dme_mock , dse_mock ):
51
+ azf_eh .EventHubTriggerConverter .decode (
52
+ data = self ._generate_single_iothub_datum (),
53
+ trigger_metadata = self ._generate_single_trigger_metadatum ()
54
+ )
55
+ dse_mock .assert_called_once ()
56
+ dme_mock .assert_not_called ()
57
+
58
+ @patch ('azure.functions.eventhub.EventHubTriggerConverter'
59
+ '.decode_single_event' )
60
+ @patch ('azure.functions.eventhub.EventHubTriggerConverter'
61
+ '.decode_multiple_events' )
62
+ def test_eventhub_decode_multiple_events (self , dme_mock , dse_mock ):
63
+ azf_eh .EventHubTriggerConverter .decode (
64
+ data = self ._generate_multiple_iothub_data (),
65
+ trigger_metadata = self ._generate_multiple_trigger_metadata ()
66
+ )
67
+ dse_mock .assert_not_called ()
68
+ dme_mock .assert_called_once ()
69
+
70
+ def test_eventhub_trigger_single_event_json (self ):
71
+ result = azf_eh .EventHubTriggerConverter .decode (
72
+ data = self ._generate_single_iothub_datum ('json' ),
73
+ trigger_metadata = self ._generate_single_trigger_metadatum ()
74
+ )
75
+ # Result body always has the datatype of bytes
76
+ self .assertEqual (
77
+ result .get_body ().decode ('utf-8' ), '{"device-status": "good"}'
78
+ )
79
+ self .assertEqual (result .enqueued_time , self .MOCKED_ENQUEUE_TIME )
80
+
81
+ def test_eventhub_trigger_single_event_bytes (self ):
82
+ result = azf_eh .EventHubTriggerConverter .decode (
83
+ data = self ._generate_single_iothub_datum ('bytes' ),
84
+ trigger_metadata = self ._generate_single_trigger_metadatum ()
85
+ )
86
+ self .assertEqual (
87
+ result .get_body ().decode ('utf-8' ), '{"device-status": "good"}'
88
+ )
89
+ self .assertEqual (result .enqueued_time , self .MOCKED_ENQUEUE_TIME )
90
+
91
+ def test_iothub_metadata_single_event (self ):
92
+ result = azf_eh .EventHubTriggerConverter .decode (
93
+ data = self ._generate_single_iothub_datum ('json' ),
94
+ trigger_metadata = self ._generate_single_trigger_metadatum ()
95
+ )
96
+ self .assertIsNotNone (result .iothub_metadata )
97
+ self .assertEqual (
98
+ result .iothub_metadata ['connection-device-id' ], 'MyTestDevice'
99
+ )
100
+
101
+ def test_eventhub_trigger_single_event_string (self ):
102
+ result = azf_eh .EventHubTriggerConverter .decode (
103
+ data = self ._generate_single_iothub_datum ('string' ),
104
+ trigger_metadata = self ._generate_single_trigger_metadatum ()
105
+ )
106
+ self .assertEqual (
107
+ result .get_body ().decode ('utf-8' ), '{"device-status": "good"}'
108
+ )
109
+ self .assertEqual (result .enqueued_time , self .MOCKED_ENQUEUE_TIME )
110
+
111
+ def test_eventhub_trigger_multiple_events_json (self ):
112
+ result = azf_eh .EventHubTriggerConverter .decode (
113
+ data = self ._generate_multiple_iothub_data ('json' ),
114
+ trigger_metadata = self ._generate_multiple_trigger_metadata ()
115
+ )
116
+ self .assertIsInstance (result , list )
117
+ self .assertEqual (len (result ), 2 )
118
+
119
+ self .assertEqual (result [0 ].enqueued_time , self .MOCKED_ENQUEUE_TIME )
120
+ self .assertEqual (
121
+ result [0 ].get_body ().decode ('utf-8' ), '{"device-status": "good1"}'
122
+ )
123
+
124
+ self .assertEqual (result [1 ].enqueued_time , self .MOCKED_ENQUEUE_TIME )
125
+ self .assertEqual (
126
+ result [1 ].get_body ().decode ('utf-8' ), '{"device-status": "good2"}'
127
+ )
128
+
129
+ def test_eventhub_trigger_multiple_events_collection_string (self ):
130
+ result = azf_eh .EventHubTriggerConverter .decode (
131
+ data = self ._generate_multiple_iothub_data ('collection_string' ),
132
+ trigger_metadata = self ._generate_multiple_trigger_metadata ()
133
+ )
134
+ self .assertIsInstance (result , list )
135
+ self .assertEqual (len (result ), 2 )
136
+
137
+ self .assertEqual (result [0 ].enqueued_time , self .MOCKED_ENQUEUE_TIME )
138
+ self .assertEqual (
139
+ result [0 ].get_body ().decode ('utf-8' ), '{"device-status": "good1"}'
140
+ )
141
+
142
+ self .assertEqual (result [1 ].enqueued_time , self .MOCKED_ENQUEUE_TIME )
143
+ self .assertEqual (
144
+ result [1 ].get_body ().decode ('utf-8' ), '{"device-status": "good2"}'
145
+ )
146
+
147
+ def test_eventhub_trigger_multiple_events_collection_bytes (self ):
148
+ result = azf_eh .EventHubTriggerConverter .decode (
149
+ data = self ._generate_multiple_iothub_data ('collection_bytes' ),
150
+ trigger_metadata = self ._generate_multiple_trigger_metadata ()
151
+ )
152
+ self .assertIsInstance (result , list )
153
+ self .assertEqual (len (result ), 2 )
154
+
155
+ self .assertEqual (result [0 ].enqueued_time , self .MOCKED_ENQUEUE_TIME )
156
+ self .assertEqual (
157
+ result [0 ].get_body ().decode ('utf-8' ), '{"device-status": "good1"}'
158
+ )
159
+
160
+ self .assertEqual (result [1 ].enqueued_time , self .MOCKED_ENQUEUE_TIME )
161
+ self .assertEqual (
162
+ result [1 ].get_body ().decode ('utf-8' ), '{"device-status": "good2"}'
163
+ )
164
+
165
+ def test_iothub_metadata_events (self ):
166
+ result = azf_eh .EventHubTriggerConverter .decode (
167
+ data = self ._generate_multiple_iothub_data ('json' ),
168
+ trigger_metadata = self ._generate_multiple_trigger_metadata ()
169
+ )
170
+ self .assertIsNotNone (result [0 ].iothub_metadata )
171
+ self .assertEqual (
172
+ result [0 ].iothub_metadata ['connection-device-id' ], 'MyTestDevice1'
173
+ )
174
+
175
+ self .assertIsNotNone (result [1 ].iothub_metadata )
176
+ self .assertEqual (
177
+ result [1 ].iothub_metadata ['connection-device-id' ], 'MyTestDevice2'
178
+ )
179
+
180
+ def _generate_single_iothub_datum (self , datum_type = 'json' ):
181
+ datum = '{"device-status": "good"}'
182
+ if datum_type == 'bytes' :
183
+ datum = datum .encode ('utf-8' )
184
+
185
+ return meta .Datum (datum , datum_type )
186
+
187
+ def _generate_multiple_iothub_data (self , data_type = 'json' ):
188
+ data = '[{"device-status": "good1"}, {"device-status": "good2"}]'
189
+ if data_type == 'collection_bytes' :
190
+ data = list (
191
+ map (lambda x : json .dumps (x ).encode ('utf-8' ), json .loads (data ))
192
+ )
193
+ data = CollectionBytes (data )
194
+ elif data_type == 'collection_string' :
195
+ data = list (
196
+ map (lambda x : json .dumps (x ), json .loads (data ))
197
+ )
198
+ data = CollectionString (data )
199
+
200
+ return meta .Datum (data , data_type )
201
+
202
+ def _generate_single_trigger_metadatum (self ):
203
+ return {
204
+ 'EnqueuedTime' : meta .Datum (
205
+ f'"{ self .MOCKED_ENQUEUE_TIME .isoformat ()} "' , 'json'
206
+ ),
207
+ 'SystemProperties' : meta .Datum (
208
+ '{"iothub-connection-device-id": "MyTestDevice"}' , 'json'
209
+ )
210
+ }
211
+
212
+ def _generate_multiple_trigger_metadata (self ):
213
+ system_props_array = [
214
+ {
215
+ 'EnqueuedTimeUtc' : self .MOCKED_ENQUEUE_TIME .isoformat (),
216
+ 'iothub-connection-device-id' : 'MyTestDevice1' ,
217
+ },
218
+ {
219
+ 'EnqueuedTimeUtc' : self .MOCKED_ENQUEUE_TIME .isoformat (),
220
+ 'iothub-connection-device-id' : 'MyTestDevice2' ,
221
+ }
222
+ ]
223
+
224
+ return {
225
+ 'SystemPropertiesArray' : meta .Datum (
226
+ json .dumps (system_props_array ), 'json'
227
+ )
228
+ }
0 commit comments