|
| 1 | +from pathlib import Path |
1 | 2 | import sys |
2 | | -import unittest |
3 | 3 |
|
| 4 | +import pytest |
4 | 5 | import requests_mock |
5 | 6 |
|
6 | 7 | import tableauserverclient as TSC |
7 | 8 | from tableauserverclient.datetime_helpers import format_datetime |
8 | 9 | from tableauserverclient.server.endpoint.exceptions import FlowRunFailedException |
9 | | -from ._utils import read_xml_asset, mocked_time, server_response_error_factory |
10 | | - |
11 | | -GET_XML = "flow_runs_get.xml" |
12 | | -GET_BY_ID_XML = "flow_runs_get_by_id.xml" |
13 | | -GET_BY_ID_FAILED_XML = "flow_runs_get_by_id_failed.xml" |
14 | | -GET_BY_ID_INPROGRESS_XML = "flow_runs_get_by_id_inprogress.xml" |
15 | | - |
16 | | - |
17 | | -class FlowRunTests(unittest.TestCase): |
18 | | - def setUp(self) -> None: |
19 | | - self.server = TSC.Server("http://test", False) |
20 | | - |
21 | | - # Fake signin |
22 | | - self.server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" |
23 | | - self.server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" |
24 | | - self.server.version = "3.10" |
25 | | - |
26 | | - self.baseurl = self.server.flow_runs.baseurl |
27 | | - |
28 | | - def test_get(self) -> None: |
29 | | - response_xml = read_xml_asset(GET_XML) |
30 | | - with requests_mock.mock() as m: |
31 | | - m.get(self.baseurl, text=response_xml) |
32 | | - all_flow_runs = self.server.flow_runs.get() |
33 | | - |
34 | | - self.assertEqual("cc2e652d-4a9b-4476-8c93-b238c45db968", all_flow_runs[0].id) |
35 | | - self.assertEqual("2021-02-11T01:42:55Z", format_datetime(all_flow_runs[0].started_at)) |
36 | | - self.assertEqual("2021-02-11T01:57:38Z", format_datetime(all_flow_runs[0].completed_at)) |
37 | | - self.assertEqual("Success", all_flow_runs[0].status) |
38 | | - self.assertEqual("100", all_flow_runs[0].progress) |
39 | | - self.assertEqual("aa23f4ac-906f-11e9-86fb-3f0f71412e77", all_flow_runs[0].background_job_id) |
40 | | - |
41 | | - self.assertEqual("a3104526-c0c6-4ea5-8362-e03fc7cbd7ee", all_flow_runs[1].id) |
42 | | - self.assertEqual("2021-02-13T04:05:30Z", format_datetime(all_flow_runs[1].started_at)) |
43 | | - self.assertEqual("2021-02-13T04:05:35Z", format_datetime(all_flow_runs[1].completed_at)) |
44 | | - self.assertEqual("Failed", all_flow_runs[1].status) |
45 | | - self.assertEqual("100", all_flow_runs[1].progress) |
46 | | - self.assertEqual("1ad21a9d-2530-4fbf-9064-efd3c736e023", all_flow_runs[1].background_job_id) |
47 | | - |
48 | | - def test_get_by_id(self) -> None: |
49 | | - response_xml = read_xml_asset(GET_BY_ID_XML) |
50 | | - with requests_mock.mock() as m: |
51 | | - m.get(self.baseurl + "/cc2e652d-4a9b-4476-8c93-b238c45db968", text=response_xml) |
52 | | - flow_run = self.server.flow_runs.get_by_id("cc2e652d-4a9b-4476-8c93-b238c45db968") |
53 | | - |
54 | | - self.assertEqual("cc2e652d-4a9b-4476-8c93-b238c45db968", flow_run.id) |
55 | | - self.assertEqual("2021-02-11T01:42:55Z", format_datetime(flow_run.started_at)) |
56 | | - self.assertEqual("2021-02-11T01:57:38Z", format_datetime(flow_run.completed_at)) |
57 | | - self.assertEqual("Success", flow_run.status) |
58 | | - self.assertEqual("100", flow_run.progress) |
59 | | - self.assertEqual("1ad21a9d-2530-4fbf-9064-efd3c736e023", flow_run.background_job_id) |
60 | | - |
61 | | - def test_cancel_id(self) -> None: |
62 | | - with requests_mock.mock() as m: |
63 | | - m.put(self.baseurl + "/ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", status_code=204) |
64 | | - self.server.flow_runs.cancel("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760") |
65 | | - |
66 | | - def test_cancel_item(self) -> None: |
67 | | - run = TSC.FlowRunItem() |
68 | | - run._id = "ee8c6e70-43b6-11e6-af4f-f7b0d8e20760" |
69 | | - with requests_mock.mock() as m: |
70 | | - m.put(self.baseurl + "/ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", status_code=204) |
71 | | - self.server.flow_runs.cancel(run) |
72 | | - |
73 | | - def test_wait_for_job_finished(self) -> None: |
74 | | - # Waiting for an already finished job, directly returns that job's info |
75 | | - response_xml = read_xml_asset(GET_BY_ID_XML) |
76 | | - flow_run_id = "cc2e652d-4a9b-4476-8c93-b238c45db968" |
77 | | - with mocked_time(), requests_mock.mock() as m: |
78 | | - m.get(f"{self.baseurl}/{flow_run_id}", text=response_xml) |
79 | | - flow_run = self.server.flow_runs.wait_for_job(flow_run_id) |
80 | | - |
81 | | - self.assertEqual(flow_run_id, flow_run.id) |
82 | | - self.assertEqual(flow_run.progress, "100") |
83 | | - |
84 | | - def test_wait_for_job_failed(self) -> None: |
85 | | - # Waiting for a failed job raises an exception |
86 | | - response_xml = read_xml_asset(GET_BY_ID_FAILED_XML) |
87 | | - flow_run_id = "c2b35d5a-e130-471a-aec8-7bc5435fe0e7" |
88 | | - with mocked_time(), requests_mock.mock() as m: |
89 | | - m.get(f"{self.baseurl}/{flow_run_id}", text=response_xml) |
90 | | - with self.assertRaises(FlowRunFailedException): |
91 | | - self.server.flow_runs.wait_for_job(flow_run_id) |
92 | | - |
93 | | - def test_wait_for_job_timeout(self) -> None: |
94 | | - # Waiting for a job which doesn't terminate will throw an exception |
95 | | - response_xml = read_xml_asset(GET_BY_ID_INPROGRESS_XML) |
96 | | - flow_run_id = "71afc22c-9c06-40be-8d0f-4c4166d29e6c" |
97 | | - with mocked_time(), requests_mock.mock() as m: |
98 | | - m.get(f"{self.baseurl}/{flow_run_id}", text=response_xml) |
99 | | - with self.assertRaises(TimeoutError): |
100 | | - self.server.flow_runs.wait_for_job(flow_run_id, timeout=30) |
101 | | - |
102 | | - def test_queryset(self) -> None: |
103 | | - response_xml = read_xml_asset(GET_XML) |
104 | | - error_response = server_response_error_factory( |
105 | | - "400006", "Bad Request", "0xB4EAB088 : The start index '9900' is greater than or equal to the total count.)" |
106 | | - ) |
107 | | - with requests_mock.mock() as m: |
108 | | - m.get(f"{self.baseurl}?pageNumber=1", text=response_xml) |
109 | | - m.get(f"{self.baseurl}?pageNumber=2", text=error_response) |
110 | | - queryset = self.server.flow_runs.all() |
111 | | - assert len(queryset) == sys.maxsize |
| 10 | +from ._utils import mocked_time, server_response_error_factory |
| 11 | + |
| 12 | +TEST_ASSET_DIR = Path(__file__).parent / "assets" |
| 13 | + |
| 14 | +GET_XML = TEST_ASSET_DIR / "flow_runs_get.xml" |
| 15 | +GET_BY_ID_XML = TEST_ASSET_DIR / "flow_runs_get_by_id.xml" |
| 16 | +GET_BY_ID_FAILED_XML = TEST_ASSET_DIR / "flow_runs_get_by_id_failed.xml" |
| 17 | +GET_BY_ID_INPROGRESS_XML = TEST_ASSET_DIR / "flow_runs_get_by_id_inprogress.xml" |
| 18 | + |
| 19 | + |
| 20 | +@pytest.fixture(scope="function") |
| 21 | +def server() -> TSC.Server: |
| 22 | + server = TSC.Server("http://test", False) |
| 23 | + # Fake signin |
| 24 | + server._site_id = "dad65087-b08b-4603-af4e-2887b8aafc67" |
| 25 | + server._auth_token = "j80k54ll2lfMZ0tv97mlPvvSCRyD0DOM" |
| 26 | + server.version = "3.10" |
| 27 | + |
| 28 | + return server |
| 29 | + |
| 30 | + |
| 31 | +def test_get(server: TSC.Server) -> None: |
| 32 | + response_xml = GET_XML.read_text() |
| 33 | + with requests_mock.mock() as m: |
| 34 | + m.get(server.flow_runs.baseurl, text=response_xml) |
| 35 | + all_flow_runs = server.flow_runs.get() |
| 36 | + |
| 37 | + assert "cc2e652d-4a9b-4476-8c93-b238c45db968" == all_flow_runs[0].id |
| 38 | + assert "2021-02-11T01:42:55Z" == format_datetime(all_flow_runs[0].started_at) |
| 39 | + assert "2021-02-11T01:57:38Z" == format_datetime(all_flow_runs[0].completed_at) |
| 40 | + assert "Success" == all_flow_runs[0].status |
| 41 | + assert "100" == all_flow_runs[0].progress |
| 42 | + assert "aa23f4ac-906f-11e9-86fb-3f0f71412e77" == all_flow_runs[0].background_job_id |
| 43 | + |
| 44 | + assert "a3104526-c0c6-4ea5-8362-e03fc7cbd7ee" == all_flow_runs[1].id |
| 45 | + assert "2021-02-13T04:05:30Z" == format_datetime(all_flow_runs[1].started_at) |
| 46 | + assert "2021-02-13T04:05:35Z" == format_datetime(all_flow_runs[1].completed_at) |
| 47 | + assert "Failed" == all_flow_runs[1].status |
| 48 | + assert "100" == all_flow_runs[1].progress |
| 49 | + assert "1ad21a9d-2530-4fbf-9064-efd3c736e023" == all_flow_runs[1].background_job_id |
| 50 | + |
| 51 | + |
| 52 | +def test_get_by_id(server: TSC.Server) -> None: |
| 53 | + response_xml = GET_BY_ID_XML.read_text() |
| 54 | + with requests_mock.mock() as m: |
| 55 | + m.get(server.flow_runs.baseurl + "/cc2e652d-4a9b-4476-8c93-b238c45db968", text=response_xml) |
| 56 | + flow_run = server.flow_runs.get_by_id("cc2e652d-4a9b-4476-8c93-b238c45db968") |
| 57 | + |
| 58 | + assert "cc2e652d-4a9b-4476-8c93-b238c45db968" == flow_run.id |
| 59 | + assert "2021-02-11T01:42:55Z" == format_datetime(flow_run.started_at) |
| 60 | + assert "2021-02-11T01:57:38Z" == format_datetime(flow_run.completed_at) |
| 61 | + assert "Success" == flow_run.status |
| 62 | + assert "100" == flow_run.progress |
| 63 | + assert "1ad21a9d-2530-4fbf-9064-efd3c736e023" == flow_run.background_job_id |
| 64 | + |
| 65 | + |
| 66 | +def test_cancel_id(server: TSC.Server) -> None: |
| 67 | + with requests_mock.mock() as m: |
| 68 | + m.put(server.flow_runs.baseurl + "/ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", status_code=204) |
| 69 | + server.flow_runs.cancel("ee8c6e70-43b6-11e6-af4f-f7b0d8e20760") |
| 70 | + |
| 71 | + |
| 72 | +def test_cancel_item(server: TSC.Server) -> None: |
| 73 | + run = TSC.FlowRunItem() |
| 74 | + run._id = "ee8c6e70-43b6-11e6-af4f-f7b0d8e20760" |
| 75 | + with requests_mock.mock() as m: |
| 76 | + m.put(server.flow_runs.baseurl + "/ee8c6e70-43b6-11e6-af4f-f7b0d8e20760", status_code=204) |
| 77 | + server.flow_runs.cancel(run) |
| 78 | + |
| 79 | + |
| 80 | +def test_wait_for_job_finished(server: TSC.Server) -> None: |
| 81 | + # Waiting for an already finished job, directly returns that job's info |
| 82 | + response_xml = GET_BY_ID_XML.read_text() |
| 83 | + flow_run_id = "cc2e652d-4a9b-4476-8c93-b238c45db968" |
| 84 | + with mocked_time(), requests_mock.mock() as m: |
| 85 | + m.get(f"{server.flow_runs.baseurl}/{flow_run_id}", text=response_xml) |
| 86 | + flow_run = server.flow_runs.wait_for_job(flow_run_id) |
| 87 | + |
| 88 | + assert flow_run_id == flow_run.id |
| 89 | + assert flow_run.progress == "100" |
| 90 | + |
| 91 | + |
| 92 | +def test_wait_for_job_failed(server: TSC.Server) -> None: |
| 93 | + # Waiting for a failed job raises an exception |
| 94 | + response_xml = GET_BY_ID_FAILED_XML.read_text() |
| 95 | + flow_run_id = "c2b35d5a-e130-471a-aec8-7bc5435fe0e7" |
| 96 | + with mocked_time(), requests_mock.mock() as m: |
| 97 | + m.get(f"{server.flow_runs.baseurl}/{flow_run_id}", text=response_xml) |
| 98 | + with pytest.raises(FlowRunFailedException): |
| 99 | + server.flow_runs.wait_for_job(flow_run_id) |
| 100 | + |
| 101 | + |
| 102 | +def test_wait_for_job_timeout(server: TSC.Server) -> None: |
| 103 | + # Waiting for a job which doesn't terminate will throw an exception |
| 104 | + response_xml = GET_BY_ID_INPROGRESS_XML.read_text() |
| 105 | + flow_run_id = "71afc22c-9c06-40be-8d0f-4c4166d29e6c" |
| 106 | + with mocked_time(), requests_mock.mock() as m: |
| 107 | + m.get(f"{server.flow_runs.baseurl}/{flow_run_id}", text=response_xml) |
| 108 | + with pytest.raises(TimeoutError): |
| 109 | + server.flow_runs.wait_for_job(flow_run_id, timeout=30) |
| 110 | + |
| 111 | + |
| 112 | +def test_queryset(server: TSC.Server) -> None: |
| 113 | + response_xml = GET_XML.read_text() |
| 114 | + error_response = server_response_error_factory( |
| 115 | + "400006", "Bad Request", "0xB4EAB088 : The start index '9900' is greater than or equal to the total count.)" |
| 116 | + ) |
| 117 | + with requests_mock.mock() as m: |
| 118 | + m.get(f"{server.flow_runs.baseurl}?pageNumber=1", text=response_xml) |
| 119 | + m.get(f"{server.flow_runs.baseurl}?pageNumber=2", text=error_response) |
| 120 | + queryset = server.flow_runs.all() |
| 121 | + assert len(queryset) == sys.maxsize |
0 commit comments