def test_new_actor(repository_dir): # We need the model to be created already if not repository_dir.join('models/testmodel.py').check(file=True): test_new_model(repository_dir) with repository_dir.as_cwd(): check_call(['snactor', 'new-actor', 'Test']) assert repository_dir.join('actors/test/actor.py').check(file=True) with pytest.raises(CalledProcessError): check_call(['snactor', 'discover']) repository_dir.join('actors/test/actor.py').write(''' from leapp.actors import Actor from leapp.models import TestModel from leapp.tags import TestTag class Test(Actor): name = 'test' description = 'No description has been provided for the test actor.' consumes = () produces = (TestModel,) tags = (TestTag.Common,) def process(self): pass ''') check_call(['snactor', 'discover'])
def test_new_topic(repository_dir): with repository_dir.as_cwd(): # We need the topic to be created already for the model # So we have to check if it wasn't already created if not repository_dir.join('topics/test.py').check(file=True): check_call(['snactor', 'new-topic', 'Test']) assert repository_dir.join('topics/test.py').check(file=True) check_call(['snactor', 'discover'])
def test_messaging_messages(repository_dir, stored): with repository_dir.as_cwd(): msg = InProcessMessaging(stored=stored) v = UnitTestModel() msg.produce(v, FakeActor()) consumed = tuple(msg.consume(FakeActor(), UnitTestModel)) assert len(consumed) == 1 assert len(msg.messages()) == 1 assert consumed[0] == v
def test_run_workflow(repository_dir): # We need the workflow to be created already if not repository_dir.join('workflows/test.py').check(file=True): test_new_workflow(repository_dir) with pytest.raises(CalledProcessError): check_call(['snactor', 'workflow', 'run', 'Test']) with repository_dir.as_cwd(): check_call(['snactor', 'workflow', 'run', 'Test']) check_call(['snactor', '--debug', 'workflow', 'run', 'Test']) check_call(['snactor', 'workflow', '--debug', 'run', 'Test']) check_call(['snactor', 'workflow', 'run', '--debug', 'Test'])
def test_report_error(repository_dir): with repository_dir.as_cwd(): msg = InProcessMessaging() msg.report_error('Some error', ErrorSeverity.ERROR, FakeActor(), details=None) msg.report_error('Some error with details', ErrorSeverity.ERROR, FakeActor(), details={'foo': 'bar'}) assert len(msg.errors()) == 2
def setup_repo(repository_dir): with repository_dir.as_cwd(): new_tag_cmd(Namespace(tag_name='Test')) new_workflow_cmd( Namespace(name='Test', class_name=None, short_name=None)) actor_path = new_actor_cmd( Namespace( actor_name='TestActor', tag=['TestTag', 'TestWorkflowTag'], consumes=[], produces=[], )) type(repository_dir)(actor_path).join( 'tests', 'test_this_actor.py').write('print("I am a test")') type(repository_dir)(actor_path).mkdir('libraries').mkdir('lib').join( '__init__.py').write('''from subprocess import call # This is to ensure that actor tools are available on actor library load time assert call(['woot-tool']) == 42 # This is to ensure that common tools are available on actor library load time assert call(['common-woot-tool']) == 42 def do(): # This must always fail - This function is crashing the actor ;-) assert call(['woot-tool']) == 0 ''') repository_dir.mkdir('libraries').mkdir('lib').join( '__init__.py').write('''from subprocess import call # This is to ensure that common tools are available on common library load time assert call(['common-woot-tool']) == 42 ''') type(repository_dir)(actor_path).mkdir('files').join( 'test.data').write('data') repository_dir.mkdir('files').join('common-test.data').write('data') tool_path = type(repository_dir)(actor_path).mkdir('tools').join( 'woot-tool') woot_tool_content = '''#!/bin/bash echo 'WOOT' exit 42 ''' tool_path.write(woot_tool_content) tool_path.chmod(0o755) tool_path = repository_dir.mkdir('tools').join('common-woot-tool') tool_path.write(woot_tool_content) tool_path.chmod(0o755) actor_file = type(repository_dir)(actor_path).join('actor.py') actor_content = actor_file.read().replace( 'pass', '''from leapp.libraries.actor.lib import do import leapp.libraries.common.lib do()''') actor_file.write(actor_content)
def test_run_actor(repository_dir): with repository_dir.as_cwd(): check_call(['snactor', 'run', 'Test']) check_call(['snactor', 'run', '--print-output', 'Test']) check_call(['snactor', 'run', '--save-output', 'Test']) check_call(['snactor', 'run', '--print-output', '--save-output', 'Test']) check_call(['snactor', 'run', '--debug', 'Test']) check_call(['snactor', 'run', '--debug', '--print-output', 'Test']) check_call(['snactor', 'run', '--debug', '--save-output', 'Test']) check_call(['snactor', 'run', '--debug', '--print-output', '--save-output', 'Test']) check_call(['snactor', '--debug', 'run', 'Test']) check_call(['snactor', '--debug', 'run', '--print-output', 'Test']) check_call(['snactor', '--debug', 'run', '--save-output', 'Test']) check_call(['snactor', '--debug', 'run', '--print-output', '--save-output', 'Test'])
def test_actor_definition(repository_dir): with repository_dir.as_cwd(): logger = logging.getLogger('leapp.actor.test') with mock.patch.object(logger, 'log') as log_mock: definition = ActorDefinition('actors/test', '.', log=log_mock) for kind in set(DefinitionKind.REPO_WHITELIST + DefinitionKind.ACTOR_WHITELIST): if kind in DefinitionKind.ACTOR_WHITELIST: definition.add(kind, '.') else: with pytest.raises(UnsupportedDefinitionKindError): definition.add(kind, '.') log_mock.error.assert_called_with( "Attempt to add item type %s to actor that is not supported", kind.name) log_mock.reset_mock() with mock.patch('leapp.repository.actor_definition.get_actor_metadata', return_value=_FAKE_META_DATA): with mock.patch('leapp.repository.actor_definition.get_actors', return_value=[True]): definition._module = True assert definition.consumes == _FAKE_META_DATA['consumes'] assert definition.produces == _FAKE_META_DATA['produces'] assert definition.tags == _FAKE_META_DATA['tags'] assert definition.class_name == _FAKE_META_DATA['class_name'] assert definition.dialogs == _FAKE_META_DATA['dialogs'] assert definition.name == _FAKE_META_DATA['name'] assert definition.description == _FAKE_META_DATA['description'] dumped = definition.dump() assert dumped.pop('path') == _FAKE_META_DATA['path'] assert dumped.pop('name') == definition.name assert dumped.pop('files') == ('.',) assert dumped.pop('libraries') == ('.',) assert dumped.pop('tests') == ('.',) assert dumped.pop('tools') == ('.',) # Assert to ensure we covered all keys assert not dumped with pytest.raises(ActorInspectionFailedError): with mock.patch('leapp.repository.actor_definition.get_actors', return_value=[]): definition._discovery = None definition.discover() with pytest.raises(ActorInspectionFailedError): with mock.patch('leapp.repository.actor_definition.get_actors') as mocked_actors: mocked_actors.side_effect = RuntimeError('Test error') definition._discovery = None definition.discover() with pytest.raises(MultipleActorsError): with mock.patch('leapp.repository.actor_definition.get_actor_metadata', return_value=_FAKE_META_DATA): with mock.patch('leapp.repository.actor_definition.get_actors', return_value=[True, True]): definition._discovery = None definition.discover()
def test_different_objects_same_name_discover(repository_dir): with repository_dir.as_cwd(): check_call(['snactor', 'new-tag', 'winteriscoming']) check_call(['snactor', 'new-topic', 'winteriscoming']) check_call([ 'snactor', 'new-model', 'winteriscoming', '--topic', 'WinteriscomingTopic' ]) objs = [ 'tags/winteriscoming.py', 'topics/winteriscoming.py', 'models/winteriscoming.py' ] for obj in objs: assert repository_dir.join(obj).check(file=True) out = check_output(['snactor', 'discover']) for obj in objs: assert obj.encode('utf-8') in out
def test_discovery(repository_dir): with repository_dir.as_cwd(): check_call(['snactor', 'discover']) # Ensure snactor discover --json returns valid json output = check_output(['snactor', 'discover', '--json']).decode('utf-8') data = json.loads(output) assert 'actors' in data assert 'base_dir' in data and repository_dir.samefile(data['base_dir']) assert 'models' in data assert 'repository' in data assert 'tags' in data assert 'topics' in data with type(repository_dir)(path=repository_dir.dirname).as_cwd(): with pytest.raises(CalledProcessError): check_call(['snactor', 'discover'])
def test_not_implemented(repository_dir, stored): with repository_dir.as_cwd(): msg = BaseMessaging(stored=stored) if stored: with pytest.raises(NotImplementedError): msg.report_error('Some error', ErrorSeverity.ERROR, FakeActor(), details=None) with pytest.raises(NotImplementedError): msg.produce(UnitTestModel(), FakeActor()) with pytest.raises(NotImplementedError): msg.load(FakeActor.consumes) msg.consume(FakeActor()) msg.consume(FakeActor(), UnitTestModel) assert len(msg.errors()) == 0 assert len(msg.messages()) == 0 assert msg.stored == stored
def test_new_workflow(repository_dir): if repository_dir.join('workflows/test.py').check(file=True): # Test must have been run already return with repository_dir.as_cwd(): check_call(['snactor', 'workflow', 'new', 'Test']) assert repository_dir.join('workflows/test.py').check(file=True) check_call(['snactor', 'discover']) content = repository_dir.join('workflows/test.py').read() repository_dir.join('workflows/test.py').write('from leapp.tags import TestTag\n' + content + ''' class TestPhase(Phase): name = 'unit-test-workflow-phase' filter = TagFilter(TestTag) policies = Policies(Policies.Errors.FailPhase, Policies.Retry.Phase) flags = Flags() ''') check_call(['snactor', 'discover'])
def test_ref_model(repository_dir): # We need the topic to be created already if not repository_dir.join('topics/test.py').check(file=True): test_new_topic(repository_dir) with repository_dir.as_cwd(): # We need the model to be created already for the actor # So we have to check if it wasn't already created if not repository_dir.join('models/a.py').check(file=True): check_call(['snactor', 'new-model', 'A']) assert repository_dir.join('models/a.py').check(file=True) with pytest.raises(CalledProcessError): # Now discover should fail due to the missing topic check_call(['snactor', 'discover']) repository_dir.join('models/a.py').write(''' from leapp.models import Model, fields, TestModel from leapp.topics import TestTopic class A(Model): topic = TestTopic referenced = fields.Model(TestModel) ''') check_call(['snactor', 'discover'])
def test_run_workflow(repository_dir): # We need the workflow to be created already if not repository_dir.join('workflows/test.py').check(file=True): test_new_workflow(repository_dir) with pytest.raises(CalledProcessError): check_call(['snactor', 'workflow', 'run', 'Test']) with repository_dir.as_cwd(): check_call(['snactor', 'workflow', 'run', 'Test']) check_call(['snactor', '--debug', 'workflow', 'run', 'Test']) check_call(['snactor', 'workflow', '--debug', 'run', 'Test']) check_call(['snactor', 'workflow', 'run', '--debug', 'Test']) test_clear_messages(repository_dir) connection = audit.create_connection('.leapp/leapp.db') assert len( audit.get_messages( names=('TestModel', ), context=context.last_snactor_context(connection), connection=connection)) == 0 check_call( ['snactor', 'workflow', 'run', '--debug', '--save-output', 'Test']) assert len( audit.get_messages( names=('TestModel', ), context=context.last_snactor_context(connection), connection=connection)) == 1 check_call(['snactor', 'workflow', 'run', 'Test']) assert len( audit.get_messages( names=('TestModel', ), context=context.last_snactor_context(connection), connection=connection)) == 1 check_call(['snactor', 'workflow', 'run', '--save-output', 'Test']) assert len( audit.get_messages( names=('TestModel', ), context=context.last_snactor_context(connection), connection=connection)) == 2
def test_loading(repository_dir): with repository_dir.as_cwd(): msg = InProcessMessaging() with pytest.raises(CannotConsumeErrorMessages): msg.load((ErrorModel, )) msg.load((UnitTestModel, )) v = UnitTestModel() consumed = tuple(msg.consume(FakeActor(), UnitTestModel)) assert len(consumed) == 1 assert len(msg.messages()) == 0 assert consumed[0] == v consumed = tuple(msg.consume(FakeActor(), UnitTestModelUnused)) assert len(consumed) == 0 assert len(msg.messages()) == 0 consumed = tuple(msg.consume(FakeActor())) assert len(consumed) == 1 assert len(msg.messages()) == 0 assert consumed[0] == v consumed = tuple(msg.consume(FakeActor(), UnitTestModelUnused)) assert len(consumed) == 0 assert len(msg.messages()) == 0
def test_requires_repository(repository_dir): with pytest.raises(CommandError): _test_repository_dir_presence() with repository_dir.as_cwd(): _test_repository_dir_presence()
def test_new_tag(repository_dir): with repository_dir.as_cwd(): check_call(['snactor', 'new-tag', 'Test']) assert repository_dir.join('tags/test.py').check(file=True) check_call(['snactor', 'discover'])
def test_clear_messages(repository_dir): with repository_dir.as_cwd(): check_call(['snactor', 'messages', 'clear'])