<reponame>MPIB/SingularityAutobuild
# -*- coding: utf-8 -*-
""" Test the functions that work with recipes and images.

"""

import os
import re
import types
import unittest
from subprocess import call

from singularity_autobuild.autobuild_logger import get_stdout_logger
from singularity_autobuild.image_recipe_tools import (dependency_drill_down,
                                                      dependency_resolver,
                                                      get_collection_from_recipe_path,
                                                      get_dependency_from_recipe,
                                                      get_image_name_from_recipe,
                                                      get_path_from_dependency,
                                                      get_version_from_recipe,
                                                      image_in_sregistry,
                                                      image_pusher,
                                                      is_own_dependency,
                                                      recipe_finder,
                                                      recipe_list_sanity_check)
from singularity_autobuild.singularity_builder import Builder
from singularity_autobuild.test.configurator import configure_test_recipe

LOGGER = get_stdout_logger()

RECIPE_CONF = configure_test_recipe()['TEST_RECIPE']

RECIPE_FILE_PATH = RECIPE_CONF['recipe_file_path']
COLLECTION = RECIPE_CONF['collection_name']
MODULE_DIR = os.path.abspath(os.path.dirname(__file__))


class TestImageInSRegistry(unittest.TestCase):
    """ Test the function to check, if an image already exists in the sregistry. """

    def setUp(self):
        os.environ['SREGISTRY_CLIENT'] = 'registry'
        self.builder = Builder(recipe_path=RECIPE_FILE_PATH, image_type='simg')
        _build_info = self.builder.build()
        self.collection = _build_info
        self.image_path = _build_info['image_full_path']
        self.collection = _build_info['collection_name']
        self.version = _build_info['image_version']
        self.image = _build_info['container_name']

        image_pusher(
            image_path=self.image_path,
            collection=self.collection,
            version=self.version,
            image=self.image
        )

    def test_image_in_sregistry(self):
        """ Tested function should return correct boolean for image existence. """
        self.assertTrue(image_in_sregistry(
            collection=self.collection,
            version=self.version,
            image=self.image
        ))

        call([
            'sregistry',
            'delete',
            '-f',
            "%s/%s:%s" % (self.collection, self.image, self.version)
            ])

        self.assertFalse(image_in_sregistry(
            collection=self.collection,
            version=self.version,
            image=self.image
        ))



    def tearDown(self):
        LOGGER.debug("Deleting local test image.")
        os.remove(self.image_path)

class TestRecipeFinder(unittest.TestCase):
    """ Test the generator that returns directory and file information. """

    RECIPE_GRANDPARENT_FOLDER = MODULE_DIR

    def test_exceptions(self):
        """ Test if specified exceptions are raised. """
        with self.assertRaises(OSError):
            next(recipe_finder(path=os.path.abspath(__file__)))

    def test_recipe_finder(self):
        """ Test if recipes can be found and returned as expected. """
        _finder = recipe_finder(self.RECIPE_GRANDPARENT_FOLDER)
        self.assertIsInstance(_finder, types.GeneratorType)
        _recipe = next(_finder)
        self.assertEqual(_recipe, RECIPE_FILE_PATH)

class TestImagePusher(unittest.TestCase):
    """ Test the function to Push an image to an sregistry. """

    image_path = ''
    collection = ''
    version = ''
    image = ''

    def setUp(self):
        os.environ['SREGISTRY_CLIENT'] = 'registry'
        _builder = Builder(recipe_path=RECIPE_FILE_PATH, image_type='simg')
        _build_info = _builder.build()
        self.image_path = _build_info['image_full_path']
        self.collection = _build_info['collection_name']
        self.version = _build_info['image_version']
        self.image = _build_info['container_name']

    def test_image_pusher(self):
        """ Test the image upload function. """
        self.assertTrue(
            image_pusher(
                image_path=self.image_path,
                collection=self.collection,
                version=self.version,
                image=self.image
                )
        )
        _exit_code_image_pushed = 0
        # Does the image exist inside the sregistry?
        self.assertEqual(
            call([
                'sregistry',
                'search',
                "%s/%s:%s" % (self.collection, self.image, self.version)
                ]),
            _exit_code_image_pushed
        )

    def tearDown(self):
        LOGGER.debug("Deleting remote test image.")
        os.remove(self.image_path)
        call([
            'sregistry',
            'delete',
            '-f',
            "%s/%s:%s" % (self.collection, self.image, self.version)
            ])

class TestInfoFromRecipe(unittest.TestCase):
    """Test the functions to return collection, image version and name given a recipe."""

    TEST_IMAGE_NAME = 'test_recipe'
    TEST_VERSIONED_RECIPE_NAME = TEST_IMAGE_NAME+'.%s.recipe'
    TEST_RECIPE_NAME = TEST_IMAGE_NAME+'.recipe'

    def test_get_coll_from_recipe_path(self):
        """Test the function to return the collection name given a recipes full path."""
        _test_collection_name = 'collection_test'
        _test_collection_full_path = '/test/' + _test_collection_name
        _recipe_file_name = self.TEST_VERSIONED_RECIPE_NAME % '1.0'
        _recipe_path = '%s/%s' % (
            _test_collection_full_path,
            _recipe_file_name
        )
        self.assertEqual(
            _test_collection_name,
            get_collection_from_recipe_path(
                recipe_file_full_path=_recipe_path
            )
        )


    def test_get_version_from_recipe(self):
        """Test the function to return image version given a recipe name."""
        _recipe_version = '1.0'
        _recipe_with_version = self.TEST_VERSIONED_RECIPE_NAME % (_recipe_version)
        _recipe_latest = self.TEST_RECIPE_NAME

        self.assertEqual(
            _recipe_version,
            get_version_from_recipe(recipe_file_name=_recipe_with_version)
        )
        self.assertEqual(
            'latest',
            get_version_from_recipe(recipe_file_name=_recipe_latest)
        )

    def test_get_image_name_from_recipe(self):
        """Test the function to return image name given a recipe name."""
        _recipe_file_name = self.TEST_VERSIONED_RECIPE_NAME % "1.0"
        _image_name = self.TEST_IMAGE_NAME

        self.assertEqual(
            _image_name,
            get_image_name_from_recipe(recipe_file_name=_recipe_file_name)
            )

class TestDependencyResolver(unittest.TestCase):
    """ Test the function, that sorts a list of recipe files on their dependencies. """

    def setUp(self):
        self.main_recipe = RECIPE_FILE_PATH
        # Recipe containing folder
        _recipe_folder_path = os.path.dirname(self.main_recipe)
        # Just its filename
        _recipe_file_name = os.path.basename(self.main_recipe)
        # Name of the image it creates
        _image_name = get_image_name_from_recipe(_recipe_file_name)
        # Version of the image it creates
        _image_version = get_version_from_recipe(_recipe_file_name)
        # Collection of the image it creates
        _collection = get_collection_from_recipe_path(self.main_recipe)
        # The Base folder for all recipes
        self.recipe_base_folder_path = os.path.dirname(
            os.path.dirname(RECIPE_FILE_PATH)
        )

        _sregistry_host_name_raw = os.environ['SREGISTRY_HOSTNAME']
        # Strip protocol part from the hostname
        _host_name = re.sub(r'^http[s]?:\/\/(.*)$', r'\1', _sregistry_host_name_raw)

        _child_version = float(1.0)
        _child_name = "test_dependency"
        self.child_dependency_file = "%s/%s.%s.recipe" % (
            _recipe_folder_path,
            _child_name,
            str(_child_version)
        )
        self.child_dependency = "%s/%s/%s:%s" % (
            _host_name,
            _collection,
            _image_name,
            _image_version
        )
        self.child_of_child_dependency_file = "%s/%s.%s.recipe" %(
            _recipe_folder_path,
            _child_name,
            str(_child_version+0.1)
        )
        self.child_of_child_dependency = "%s/%s/%s:%s" % (
            _host_name,
            _collection,
            _child_name,
            _child_version
        )
        # Set up mock recipes.
        # One that depends on the main recipe and
        # one that depends on the first.
        self.dependency_files = {
            self.child_dependency_file:
            "BOOTSTRAP: shub\nFROM: %s" % self.child_dependency,
            self.child_of_child_dependency_file:
            "BOOTSTRAP: shub\nFROM: %s" % self.child_of_child_dependency
        }

        # Create mock recipes.
        for filename in self.dependency_files:
            with open(filename, 'w') as file:
                file.write(self.dependency_files[filename])

    def test_get_dependency_from_recipe(self):
        """ Test the function, that reads the dependency from a recipes header. """
        _test_dependency = get_dependency_from_recipe(self.main_recipe)
        if 'shub' in _test_dependency:
            self.fail(msg='Dependency was read wrong')
        _test_dependency = get_dependency_from_recipe(self.child_dependency_file)
        self.assertIn('shub', _test_dependency)
        self.assertEqual(_test_dependency['shub'], self.child_dependency)

    def test_get_path_from_dependency(self):
        """ Test the function to get the recipe path from a dependency. """
        # Test for parent of first child
        _expected_file_path = self.main_recipe
        _test_file_path = get_path_from_dependency(
            recipe_dependency_value=self.child_dependency,
            recipe_base_folder_path=self.recipe_base_folder_path
        )
        self.assertEqual(_expected_file_path, _test_file_path)
        # Test for parent of child of child
        _expected_file_path = self.child_dependency_file
        _test_file_path = get_path_from_dependency(
            recipe_dependency_value=self.child_of_child_dependency,
            recipe_base_folder_path=self.recipe_base_folder_path
        )
        self.assertEqual(_expected_file_path, _test_file_path)

    def test_is_own_dependency(self):
        """ Test the function that checks if dependency is to a private sregistry."""
        self.assertFalse(is_own_dependency("collection/container:version"))
        self.assertTrue(is_own_dependency)

    def test_recipe_list_sanity_check(self):
        """ Test the function that finds recipes that would create images with the same name. """
        _sane_list = [
            "/path/to/project/collection/recipe_name.1.0.recipe",
            "/path/to/project/collection_two/recipe_name.1.0.recipe"
        ]
        _not_sane_list = [
            "/path/to/project/collection/recipe_name.1.0.recipe",
            "/path/to/project/subfolder/collection/recipe_name.1.0.recipe"
        ]

        try:
            self.assertIsNone(recipe_list_sanity_check(_sane_list))
        except RuntimeError:
            self.fail(msg="%s should not fail on a sane list." % str(recipe_list_sanity_check))

        with self.assertRaises(RuntimeError):
            recipe_list_sanity_check(recipe_file_paths=_not_sane_list)

    def test_dependency_resolver(self):
        """ Test the function that orders a list on recipe dependencies. """
        _unordered_recipe_list = [
            self.child_of_child_dependency_file,
            self.main_recipe,
            self.child_dependency_file
        ]
        _ordered_recipe_list = [
            self.main_recipe,
            self.child_dependency_file,
            self.child_of_child_dependency_file
        ]
        _test_list = dependency_resolver(
            recipe_file_paths=_unordered_recipe_list,
            recipe_base_path=self.recipe_base_folder_path)

        self.assertEqual(_test_list, _ordered_recipe_list)

    def test_dependency_drill_down(self):
        """ Test the function that follows a single dependency chain. """
        _expected_dict = {
            self.main_recipe: 0,
            self.child_dependency_file: 1,
            self.child_of_child_dependency_file: 2
        }
        # Set up dict without any work done.
        _test_dependency_dict = {
        }
        dependency_drill_down(
            dependency_dict=_test_dependency_dict,
            recipe_path=self.child_of_child_dependency_file,
            recipe_base_path=self.recipe_base_folder_path
        )
        # Test function for dict without any work done.
        self.assertEqual(
            _expected_dict,
            _test_dependency_dict
        )
        # Set up dict with some work done.
        _test_dependency_dict = {
            self.main_recipe: 0,
            self.child_dependency_file: 1,
        }
        dependency_drill_down(
            dependency_dict=_test_dependency_dict,
            recipe_path=self.child_of_child_dependency_file,
            recipe_base_path=self.recipe_base_folder_path
        )
        # Test function for dict with some work done.
        self.assertEqual(
            _expected_dict,
            _test_dependency_dict
        )


    def tearDown(self):
        for filename in self.dependency_files:
            os.remove(filename)

# -*- coding: utf-8 -*-
""" Test the functions that work with recipes and images.

"""

import os
import re
import types
import unittest
from subprocess import call

from singularity_autobuild.autobuild_logger import get_stdout_logger
from singularity_autobuild.image_recipe_tools import (dependency_drill_down,
                                                      dependency_resolver,
                                                      get_collection_from_recipe_path,
                                                      get_dependency_from_recipe,
                                                      get_image_name_from_recipe,
                                                      get_path_from_dependency,
                                                      get_version_from_recipe,
                                                      image_in_sregistry,
                                                      image_pusher,
                                                      is_own_dependency,
                                                      recipe_finder,
                                                      recipe_list_sanity_check)
from singularity_autobuild.singularity_builder import Builder
from singularity_autobuild.test.configurator import configure_test_recipe

LOGGER = get_stdout_logger()

RECIPE_CONF = configure_test_recipe()['TEST_RECIPE']

RECIPE_FILE_PATH = RECIPE_CONF['recipe_file_path']
COLLECTION = RECIPE_CONF['collection_name']
MODULE_DIR = os.path.abspath(os.path.dirname(__file__))


class TestImageInSRegistry(unittest.TestCase):
    """ Test the function to check, if an image already exists in the sregistry. """

    def setUp(self):
        os.environ['SREGISTRY_CLIENT'] = 'registry'
        self.builder = Builder(recipe_path=RECIPE_FILE_PATH, image_type='simg')
        _build_info = self.builder.build()
        self.collection = _build_info
        self.image_path = _build_info['image_full_path']
        self.collection = _build_info['collection_name']
        self.version = _build_info['image_version']
        self.image = _build_info['container_name']

        image_pusher(
            image_path=self.image_path,
            collection=self.collection,
            version=self.version,
            image=self.image
        )

    def test_image_in_sregistry(self):
        """ Tested function should return correct boolean for image existence. """
        self.assertTrue(image_in_sregistry(
            collection=self.collection,
            version=self.version,
            image=self.image
        ))

        call([
            'sregistry',
            'delete',
            '-f',
            "%s/%s:%s" % (self.collection, self.image, self.version)
            ])

        self.assertFalse(image_in_sregistry(
            collection=self.collection,
            version=self.version,
            image=self.image
        ))



    def tearDown(self):
        LOGGER.debug("Deleting local test image.")
        os.remove(self.image_path)

class TestRecipeFinder(unittest.TestCase):
    """ Test the generator that returns directory and file information. """

    RECIPE_GRANDPARENT_FOLDER = MODULE_DIR

    def test_exceptions(self):
        """ Test if specified exceptions are raised. """
        with self.assertRaises(OSError):
            next(recipe_finder(path=os.path.abspath(__file__)))

    def test_recipe_finder(self):
        """ Test if recipes can be found and returned as expected. """
        _finder = recipe_finder(self.RECIPE_GRANDPARENT_FOLDER)
        self.assertIsInstance(_finder, types.GeneratorType)
        _recipe = next(_finder)
        self.assertEqual(_recipe, RECIPE_FILE_PATH)

class TestImagePusher(unittest.TestCase):
    """ Test the function to Push an image to an sregistry. """

    image_path = ''
    collection = ''
    version = ''
    image = ''

    def setUp(self):
        os.environ['SREGISTRY_CLIENT'] = 'registry'
        _builder = Builder(recipe_path=RECIPE_FILE_PATH, image_type='simg')
        _build_info = _builder.build()
        self.image_path = _build_info['image_full_path']
        self.collection = _build_info['collection_name']
        self.version = _build_info['image_version']
        self.image = _build_info['container_name']

    def test_image_pusher(self):
        """ Test the image upload function. """
        self.assertTrue(
            image_pusher(
                image_path=self.image_path,
                collection=self.collection,
                version=self.version,
                image=self.image
                )
        )
        _exit_code_image_pushed = 0
        # Does the image exist inside the sregistry?
        self.assertEqual(
            call([
                'sregistry',
                'search',
                "%s/%s:%s" % (self.collection, self.image, self.version)
                ]),
            _exit_code_image_pushed
        )

    def tearDown(self):
        LOGGER.debug("Deleting remote test image.")
        os.remove(self.image_path)
        call([
            'sregistry',
            'delete',
            '-f',
            "%s/%s:%s" % (self.collection, self.image, self.version)
            ])

class TestInfoFromRecipe(unittest.TestCase):
    """Test the functions to return collection, image version and name given a recipe."""

    TEST_IMAGE_NAME = 'test_recipe'
    TEST_VERSIONED_RECIPE_NAME = TEST_IMAGE_NAME+'.%s.recipe'
    TEST_RECIPE_NAME = TEST_IMAGE_NAME+'.recipe'

    def test_get_coll_from_recipe_path(self):
        """Test the function to return the collection name given a recipes full path."""
        _test_collection_name = 'collection_test'
        _test_collection_full_path = '/test/' + _test_collection_name
        _recipe_file_name = self.TEST_VERSIONED_RECIPE_NAME % '1.0'
        _recipe_path = '%s/%s' % (
            _test_collection_full_path,
            _recipe_file_name
        )
        self.assertEqual(
            _test_collection_name,
            get_collection_from_recipe_path(
                recipe_file_full_path=_recipe_path
            )
        )


    def test_get_version_from_recipe(self):
        """Test the function to return image version given a recipe name."""
        _recipe_version = '1.0'
        _recipe_with_version = self.TEST_VERSIONED_RECIPE_NAME % (_recipe_version)
        _recipe_latest = self.TEST_RECIPE_NAME

        self.assertEqual(
            _recipe_version,
            get_version_from_recipe(recipe_file_name=_recipe_with_version)
        )
        self.assertEqual(
            'latest',
            get_version_from_recipe(recipe_file_name=_recipe_latest)
        )

    def test_get_image_name_from_recipe(self):
        """Test the function to return image name given a recipe name."""
        _recipe_file_name = self.TEST_VERSIONED_RECIPE_NAME % "1.0"
        _image_name = self.TEST_IMAGE_NAME

        self.assertEqual(
            _image_name,
            get_image_name_from_recipe(recipe_file_name=_recipe_file_name)
            )

class TestDependencyResolver(unittest.TestCase):
    """ Test the function, that sorts a list of recipe files on their dependencies. """

    def setUp(self):
        self.main_recipe = RECIPE_FILE_PATH
        # Recipe containing folder
        _recipe_folder_path = os.path.dirname(self.main_recipe)
        # Just its filename
        _recipe_file_name = os.path.basename(self.main_recipe)
        # Name of the image it creates
        _image_name = get_image_name_from_recipe(_recipe_file_name)
        # Version of the image it creates
        _image_version = get_version_from_recipe(_recipe_file_name)
        # Collection of the image it creates
        _collection = get_collection_from_recipe_path(self.main_recipe)
        # The Base folder for all recipes
        self.recipe_base_folder_path = os.path.dirname(
            os.path.dirname(RECIPE_FILE_PATH)
        )

        _sregistry_host_name_raw = os.environ['SREGISTRY_HOSTNAME']
        # Strip protocol part from the hostname
        _host_name = re.sub(r'^http[s]?:\/\/(.*)$', r'\1', _sregistry_host_name_raw)

        _child_version = float(1.0)
        _child_name = "test_dependency"
        self.child_dependency_file = "%s/%s.%s.recipe" % (
            _recipe_folder_path,
            _child_name,
            str(_child_version)
        )
        self.child_dependency = "%s/%s/%s:%s" % (
            _host_name,
            _collection,
            _image_name,
            _image_version
        )
        self.child_of_child_dependency_file = "%s/%s.%s.recipe" %(
            _recipe_folder_path,
            _child_name,
            str(_child_version+0.1)
        )
        self.child_of_child_dependency = "%s/%s/%s:%s" % (
            _host_name,
            _collection,
            _child_name,
            _child_version
        )
        # Set up mock recipes.
        # One that depends on the main recipe and
        # one that depends on the first.
        self.dependency_files = {
            self.child_dependency_file:
            "BOOTSTRAP: shub\nFROM: %s" % self.child_dependency,
            self.child_of_child_dependency_file:
            "BOOTSTRAP: shub\nFROM: %s" % self.child_of_child_dependency
        }

        # Create mock recipes.
        for filename in self.dependency_files:
            with open(filename, 'w') as file:
                file.write(self.dependency_files[filename])

    def test_get_dependency_from_recipe(self):
        """ Test the function, that reads the dependency from a recipes header. """
        _test_dependency = get_dependency_from_recipe(self.main_recipe)
        if 'shub' in _test_dependency:
            self.fail(msg='Dependency was read wrong')
        _test_dependency = get_dependency_from_recipe(self.child_dependency_file)
        self.assertIn('shub', _test_dependency)
        self.assertEqual(_test_dependency['shub'], self.child_dependency)

    def test_get_path_from_dependency(self):
        """ Test the function to get the recipe path from a dependency. """
        # Test for parent of first child
        _expected_file_path = self.main_recipe
        _test_file_path = get_path_from_dependency(
            recipe_dependency_value=self.child_dependency,
            recipe_base_folder_path=self.recipe_base_folder_path
        )
        self.assertEqual(_expected_file_path, _test_file_path)
        # Test for parent of child of child
        _expected_file_path = self.child_dependency_file
        _test_file_path = get_path_from_dependency(
            recipe_dependency_value=self.child_of_child_dependency,
            recipe_base_folder_path=self.recipe_base_folder_path
        )
        self.assertEqual(_expected_file_path, _test_file_path)

    def test_is_own_dependency(self):
        """ Test the function that checks if dependency is to a private sregistry."""
        self.assertFalse(is_own_dependency("collection/container:version"))
        self.assertTrue(is_own_dependency)

    def test_recipe_list_sanity_check(self):
        """ Test the function that finds recipes that would create images with the same name. """
        _sane_list = [
            "/path/to/project/collection/recipe_name.1.0.recipe",
            "/path/to/project/collection_two/recipe_name.1.0.recipe"
        ]
        _not_sane_list = [
            "/path/to/project/collection/recipe_name.1.0.recipe",
            "/path/to/project/subfolder/collection/recipe_name.1.0.recipe"
        ]

        try:
            self.assertIsNone(recipe_list_sanity_check(_sane_list))
        except RuntimeError:
            self.fail(msg="%s should not fail on a sane list." % str(recipe_list_sanity_check))

        with self.assertRaises(RuntimeError):
            recipe_list_sanity_check(recipe_file_paths=_not_sane_list)

    def test_dependency_resolver(self):
        """ Test the function that orders a list on recipe dependencies. """
        _unordered_recipe_list = [
            self.child_of_child_dependency_file,
            self.main_recipe,
            self.child_dependency_file
        ]
        _ordered_recipe_list = [
            self.main_recipe,
            self.child_dependency_file,
            self.child_of_child_dependency_file
        ]
        _test_list = dependency_resolver(
            recipe_file_paths=_unordered_recipe_list,
            recipe_base_path=self.recipe_base_folder_path)

        self.assertEqual(_test_list, _ordered_recipe_list)

    def test_dependency_drill_down(self):
        """ Test the function that follows a single dependency chain. """
        _expected_dict = {
            self.main_recipe: 0,
            self.child_dependency_file: 1,
            self.child_of_child_dependency_file: 2
        }
        # Set up dict without any work done.
        _test_dependency_dict = {
        }
        dependency_drill_down(
            dependency_dict=_test_dependency_dict,
            recipe_path=self.child_of_child_dependency_file,
            recipe_base_path=self.recipe_base_folder_path
        )
        # Test function for dict without any work done.
        self.assertEqual(
            _expected_dict,
            _test_dependency_dict
        )
        # Set up dict with some work done.
        _test_dependency_dict = {
            self.main_recipe: 0,
            self.child_dependency_file: 1,
        }
        dependency_drill_down(
            dependency_dict=_test_dependency_dict,
            recipe_path=self.child_of_child_dependency_file,
            recipe_base_path=self.recipe_base_folder_path
        )
        # Test function for dict with some work done.
        self.assertEqual(
            _expected_dict,
            _test_dependency_dict
        )


    def tearDown(self):
        for filename in self.dependency_files:
            os.remove(filename)
# -*- coding: utf-8 -*- Test the functions that work with recipes and images. Test the function to check, if an image already exists in the sregistry. Tested function should return correct boolean for image existence. Test the generator that returns directory and file information. Test if specified exceptions are raised. Test if recipes can be found and returned as expected. Test the function to Push an image to an sregistry. Test the image upload function. # Does the image exist inside the sregistry? Test the functions to return collection, image version and name given a recipe. Test the function to return the collection name given a recipes full path. Test the function to return image version given a recipe name. Test the function to return image name given a recipe name. Test the function, that sorts a list of recipe files on their dependencies. # Recipe containing folder # Just its filename # Name of the image it creates # Version of the image it creates # Collection of the image it creates # The Base folder for all recipes # Strip protocol part from the hostname # Set up mock recipes. # One that depends on the main recipe and # one that depends on the first. # Create mock recipes. Test the function, that reads the dependency from a recipes header. Test the function to get the recipe path from a dependency. # Test for parent of first child # Test for parent of child of child Test the function that checks if dependency is to a private sregistry. Test the function that finds recipes that would create images with the same name. Test the function that orders a list on recipe dependencies. Test the function that follows a single dependency chain. # Set up dict without any work done. # Test function for dict without any work done. # Set up dict with some work done. # Test function for dict with some work done.