import unittest import datetime from dateutil.tz import tzutc from unittest.mock import patch from core.replay.transactions_parser import TransactionsParser, Transaction, Query config = { "tag": "", "workload_location": "testdata/extract", "target_cluster_endpoint": "test.111222333222.us-east-1.redshift-serverless.amazonaws.com:5439/dev", "target_cluster_region": "us-east-1", "master_username": "testuser", "nlb_nat_dns": "", "odbc_driver": "", "default_interface": "psql", "time_interval_between_transactions": "all on", "time_interval_between_queries": "all on", "execute_copy_statements": "false", "execute_unload_statements": "false", "replay_output": "s3://location/replay", "analysis_output": "", "unload_iam_role": "arn:aws:iam::999999999999:role/Test", "analysis_iam_role": "", "unload_system_table_queries": "unload_system_tables.sql", "target_cluster_system_table_unload_iam_role": "", "filters": { "include": {"database_name": ["*"], "username": ["*"], "pid": ["*"]}, "exclude": {"database_name": [], "username": [], "pid": []}, }, } sql_json = { "transactions": { "2612671": { "xid": "2612671", "pid": "1073815778", "db": "dev", "user": "awsuser", "time_interval": True, "queries": [ { "record_time": "2023-01-09T15:48:15+00:00", "start_time": None, "end_time": None, "text": "SET query_group='0000_create_user.ddl - IR-960eb458-9033-11ed-84bb-029845ae12cf.create-user.create-user.s0001.f0000.1.0';", } ], }, "2612672": { "xid": "2612672", "pid": "1073815778", "db": "dev", "user": "awsuser", "time_interval": True, "queries": [ { "record_time": "2023-01-09T15:48:15+00:00", "start_time": None, "end_time": None, "text": "SET query_group='0000_create_user.ddl - IR-960eb458-9033-11ed-84bb-029845ae12cf.create-user.create-user.s0001.f0000.1.0';", } ], }, } } replay_id = "2023-02-07T19:17:11.472063+00:00_cluster-testing" transaction_dict = { "xid": "2612671", "pid": "1073815778", "db": "dev", "user": "awsuser", "time_interval": True, "queries": [ { "record_time": "2023-01-09T15:48:15+00:00", "start_time": None, "end_time": None, "text": "SET query_group='0000_create_user.ddl - IR-960eb458-9033-11ed-84bb-029845ae12cf.create-user.create-user.s0001.f0000.1.0';", } ], } def mock_filters(a, b): return True class TestTransactionParser(unittest.TestCase): # need to test more in this function @patch("core.replay.transactions_parser.matches_filters", mock_filters) @patch.object(Transaction, "start_time") @patch.object(TransactionsParser, "parse_transaction") @patch("core.replay.transactions_parser.parse_copy_replacements") @patch("core.replay.transactions_parser.retrieve_compressed_json") def test_parse_transactions_copy_statements_True( self, mock_retrieve_json, mock_copy_repl, mock_parse_trans, mock_time ): config["execute_copy_statements"] = "true" q = { "record_time": "2023-01-09T15:48:15+00:00", "start_time": None, "end_time": None, "text": "SET query_group='0000_create_user.ddl - IR-960eb458-9033-11ed-84bb-029845ae12cf.create-user.create-user.s0001.f0000.1.0';", } transaction_key = "test-key" start_time_q = datetime.datetime(2022, 12, 2, 0, 0, 0) end_time_q = datetime.datetime(2022, 12, 2, 0, 10, 0) mock_time.return_value = True queries = Query(start_time_q, end_time_q, q["text"]) mock_copy_repl.return_value = True mock_parse_trans.return_value = Transaction( transaction_dict["time_interval"], transaction_dict["db"], transaction_dict["user"], transaction_dict["pid"], transaction_dict["xid"], queries, transaction_key, ) mock_retrieve_json.return_value = sql_json parser = TransactionsParser(config, replay_id) class_object = parser.parse_transactions() mock_copy_repl.assert_called_once_with("testdata/extract") mock_retrieve_json.assert_called_once_with("testdata/extract/SQLs.json.gz") mock_parse_trans.assert_called_with( { "xid": "2612672", "pid": "1073815778", "db": "dev", "user": "awsuser", "time_interval": True, "queries": [ { "record_time": "2023-01-09T15:48:15+00:00", "start_time": None, "end_time": None, "text": "SET query_group='0000_create_user.ddl - IR-960eb458-9033-11ed-84bb-029845ae12cf.create-user.create-user.s0001.f0000.1.0';", } ], }, True, ) assert ( class_object[0].queries.text == "SET query_group='0000_create_user.ddl - IR-960eb458-9033-11ed-84bb-029845ae12cf.create-user.create-user.s0001.f0000.1.0';" ) assert class_object[0].pid == "1073815778" @patch("core.replay.transactions_parser.matches_filters", mock_filters) @patch.object(Transaction, "start_time") @patch.object(TransactionsParser, "parse_transaction") @patch("core.replay.transactions_parser.parse_copy_replacements") @patch("core.replay.transactions_parser.retrieve_compressed_json") def test_parse_transactions_copy_statements_False( self, mock_retrieve_json, mock_copy_repl, mock_parse_trans, mock_time ): config["execute_copy_statements"] = "false" q = { "record_time": "2023-01-09T15:48:15+00:00", "start_time": None, "end_time": None, "text": "SET query_group='0000_create_user.ddl - IR-960eb458-9033-11ed-84bb-029845ae12cf.create-user.create-user.s0001.f0000.1.0';", } transaction_key = "test-key" start_time = datetime.datetime(2022, 12, 2, 0, 0, 0) end_time = datetime.datetime(2022, 12, 2, 0, 10, 0) mock_time.return_value = True queries = Query(start_time, end_time, q["text"]) mock_copy_repl.return_value = True mock_parse_trans.return_value = Transaction( transaction_dict["time_interval"], transaction_dict["db"], transaction_dict["user"], transaction_dict["pid"], transaction_dict["xid"], queries, transaction_key, ) mock_time = True mock_retrieve_json.return_value = sql_json parser = TransactionsParser(config, replay_id) queries = Query(start_time, end_time, q["text"]) parser.parse_transactions() mock_retrieve_json.assert_called_once_with("testdata/extract/SQLs.json.gz") mock_parse_trans.assert_called_with( { "xid": "2612672", "pid": "1073815778", "db": "dev", "user": "awsuser", "time_interval": True, "queries": [ { "record_time": "2023-01-09T15:48:15+00:00", "start_time": None, "end_time": None, "text": "SET query_group='0000_create_user.ddl - IR-960eb458-9033-11ed-84bb-029845ae12cf.create-user.create-user.s0001.f0000.1.0';", } ], }, [], ) @patch("core.replay.transactions_parser.matches_filters", mock_filters) @patch.object(Transaction, "start_time") @patch.object(TransactionsParser, "parse_transaction") @patch("core.replay.transactions_parser.parse_copy_replacements") @patch("core.replay.transactions_parser.retrieve_compressed_json") def test_parse_transactions_start_time_false( self, mock_retrieve_json, mock_copy_repl, mock_parse_trans, mock_time ): q = { "record_time": "2023-01-09T15:48:15+00:00", "start_time": None, "end_time": None, "text": "SET query_group='0000_create_user.ddl - IR-960eb458-9033-11ed-84bb-029845ae12cf.create-user.create-user.s0001.f0000.1.0';", } transaction_key = "test-key" start_time = datetime.datetime(2022, 12, 2, 0, 0, 0) end_time = datetime.datetime(2022, 12, 2, 0, 10, 0) config["execute_copy_statements"] = "false" mock_time.return_value = False queries = Query(start_time, end_time, q["text"]) mock_copy_repl.return_value = True mock_parse_trans.return_value = Transaction( transaction_dict["time_interval"], transaction_dict["db"], transaction_dict["user"], transaction_dict["pid"], transaction_dict["xid"], queries, transaction_key, ) mock_retrieve_json.return_value = sql_json parser = TransactionsParser(config, replay_id) queries = Query(start_time, end_time, q["text"]) parser.parse_transactions() mock_retrieve_json.assert_called_once_with("testdata/extract/SQLs.json.gz") mock_parse_trans.assert_called_with( { "xid": "2612672", "pid": "1073815778", "db": "dev", "user": "awsuser", "time_interval": True, "queries": [ { "record_time": "2023-01-09T15:48:15+00:00", "start_time": None, "end_time": None, "text": "SET query_group='0000_create_user.ddl - IR-960eb458-9033-11ed-84bb-029845ae12cf.create-user.create-user.s0001.f0000.1.0';", } ], }, [], ) @patch("core.replay.transactions_parser.Query") def test_parse_transaction_start_time_end_time(self, mock_Query): config["execute_copy_statements"] = "false" transaction_dict = { "xid": "1519323", "pid": "1073750303", "db": "tpcds_1g", "user": "rsperf", "time_interval": True, "queries": [ { "record_time": "2022-12-27T16:43:34+00:00", "start_time": "2022-12-27T17:00:00+00:00", "end_time": "2022-12-27T17:01:00+00:00", "text": "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://location/call_center/'\n credentials '' \n region 'us-east-1' \n gzip delimiter '|';", } ], } parser = TransactionsParser(config, replay_id) parser.parse_transaction(transaction_dict, None) mock_Query.assert_called_once_with( datetime.datetime(2022, 12, 27, 17, 0, tzinfo=tzutc()), datetime.datetime(2022, 12, 27, 17, 1, tzinfo=tzutc()), "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://location/call_center/'\n credentials '' \n region 'us-east-1' \n gzip delimiter '|';", ) @patch.object(TransactionsParser, "get_copy_replacement") def test_parse_transaction_copy_statements(self, mock_copy_replacements): replacements = { "s3://location/catalog_page/": [ "s3://test-location", "arn:iam:role-test-role", ], "s3://location/call_center/": [ "s3://test-location", "arn:iam:role-test-role", ], } config["execute_copy_statements"] = "true" transaction_dict = { "xid": "1519323", "pid": "1073750303", "db": "tpcds_1g", "user": "rsperf", "time_interval": True, "queries": [ { "record_time": "2022-12-27T16:43:34+00:00", "start_time": None, "end_time": None, "text": "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://location/call_center/'\n credentials '' \n region 'us-east-1' \n gzip delimiter '|';", } ], } parser = TransactionsParser(config, replay_id) parser.parse_transaction(transaction_dict, replacements) mock_copy_replacements.assert_called_with( "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://location/call_center/'\n credentials '' \n region 'us-east-1' \n gzip delimiter '|';", { "s3://location/catalog_page/": [ "s3://test-location", "arn:iam:role-test-role", ], "s3://location/call_center/": [ "s3://test-location", "arn:iam:role-test-role", ], }, ) @patch("core.replay.transactions_parser.random") @patch.object(TransactionsParser, "get_copy_replacement") def test_parse_transaction_copy_statements_password(self, mock_copy_replacements, mock_random): replacements = { "s3://location/catalog_page/": [ "s3://test-location", "arn:iam:role-test-role", ], "s3://location/call_center/": [ "s3://test-location", "arn:iam:role-test-role", ], } mock_copy_replacements.return_value = "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://test-location'\n IAM_ROLE 'arn:iam:role-test-role' \n region 'us-east-1' \n gzip delimiter '|';" config["execute_copy_statements"] = "true" mock_random.choices.return_value = "abcd" transaction_dict = { "xid": "1519323", "pid": "1073750303", "db": "tpcds_1g", "user": "rsperf", "time_interval": True, "queries": [ { "record_time": "2022-12-27T16:43:34+00:00", "start_time": None, "end_time": None, "text": "CREATE USER rsperf PASSWORD '***' CREATEUSER;", } ], } parser = TransactionsParser(config, replay_id) class_object = parser.parse_transaction(transaction_dict, replacements) self.assertEqual( class_object.queries[0].text, "CREATE USER rsperf PASSWORD 'abcdaA0' CREATEUSER;", ) @patch.object(TransactionsParser, "get_unload_replacements") def test_parse_transaction_unload_statements(self, mock_unload_replacements): config["execute_unload_statements"] = "true" config["replay_output"] = "s3://location/replay" config["unload_iam_role"] = "arn:aws:iam::111111111111:role/Test" replacements = { "s3://location/call_center/": [ "s3://test-location", "arn:iam:role-test-role", ] } transaction_dict = { "xid": "1519323", "pid": "1073750303", "db": "tpcds_1g", "user": "rsperf", "time_interval": True, "queries": [ { "record_time": "2022-12-27T16:43:34+00:00", "start_time": None, "end_time": None, "text": "unload ('select * from venue') to 's3://mybucket/unload/' iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';", } ], } parser = TransactionsParser(config, replay_id) parser.parse_transaction(transaction_dict, replacements) mock_unload_replacements.assert_called_with( "unload ('select * from venue') to 's3://mybucket/unload/' iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';", "s3://location/replay", "2023-02-07T19:17:11.472063+00:00_cluster-testing", "arn:aws:iam::111111111111:role/Test", ) def test_get_unload_replacements_iam_role_with_role(self): query_text = "unload ('select * from venue') to 's3://mybucket/unload/' iam_role 'arn:aws:iam::0123456789012:role/MyRedshiftRole';" replay_output = config["replay_output"] replay_name = replay_id unload_iam_role = config["unload_iam_role"] parser = TransactionsParser(config, replay_id) query = parser.get_unload_replacements( query_text, replay_output, replay_name, unload_iam_role ) self.assertEqual( query, "unload ('select * from venue') to 's3://location/replay/2023-02-07T19:17:11.472063+00:00_cluster-testing/UNLOADs/mybucket/unload/' IAM_ROLE 'arn:aws:iam::999999999999:role/Test';", ) def test_get_unload_replacements_credentials(self): query_text = "unload ('select * from venue') to 's3://mybucket/unload/' credentials '';" replay_output = config["replay_output"] replay_name = replay_id unload_iam_role = config["unload_iam_role"] parser = TransactionsParser(config, replay_id) query = parser.get_unload_replacements( query_text, replay_output, replay_name, unload_iam_role ) self.assertEqual( query, "unload ('select * from venue') to 's3://location/replay/2023-02-07T19:17:11.472063+00:00_cluster-testing/UNLOADs/mybucket/unload/' IAM_ROLE 'arn:aws:iam::999999999999:role/Test';", ) def test_get_unload_replacements_with_credentials(self): query_text = ( "unload ('select * from venue') to 's3://mybucket/unload/' with credentials as '';" ) replay_output = config["replay_output"] replay_name = replay_id unload_iam_role = config["unload_iam_role"] parser = TransactionsParser(config, replay_id) query = parser.get_unload_replacements( query_text, replay_output, replay_name, unload_iam_role ) self.assertEqual( query, "unload ('select * from venue') to 's3://location/replay/2023-02-07T19:17:11.472063+00:00_cluster-testing/UNLOADs/mybucket/unload/' IAM_ROLE 'arn:aws:iam::999999999999:role/Test';", ) def test_get_unload_replacements_iam_role(self): query_text = "unload ('select * from venue') to 's3://mybucket/unload/' iam_role '';" replay_output = config["replay_output"] replay_name = replay_id unload_iam_role = config["unload_iam_role"] parser = TransactionsParser(config, replay_id) query = parser.get_unload_replacements( query_text, replay_output, replay_name, unload_iam_role ) self.assertEqual( query, "unload ('select * from venue') to 's3://location/replay/2023-02-07T19:17:11.472063+00:00_cluster-testing/UNLOADs/mybucket/unload/' IAM_ROLE 'arn:aws:iam::999999999999:role/Test';", ) def test_get_unload_replacements_with_session_token(self): query_text = "unload ('select * from venue') to 's3://mybucket/unload/' access_key_id '' secret_access_key '' session_token '';" replay_output = config["replay_output"] replay_name = replay_id unload_iam_role = config["unload_iam_role"] parser = TransactionsParser(config, replay_id) query = parser.get_unload_replacements( query_text, replay_output, replay_name, unload_iam_role ) self.assertEqual( query, "unload ('select * from venue') to 's3://location/replay/2023-02-07T19:17:11.472063+00:00_cluster-testing/UNLOADs/mybucket/unload/' IAM_ROLE 'arn:aws:iam::999999999999:role/Test';", ) def test_get_unload_replacements_no_session_token(self): query_text = "unload ('select * from venue') to 's3://mybucket/unload/' access_key_id '' secret_access_key '';" replay_output = config["replay_output"] replay_name = replay_id unload_iam_role = config["unload_iam_role"] parser = TransactionsParser(config, replay_id) query = parser.get_unload_replacements( query_text, replay_output, replay_name, unload_iam_role ) self.assertEqual( query, "unload ('select * from venue') to 's3://location/replay/2023-02-07T19:17:11.472063+00:00_cluster-testing/UNLOADs/mybucket/unload/' IAM_ROLE 'arn:aws:iam::999999999999:role/Test';", ) def test_get_copy_replacement(self): query_text = "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://location/call_center/'\n credentials '' \n region 'us-east-1' \n gzip delimiter '|';" replacements = { "s3://location/call_center/": [ "s3://test-location", "arn:iam:role-test-role", ] } parser = TransactionsParser(config, replay_id) text = parser.get_copy_replacement(query_text, replacements) self.assertEqual( text, "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://test-location'\n IAM_ROLE 'arn:iam:role-test-role' \n region 'us-east-1' \n gzip delimiter '|';", ) def test_get_copy_replacement_no_copy_replacement_location(self): query_text = "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://location/call_center/'\n credentials '' \n region 'us-east-1' \n gzip delimiter '|';" replacements = { "s3://location/call_center/": [ "", "arn:iam:role-test-role", ] } parser = TransactionsParser(config, replay_id) text = parser.get_copy_replacement(query_text, replacements) self.assertEqual( text, "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://location/call_center/'\n IAM_ROLE 'arn:iam:role-test-role' \n region 'us-east-1' \n gzip delimiter '|';", ) def test_get_copy_replacement_no_copy_replacement(self): query_text = "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://location/call_center/'\n credentials '' \n region 'us-east-1' \n gzip delimiter '|';" replacements = {"": ["", "arn:iam:role-test-role"]} parser = TransactionsParser(config, replay_id) text = parser.get_copy_replacement(query_text, replacements) self.assertEqual(text, None) def test_get_copy_replacement_no_copy_replacement(self): query_text = "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://location/call_center/'\n credentials '' \n region 'us-east-1' \n gzip delimiter '|';" replacements = { "s3://location/call_center/": [ "s3://test-location", "", ] } parser = TransactionsParser(config, replay_id) with self.assertRaises(SystemExit) as cm: text = parser.get_copy_replacement(query_text, replacements) self.assertEqual(cm.exception.code, -1) def test_get_copy_replacement_no_copy_replacement_iam_role_with_value(self): query_text = "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://location/call_center/'\n IAM_ROLE '' \n region 'us-east-1' \n gzip delimiter '|';" replacements = { "s3://location/call_center/": [ "s3://test-location", "This_is_a_test_role", ] } parser = TransactionsParser(config, replay_id) text = parser.get_copy_replacement(query_text, replacements) self.assertEqual( text, "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://test-location'\n IAM_ROLE 'This_is_a_test_role' \n region 'us-east-1' \n gzip delimiter '|';", ) def test_get_copy_replacement_no_copy_replacement_with_credentials(self): query_text = "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://location/call_center/'\n with credentials as '' \n region 'us-east-1' \n gzip delimiter '|';" replacements = { "s3://location/call_center/": [ "s3://test-location", "This_is_a_test_role", ] } parser = TransactionsParser(config, replay_id) text = parser.get_copy_replacement(query_text, replacements) self.assertEqual( text, "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://test-location'\n IAM_ROLE 'This_is_a_test_role' \n region 'us-east-1' \n gzip delimiter '|';", ) def test_get_copy_replacement_no_copy_replacement_credentials(self): query_text = "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://location/call_center/'\n credentials '' \n region 'us-east-1' \n gzip delimiter '|';" replacements = { "s3://location/call_center/": [ "s3://test-location", "This_is_a_test_role", ] } parser = TransactionsParser(config, replay_id) text = parser.get_copy_replacement(query_text, replacements) self.assertEqual( text, "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://test-location'\n IAM_ROLE 'This_is_a_test_role' \n region 'us-east-1' \n gzip delimiter '|';", ) def test_get_copy_replacement_no_copy_replacement_session_token(self): query_text = "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://location/call_center/'\n ACCESS_KEY_ID '' SECRET_ACCESS_KEY '' SESSION_TOKEN '' \n region 'us-east-1' \n gzip delimiter '|';" replacements = { "s3://location/call_center/": [ "s3://test-location", "This_is_a_test_role", ] } parser = TransactionsParser(config, replay_id) text = parser.get_copy_replacement(query_text, replacements) self.assertEqual( text, "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://test-location'\n IAM_ROLE 'This_is_a_test_role' \n region 'us-east-1' \n gzip delimiter '|';", ) def test_get_copy_replacement_no_copy_replacement_access_key(self): query_text = "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://location/call_center/'\n ACCESS_KEY_ID '' SECRET_ACCESS_KEY '' \n region 'us-east-1' \n gzip delimiter '|';" replacements = { "s3://location/call_center/": [ "s3://test-location", "This_is_a_test_role", ] } parser = TransactionsParser(config, replay_id) text = parser.get_copy_replacement(query_text, replacements) self.assertEqual( text, "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://test-location'\n IAM_ROLE 'This_is_a_test_role' \n region 'us-east-1' \n gzip delimiter '|';", ) def test_get_copy_replacement_no_copy_replacement_IAM_ROLE(self): query_text = "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://location/call_center/'\n IAM_ROLE 'arn:aws:iam::0123456789012:role/MyRedshiftRole' \n region 'us-east-1' \n gzip delimiter '|';" replacements = { "s3://location/call_center/": [ "s3://test-location", "This_is_a_test_role", ] } parser = TransactionsParser(config, replay_id) text = parser.get_copy_replacement(query_text, replacements) self.assertEqual( text, "COPY /* 0001_01_call_center_copy.sql.0 !CF:IR-fb3d5188-8604-11ed-b844-022e2270cad7.load-tables.load-tables.s0001.f0001.1.1:CF! */public.call_center \n FROM 's3://test-location'\n IAM_ROLE 'This_is_a_test_role' \n region 'us-east-1' \n gzip delimiter '|';", )