OLD | NEW |
(Empty) | |
| 1 """ |
| 2 Tests for Layer1 of Simple Workflow |
| 3 |
| 4 """ |
| 5 import os |
| 6 import unittest |
| 7 import time |
| 8 |
| 9 from boto.swf.layer1 import Layer1 |
| 10 from boto.swf import exceptions as swf_exceptions |
| 11 |
| 12 |
| 13 |
| 14 # A standard AWS account is permitted a maximum of 100 of SWF domains, |
| 15 # registered or deprecated. Deleting deprecated domains on demand does |
| 16 # not appear possible. Therefore, these tests reuse a default or |
| 17 # user-named testing domain. This is named by the user via the environment |
| 18 # variable BOTO_SWF_UNITTEST_DOMAIN, if available. Otherwise the default |
| 19 # testing domain is literally "boto-swf-unittest-domain". Do not use |
| 20 # the testing domain for other purposes. |
| 21 BOTO_SWF_UNITTEST_DOMAIN = os.environ.get("BOTO_SWF_UNITTEST_DOMAIN", |
| 22 "boto-swf-unittest-domain") |
| 23 |
| 24 # A standard domain can have a maxiumum of 10,000 workflow types and |
| 25 # activity types, registered or deprecated. Therefore, eventually any |
| 26 # tests which register new workflow types or activity types would begin |
| 27 # to fail with LimitExceeded. Instead of generating new workflow types |
| 28 # and activity types, these tests reuse the existing types. |
| 29 |
| 30 # The consequence of the limits and inability to delete deprecated |
| 31 # domains, workflow types, and activity types is that the tests in |
| 32 # this module will not test for the three register actions: |
| 33 # * register_domain |
| 34 # * register_workflow_type |
| 35 # * register_activity_type |
| 36 # Instead, the setUp of the TestCase create a domain, workflow type, |
| 37 # and activity type, expecting that they may already exist, and the |
| 38 # tests themselves test other things. |
| 39 |
| 40 # If you really want to re-test the register_* functions in their |
| 41 # ability to create things (rather than just reporting that they |
| 42 # already exist), you'll need to use a new BOTO_SWF_UNITTEST_DOMAIN. |
| 43 # But, beware that once you hit 100 domains, you are cannot create any |
| 44 # more, delete existing ones, or rename existing ones. |
| 45 |
| 46 # Some API calls establish resources, but these resources are not instantly |
| 47 # available to the next API call. For testing purposes, it is necessary to |
| 48 # have a short pause to avoid having tests fail for invalid reasons. |
| 49 PAUSE_SECONDS = 4 |
| 50 |
| 51 |
| 52 |
| 53 class SimpleWorkflowLayer1TestBase(unittest.TestCase): |
| 54 """ |
| 55 There are at least two test cases which share this setUp/tearDown |
| 56 and the class-based parameter definitions: |
| 57 * SimpleWorkflowLayer1Test |
| 58 * tests.swf.test_layer1_workflow_execution.SwfL1WorkflowExecutionTest |
| 59 """ |
| 60 swf = True |
| 61 # Some params used throughout the tests... |
| 62 # Domain registration params... |
| 63 _domain = BOTO_SWF_UNITTEST_DOMAIN |
| 64 _workflow_execution_retention_period_in_days = 'NONE' |
| 65 _domain_description = 'test workflow domain' |
| 66 # Type registration params used for workflow type and activity type... |
| 67 _task_list = 'tasklist1' |
| 68 # Workflow type registration params... |
| 69 _workflow_type_name = 'wft1' |
| 70 _workflow_type_version = '1' |
| 71 _workflow_type_description = 'wft1 description' |
| 72 _default_child_policy = 'REQUEST_CANCEL' |
| 73 _default_execution_start_to_close_timeout = '600' |
| 74 _default_task_start_to_close_timeout = '60' |
| 75 # Activity type registration params... |
| 76 _activity_type_name = 'at1' |
| 77 _activity_type_version = '1' |
| 78 _activity_type_description = 'at1 description' |
| 79 _default_task_heartbeat_timeout = '30' |
| 80 _default_task_schedule_to_close_timeout = '90' |
| 81 _default_task_schedule_to_start_timeout = '10' |
| 82 _default_task_start_to_close_timeout = '30' |
| 83 |
| 84 |
| 85 def setUp(self): |
| 86 # Create a Layer1 connection for testing. |
| 87 # Tester needs boto config or keys in environment variables. |
| 88 self.conn = Layer1() |
| 89 |
| 90 # Register a domain. Expect None (success) or |
| 91 # SWFDomainAlreadyExistsError. |
| 92 try: |
| 93 r = self.conn.register_domain(self._domain, |
| 94 self._workflow_execution_retention_period_in_days, |
| 95 description=self._domain_description) |
| 96 assert r is None |
| 97 time.sleep(PAUSE_SECONDS) |
| 98 except swf_exceptions.SWFDomainAlreadyExistsError: |
| 99 pass |
| 100 |
| 101 # Register a workflow type. Expect None (success) or |
| 102 # SWFTypeAlreadyExistsError. |
| 103 try: |
| 104 r = self.conn.register_workflow_type(self._domain, |
| 105 self._workflow_type_name, self._workflow_type_version, |
| 106 task_list=self._task_list, |
| 107 default_child_policy=self._default_child_policy, |
| 108 default_execution_start_to_close_timeout= |
| 109 self._default_execution_start_to_close_timeout, |
| 110 default_task_start_to_close_timeout= |
| 111 self._default_task_start_to_close_timeout, |
| 112 description=self._workflow_type_description) |
| 113 assert r is None |
| 114 time.sleep(PAUSE_SECONDS) |
| 115 except swf_exceptions.SWFTypeAlreadyExistsError: |
| 116 pass |
| 117 |
| 118 # Register an activity type. Expect None (success) or |
| 119 # SWFTypeAlreadyExistsError. |
| 120 try: |
| 121 r = self.conn.register_activity_type(self._domain, |
| 122 self._activity_type_name, self._activity_type_version, |
| 123 task_list=self._task_list, |
| 124 default_task_heartbeat_timeout= |
| 125 self._default_task_heartbeat_timeout, |
| 126 default_task_schedule_to_close_timeout= |
| 127 self._default_task_schedule_to_close_timeout, |
| 128 default_task_schedule_to_start_timeout= |
| 129 self._default_task_schedule_to_start_timeout, |
| 130 default_task_start_to_close_timeout= |
| 131 self._default_task_start_to_close_timeout, |
| 132 description=self._activity_type_description) |
| 133 assert r is None |
| 134 time.sleep(PAUSE_SECONDS) |
| 135 except swf_exceptions.SWFTypeAlreadyExistsError: |
| 136 pass |
| 137 |
| 138 def tearDown(self): |
| 139 # Delete what we can... |
| 140 pass |
| 141 |
| 142 |
| 143 |
| 144 |
| 145 class SimpleWorkflowLayer1Test(SimpleWorkflowLayer1TestBase): |
| 146 |
| 147 def test_list_domains(self): |
| 148 # Find the domain. |
| 149 r = self.conn.list_domains('REGISTERED') |
| 150 found = None |
| 151 for info in r['domainInfos']: |
| 152 if info['name'] == self._domain: |
| 153 found = info |
| 154 break |
| 155 self.assertNotEqual(found, None, 'list_domains; test domain not found') |
| 156 # Validate some properties. |
| 157 self.assertEqual(found['description'], self._domain_description, |
| 158 'list_domains; description does not match') |
| 159 self.assertEqual(found['status'], 'REGISTERED', |
| 160 'list_domains; status does not match') |
| 161 |
| 162 def test_list_workflow_types(self): |
| 163 # Find the workflow type. |
| 164 r = self.conn.list_workflow_types(self._domain, 'REGISTERED') |
| 165 found = None |
| 166 for info in r['typeInfos']: |
| 167 if ( info['workflowType']['name'] == self._workflow_type_name and |
| 168 info['workflowType']['version'] == self._workflow_type_version
): |
| 169 found = info |
| 170 break |
| 171 self.assertNotEqual(found, None, 'list_workflow_types; test type not fou
nd') |
| 172 # Validate some properties. |
| 173 self.assertEqual(found['description'], self._workflow_type_description, |
| 174 'list_workflow_types; description does not match') |
| 175 self.assertEqual(found['status'], 'REGISTERED', |
| 176 'list_workflow_types; status does not match') |
| 177 |
| 178 def test_list_activity_types(self): |
| 179 # Find the activity type. |
| 180 r = self.conn.list_activity_types(self._domain, 'REGISTERED') |
| 181 found = None |
| 182 for info in r['typeInfos']: |
| 183 if info['activityType']['name'] == self._activity_type_name: |
| 184 found = info |
| 185 break |
| 186 self.assertNotEqual(found, None, 'list_activity_types; test type not fou
nd') |
| 187 # Validate some properties. |
| 188 self.assertEqual(found['description'], self._activity_type_description, |
| 189 'list_activity_types; description does not match') |
| 190 self.assertEqual(found['status'], 'REGISTERED', |
| 191 'list_activity_types; status does not match') |
| 192 |
| 193 |
| 194 def test_list_closed_workflow_executions(self): |
| 195 # Test various legal ways to call function. |
| 196 latest_date = time.time() |
| 197 oldest_date = time.time() - 3600 |
| 198 # With startTimeFilter... |
| 199 self.conn.list_closed_workflow_executions(self._domain, |
| 200 start_latest_date=latest_date, start_oldest_date=oldest_date) |
| 201 # With closeTimeFilter... |
| 202 self.conn.list_closed_workflow_executions(self._domain, |
| 203 close_latest_date=latest_date, close_oldest_date=oldest_date) |
| 204 # With closeStatusFilter... |
| 205 self.conn.list_closed_workflow_executions(self._domain, |
| 206 close_latest_date=latest_date, close_oldest_date=oldest_date, |
| 207 close_status='COMPLETED') |
| 208 # With tagFilter... |
| 209 self.conn.list_closed_workflow_executions(self._domain, |
| 210 close_latest_date=latest_date, close_oldest_date=oldest_date, |
| 211 tag='ig') |
| 212 # With executionFilter... |
| 213 self.conn.list_closed_workflow_executions(self._domain, |
| 214 close_latest_date=latest_date, close_oldest_date=oldest_date, |
| 215 workflow_id='ig') |
| 216 # With typeFilter... |
| 217 self.conn.list_closed_workflow_executions(self._domain, |
| 218 close_latest_date=latest_date, close_oldest_date=oldest_date, |
| 219 workflow_name='ig', workflow_version='ig') |
| 220 # With reverseOrder... |
| 221 self.conn.list_closed_workflow_executions(self._domain, |
| 222 close_latest_date=latest_date, close_oldest_date=oldest_date, |
| 223 reverse_order=True) |
| 224 |
| 225 |
| 226 def test_list_open_workflow_executions(self): |
| 227 # Test various legal ways to call function. |
| 228 latest_date = time.time() |
| 229 oldest_date = time.time() - 3600 |
| 230 # With required params only... |
| 231 self.conn.list_closed_workflow_executions(self._domain, |
| 232 latest_date, oldest_date) |
| 233 # With tagFilter... |
| 234 self.conn.list_closed_workflow_executions(self._domain, |
| 235 latest_date, oldest_date, tag='ig') |
| 236 # With executionFilter... |
| 237 self.conn.list_closed_workflow_executions(self._domain, |
| 238 latest_date, oldest_date, workflow_id='ig') |
| 239 # With typeFilter... |
| 240 self.conn.list_closed_workflow_executions(self._domain, |
| 241 latest_date, oldest_date, |
| 242 workflow_name='ig', workflow_version='ig') |
| 243 # With reverseOrder... |
| 244 self.conn.list_closed_workflow_executions(self._domain, |
| 245 latest_date, oldest_date, reverse_order=True) |
| 246 |
OLD | NEW |