github.com/apache/beam/sdks/v2@v2.48.2/python/apache_beam/testing/test_stream_service_test.py (about) 1 # 2 # Licensed to the Apache Software Foundation (ASF) under one or more 3 # contributor license agreements. See the NOTICE file distributed with 4 # this work for additional information regarding copyright ownership. 5 # The ASF licenses this file to You under the Apache License, Version 2.0 6 # (the "License"); you may not use this file except in compliance with 7 # the License. You may obtain a copy of the License at 8 # 9 # http://www.apache.org/licenses/LICENSE-2.0 10 # 11 # Unless required by applicable law or agreed to in writing, software 12 # distributed under the License is distributed on an "AS IS" BASIS, 13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 # See the License for the specific language governing permissions and 15 # limitations under the License. 16 # 17 18 # pytype: skip-file 19 20 import unittest 21 from unittest.mock import patch 22 23 import grpc 24 25 from apache_beam.portability.api import beam_interactive_api_pb2 26 from apache_beam.portability.api import beam_runner_api_pb2 27 from apache_beam.portability.api import beam_runner_api_pb2_grpc 28 from apache_beam.testing.test_stream_service import TestStreamServiceController 29 30 # Nose automatically detects tests if they match a regex. Here, it mistakens 31 # these protos as tests. For more info see the Nose docs at: 32 # https://nose.readthedocs.io/en/latest/writing_tests.html 33 beam_runner_api_pb2.TestStreamPayload.__test__ = False # type: ignore[attr-defined] 34 beam_interactive_api_pb2.TestStreamFileHeader.__test__ = False # type: ignore[attr-defined] 35 beam_interactive_api_pb2.TestStreamFileRecord.__test__ = False # type: ignore[attr-defined] 36 37 38 class EventsReader: 39 def __init__(self, expected_key): 40 self._expected_key = expected_key 41 42 def read_multiple(self, keys): 43 if keys != self._expected_key: 44 raise ValueError( 45 'Expected key ({}) is not argument({})'.format( 46 self._expected_key, keys)) 47 48 for i in range(10): 49 e = beam_runner_api_pb2.TestStreamPayload.Event() 50 e.element_event.elements.append( 51 beam_runner_api_pb2.TestStreamPayload.TimestampedElement(timestamp=i)) 52 yield e 53 54 55 EXPECTED_KEY = 'key' 56 EXPECTED_KEYS = [EXPECTED_KEY] 57 58 59 class TestStreamServiceTest(unittest.TestCase): 60 def setUp(self): 61 self.controller = TestStreamServiceController( 62 EventsReader(expected_key=[('full', EXPECTED_KEY)])) 63 self.controller.start() 64 65 channel = grpc.insecure_channel(self.controller.endpoint) 66 self.stub = beam_runner_api_pb2_grpc.TestStreamServiceStub(channel) 67 68 def tearDown(self): 69 self.controller.stop() 70 71 def test_normal_run(self): 72 r = self.stub.Events( 73 beam_runner_api_pb2.EventsRequest(output_ids=EXPECTED_KEYS)) 74 events = [e for e in r] 75 expected_events = [ 76 e for e in EventsReader( 77 expected_key=[EXPECTED_KEYS]).read_multiple([EXPECTED_KEYS]) 78 ] 79 80 self.assertEqual(events, expected_events) 81 82 def test_multiple_sessions(self): 83 resp_a = self.stub.Events( 84 beam_runner_api_pb2.EventsRequest(output_ids=EXPECTED_KEYS)) 85 resp_b = self.stub.Events( 86 beam_runner_api_pb2.EventsRequest(output_ids=EXPECTED_KEYS)) 87 88 events_a = [] 89 events_b = [] 90 91 done = False 92 while not done: 93 a_is_done = False 94 b_is_done = False 95 try: 96 events_a.append(next(resp_a)) 97 except StopIteration: 98 a_is_done = True 99 100 try: 101 events_b.append(next(resp_b)) 102 except StopIteration: 103 b_is_done = True 104 105 done = a_is_done and b_is_done 106 107 expected_events = [ 108 e for e in EventsReader( 109 expected_key=[EXPECTED_KEYS]).read_multiple([EXPECTED_KEYS]) 110 ] 111 112 self.assertEqual(events_a, expected_events) 113 self.assertEqual(events_b, expected_events) 114 115 116 class TestStreamServiceStartStopTest(unittest.TestCase): 117 118 # Weak internal use needs to be explicitly imported. 119 from grpc import _server 120 121 def setUp(self): 122 self.controller = TestStreamServiceController( 123 EventsReader(expected_key=[('full', EXPECTED_KEY)])) 124 self.assertFalse(self.controller._server_started) 125 self.assertFalse(self.controller._server_stopped) 126 127 def tearDown(self): 128 self.controller.stop() 129 130 def test_start_when_never_started(self): 131 with patch.object(self._server._Server, 132 'start', 133 wraps=self.controller._server.start) as mock_start: 134 self.controller.start() 135 mock_start.assert_called_once() 136 self.assertTrue(self.controller._server_started) 137 self.assertFalse(self.controller._server_stopped) 138 139 def test_start_noop_when_already_started(self): 140 with patch.object(self._server._Server, 141 'start', 142 wraps=self.controller._server.start) as mock_start: 143 self.controller.start() 144 mock_start.assert_called_once() 145 self.controller.start() 146 mock_start.assert_called_once() 147 148 def test_start_noop_when_already_stopped(self): 149 with patch.object(self._server._Server, 150 'start', 151 wraps=self.controller._server.start) as mock_start: 152 self.controller.start() 153 self.controller.stop() 154 mock_start.assert_called_once() 155 self.controller.start() 156 mock_start.assert_called_once() 157 158 def test_stop_noop_when_not_started(self): 159 with patch.object(self._server._Server, 160 'stop', 161 wraps=self.controller._server.stop) as mock_stop: 162 self.controller.stop() 163 mock_stop.assert_not_called() 164 165 def test_stop_when_already_started(self): 166 with patch.object(self._server._Server, 167 'stop', 168 wraps=self.controller._server.stop) as mock_stop: 169 self.controller.start() 170 mock_stop.assert_not_called() 171 self.controller.stop() 172 mock_stop.assert_called_once() 173 self.assertFalse(self.controller._server_started) 174 self.assertTrue(self.controller._server_stopped) 175 176 def test_stop_noop_when_already_stopped(self): 177 with patch.object(self._server._Server, 178 'stop', 179 wraps=self.controller._server.stop) as mock_stop: 180 self.controller.start() 181 self.controller.stop() 182 mock_stop.assert_called_once() 183 self.controller.stop() 184 mock_stop.assert_called_once() 185 186 187 if __name__ == '__main__': 188 unittest.main()