Best Python code snippet using playwright-python
integration_test.py
Source:integration_test.py
1""" Integration tests for testing the Task execution order etc. """2import logging3import datetime4import random # pylint: disable=W06115from fantasm.lock import ReadWriteLock6from fantasm import config # pylint: disable=W06117from fantasm.fsm import FSM8from fantasm.models import _FantasmFanIn, _FantasmInstance, _FantasmLog9from fantasm_tests.helpers import runQueuedTasks10from fantasm_tests.helpers import overrideFails11from fantasm_tests.helpers import setUpByFilename12from fantasm_tests.helpers import getCounts13from fantasm_tests.fixtures import AppEngineTestCase14from fantasm_tests.fsm_test import TestModel, NDBTestModel15from fantasm_tests.fsm_test import getLoggingDouble16from fantasm_tests.actions import ContextRecorder, CountExecuteCallsFanIn, TestFileContinuationFSMAction, \17 DoubleContinuation1, DoubleContinuation2, ResultModel, CustomImpl18from minimock import mock, restore19from google.appengine.api import datastore_types20from google.appengine.ext.ndb import key as ndb_key21# pylint: disable=C0111, W0212, W0612, W0613, C030122# - docstrings not reqd in unit tests23# - unit tests need access to protected members24# - lots of unused args in unit tests25# - lots of long lines for clarity26class RunTasksBaseTest(AppEngineTestCase):27 FILENAME = None28 MACHINE_NAME = None29 METHOD = 'GET'30 def setUp(self):31 super(RunTasksBaseTest, self).setUp()32 for i in range(10):33 TestModel(key_name=str(i)).put()34 nkey = ndb_key.Key('NDBTestModel', str(i))35 NDBTestModel(key=nkey).put()36 self.setUpByFilename(self.FILENAME, instanceName='instanceName', machineName=self.MACHINE_NAME,37 method=self.METHOD)38 self.maxDiff = None39 def tearDown(self):40 super(RunTasksBaseTest, self).tearDown()41 restore()42 def setUpMock(self):43 mock('config.currentConfiguration', returns=self.currentConfig, tracker=None)44 mock('random.randint', returns=1, tracker=None)45 def setUpByFilename(self, filename, instanceName=None, taskRetryLimitOverrides=None, machineName=None,46 method='GET'):47 setUpByFilename(self,48 filename,49 instanceName=instanceName,50 taskRetryLimitOverrides=taskRetryLimitOverrides,51 machineName=machineName,52 method=method)53 self.setUpMock()54class LoggingTests( RunTasksBaseTest ):55 FILENAME = 'test-TaskQueueFSMTests.yaml'56 def setUp(self):57 super(LoggingTests, self).setUp()58 self.context.initialize()59 self.context.logger.persistentLogging = True60 def test_FantasmInstance(self):61 self.assertEqual(1, _FantasmInstance.all(namespace='').count())62 def _test_FantasmLog(self, level, logger):63 self.assertEqual(1, _FantasmInstance.all(namespace='').count())64 logger("message: %s", "foo", exc_info=True)65 runQueuedTasks(queueName=self.context.queueName)66 query = _FantasmLog.all(namespace='').filter("level =", level)67 self.assertEqual(1, query.count())68 self.assertEqual("message: foo", query.get().message)69 def test_FantasmLog_DEBUG(self):70 self._test_FantasmLog(logging.DEBUG, self.context.logger.debug)71 def test_FantasmLog_INFO(self):72 self._test_FantasmLog(logging.INFO, self.context.logger.info)73 def test_FantasmLog_WARNING(self):74 self._test_FantasmLog(logging.WARNING, self.context.logger.warning)75 def test_FantasmLog_ERROR(self):76 self._test_FantasmLog(logging.ERROR, self.context.logger.error)77 def test_FantasmLog_CRITICAL(self):78 self._test_FantasmLog(logging.CRITICAL, self.context.logger.critical)79 def test_FantasmInstance_stack(self):80 self.context.logger.critical("message", exc_info=1)81 runQueuedTasks(queueName=self.context.queueName)82 log = _FantasmLog.all(namespace='').get()83 self.assertEqual("message", log.message)84 self.assertEqual("None\n", log.stack)85 def test_FantasmInstance_stack_error(self):86 try:87 list()[0]88 except Exception:89 self.context.logger.critical("message", exc_info=1)90 runQueuedTasks(queueName=self.context.queueName)91 log = _FantasmLog.all(namespace='').get()92 self.assertEqual("message", log.message)93 self.assertTrue("Traceback" in log.stack and "IndexError" in log.stack)94class ParamsTests(RunTasksBaseTest):95 FILENAME = 'test-TaskQueueFSMTests.yaml'96 MACHINE_NAME = 'ContextRecorder'97 def setUp(self):98 super(ParamsTests, self).setUp()99 ContextRecorder.CONTEXTS = []100 def tearDown(self):101 super(ParamsTests, self).tearDown()102 ContextRecorder.CONTEXTS = []103 def _test_not_a_list(self, method):104 self.context.method = method105 self.context['foo'] = 'bar'106 self.context.initialize() # queues the first task107 ran = runQueuedTasks(queueName=self.context.queueName)108 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',109 'instanceName--state-initial--next-event--state-final--step-1'], ran)110 self.assertEqual([{'foo': 'bar',111 '__step__': 1}], ContextRecorder.CONTEXTS)112 def _test_list(self, method):113 self.context.method = method114 self.context['foo'] = ['bar1', 'bar2', 'bar3']115 self.context.initialize() # queues the first task116 ran = runQueuedTasks(queueName=self.context.queueName)117 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',118 'instanceName--state-initial--next-event--state-final--step-1'], ran)119 self.assertEqual([{'foo': ['bar1', 'bar2', 'bar3'],120 '__step__': 1}], ContextRecorder.CONTEXTS)121 def test_GET_not_a_list(self):122 self._test_not_a_list('GET')123 def test_POST_not_a_list(self):124 self._test_not_a_list('POST')125 def test_GET_list(self):126 self._test_list('GET')127 def test_POST_list(self):128 self._test_list('POST')129 def _test_lots_of_different_data_types(self, method):130 self.context.method = method131 models = list(TestModel.all())132 dt = datetime.datetime.now() # NOT in UTC133 self.context['db_Key'] = models[0].key()134 self.context['db_Key_defined_in_context_types'] = models[0].key()135 self.context['char'] = 'a'136 self.context['bool1'] = False137 self.context['bool2'] = True138 self.context['str'] = 'abc'139 self.context['str_as_unicode'] = 'abc'140 self.context['unicode'] = u'\xe8' # MUST be context_types141 self.context['list_of_str'] = ['a', 'b', 'c']142 self.context['list_of_str_len_1'] = ['a']143 self.context['list_of_db_Key'] = [models[0].key(), models[1].key(), models[2].key()]144 self.context['list_of_db_Key_len_1'] = [models[0].key()]145 self.context['list_of_mixed'] = ['a', 1, 'b', 2]146 self.context['list_of_unicode'] = [u'\xe8', u'\xe9'] # MUST be context_types147 self.context['dict_int_keys'] = {1: 1, 2: 2} # BAD!!!! not defined in context_types148 self.context['dict_int_keys_defined_in_context_types'] = {1: 1, 2: 2}149 self.context['dict_str_keys'] = {'a': 1, 'b': 2} # BAD!!!! not defined in context_types150 self.context['dict_str_keys_defined_in_context_types'] = {'a': 1, 'b': 2}151 self.context['dict_db_Key'] = {'a': models[1].key()} # BAD!!!! not defined in context_types152 self.context['dict_db_Key_defined_in_context_types'] = {'a': models[1].key()}153 self.context['unicode2'] = " Mik\xe9 , Br\xe9\xe9 , Michael.Bree-1@gmail.com , Montr\xe9al ".decode('iso-8859-1')154 self.context['custom'] = CustomImpl(a='A', b='B')155 self.context['list_of_custom'] = [CustomImpl(a='A', b='B'), CustomImpl(a='AA', b='BB')]156 self.context['list_of_custom_len_1'] = [CustomImpl(a='A', b='B')]157 self.context['plain_old_object'] = {'a': 'b'}158 self.context['list_of_plain_old_object'] = [{'a': 'b'}, {'c': 'd'}]159 self.context['datetime_obj'] = dt160 self.context['list_of_datetime_obj'] = [dt, dt, dt]161 # NDB Key stuff162 nkey1 = ndb_key.Key('NDBTestModel', '1')163 self.context['ndb_Key'] = nkey1164 self.context['ndb_key_Key'] = nkey1165 self.context['ndb_model_Key'] = nkey1166 self.context['ndb_context_Key'] = nkey1167 self.context.initialize() # queues the first task168 ran = runQueuedTasks(queueName=self.context.queueName)169 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',170 'instanceName--state-initial--next-event--state-final--step-1'], ran)171 self.assertEqual([{'datetime_obj': dt,172 'list_of_datetime_obj': [dt, dt, dt],173 'plain_old_object': {'a': 'b'},174 'list_of_plain_old_object': [{'a': 'b'}, {'c': 'd'}],175 'custom': CustomImpl(a="A", b="B"),176 'list_of_custom': [CustomImpl(a="A", b="B"), CustomImpl(a="AA", b="BB")],177 'list_of_custom_len_1': [CustomImpl(a="A", b="B")],178 'db_Key': 'agdmYW50YXNtchALEglUZXN0TW9kZWwiATAM',179 'db_Key_defined_in_context_types': datastore_types.Key.from_path(u'TestModel', u'0', _app=u'fantasm'),180 'char': 'a',181 'unicode': u'\xe8',182 'bool1': False,183 'bool2': True,184 'str': 'abc',185 'str_as_unicode': u'abc',186 'list_of_str': ['a', 'b', 'c'],187 'list_of_str_len_1': ['a'],188 'list_of_db_Key': [datastore_types.Key.from_path(u'TestModel', u'0', _app=u'fantasm'),189 datastore_types.Key.from_path(u'TestModel', u'1', _app=u'fantasm'),190 datastore_types.Key.from_path(u'TestModel', u'2', _app=u'fantasm')],191 'list_of_db_Key_len_1': [datastore_types.Key.from_path(u'TestModel', u'0', _app=u'fantasm')],192 'list_of_unicode': [u'\xe8', u'\xe9'],193 'list_of_mixed': ['a', '1', 'b', '2'],194 'dict_int_keys': '{"1": 1, "2": 2}',195 'dict_int_keys_defined_in_context_types': {"1": 1, "2": 2},196 'dict_str_keys': '{"a": 1, "b": 2}',197 'dict_str_keys_defined_in_context_types': {"a": 1, "b": 2},198 'dict_db_Key': '{"a": {"__db.Key__": true, "key": "agdmYW50YXNtchALEglUZXN0TW9kZWwiATEM"}}',199 'dict_db_Key_defined_in_context_types': {'a': datastore_types.Key.from_path(u'TestModel', u'1', _app=u'fantasm')},200 'unicode2': u" Mik\xe9 , Br\xe9\xe9 , Michael.Bree-1@gmail.com , Montr\xe9al ",201 '__step__': 1,202 # NDB Key stuff203 'ndb_Key': nkey1,204 'ndb_key_Key': nkey1,205 'ndb_model_Key': nkey1,206 'ndb_context_Key': nkey1,207 }], ContextRecorder.CONTEXTS)208 def test_GET_lots_of_different_data_types(self):209 self._test_lots_of_different_data_types('GET')210 def test_POST_lots_of_different_data_types(self):211 self._test_lots_of_different_data_types('POST')212class HeadersTests(RunTasksBaseTest):213 FILENAME = 'test-TaskQueueFSMTests.yaml'214 MACHINE_NAME = 'TaskQueueFSMTests'215 def setUp(self):216 super(HeadersTests, self).setUp()217 ContextRecorder.CONTEXTS = []218 def tearDown(self):219 super(HeadersTests, self).tearDown()220 ContextRecorder.CONTEXTS = []221 def test_headers(self):222 self.context.headers = {'X-Fantasm-Header': 'abc'}223 self.context.initialize() # queues the first task224 ran = runQueuedTasks(queueName=self.context.queueName)225 def test_headers_multi_valued(self):226 self.context.headers = {'X-Fantasm-Header': ['abc', '123']}227 self.context.initialize() # queues the first task228 ran = runQueuedTasks(queueName=self.context.queueName)229class RunTasksTests_TaskQueueFSMTests(RunTasksBaseTest):230 FILENAME = 'test-TaskQueueFSMTests.yaml'231 MACHINE_NAME = 'TaskQueueFSMTests'232 def test_TaskQueueFSMTests(self):233 self.context.initialize() # queues the first task234 ran = runQueuedTasks(queueName=self.context.queueName)235 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',236 'instanceName--state-initial--next-event--state-normal--step-1',237 'instanceName--state-normal--next-event--state-final--step-2'], ran)238 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 1},239 'state-normal': {'entry': 1, 'action': 1, 'exit': 1},240 'state-final': {'entry': 1, 'action': 1, 'exit': 0},241 'state-initial--next-event': {'action': 1},242 'state-normal--next-event': {'action': 1}},243 getCounts(self.machineConfig))244class RunTasksTests_TaskQueueFSMTests_POST(RunTasksTests_TaskQueueFSMTests):245 METHOD = 'POST'246class RunTasksTests_TaskQueueFSMTestsFinalExit(RunTasksBaseTest):247 FILENAME = 'test-TaskQueueFSMTests.yaml'248 MACHINE_NAME = 'TaskQueueFSMTestsFinalExit'249 def test_TaskQueueFSMTests(self):250 self.context.initialize() # queues the first task251 ran = runQueuedTasks(queueName=self.context.queueName)252 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',253 'instanceName--state-initial--next-event--state-normal--step-1',254 'instanceName--state-normal--next-event--state-final--step-2',255 'instanceName--state-final--pseudo-final--pseudo-final--step-3'], ran)256 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 1},257 'state-normal': {'entry': 1, 'action': 1, 'exit': 1},258 'state-final': {'entry': 1, 'action': 1, 'exit': 1},259 'state-initial--next-event': {'action': 1},260 'state-normal--next-event': {'action': 1}},261 getCounts(self.machineConfig))262class RunTasksTests_TaskQueueFSMTestsFinalExit_POST(RunTasksTests_TaskQueueFSMTestsFinalExit):263 METHOD = 'POST'264class RunTasksTests_SelfTransitionTests(RunTasksBaseTest):265 FILENAME = 'test-TaskQueueFSMTests.yaml'266 MACHINE_NAME = 'SelfTransitionTests'267 def test_SelfTransitionTests(self):268 self.context.initialize() # queues the first task269 ran = runQueuedTasks(queueName=self.context.queueName)270 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state1--step-0',271 'instanceName--state1--next-event1--state1--step-1',272 'instanceName--state1--next-event1--state1--step-2',273 'instanceName--state1--next-event1--state1--step-3',274 'instanceName--state1--next-event1--state1--step-4',275 'instanceName--state1--next-event1--state1--step-5',276 'instanceName--state1--next-event2--state2--step-6'], ran)277 self.assertEqual({'state1': {'entry': 6, 'action': 6, 'exit': 6},278 'state2': {'entry': 1, 'action': 1, 'exit': 0},279 'state1--next-event1': {'action': 5},280 'state1--next-event2': {'action': 1}},281 getCounts(self.machineConfig))282class RunTasksTests_SelfTransitionTests_POST(RunTasksTests_SelfTransitionTests):283 METHOD = 'POST'284class RunTasksTests_DatastoreFSMContinuationTests(RunTasksBaseTest):285 FILENAME = 'test-DatastoreFSMContinuationTests.yaml'286 MACHINE_NAME = 'DatastoreFSMContinuationTests'287 def test_DatastoreFSMContinuationTests(self):288 self.context.initialize() # queues the first task289 ran = runQueuedTasks(queueName=self.context.queueName)290 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',291 'instanceName--state-initial--next-event--state-continuation--step-1',292 'instanceName--continuation-1-1--state-initial--next-event--state-continuation--step-1',293 'instanceName--state-continuation--next-event--state-final--step-2',294 'instanceName--continuation-1-2--state-initial--next-event--state-continuation--step-1',295 'instanceName--continuation-1-1--state-continuation--next-event--state-final--step-2',296 'instanceName--continuation-1-3--state-initial--next-event--state-continuation--step-1',297 'instanceName--continuation-1-2--state-continuation--next-event--state-final--step-2',298 'instanceName--continuation-1-4--state-initial--next-event--state-continuation--step-1',299 'instanceName--continuation-1-3--state-continuation--next-event--state-final--step-2',300 'instanceName--continuation-1-5--state-initial--next-event--state-continuation--step-1',301 'instanceName--continuation-1-4--state-continuation--next-event--state-final--step-2'], ran)302 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 0},303 'state-continuation': {'entry': 6, 'action': 5, 'continuation': 6, 'exit': 0},304 'state-final': {'entry': 5, 'action': 5, 'exit': 0},305 'state-initial--next-event': {'action': 0},306 'state-continuation--next-event': {'action': 0}},307 getCounts(self.machineConfig))308class RunTasksTests_DatastoreFSMContinuationTests_POST(RunTasksTests_DatastoreFSMContinuationTests):309 METHOD = 'POST'310class RunTasksTests_NDBDatastoreFSMContinuationTests(RunTasksBaseTest):311 FILENAME = 'test-NDBDatastoreFSMContinuationTests.yaml'312 MACHINE_NAME = 'NDBDatastoreFSMContinuationTests'313 def test_NDBDatastoreFSMContinuationTests(self):314 self.context.initialize() # queues the first task315 ran = runQueuedTasks(queueName=self.context.queueName)316 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',317 'instanceName--state-initial--next-event--state-continuation--step-1',318 'instanceName--continuation-1-1--state-initial--next-event--state-continuation--step-1',319 'instanceName--state-continuation--next-event--state-final--step-2',320 'instanceName--continuation-1-2--state-initial--next-event--state-continuation--step-1',321 'instanceName--continuation-1-1--state-continuation--next-event--state-final--step-2',322 'instanceName--continuation-1-3--state-initial--next-event--state-continuation--step-1',323 'instanceName--continuation-1-2--state-continuation--next-event--state-final--step-2',324 'instanceName--continuation-1-4--state-initial--next-event--state-continuation--step-1',325 'instanceName--continuation-1-3--state-continuation--next-event--state-final--step-2',326 'instanceName--continuation-1-4--state-continuation--next-event--state-final--step-2'], ran)327 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 0},328 'state-continuation': {'entry': 5, 'action': 5, 'continuation': 5, 'exit': 0},329 'state-final': {'entry': 5, 'action': 5, 'exit': 0},330 'state-initial--next-event': {'action': 0},331 'state-continuation--next-event': {'action': 0}},332 getCounts(self.machineConfig))333class RunTasksTests_NDBDatastoreFSMContinuationTests_POST(RunTasksTests_NDBDatastoreFSMContinuationTests):334 METHOD = 'POST'335class RunTasksTests_DatastoreFSMContinuationQueueTests(RunTasksBaseTest):336 FILENAME = 'test-DatastoreFSMContinuationTests.yaml'337 MACHINE_NAME = 'DatastoreFSMContinuationQueueTests'338 def setUp(self):339 super(RunTasksTests_DatastoreFSMContinuationQueueTests, self).setUp()340 import google.appengine.api.taskqueue.taskqueue_stub as taskqueue_stub341 import google.appengine.api.apiproxy_stub_map as apiproxy_stub_map342 self.__taskqueue = taskqueue_stub.TaskQueueServiceStub(root_path='./test/fantasm_tests/yaml/')343 apiproxy_stub_map.apiproxy._APIProxyStubMap__stub_map.pop('taskqueue')344 apiproxy_stub_map.apiproxy.RegisterStub('taskqueue', self.__taskqueue)345 def test_DatastoreFSMContinuationTests(self):346 self.context.initialize() # queues the first task347 ran1 = runQueuedTasks(queueName='queue1')348 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0'], ran1)349 ran2 = runQueuedTasks(queueName='queue2')350 self.assertEqual(['instanceName--state-initial--next-event--state-continuation--step-1',351 'instanceName--continuation-1-1--state-initial--next-event--state-continuation--step-1',352 'instanceName--continuation-1-2--state-initial--next-event--state-continuation--step-1',353 'instanceName--continuation-1-3--state-initial--next-event--state-continuation--step-1',354 'instanceName--continuation-1-4--state-initial--next-event--state-continuation--step-1',355 'instanceName--continuation-1-5--state-initial--next-event--state-continuation--step-1'], ran2)356 ran3 = runQueuedTasks(queueName='queue3')357 self.assertEqual(['instanceName--state-continuation--next-event--state-final--step-2',358 'instanceName--continuation-1-1--state-continuation--next-event--state-final--step-2',359 'instanceName--continuation-1-2--state-continuation--next-event--state-final--step-2',360 'instanceName--continuation-1-3--state-continuation--next-event--state-final--step-2',361 'instanceName--continuation-1-4--state-continuation--next-event--state-final--step-2'], ran3)362 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 0},363 'state-continuation': {'entry': 6, 'action': 5, 'continuation': 6, 'exit': 0},364 'state-final': {'entry': 5, 'action': 5, 'exit': 0},365 'state-initial--next-event': {'action': 0},366 'state-continuation--next-event': {'action': 0}},367 getCounts(self.machineConfig))368class RunTasksTests_DatastoreFSMContinuationQueueTests_POST(RunTasksTests_DatastoreFSMContinuationQueueTests):369 METHOD = 'POST'370class RunTasksTests_NDBDatastoreFSMContinuationQueueTests(RunTasksBaseTest):371 FILENAME = 'test-NDBDatastoreFSMContinuationTests.yaml'372 MACHINE_NAME = 'NDBDatastoreFSMContinuationQueueTests'373 def setUp(self):374 super(RunTasksTests_NDBDatastoreFSMContinuationQueueTests, self).setUp()375 import google.appengine.api.taskqueue.taskqueue_stub as taskqueue_stub376 import google.appengine.api.apiproxy_stub_map as apiproxy_stub_map377 self.__taskqueue = taskqueue_stub.TaskQueueServiceStub(root_path='./test/fantasm_tests/yaml/')378 apiproxy_stub_map.apiproxy._APIProxyStubMap__stub_map.pop('taskqueue')379 apiproxy_stub_map.apiproxy.RegisterStub('taskqueue', self.__taskqueue)380 def test_NDBDatastoreFSMContinuationTests(self):381 self.context.initialize() # queues the first task382 ran1 = runQueuedTasks(queueName='queue1')383 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0'], ran1)384 ran2 = runQueuedTasks(queueName='queue2')385 self.assertEqual(['instanceName--state-initial--next-event--state-continuation--step-1',386 'instanceName--continuation-1-1--state-initial--next-event--state-continuation--step-1',387 'instanceName--continuation-1-2--state-initial--next-event--state-continuation--step-1',388 'instanceName--continuation-1-3--state-initial--next-event--state-continuation--step-1',389 'instanceName--continuation-1-4--state-initial--next-event--state-continuation--step-1'], ran2)390 ran3 = runQueuedTasks(queueName='queue3')391 self.assertEqual(['instanceName--state-continuation--next-event--state-final--step-2',392 'instanceName--continuation-1-1--state-continuation--next-event--state-final--step-2',393 'instanceName--continuation-1-2--state-continuation--next-event--state-final--step-2',394 'instanceName--continuation-1-3--state-continuation--next-event--state-final--step-2',395 'instanceName--continuation-1-4--state-continuation--next-event--state-final--step-2'], ran3)396 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 0},397 'state-continuation': {'entry': 5, 'action': 5, 'continuation': 5, 'exit': 0},398 'state-final': {'entry': 5, 'action': 5, 'exit': 0},399 'state-initial--next-event': {'action': 0},400 'state-continuation--next-event': {'action': 0}},401 getCounts(self.machineConfig))402class RunTasksTests_NDBDatastoreFSMContinuationQueueTests_POST(RunTasksTests_NDBDatastoreFSMContinuationQueueTests):403 METHOD = 'POST'404class RunTasksTests_FileFSMContinuationTests(RunTasksBaseTest):405 FILENAME = 'test-FileFSMContinuationTests.yaml'406 MACHINE_NAME = 'FileFSMContinuationTests'407 def setUp(self):408 super(RunTasksTests_FileFSMContinuationTests, self).setUp()409 TestFileContinuationFSMAction.CONTEXTS = []410 def tearDown(self):411 super(RunTasksTests_FileFSMContinuationTests, self).tearDown()412 TestFileContinuationFSMAction.CONTEXTS = []413 def test_FileFSMContinuationTests(self):414 self.context.initialize() # queues the first task415 ran = runQueuedTasks(queueName=self.context.queueName)416 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-continuation--step-0',417 'instanceName--continuation-0-1--pseudo-init--pseudo-init--state-continuation--step-0',418 'instanceName--state-continuation--next-event--state-final--step-1',419 'instanceName--continuation-0-2--pseudo-init--pseudo-init--state-continuation--step-0',420 'instanceName--continuation-0-1--state-continuation--next-event--state-final--step-1',421 'instanceName--continuation-0-3--pseudo-init--pseudo-init--state-continuation--step-0',422 'instanceName--continuation-0-2--state-continuation--next-event--state-final--step-1',423 'instanceName--continuation-0-3--state-continuation--next-event--state-final--step-1'],424 ran)425 self.assertEqual({'state-continuation': {'entry': 4, 'action': 4, 'continuation': 4, 'exit': 0},426 'state-final': {'entry': 4, 'action': 4, 'exit': 0},427 'state-continuation--next-event': {'action': 0}},428 getCounts(self.machineConfig))429 self.assertEqual([{'result': 'a', '__step__': 1},430 {'__step__': 1, 'result': 'b', '__ge__': {'0': 1}},431 {'__step__': 1, 'result': 'c', '__ge__': {'0': 2}},432 {'__step__': 1, 'result': 'd', '__ge__': {'0': 3}}],433 TestFileContinuationFSMAction.CONTEXTS)434class RunTasksTests_FileFSMContinuationTests_POST(RunTasksTests_FileFSMContinuationTests):435 METHOD = 'POST'436class RunTasksTests_DoubleContinuationTests(RunTasksBaseTest):437 FILENAME = 'test-DoubleContinuationTests.yaml'438 MACHINE_NAME = 'DoubleContinuationTests'439 def setUp(self):440 super(RunTasksTests_DoubleContinuationTests, self).setUp()441 DoubleContinuation1.CONTEXTS = []442 DoubleContinuation2.CONTEXTS = []443 def tearDown(self):444 super(RunTasksTests_DoubleContinuationTests, self).tearDown()445 DoubleContinuation1.CONTEXTS = []446 DoubleContinuation2.CONTEXTS = []447 def test_FileFSMContinuationTests(self):448 self.context.initialize() # queues the first task449 ran = runQueuedTasks(queueName=self.context.queueName)450 # Shawn:451 #452 # I'm suggesting some task names here, but am fine with other stuff.453 # You can see I added a new final state (StateFinal) to show how the continuation454 # markers would carry forward into subsequent states.455 #456 # Also, since I've never run this, my values in the counts and contexts may not be correct.457 self.assertEqual(458 ['instanceName--pseudo-init--pseudo-init--DoubleContinuation1--step-0',459 'instanceName--continuation-0-1--pseudo-init--pseudo-init--DoubleContinuation1--step-0',460 'instanceName--DoubleContinuation1--ok--DoubleContinuation2--step-1',461 'instanceName--continuation-0-2--pseudo-init--pseudo-init--DoubleContinuation1--step-0',462 'instanceName--continuation-0-1--DoubleContinuation1--ok--DoubleContinuation2--step-1',463 'instanceName--continuation-1-1--DoubleContinuation1--ok--DoubleContinuation2--step-1',464 'instanceName--DoubleContinuation2--okfinal--StateFinal--step-2',465 'instanceName--continuation-0-2--DoubleContinuation1--ok--DoubleContinuation2--step-1',466 'instanceName--continuation-1-1--continuation-0-1--DoubleContinuation1--ok--DoubleContinuation2--step-1',467 'instanceName--continuation-0-1--DoubleContinuation2--okfinal--StateFinal--step-2',468 'instanceName--continuation-1-2--DoubleContinuation1--ok--DoubleContinuation2--step-1',469 'instanceName--continuation-1-1--DoubleContinuation2--okfinal--StateFinal--step-2',470 'instanceName--continuation-1-1--continuation-0-2--DoubleContinuation1--ok--DoubleContinuation2--step-1',471 'instanceName--continuation-0-2--DoubleContinuation2--okfinal--StateFinal--step-2',472 'instanceName--continuation-1-2--continuation-0-1--DoubleContinuation1--ok--DoubleContinuation2--step-1',473 'instanceName--continuation-1-1--continuation-0-1--DoubleContinuation2--okfinal--StateFinal--step-2',474 'instanceName--continuation-1-2--DoubleContinuation2--okfinal--StateFinal--step-2',475 'instanceName--continuation-1-2--continuation-0-2--DoubleContinuation1--ok--DoubleContinuation2--step-1',476 'instanceName--continuation-1-1--continuation-0-2--DoubleContinuation2--okfinal--StateFinal--step-2',477 'instanceName--continuation-1-2--continuation-0-1--DoubleContinuation2--okfinal--StateFinal--step-2',478 'instanceName--continuation-1-2--continuation-0-2--DoubleContinuation2--okfinal--StateFinal--step-2'],479 ran)480 self.assertEqual({481 'DoubleContinuation1': {482 'entry': 3,483 'action': 3,484 'continuation': 3,485 'exit': 0486 },487 'DoubleContinuation2': {488 'entry': 9,489 'action': 9,490 'continuation': 9,491 'exit': 0492 },493 'StateFinal': {494 'entry': 9,495 'action': 9,496 'exit': 0497 },498 'DoubleContinuation1--ok': {499 'action': 0500 },501 'DoubleContinuation2--okfinal': {502 'action': 0503 },504 }, getCounts(self.machineConfig))505 self.assertEqual([506 {'c1': '1', '__step__': 1},507 {'c1': '2', '__step__': 1, '__ge__': {'0': 1}},508 {'c1': '3', '__step__': 1, '__ge__': {'0': 2}}509 ], DoubleContinuation1.CONTEXTS510 )511 self.assertEqual([512 {'c2': 'a', u'c1': u'1', u'__step__': 2},513 {'c2': 'a', u'c1': u'2', u'__ge__': {u'0': 1}, u'__step__': 2},514 {'c2': 'b', u'c1': u'1', u'__ge__': {u'1': 1}, u'__step__': 2},515 {'c2': 'a', u'c1': u'3', u'__ge__': {u'0': 2}, u'__step__': 2},516 {'c2': 'b', u'c1': u'2', u'__ge__': {u'1': 1, u'0': 1}, u'__step__': 2},517 {'c2': 'c', u'c1': u'1', u'__ge__': {u'1': 2}, u'__step__': 2},518 {'c2': 'b', u'c1': u'3', u'__ge__': {u'1': 1, u'0': 2}, u'__step__': 2},519 {'c2': 'c', u'c1': u'2', u'__ge__': {u'1': 2, u'0': 1}, u'__step__': 2},520 {'c2': 'c', u'c1': u'3', u'__ge__': {u'1': 2, u'0': 2}, u'__step__': 2}521 ], DoubleContinuation2.CONTEXTS522 )523class RunTasksTests_DoubleContinuationTests_POST(RunTasksTests_DoubleContinuationTests):524 METHOD = 'POST'525class RunTasksTests_DatastoreFSMContinuationAndForkTests(RunTasksBaseTest):526 FILENAME = 'test-DatastoreFSMContinuationTests.yaml'527 MACHINE_NAME = 'DatastoreFSMContinuationAndForkTests'528 def test_DatastoreFSMContinuationTests(self):529 self.context.initialize() # queues the first task530 ran = runQueuedTasks(queueName=self.context.queueName)531 self.assertEqual(532 ['instanceName--pseudo-init--pseudo-init--state-continuation-and-fork--step-0',533 'instanceName--continuation-0-1--pseudo-init--pseudo-init--state-continuation-and-fork--step-0',534 'instanceName--state-continuation-and-fork--next-event--state-final--step-1',535 'instanceName--fork--1--state-continuation-and-fork--next-event--state-final--step-1',536 'instanceName--continuation-0-2--pseudo-init--pseudo-init--state-continuation-and-fork--step-0',537 'instanceName--continuation-0-1--state-continuation-and-fork--next-event--state-final--step-1',538 'instanceName--continuation-0-1--fork--1--state-continuation-and-fork--next-event--state-final--step-1',539 'instanceName--continuation-0-3--pseudo-init--pseudo-init--state-continuation-and-fork--step-0',540 'instanceName--continuation-0-2--state-continuation-and-fork--next-event--state-final--step-1',541 'instanceName--continuation-0-2--fork--1--state-continuation-and-fork--next-event--state-final--step-1',542 'instanceName--continuation-0-4--pseudo-init--pseudo-init--state-continuation-and-fork--step-0',543 'instanceName--continuation-0-3--state-continuation-and-fork--next-event--state-final--step-1',544 'instanceName--continuation-0-3--fork--1--state-continuation-and-fork--next-event--state-final--step-1',545 'instanceName--continuation-0-5--pseudo-init--pseudo-init--state-continuation-and-fork--step-0',546 'instanceName--continuation-0-4--state-continuation-and-fork--next-event--state-final--step-1',547 'instanceName--continuation-0-4--fork--1--state-continuation-and-fork--next-event--state-final--step-1'],ran)548 self.assertEqual({'state-continuation-and-fork': {'entry': 6, 'action': 5, 'continuation': 6, 'exit': 0},549 'state-final': {'entry': 10, 'action': 10, 'exit': 0},550 'state-continuation-and-fork--next-event': {'action': 0}},551 getCounts(self.machineConfig))552class RunTasksTests_DatastoreFSMContinuationAndForkTests_POST(RunTasksTests_DatastoreFSMContinuationAndForkTests):553 METHOD = 'POST'554class RunTasksTests_NDBDatastoreFSMContinuationAndForkTests(RunTasksBaseTest):555 FILENAME = 'test-NDBDatastoreFSMContinuationTests.yaml'556 MACHINE_NAME = 'NDBDatastoreFSMContinuationAndForkTests'557 def test_NDBDatastoreFSMContinuationTests(self):558 self.context.initialize() # queues the first task559 ran = runQueuedTasks(queueName=self.context.queueName)560 self.assertEqual(561 ['instanceName--pseudo-init--pseudo-init--state-continuation-and-fork--step-0',562 'instanceName--continuation-0-1--pseudo-init--pseudo-init--state-continuation-and-fork--step-0',563 'instanceName--state-continuation-and-fork--next-event--state-final--step-1',564 'instanceName--fork--1--state-continuation-and-fork--next-event--state-final--step-1',565 'instanceName--continuation-0-2--pseudo-init--pseudo-init--state-continuation-and-fork--step-0',566 'instanceName--continuation-0-1--state-continuation-and-fork--next-event--state-final--step-1',567 'instanceName--continuation-0-1--fork--1--state-continuation-and-fork--next-event--state-final--step-1',568 'instanceName--continuation-0-3--pseudo-init--pseudo-init--state-continuation-and-fork--step-0',569 'instanceName--continuation-0-2--state-continuation-and-fork--next-event--state-final--step-1',570 'instanceName--continuation-0-2--fork--1--state-continuation-and-fork--next-event--state-final--step-1',571 'instanceName--continuation-0-4--pseudo-init--pseudo-init--state-continuation-and-fork--step-0',572 'instanceName--continuation-0-3--state-continuation-and-fork--next-event--state-final--step-1',573 'instanceName--continuation-0-3--fork--1--state-continuation-and-fork--next-event--state-final--step-1',574 'instanceName--continuation-0-4--state-continuation-and-fork--next-event--state-final--step-1',575 'instanceName--continuation-0-4--fork--1--state-continuation-and-fork--next-event--state-final--step-1'],ran)576 self.assertEqual({'state-continuation-and-fork': {'entry': 5, 'action': 5, 'continuation': 5, 'exit': 0},577 'state-final': {'entry': 10, 'action': 10, 'exit': 0},578 'state-continuation-and-fork--next-event': {'action': 0}},579 getCounts(self.machineConfig))580class RunTasksTests_NDBDatastoreFSMContinuationAndForkTests_POST(RunTasksTests_NDBDatastoreFSMContinuationAndForkTests):581 METHOD = 'POST'582class RunTasksTests_DatastoreFSMContinuationFanInAndForkTests(RunTasksBaseTest):583 FILENAME = 'test-DatastoreFSMContinuationFanInTests.yaml'584 MACHINE_NAME = 'DatastoreFSMContinuationFanInAndForkTests'585 def setUp(self):586 super(RunTasksTests_DatastoreFSMContinuationFanInAndForkTests, self).setUp()587 CountExecuteCallsFanIn.CONTEXTS = []588 def tearDown(self):589 super(RunTasksTests_DatastoreFSMContinuationFanInAndForkTests, self).tearDown()590 CountExecuteCallsFanIn.CONTEXTS = []591 def test_DatastoreFSMContinuationTests(self):592 self.context.initialize() # queues the first task593 ran = runQueuedTasks(queueName=self.context.queueName)594 self.assertEqual(595 ['instanceName--pseudo-init--pseudo-init--state-continuation-and-fork--step-0',596 'instanceName--continuation-0-1--pseudo-init--pseudo-init--state-continuation-and-fork--step-0',597 'instanceName--continuation-0-2--pseudo-init--pseudo-init--state-continuation-and-fork--step-0',598 'instanceName--continuation-0-3--pseudo-init--pseudo-init--state-continuation-and-fork--step-0',599 'instanceName--continuation-0-4--pseudo-init--pseudo-init--state-continuation-and-fork--step-0',600 'instanceName--continuation-0-5--pseudo-init--pseudo-init--state-continuation-and-fork--step-0',601 'instanceName--state-continuation-and-fork--next-event--state-fan-in--step-1-1',602 'instanceName--work-index-1--state-fan-in--next-event--state-final--step-2'],ran)603 self.assertEqual({'state-continuation-and-fork': {'entry': 6, 'action': 5, 'continuation': 6, 'exit': 0},604 'state-fan-in': {'entry': 1, 'action': 1, 'exit': 0,605 'fan-in-entry': 10, 'fan-in-action': 10, 'fan-in-exit': 0},606 'state-final': {'entry': 1, 'action': 1, 'exit': 0},607 'state-continuation-and-fork--next-event': {'action': 0},608 'state-fan-in--next-event': {'action': 0}},609 getCounts(self.machineConfig))610 self.assertEqual(0, _FantasmFanIn.all(namespace='').count())611 # pylint: disable=C0301612 # - long lines are much clearer in htis case613 self.assertEqual([{u'__crs__': 2, u'__crc__': 4, '__cc__': False, u'__count__': 2, u'key': datastore_types.Key.from_path(u'TestModel', '3', _app=u'fantasm'), 'data': {'a': 'b'}, u'__step__': 1, u'__ix__': 1},614 {u'__crs__': 2, u'__crc__': 4, '__cc__': False, u'__count__': 2, u'key': datastore_types.Key.from_path(u'TestModel', '2', _app=u'fantasm'), 'data': {'a': 'b'}, u'__step__': 1, u'__ix__': 1},615 {u'__crs__': 2, u'__crc__': 6, '__cc__': False, u'__count__': 3, u'key': datastore_types.Key.from_path(u'TestModel', '5', _app=u'fantasm'), 'data': {'a': 'b'}, u'__step__': 1, u'__ix__': 1},616 {u'__crs__': 2, u'__crc__': 6, '__cc__': False, u'__count__': 3, u'key': datastore_types.Key.from_path(u'TestModel', '4', _app=u'fantasm'), 'data': {'a': 'b'}, u'__step__': 1, u'__ix__': 1},617 {u'__crs__': 2, u'__crc__': 8, '__cc__': False, u'__count__': 4, u'key': datastore_types.Key.from_path(u'TestModel', '7', _app=u'fantasm'), 'data': {'a': 'b'}, u'__step__': 1, u'__ix__': 1},618 {u'__crs__': 2, u'__crc__': 8, '__cc__': False, u'__count__': 4, u'key': datastore_types.Key.from_path(u'TestModel', '6', _app=u'fantasm'), 'data': {'a': 'b'}, u'__step__': 1, u'__ix__': 1},619 {u'__crs__': 2, u'__crc__': 10, '__cc__': False, u'__count__': 5, u'key': datastore_types.Key.from_path(u'TestModel', '9', _app=u'fantasm'), 'data': {'a': 'b'}, u'__step__': 1, u'__ix__': 1},620 {u'__crs__': 2, u'__crc__': 10, '__cc__': False, u'__count__': 5, u'key': datastore_types.Key.from_path(u'TestModel', '8', _app=u'fantasm'), 'data': {'a': 'b'}, u'__step__': 1, u'__ix__': 1},621 {u'__crs__': 2, u'__crc__': 2, '__cc__': False, u'__count__': 1, u'key': datastore_types.Key.from_path(u'TestModel', '1', _app=u'fantasm'), 'data': {'a': 'b'}, u'__step__': 1, u'__ix__': 1},622 {u'__crs__': 2, u'__crc__': 2, '__cc__': False, u'__count__': 1, u'key': datastore_types.Key.from_path(u'TestModel','0', _app=u'fantasm'), 'data': {'a': 'b'}, u'__step__': 1, u'__ix__': 1}], CountExecuteCallsFanIn.CONTEXTS)623class RunTasksTests_DatastoreFSMContinuationFanInAndForkTests_POST(624 RunTasksTests_DatastoreFSMContinuationFanInAndForkTests):625 METHOD = 'POST'626class RunTasksTests_DatastoreFSMContinuationTestsInitCont(RunTasksBaseTest):627 FILENAME = 'test-DatastoreFSMContinuationTests.yaml'628 MACHINE_NAME = 'DatastoreFSMContinuationTestsInitCont'629 def test_DatastoreFSMContinuationTestsInitCont(self):630 self.context.initialize() # queues the first task631 ran = runQueuedTasks(queueName=self.context.queueName)632 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-continuation--step-0',633 'instanceName--continuation-0-1--pseudo-init--pseudo-init--state-continuation--step-0',634 'instanceName--state-continuation--next-event--state-final--step-1',635 'instanceName--continuation-0-2--pseudo-init--pseudo-init--state-continuation--step-0',636 'instanceName--continuation-0-1--state-continuation--next-event--state-final--step-1',637 'instanceName--continuation-0-3--pseudo-init--pseudo-init--state-continuation--step-0',638 'instanceName--continuation-0-2--state-continuation--next-event--state-final--step-1',639 'instanceName--continuation-0-4--pseudo-init--pseudo-init--state-continuation--step-0',640 'instanceName--continuation-0-3--state-continuation--next-event--state-final--step-1',641 'instanceName--continuation-0-5--pseudo-init--pseudo-init--state-continuation--step-0',642 'instanceName--continuation-0-4--state-continuation--next-event--state-final--step-1'], ran)643 self.assertEqual({'state-continuation': {'entry': 6, 'action': 5, 'continuation': 6, 'exit': 0},644 'state-final': {'entry': 5, 'action': 5, 'exit': 0},645 'state-continuation--next-event': {'action': 0}},646 getCounts(self.machineConfig))647class RunTasksTests_DatastoreFSMContinuationTestsInitCont_POST(RunTasksTests_DatastoreFSMContinuationTestsInitCont):648 method = 'POST'649class RunTasksTests_NDBDatastoreFSMContinuationTestsInitCont(RunTasksBaseTest):650 FILENAME = 'test-NDBDatastoreFSMContinuationTests.yaml'651 MACHINE_NAME = 'NDBDatastoreFSMContinuationTestsInitCont'652 def test_NDBDatastoreFSMContinuationTestsInitCont(self):653 self.context.initialize() # queues the first task654 ran = runQueuedTasks(queueName=self.context.queueName)655 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-continuation--step-0',656 'instanceName--continuation-0-1--pseudo-init--pseudo-init--state-continuation--step-0',657 'instanceName--state-continuation--next-event--state-final--step-1',658 'instanceName--continuation-0-2--pseudo-init--pseudo-init--state-continuation--step-0',659 'instanceName--continuation-0-1--state-continuation--next-event--state-final--step-1',660 'instanceName--continuation-0-3--pseudo-init--pseudo-init--state-continuation--step-0',661 'instanceName--continuation-0-2--state-continuation--next-event--state-final--step-1',662 'instanceName--continuation-0-4--pseudo-init--pseudo-init--state-continuation--step-0',663 'instanceName--continuation-0-3--state-continuation--next-event--state-final--step-1',664 'instanceName--continuation-0-4--state-continuation--next-event--state-final--step-1'], ran)665 self.assertEqual({'state-continuation': {'entry': 5, 'action': 5, 'continuation': 5, 'exit': 0},666 'state-final': {'entry': 5, 'action': 5, 'exit': 0},667 'state-continuation--next-event': {'action': 0}},668 getCounts(self.machineConfig))669class RunTasksTests_NDBDatastoreFSMContinuationTestsInitCont_POST(RunTasksTests_NDBDatastoreFSMContinuationTestsInitCont):670 method = 'POST'671class RunTasksTests_DatastoreFSMContinuationFanInTests(RunTasksBaseTest):672 FILENAME = 'test-DatastoreFSMContinuationFanInTests.yaml'673 MACHINE_NAME = 'DatastoreFSMContinuationFanInTests'674 def setUp(self):675 super(RunTasksTests_DatastoreFSMContinuationFanInTests, self).setUp()676 CountExecuteCallsFanIn.CONTEXTS = []677 def tearDown(self):678 super(RunTasksTests_DatastoreFSMContinuationFanInTests, self).tearDown()679 CountExecuteCallsFanIn.CONTEXTS = []680 def test_DatastoreFSMContinuationFanInTests(self):681 # FIXME: this test is non-deterministic based on time.time in _queueDispatchFanIn682 self.context.initialize() # queues the first task683 ran = runQueuedTasks(queueName=self.context.queueName)684 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',685 'instanceName--state-initial--next-event--state-continuation--step-1',686 'instanceName--continuation-1-1--state-initial--next-event--state-continuation--step-1',687 'instanceName--continuation-1-2--state-initial--next-event--state-continuation--step-1',688 'instanceName--continuation-1-3--state-initial--next-event--state-continuation--step-1',689 'instanceName--continuation-1-4--state-initial--next-event--state-continuation--step-1',690 'instanceName--continuation-1-5--state-initial--next-event--state-continuation--step-1',691 'instanceName--state-continuation--next-event--state-fan-in--step-2-1',692 'instanceName--work-index-1--state-fan-in--next-event--state-final--step-3'], ran)693 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 0},694 'state-continuation': {'entry': 6, 'action': 5, 'continuation': 6, 'exit': 0},695 'state-fan-in': {'entry': 1, 'action': 1, 'exit': 0,696 'fan-in-entry': 5, 'fan-in-action': 5, 'fan-in-exit': 0},697 'state-final': {'entry': 1, 'action': 1, 'exit': 0},698 'state-initial--next-event': {'action': 0},699 'state-continuation--next-event': {'action': 0},700 'state-fan-in--next-event': {'action': 0}},701 getCounts(self.machineConfig))702 # pylint: disable=C0301703 self.assertEqual([{u'__crs__': 2, u'__crc__': 4, '__cc__': False, u'__ix__': 1, u'__count__': 2, u'__step__': 2, 'fan-me-in': [datastore_types.Key.from_path(u'TestModel', u'2', _app=u'fantasm'), datastore_types.Key.from_path(u'TestModel', u'3', _app=u'fantasm')]},704 {u'__crs__': 2, u'__crc__': 6, '__cc__': False, u'__ix__': 1, u'__count__': 3, u'__step__': 2, 'fan-me-in': [datastore_types.Key.from_path(u'TestModel', u'4', _app=u'fantasm'), datastore_types.Key.from_path(u'TestModel', u'5', _app=u'fantasm')]},705 {u'__crs__': 2, u'__crc__': 8, '__cc__': False, u'__ix__': 1, u'__count__': 4, u'__step__': 2, 'fan-me-in': [datastore_types.Key.from_path(u'TestModel', u'6', _app=u'fantasm'), datastore_types.Key.from_path(u'TestModel', u'7', _app=u'fantasm')]},706 {u'__crs__': 2, u'__crc__': 10, '__cc__': False, u'__ix__': 1, u'__count__': 5, u'__step__': 2, 'fan-me-in': [datastore_types.Key.from_path(u'TestModel', u'8', _app=u'fantasm'), datastore_types.Key.from_path(u'TestModel', u'9', _app=u'fantasm')]},707 {u'__crs__': 2, u'__crc__': 2, '__cc__': False, u'__ix__': 1, u'__count__': 1, u'__step__': 2, 'fan-me-in': [datastore_types.Key.from_path(u'TestModel', u'0', _app=u'fantasm'), datastore_types.Key.from_path(u'TestModel', u'1', _app=u'fantasm')]}], CountExecuteCallsFanIn.CONTEXTS)708 self.assertEqual(0, _FantasmFanIn.all(namespace='').count())709 self.assertEqual(10, ResultModel.get_by_key_name(self.context.instanceName).total)710class RunTasksTests_DatastoreFSMContinuationFanInTests_POST(RunTasksTests_DatastoreFSMContinuationFanInTests):711 METHOD = 'POST'712class RunTasksTests_DatastoreFSMContinuationFanInGroupDefaultTests(RunTasksBaseTest):713 FILENAME = 'test-DatastoreFSMContinuationFanInTests.yaml'714 MACHINE_NAME = 'DatastoreFSMContinuationFanInGroupDefaultTests'715 def setUp(self):716 super(RunTasksTests_DatastoreFSMContinuationFanInGroupDefaultTests, self).setUp()717 CountExecuteCallsFanIn.CONTEXTS = []718 def tearDown(self):719 super(RunTasksTests_DatastoreFSMContinuationFanInGroupDefaultTests, self).tearDown()720 CountExecuteCallsFanIn.CONTEXTS = []721 def test_DatastoreFSMContinuationFanInTests(self):722 # FIXME: this test is non-deterministic based on time.time in _queueDispatchFanIn723 self.context.initialize() # queues the first task724 ran = runQueuedTasks(queueName=self.context.queueName)725 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',726 'instanceName--state-initial--next-event--state-continuation--step-1',727 'instanceName--continuation-1-1--state-initial--next-event--state-continuation--step-1',728 'instanceName--continuation-1-2--state-initial--next-event--state-continuation--step-1',729 'instanceName--continuation-1-3--state-initial--next-event--state-continuation--step-1',730 'instanceName--continuation-1-4--state-initial--next-event--state-continuation--step-1',731 'instanceName--continuation-1-5--state-initial--next-event--state-continuation--step-1',732 'instanceName--state-continuation--next-event--state-fan-in--step-2-1',733 'instanceName--work-index-1--state-fan-in--next-event--state-final--step-3'], ran)734 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 0},735 'state-continuation': {'entry': 6, 'action': 5, 'continuation': 6, 'exit': 0},736 'state-fan-in': {'entry': 1, 'action': 1, 'exit': 0,737 'fan-in-entry': 5, 'fan-in-action': 5, 'fan-in-exit': 0},738 'state-final': {'entry': 1, 'action': 1, 'exit': 0},739 'state-initial--next-event': {'action': 0},740 'state-continuation--next-event': {'action': 0},741 'state-fan-in--next-event': {'action': 0}},742 getCounts(self.machineConfig))743class RunTasksTests_DatastoreFSMContinuationFanInGroupDefaultTests_POST(744 RunTasksTests_DatastoreFSMContinuationFanInGroupDefaultTests):745 METHOD = 'POST'746class RunTasksTests_DatastoreFSMContinuationFanInGroupTests(RunTasksBaseTest):747 FILENAME = 'test-DatastoreFSMContinuationFanInTests.yaml'748 MACHINE_NAME = 'DatastoreFSMContinuationFanInGroupTests'749 def setUp(self):750 super(RunTasksTests_DatastoreFSMContinuationFanInGroupTests, self).setUp()751 CountExecuteCallsFanIn.CONTEXTS = []752 def tearDown(self):753 super(RunTasksTests_DatastoreFSMContinuationFanInGroupTests, self).tearDown()754 CountExecuteCallsFanIn.CONTEXTS = []755 def test_DatastoreFSMContinuationFanInTests(self):756 # FIXME: this test is non-deterministic based on time.time in _queueDispatchFanIn757 self.context.initialize() # queues the first task758 ran = runQueuedTasks(queueName=self.context.queueName)759 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',760 'instanceName--state-initial--next-event--state-continuation--step-1',761 'instanceName--continuation-1-1--state-initial--next-event--state-continuation--step-1',762 'instanceName--continuation-1-2--state-initial--next-event--state-continuation--step-1',763 'instanceName--continuation-1-3--state-initial--next-event--state-continuation--step-1',764 'instanceName--continuation-1-4--state-initial--next-event--state-continuation--step-1',765 'instanceName--continuation-1-5--state-initial--next-event--state-continuation--step-1',766 'instanceName--state-continuation--next-event--state-fan-in--step-2--group-0-1',767 'instanceName--work-index-1--state-fan-in--next-event--state-final--step-3--group-0',768 'instanceName--state-continuation--next-event--state-fan-in--step-2--group-2-1',769 'instanceName--work-index-1--state-fan-in--next-event--state-final--step-3--group-2',770 'instanceName--state-continuation--next-event--state-fan-in--step-2--group-4-1',771 'instanceName--work-index-1--state-fan-in--next-event--state-final--step-3--group-4',772 'instanceName--state-continuation--next-event--state-fan-in--step-2--group-6-1',773 'instanceName--work-index-1--state-fan-in--next-event--state-final--step-3--group-6',774 'instanceName--state-continuation--next-event--state-fan-in--step-2--group-8-1',775 'instanceName--work-index-1--state-fan-in--next-event--state-final--step-3--group-8'], ran)776 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 0},777 'state-continuation': {'entry': 6, 'action': 5, 'continuation': 6, 'exit': 0},778 'state-fan-in': {'entry': 5, 'action': 5, 'exit': 0,779 'fan-in-entry': 5, 'fan-in-action': 5, 'fan-in-exit': 0},780 'state-final': {'entry': 5, 'action': 5, 'exit': 0},781 'state-initial--next-event': {'action': 0},782 'state-continuation--next-event': {'action': 0},783 'state-fan-in--next-event': {'action': 0}},784 getCounts(self.machineConfig))785class RunTasksTests_DatastoreFSMContinuationFanInGroupTests_POST(RunTasksTests_DatastoreFSMContinuationFanInGroupTests):786 METHOD = 'POST'787class RunTasksTests_DatastoreFSMContinuationFanInTests_memcache_problems(RunTasksBaseTest):788 FILENAME = 'test-DatastoreFSMContinuationFanInTests.yaml'789 MACHINE_NAME = 'DatastoreFSMContinuationFanInTests'790 def setUp(self):791 super(RunTasksTests_DatastoreFSMContinuationFanInTests_memcache_problems, self).setUp()792 self.loggingDouble = getLoggingDouble()793 class BreakReadLock( object ):794 def execute(self, context, obj):795 from google.appengine.api import memcache796 lockKey = 'instanceName--state-continuation--next-event--state-fan-in--step-2-lock-1'797 memcache.set(lockKey, 2**64)798 self.context.currentState.getTransition(FSM.PSEUDO_INIT) \799 .target.getTransition('next-event') \800 .target.exitAction = BreakReadLock()801 CountExecuteCallsFanIn.CONTEXTS = []802 ReadWriteLock._BUSY_WAIT_ITER_SECS = ReadWriteLock.BUSY_WAIT_ITERS803 ReadWriteLock.BUSY_WAIT_ITER_SECS = 0804 ReadWriteLock._BUSY_WAIT_ITERS = ReadWriteLock.BUSY_WAIT_ITERS805 ReadWriteLock.BUSY_WAIT_ITERS = 2806 def tearDown(self):807 super(RunTasksTests_DatastoreFSMContinuationFanInTests_memcache_problems, self).tearDown()808 CountExecuteCallsFanIn.CONTEXTS = []809 ReadWriteLock.BUSY_WAIT_ITER_SECS = ReadWriteLock._BUSY_WAIT_ITER_SECS810 ReadWriteLock.BUSY_WAIT_ITERS = ReadWriteLock._BUSY_WAIT_ITERS811 def test_DatastoreFSMContinuationFanInTests(self):812 # FIXME: this test is non-deterministic based on time.time in _queueDispatchFanIn813 self.context.initialize() # queues the first task814 ran = runQueuedTasks(queueName=self.context.queueName)815 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',816 'instanceName--state-initial--next-event--state-continuation--step-1',817 'instanceName--continuation-1-1--state-initial--next-event--state-continuation--step-1',818 'instanceName--continuation-1-2--state-initial--next-event--state-continuation--step-1',819 'instanceName--continuation-1-3--state-initial--next-event--state-continuation--step-1',820 'instanceName--continuation-1-4--state-initial--next-event--state-continuation--step-1',821 'instanceName--continuation-1-5--state-initial--next-event--state-continuation--step-1',822 'instanceName--continuation-1-5--state-continuation--pseudo-final--pseudo-final--step-2', #???823 'instanceName--state-continuation--next-event--state-fan-in--step-2-1',824 'instanceName--state-continuation--next-event--state-fan-in--step-2-1',825 'instanceName--state-continuation--next-event--state-fan-in--step-2-1',826 'instanceName--state-continuation--next-event--state-fan-in--step-2-1',827 'instanceName--state-continuation--next-event--state-fan-in--step-2-1',828 'instanceName--state-continuation--next-event--state-fan-in--step-2-1',829 'instanceName--work-index-1--state-fan-in--next-event--state-final--step-3'], ran)830 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 0},831 'state-continuation': {'entry': 6, 'action': 5, 'continuation': 6, 'exit': 0},832 'state-fan-in': {'entry': 1, 'action': 1, 'exit': 0,833 'fan-in-entry': 5, 'fan-in-action': 5, 'fan-in-exit': 0},834 'state-final': {'entry': 1, 'action': 1, 'exit': 0},835 'state-initial--next-event': {'action': 0},836 'state-continuation--next-event': {'action': 0},837 'state-fan-in--next-event': {'action': 0}},838 getCounts(self.machineConfig))839 # pylint: disable=C0301840 self.assertEqual(["Gave up waiting for all fan-in work items with read lock 'instanceName--state-continuation--next-event--state-fan-in--step-2-lock-1'.",841 "Gave up waiting for all fan-in work items with read lock 'instanceName--state-continuation--next-event--state-fan-in--step-2-lock-1'.",842 "Gave up waiting for all fan-in work items with read lock 'instanceName--state-continuation--next-event--state-fan-in--step-2-lock-1'.",843 "Gave up waiting for all fan-in work items with read lock 'instanceName--state-continuation--next-event--state-fan-in--step-2-lock-1'.",844 "Gave up waiting for all fan-in work items with read lock 'instanceName--state-continuation--next-event--state-fan-in--step-2-lock-1'.",845 "Gave up waiting for all fan-in work items with read lock 'instanceName--state-continuation--next-event--state-fan-in--step-2-lock-1'."], self.loggingDouble.messages['critical'])846 # pylint: disable=C0301847 self.assertEqual([{u'__crs__': 2, u'__crc__': 4, u'__cc__': False, u'__ix__': 1, u'__count__': 2, u'__step__': 2, 'fan-me-in': [datastore_types.Key.from_path(u'TestModel', u'2', _app=u'fantasm'), datastore_types.Key.from_path(u'TestModel', u'3', _app=u'fantasm')]},848 {u'__crs__': 2, u'__crc__': 6, u'__cc__': False, u'__ix__': 1, u'__count__': 3, u'__step__': 2, 'fan-me-in': [datastore_types.Key.from_path(u'TestModel', u'4', _app=u'fantasm'), datastore_types.Key.from_path(u'TestModel', u'5', _app=u'fantasm')]},849 {u'__crs__': 2, u'__crc__': 8, u'__cc__': False, u'__ix__': 1, u'__count__': 4, u'__step__': 2, 'fan-me-in': [datastore_types.Key.from_path(u'TestModel', u'6', _app=u'fantasm'), datastore_types.Key.from_path(u'TestModel', u'7', _app=u'fantasm')]},850 {u'__crs__': 2, u'__crc__': 10, u'__cc__': False, u'__ix__': 1, u'__count__': 5, u'__step__': 2, 'fan-me-in': [datastore_types.Key.from_path(u'TestModel', u'8', _app=u'fantasm'), datastore_types.Key.from_path(u'TestModel', u'9', _app=u'fantasm')]},851 {u'__crs__': 2, u'__crc__': 2, u'__cc__': False, u'__ix__': 1, u'__count__': 1, u'__step__': 2, 'fan-me-in': [datastore_types.Key.from_path(u'TestModel', u'0', _app=u'fantasm'), datastore_types.Key.from_path(u'TestModel', u'1', _app=u'fantasm')]}], CountExecuteCallsFanIn.CONTEXTS)852 self.assertEqual(0, _FantasmFanIn.all(namespace='').count())853 self.assertEqual(10, ResultModel.get_by_key_name(self.context.instanceName).total)854class RunTasksTests_DatastoreFSMContinuationFanInTests__memcache_problems_POST(855 RunTasksTests_DatastoreFSMContinuationFanInTests_memcache_problems):856 METHOD = 'POST'857class RunTasksTests_DatastoreFSMContinuationFanInTests_fail_post_fan_in(RunTasksBaseTest):858 FILENAME = 'test-DatastoreFSMContinuationFanInTests.yaml'859 MACHINE_NAME = 'DatastoreFSMContinuationFanInTests'860 def setUp(self):861 super(RunTasksTests_DatastoreFSMContinuationFanInTests_fail_post_fan_in, self).setUp()862 CountExecuteCallsFanIn.CONTEXTS = []863 ReadWriteLock._BUSY_WAIT_ITER_SECS = ReadWriteLock.BUSY_WAIT_ITERS864 ReadWriteLock.BUSY_WAIT_ITER_SECS = 0865 ReadWriteLock._BUSY_WAIT_ITERS = ReadWriteLock.BUSY_WAIT_ITERS866 ReadWriteLock.BUSY_WAIT_ITERS = 2867 self.context['UNITTEST_RAISE_AFTER_FAN_IN'] = True868 def tearDown(self):869 super(RunTasksTests_DatastoreFSMContinuationFanInTests_fail_post_fan_in, self).tearDown()870 CountExecuteCallsFanIn.CONTEXTS = []871 ReadWriteLock.BUSY_WAIT_ITER_SECS = ReadWriteLock._BUSY_WAIT_ITER_SECS872 ReadWriteLock.BUSY_WAIT_ITERS = ReadWriteLock._BUSY_WAIT_ITERS873 def test_DatastoreFSMContinuationFanInTests(self):874 # FIXME: this test is non-deterministic based on time.time in _queueDispatchFanIn875 self.context.initialize() # queues the first task876 ran = runQueuedTasks(queueName=self.context.queueName)877 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',878 'instanceName--state-initial--next-event--state-continuation--step-1',879 'instanceName--continuation-1-1--state-initial--next-event--state-continuation--step-1',880 'instanceName--continuation-1-2--state-initial--next-event--state-continuation--step-1',881 'instanceName--continuation-1-3--state-initial--next-event--state-continuation--step-1',882 'instanceName--continuation-1-4--state-initial--next-event--state-continuation--step-1',883 'instanceName--continuation-1-5--state-initial--next-event--state-continuation--step-1',884 'instanceName--state-continuation--next-event--state-fan-in--step-2-1',885 'instanceName--state-continuation--next-event--state-fan-in--step-2-1',886 'instanceName--work-index-1--state-fan-in--next-event--state-final--step-3'], ran)887 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 0},888 'state-continuation': {'entry': 6, 'action': 5, 'continuation': 6, 'exit': 0},889 'state-fan-in': {'entry': 2, 'action': 2, 'exit': 0,890 'fan-in-entry': 5, 'fan-in-action': 5, 'fan-in-exit': 0},891 'state-final': {'entry': 1, 'action': 1, 'exit': 0},892 'state-initial--next-event': {'action': 0},893 'state-continuation--next-event': {'action': 0},894 'state-fan-in--next-event': {'action': 0}},895 getCounts(self.machineConfig))896 self.assertEqual(10, ResultModel.get_by_key_name(self.context.instanceName).total)897class RunTasksTests_DatastoreFSMContinuationFanInTests_fail_post_fan_in_POST(898 RunTasksTests_DatastoreFSMContinuationFanInTests_fail_post_fan_in):899 METHOD = 'POST'900class RunTasksTests_DatastoreFSMContinuationFanInDiamondTests(RunTasksBaseTest):901 FILENAME = 'test-DatastoreFSMContinuationFanInTests.yaml'902 MACHINE_NAME = 'DatastoreFSMContinuationFanInDiamondTests'903 def test_DatastoreFSMContinuationFanInDiamondTests(self):904 # FIXME: this test is non-deterministic based on time.time in _queueDispatchFanIn905 self.context.initialize() # queues the first task906 ran = runQueuedTasks(queueName=self.context.queueName)907 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-continuation--step-0',908 'instanceName--continuation-0-1--pseudo-init--pseudo-init--state-continuation--step-0',909 'instanceName--state-continuation--happy--state-happy--step-1',910 'instanceName--continuation-0-2--pseudo-init--pseudo-init--state-continuation--step-0',911 'instanceName--continuation-0-1--state-continuation--sad--state-sad--step-1',912 'instanceName--continuation-0-3--pseudo-init--pseudo-init--state-continuation--step-0',913 'instanceName--continuation-0-2--state-continuation--happy--state-happy--step-1',914 'instanceName--continuation-0-4--pseudo-init--pseudo-init--state-continuation--step-0',915 'instanceName--continuation-0-3--state-continuation--sad--state-sad--step-1',916 'instanceName--continuation-0-5--pseudo-init--pseudo-init--state-continuation--step-0',917 'instanceName--continuation-0-4--state-continuation--happy--state-happy--step-1',918 'instanceName--state-happy--next-event--state-fan-in--step-2-1',919 'instanceName--state-sad--next-event--state-fan-in--step-2-1'], ran)920 self.assertEqual({'state-continuation': {'entry': 6, 'continuation': 6, 'action': 5, 'exit': 0},921 'state-happy': {'entry': 3, 'action': 3, 'exit': 0},922 'state-sad': {'entry': 2, 'action': 2, 'exit': 0},923 'state-fan-in': {'entry': 2, 'action': 2, 'exit': 0,924 'fan-in-entry': 5, 'fan-in-action': 5, 'fan-in-exit': 0},925 'state-continuation--happy': {'action': 0},926 'state-continuation--sad': {'action': 0},927 'state-happy--next-event': {'action': 0},928 'state-sad--next-event': {'action': 0}},929 getCounts(self.machineConfig))930class RunTasksTests_DatastoreFSMContinuationFanInDiamondTests_POST(931 RunTasksTests_DatastoreFSMContinuationFanInDiamondTests):932 METHOD = 'POST'933class RunTasksTests_DatastoreFSMContinuationFanInTestsInitCont(RunTasksBaseTest):934 FILENAME = 'test-DatastoreFSMContinuationFanInTests.yaml'935 MACHINE_NAME = 'DatastoreFSMContinuationFanInTestsInitCont'936 def test_DatastoreFSMContinuationFanInTests(self):937 # FIXME: this test is non-deterministic based on time.time in _queueDispatchFanIn938 self.context.initialize() # queues the first task939 ran = runQueuedTasks(queueName=self.context.queueName)940 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-continuation--step-0',941 'instanceName--continuation-0-1--pseudo-init--pseudo-init--state-continuation--step-0',942 'instanceName--continuation-0-2--pseudo-init--pseudo-init--state-continuation--step-0',943 'instanceName--continuation-0-3--pseudo-init--pseudo-init--state-continuation--step-0',944 'instanceName--continuation-0-4--pseudo-init--pseudo-init--state-continuation--step-0',945 'instanceName--continuation-0-5--pseudo-init--pseudo-init--state-continuation--step-0',946 'instanceName--state-continuation--next-event--state-fan-in--step-1-1',947 'instanceName--work-index-1--state-fan-in--next-event--state-final--step-2'], ran)948 self.assertEqual({'state-continuation': {'entry': 6, 'action': 5, 'continuation': 6, 'exit': 0},949 'state-fan-in': {'entry': 1, 'action': 1, 'exit': 0,950 'fan-in-entry': 5, 'fan-in-action': 5, 'fan-in-exit': 0},951 'state-final': {'entry': 1, 'action': 1, 'exit': 0},952 'state-continuation--next-event': {'action': 0},953 'state-fan-in--next-event': {'action': 0}},954 getCounts(self.machineConfig))955class RunTasksTests_DatastoreFSMContinuationFanInTestsInitCont_POST(956 RunTasksTests_DatastoreFSMContinuationFanInTestsInitCont):957 METHOD = 'POST'958class RunTasksTests_DatastoreFSMContinuationNoFinalAction(RunTasksBaseTest):959 FILENAME = 'test-DatastoreFSMContinuationFanInTests.yaml'960 MACHINE_NAME = 'DatastoreFSMContinuationNoFinalAction'961 def test_DatastoreFSMContinuationFanInTests(self):962 # FIXME: this test is non-deterministic based on time.time in _queueDispatchFanIn963 self.context.initialize() # queues the first task964 ran = runQueuedTasks(queueName=self.context.queueName)965 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-continuation--step-0',966 'instanceName--continuation-0-1--pseudo-init--pseudo-init--state-continuation--step-0',967 'instanceName--continuation-0-2--pseudo-init--pseudo-init--state-continuation--step-0',968 'instanceName--continuation-0-3--pseudo-init--pseudo-init--state-continuation--step-0',969 'instanceName--continuation-0-4--pseudo-init--pseudo-init--state-continuation--step-0',970 'instanceName--continuation-0-5--pseudo-init--pseudo-init--state-continuation--step-0',971 'instanceName--state-continuation--next-event--state-fan-in--step-1-1',972 'instanceName--work-index-1--state-fan-in--next-event--state-final--step-2',973 'instanceName--work-index-1--state-final--pseudo-final--pseudo-final--step-3'], ran)974 self.assertEqual({'state-continuation': {'entry': 6, 'action': 5, 'continuation': 6, 'exit': 0},975 'state-fan-in': {'entry': 1, 'action': 1, 'exit': 0,976 'fan-in-entry': 5, 'fan-in-action': 5, 'fan-in-exit': 0},977 'state-final': {'entry': 1, 'action': 0, 'exit': 1},978 'state-continuation--next-event': {'action': 0},979 'state-fan-in--next-event': {'action': 0}},980 getCounts(self.machineConfig))981class RunTasksTests_DatastoreFSMContinuationFanInTestsInitContNoFinalAction_POST(982 RunTasksTests_DatastoreFSMContinuationNoFinalAction):983 METHOD = 'POST'984class RunTasksWithFailuresTests_TaskQueueFSMTests(RunTasksBaseTest):985 FILENAME = 'test-TaskQueueFSMTests.yaml'986 MACHINE_NAME = 'TaskQueueFSMTests'987 def test_TaskQueueFSMTests_initial_state_entry(self):988 overrideFails(self.machineConfig, [('state-initial', 'entry', 1)], [])989 self.context.initialize() # queues the first task990 ran = runQueuedTasks(queueName=self.context.queueName)991 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',992 'instanceName--pseudo-init--pseudo-init--state-initial--step-0',993 'instanceName--state-initial--next-event--state-normal--step-1',994 'instanceName--state-normal--next-event--state-final--step-2'], ran)995 self.assertEqual({'state-initial': {'entry': 2, 'action': 1, 'exit': 1},996 'state-normal': {'entry': 1, 'action': 1, 'exit': 1},997 'state-final': {'entry': 1, 'action': 1, 'exit': 0},998 'state-initial--next-event': {'action': 1},999 'state-normal--next-event': {'action': 1}},1000 getCounts(self.machineConfig))1001 def test_TaskQueueFSMTests_initial_state_do(self):1002 overrideFails(self.machineConfig, [('state-initial', 'action', 1)], [])1003 self.context.initialize() # queues the first task1004 ran = runQueuedTasks(queueName=self.context.queueName)1005 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',1006 'instanceName--pseudo-init--pseudo-init--state-initial--step-0',1007 'instanceName--state-initial--next-event--state-normal--step-1',1008 'instanceName--state-normal--next-event--state-final--step-2'], ran)1009 self.assertEqual({'state-initial': {'entry': 2, 'action': 2, 'exit': 1},1010 'state-normal': {'entry': 1, 'action': 1, 'exit': 1},1011 'state-final': {'entry': 1, 'action': 1, 'exit': 0},1012 'state-initial--next-event': {'action': 1},1013 'state-normal--next-event': {'action': 1}},1014 getCounts(self.machineConfig))1015 def test_TaskQueueFSMTests_initial_state_exit(self):1016 overrideFails(self.machineConfig, [('state-initial', 'exit', 1)], [])1017 self.context.initialize() # queues the first task1018 ran = runQueuedTasks(queueName=self.context.queueName)1019 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',1020 'instanceName--state-initial--next-event--state-normal--step-1',1021 'instanceName--state-initial--next-event--state-normal--step-1',1022 'instanceName--state-normal--next-event--state-final--step-2'], ran)1023 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 2},1024 'state-normal': {'entry': 1, 'action': 1, 'exit': 1},1025 'state-final': {'entry': 1, 'action': 1, 'exit': 0},1026 'state-initial--next-event': {'action': 1},1027 'state-normal--next-event': {'action': 1}},1028 getCounts(self.machineConfig))1029 def test_TaskQueueFSMTests_normal_state_entry(self):1030 overrideFails(self.machineConfig, [('state-normal', 'entry', 1)], [])1031 self.context.initialize() # queues the first task1032 ran = runQueuedTasks(queueName=self.context.queueName)1033 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',1034 'instanceName--state-initial--next-event--state-normal--step-1',1035 'instanceName--state-initial--next-event--state-normal--step-1',1036 'instanceName--state-normal--next-event--state-final--step-2'], ran)1037 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 2},1038 'state-normal': {'entry': 2, 'action': 1, 'exit': 1},1039 'state-final': {'entry': 1, 'action': 1, 'exit': 0},1040 'state-initial--next-event': {'action': 2},1041 'state-normal--next-event': {'action': 1}},1042 getCounts(self.machineConfig))1043 def test_TaskQueueFSMTests_normal_state_do(self):1044 overrideFails(self.machineConfig, [('state-normal', 'action', 1)], [])1045 self.context.initialize() # queues the first task1046 ran = runQueuedTasks(queueName=self.context.queueName)1047 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',1048 'instanceName--state-initial--next-event--state-normal--step-1',1049 'instanceName--state-initial--next-event--state-normal--step-1',1050 'instanceName--state-normal--next-event--state-final--step-2'], ran)1051 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 2},1052 'state-normal': {'entry': 2, 'action': 2, 'exit': 1},1053 'state-final': {'entry': 1, 'action': 1, 'exit': 0},1054 'state-initial--next-event': {'action': 2},1055 'state-normal--next-event': {'action': 1}},1056 getCounts(self.machineConfig))1057 def test_TaskQueueFSMTests_normal_state_exit(self):1058 overrideFails(self.machineConfig, [('state-normal', 'exit', 1)], [])1059 self.context.initialize() # queues the first task1060 ran = runQueuedTasks(queueName=self.context.queueName)1061 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',1062 'instanceName--state-initial--next-event--state-normal--step-1',1063 'instanceName--state-normal--next-event--state-final--step-2',1064 'instanceName--state-normal--next-event--state-final--step-2'], ran)1065 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 1},1066 'state-normal': {'entry': 1, 'action': 1, 'exit': 2},1067 'state-final': {'entry': 1, 'action': 1, 'exit': 0},1068 'state-initial--next-event': {'action': 1},1069 'state-normal--next-event': {'action': 1}},1070 getCounts(self.machineConfig))1071 def test_TaskQueueFSMTests_final_state_entry(self):1072 overrideFails(self.machineConfig, [('state-final', 'entry', 1)], [])1073 self.context.initialize() # queues the first task1074 ran = runQueuedTasks(queueName=self.context.queueName)1075 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',1076 'instanceName--state-initial--next-event--state-normal--step-1',1077 'instanceName--state-normal--next-event--state-final--step-2',1078 'instanceName--state-normal--next-event--state-final--step-2'], ran)1079 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 1},1080 'state-normal': {'entry': 1, 'action': 1, 'exit': 2},1081 'state-final': {'entry': 2, 'action': 1, 'exit': 0},1082 'state-initial--next-event': {'action': 1},1083 'state-normal--next-event': {'action': 2}},1084 getCounts(self.machineConfig))1085 def test_TaskQueueFSMTests_final_state_do(self):1086 overrideFails(self.machineConfig, [('state-final', 'action', 1)], [])1087 self.context.initialize() # queues the first task1088 ran = runQueuedTasks(queueName=self.context.queueName)1089 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',1090 'instanceName--state-initial--next-event--state-normal--step-1',1091 'instanceName--state-normal--next-event--state-final--step-2',1092 'instanceName--state-normal--next-event--state-final--step-2'], ran)1093 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 1},1094 'state-normal': {'entry': 1, 'action': 1, 'exit': 2},1095 'state-final': {'entry': 2, 'action': 2, 'exit': 0},1096 'state-initial--next-event': {'action': 1},1097 'state-normal--next-event': {'action': 2}},1098 getCounts(self.machineConfig))1099 def test_TaskQueueFSMTests_initial_state_next_event(self):1100 overrideFails(self.machineConfig, [], [('state-initial--next-event', 1)])1101 self.context.initialize() # queues the first task1102 ran = runQueuedTasks(queueName=self.context.queueName)1103 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',1104 'instanceName--state-initial--next-event--state-normal--step-1',1105 'instanceName--state-initial--next-event--state-normal--step-1',1106 'instanceName--state-normal--next-event--state-final--step-2'], ran)1107 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 2},1108 'state-normal': {'entry': 1, 'action': 1, 'exit': 1},1109 'state-final': {'entry': 1, 'action': 1, 'exit': 0},1110 'state-initial--next-event': {'action': 2},1111 'state-normal--next-event': {'action': 1}},1112 getCounts(self.machineConfig))1113 def test_TaskQueueFSMTests_normal_state_next_event(self):1114 overrideFails(self.machineConfig, [], [('state-normal--next-event', 1)])1115 self.context.initialize() # queues the first task1116 ran = runQueuedTasks(queueName=self.context.queueName)1117 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',1118 'instanceName--state-initial--next-event--state-normal--step-1',1119 'instanceName--state-normal--next-event--state-final--step-2',1120 'instanceName--state-normal--next-event--state-final--step-2'], ran)1121 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 1},1122 'state-normal': {'entry': 1, 'action': 1, 'exit': 2},1123 'state-final': {'entry': 1, 'action': 1, 'exit': 0},1124 'state-initial--next-event': {'action': 1},1125 'state-normal--next-event': {'action': 2}},1126 getCounts(self.machineConfig))1127class RunTasksWithFailuresTests_TaskQueueFSMTests_POST(RunTasksWithFailuresTests_TaskQueueFSMTests):1128 METHOD = 'POST'1129class RunTasksWithFailuresTests_DatastoreFSMContinuationTests(RunTasksBaseTest):1130 FILENAME = 'test-DatastoreFSMContinuationTests.yaml'1131 MACHINE_NAME = 'DatastoreFSMContinuationTests'1132 def test_DatastoreFSMContinuationTests_initial_state_entry(self):1133 overrideFails(self.machineConfig, [('state-initial', 'entry', 1)], [])1134 self.context.initialize() # queues the first task1135 ran = runQueuedTasks(queueName=self.context.queueName)1136 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',1137 'instanceName--pseudo-init--pseudo-init--state-initial--step-0',1138 'instanceName--state-initial--next-event--state-continuation--step-1',1139 'instanceName--continuation-1-1--state-initial--next-event--state-continuation--step-1',1140 'instanceName--state-continuation--next-event--state-final--step-2',1141 'instanceName--continuation-1-2--state-initial--next-event--state-continuation--step-1',1142 'instanceName--continuation-1-1--state-continuation--next-event--state-final--step-2',1143 'instanceName--continuation-1-3--state-initial--next-event--state-continuation--step-1',1144 'instanceName--continuation-1-2--state-continuation--next-event--state-final--step-2',1145 'instanceName--continuation-1-4--state-initial--next-event--state-continuation--step-1',1146 'instanceName--continuation-1-3--state-continuation--next-event--state-final--step-2',1147 'instanceName--continuation-1-5--state-initial--next-event--state-continuation--step-1',1148 'instanceName--continuation-1-4--state-continuation--next-event--state-final--step-2'], ran)1149 self.assertEqual({'state-initial': {'entry': 2, 'action': 1, 'exit': 0},1150 'state-continuation': {'entry': 6, 'action': 5, 'continuation': 6, 'exit': 0},1151 'state-final': {'entry': 5, 'action': 5, 'exit': 0},1152 'state-initial--next-event': {'action': 0},1153 'state-continuation--next-event': {'action': 0}},1154 getCounts(self.machineConfig))1155 def test_DatastoreFSMContinuationTests_initial_state_do(self):1156 overrideFails(self.machineConfig, [('state-initial', 'action', 1)], [])1157 self.context.initialize() # queues the first task1158 ran = runQueuedTasks(queueName=self.context.queueName)1159 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',1160 'instanceName--pseudo-init--pseudo-init--state-initial--step-0',1161 'instanceName--state-initial--next-event--state-continuation--step-1',1162 'instanceName--continuation-1-1--state-initial--next-event--state-continuation--step-1',1163 'instanceName--state-continuation--next-event--state-final--step-2',1164 'instanceName--continuation-1-2--state-initial--next-event--state-continuation--step-1',1165 'instanceName--continuation-1-1--state-continuation--next-event--state-final--step-2',1166 'instanceName--continuation-1-3--state-initial--next-event--state-continuation--step-1',1167 'instanceName--continuation-1-2--state-continuation--next-event--state-final--step-2',1168 'instanceName--continuation-1-4--state-initial--next-event--state-continuation--step-1',1169 'instanceName--continuation-1-3--state-continuation--next-event--state-final--step-2',1170 'instanceName--continuation-1-5--state-initial--next-event--state-continuation--step-1',1171 'instanceName--continuation-1-4--state-continuation--next-event--state-final--step-2'], ran)1172 self.assertEqual({'state-initial': {'entry': 2, 'action': 2, 'exit': 0},1173 'state-continuation': {'entry': 6, 'action': 5, 'continuation': 6, 'exit': 0},1174 'state-final': {'entry': 5, 'action': 5, 'exit': 0},1175 'state-initial--next-event': {'action': 0},1176 'state-continuation--next-event': {'action': 0}},1177 getCounts(self.machineConfig))1178 def test_DatastoreFSMContinuationTests_continuation_state_entry(self):1179 overrideFails(self.machineConfig, [('state-continuation', 'entry', 1)], [])1180 self.context.initialize() # queues the first task1181 ran = runQueuedTasks(queueName=self.context.queueName)1182 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',1183 'instanceName--state-initial--next-event--state-continuation--step-1',1184 'instanceName--state-initial--next-event--state-continuation--step-1',1185 'instanceName--continuation-1-1--state-initial--next-event--state-continuation--step-1',1186 'instanceName--state-continuation--next-event--state-final--step-2',1187 'instanceName--continuation-1-2--state-initial--next-event--state-continuation--step-1',1188 'instanceName--continuation-1-1--state-continuation--next-event--state-final--step-2',1189 'instanceName--continuation-1-3--state-initial--next-event--state-continuation--step-1',1190 'instanceName--continuation-1-2--state-continuation--next-event--state-final--step-2',1191 'instanceName--continuation-1-4--state-initial--next-event--state-continuation--step-1',1192 'instanceName--continuation-1-3--state-continuation--next-event--state-final--step-2',1193 'instanceName--continuation-1-5--state-initial--next-event--state-continuation--step-1',1194 'instanceName--continuation-1-4--state-continuation--next-event--state-final--step-2'], ran)1195 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 0},1196 'state-continuation': {'entry': 7, 'action': 5, 'continuation': 6, 'exit': 0},1197 'state-final': {'entry': 5, 'action': 5, 'exit': 0},1198 'state-initial--next-event': {'action': 0},1199 'state-continuation--next-event': {'action': 0}},1200 getCounts(self.machineConfig))1201 def test_DatastoreFSMContinuationTests_continuation_state_continuation_2(self):1202 overrideFails(self.machineConfig, [('state-continuation', 'action', (0, 0, 2))], [])1203 self.context.initialize() # queues the first task1204 ran = runQueuedTasks(queueName=self.context.queueName)1205 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',1206 'instanceName--state-initial--next-event--state-continuation--step-1',1207 'instanceName--continuation-1-1--state-initial--next-event--state-continuation--step-1',1208 'instanceName--state-continuation--next-event--state-final--step-2',1209 'instanceName--continuation-1-1--state-initial--next-event--state-continuation--step-1',1210 'instanceName--continuation-1-2--state-initial--next-event--state-continuation--step-1',1211 'instanceName--continuation-1-1--state-continuation--next-event--state-final--step-2',1212 'instanceName--continuation-1-3--state-initial--next-event--state-continuation--step-1',1213 'instanceName--continuation-1-2--state-continuation--next-event--state-final--step-2',1214 'instanceName--continuation-1-4--state-initial--next-event--state-continuation--step-1',1215 'instanceName--continuation-1-3--state-continuation--next-event--state-final--step-2',1216 'instanceName--continuation-1-5--state-initial--next-event--state-continuation--step-1',1217 'instanceName--continuation-1-4--state-continuation--next-event--state-final--step-2'], ran)1218 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 0},1219 'state-continuation': {'entry': 7, 'action': 5, 'continuation': 7, 'exit': 0},1220 'state-final': {'entry': 5, 'action': 5, 'exit': 0},1221 'state-initial--next-event': {'action': 0},1222 'state-continuation--next-event': {'action': 0}},1223 getCounts(self.machineConfig))1224 def test_DatastoreFSMContinuationTests_continuation_state_do_2(self):1225 overrideFails(self.machineConfig, [('state-continuation', 'action', (0, 2, 0))], [])1226 self.context.initialize() # queues the first task1227 ran = runQueuedTasks(queueName=self.context.queueName)1228 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',1229 'instanceName--state-initial--next-event--state-continuation--step-1',1230 'instanceName--continuation-1-1--state-initial--next-event--state-continuation--step-1',1231 'instanceName--state-continuation--next-event--state-final--step-2',1232 'instanceName--continuation-1-1--state-initial--next-event--state-continuation--step-1',1233 'instanceName--continuation-1-2--state-initial--next-event--state-continuation--step-1',1234 'instanceName--continuation-1-1--state-continuation--next-event--state-final--step-2',1235 'instanceName--continuation-1-3--state-initial--next-event--state-continuation--step-1',1236 'instanceName--continuation-1-2--state-continuation--next-event--state-final--step-2',1237 'instanceName--continuation-1-4--state-initial--next-event--state-continuation--step-1',1238 'instanceName--continuation-1-3--state-continuation--next-event--state-final--step-2',1239 'instanceName--continuation-1-5--state-initial--next-event--state-continuation--step-1',1240 'instanceName--continuation-1-4--state-continuation--next-event--state-final--step-2'], ran)1241 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 0},1242 'state-continuation': {'entry': 7, 'action': 6, 'continuation': 7, 'exit': 0},1243 'state-final': {'entry': 5, 'action': 5, 'exit': 0},1244 'state-initial--next-event': {'action': 0},1245 'state-continuation--next-event': {'action': 0}},1246 getCounts(self.machineConfig))1247class RunTasksWithFailuresTests_DatastoreFSMContinuationTests_POST(1248 RunTasksWithFailuresTests_DatastoreFSMContinuationTests):1249 METHOD = 'POST'1250class RunTasksWithFailuresTests_DatastoreFSMContinuationFanInTests(RunTasksBaseTest):1251 FILENAME = 'test-DatastoreFSMContinuationFanInTests.yaml'1252 MACHINE_NAME = 'DatastoreFSMContinuationFanInTests'1253 def test_DatastoreFSMContinuationTests_initial_state_entry(self):1254 overrideFails(self.machineConfig, [('state-initial', 'entry', 1)], [])1255 self.context.initialize() # queues the first task1256 ran = runQueuedTasks(queueName=self.context.queueName)1257 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',1258 'instanceName--pseudo-init--pseudo-init--state-initial--step-0',1259 'instanceName--state-initial--next-event--state-continuation--step-1',1260 'instanceName--continuation-1-1--state-initial--next-event--state-continuation--step-1',1261 'instanceName--continuation-1-2--state-initial--next-event--state-continuation--step-1',1262 'instanceName--continuation-1-3--state-initial--next-event--state-continuation--step-1',1263 'instanceName--continuation-1-4--state-initial--next-event--state-continuation--step-1',1264 'instanceName--continuation-1-5--state-initial--next-event--state-continuation--step-1',1265 'instanceName--state-continuation--next-event--state-fan-in--step-2-1',1266 'instanceName--work-index-1--state-fan-in--next-event--state-final--step-3'], ran)1267 self.assertEqual({'state-initial': {'entry': 2, 'action': 1, 'exit': 0},1268 'state-continuation': {'entry': 6, 'action': 5, 'continuation': 6, 'exit': 0},1269 'state-fan-in': {'entry': 1, 'action': 1, 'exit': 0,1270 'fan-in-entry': 5, 'fan-in-action': 5, 'fan-in-exit': 0},1271 'state-final': {'entry': 1, 'action': 1, 'exit': 0},1272 'state-initial--next-event': {'action': 0},1273 'state-continuation--next-event': {'action': 0},1274 'state-fan-in--next-event': {'action': 0}},1275 getCounts(self.machineConfig))1276 self.assertEqual(10, TestModel.all().count())1277 self.assertEqual(1, ResultModel.all().count())1278 self.assertEqual(self.context.instanceName, ResultModel.all().get().key().name())1279 self.assertEqual(10, ResultModel.get_by_key_name(self.context.instanceName).total)1280 def test_DatastoreFSMContinuationTests_fan_in_state_entry(self):1281 overrideFails(self.machineConfig, [('state-fan-in', 'entry', 1)], [])1282 self.context.initialize() # queues the first task1283 ran = runQueuedTasks(queueName=self.context.queueName)1284 self.assertEqual(['instanceName--pseudo-init--pseudo-init--state-initial--step-0',1285 'instanceName--state-initial--next-event--state-continuation--step-1',1286 'instanceName--continuation-1-1--state-initial--next-event--state-continuation--step-1',1287 'instanceName--continuation-1-2--state-initial--next-event--state-continuation--step-1',1288 'instanceName--continuation-1-3--state-initial--next-event--state-continuation--step-1',1289 'instanceName--continuation-1-4--state-initial--next-event--state-continuation--step-1',1290 'instanceName--continuation-1-5--state-initial--next-event--state-continuation--step-1',1291 'instanceName--state-continuation--next-event--state-fan-in--step-2-1',1292 'instanceName--state-continuation--next-event--state-fan-in--step-2-1',1293 'instanceName--work-index-1--state-fan-in--next-event--state-final--step-3'], ran)1294 self.assertEqual({'state-initial': {'entry': 1, 'action': 1, 'exit': 0},1295 'state-continuation': {'entry': 6, 'action': 5, 'continuation': 6, 'exit': 0},1296 'state-fan-in': {'entry': 2, 'action': 1, 'exit': 0,1297 'fan-in-entry': 10, 'fan-in-action': 5, 'fan-in-exit': 0},1298 'state-final': {'entry': 1, 'action': 1, 'exit': 0},1299 'state-initial--next-event': {'action': 0},1300 'state-continuation--next-event': {'action': 0},1301 'state-fan-in--next-event': {'action': 0}},1302 getCounts(self.machineConfig))1303 self.assertEqual(0, _FantasmFanIn.all(namespace='').count())1304 self.assertEqual(10, ResultModel.get_by_key_name(self.context.instanceName).total)1305class RunTasksWithFailuresTests_DatastoreFSMContinuationFanInTests_POST(1306 RunTasksWithFailuresTests_DatastoreFSMContinuationFanInTests):1307 METHOD = 'POST'1308class FinalStateCanEmitEventTests(RunTasksBaseTest):1309 FILENAME = 'test-TaskQueueFSMTests.yaml'1310 MACHINE_NAME = 'FinalStateCanEmitEvent'1311 def test_DatastoreFSMContinuationTests(self):1312 self.context.initialize() # queues the first task1313 ran = runQueuedTasks(queueName=self.context.queueName)1314 counts = getCounts(self.machineConfig)1315 self.assertEquals(1, counts['InitialState']['action'])1316 self.assertEquals(1, counts['OptionalFinalState']['action'])1317 self.assertEquals(1, counts['FinalState']['action'])1318class SpawnMachinesTests(RunTasksBaseTest):1319 FILENAME = 'test-SpawnTests.yaml'1320 MACHINE_NAME = 'SpawnTests'1321 def test_spawnKicksOffMachines(self):1322 self.context.initialize()1323 ran = runQueuedTasks(queueName=self.context.queueName)1324 counts = getCounts(self.machineConfig)1325 self.assertEqual({'SpawnTests-InitialState': {'entry': 1, 'action': 1, 'exit': 1}},1326 getCounts(self.machineConfig))1327 self.assertTrue('instanceName--pseudo-init--pseudo-init--SpawnTests-InitialState--step-0' in ran)1328 self.assertTrue('instanceName--pseudo-init--pseudo-init--SpawnTests-InitialState--step-0--startStateMachine-0' in ran)1329 self.assertTrue('instanceName--pseudo-init--pseudo-init--SpawnTests-InitialState--step-0--startStateMachine-1' in ran)1330 self.assertTrue('instanceName--SpawnTests-InitialState--pseudo-final--pseudo-final--step-1' in ran)1331 self.assertEquals({'action': 1, 'entry': 1, 'exit': 1}, counts['SpawnTests-InitialState'])1332 # FIXME: counts only considers one machine and needs to be extended1333 # FIXME: spawned machines don't have an instrumented instanceName, so the tasks are difficult to compare1334 # u'MachineToSpawn-20101020035109-W579H8--MachineToSpawn-InitialState--pseudo-final--pseudo-final--step-1',1335 # u'MachineToSpawn-20101020035109-GKQD74--MachineToSpawn-InitialState--pseudo-final--pseudo-final--step-1'...
action.py
Source:action.py
...33 """34 raise NotImplementedError()35class ContinuationFSMAction(FSMAction):36 """ Defines the interface for all continuation actions. """37 def continuation(self, context, obj, token=None):38 """ Accepts a token (may be None) and returns the next token for the continutation.39 @param token: the continuation token40 @param context The FSMContext (i.e., machine). context.get() and context.put() can be used to get data41 from/to the context.42 @param obj: An object which the action can operate on43 """44 raise NotImplementedError()45 @staticmethod46 def checkFanInForTotalResultsCount(contexts, obj):47 """ Checks for the total number of continuation results48 @param contexts: a list of FSMContext instances, from a fan-in49 @param obj: An object which the action can operate on50 @return: the total number of results from the continuation, or None if that is not yet available51 FIXME: this currently only handles single-level continuations52 """53 totalResultsCount = None54 for context in contexts:55 if context.get(CONTINUATION_COMPLETE_PARAM):56 totalResultsCount = context[CONTINUATION_RESULTS_COUNTER_PARAM]57 return totalResultsCount58 @staticmethod59 def getResultsCount(context, obj):60 """ Returns the number of continuation results from the current batch61 @param token: the continuation token62 @param context The FSMContext (i.e., machine). context.get() and context.put() can be used to get data63 from/to the context.64 @return: the number of continuation results in this batch65 FIXME: this currently only handles single-level continuations66 """67 return context.get(CONTINUATION_RESULTS_SIZE_PARAM, 0)68class DatastoreContinuationFSMAction(ContinuationFSMAction):69 """ A datastore continuation. """70 __NEXT_TOKEN = '__next_token__'71 def continuation(self, context, obj, token=None):72 """ Accepts a token (an optional cursor) and returns the next token for the continutation.73 The results of the query are stored on obj.results.74 """75 limit = self.getBatchSize(context, obj)76 results = self._fetchResults(limit, context, obj, token=token)77 # place results on obj.results78 obj[CONTINUATION_RESULTS_KEY] = results79 obj.results = obj[CONTINUATION_RESULTS_KEY] # deprecated interface80 # add first obj.results item on obj.result - convenient for batch size 181 if obj[CONTINUATION_RESULTS_KEY] and len(obj[CONTINUATION_RESULTS_KEY]) > 0:82 obj[CONTINUATION_RESULT_KEY] = obj[CONTINUATION_RESULTS_KEY][0]83 else:84 obj[CONTINUATION_RESULT_KEY] = None85 obj.result = obj[CONTINUATION_RESULT_KEY] # deprecated interface86 context[CONTINUATION_RESULTS_COUNTER_PARAM] = \87 context.get(GEN_PARAM, {}).get(str(context[STEPS_PARAM]), 0) * limit + len(obj[CONTINUATION_RESULTS_KEY])88 context[CONTINUATION_RESULTS_SIZE_PARAM] = len(obj[CONTINUATION_RESULTS_KEY])89 if len(obj[CONTINUATION_RESULTS_KEY]) == limit:90 nextToken = self._getNextToken(context, obj, token=token)91 if nextToken:92 context[CONTINUATION_COMPLETE_PARAM] = False93 else:94 context[CONTINUATION_COMPLETE_PARAM] = True95 return nextToken96 else:97 context[CONTINUATION_COMPLETE_PARAM] = True98 return None99 def _fetchResults(self, limit, context, obj, token=None):100 """ Actually fetches the results. """101 query = self.getQuery(context, obj)102 if token:103 query.with_cursor(token)104 results = query.fetch(limit)105 obj[self.__NEXT_TOKEN] = query.cursor()106 return results107 def _getNextToken(self, context, obj, token=None):108 """ Gets the next token. """109 return obj.pop(self.__NEXT_TOKEN)110 def getQuery(self, context, obj):111 """ Returns a GqlQuery """112 raise NotImplementedError()113 # W0613: 78:DatastoreContinuationFSMAction.getBatchSize: Unused argument 'obj'114 def getBatchSize(self, context, obj): # pylint: disable=W0613115 """ Returns a batch size, default 1. Override for different values. """116 return 1117class NDBDatastoreContinuationFSMAction(DatastoreContinuationFSMAction):118 """ A datastore continuation, using the NDB API.119 IMPORTANT!!!120 To use this effectively, you must uncomment some lines in handlers.py. Search for "ndb_context" to see121 the specific lines to uncomment (there are 3). If you do not do this, errors in your own code may end up122 surfacing as:123 Deadlock waiting for <Future 94c0fd8731c2dca0 created by tasklet_wrapper(tasklets.py:906)124 for tasklet positional_wrapper(datastore_rpc.py:84); pending>125 with seemingly unrelated stacktraces. These are very difficult to debug. Uncommenting the lines in126 handlers.py will give you nice stacktraces again.127 """128 __NEXT_TOKEN = '__next_token__'129 def _fetchResults(self, limit, context, obj, token=None):130 """ Actually fetches the results. """131 from google.appengine.ext.ndb import query as ndb_query132 query = self.getQuery(context, obj)133 assert isinstance(query, ndb_query.Query)134 kwargs = {135 'produce_cursors': True,136 'keys_only': self.getKeysOnly(context, obj),137 'deadline': self.getDeadline(context, obj),138 'read_policy': self.getReadPolicy(context, obj),139 }140 if token:141 kwargs['start_cursor'] = ndb_query.Cursor.from_websafe_string(token)142 results, cursor, more = query.fetch_page(limit, **kwargs)143 obj[CONTINUATION_MORE_RESULTS_KEY] = more144 obj[self.__NEXT_TOKEN] = more and cursor.to_websafe_string() or None145 return results146 def _getNextToken(self, context, obj, token=None):147 """ Gets the next token. """148 return obj.pop(self.__NEXT_TOKEN)149 def getQuery(self, context, obj):150 """ Returns a google.appengine.ext.ndb.query.Query object. """151 raise NotImplementedError()152 # W0613: 78:DatastoreContinuationFSMAction.getBatchSize: Unused argument 'obj'153 def getKeysOnly(self, context, obj): # pylint: disable=W0613154 """ Returns if the query should returns keys_only. Default False. """155 return False156 # W0613: 78:DatastoreContinuationFSMAction.getBatchSize: Unused argument 'obj'157 def getDeadline(self, context, obj): # pylint: disable=W0613158 """ Returns the RPC deadline. Default 5 seconds."""159 return 5160 # W0613: 78:DatastoreContinuationFSMAction.getBatchSize: Unused argument 'obj'161 def getReadPolicy(self, context, obj): # pylint: disable=W0613162 """ Returns the RPC deadline. Default 5 seconds."""163 return 0 # Strong Consistency164class ListContinuationFSMAction(ContinuationFSMAction):165 """ A list-of-things continuation. """166 def getList(self, context, obj):167 """ Returns a list of items to continue over. THIS LIST CANNOT CHANGE BETWEEN CALLS!!!"""168 raise NotImplementedError()169 def getBatchSize(self, context, obj): # pylint: disable=W0613170 """ Returns a batch size, default 1. Override for different values. """171 return 1172 def continuation(self, context, obj, token=None):173 """ Accepts a token (an optional index) and returns the next token for the continutation.174 The results of getList()[token] are stored on obj.results.175 """176 # the token is the index into the list177 items = self.getList(context, obj)178 index = int(token or '0')179 batchsize = limit = self.getBatchSize(context, obj)180 results = items[index:index + batchsize]181 # place results on obj.results182 obj[CONTINUATION_RESULTS_KEY] = results183 obj.results = obj[CONTINUATION_RESULTS_KEY] # deprecated interface'184 # add first obj.results item on obj.result - convenient for batch size 1185 if obj[CONTINUATION_RESULTS_KEY] and len(obj[CONTINUATION_RESULTS_KEY]) > 0:186 obj[CONTINUATION_RESULT_KEY] = obj[CONTINUATION_RESULTS_KEY][0]...
engine.py
Source:engine.py
1from pypy.lang.prolog.interpreter.term import Var, Term, Rule, Atom, debug_print, \2 Callable3from pypy.lang.prolog.interpreter.error import UnificationFailed, FunctionNotFound, \4 CutException5from pypy.lang.prolog.interpreter import error6from pypy.rlib.jit import purefunction7DEBUG = False8# bytecodes:9CALL = 'a'10USER_CALL = 'u'11TRY_RULE = 't'12CONTINUATION = 'c'13DONE = 'd'14class Continuation(object):15 def call(self, engine, choice_point=True):16 if choice_point:17 return engine.main_loop(CONTINUATION, None, self, None)18 return (CONTINUATION, None, self, None)19 def _call(self, engine):20 return (DONE, None, None, None)21DONOTHING = Continuation()22class LimitedScopeContinuation(Continuation):23 def __init__(self, continuation):24 self.scope_active = True25 self.continuation = continuation26 def _call(self, engine):27 self.scope_active = False28 return self.continuation.call(engine, choice_point=False)29class Heap(object):30 def __init__(self):31 self.trail = []32 def reset(self):33 self.trail = []34 self.last_branch = 035 def add_trail(self, var):36 self.trail.append((var, var.binding))37 def branch(self):38 return len(self.trail)39 def revert(self, state):40 trails = state41 for i in range(len(self.trail) - 1, trails - 1, -1):42 var, val = self.trail[i]43 var.binding = val44 del self.trail[trails:]45 def discard(self, state):46 pass #XXX for now47 def maxvar(self):48 XXX49 return self.needed_vars50 def newvar(self):51 result = Var(self)52 return result53class LinkedRules(object):54 _immutable_ = True55 def __init__(self, rule, next=None):56 self.rule = rule57 self.next = next58 def copy(self, stopat=None):59 first = LinkedRules(self.rule)60 curr = self.next61 copy = first62 while curr is not stopat:63 new = LinkedRules(curr.rule)64 copy.next = new65 copy = new66 curr = curr.next67 return first, copy68 def find_applicable_rule(self, uh2):69 #import pdb;pdb.set_trace()70 while self:71 uh = self.rule.unify_hash72 j = 073 while j < len(uh):74 hash1 = uh[j]75 hash2 = uh2[j]76 if hash1 != 0 and hash2 * (hash2 - hash1) != 0:77 break78 j += 179 else:80 return self81 self = self.next82 return None83 def __repr__(self):84 return "LinkedRules(%r, %r)" % (self.rule, self.next)85class Function(object):86 def __init__(self, firstrule=None):87 if firstrule is None:88 self.rulechain = self.last = None89 else:90 self.rulechain = LinkedRules(firstrule)91 self.last = self.rulechain92 def add_rule(self, rule, end):93 if self.rulechain is None:94 self.rulechain = self.last = LinkedRules(rule)95 elif end:96 self.rulechain, last = self.rulechain.copy()97 self.last = LinkedRules(rule)98 last.next = self.last99 else:100 self.rulechain = LinkedRules(rule, self.rulechain)101 def remove(self, rulechain):102 self.rulechain, last = self.rulechain.copy(rulechain)103 last.next = rulechain.next104class Engine(object):105 def __init__(self):106 self.heap = Heap()107 self.signature2function = {}108 self.parser = None109 self.operations = None110 def add_rule(self, rule, end=True):111 from pypy.lang.prolog import builtin112 if DEBUG:113 debug_print("add_rule", rule)114 if isinstance(rule, Term):115 if rule.name == ":-":116 rule = Rule(rule.args[0], rule.args[1])117 else:118 rule = Rule(rule, None)119 signature = rule.signature120 elif isinstance(rule, Atom):121 rule = Rule(rule, None)122 signature = rule.signature123 else:124 error.throw_type_error("callable", rule)125 assert 0, "unreachable" # make annotator happy126 if signature in builtin.builtins:127 error.throw_permission_error(128 "modify", "static_procedure", rule.head.get_prolog_signature())129 function = self._lookup(signature)130 function.add_rule(rule, end)131 def run(self, query, continuation=DONOTHING):132 if not isinstance(query, Callable):133 error.throw_type_error("callable", query)134 try:135 return self.call(query, continuation, choice_point=True)136 except CutException, e:137 return self.continue_after_cut(e.continuation)138 def _build_and_run(self, tree):139 from pypy.lang.prolog.interpreter.parsing import TermBuilder140 builder = TermBuilder()141 term = builder.build_query(tree)142 if isinstance(term, Term) and term.name == ":-" and len(term.args) == 1:143 self.run(term.args[0])144 else:145 self.add_rule(term)146 return self.parser147 def runstring(self, s):148 from pypy.lang.prolog.interpreter.parsing import parse_file149 trees = parse_file(s, self.parser, Engine._build_and_run, self)150 def call(self, query, continuation=DONOTHING, choice_point=True):151 assert isinstance(query, Callable)152 if not choice_point:153 return (CALL, query, continuation, None)154 return self.main_loop(CALL, query, continuation)155 def _call(self, query, continuation):156 from pypy.lang.prolog.builtin import builtins157 signature = query.signature158 builtin = builtins.get(signature, None)159 if builtin is not None:160 return builtin.call(self, query, continuation)161 # do a real call162 return self.user_call(query, continuation, choice_point=False)163 def main_loop(self, where, query, continuation, rule=None):164 next = (DONE, None, None, None)165 while 1:166 if where == DONE:167 return next168 next = self.dispatch_bytecode(where, query, continuation, rule)169 where, query, continuation, rule = next170 def dispatch_bytecode(self, where, query, continuation, rule):171 if where == CALL:172 next = self._call(query, continuation)173 elif where == TRY_RULE:174 next = self._try_rule(rule, query, continuation)175 elif where == USER_CALL:176 next = self._user_call(query, continuation)177 elif where == CONTINUATION:178 next = continuation._call(self)179 else:180 raise Exception("unknown bytecode")181 return next182 @purefunction183 def _lookup(self, signature):184 signature2function = self.signature2function185 function = signature2function.get(signature, None)186 if function is None:187 signature2function[signature] = function = Function()188 return function189 def user_call(self, query, continuation, choice_point=True):190 if not choice_point:191 return (USER_CALL, query, continuation, None)192 return self.main_loop(USER_CALL, query, continuation)193 def _user_call(self, query, continuation):194 signature = query.signature195 function = self._lookup(signature)196 startrulechain = function.rulechain197 if startrulechain is None:198 error.throw_existence_error(199 "procedure", query.get_prolog_signature())200 unify_hash = query.unify_hash_of_children(self.heap)201 rulechain = startrulechain.find_applicable_rule(unify_hash)202 if rulechain is None:203 # none of the rules apply204 raise UnificationFailed()205 rule = rulechain.rule206 rulechain = rulechain.next207 oldstate = self.heap.branch()208 while 1:209 if rulechain is not None:210 rulechain = rulechain.find_applicable_rule(unify_hash)211 choice_point = rulechain is not None212 else:213 choice_point = False214 if rule.contains_cut:215 continuation = LimitedScopeContinuation(continuation)216 try:217 result = self.try_rule(rule, query, continuation)218 self.heap.discard(oldstate)219 return result220 except UnificationFailed:221 self.heap.revert(oldstate)222 except CutException, e:223 if continuation.scope_active:224 return self.continue_after_cut(e.continuation,225 continuation)226 raise227 else:228 try:229 # for the last rule (rulechain is None), this will always230 # return immediately, because choice_point is False231 result = self.try_rule(rule, query, continuation,232 choice_point=choice_point)233 self.heap.discard(oldstate)234 return result235 except UnificationFailed:236 assert choice_point237 self.heap.revert(oldstate)238 rule = rulechain.rule239 rulechain = rulechain.next240 def try_rule(self, rule, query, continuation=DONOTHING, choice_point=True):241 if not choice_point:242 return (TRY_RULE, query, continuation, rule)243 return self.main_loop(TRY_RULE, query, continuation, rule)244 def _try_rule(self, rule, query, continuation):245 # standardizing apart246 nextcall = rule.clone_and_unify_head(self.heap, query)247 if nextcall is not None:248 return self.call(nextcall, continuation, choice_point=False)249 else:250 return continuation.call(self, choice_point=False)251 def continue_after_cut(self, continuation, lsc=None):252 while 1:253 try:254 return continuation.call(self, choice_point=True)255 except CutException, e:256 if lsc is not None and not lsc.scope_active:257 raise258 continuation = e.continuation259 def parse(self, s):260 from pypy.lang.prolog.interpreter.parsing import parse_file, TermBuilder, lexer261 builder = TermBuilder()262 trees = parse_file(s, self.parser)263 terms = builder.build_many(trees)264 return terms, builder.varname_to_var265 def getoperations(self):266 from pypy.lang.prolog.interpreter.parsing import default_operations267 if self.operations is None:268 return default_operations...
selectors.py
Source:selectors.py
1from __future__ import annotations2from typing import Dict, Set, Any3import random4import math5"""6Selectors.7Selectors functions used by the model to select a continuation index among possible continuation indexes.8"""9def random_select(continuation_idxs_by_viewpoints: Dict[str: Set[Any]], verbose=False) -> int | None:10 """Returns a continuation index by randomly selecting in all continuation indexes."""11 all_continuation_idxs = list()12 for continuation_idxs in continuation_idxs_by_viewpoints.values():13 if continuation_idxs is not None:14 all_continuation_idxs.extend(list(continuation_idxs))15 if not all_continuation_idxs:16 return None17 state_selected = random.choice(all_continuation_idxs)18 if verbose:19 str_format = '{} was selected among {}'.format(state_selected, all_continuation_idxs)20 print(str_format)21 return state_selected22def intersect_select(continuation_idxs_by_viewpoints: Dict[str: Set[Any]], verbose=False) -> int | None:23 """Returns a continuation index by randomly selecting in continuation indexes present in all viewpoints."""24 all_continuation_idxs = (continuation_idxs for continuation_idxs in continuation_idxs_by_viewpoints.values()25 if continuation_idxs is not None)26 continuation_idxs_intersection = set.intersection(*all_continuation_idxs)27 if not continuation_idxs_intersection:28 return None29 state_selected = random.choice(list(continuation_idxs_intersection))30 if verbose:31 str_format = '{} was selected among {}'.format(state_selected, continuation_idxs_intersection)32 print(str_format)33 return state_selected34def weighted_intersect_select(continuation_idxs_by_viewpoints: Dict[str: Set[Any]], verbose=False) -> int | None:35 """Returns a continuation index by assigning a weight to each continuation index and randomly selecting using the36 weights.37 weight = sum(1 / len(continuation_idxs)) for viewpoints if continuation_idx in viewpoint38 """39 all_weighted_continuation_idxs = dict()40 for continuation_idxs in continuation_idxs_by_viewpoints.values():41 if continuation_idxs is not None:42 for continuation_idx in continuation_idxs:43 if continuation_idx in all_weighted_continuation_idxs:44 all_weighted_continuation_idxs[continuation_idx] += 1 / len(continuation_idxs)45 else:46 all_weighted_continuation_idxs[continuation_idx] = 1 / len(continuation_idxs)47 if not all_weighted_continuation_idxs:48 return None49 state_selected = random.choices(list(all_weighted_continuation_idxs.keys()),50 list(all_weighted_continuation_idxs.values()))[0]51 if verbose:52 str_format = '{} was selected among {}'.format(state_selected, all_weighted_continuation_idxs)53 print(str_format)54 return state_selected55def exp_weighted_intersect_select(continuation_idxs_by_viewpoints: Dict[str: Set[Any]],56 factor=1, verbose=False) -> int | None:57 """Similar to weighted_intersect_select except that an exponential factor is given to increase relative58 weighting."""59 all_weighted_continuation_idxs = dict()60 for continuation_idxs in continuation_idxs_by_viewpoints.values():61 if continuation_idxs is not None:62 for continuation_idx in continuation_idxs:63 if continuation_idx in all_weighted_continuation_idxs:64 all_weighted_continuation_idxs[continuation_idx] += 1 / len(continuation_idxs)65 else:66 all_weighted_continuation_idxs[continuation_idx] = 1 / len(continuation_idxs)67 for continuation_idx, weight in all_weighted_continuation_idxs.items():68 all_weighted_continuation_idxs[continuation_idx] = math.exp(weight * factor) - 169 if not all_weighted_continuation_idxs:70 return None71 state_selected = random.choices(list(all_weighted_continuation_idxs.keys()),72 list(all_weighted_continuation_idxs.values()))[0]73 if verbose:74 str_format = '{} was selected among {}'.format(state_selected, all_weighted_continuation_idxs)75 print(str_format)76 return state_selected77#TODO: Hierarchical select...
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.
Get 100 minutes of automation test minutes FREE!!