Exemplo n.º 1
0
    def test_check_secrets(self):
        os.environ['SECRET_ONE'] = '1234'
        os.environ['SECRET_TWO'] = '5678'
        pu.write_file(
            '/tmp/test_folder/a.workflow', """
        workflow "sample" {
            resolves = "a"
        }

        action "a" {
            uses = "popperized/bin/sh@master"
            args = ["ls -ltr"]
            secrets = ["SECRET_ONE", "SECRET_TWO"]
        }
        """)
        wf = Workflow('/tmp/test_folder/a.workflow')
        wf.parse()
        WorkflowRunner.check_secrets(wf, False, False)
        WorkflowRunner.check_secrets(wf, True, False)
        WorkflowRunner.check_secrets(wf, False, True)

        os.environ.pop('SECRET_ONE')
        pu.write_file(
            '/tmp/test_folder/a.workflow', """
        workflow "sample" {
            resolves = "a"
        }

        action "a" {
            uses = "popperized/bin/sh@master"
            args = ["ls -ltr"]
            secrets = ["SECRET_ONE", "SECRET_TWO"]
        }
        """)
        wf = Workflow('/tmp/test_folder/a.workflow')
        wf.parse()
        os.environ['CI'] = 'false'
        with patch('getpass.getpass', return_value='1234') as fake_input:
            WorkflowRunner.check_secrets(wf, False, False)

        os.environ['CI'] = 'true'
        os.environ.pop('SECRET_ONE')
        self.assertRaises(SystemExit, WorkflowRunner.check_secrets, wf, False,
                          False)
Exemplo n.º 2
0
def cli(ctx, wfile, skip, recursive, colors):
    """
    Creates a graph in the .dot format representing the workflow.
    """
    def add_to_graph(dot_str, wf, parent, children, node_attrs, stage_edges):
        """Recursively goes over the children ("next" attribute) of the given
        parent, adding an edge from parent to children
        """
        for n in children:
            edge = '  "{}" -> "{}";\n'.format(parent, n)
            if edge in stage_edges:
                continue
            dot_str += edge + '  "{}" [{}];\n'.format(n, node_attrs)

            stage_edges.add(edge)

            for M in wf.get_action(n).get('next', []):
                dot_str = add_to_graph(dot_str, wf, n, [M], node_attrs,
                                       stage_edges)
        return dot_str

    wfile_list = list()

    if recursive:
        wfile_list = pu.find_recursive_wfile()
    else:
        wfile_list.append(pu.find_default_wfile(wfile))

    for wfile in wfile_list:
        wf = Workflow(wfile)
        wf.parse()
        wf = Workflow.skip_actions(wf, skip)
        wf.check_for_unreachable_actions()

        node_attrs = ('shape=box, style="filled{}", fillcolor=transparent{}')
        wf_attr = node_attrs.format(',rounded', ',color=red' if colors else '')
        act_attr = node_attrs.format('', ',color=cyan' if colors else '')
        dot_str = add_to_graph("", wf, wf.name, wf.root, act_attr, set())
        dot_str += '  "{}" [{}];\n'.format(wf.name, wf_attr)
        log.info("digraph G { graph [bgcolor=transparent];\n" + dot_str +
                 "}\n")
Exemplo n.º 3
0
    def test_download_actions(self):
        pu.write_file(
            '/tmp/test_folder/a.workflow', """
        workflow "sample" {
            resolves = "a"
        }

        action "a" {
            uses = "popperized/bin/sh@master"
        }

        action "b" {
            uses = "popperized/ansible@master"
        }
        """)
        wf = Workflow('/tmp/test_folder/a.workflow')
        wf.parse()

        # Download actions in the default cache directory.
        WorkflowRunner.download_actions(wf, False, False, '12345')
        self.assertEqual(
            os.path.exists(os.environ['HOME'] +
                           '/.cache/.popper/actions/12345/github.com'), True)

        # Download actions in custom cache directory
        os.environ['POPPER_CACHE_DIR'] = '/tmp/somedir'
        WorkflowRunner.download_actions(wf, False, False, '12345')
        self.assertEqual(
            os.path.exists('/tmp/somedir/actions/12345/github.com'), True)
        os.environ.pop('POPPER_CACHE_DIR')

        # Release resources.
        shutil.rmtree('/tmp/somedir')
        shutil.rmtree(os.environ['HOME'] +
                      '/.cache/.popper/actions/12345/github.com')

        # Test with skipclone flag when action not present in cache.
        self.assertRaises(SystemExit, WorkflowRunner.download_actions, wf,
                          False, True, '12345')
Exemplo n.º 4
0
    def test_get_workflow_env(self):
        pu.write_file(
            '/tmp/test_folder/a.workflow', """
        workflow "sample" {
            resolves = "a"
        }

        action "a" {
            uses = "sh"
        }
        """)
        wf = Workflow('/tmp/test_folder/a.workflow')
        wf.parse()
        env = WorkflowRunner.get_workflow_env(wf, '/tmp/test_folder')
        self.assertDictEqual(
            env, {
                'HOME': os.environ['HOME'],
                'GITHUB_WORKFLOW': 'sample',
                'GITHUB_ACTION': '',
                'GITHUB_ACTOR': 'popper',
                'GITHUB_REPOSITORY': 'unknown',
                'GITHUB_EVENT_NAME': 'push',
                'GITHUB_EVENT_PATH': '/tmp/github_event.json',
                'GITHUB_WORKSPACE': '/tmp/test_folder',
                'GITHUB_SHA': 'unknown',
                'GITHUB_REF': 'unknown',
                'POPPER_WORKFLOW': 'sample',
                'POPPER_ACTION': '',
                'POPPER_ACTOR': 'popper',
                'POPPER_REPOSITORY': 'unknown',
                'POPPER_EVENT_NAME': 'push',
                'POPPER_EVENT_PATH': '/tmp/github_event.json',
                'POPPER_WORKSPACE': '/tmp/test_folder',
                'POPPER_SHA': 'unknown',
                'POPPER_REF': 'unknown'
            })
Exemplo n.º 5
0
    def test_instantiate_runners(self):
        pu.write_file(
            '/tmp/test_folder/a.workflow', """
        workflow "sample" {
            resolves = "a"
        }

        action "a" {
            uses = "sh"
            args = "ls"
        }
        """)
        wf = Workflow('/tmp/test_folder/a.workflow')
        wf.parse()
        env = WorkflowRunner.get_workflow_env(wf, '/tmp/test_folder')
        WorkflowRunner.instantiate_runners('docker', wf, '/tmp/test_folder',
                                           False, False, '12345')
        self.assertIsInstance(wf.action['a']['runner'], HostRunner)

        os.makedirs('/tmp/test_folder/actions/sample')
        pu.write_file('/tmp/test_folder/actions/sample/entrypoint.sh')
        pu.write_file('/tmp/test_folder/actions/sample/README.md')

        pu.write_file(
            '/tmp/test_folder/a.workflow', """
        workflow "sample" {
            resolves = "a"
        }

        action "a" {
            uses = "./actions/sample"

        }
        """)
        wf = Workflow('/tmp/test_folder/a.workflow')
        wf.parse()
        env = WorkflowRunner.get_workflow_env(wf, '/tmp/test_folder')
        WorkflowRunner.instantiate_runners('singularity', wf,
                                           '/tmp/test_folder', False, False,
                                           '12345')
        self.assertIsInstance(wf.action['a']['runner'], HostRunner)

        pu.write_file(
            '/tmp/test_folder/a.workflow', """
        workflow "sample" {
            resolves = "a"
        }

        action "a" {
            uses = "popperized/bin/sh@master"
        }
        """)
        wf = Workflow('/tmp/test_folder/a.workflow')
        wf.parse()
        env = WorkflowRunner.get_workflow_env(wf, '/tmp/test_folder')
        WorkflowRunner.instantiate_runners('singularity', wf,
                                           '/tmp/test_folder', False, False,
                                           '12345')
        self.assertIsInstance(wf.action['a']['runner'], SingularityRunner)

        WorkflowRunner.instantiate_runners('docker', wf, '/tmp/test_folder',
                                           False, False, '12345')
        self.assertIsInstance(wf.action['a']['runner'], DockerRunner)

        WorkflowRunner.instantiate_runners('vagrant', wf, '/tmp/test_folder',
                                           False, False, '12345')
        self.assertIsInstance(wf.action['a']['runner'], VagrantRunner)
Exemplo n.º 6
0
class TestHostRunner(unittest.TestCase):
    def setUp(self):
        os.makedirs('/tmp/test_folder')
        os.chdir('/tmp/test_folder')
        log.setLevel('CRITICAL')
        workflow = """
        workflow "sample" {
            resolves = "sample action"
        }

        action "sample action" {
            uses = "sh"
            args = ["echo", "Hello"]
        }
        """
        pu.write_file('/tmp/test_folder/a.workflow', workflow)
        self.wf = Workflow('/tmp/test_folder/a.workflow')
        self.wf.parse()
        WorkflowRunner.instantiate_runners('docker', self.wf,
                                           '/tmp/test_folder', False, False,
                                           '12345')

    def tearDown(self):
        os.chdir('/tmp')
        shutil.rmtree('/tmp/test_folder')
        log.setLevel('NOTSET')

    def test_run(self):
        runner = self.wf.action['sample action']['runner']
        self.assertRaises(SystemExit, runner.run, reuse=True)
        runner.run()

    def test_host_prepare(self):
        runner = self.wf.action['sample action']['runner']
        runner.action['runs'] = ['script1']
        runner.action['args'] = ['github.com']
        cmd = runner.host_prepare()
        self.assertEqual(cmd, ['/tmp/test_folder/script1', 'github.com'])
        os.makedirs('/tmp/test_folder/action/myaction')
        runner.action['uses'] = './action/myaction'
        runner.action['runs'] = ['script']
        runner.action['args'] = ['arg1', 'arg2']
        cmd = runner.host_prepare()
        self.assertEqual(
            cmd,
            ['/tmp/test_folder/./action/myaction/./script', 'arg1', 'arg2'])
        os.chdir('/tmp/test_folder')
        runner.action.pop('runs')
        cmd = runner.host_prepare()
        self.assertEqual(cmd, [
            '/tmp/test_folder/./action/myaction/./entrypoint.sh', 'arg1',
            'arg2'
        ])

    def test_host_start(self):
        runner = self.wf.action['sample action']['runner']
        runner.prepare_environment(set_env=True)
        e = runner.host_start(
            ["sh", "-c", "echo 'Hello from Popper 2.x !' > popper.file"])
        self.assertEqual(e, 0)
        self.assertEqual(os.path.exists('popper.file'), True)
        runner.remove_environment()
Exemplo n.º 7
0
class TestVagrantRunner(unittest.TestCase):
    def setUp(self):
        os.makedirs('/tmp/test_folder')
        os.chdir('/tmp/test_folder')
        log.setLevel('CRITICAL')
        workflow = """
        workflow "sample" {
            resolves = "sample action"
        }

        action "sample action" {
            uses = "popperized/bin/sh@master"
            args = ["echo", "Hello"]
        }
        """
        pu.write_file('/tmp/test_folder/a.workflow', workflow)
        self.wf = Workflow('/tmp/test_folder/a.workflow')
        self.wf.parse()
        WorkflowRunner.download_actions(self.wf, False, False, '12345')
        WorkflowRunner.instantiate_runners('vagrant', self.wf,
                                           '/tmp/test_folder', False, False,
                                           '12345')
        self.runner = self.wf.action['sample action']['runner']
        VagrantRunner.setup_vagrant_cache('12345')

    def tearDown(self):
        os.chdir('/tmp')
        shutil.rmtree('/tmp/test_folder')
        log.setLevel('NOTSET')

    @unittest.skipIf(os.environ['RUNTIME'] != 'vagrant',
                     'Skipping vagrant tests...')
    def test_setup_vagrant_cache(self):
        cache_path = os.path.join(os.environ['HOME'],
                                  '.cache/.popper/vagrant/12345')
        shutil.rmtree(cache_path)
        self.assertEqual(os.path.exists(cache_path), False)
        VagrantRunner.setup_vagrant_cache('12345')
        self.assertEqual(os.path.exists(cache_path), True)

    @unittest.skipIf(os.environ['RUNTIME'] != 'vagrant',
                     'Skipping vagrant tests...')
    def test_vagrant_start(self):
        os.makedirs('/tmp/test_folder/test_vm')
        vagrantfile_content = """
        Vagrant.configure("2") do |config|
            config.vm.box = "ailispaw/barge"
        end
        """
        pu.write_file('/tmp/test_folder/test_vm/Vagrantfile',
                      vagrantfile_content)
        self.runner.vagrant_start('/tmp/test_folder/test_vm')
        self.assertEqual(
            self.runner.vagrant_exists('/tmp/test_folder/test_vm'), True)
        vagrant.Vagrant(root='/tmp/test_folder/test_vm').halt()
        vagrant.Vagrant(root='/tmp/test_folder/test_vm').destroy()

    @unittest.skipIf(os.environ['RUNTIME'] != 'vagrant',
                     'Skipping vagrant tests...')
    def test_vagrant_stop(self):
        os.makedirs('/tmp/test_folder/test_vm')
        vagrantfile_content = """
        Vagrant.configure("2") do |config|
            config.vm.box = "ailispaw/barge"
        end
        """
        pu.write_file('/tmp/test_folder/test_vm/Vagrantfile',
                      vagrantfile_content)
        v = vagrant.Vagrant(root='/tmp/test_folder/test_vm')
        v.up()
        self.assertEqual(
            self.runner.vagrant_exists('/tmp/test_folder/test_vm'), True)
        self.runner.vagrant_stop('/tmp/test_folder/test_vm')
        self.assertEqual(
            self.runner.vagrant_exists('/tmp/test_folder/test_vm'), False)
        vagrant.Vagrant(root='/tmp/test_folder/test_vm').destroy()

    @unittest.skipIf(os.environ['RUNTIME'] != 'vagrant',
                     'Skipping vagrant tests...')
    def test_vagrant_exists(self):
        os.makedirs('/tmp/test_folder/test_vm')
        vagrantfile_content = """
        Vagrant.configure("2") do |config|
            config.vm.box = "ailispaw/barge"
        end
        """
        pu.write_file('/tmp/test_folder/test_vm/Vagrantfile',
                      vagrantfile_content)
        v = vagrant.Vagrant(root='/tmp/test_folder/test_vm')
        v.up()
        self.assertEqual(
            self.runner.vagrant_exists('/tmp/test_folder/test_vm'), True)
        v.halt()
        self.assertEqual(
            self.runner.vagrant_exists('/tmp/test_folder/test_vm'), False)
        vagrant.Vagrant(root='/tmp/test_folder/test_vm').destroy()
        shutil.rmtree('/tmp/test_folder/test_vm')
        self.assertEqual(
            self.runner.vagrant_exists('/tmp/test_folder/test_vm'), False)

    @unittest.skipIf(os.environ['RUNTIME'] != 'vagrant',
                     'Skipping vagrant tests...')
    def test_vagrant_write_vagrantfile(self):
        self.runner.vagrant_write_vagrantfile('/tmp/test_folder/test_vm')
        required_content = """
        Vagrant.configure("2") do |config|
            config.vm.box = "ailispaw/barge"
            config.vm.synced_folder "{}", "{}"
            config.vm.synced_folder "/tmp/test_folder", "/tmp/test_folder"
        end
        """.format(os.environ['HOME'], os.environ['HOME'])
        f = open('/tmp/test_folder/test_vm/Vagrantfile')
        content = f.readlines()
        f.close()
        for line in content:
            self.assertEqual(line in required_content, True)
Exemplo n.º 8
0
class TestSingularityRunner(unittest.TestCase):
    def setUp(self):
        os.makedirs('/tmp/test_folder')
        os.chdir('/tmp/test_folder')
        log.setLevel('CRITICAL')
        workflow = """
        workflow "sample" {
            resolves = "sample action"
        }

        action "sample action" {
            uses = "popperized/bin/sh@master"
            args = ["echo", "Hello"]
        }
        """
        pu.write_file('/tmp/test_folder/a.workflow', workflow)
        self.wf = Workflow('/tmp/test_folder/a.workflow')
        self.wf.parse()
        WorkflowRunner.download_actions(self.wf, False, False, '12345')
        WorkflowRunner.instantiate_runners('singularity', self.wf,
                                           '/tmp/test_folder', False, False,
                                           '12345')
        self.runner = self.wf.action['sample action']['runner']
        SingularityRunner.setup_singularity_cache('12345')

    def tearDown(self):
        os.chdir('/tmp')
        shutil.rmtree('/tmp/test_folder')
        shutil.rmtree(os.path.join(os.environ['HOME'], '.cache/.popper'))
        log.setLevel('NOTSET')

    @unittest.skipIf(os.environ['RUNTIME'] != 'singularity',
                     'Skipping singularity tests...')
    def test_singularity_exists(self):
        pu.write_file('/tmp/test_folder/testimg.sif', 'fake image file')
        self.assertEqual(
            self.runner.singularity_exists('/tmp/test_folder/testimg.sif'),
            True)
        os.remove('/tmp/test_folder/testimg.sif')

    @unittest.skipIf(os.environ['RUNTIME'] != 'singularity',
                     'Skipping singularity tests...')
    def test_singularity_rm(self):
        pu.write_file('/tmp/test_folder/testimg.sif', 'fake image file')
        self.runner.singularity_rm('/tmp/test_folder/testimg.sif')
        self.assertEqual(
            self.runner.singularity_exists('/tmp/test_folder/testimg.sif'),
            False)

    @unittest.skipIf(os.environ['RUNTIME'] != 'singularity',
                     'Skipping singularity tests...')
    def test_singularity_build_from_image(self):
        self.runner.singularity_build_from_image(
            'docker://*****:*****@unittest.skipIf(os.environ['RUNTIME'] != 'singularity',
                     'Skipping singularity tests...')
    def test_singularity_build_from_recipe(self):
        os.chdir(
            os.path.join(
                os.environ['HOME'],
                '.cache/.popper/actions/12345/github.com/popperized/bin/sh'))
        self.runner.singularity_build_from_recipe(
            os.path.join(
                os.environ['HOME'],
                '.cache/.popper/actions/12345/github.com/popperized/bin/sh'),
            os.path.join(os.environ['HOME'],
                         '.cache/.popper/singularity/12345/testimg.sif'))
        self.assertEqual(
            os.path.exists(
                os.path.join(os.environ['HOME'],
                             '.cache/.popper/singularity/12345/testimg.sif')),
            True)

    @unittest.skipIf(os.environ['RUNTIME'] != 'singularity',
                     'Skipping singularity tests...')
    def test_get_recipe_file(self):
        os.chdir(os.environ['HOME'] +
                 '/.cache/.popper/actions/12345/github.com/popperized/bin/sh')
        file = SingularityRunner.get_recipe_file(os.getcwd(), '12345')
        self.assertEqual(
            file, os.environ['HOME'] +
            '/.cache/.popper/actions/12345/github.com/popperized/bin/sh/' +
            'Singularity.12345')
        os.remove(
            os.environ['HOME'] +
            '/.cache/.popper/actions/12345/github.com/popperized/bin/sh/' +
            'Dockerfile')
        self.assertRaises(SystemExit, SingularityRunner.get_recipe_file,
                          os.getcwd(), '12345')

    @unittest.skipIf(os.environ['RUNTIME'] != 'singularity',
                     'Skipping singularity tests...')
    def test_singularity_start(self):
        self.runner.action['runs'] = [
            "sh", "-c", "echo 'Hello from Popper 2.x !' > popper.file"
        ]
        self.runner.singularity_build_from_image(
            'docker://*****:*****@unittest.skipIf(os.environ['RUNTIME'] != 'singularity',
                     'Skipping singularity tests...')
    def test_get_build_resources(self):
        res = self.runner.get_build_resources()
        self.assertTupleEqual(
            res,
            (True, 'popperized/bin/sh@master',
             os.path.join(
                 os.environ['HOME'],
                 '.cache/.popper/actions/12345/github.com/popperized/bin/sh')))
        self.runner.action['uses'] = 'docker://*****:*****@unittest.skipIf(os.environ['RUNTIME'] != 'singularity',
                     'Skipping singularity tests...')
    def test_setup_singularity_cache(self):
        cache_path = os.path.join(os.environ['HOME'],
                                  '.cache/.popper/singularity/12345')
        shutil.rmtree(cache_path)
        self.assertEqual(os.path.exists(cache_path), False)
        SingularityRunner.setup_singularity_cache('12345')
        self.assertEqual(os.path.exists(cache_path), True)
Exemplo n.º 9
0
class TestDockerRunner(unittest.TestCase):
    def setUp(self):
        os.makedirs('/tmp/test_folder')
        os.chdir('/tmp/test_folder')
        log.setLevel('CRITICAL')
        workflow = """
        workflow "sample" {
            resolves = "sample action"
        }

        action "sample action" {
            uses = "popperized/bin/sh@master"
            args = ["echo", "Hello"]
        }
        """
        pu.write_file('/tmp/test_folder/a.workflow', workflow)
        self.wf = Workflow('/tmp/test_folder/a.workflow')
        self.wf.parse()
        WorkflowRunner.download_actions(self.wf, False, False, '12345')
        WorkflowRunner.instantiate_runners('docker', self.wf,
                                           '/tmp/test_folder', False, False,
                                           '12345')
        self.docker_client = docker.from_env()
        self.runner = self.wf.action['sample action']['runner']

    def tearDown(self):
        os.chdir('/tmp')
        shutil.rmtree('/tmp/test_folder')
        shutil.rmtree(os.path.join(os.environ['HOME'], '.cache/.popper'))
        log.setLevel('NOTSET')
        self.docker_client.close()

    @unittest.skipIf(os.environ['RUNTIME'] != 'docker',
                     'Skipping docker tests...')
    def test_get_build_resources(self):
        res = self.runner.get_build_resources()
        self.assertTupleEqual(
            res,
            (True, 'popperized/bin:master', os.environ['HOME'] +
             '/.cache/.popper/actions/12345/github.com/popperized/bin/sh'))
        self.runner.action['uses'] = 'docker://*****:*****@unittest.skipIf(os.environ['RUNTIME'] != 'docker',
                     'Skipping docker tests...')
    def test_docker_exists(self):
        image = self.docker_client.images.pull('debian:buster-slim')
        container = self.docker_client.containers.create(
            image='debian:buster-slim', name='popper_sample_action_12345')
        self.assertEqual(self.runner.docker_exists(), True)
        container.remove()
        self.docker_client.images.remove('debian:buster-slim')

    @unittest.skipIf(os.environ['RUNTIME'] != 'docker',
                     'Skipping docker tests...')
    def test_docker_image_exists(self):
        image = self.docker_client.images.pull('debian:buster-slim')
        self.assertEqual(self.runner.docker_image_exists('debian:buster-slim'),
                         True)
        self.docker_client.images.remove('debian:buster-slim', force=True)

    @unittest.skipIf(os.environ['RUNTIME'] != 'docker',
                     'Skipping docker tests...')
    def test_docker_rm(self):
        self.docker_client.images.pull('debian:buster-slim')
        self.runner.docker_create('debian:buster-slim')
        self.runner.docker_rm()
        self.assertRaises(docker.errors.NotFound, self.runner.docker_rm)

    @unittest.skipIf(os.environ['RUNTIME'] != 'docker',
                     'Skipping docker tests...')
    def test_docker_pull(self):
        self.assertEqual(self.runner.docker_image_exists('debian:buster-slim'),
                         False)
        self.runner.skip_pull = True
        self.assertRaises(SystemExit, self.runner.docker_pull,
                          'debian:buster-slim')
        self.runner.skip_pull = False
        self.runner.docker_pull('debian:buster-slim')
        self.assertEqual(self.runner.docker_image_exists('debian:buster-slim'),
                         True)

    @unittest.skipIf(os.environ['RUNTIME'] != 'docker',
                     'Skipping docker tests...')
    def test_docker_start(self):
        self.runner.action['runs'] = [
            "sh", "-c", "echo 'Hello from Popper 2.x !' > popper.file"
        ]
        self.runner.docker_pull('debian:buster-slim')
        self.runner.docker_create('debian:buster-slim')
        e = self.runner.docker_start()
        self.assertEqual(e, 0)
        self.assertEqual(os.path.exists('popper.file'), True)
        res = self.docker_client.containers.list(filters={'status': 'running'})
        self.assertListEqual(res, [])
        self.runner.docker_rm()

    @unittest.skipIf(os.environ['RUNTIME'] != 'docker',
                     'Skipping docker tests...')
    def test_docker_build(self):
        pu.write_file(
            '/tmp/test_folder/Dockerfile', """
        FROM debian:stable-slim

        RUN apt-get update && \
            apt-get install curl -y && \
            apt-get clean -y
        """)
        self.runner.docker_build('abcd:latest', '/tmp/test_folder')
        res = self.docker_client.images.get('abcd:latest')

    @unittest.skipIf(os.environ['RUNTIME'] != 'docker',
                     'Skipping docker tests...')
    def test_docker_create(self):
        self.runner.action['args'] = ['env']
        self.runner.docker_pull('debian:buster-slim')
        self.runner.docker_create('debian:buster-slim')
        self.assertEqual(self.runner.docker_exists(), True)
        self.runner.docker_rm()
Exemplo n.º 10
0
class TestActionRunner(unittest.TestCase):
    def setUp(self):
        os.makedirs('/tmp/test_folder')
        os.chdir('/tmp/test_folder')
        log.setLevel('CRITICAL')
        workflow = """
        workflow "sample" {
            resolves = "sample action"
        }

        action "sample action" {
            uses = "popperized/bin/sh@master"
            args = ["echo", "Hello"]
        }
        """
        pu.write_file('/tmp/test_folder/a.workflow', workflow)
        self.wf = Workflow('/tmp/test_folder/a.workflow')
        self.wf.parse()
        WorkflowRunner.instantiate_runners('docker', self.wf,
                                           '/tmp/test_folder', False, False,
                                           '12345')
        self.runner = self.wf.action['sample action']['runner']

    def tearDown(self):
        os.chdir('/tmp')
        shutil.rmtree('/tmp/test_folder')
        log.setLevel('NOTSET')

    def test_check_executable(self):
        self.assertRaises(SystemExit, self.runner.check_executable, 'abcd')

    def test_handle_exit(self):
        self.flag = 0

        def signal_handler(sig, frame):
            self.flag = 1

        signal.signal(signal.SIGUSR1, signal_handler)
        self.assertRaises(SystemExit, self.runner.handle_exit, 1)
        self.runner.handle_exit(0)
        self.assertEqual(self.flag, 0)
        self.runner.handle_exit(78)
        self.assertEqual(self.flag, 1)

    def test_prepare_environment(self):
        env = self.runner.prepare_environment()
        self.assertDictEqual(
            env, {
                'HOME': os.environ['HOME'],
                'GITHUB_WORKFLOW': 'sample',
                'GITHUB_ACTION': 'sample action',
                'GITHUB_ACTOR': 'popper',
                'GITHUB_REPOSITORY': 'unknown',
                'GITHUB_EVENT_NAME': 'push',
                'GITHUB_EVENT_PATH': '/tmp/github_event.json',
                'GITHUB_WORKSPACE': '/tmp/test_folder',
                'GITHUB_SHA': 'unknown',
                'GITHUB_REF': 'unknown',
                'POPPER_WORKFLOW': 'sample',
                'POPPER_ACTION': 'sample action',
                'POPPER_ACTOR': 'popper',
                'POPPER_REPOSITORY': 'unknown',
                'POPPER_EVENT_NAME': 'push',
                'POPPER_EVENT_PATH': '/tmp/github_event.json',
                'POPPER_WORKSPACE': '/tmp/test_folder',
                'POPPER_SHA': 'unknown',
                'POPPER_REF': 'unknown'
            })

        self.assertEqual(set(env.keys()).issubset(set(os.environ)), False)
        env = self.runner.prepare_environment(set_env=True)
        self.assertEqual(set(env.keys()).issubset(set(os.environ)), True)
        self.runner.remove_environment()

    def test_prepare_volumes(self):
        env = self.runner.prepare_environment()
        volumes = self.runner.prepare_volumes(env)
        self.assertEqual(volumes, [
            '{}:{}'.format(os.environ['HOME'], os.environ['HOME']),
            '{}:/github/home'.format(
                os.environ['HOME']), '/tmp/test_folder:/tmp/test_folder',
            '/tmp/test_folder:/github/workspace',
            '/tmp/github_event.json:/github/workflow/event.json'
        ])
        volumes = self.runner.prepare_volumes(env, include_docker_socket=True)
        self.assertEqual(volumes, [
            '/var/run/docker.sock:/var/run/docker.sock', '{}:{}'.format(
                os.environ['HOME'],
                os.environ['HOME']), '{}:/github/home'.format(
                    os.environ['HOME']), '/tmp/test_folder:/tmp/test_folder',
            '/tmp/test_folder:/github/workspace',
            '/tmp/github_event.json:/github/workflow/event.json'
        ])

    def test_remove_environment(self):
        env = self.runner.prepare_environment(set_env=True)
        self.assertEqual(set(env.keys()).issubset(set(os.environ)), True)
        self.runner.remove_environment()
        self.assertEqual(set(env.keys()).issubset(set(os.environ)), False)

    def test_setup_necessary_files(self):
        os.remove('/tmp/github_event.json')
        self.assertEqual(os.path.exists('/tmp/github_event.json'), False)
        self.runner.setup_necessary_files()
        self.assertEqual(os.path.exists('/tmp/github_event.json'), True)
        self.runner.workspace = '/tmp/a/b/c'
        self.runner.setup_necessary_files()
        self.assertEqual(os.path.exists('/tmp/a/b/c'), True)
Exemplo n.º 11
0
    def test_get_stages(self):
        self.create_workflow_file("""
        workflow "example" {
        resolves = "end"
        }

        action "a" {
        uses = "sh"
        args = "ls"
        }

        action "b" {
        uses = "sh"
        args = "ls"
        }

        action "c" {
        uses = "sh"
        args = "ls"
        }

        action "d" {
        needs = ["c"]
        uses = "sh"
        args = "ls"
        }

        action "e" {
        needs = ["d", "b", "a"]
        uses = "sh"
        args = "ls"
        }

        action "end" {
        needs = "e"
        uses = "sh"
        args = "ls"
        }
        """)
        wf = Workflow('/tmp/test_folder/a.workflow')
        wf.parse()
        stages = list()
        for stage in wf.get_stages():
            stages.append(stage)

        self.assertListEqual(stages, [{'b', 'c', 'a'}, {'d'}, {'e'}, {'end'}])

        self.create_workflow_file("""
        workflow "example" {
            resolves = ["end"]
        }

        action "a" {
            uses = "sh"
            args = "ls"
        }

        action "b" {
            needs = "a"
            uses = "sh"
            args = "ls"
        }

        action "c" {
            uses = "sh"
            args = "ls"
        }

        action "d" {
            uses = "sh"
            needs = ["b", "c"]
            args = "ls"
        }

        action "g" {
            needs = "d"
            uses = "sh"
            args = "ls"
        }

        action "f" {
            needs = "d"
            uses = "sh"
            args = "ls"
        }

        action "h" {
            needs = "g"
            uses = "sh"
            args = "ls"
        }

        action "end" {
            needs = ["h", "f"]
            uses = "sh"
            args = "ls"
        }
        """)
        wf = Workflow('/tmp/test_folder/a.workflow')
        wf.parse()
        stages = list()
        for stage in wf.get_stages():
            stages.append(stage)

        self.assertListEqual(
            stages, [{'a', 'c'}, {'b'}, {'d'}, {'g', 'f'}, {'h'}, {'end'}])
Exemplo n.º 12
0
    def test_check_for_unreachable_actions(self):
        self.create_workflow_file("""
        workflow "example" {
        resolves = "end"
        }

        action "a" {
        uses = "sh"
        args = "ls"
        }

        action "b" {
        uses = "sh"
        args = "ls"
        }

        action "c" {
        uses = "sh"
        args = "ls"
        }

        action "d" {
        needs = ["c"]
        uses = "sh"
        args = "ls"
        }

        action "e" {
        needs = ["d", "b", "a"]
        uses = "sh"
        args = "ls"
        }

        action "end" {
        needs = "e"
        uses = "sh"
        args = "ls"
        }
        """)
        wf = Workflow('/tmp/test_folder/a.workflow')
        wf.parse()
        changed_wf = Workflow.skip_actions(wf, ['d', 'a', 'b'])
        self.assertDictEqual(
            changed_wf.action, {
                'a': {
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'a',
                    'next': set()
                },
                'b': {
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'b',
                    'next': set()
                },
                'c': {
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'c',
                    'next': set()
                },
                'd': {
                    'needs': [],
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'd',
                    'next': set()
                },
                'e': {
                    'needs': [],
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'e',
                    'next': {'end'}
                },
                'end': {
                    'needs': ['e'],
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'end'
                }
            })
        self.assertRaises(SystemExit, changed_wf.check_for_unreachable_actions,
                          True)

        self.create_workflow_file("""
        workflow "sample" {
            resolves = ["reachable"]
        }

        action "reachable" {
            uses = "popperized/bin/sh@master"
            args = "ls"
        }

        action "unreachable" {
            uses = "popperized/bin/sh@master"
            args = ["ls -ltr"]
        }
        """)
        wf = Workflow('/tmp/test_folder/a.workflow')
        wf.parse()
        wf.check_for_unreachable_actions()
Exemplo n.º 13
0
    def test_filter_action(self):
        self.create_workflow_file("""
        workflow "example" {
            resolves = "end"
            }

            action "a" {
            uses = "sh"
            args = "ls"
            }

            action "b" {
            uses = "sh"
            args = "ls"
            }

            action "c" {
            uses = "sh"
            args = "ls"
            }

            action "d" {
            needs = ["c"]
            uses = "sh"
            args = "ls"
            }

            action "e" {
            needs = ["d", "b", "a"]
            uses = "sh"
            args = "ls"
            }

            action "end" {
            needs = "e"
            uses = "sh"
            args = "ls"
            }
        """)
        wf = Workflow('/tmp/test_folder/a.workflow')
        wf.parse()
        changed_wf = Workflow.filter_action(wf, 'e')
        self.assertSetEqual(changed_wf.root, {'e'})
        self.assertDictEqual(
            changed_wf.action, {
                'e': {
                    'needs': [],
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'e',
                    'next': set()
                }
            })

        changed_wf = Workflow.filter_action(wf, 'd')
        self.assertSetEqual(changed_wf.root, {'d'})
        self.assertDictEqual(
            changed_wf.action, {
                'd': {
                    'needs': [],
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'd',
                    'next': set()
                }
            })

        changed_wf = Workflow.filter_action(wf, 'e', with_dependencies=True)
        self.assertSetEqual(changed_wf.root, {'b', 'a', 'c'})
        self.assertDictEqual(
            changed_wf.action, {
                'a': {
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'a',
                    'next': {'e'}
                },
                'b': {
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'b',
                    'next': {'e'}
                },
                'c': {
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'c',
                    'next': {'d'}
                },
                'd': {
                    'needs': ['c'],
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'd',
                    'next': {'e'}
                },
                'e': {
                    'needs': ['d', 'b', 'a'],
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'e',
                    'next': set()
                }
            })

        changed_wf = Workflow.filter_action(wf, 'd', with_dependencies=True)
        self.assertSetEqual(changed_wf.root, {'c'})
        self.assertDictEqual(
            changed_wf.action, {
                'c': {
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'c',
                    'next': {'d'}
                },
                'd': {
                    'needs': ['c'],
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'd',
                    'next': set()
                }
            })
Exemplo n.º 14
0
    def test_skip_actions(self):
        self.create_workflow_file("""
        workflow "example" {
            resolves = "end"
            }

            action "a" {
            uses = "sh"
            args = "ls"
            }

            action "b" {
            uses = "sh"
            args = "ls"
            }

            action "c" {
            uses = "sh"
            args = "ls"
            }

            action "d" {
            needs = ["c"]
            uses = "sh"
            args = "ls"
            }

            action "e" {
            needs = ["d", "b", "a"]
            uses = "sh"
            args = "ls"
            }

            action "end" {
            needs = "e"
            uses = "sh"
            args = "ls"
            }
        """)
        wf = Workflow('/tmp/test_folder/a.workflow')
        wf.parse()
        changed_wf = Workflow.skip_actions(wf, ['b'])
        self.assertDictEqual(
            changed_wf.action, {
                'a': {
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'a',
                    'next': {'e'}
                },
                'b': {
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'b',
                    'next': set()
                },
                'c': {
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'c',
                    'next': {'d'}
                },
                'd': {
                    'needs': ['c'],
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'd',
                    'next': {'e'}
                },
                'e': {
                    'needs': ['d', 'a'],
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'e',
                    'next': {'end'}
                },
                'end': {
                    'needs': ['e'],
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'end'
                }
            })

        changed_wf = Workflow.skip_actions(wf, ['d', 'a'])
        self.assertDictEqual(
            changed_wf.action, {
                'a': {
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'a',
                    'next': set()
                },
                'b': {
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'b',
                    'next': {'e'}
                },
                'c': {
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'c',
                    'next': set()
                },
                'd': {
                    'needs': [],
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'd',
                    'next': set()
                },
                'e': {
                    'needs': ['b'],
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'e',
                    'next': {'end'}
                },
                'end': {
                    'needs': ['e'],
                    'uses': 'sh',
                    'args': ['ls'],
                    'name': 'end'
                }
            })