How to use onMessage method in Playwright Python

Best Python code snippet using playwright-python

test_queue_lifecycle.py

Source:test_queue_lifecycle.py Github

copy

Full Screen

...41 resp = json.loads(resp.decode())42 self.assertEqual(400, resp['headers']['status'])43 with mock.patch.object(self.protocol, 'sendMessage') as msg_mock:44 msg_mock.side_effect = validator45 self.protocol.onMessage(req, False)46 @ddt.data('480924', 'foo')47 def test_basics_thoroughly(self, project_id):48 # Stats are empty - queue not created yet49 action = consts.QUEUE_GET_STATS50 body = {"queue_name": "gummybears"}51 headers = {52 'Client-ID': uuidutils.generate_uuid(),53 'X-Project-ID': project_id54 }55 send_mock = mock.patch.object(self.protocol, 'sendMessage')56 self.addCleanup(send_mock.stop)57 sender = send_mock.start()58 req = test_utils.create_request(action, body, headers)59 def validator(resp, isBinary):60 resp = json.loads(resp.decode())61 self.assertEqual(404, resp['headers']['status'])62 sender.side_effect = validator63 self.protocol.onMessage(req, False)64 # Create65 action = consts.QUEUE_CREATE66 body = {"queue_name": "gummybears",67 "metadata": {68 "key": {69 "key2": "value",70 "key3": [1, 2, 3, 4, 5]},71 "messages": {"ttl": 600},72 }73 }74 req = test_utils.create_request(action, body, headers)75 def validator(resp, isBinary):76 resp = json.loads(resp.decode())77 self.assertEqual(201, resp['headers']['status'])78 sender.side_effect = validator79 self.protocol.onMessage(req, False)80 # Fetch metadata81 action = consts.QUEUE_GET82 body = {"queue_name": "gummybears"}83 meta = {"messages": {"ttl": 600},84 "key": {85 "key2": "value",86 "key3": [1, 2, 3, 4, 5]}87 }88 req = test_utils.create_request(action, body, headers)89 def validator(resp, isBinary):90 resp = json.loads(resp.decode())91 self.assertEqual(200, resp['headers']['status'])92 self.assertEqual(meta, resp['body'])93 sender.side_effect = validator94 self.protocol.onMessage(req, False)95 # Stats empty queue96 action = consts.QUEUE_GET_STATS97 body = {"queue_name": "gummybears"}98 req = test_utils.create_request(action, body, headers)99 def validator(resp, isBinary):100 resp = json.loads(resp.decode())101 self.assertEqual(200, resp['headers']['status'])102 sender.side_effect = validator103 self.protocol.onMessage(req, False)104 # Delete105 action = consts.QUEUE_DELETE106 body = {"queue_name": "gummybears"}107 req = test_utils.create_request(action, body, headers)108 def validator(resp, isBinary):109 resp = json.loads(resp.decode())110 self.assertEqual(204, resp['headers']['status'])111 sender.side_effect = validator112 self.protocol.onMessage(req, False)113 # Get non-existent stats114 action = consts.QUEUE_GET_STATS115 body = {"queue_name": "gummybears"}116 req = test_utils.create_request(action, body, headers)117 def validator(resp, isBinary):118 resp = json.loads(resp.decode())119 self.assertEqual(404, resp['headers']['status'])120 sender.side_effect = validator121 self.protocol.onMessage(req, False)122 def test_name_restrictions(self):123 headers = {124 'Client-ID': uuidutils.generate_uuid(),125 'X-Project-ID': 'test-project'126 }127 action = consts.QUEUE_CREATE128 body = {"queue_name": 'marsbar',129 "metadata": {130 "key": {131 "key2": "value",132 "key3": [1, 2, 3, 4, 5]},133 "messages": {"ttl": 600},134 }135 }136 send_mock = mock.patch.object(self.protocol, 'sendMessage')137 self.addCleanup(send_mock.stop)138 sender = send_mock.start()139 req = test_utils.create_request(action, body, headers)140 def validator(resp, isBinary):141 resp = json.loads(resp.decode())142 self.assertIn(resp['headers']['status'], [201, 204])143 sender.side_effect = validator144 self.protocol.onMessage(req, False)145 body["queue_name"] = "m@rsb@r"146 req = test_utils.create_request(action, body, headers)147 def validator(resp, isBinary):148 resp = json.loads(resp.decode())149 self.assertEqual(400, resp['headers']['status'])150 sender.side_effect = validator151 self.protocol.onMessage(req, False)152 body["queue_name"] = "marsbar" * 10153 req = test_utils.create_request(action, body, headers)154 self.protocol.onMessage(req, False)155 def test_project_id_restriction(self):156 headers = {157 'Client-ID': uuidutils.generate_uuid(),158 'X-Project-ID': 'test-project' * 30159 }160 action = consts.QUEUE_CREATE161 body = {"queue_name": 'poptart'}162 send_mock = mock.patch.object(self.protocol, 'sendMessage')163 self.addCleanup(send_mock.stop)164 sender = send_mock.start()165 req = test_utils.create_request(action, body, headers)166 def validator(resp, isBinary):167 resp = json.loads(resp.decode())168 self.assertEqual(400, resp['headers']['status'])169 sender.side_effect = validator170 self.protocol.onMessage(req, False)171 headers['X-Project-ID'] = 'test-project'172 req = test_utils.create_request(action, body, headers)173 def validator(resp, isBinary):174 resp = json.loads(resp.decode())175 self.assertIn(resp['headers']['status'], [201, 204])176 sender.side_effect = validator177 self.protocol.onMessage(req, False)178 def test_non_ascii_name(self):179 test_params = ((u'/queues/non-ascii-n\u0153me', 'utf-8'),180 (u'/queues/non-ascii-n\xc4me', 'iso8859-1'))181 headers = {182 'Client-ID': uuidutils.generate_uuid(),183 'X-Project-ID': 'test-project' * 30184 }185 action = consts.QUEUE_CREATE186 body = {"queue_name": test_params[0]}187 send_mock = mock.patch.object(self.protocol, 'sendMessage')188 self.addCleanup(send_mock.stop)189 sender = send_mock.start()190 req = test_utils.create_request(action, body, headers)191 def validator(resp, isBinary):192 resp = json.loads(resp.decode())193 self.assertEqual(400, resp['headers']['status'])194 sender.side_effect = validator195 self.protocol.onMessage(req, False)196 body = {"queue_name": test_params[1]}197 req = test_utils.create_request(action, body, headers)198 self.protocol.onMessage(req, False)199 def test_no_metadata(self):200 headers = {201 'Client-ID': uuidutils.generate_uuid(),202 'X-Project-ID': 'test-project'203 }204 action = consts.QUEUE_CREATE205 body = {"queue_name": "fizbat"}206 send_mock = mock.patch.object(self.protocol, 'sendMessage')207 self.addCleanup(send_mock.stop)208 sender = send_mock.start()209 req = test_utils.create_request(action, body, headers)210 def validator(resp, isBinary):211 resp = json.loads(resp.decode())212 self.assertIn(resp['headers']['status'], [201, 204])213 sender.side_effect = validator214 self.protocol.onMessage(req, False)215 def validator(resp, isBinary):216 resp = json.loads(resp.decode())217 self.assertEqual(204, resp['headers']['status'])218 sender.side_effect = validator219 self.protocol.onMessage(req, False)220 @ddt.data('{', '[]', '.', ' ')221 def test_bad_metadata(self, meta):222 headers = {223 'Client-ID': uuidutils.generate_uuid(),224 'X-Project-ID': 'test-project' * 30225 }226 action = consts.QUEUE_CREATE227 body = {"queue_name": "fizbat",228 "metadata": meta}229 send_mock = mock.patch.object(self.protocol, 'sendMessage')230 self.addCleanup(send_mock.stop)231 sender = send_mock.start()232 req = test_utils.create_request(action, body, headers)233 def validator(resp, isBinary):234 resp = json.loads(resp.decode())235 self.assertEqual(400, resp['headers']['status'])236 sender.side_effect = validator237 self.protocol.onMessage(req, False)238 def test_too_much_metadata(self):239 headers = {240 'Client-ID': uuidutils.generate_uuid(),241 'X-Project-ID': 'test-project'242 }243 action = consts.QUEUE_CREATE244 body = {"queue_name": "buttertoffee",245 "metadata": {"messages": {"ttl": 600},246 "padding": "x"}247 }248 max_size = self.transport_cfg.max_queue_metadata249 body["metadata"]["padding"] = "x" * max_size250 send_mock = mock.patch.object(self.protocol, 'sendMessage')251 self.addCleanup(send_mock.stop)252 sender = send_mock.start()253 req = test_utils.create_request(action, body, headers)254 def validator(resp, isBinary):255 resp = json.loads(resp.decode())256 self.assertEqual(400, resp['headers']['status'])257 sender.side_effect = validator258 self.protocol.onMessage(req, False)259 def test_way_too_much_metadata(self):260 headers = {261 'Client-ID': uuidutils.generate_uuid(),262 'X-Project-ID': 'test-project'263 }264 action = consts.QUEUE_CREATE265 body = {"queue_name": "peppermint",266 "metadata": {"messages": {"ttl": 600},267 "padding": "x"}268 }269 max_size = self.transport_cfg.max_queue_metadata270 body["metadata"]["padding"] = "x" * max_size * 5271 send_mock = mock.patch.object(self.protocol, 'sendMessage')272 self.addCleanup(send_mock.stop)273 sender = send_mock.start()274 req = test_utils.create_request(action, body, headers)275 def validator(resp, isBinary):276 resp = json.loads(resp.decode())277 self.assertEqual(400, resp['headers']['status'])278 sender.side_effect = validator279 self.protocol.onMessage(req, False)280 def test_update_metadata(self):281 self.skip("Implement patch method")282 headers = {283 'Client-ID': uuidutils.generate_uuid(),284 'X-Project-ID': 'test-project'285 }286 action = consts.QUEUE_CREATE287 body = {"queue_name": "bonobon"}288 send_mock = mock.patch.object(self.protocol, 'sendMessage')289 self.addCleanup(send_mock.stop)290 sender = send_mock.start()291 # Create292 req = test_utils.create_request(action, body, headers)293 def validator(resp, isBinary):294 resp = json.loads(resp.decode())295 self.assertEqual(201, resp['headers']['status'])296 sender.side_effect = validator297 self.protocol.onMessage(req, False)298 # Set meta299 meta1 = {"messages": {"ttl": 600}, "padding": "x"}300 body["metadata"] = meta1301 req = test_utils.create_request(action, body, headers)302 def validator(resp, isBinary):303 resp = json.loads(resp.decode())304 self.assertEqual(204, resp['headers']['status'])305 sender.side_effect = validator306 self.protocol.onMessage(req, False)307 # Get308 action = consts.QUEUE_GET309 body = {"queue_name": "bonobon"}310 req = test_utils.create_request(action, body, headers)311 def validator(resp, isBinary):312 resp = json.loads(resp.decode())313 self.assertEqual(204, resp['headers']['status'])314 self.assertEqual(meta1, resp['body'])315 sender.side_effect = validator316 self.protocol.onMessage(req, False)317 # Update318 action = consts.QUEUE_CREATE319 meta2 = {"messages": {"ttl": 100}, "padding": "y"}320 body["metadata"] = meta2321 req = test_utils.create_request(action, body, headers)322 def validator(resp, isBinary):323 resp = json.loads(resp.decode())324 self.assertEqual(204, resp['headers']['status'])325 sender.side_effect = validator326 self.protocol.onMessage(req, False)327 # Get again328 action = consts.QUEUE_GET329 body = {"queue_name": "bonobon"}330 req = test_utils.create_request(action, body, headers)331 def validator(resp, isBinary):332 resp = json.loads(resp.decode())333 self.assertEqual(200, resp['headers']['status'])334 self.assertEqual(meta2, resp['body'])335 sender.side_effect = validator336 self.protocol.onMessage(req, False)337 def test_list(self):338 arbitrary_number = 644079696574693339 project_id = str(arbitrary_number)340 client_id = uuidutils.generate_uuid()341 headers = {342 'X-Project-ID': project_id,343 'Client-ID': client_id344 }345 send_mock = mock.patch.object(self.protocol, 'sendMessage')346 self.addCleanup(send_mock.stop)347 sender = send_mock.start()348 # NOTE(kgriffs): It's important that this one sort after the one349 # above. This is in order to prove that bug/1236605 is fixed, and350 # stays fixed!351 # NOTE(vkmc): In websockets as well!352 alt_project_id = str(arbitrary_number + 1)353 # List empty354 action = consts.QUEUE_LIST355 body = {}356 req = test_utils.create_request(action, body, headers)357 def validator(resp, isBinary):358 resp = json.loads(resp.decode())359 self.assertEqual(200, resp['headers']['status'])360 self.assertEqual([], resp['body']['queues'])361 sender.side_effect = validator362 self.protocol.onMessage(req, False)363 # Payload exceeded364 body = {'limit': 21}365 req = test_utils.create_request(action, body, headers)366 def validator(resp, isBinary):367 resp = json.loads(resp.decode())368 self.assertEqual(400, resp['headers']['status'])369 sender.side_effect = validator370 self.protocol.onMessage(req, False)371 # Create some372 def create_queue(project_id, queue_name, metadata):373 altheaders = {'Client-ID': client_id}374 if project_id is not None:375 altheaders['X-Project-ID'] = project_id376 action = consts.QUEUE_CREATE377 body['queue_name'] = queue_name378 body['metadata'] = metadata379 req = test_utils.create_request(action, body, altheaders)380 def validator(resp, isBinary):381 resp = json.loads(resp.decode())382 self.assertEqual(201, resp['headers']['status'])383 sender.side_effect = validator384 self.protocol.onMessage(req, False)385 create_queue(project_id, 'q1', {"node": 31})386 create_queue(project_id, 'q2', {"node": 32})387 create_queue(project_id, 'q3', {"node": 33})388 create_queue(alt_project_id, 'q3', {"alt": 1})389 # List (limit)390 body = {'limit': 2}391 req = test_utils.create_request(action, body, headers)392 def validator(resp, isBinary):393 resp = json.loads(resp.decode())394 self.assertEqual(2, len(resp['body']['queues']))395 sender.side_effect = validator396 self.protocol.onMessage(req, False)397 # List (no metadata, get all)398 body = {'limit': 5}399 req = test_utils.create_request(action, body, headers)400 def validator(resp, isBinary):401 resp = json.loads(resp.decode())402 self.assertEqual(200, resp['headers']['status'])403 # Ensure we didn't pick up the queue from the alt project.404 self.assertEqual(3, len(resp['body']['queues']))405 sender.side_effect = validator406 self.protocol.onMessage(req, False)407 # List with metadata408 body = {'detailed': True}409 req = test_utils.create_request(action, body, headers)410 def validator(resp, isBinary):411 resp = json.loads(resp.decode())412 self.assertEqual(200, resp['headers']['status'])413 sender.side_effect = validator414 self.protocol.onMessage(req, False)415 action = consts.QUEUE_GET416 body = {"queue_name": "q1"}417 req = test_utils.create_request(action, body, headers)418 def validator(resp, isBinary):419 resp = json.loads(resp.decode())420 self.assertEqual(200, resp['headers']['status'])421 self.assertEqual({"node": 31}, resp['body'])422 sender.side_effect = validator423 self.protocol.onMessage(req, False)424 # List tail425 action = consts.QUEUE_LIST426 body = {}427 req = test_utils.create_request(action, body, headers)428 def validator(resp, isBinary):429 resp = json.loads(resp.decode())430 self.assertEqual(200, resp['headers']['status'])431 sender.side_effect = validator432 self.protocol.onMessage(req, False)433 # List manually-constructed tail434 body = {'marker': "zzz"}435 req = test_utils.create_request(action, body, headers)436 self.protocol.onMessage(req, False)437 def test_list_returns_503_on_nopoolfound_exception(self):438 headers = {439 'Client-ID': uuidutils.generate_uuid(),440 'X-Project-ID': 'test-project'441 }442 action = consts.QUEUE_LIST443 body = {}444 send_mock = mock.patch.object(self.protocol, 'sendMessage')445 self.addCleanup(send_mock.stop)446 sender = send_mock.start()447 req = test_utils.create_request(action, body, headers)448 def validator(resp, isBinary):449 resp = json.loads(resp.decode())450 self.assertEqual(503, resp['headers']['status'])451 sender.side_effect = validator452 queue_controller = self.boot.storage.queue_controller453 with mock.patch.object(queue_controller, 'list') as mock_queue_list:454 def queue_generator():455 raise storage_errors.NoPoolFound()456 # This generator tries to be like queue controller list generator457 # in some ways.458 def fake_generator():459 yield queue_generator()460 yield {}461 mock_queue_list.return_value = fake_generator()462 self.protocol.onMessage(req, False)463 def _post_messages(self, queue_name, headers, repeat=1):464 messages = [{'body': 239, 'ttl': 300}] * repeat465 action = consts.MESSAGE_POST466 body = {"queue_name": queue_name,467 "messages": messages}468 send_mock = mock.Mock()469 self.protocol.sendMessage = send_mock470 req = test_utils.create_request(action, body, headers)471 self.protocol.onMessage(req, False)472 return json.loads(send_mock.call_args[0][0].decode())473 def test_purge(self):474 arbitrary_number = 644079696574693475 project_id = str(arbitrary_number)476 client_id = uuidutils.generate_uuid()477 headers = {478 'X-Project-ID': project_id,479 'Client-ID': client_id480 }481 queue_name = 'myqueue'482 resp = self._post_messages(queue_name, headers, repeat=5)483 msg_ids = resp['body']['message_ids']484 send_mock = mock.Mock()485 self.protocol.sendMessage = send_mock486 for msg_id in msg_ids:487 action = consts.MESSAGE_GET488 body = {"queue_name": queue_name, "message_id": msg_id}489 req = test_utils.create_request(action, body, headers)490 self.protocol.onMessage(req, False)491 resp = json.loads(send_mock.call_args[0][0].decode())492 self.assertEqual(200, resp['headers']['status'])493 action = consts.QUEUE_PURGE494 body = {"queue_name": queue_name, "resource_types": ["messages"]}495 req = test_utils.create_request(action, body, headers)496 self.protocol.onMessage(req, False)497 resp = json.loads(send_mock.call_args[0][0].decode())498 self.assertEqual(204, resp['headers']['status'])499 for msg_id in msg_ids:500 action = consts.MESSAGE_GET501 body = {"queue_name": queue_name, "message_id": msg_id}502 req = test_utils.create_request(action, body, headers)503 self.protocol.onMessage(req, False)504 resp = json.loads(send_mock.call_args[0][0].decode())505 self.assertEqual(404, resp['headers']['status'])506class TestQueueLifecycleMongoDB(QueueLifecycleBaseTest):507 config_file = 'websocket_mongodb.conf'508 @testing.requires_mongodb509 def setUp(self):510 super(TestQueueLifecycleMongoDB, self).setUp()511 def tearDown(self):512 storage = self.boot.storage._storage513 connection = storage.connection514 connection.drop_database(self.boot.control.queues_database)515 for db in storage.message_databases:516 connection.drop_database(db)517 super(TestQueueLifecycleMongoDB, self).tearDown()

Full Screen

Full Screen

test_messages.py

Source:test_messages.py Github

copy

Full Screen

...39 body = {"queue_name": "kitkat"}40 req = test_utils.create_request(consts.QUEUE_CREATE,41 body, self.headers)42 with mock.patch.object(self.protocol, 'sendMessage') as msg_mock:43 self.protocol.onMessage(req, False)44 resp = json.loads(msg_mock.call_args[0][0].decode())45 self.assertIn(resp['headers']['status'], [201, 204])46 def tearDown(self):47 super(MessagesBaseTest, self).tearDown()48 body = {"queue_name": "kitkat"}49 send_mock = mock.Mock()50 self.protocol.sendMessage = send_mock51 req = test_utils.create_request(consts.QUEUE_DELETE,52 body, self.headers)53 self.protocol.onMessage(req, False)54 resp = json.loads(send_mock.call_args[0][0].decode())55 self.assertEqual(204, resp['headers']['status'])56 def _test_post(self, sample_messages, in_binary=False):57 body = {"queue_name": "kitkat",58 "messages": sample_messages}59 send_mock = mock.Mock()60 self.protocol.sendMessage = send_mock61 dumps, loads, create_req = test_utils.get_pack_tools(binary=in_binary)62 req = create_req(consts.MESSAGE_POST, body, self.headers)63 self.protocol.onMessage(req, in_binary)64 arg = send_mock.call_args[0][0]65 if not in_binary:66 arg = arg.decode()67 resp = loads(arg)68 self.assertEqual(201, resp['headers']['status'])69 self.msg_ids = resp['body']['message_ids']70 self.assertEqual(len(sample_messages), len(self.msg_ids))71 lookup = dict([(m['ttl'], m['body']) for m in sample_messages])72 # Test GET on the message resource directly73 # NOTE(cpp-cabrera): force the passing of time to age a message74 timeutils_utcnow = 'oslo_utils.timeutils.utcnow'75 now = timeutils.utcnow() + datetime.timedelta(seconds=10)76 with mock.patch(timeutils_utcnow) as mock_utcnow:77 mock_utcnow.return_value = now78 for msg_id in self.msg_ids:79 headers = self.headers.copy()80 headers['X-Project-ID'] = '777777'81 # Wrong project ID82 action = consts.MESSAGE_GET83 body = {"queue_name": "kitkat",84 "message_id": msg_id}85 req = create_req(action, body, headers)86 self.protocol.onMessage(req, in_binary)87 arg = send_mock.call_args[0][0]88 if not in_binary:89 arg = arg.decode()90 resp = loads(arg)91 self.assertEqual(404, resp['headers']['status'])92 # Correct project ID93 req = create_req(action, body, self.headers)94 self.protocol.onMessage(req, in_binary)95 arg = send_mock.call_args[0][0]96 if not in_binary:97 arg = arg.decode()98 resp = loads(arg)99 self.assertEqual(200, resp['headers']['status'])100 # Check message properties101 message = resp['body']['messages']102 self.assertEqual(lookup[message['ttl']], message['body'])103 self.assertEqual(msg_id, message['id'])104 # no negative age105 # NOTE(cpp-cabrera): testtools lacks106 # GreaterThanEqual on py26107 self.assertThat(message['age'],108 matchers.GreaterThan(-1))109 # Test bulk GET110 action = consts.MESSAGE_GET_MANY111 body = {"queue_name": "kitkat",112 "message_ids": self.msg_ids}113 req = create_req(action, body, self.headers)114 self.protocol.onMessage(req, in_binary)115 arg = send_mock.call_args[0][0]116 if not in_binary:117 arg = arg.decode()118 resp = loads(arg)119 self.assertEqual(200, resp['headers']['status'])120 expected_ttls = set(m['ttl'] for m in sample_messages)121 actual_ttls = set(m['ttl'] for m in resp['body']['messages'])122 self.assertFalse(expected_ttls - actual_ttls)123 actual_ids = set(m['id'] for m in resp['body']['messages'])124 self.assertFalse(set(self.msg_ids) - actual_ids)125 def test_exceeded_payloads(self):126 # Get a valid message id127 resp = self._post_messages("kitkat")128 msg_id = resp['body']['message_ids']129 # Bulk GET restriction130 get_msg_ids = msg_id * 21131 action = consts.MESSAGE_GET_MANY132 body = {"queue_name": "kitkat",133 "message_ids": get_msg_ids}134 send_mock = mock.Mock()135 self.protocol.sendMessage = send_mock136 req = test_utils.create_request(action, body, self.headers)137 self.protocol.onMessage(req, False)138 resp = json.loads(send_mock.call_args[0][0].decode())139 self.assertEqual(400, resp['headers']['status'])140 # Listing restriction141 body['limit'] = 21142 req = test_utils.create_request(action, body, self.headers)143 self.protocol.onMessage(req, False)144 resp = json.loads(send_mock.call_args[0][0].decode())145 self.assertEqual(400, resp['headers']['status'])146 # Bulk deletion restriction147 del_msg_ids = msg_id * 22148 action = consts.MESSAGE_GET_MANY149 body = {"queue_name": "kitkat",150 "message_ids": del_msg_ids}151 req = test_utils.create_request(action, body, self.headers)152 self.protocol.onMessage(req, False)153 resp = json.loads(send_mock.call_args[0][0].decode())154 self.assertEqual(400, resp['headers']['status'])155 @ddt.data(True, False)156 def test_post_single(self, in_binary):157 sample_messages = [158 {'body': {'key': 'value'}, 'ttl': 200},159 ]160 self._test_post(sample_messages, in_binary=in_binary)161 @ddt.data(True, False)162 def test_post_multiple(self, in_binary):163 sample_messages = [164 {'body': 239, 'ttl': 100},165 {'body': {'key': 'value'}, 'ttl': 200},166 {'body': [1, 3], 'ttl': 300},167 ]168 self._test_post(sample_messages, in_binary=in_binary)169 def test_post_optional_ttl(self):170 messages = [{'body': 239},171 {'body': {'key': 'value'}, 'ttl': 200}]172 action = consts.MESSAGE_POST173 body = {"queue_name": "kitkat",174 "messages": messages}175 req = test_utils.create_request(action, body, self.headers)176 send_mock = mock.Mock()177 self.protocol.sendMessage = send_mock178 self.protocol.onMessage(req, False)179 resp = json.loads(send_mock.call_args[0][0].decode())180 self.assertEqual(201, resp['headers']['status'])181 msg_id = resp['body']['message_ids'][0]182 action = consts.MESSAGE_GET183 body = {"queue_name": "kitkat", "message_id": msg_id}184 req = test_utils.create_request(action, body, self.headers)185 self.protocol.onMessage(req, False)186 resp = json.loads(send_mock.call_args[0][0].decode())187 self.assertEqual(200, resp['headers']['status'])188 self.assertEqual(self.default_message_ttl,189 resp['body']['messages']['ttl'])190 def test_post_to_non_ascii_queue(self):191 queue_name = u'non-ascii-n\u0153me'192 if six.PY2:193 queue_name = queue_name.encode('utf-8')194 resp = self._post_messages(queue_name)195 self.assertEqual(400, resp['headers']['status'])196 def test_post_with_long_queue_name(self):197 # NOTE(kgriffs): This test verifies that routes with198 # embedded queue name params go through the validation199 # hook, regardless of the target resource.200 queue_name = 'v' * validation.QUEUE_NAME_MAX_LEN201 resp = self._post_messages(queue_name)202 self.assertEqual(201, resp['headers']['status'])203 queue_name += 'v'204 resp = self._post_messages(queue_name)205 self.assertEqual(400, resp['headers']['status'])206 def test_post_to_missing_queue(self):207 queue_name = 'nonexistent'208 resp = self._post_messages(queue_name)209 self.assertEqual(201, resp['headers']['status'])210 def test_post_invalid_ttl(self):211 sample_messages = [212 {'body': {'key': 'value'}, 'ttl': '200'},213 ]214 action = consts.MESSAGE_POST215 body = {"queue_name": "kitkat",216 "messages": sample_messages}217 send_mock = mock.patch.object(self.protocol, 'sendMessage')218 self.addCleanup(send_mock.stop)219 send_mock = send_mock.start()220 req = test_utils.create_request(action, body, self.headers)221 self.protocol.onMessage(req, False)222 resp = json.loads(send_mock.call_args[0][0].decode())223 self.assertEqual(400, resp['headers']['status'])224 self.assertEqual(225 'Bad request. The value of the "ttl" field must be a int.',226 resp['body']['exception'])227 def test_post_no_body(self):228 sample_messages = [229 {'ttl': 200},230 ]231 action = consts.MESSAGE_POST232 body = {"queue_name": "kitkat",233 "messages": sample_messages}234 send_mock = mock.patch.object(self.protocol, 'sendMessage')235 self.addCleanup(send_mock.stop)236 send_mock = send_mock.start()237 req = test_utils.create_request(action, body, self.headers)238 self.protocol.onMessage(req, False)239 resp = json.loads(send_mock.call_args[0][0].decode())240 self.assertEqual(400, resp['headers']['status'])241 self.assertEqual(242 'Bad request. Missing "body" field.', resp['body']['exception'])243 def test_get_from_missing_queue(self):244 action = consts.MESSAGE_LIST245 body = {"queue_name": "anothernonexistent"}246 req = test_utils.create_request(action, body, self.headers)247 send_mock = mock.Mock()248 self.protocol.sendMessage = send_mock249 self.protocol.onMessage(req, False)250 resp = json.loads(send_mock.call_args[0][0].decode())251 self.assertEqual(200, resp['headers']['status'])252 self.assertEqual([], resp['body']['messages'])253 @ddt.data('', '0xdeadbeef', '550893e0-2b6e-11e3-835a-5cf9dd72369')254 def test_bad_client_id(self, text_id):255 action = consts.MESSAGE_POST256 body = {257 "queue_name": "kinder",258 "messages": [{"ttl": 60,259 "body": ""}]260 }261 headers = {262 'Client-ID': text_id,263 'X-Project-ID': self.project_id264 }265 send_mock = mock.Mock()266 self.protocol.sendMessage = send_mock267 req = test_utils.create_request(action, body, headers)268 self.protocol.onMessage(req, False)269 resp = json.loads(send_mock.call_args[0][0].decode())270 self.assertEqual(400, resp['headers']['status'])271 action = consts.MESSAGE_GET272 body = {273 "queue_name": "kinder",274 "limit": 3,275 "echo": True276 }277 req = test_utils.create_request(action, body, headers)278 self.protocol.onMessage(req, False)279 resp = json.loads(send_mock.call_args[0][0].decode())280 self.assertEqual(400, resp['headers']['status'])281 @ddt.data(None, '[', '[]', '{}', '.')282 def test_post_bad_message(self, document):283 action = consts.MESSAGE_POST284 body = {285 "queue_name": "kinder",286 "messages": document287 }288 send_mock = mock.Mock()289 self.protocol.sendMessage = send_mock290 req = test_utils.create_request(action, body, self.headers)291 self.protocol.onMessage(req, False)292 resp = json.loads(send_mock.call_args[0][0].decode())293 self.assertEqual(400, resp['headers']['status'])294 @ddt.data(-1, 59, 1209601)295 def test_unacceptable_ttl(self, ttl):296 action = consts.MESSAGE_POST297 body = {"queue_name": "kinder",298 "messages": [{"ttl": ttl, "body": ""}]}299 send_mock = mock.Mock()300 self.protocol.sendMessage = send_mock301 req = test_utils.create_request(action, body, self.headers)302 self.protocol.onMessage(req, False)303 resp = json.loads(send_mock.call_args[0][0].decode())304 self.assertEqual(400, resp['headers']['status'])305 def test_exceeded_message_posting(self):306 # Total (raw request) size307 document = [{'body': "some body", 'ttl': 100}] * 8000308 action = consts.MESSAGE_POST309 body = {310 "queue_name": "kinder",311 "messages": document312 }313 send_mock = mock.Mock()314 self.protocol.sendMessage = send_mock315 req = test_utils.create_request(action, body, self.headers)316 self.protocol.onMessage(req, False)317 resp = json.loads(send_mock.call_args[0][0].decode())318 self.assertEqual(400, resp['headers']['status'])319 @ddt.data('{"overflow": 9223372036854775808}',320 '{"underflow": -9223372036854775809}')321 def test_unsupported_json(self, document):322 action = consts.MESSAGE_POST323 body = {324 "queue_name": "fizz",325 "messages": document326 }327 send_mock = mock.Mock()328 self.protocol.sendMessage = send_mock329 req = test_utils.create_request(action, body, self.headers)330 self.protocol.onMessage(req, False)331 resp = json.loads(send_mock.call_args[0][0].decode())332 self.assertEqual(400, resp['headers']['status'])333 def test_delete(self):334 resp = self._post_messages("tofi")335 msg_id = resp['body']['message_ids'][0]336 action = consts.MESSAGE_GET337 body = {"queue_name": "tofi",338 "message_id": msg_id}339 send_mock = mock.Mock()340 self.protocol.sendMessage = send_mock341 req = test_utils.create_request(action, body, self.headers)342 self.protocol.onMessage(req, False)343 resp = json.loads(send_mock.call_args[0][0].decode())344 self.assertEqual(200, resp['headers']['status'])345 # Delete queue346 action = consts.MESSAGE_DELETE347 req = test_utils.create_request(action, body, self.headers)348 self.protocol.onMessage(req, False)349 resp = json.loads(send_mock.call_args[0][0].decode())350 self.assertEqual(204, resp['headers']['status'])351 # Get non existent queue352 action = consts.MESSAGE_GET353 req = test_utils.create_request(action, body, self.headers)354 self.protocol.onMessage(req, False)355 resp = json.loads(send_mock.call_args[0][0].decode())356 self.assertEqual(404, resp['headers']['status'])357 # Safe to delete non-existing ones358 action = consts.MESSAGE_DELETE359 req = test_utils.create_request(action, body, self.headers)360 self.protocol.onMessage(req, False)361 resp = json.loads(send_mock.call_args[0][0].decode())362 self.assertEqual(204, resp['headers']['status'])363 def test_bulk_delete(self):364 resp = self._post_messages("nerds", repeat=5)365 msg_ids = resp['body']['message_ids']366 action = consts.MESSAGE_DELETE_MANY367 body = {"queue_name": "nerds",368 "message_ids": msg_ids}369 send_mock = mock.Mock()370 self.protocol.sendMessage = send_mock371 req = test_utils.create_request(action, body, self.headers)372 self.protocol.onMessage(req, False)373 resp = json.loads(send_mock.call_args[0][0].decode())374 self.assertEqual(204, resp['headers']['status'])375 action = consts.MESSAGE_GET376 req = test_utils.create_request(action, body, self.headers)377 self.protocol.onMessage(req, False)378 resp = json.loads(send_mock.call_args[0][0].decode())379 self.assertEqual(400, resp['headers']['status'])380 # Safe to delete non-existing ones381 action = consts.MESSAGE_DELETE_MANY382 req = test_utils.create_request(action, body, self.headers)383 self.protocol.onMessage(req, False)384 resp = json.loads(send_mock.call_args[0][0].decode())385 self.assertEqual(204, resp['headers']['status'])386 # Even after the queue is gone387 action = consts.QUEUE_DELETE388 body = {"queue_name": "nerds"}389 req = test_utils.create_request(action, body, self.headers)390 self.protocol.onMessage(req, False)391 resp = json.loads(send_mock.call_args[0][0].decode())392 self.assertEqual(204, resp['headers']['status'])393 action = consts.MESSAGE_DELETE_MANY394 body = {"queue_name": "nerds",395 "message_ids": msg_ids}396 req = test_utils.create_request(action, body, self.headers)397 self.protocol.onMessage(req, False)398 resp = json.loads(send_mock.call_args[0][0].decode())399 self.assertEqual(204, resp['headers']['status'])400 def test_pop_delete(self):401 self._post_messages("kitkat", repeat=5)402 action = consts.MESSAGE_DELETE_MANY403 body = {"queue_name": "kitkat", "pop": 2}404 send_mock = mock.Mock()405 self.protocol.sendMessage = send_mock406 req = test_utils.create_request(action, body, self.headers)407 self.protocol.onMessage(req, False)408 resp = json.loads(send_mock.call_args[0][0].decode())409 self.assertEqual(200, resp['headers']['status'])410 self.assertEqual(2, len(resp['body']['messages']))411 self.assertEqual(239, resp['body']['messages'][0]['body'])412 self.assertEqual(239, resp['body']['messages'][1]['body'])413 def test_get_nonexistent_message_404s(self):414 action = consts.MESSAGE_GET415 body = {"queue_name": "notthere",416 "message_id": "a"}417 send_mock = mock.Mock()418 self.protocol.sendMessage = send_mock419 req = test_utils.create_request(action, body, self.headers)420 self.protocol.onMessage(req, False)421 resp = json.loads(send_mock.call_args[0][0].decode())422 self.assertEqual(404, resp['headers']['status'])423 def test_get_multiple_invalid_messages_404s(self):424 action = consts.MESSAGE_GET_MANY425 body = {"queue_name": "notnotthere",426 "message_ids": ["a", "b", "c"]}427 send_mock = mock.Mock()428 self.protocol.sendMessage = send_mock429 req = test_utils.create_request(action, body, self.headers)430 self.protocol.onMessage(req, False)431 resp = json.loads(send_mock.call_args[0][0].decode())432 self.assertEqual(200, resp['headers']['status'])433 def test_delete_multiple_invalid_messages_204s(self):434 action = consts.MESSAGE_DELETE435 body = {"queue_name": "yetanothernotthere",436 "message_ids": ["a", "b", "c"]}437 send_mock = mock.Mock()438 self.protocol.sendMessage = send_mock439 req = test_utils.create_request(action, body, self.headers)440 self.protocol.onMessage(req, False)441 resp = json.loads(send_mock.call_args[0][0].decode())442 self.assertEqual(400, resp['headers']['status'])443 def _post_messages(self, queue_name, repeat=1):444 messages = [{'body': 239, 'ttl': 300}] * repeat445 action = consts.MESSAGE_POST446 body = {"queue_name": queue_name,447 "messages": messages}448 send_mock = mock.Mock()449 self.protocol.sendMessage = send_mock450 req = test_utils.create_request(action, body, self.headers)451 self.protocol.onMessage(req, False)452 return json.loads(send_mock.call_args[0][0].decode())453 def test_invalid_request(self):454 send_mock = mock.Mock()455 self.protocol.sendMessage = send_mock456 self.protocol.onMessage('foo', False)457 self.assertEqual(1, send_mock.call_count)458 response = json.loads(send_mock.call_args[0][0].decode())459 self.assertIn('error', response['body'])460 self.assertEqual({'status': 400}, response['headers'])461 self.assertEqual(462 {'action': None, 'api': 'v2', 'body': {}, 'headers': {}},...

Full Screen

Full Screen

bybit.py

Source:bybit.py Github

copy

Full Screen

1from __future__ import annotations2import asyncio3import logging4from typing import Awaitable, Optional, Union5import aiohttp6from ..store import DataStore, DataStoreManager7from ..typedefs import Item8from ..ws import ClientWebSocketResponse9logger = logging.getLogger(__name__)10class BybitInverseDataStore(DataStoreManager):11 """12 Bybit Inverse契約のデータストアマネージャー13 """14 def _init(self) -> None:15 self.create("orderbook", datastore_class=OrderBookInverse)16 self.create("trade", datastore_class=TradeInverse)17 self.create("insurance", datastore_class=Insurance)18 self.create("instrument", datastore_class=InstrumentInverse)19 self.create("kline", datastore_class=KlineInverse)20 self.create("liquidation", datastore_class=LiquidationInverse)21 self.create("position", datastore_class=PositionInverse)22 self.create("execution", datastore_class=ExecutionInverse)23 self.create("order", datastore_class=OrderInverse)24 self.create("stoporder", datastore_class=StopOrderInverse)25 self.create("wallet", datastore_class=WalletInverse)26 self.timestamp_e6: Optional[int] = None27 async def initialize(self, *aws: Awaitable[aiohttp.ClientResponse]) -> None:28 """29 対応エンドポイント30 - GET /v2/private/order (DataStore: order)31 - GET /futures/private/order (DataStore: order)32 - GET /v2/private/stop-order (DataStore: stoporder)33 - GET /futures/private/stop-order (DataStore: stoporder)34 - GET /v2/private/position/list (DataStore: position)35 - GET /futures/private/position/list (DataStore: position)36 - GET /v2/private/wallet/balance (DataStore: wallet)37 - GET /v2/public/kline/list (DataStore: kline)38 """39 for f in asyncio.as_completed(aws):40 resp = await f41 data = await resp.json()42 if data["ret_code"] != 0:43 raise ValueError(44 "Response error at DataStore initialization\n"45 f"URL: {resp.url}\n"46 f"Data: {data}"47 )48 if resp.url.path in (49 "/v2/private/order",50 "/futures/private/order",51 ):52 self.order._onresponse(data["result"])53 elif resp.url.path in (54 "/v2/private/stop-order",55 "/futures/private/stop-order",56 ):57 self.stoporder._onresponse(data["result"])58 elif resp.url.path in (59 "/v2/private/position/list",60 "/futures/private/position/list",61 ):62 self.position._onresponse(data["result"])63 elif resp.url.path == "/v2/public/kline/list":64 self.kline._onresponse(data["result"])65 elif resp.url.path == "/v2/private/wallet/balance":66 self.wallet._onresponse(data["result"])67 def _onmessage(self, msg: Item, ws: ClientWebSocketResponse) -> None:68 if "success" in msg:69 if not msg["success"]:70 logger.warning(msg)71 if "topic" in msg:72 topic: str = msg["topic"]73 data = msg["data"]74 if any(75 [76 topic.startswith("orderBookL2_25"),77 topic.startswith("orderBook_200"),78 ]79 ):80 self.orderbook._onmessage(topic, msg["type"], data)81 elif topic.startswith("trade"):82 self.trade._onmessage(data)83 elif topic.startswith("insurance"):84 self.insurance._onmessage(data)85 elif topic.startswith("instrument_info"):86 self.instrument._onmessage(topic, msg["type"], data)87 if topic.startswith("klineV2"):88 self.kline._onmessage(topic, data)89 elif topic.startswith("liquidation"):90 self.liquidation._onmessage(data)91 elif topic == "position":92 self.position._onmessage(data)93 elif topic == "execution":94 self.execution._onmessage(data)95 elif topic == "order":96 self.order._onmessage(data)97 elif topic == "stop_order":98 self.stoporder._onmessage(data)99 elif topic == "wallet":100 self.wallet._onmessage(data)101 if "timestamp_e6" in msg:102 self.timestamp_e6 = int(msg["timestamp_e6"])103 @property104 def orderbook(self) -> "OrderBookInverse":105 return self.get("orderbook", OrderBookInverse)106 @property107 def trade(self) -> "TradeInverse":108 return self.get("trade", TradeInverse)109 @property110 def insurance(self) -> "Insurance":111 return self.get("insurance", Insurance)112 @property113 def instrument(self) -> "InstrumentInverse":114 return self.get("instrument", InstrumentInverse)115 @property116 def kline(self) -> "KlineInverse":117 return self.get("kline", KlineInverse)118 @property119 def liquidation(self) -> "LiquidationInverse":120 return self.get("liquidation", LiquidationInverse)121 @property122 def position(self) -> "PositionInverse":123 """124 インバース契約(無期限/先物)用のポジション125 """126 return self.get("position", PositionInverse)127 @property128 def execution(self) -> "ExecutionInverse":129 return self.get("execution", ExecutionInverse)130 @property131 def order(self) -> "OrderInverse":132 """133 アクティブオーダーのみ(約定・キャンセル済みは削除される)134 """135 return self.get("order", OrderInverse)136 @property137 def stoporder(self) -> "StopOrderInverse":138 """139 アクティブオーダーのみ(トリガー済みは削除される)140 """141 return self.get("stoporder", StopOrderInverse)142 @property143 def wallet(self) -> "WalletInverse":144 return self.get("wallet", WalletInverse)145class BybitUSDTDataStore(DataStoreManager):146 """147 Bybit USDT契約のデータストアマネージャー148 """149 def _init(self) -> None:150 self.create("orderbook", datastore_class=OrderBookUSDT)151 self.create("trade", datastore_class=TradeUSDT)152 self.create("insurance", datastore_class=Insurance)153 self.create("instrument", datastore_class=InstrumentUSDT)154 self.create("kline", datastore_class=KlineUSDT)155 self.create("liquidation", datastore_class=LiquidationUSDT)156 self.create("position", datastore_class=PositionUSDT)157 self.create("execution", datastore_class=ExecutionUSDT)158 self.create("order", datastore_class=OrderUSDT)159 self.create("stoporder", datastore_class=StopOrderUSDT)160 self.create("wallet", datastore_class=WalletUSDT)161 self.timestamp_e6: Optional[int] = None162 async def initialize(self, *aws: Awaitable[aiohttp.ClientResponse]) -> None:163 """164 対応エンドポイント165 - GET /private/linear/order/search (DataStore: order)166 - GET /private/linear/stop-order/search (DataStore: stoporder)167 - GET /private/linear/position/list (DataStore: position)168 - GET /private/linear/position/list (DataStore: position)169 - GET /public/linear/kline (DataStore: kline)170 - GET /v2/private/wallet/balance (DataStore: wallet)171 """172 for f in asyncio.as_completed(aws):173 resp = await f174 data = await resp.json()175 if data["ret_code"] != 0:176 raise ValueError(177 "Response error at DataStore initialization\n"178 f"URL: {resp.url}\n"179 f"Data: {data}"180 )181 if resp.url.path == "/private/linear/order/search":182 self.order._onresponse(data["result"])183 elif resp.url.path == "/private/linear/stop-order/search":184 self.stoporder._onresponse(data["result"])185 elif resp.url.path == "/private/linear/position/list":186 self.position._onresponse(data["result"])187 elif resp.url.path == "/public/linear/kline":188 self.kline._onresponse(data["result"])189 elif resp.url.path == "/v2/private/wallet/balance":190 self.wallet._onresponse(data["result"])191 def _onmessage(self, msg: Item, ws: ClientWebSocketResponse) -> None:192 if "success" in msg:193 if not msg["success"]:194 logger.warning(msg)195 if "topic" in msg:196 topic: str = msg["topic"]197 data = msg["data"]198 if any(199 [200 topic.startswith("orderBookL2_25"),201 topic.startswith("orderBook_200"),202 ]203 ):204 self.orderbook._onmessage(topic, msg["type"], data)205 elif topic.startswith("trade"):206 self.trade._onmessage(data)207 elif topic.startswith("instrument_info"):208 self.instrument._onmessage(topic, msg["type"], data)209 if topic.startswith("candle"):210 self.kline._onmessage(topic, data)211 elif topic.startswith("liquidation"):212 self.liquidation._onmessage(data)213 elif topic == "position":214 self.position._onmessage(data)215 elif topic == "execution":216 self.execution._onmessage(data)217 elif topic == "order":218 self.order._onmessage(data)219 elif topic == "stop_order":220 self.stoporder._onmessage(data)221 elif topic == "wallet":222 self.wallet._onmessage(data)223 if "timestamp_e6" in msg:224 self.timestamp_e6 = int(msg["timestamp_e6"])225 @property226 def orderbook(self) -> "OrderBookUSDT":227 return self.get("orderbook", OrderBookUSDT)228 @property229 def trade(self) -> "TradeUSDT":230 return self.get("trade", TradeUSDT)231 @property232 def instrument(self) -> "InstrumentUSDT":233 return self.get("instrument", InstrumentUSDT)234 @property235 def kline(self) -> "KlineUSDT":236 return self.get("kline", KlineUSDT)237 @property238 def liquidation(self) -> "LiquidationUSDT":239 return self.get("liquidation", LiquidationUSDT)240 @property241 def position(self) -> "PositionUSDT":242 """243 USDT契約用のポジション244 """245 return self.get("position", PositionUSDT)246 @property247 def execution(self) -> "ExecutionUSDT":248 return self.get("execution", ExecutionUSDT)249 @property250 def order(self) -> "OrderUSDT":251 """252 アクティブオーダーのみ(約定・キャンセル済みは削除される)253 """254 return self.get("order", OrderUSDT)255 @property256 def stoporder(self) -> "StopOrderUSDT":257 """258 アクティブオーダーのみ(トリガー済みは削除される)259 """260 return self.get("stoporder", StopOrderUSDT)261 @property262 def wallet(self) -> "WalletUSDT":263 return self.get("wallet", WalletUSDT)264class OrderBookInverse(DataStore):265 _KEYS = ["symbol", "id", "side"]266 def sorted(self, query: Optional[Item] = None) -> dict[str, list[Item]]:267 if query is None:268 query = {}269 result = {"Sell": [], "Buy": []}270 for item in self:271 if all(k in item and query[k] == item[k] for k in query):272 result[item["side"]].append(item)273 result["Sell"].sort(key=lambda x: x["id"])274 result["Buy"].sort(key=lambda x: x["id"], reverse=True)275 return result276 def _onmessage(self, topic: str, type_: str, data: Union[list[Item], Item]) -> None:277 if type_ == "snapshot":278 symbol = topic.split(".")[-1]279 # ex: "orderBookL2_25.BTCUSD", "orderBook_200.100ms.BTCUSD"280 result = self.find({"symbol": symbol})281 self._delete(result)282 self._insert(data)283 elif type_ == "delta":284 self._delete(data["delete"])285 self._update(data["update"])286 self._insert(data["insert"])287class OrderBookUSDT(OrderBookInverse):288 def _onmessage(self, topic: str, type_: str, data: Union[list[Item], Item]) -> None:289 if type_ == "snapshot":290 symbol = topic.split(".")[-1]291 # ex: "orderBookL2_25.BTCUSDT", "orderBook_200.100ms.BTCUSDT"292 result = self.find({"symbol": symbol})293 self._delete(result)294 self._insert(data["order_book"])295 elif type_ == "delta":296 self._delete(data["delete"])297 self._update(data["update"])298 self._insert(data["insert"])299class TradeInverse(DataStore):300 _KEYS = ["trade_id"]301 _MAXLEN = 99999302 def _onmessage(self, data: list[Item]) -> None:303 self._insert(data)304class TradeUSDT(TradeInverse):305 ...306class Insurance(DataStore):307 _KEYS = ["currency"]308 def _onmessage(self, data: list[Item]) -> None:309 self._update(data)310class InstrumentInverse(DataStore):311 _KEYS = ["symbol"]312 def _onmessage(self, topic: str, type_: str, data: Item) -> None:313 if type_ == "snapshot":314 symbol = topic.split(".")[-1] # ex: "instrument_info.100ms.BTCUSD"315 result = self.find({"symbol": symbol})316 self._delete(result)317 self._insert([data])318 elif type_ == "delta":319 self._update(data["update"])320class InstrumentUSDT(InstrumentInverse):321 ...322class KlineInverse(DataStore):323 _KEYS = ["start", "symbol", "interval"]324 def _onmessage(self, topic: str, data: list[Item]) -> None:325 topic_split = topic.split(".") # ex:"klineV2.1.BTCUSD"326 for item in data:327 item["symbol"] = topic_split[-1]328 item["interval"] = topic_split[-2]329 self._update(data)330 def _onresponse(self, data: list[Item]) -> None:331 for item in data:332 item["start"] = item.pop("open_time")333 self._update(data)334class KlineUSDT(KlineInverse):335 ...336class LiquidationInverse(DataStore):337 _MAXLEN = 99999338 def _onmessage(self, item: Item) -> None:339 self._insert([item])340class LiquidationUSDT(LiquidationInverse):341 ...342class PositionInverse(DataStore):343 _KEYS = ["symbol", "position_idx"]344 def one(self, symbol: str) -> Optional[Item]:345 return self.get({"symbol": symbol, "position_idx": 0})346 def both(self, symbol: str) -> dict[str, Optional[Item]]:347 return {348 "Sell": self.get({"symbol": symbol, "position_idx": 2}),349 "Buy": self.get({"symbol": symbol, "position_idx": 1}),350 }351 def _onresponse(self, data: Union[Item, list[Item]]) -> None:352 if isinstance(data, dict):353 self._update([data]) # ex: {"symbol": "BTCUSD", ...}354 elif isinstance(data, list):355 for item in data:356 if "is_valid" in item:357 if item["is_valid"]:358 self._update([item["data"]])359 # ex:360 # [361 # {362 # "is_valid": True,363 # "data": {"symbol": "BTCUSDM21", ...}364 # },365 # ...366 # ]367 else:368 self._update([item])369 # ex: [{"symbol": "BTCUSDT", ...}, ...]370 def _onmessage(self, data: list[Item]) -> None:371 self._update(data)372class PositionUSDT(PositionInverse):373 def _onmessage(self, data: list[Item]) -> None:374 for item in data:375 item["position_idx"] = int(item["position_idx"])376 self._update([item])377class ExecutionInverse(DataStore):378 _KEYS = ["exec_id"]379 def _onmessage(self, data: list[Item]) -> None:380 self._update(data)381class ExecutionUSDT(ExecutionInverse):382 ...383class OrderInverse(DataStore):384 _KEYS = ["order_id"]385 def _onresponse(self, data: list[Item]) -> None:386 if isinstance(data, list):387 self._update(data)388 elif isinstance(data, dict):389 self._update([data])390 def _onmessage(self, data: list[Item]) -> None:391 for item in data:392 if item["order_status"] in ("Created", "New", "PartiallyFilled"):393 self._update([item])394 else:395 self._delete([item])396class OrderUSDT(OrderInverse):397 ...398class StopOrderInverse(DataStore):399 _KEYS = ["order_id"]400 def _onresponse(self, data: list[Item]) -> None:401 if isinstance(data, list):402 self._update(data)403 elif isinstance(data, dict):404 self._update([data])405 def _onmessage(self, data: list[Item]) -> None:406 for item in data:407 if item["order_status"] in ("Active", "Untriggered"):408 self._update([item])409 else:410 self._delete([item])411class StopOrderUSDT(StopOrderInverse):412 _KEYS = ["stop_order_id"]413class WalletInverse(DataStore):414 _KEYS = ["coin"]415 def _onresponse(self, data: dict[str, Item]) -> None:416 data.pop("USDT", None)417 for coin in data:418 self._update(419 [420 {421 "coin": coin,422 "available_balance": data[coin]["available_balance"],423 "wallet_balance": data[coin]["wallet_balance"],424 }425 ]426 )427 def _onmessage(self, data: list[Item]) -> None:428 self._update(data)429class WalletUSDT(WalletInverse):430 def _onresponse(self, data: dict[str, Item]) -> None:431 if "USDT" in data:432 self._update(433 [434 {435 "coin": "USDT",436 "wallet_balance": data["USDT"]["wallet_balance"],437 "available_balance": data["USDT"]["available_balance"],438 }439 ]440 )441 def _onmessage(self, data: list[Item]) -> None:442 for item in data:...

Full Screen

Full Screen

test_claims.py

Source:test_claims.py Github

copy

Full Screen

...34 action = consts.QUEUE_CREATE35 body = {"queue_name": "skittle"}36 req = test_utils.create_request(action, body, self.headers)37 with mock.patch.object(self.protocol, 'sendMessage') as msg_mock:38 self.protocol.onMessage(req, False)39 resp = json.loads(msg_mock.call_args[0][0].decode())40 self.assertIn(resp['headers']['status'], [201, 204])41 action = consts.MESSAGE_POST42 body = {"queue_name": "skittle",43 "messages": [44 {'body': 239, 'ttl': 300},45 {'body': {'key_1': 'value_1'}, 'ttl': 300},46 {'body': [1, 3], 'ttl': 300},47 {'body': 439, 'ttl': 300},48 {'body': {'key_2': 'value_2'}, 'ttl': 300},49 {'body': ['a', 'b'], 'ttl': 300},50 {'body': 639, 'ttl': 300},51 {'body': {'key_3': 'value_3'}, 'ttl': 300},52 {'body': ["aa", "bb"], 'ttl': 300}]53 }54 send_mock = mock.Mock()55 self.protocol.sendMessage = send_mock56 req = test_utils.create_request(action, body, self.headers)57 self.protocol.onMessage(req, False)58 resp = json.loads(send_mock.call_args[0][0].decode())59 self.assertEqual(201, resp['headers']['status'])60 def tearDown(self):61 super(ClaimsBaseTest, self).tearDown()62 action = consts.QUEUE_DELETE63 body = {'queue_name': 'skittle'}64 send_mock = mock.Mock()65 self.protocol.sendMessage = send_mock66 req = test_utils.create_request(action, body, self.headers)67 self.protocol.onMessage(req, False)68 resp = json.loads(send_mock.call_args[0][0].decode())69 self.assertEqual(204, resp['headers']['status'])70 @ddt.data('[', '[]', '.', '"fail"')71 def test_bad_claim(self, doc):72 action = consts.CLAIM_CREATE73 body = doc74 send_mock = mock.Mock()75 self.protocol.sendMessage = send_mock76 req = test_utils.create_request(action, body, self.headers)77 self.protocol.onMessage(req, False)78 resp = json.loads(send_mock.call_args[0][0].decode())79 self.assertEqual(400, resp['headers']['status'])80 action = consts.CLAIM_UPDATE81 body = doc82 req = test_utils.create_request(action, body, self.headers)83 self.protocol.onMessage(req, False)84 resp = json.loads(send_mock.call_args[0][0].decode())85 self.assertEqual(400, resp['headers']['status'])86 def test_exceeded_claim(self):87 action = consts.CLAIM_CREATE88 body = {"queue_name": "skittle",89 "ttl": 100,90 "grace": 60,91 "limit": 21}92 send_mock = mock.Mock()93 self.protocol.sendMessage = send_mock94 req = test_utils.create_request(action, body, self.headers)95 self.protocol.onMessage(req, False)96 resp = json.loads(send_mock.call_args[0][0].decode())97 self.assertEqual(400, resp['headers']['status'])98 @ddt.data((-1, -1), (59, 60), (60, 59), (60, 43201), (43201, 60))99 def test_unacceptable_ttl_or_grace(self, ttl_grace):100 ttl, grace = ttl_grace101 action = consts.CLAIM_CREATE102 body = {"queue_name": "skittle",103 "ttl": ttl,104 "grace": grace}105 send_mock = mock.Mock()106 self.protocol.sendMessage = send_mock107 req = test_utils.create_request(action, body, self.headers)108 self.protocol.onMessage(req, False)109 resp = json.loads(send_mock.call_args[0][0].decode())110 self.assertEqual(400, resp['headers']['status'])111 @ddt.data(-1, 59, 43201)112 def test_unacceptable_new_ttl(self, ttl):113 claim = self._get_a_claim()114 action = consts.CLAIM_UPDATE115 body = {"queue_name": "skittle",116 "claim_id": claim['body']['claim_id'],117 "ttl": ttl}118 send_mock = mock.Mock()119 self.protocol.sendMessage = send_mock120 req = test_utils.create_request(action, body, self.headers)121 self.protocol.onMessage(req, False)122 resp = json.loads(send_mock.call_args[0][0].decode())123 self.assertEqual(400, resp['headers']['status'])124 def test_default_ttl_and_grace(self):125 action = consts.CLAIM_CREATE126 body = {"queue_name": "skittle"}127 send_mock = mock.Mock()128 self.protocol.sendMessage = send_mock129 req = test_utils.create_request(action, body, self.headers)130 self.protocol.onMessage(req, False)131 resp = json.loads(send_mock.call_args[0][0].decode())132 self.assertEqual(201, resp['headers']['status'])133 action = consts.CLAIM_GET134 body = {"queue_name": "skittle",135 "claim_id": resp['body']['claim_id']}136 req = test_utils.create_request(action, body, self.headers)137 self.protocol.onMessage(req, False)138 resp = json.loads(send_mock.call_args[0][0].decode())139 self.assertEqual(200, resp['headers']['status'])140 self.assertEqual(self.defaults.claim_ttl, resp['body']['ttl'])141 def test_lifecycle(self):142 # First, claim some messages143 action = consts.CLAIM_CREATE144 body = {"queue_name": "skittle",145 "ttl": 100,146 "grace": 60}147 send_mock = mock.Mock()148 self.protocol.sendMessage = send_mock149 req = test_utils.create_request(action, body, self.headers)150 self.protocol.onMessage(req, False)151 resp = json.loads(send_mock.call_args[0][0].decode())152 self.assertEqual(201, resp['headers']['status'])153 claimed_messages = resp['body']['messages']154 claim_id = resp['body']['claim_id']155 # No more messages to claim156 body = {"queue_name": "skittle",157 "ttl": 100,158 "grace": 60}159 req = test_utils.create_request(action, body, self.headers)160 self.protocol.onMessage(req, False)161 resp = json.loads(send_mock.call_args[0][0].decode())162 self.assertEqual(204, resp['headers']['status'])163 # Listing messages, by default, won't include claimed, will echo164 action = consts.MESSAGE_LIST165 body = {"queue_name": "skittle",166 "echo": True}167 req = test_utils.create_request(action, body, self.headers)168 self.protocol.onMessage(req, False)169 resp = json.loads(send_mock.call_args[0][0].decode())170 self.assertEqual(200, resp['headers']['status'])171 self.assertEqual([], resp['body']['messages'])172 # Listing messages, by default, won't include claimed, won't echo173 body = {"queue_name": "skittle",174 "echo": False}175 req = test_utils.create_request(action, body, self.headers)176 self.protocol.onMessage(req, False)177 resp = json.loads(send_mock.call_args[0][0].decode())178 self.assertEqual(200, resp['headers']['status'])179 self.assertEqual([], resp['body']['messages'])180 # List messages, include_claimed, but don't echo181 body = {"queue_name": "skittle",182 "include_claimed": True,183 "echo": False}184 req = test_utils.create_request(action, body, self.headers)185 self.protocol.onMessage(req, False)186 resp = json.loads(send_mock.call_args[0][0].decode())187 self.assertEqual(200, resp['headers']['status'])188 self.assertEqual(resp['body']['messages'], [])189 # List messages with a different client-id and echo=false.190 # Should return some messages191 body = {"queue_name": "skittle",192 "echo": False}193 headers = {194 'Client-ID': uuidutils.generate_uuid(),195 'X-Project-ID': self.project_id196 }197 req = test_utils.create_request(action, body, headers)198 self.protocol.onMessage(req, False)199 resp = json.loads(send_mock.call_args[0][0].decode())200 self.assertEqual(200, resp['headers']['status'])201 # Include claimed messages this time, and echo202 body = {"queue_name": "skittle",203 "include_claimed": True,204 "echo": True}205 req = test_utils.create_request(action, body, self.headers)206 self.protocol.onMessage(req, False)207 resp = json.loads(send_mock.call_args[0][0].decode())208 self.assertEqual(200, resp['headers']['status'])209 self.assertEqual(len(claimed_messages), len(resp['body']['messages']))210 message_id_1 = resp['body']['messages'][0]['id']211 message_id_2 = resp['body']['messages'][1]['id']212 # Try to delete the message without submitting a claim_id213 action = consts.MESSAGE_DELETE214 body = {"queue_name": "skittle",215 "message_id": message_id_1}216 req = test_utils.create_request(action, body, self.headers)217 self.protocol.onMessage(req, False)218 resp = json.loads(send_mock.call_args[0][0].decode())219 self.assertEqual(403, resp['headers']['status'])220 # Delete the message and its associated claim221 body = {"queue_name": "skittle",222 "message_id": message_id_1,223 "claim_id": claim_id}224 req = test_utils.create_request(action, body, self.headers)225 self.protocol.onMessage(req, False)226 resp = json.loads(send_mock.call_args[0][0].decode())227 self.assertEqual(204, resp['headers']['status'])228 # Try to get it from the wrong project229 headers = {230 'Client-ID': uuidutils.generate_uuid(),231 'X-Project-ID': 'someproject'232 }233 action = consts.MESSAGE_GET234 body = {"queue_name": "skittle",235 "message_id": message_id_2}236 req = test_utils.create_request(action, body, headers)237 self.protocol.onMessage(req, False)238 resp = json.loads(send_mock.call_args[0][0].decode())239 self.assertEqual(404, resp['headers']['status'])240 # Get the message241 action = consts.MESSAGE_GET242 body = {"queue_name": "skittle",243 "message_id": message_id_2}244 req = test_utils.create_request(action, body, self.headers)245 self.protocol.onMessage(req, False)246 resp = json.loads(send_mock.call_args[0][0].decode())247 self.assertEqual(200, resp['headers']['status'])248 # Update the claim249 creation = timeutils.utcnow()250 action = consts.CLAIM_UPDATE251 body = {"queue_name": "skittle",252 "ttl": 60,253 "grace": 60,254 "claim_id": claim_id}255 req = test_utils.create_request(action, body, self.headers)256 self.protocol.onMessage(req, False)257 resp = json.loads(send_mock.call_args[0][0].decode())258 self.assertEqual(204, resp['headers']['status'])259 # Get the claimed messages (again)260 action = consts.CLAIM_GET261 body = {"queue_name": "skittle",262 "claim_id": claim_id}263 req = test_utils.create_request(action, body, self.headers)264 self.protocol.onMessage(req, False)265 query = timeutils.utcnow()266 resp = json.loads(send_mock.call_args[0][0].decode())267 self.assertEqual(200, resp['headers']['status'])268 self.assertEqual(60, resp['body']['ttl'])269 message_id_3 = resp['body']['messages'][0]['id']270 estimated_age = timeutils.delta_seconds(creation, query)271 # The claim's age should be 0 at this moment. But in some unexpected272 # case, such as slow test, the age maybe larger than 0. Just skip273 # asserting if so.274 if resp['body']['age'] == 0:275 self.assertGreater(estimated_age, resp['body']['age'])276 # Delete the claim277 action = consts.CLAIM_DELETE278 body = {"queue_name": "skittle",279 "claim_id": claim_id}280 req = test_utils.create_request(action, body, self.headers)281 self.protocol.onMessage(req, False)282 resp = json.loads(send_mock.call_args[0][0].decode())283 self.assertEqual(204, resp['headers']['status'])284 # Try to delete a message with an invalid claim ID285 action = consts.MESSAGE_DELETE286 body = {"queue_name": "skittle",287 "message_id": message_id_3,288 "claim_id": claim_id}289 req = test_utils.create_request(action, body, self.headers)290 self.protocol.onMessage(req, False)291 resp = json.loads(send_mock.call_args[0][0].decode())292 self.assertEqual(400, resp['headers']['status'])293 # Make sure it wasn't deleted!294 action = consts.MESSAGE_GET295 body = {"queue_name": "skittle",296 "message_id": message_id_2}297 req = test_utils.create_request(action, body, self.headers)298 self.protocol.onMessage(req, False)299 resp = json.loads(send_mock.call_args[0][0].decode())300 self.assertEqual(200, resp['headers']['status'])301 # Try to get a claim that doesn't exist302 action = consts.CLAIM_GET303 body = {"queue_name": "skittle",304 "claim_id": claim_id}305 req = test_utils.create_request(action, body, self.headers)306 self.protocol.onMessage(req, False)307 resp = json.loads(send_mock.call_args[0][0].decode())308 self.assertEqual(404, resp['headers']['status'])309 # Try to update a claim that doesn't exist310 action = consts.CLAIM_UPDATE311 body = {"queue_name": "skittle",312 "ttl": 60,313 "grace": 60,314 "claim_id": claim_id}315 req = test_utils.create_request(action, body, self.headers)316 self.protocol.onMessage(req, False)317 resp = json.loads(send_mock.call_args[0][0].decode())318 self.assertEqual(404, resp['headers']['status'])319 def test_post_claim_nonexistent_queue(self):320 action = consts.CLAIM_CREATE321 body = {"queue_name": "nonexistent",322 "ttl": 100,323 "grace": 60}324 send_mock = mock.Mock()325 self.protocol.sendMessage = send_mock326 req = test_utils.create_request(action, body, self.headers)327 self.protocol.onMessage(req, False)328 resp = json.loads(send_mock.call_args[0][0].decode())329 self.assertEqual(204, resp['headers']['status'])330 def test_get_claim_nonexistent_queue(self):331 action = consts.CLAIM_GET332 body = {"queue_name": "nonexistent",333 "claim_id": "aaabbbba"}334 send_mock = mock.Mock()335 self.protocol.sendMessage = send_mock336 req = test_utils.create_request(action, body, self.headers)337 self.protocol.onMessage(req, False)338 resp = json.loads(send_mock.call_args[0][0].decode())339 self.assertEqual(404, resp['headers']['status'])340 def _get_a_claim(self):341 action = consts.CLAIM_CREATE342 body = {"queue_name": "skittle",343 "ttl": 100,344 "grace": 60}345 send_mock = mock.Mock()346 self.protocol.sendMessage = send_mock347 req = test_utils.create_request(action, body, self.headers)348 self.protocol.onMessage(req, False)349 resp = json.loads(send_mock.call_args[0][0].decode())350 self.assertEqual(201, resp['headers']['status'])...

Full Screen

Full Screen

Playwright tutorial

LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.

Chapters:

  1. What is Playwright : Playwright is comparatively new but has gained good popularity. Get to know some history of the Playwright with some interesting facts connected with it.
  2. How To Install Playwright : Learn in detail about what basic configuration and dependencies are required for installing Playwright and run a test. Get a step-by-step direction for installing the Playwright automation framework.
  3. Playwright Futuristic Features: Launched in 2020, Playwright gained huge popularity quickly because of some obliging features such as Playwright Test Generator and Inspector, Playwright Reporter, Playwright auto-waiting mechanism and etc. Read up on those features to master Playwright testing.
  4. What is Component Testing: Component testing in Playwright is a unique feature that allows a tester to test a single component of a web application without integrating them with other elements. Learn how to perform Component testing on the Playwright automation framework.
  5. Inputs And Buttons In Playwright: Every website has Input boxes and buttons; learn about testing inputs and buttons with different scenarios and examples.
  6. Functions and Selectors in Playwright: Learn how to launch the Chromium browser with Playwright. Also, gain a better understanding of some important functions like “BrowserContext,” which allows you to run multiple browser sessions, and “newPage” which interacts with a page.
  7. Handling Alerts and Dropdowns in Playwright : Playwright interact with different types of alerts and pop-ups, such as simple, confirmation, and prompt, and different types of dropdowns, such as single selector and multi-selector get your hands-on with handling alerts and dropdown in Playright testing.
  8. Playwright vs Puppeteer: Get to know about the difference between two testing frameworks and how they are different than one another, which browsers they support, and what features they provide.
  9. Run Playwright Tests on LambdaTest: Playwright testing with LambdaTest leverages test performance to the utmost. You can run multiple Playwright tests in Parallel with the LammbdaTest test cloud. Get a step-by-step guide to run your Playwright test on the LambdaTest platform.
  10. Playwright Python Tutorial: Playwright automation framework support all major languages such as Python, JavaScript, TypeScript, .NET and etc. However, there are various advantages to Python end-to-end testing with Playwright because of its versatile utility. Get the hang of Playwright python testing with this chapter.
  11. Playwright End To End Testing Tutorial: Get your hands on with Playwright end-to-end testing and learn to use some exciting features such as TraceViewer, Debugging, Networking, Component testing, Visual testing, and many more.
  12. Playwright Video Tutorial: Watch the video tutorials on Playwright testing from experts and get a consecutive in-depth explanation of Playwright automation testing.

Run Playwright Python automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful