3333from apache_beam .testing .test_utils import PullResponseMessage
3434from apache_beam .testing .test_utils import create_pull_response
3535
36- # Protect against environments where pubsub library is not available.
3736try :
3837 from google .cloud import pubsub
3938except ImportError :
@@ -54,14 +53,18 @@ def setUpClass(cls):
5453 def setUp (self ):
5554 self .mock_presult = mock .MagicMock ()
5655
57- def init_matcher (self , with_attributes = False , strip_attributes = None ):
56+ def init_matcher (self , expected_msg = None ,
57+ with_attributes = False , strip_attributes = None ):
5858 self .pubsub_matcher = PubSubMessageMatcher (
59- 'mock_project' , 'mock_sub_name' , [ 'mock_expected_msg' ] ,
59+ 'mock_project' , 'mock_sub_name' , expected_msg ,
6060 with_attributes = with_attributes , strip_attributes = strip_attributes )
6161
62+ def init_counter_matcher (self , expected_msg_len = 1 ):
63+ self .pubsub_matcher = PubSubMessageMatcher (
64+ 'mock_project' , 'mock_sub_name' , expected_msg_len = expected_msg_len )
65+
6266 def test_message_matcher_success (self , mock_get_sub , unsued_mock ):
63- self .init_matcher ()
64- self .pubsub_matcher .expected_msg = [b'a' , b'b' ]
67+ self .init_matcher (expected_msg = [b'a' , b'b' ])
6568 mock_sub = mock_get_sub .return_value
6669 mock_sub .pull .side_effect = [
6770 create_pull_response ([PullResponseMessage (b'a' , {})]),
@@ -72,8 +75,8 @@ def test_message_matcher_success(self, mock_get_sub, unsued_mock):
7275 self .assertEqual (mock_sub .acknowledge .call_count , 2 )
7376
7477 def test_message_matcher_attributes_success (self , mock_get_sub , unsued_mock ):
75- self .init_matcher (with_attributes = True )
76- self . pubsub_matcher . expected_msg = [ PubsubMessage ( b'a' , { 'k' : 'v' })]
78+ self .init_matcher (expected_msg = [ PubsubMessage ( b'a' , { 'k' : 'v' })],
79+ with_attributes = True )
7780 mock_sub = mock_get_sub .return_value
7881 mock_sub .pull .side_effect = [
7982 create_pull_response ([PullResponseMessage (b'a' , {'k' : 'v' })])
@@ -83,8 +86,8 @@ def test_message_matcher_attributes_success(self, mock_get_sub, unsued_mock):
8386 self .assertEqual (mock_sub .acknowledge .call_count , 1 )
8487
8588 def test_message_matcher_attributes_fail (self , mock_get_sub , unsued_mock ):
86- self .init_matcher (with_attributes = True )
87- self . pubsub_matcher . expected_msg = [ PubsubMessage ( b'a' , {})]
89+ self .init_matcher (expected_msg = [ PubsubMessage ( b'a' , {})],
90+ with_attributes = True )
8891 mock_sub = mock_get_sub .return_value
8992 # Unexpected attribute 'k'.
9093 mock_sub .pull .side_effect = [
@@ -96,9 +99,9 @@ def test_message_matcher_attributes_fail(self, mock_get_sub, unsued_mock):
9699 self .assertEqual (mock_sub .acknowledge .call_count , 1 )
97100
98101 def test_message_matcher_strip_success (self , mock_get_sub , unsued_mock ):
99- self .init_matcher (with_attributes = True ,
102+ self .init_matcher (expected_msg = [PubsubMessage (b'a' , {'k' : 'v' })],
103+ with_attributes = True ,
100104 strip_attributes = ['id' , 'timestamp' ])
101- self .pubsub_matcher .expected_msg = [PubsubMessage (b'a' , {'k' : 'v' })]
102105 mock_sub = mock_get_sub .return_value
103106 mock_sub .pull .side_effect = [create_pull_response ([
104107 PullResponseMessage (b'a' , {'id' : 'foo' , 'timestamp' : 'bar' , 'k' : 'v' })
@@ -108,9 +111,9 @@ def test_message_matcher_strip_success(self, mock_get_sub, unsued_mock):
108111 self .assertEqual (mock_sub .acknowledge .call_count , 1 )
109112
110113 def test_message_matcher_strip_fail (self , mock_get_sub , unsued_mock ):
111- self .init_matcher (with_attributes = True ,
114+ self .init_matcher (expected_msg = [PubsubMessage (b'a' , {'k' : 'v' })],
115+ with_attributes = True ,
112116 strip_attributes = ['id' , 'timestamp' ])
113- self .pubsub_matcher .expected_msg = [PubsubMessage (b'a' , {'k' : 'v' })]
114117 mock_sub = mock_get_sub .return_value
115118 # Message is missing attribute 'timestamp'.
116119 mock_sub .pull .side_effect = [create_pull_response ([
@@ -122,8 +125,7 @@ def test_message_matcher_strip_fail(self, mock_get_sub, unsued_mock):
122125 self .assertEqual (mock_sub .acknowledge .call_count , 1 )
123126
124127 def test_message_matcher_mismatch (self , mock_get_sub , unused_mock ):
125- self .init_matcher ()
126- self .pubsub_matcher .expected_msg = [b'a' ]
128+ self .init_matcher (expected_msg = [b'a' ])
127129 mock_sub = mock_get_sub .return_value
128130 mock_sub .pull .side_effect = [
129131 create_pull_response ([PullResponseMessage (b'c' , {}),
@@ -140,7 +142,7 @@ def test_message_matcher_mismatch(self, mock_get_sub, unused_mock):
140142 self .assertEqual (mock_sub .acknowledge .call_count , 1 )
141143
142144 def test_message_matcher_timeout (self , mock_get_sub , unused_mock ):
143- self .init_matcher ()
145+ self .init_matcher (expected_msg = [ b'a' ] )
144146 mock_sub = mock_get_sub .return_value
145147 mock_sub .return_value .full_name .return_value = 'mock_sub'
146148 self .pubsub_matcher .timeout = 0.1
@@ -149,6 +151,41 @@ def test_message_matcher_timeout(self, mock_get_sub, unused_mock):
149151 self .assertTrue (mock_sub .pull .called )
150152 self .assertEqual (mock_sub .acknowledge .call_count , 0 )
151153
154+ def test_message_count_matcher_below_fail (self , mock_get_sub , unused_mock ):
155+ self .init_counter_matcher (expected_msg_len = 1 )
156+ mock_sub = mock_get_sub .return_value
157+ mock_sub .pull .side_effect = [
158+ create_pull_response ([PullResponseMessage (b'c' , {}),
159+ PullResponseMessage (b'd' , {})]),
160+ ]
161+ with self .assertRaises (AssertionError ) as error :
162+ hc_assert_that (self .mock_presult , self .pubsub_matcher )
163+ self .assertEqual (mock_sub .pull .call_count , 1 )
164+ self .assertTrue (
165+ '\n Expected: Expected 1 messages.\n but: Got 2 messages.'
166+ in str (error .exception .args [0 ]))
167+
168+ def test_message_count_matcher_above_fail (self , mock_get_sub , unused_mock ):
169+ self .init_counter_matcher (expected_msg_len = 1 )
170+ mock_sub = mock_get_sub .return_value
171+ self .pubsub_matcher .timeout = 0.1
172+ with self .assertRaisesRegex (AssertionError , r'Expected 1.*\n.*Got 0' ):
173+ hc_assert_that (self .mock_presult , self .pubsub_matcher )
174+ self .assertTrue (mock_sub .pull .called )
175+ self .assertEqual (mock_sub .acknowledge .call_count , 0 )
176+
177+ def test_message_count_matcher_success (self , mock_get_sub , unused_mock ):
178+ self .init_counter_matcher (expected_msg_len = 15 )
179+ mock_sub = mock_get_sub .return_value
180+ mock_sub .pull .side_effect = [create_pull_response (
181+ [PullResponseMessage (
182+ b'a' , {'foo' : 'bar' })
183+ for _ in range (15 )]
184+ )]
185+ hc_assert_that (self .mock_presult , self .pubsub_matcher )
186+ self .assertEqual (mock_sub .pull .call_count , 1 )
187+ self .assertEqual (mock_sub .acknowledge .call_count , 1 )
188+
152189
153190if __name__ == '__main__' :
154191 logging .getLogger ().setLevel (logging .INFO )
0 commit comments