avocado-framework/avocado

View on GitHub
selftests/functional/serial/requirements.py

Summary

Maintainability
A
2 hrs
Test Coverage
import glob
import os

from avocado import Test, skipUnless
from avocado.core import exit_codes
from avocado.utils import process, script
from selftests.utils import AVOCADO, TestCaseTmpDir

SINGLE_SUCCESS_CHECK = '''from avocado import Test


class SuccessTest(Test):

    def test_check(self):
        """
        :avocado: dependency={"type": "package", "name": "bash", "action": "check"}
        """
'''

SINGLE_FAIL_CHECK = '''from avocado import Test


class FailTest(Test):

    def test_check(self):
        """
        :avocado: dependency={"type": "package", "name": "-foo-bar-", "action": "check"}
        """
'''

MULTIPLE_SUCCESS = '''from avocado import Test
from avocado.utils import process


class SuccessTest(Test):

    def check_hello(self):
        result = process.run("hello", ignore_status=True)
        self.assertEqual(result.exit_status, 0)
        self.assertIn('Hello, world!', result.stdout_text,)

    def test_a(self):
        """
        :avocado: dependency={"type": "package", "name": "hello"}
        """
        self.check_hello()

    def test_b(self):
        """
        :avocado: dependency={"type": "package", "name": "hello"}
        """
        self.check_hello()

    def test_c(self):
        """
        :avocado: dependency={"type": "package", "name": "hello"}
        """
        self.check_hello()
'''

MULTIPLE_FAIL = '''from avocado import Test
from avocado.utils import process


class FailTest(Test):

    def test_a(self):
        """
        :avocado: dependency={"type": "package", "name": "hello"}
        :avocado: dependency={"type": "package", "name": "-foo-bar-"}
        """
    def test_b(self):
        """
        :avocado: dependency={"type": "package", "name": "hello"}
        """
        result = process.run("hello", ignore_status=True)
        self.assertEqual(result.exit_status, 0)
        self.assertIn('Hello, world!', result.stdout_text,)

    def test_c(self):
        """
        :avocado: dependency={"type": "package", "name": "hello"}
        :avocado: dependency={"type": "package", "name": "-foo-bar-"}
        """
'''

SINGLE_SUCCESS_DUPLCITIES = '''from avocado import Test
from avocado.utils import process


class SuccessTest(Test):

    def check_hello(self):
        result = process.run("hello", ignore_status=True)
        self.assertEqual(result.exit_status, 0)
        self.assertIn('Hello, world!', result.stdout_text,)

    def test_a(self):
        """
        :avocado: dependency={"type": "package", "name": "hello"}
        :avocado: dependency={"type": "package", "name": "hello"}
        :avocado: dependency={"type": "package", "name": "hello"}
        """
        self.check_hello()
'''

TEST_WITHOUT_DEPENDENCY = """from avocado import Test
from avocado.utils import process

class SuccessTest(Test):

    def check_hello(self):
        result = process.run("hello", ignore_status=True)
        self.assertEqual(result.exit_status, 0)
        self.assertIn('Hello, world!', result.stdout_text,)

    def test_a(self):
        self.check_hello()

    def test_b(self):
        self.check_hello()

    def test_c(self):
        self.check_hello()
"""

DEPENDENCY_FILE = """
[
    {"type": "package", "name": "hello"}
]
"""

DEPENDENCY_RECIPE_FMT = """
{
  "kind": "avocado-instrumented",
  "uri": "{path}",
  "kwargs": {"dependencies": [{"type": "package", "name": "hello"}]}
}
"""


class BasicTest(TestCaseTmpDir, Test):
    """
    :avocado: dependency={"type": "package", "name": "podman", "action": "check"}
    """

    skip_install_message = (
        "This test runs on CI environments only as it"
        " installs packages to test the feature, which"
        " may not be desired locally, in the user's"
        " system."
    )
    skip_package_manager_message = (
        "This test runs on CI environments only"
        " as it depends on the system package"
        " manager, and some environments don't"
        " have it available."
    )

    def get_command(self, path):
        spawner = self.params.get("spawner", default="process")
        spawner_command = ""
        if spawner == "podman":
            spawner_command = "--spawner=podman --spawner-podman-image=fedora:38"
        return f"{AVOCADO} run {spawner_command} --job-results-dir {self.tmpdir.name} {path}"

    @skipUnless(os.getenv("CI"), skip_package_manager_message)
    def test_single_success(self):
        with script.Script(
            os.path.join(self.tmpdir.name, "test_single_success.py"),
            SINGLE_SUCCESS_CHECK,
        ) as test:
            command = self.get_command(test.path)
            result = process.run(command, ignore_status=True)
            self.assertEqual(result.exit_status, exit_codes.AVOCADO_ALL_OK)
            self.assertIn(
                "PASS 1",
                result.stdout_text,
            )
            self.assertNotIn(
                "bash",
                result.stdout_text,
            )
            test_results_path = os.path.join(self.tmpdir.name, "latest", "test-results")
            self.assertEqual(
                len(os.listdir(test_results_path)),
                2,
                "DependencyResolver created unwanted result directories.",
            )
            test_dependency_dir = glob.glob(
                os.path.join(test_results_path, "1-*", "dependencies")
            )[0]
            self.assertEqual(
                len(os.listdir(test_dependency_dir)),
                1,
                "Dependency directories is missing.",
            )
            job_dependency_dir = os.path.join(
                self.tmpdir.name, "latest", "dependencies"
            )
            self.assertEqual(
                len(os.listdir(job_dependency_dir)),
                1,
                "Dependency symlink wasn't created.",
            )

    @skipUnless(os.getenv("CI"), skip_package_manager_message)
    def test_single_fail(self):
        with script.Script(
            os.path.join(self.tmpdir.name, "test_single_fail.py"), SINGLE_FAIL_CHECK
        ) as test:
            command = self.get_command(test.path)
            result = process.run(command, ignore_status=True)
            self.assertEqual(result.exit_status, exit_codes.AVOCADO_ALL_OK)
            self.assertIn(
                "PASS 0",
                result.stdout_text,
            )
            self.assertIn(
                "SKIP 1",
                result.stdout_text,
            )
            self.assertIn(
                "SKIP: Dependency was not fulfilled.",
                result.stdout_text,
            )
            self.assertNotIn(
                "-foo-bar-",
                result.stdout_text,
            )

    @skipUnless(os.getenv("CI"), skip_install_message)
    def test_multiple_success(self):
        with script.Script(
            os.path.join(self.tmpdir.name, "test_multiple_success.py"), MULTIPLE_SUCCESS
        ) as test:
            command = self.get_command(test.path)
            result = process.run(command, ignore_status=True)
            self.assertEqual(result.exit_status, exit_codes.AVOCADO_ALL_OK)
            self.assertIn(
                "PASS 3",
                result.stdout_text,
            )
            self.assertNotIn(
                "vim-common",
                result.stdout_text,
            )

    @skipUnless(os.getenv("CI"), skip_install_message)
    def test_multiple_fails(self):
        with script.Script(
            os.path.join(self.tmpdir.name, "test_multiple_fail.py"), MULTIPLE_FAIL
        ) as test:
            command = self.get_command(test.path)
            result = process.run(command, ignore_status=True)
            self.assertEqual(result.exit_status, exit_codes.AVOCADO_ALL_OK)
            self.assertIn(
                "PASS 1",
                result.stdout_text,
            )
            self.assertIn(
                "SKIP 2",
                result.stdout_text,
            )
            self.assertNotIn(
                "-foo-bar-",
                result.stdout_text,
            )

    @skipUnless(os.getenv("CI"), skip_install_message)
    def test_dependency_duplicates(self):
        with script.Script(
            os.path.join(self.tmpdir.name, "test_single_success.py"),
            SINGLE_SUCCESS_DUPLCITIES,
        ) as test:
            command = self.get_command(test.path)
            result = process.run(command, ignore_status=True)
            self.assertEqual(result.exit_status, exit_codes.AVOCADO_ALL_OK)
            self.assertIn(
                "PASS 1",
                result.stdout_text,
            )

    @skipUnless(os.getenv("CI"), skip_install_message)
    def test_job_dependency(self):
        with script.Script(
            os.path.join(self.tmpdir.name, "test_multiple_success.py"),
            TEST_WITHOUT_DEPENDENCY,
        ) as test:
            command = self.get_command(test.path)
            with script.Script(
                os.path.join(self.tmpdir.name, "dependency.json"), DEPENDENCY_FILE
            ) as dependency_config:
                command = f"{command} --job-dependency={dependency_config.path}"
                result = process.run(command, ignore_status=True)
                self.assertEqual(result.exit_status, exit_codes.AVOCADO_ALL_OK)
                self.assertIn(
                    "PASS 3",
                    result.stdout_text,
                )
                self.assertNotIn(
                    "vim-common",
                    result.stdout_text,
                )

    @skipUnless(os.getenv("CI"), skip_install_message)
    def test_dependency_recipe(self):
        with script.Script(
            os.path.join(self.tmpdir.name, "test_multiple_success.py"),
            TEST_WITHOUT_DEPENDENCY,
        ) as test:
            dependency_recipe_data = DEPENDENCY_RECIPE_FMT.format(
                path=f"{test.path}:SuccessTest.test_a"
            )
            with script.Script(
                os.path.join(self.tmpdir.name, "dependency_recipe.json"),
                dependency_recipe_data,
            ) as recipe:
                command = self.get_command(recipe.path)
                result = process.run(command, ignore_status=True)
                self.assertEqual(result.exit_status, exit_codes.AVOCADO_ALL_OK)
                self.assertIn(
                    "PASS 3",
                    result.stdout_text,
                )
                self.assertNotIn(
                    "vim-common",
                    result.stdout_text,
                )