4343import json
4444import pytest
4545
46- from actors import health , models , codes , stores , spawner
46+ from actors import controllers , health , models , codes , stores , spawner
4747from channels import ActorMsgChannel , CommandChannel
4848from util import headers , base_url , case , \
4949 response_format , basic_response_checks , get_actor_id , check_execution_details , \
@@ -622,14 +622,32 @@ def test_execute_and_delete_sleep_loop_actor(headers):
622622 else :
623623 assert result .get ('executionId' )
624624 exc_id = result .get ('executionId' )
625+ # wait for a worker to take the execution -
626+ url = '{}/actors/{}/executions/{}' .format (base_url , actor_id , exc_id )
627+ worker_id = None
628+ idx = 0
629+ while not worker_id :
630+ rsp = requests .get (url , headers = headers ).json ().get ('result' )
631+ if case == 'snake' :
632+ worker_id = rsp .get ('worker_id' )
633+ else :
634+ worker_id = rsp .get ('workerId' )
635+ idx += 1
636+ time .sleep (1 )
637+ if idx > 10 :
638+ print ("worker never got sleep_loop execution. "
639+ "actor: {}; execution: {}; idx:{}" .format (actor_id , exc_id , idx ))
640+ assert False
625641 # now let's kill the execution -
626642 time .sleep (1 )
627643 url = '{}/actors/{}/executions/{}' .format (base_url , actor_id , exc_id )
628644 rsp = requests .delete (url , headers = headers )
629645 assert rsp .status_code in [200 , 201 , 202 , 203 , 204 ]
646+ assert 'Issued force quit command for execution' in rsp .json ().get ('message' )
630647 # make sure execution is stopped in a timely manner
631648 i = 0
632649 stopped = False
650+ status = None
633651 while i < 20 :
634652 rsp = requests .get (url , headers = headers )
635653 rsp_data = json .loads (rsp .content .decode ('utf-8' ))
@@ -639,6 +657,8 @@ def test_execute_and_delete_sleep_loop_actor(headers):
639657 break
640658 time .sleep (1 )
641659 i += 1
660+ print ("Execution never stopped. Last status of execution: {}; "
661+ "actor_id: {}; execution_id: {}" .format (status , actor_id , exc_id ))
642662 assert stopped
643663
644664def test_list_execution_details (headers ):
@@ -786,7 +806,7 @@ def test_create_actor_with_custom_queue_name(headers):
786806@pytest .mark .queuetest
787807def test_actor_uses_custom_queue (headers ):
788808 url = '{}/actors' .format (base_url )
789- # get the actor id of an actor registered on the defaul queue:
809+ # get the actor id of an actor registered on the default queue:
790810 default_queue_actor_id = get_actor_id (headers , name = 'abaco_test_suite_statelesss' )
791811 # and the actor id for the actor on the special queue:
792812 special_queue_actor_id = get_actor_id (headers , name = 'abaco_test_suite_queue1_actor1' )
@@ -1020,6 +1040,16 @@ def test_other_user_still_cant_list_actor(headers):
10201040 data = response_format (rsp )
10211041 assert 'you do not have access to this actor' in data ['message' ]
10221042
1043+ @pytest .mark .aliastest
1044+ def test_other_user_still_cant_create_alias_nonce (headers ):
1045+ # alias permissions do not confer access to the actor itself, and alias nonces require BOTH
1046+ # permissions on the alias AND on the actor
1047+ url = '{}/actors/aliases/{}/nonces' .format (base_url , ALIAS_1 )
1048+ rsp = requests .get (url , headers = priv_headers ())
1049+ assert rsp .status_code == 400
1050+ data = response_format (rsp )
1051+ assert 'you do not have access to this alias and actor' in data ['message' ]
1052+
10231053
10241054@pytest .mark .aliastest
10251055def test_get_actor_with_alias (headers ):
@@ -1620,6 +1650,188 @@ def test_tenant_list_workers(headers):
16201650 check_worker_fields (worker )
16211651
16221652
1653+ ##############
1654+ # events tests
1655+ ##############
1656+
1657+ REQUEST_BIN_URL = 'https://enqjwyug892gl.x.pipedream.net'
1658+
1659+
1660+ def check_event_logs (logs ):
1661+ assert 'event_time_utc' in logs
1662+ assert 'event_time_display' in logs
1663+ assert 'actor_id' in logs
1664+
1665+ def test_has_cycles_1 ():
1666+ links = {'A' : 'B' ,
1667+ 'B' : 'C' ,
1668+ 'C' : 'D' }
1669+ assert not controllers .has_cycles (links )
1670+
1671+ def test_has_cycles_2 ():
1672+ links = {'A' : 'B' ,
1673+ 'B' : 'A' ,
1674+ 'C' : 'D' }
1675+ assert controllers .has_cycles (links )
1676+
1677+ def test_has_cycles_3 ():
1678+ links = {'A' : 'B' ,
1679+ 'B' : 'C' ,
1680+ 'C' : 'D' ,
1681+ 'D' : 'E' ,
1682+ 'E' : 'H' ,
1683+ 'H' : 'B' }
1684+ assert controllers .has_cycles (links )
1685+
1686+ def test_has_cycles_4 ():
1687+ links = {'A' : 'B' ,
1688+ 'B' : 'C' ,
1689+ 'D' : 'E' ,
1690+ 'E' : 'H' ,
1691+ 'H' : 'J' ,
1692+ 'I' : 'J' ,
1693+ 'K' : 'J' ,
1694+ 'L' : 'M' ,
1695+ 'M' : 'J' }
1696+ assert not controllers .has_cycles (links )
1697+
1698+ def test_has_cycles_5 ():
1699+ links = {'A' : 'B' ,
1700+ 'B' : 'C' ,
1701+ 'C' : 'C' }
1702+ assert controllers .has_cycles (links )
1703+
1704+ def test_create_event_link_actor (headers ):
1705+ url = '{}/{}' .format (base_url , '/actors' )
1706+ data = {'image' : 'jstubbs/abaco_test' , 'name' : 'abaco_test_suite_event-link' , 'stateless' : False }
1707+ rsp = requests .post (url , data = data , headers = headers )
1708+ result = basic_response_checks (rsp )
1709+
1710+ def test_create_actor_with_link (headers ):
1711+ # first, get the actor id of the event_link actor:
1712+ link_actor_id = get_actor_id (headers , name = 'abaco_test_suite_event-link' )
1713+ # register a new actor with link to event_link actor
1714+ url = '{}/{}' .format (base_url , '/actors' )
1715+ data = {'image' : 'jstubbs/abaco_test' ,
1716+ 'name' : 'abaco_test_suite_event' ,
1717+ 'link' : link_actor_id }
1718+ rsp = requests .post (url , data = data , headers = headers )
1719+ result = basic_response_checks (rsp )
1720+
1721+ def test_execute_event_actor (headers ):
1722+ actor_id = get_actor_id (headers , name = 'abaco_test_suite_event' )
1723+ data = {'message' : 'testing events execution' }
1724+ result = execute_actor (headers , actor_id , data = data )
1725+ exec_id = result ['id' ]
1726+ # now that this execution has completed, check that the linked actor also executed:
1727+ idx = 0
1728+ link_execution_ex_id = None
1729+ link_actor_id = get_actor_id (headers , name = 'abaco_test_suite_event-link' )
1730+ url = '{}/actors/{}/executions' .format (base_url , link_actor_id )
1731+ # the linked actor should get 2 messages - one for the original actor initially being set to READY
1732+ # and a second when the execution sent above completes.
1733+ while not link_execution_ex_id and idx < 15 :
1734+ rsp = requests .get (url , headers = headers )
1735+ ex_data = rsp .json ().get ('result' ).get ('executions' )
1736+ if ex_data and len (ex_data ) > 1 :
1737+ link_ready_ex_id = ex_data [0 ]['id' ]
1738+ link_execution_ex_id = ex_data [1 ]['id' ]
1739+ break
1740+ else :
1741+ idx = idx + 1
1742+ time .sleep (1 )
1743+ if not link_execution_ex_id :
1744+ print ("linked actor never executed. actor_id: {}; link_actor_id: {}" .format (actor_id , link_actor_id ))
1745+ assert False
1746+ # wait for linked execution to complete and get logs
1747+ idx = 0
1748+ done = False
1749+ while not done and idx < 20 :
1750+ # get executions for linked actor and check status of each
1751+ rsp = requests .get (url , headers = headers )
1752+ ex_data = rsp .json ().get ('result' ).get ('executions' )
1753+ if ex_data [0 ].get ('status' ) == 'COMPLETE' and ex_data [1 ].get ('status' ) == 'COMPLETE' :
1754+ done = True
1755+ break
1756+ else :
1757+ time .sleep (1 )
1758+ idx = idx + 1
1759+ if not done :
1760+ print ("linked actor executions never completed. actor: {}; "
1761+ "linked_actor: {}; Final execution data: {}" .format (actor_id , link_actor_id , ex_data ))
1762+ assert False
1763+ # now check the logs from the two executions --
1764+ # first one should be the actor READY message:
1765+ url = '{}/actors/{}/executions/{}/logs' .format (base_url , link_actor_id , link_ready_ex_id )
1766+ rsp = requests .get (url , headers = headers )
1767+ result = basic_response_checks (rsp )
1768+ logs = result .get ('logs' )
1769+ assert "'event_type': 'ACTOR_READY'" in logs
1770+ check_event_logs (logs )
1771+
1772+ # second one should be the actor execution COMPLETE message:
1773+ url = '{}/actors/{}/executions/{}/logs' .format (base_url , link_actor_id , link_execution_ex_id )
1774+ rsp = requests .get (url , headers = headers )
1775+ result = basic_response_checks (rsp )
1776+ logs = result .get ('logs' )
1777+ assert "'event_type': 'EXECUTION_COMPLETE'" in logs
1778+ assert 'execution_id' in logs
1779+ check_event_logs (logs )
1780+
1781+ def test_cant_create_link_with_cycle (headers ):
1782+ # this test checks that adding a link to an actor that did not have one that creates a cycle
1783+ # is not allowed.
1784+ # register a new actor with no link
1785+ url = '{}/{}' .format (base_url , '/actors' )
1786+ data = {'image' : 'jstubbs/abaco_test' ,
1787+ 'name' : 'abaco_test_suite_create_link' ,}
1788+ rsp = requests .post (url , data = data , headers = headers )
1789+ result = basic_response_checks (rsp )
1790+ new_actor_id = result ['id' ]
1791+ # create 5 new actors, each with a link to the one created previously:
1792+ new_actor_ids = []
1793+ for i in range (5 ):
1794+ data ['link' ] = new_actor_id
1795+ rsp = requests .post (url , data = data , headers = headers )
1796+ result = basic_response_checks (rsp )
1797+ new_actor_id = result ['id' ]
1798+ new_actor_ids .append (new_actor_id )
1799+ # now, update the first created actor with a link that would create a cycle
1800+ first_aid = new_actor_ids [0 ]
1801+ data ['link' ] = new_actor_ids [4 ]
1802+ url = '{}/actors/{}' .format (base_url , first_aid )
1803+ print ("url: {}; data: {}" .format (url , data ))
1804+ rsp = requests .put (url , data = data , headers = headers )
1805+ assert rsp .status_code == 400
1806+ assert 'this update would result in a cycle of linked actors' in rsp .json ().get ('message' )
1807+
1808+ def test_cant_update_link_with_cycle (headers ):
1809+ # this test checks that an update to a link that would create a cycle is not allowed
1810+ link_actor_id = get_actor_id (headers , name = 'abaco_test_suite_event-link' )
1811+ # register a new actor with link to event_link actor
1812+ url = '{}/{}' .format (base_url , '/actors' )
1813+ data = {'image' : 'jstubbs/abaco_test' ,
1814+ 'name' : 'abaco_test_suite_event' ,
1815+ 'link' : link_actor_id }
1816+ # create 5 new actors, each with a link to the one created previously:
1817+ new_actor_ids = []
1818+ for i in range (5 ):
1819+ rsp = requests .post (url , data = data , headers = headers )
1820+ result = basic_response_checks (rsp )
1821+ new_actor_id = result ['id' ]
1822+ data ['link' ] = new_actor_id
1823+ new_actor_ids .append (new_actor_id )
1824+ # now, update the first created actor with a link that would great a cycle
1825+ first_aid = new_actor_ids [0 ]
1826+ data ['link' ] = new_actor_ids [4 ]
1827+ url = '{}/actors/{}' .format (base_url , first_aid )
1828+ print ("url: {}; data: {}" .format (url , data ))
1829+
1830+ rsp = requests .put (url , data = data , headers = headers )
1831+ assert rsp .status_code == 400
1832+ assert 'this update would result in a cycle of linked actors' in rsp .json ().get ('message' )
1833+
1834+
16231835##############
16241836# Clean up
16251837##############
0 commit comments