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!!
