Example #1
0
    def test_dependency_list(self):
        mgr = ComponentManager()
        loader = YamlConfigurationLoader(
            os.path.join(os.path.dirname(__file__),
                         "test_dependency_list.yml"))
        mgr.launch_configuration(loader.load_configuration())
        a = mgr.components["a"]
        b = mgr.components["b"]
        c = mgr.components["c"]
        d = mgr.components["d"]

        self.assertListEqual(a.others.get_list(), [b, c, d])

        for comp in (b, c, d):
            self.assertListEqual(comp.others.get_list(), [])

        # list.index implementation
        self.assertEqual(a.others.index(b), 0)
        self.assertEqual(a.others.index(c), 1)
        self.assertEqual(a.others.index(d), 2)

        # list subscript implementation
        self.assertEqual(a.others[0], b)
        self.assertEqual(a.others[1], c)
        self.assertEqual(a.others[2], d)

        # list.count implementation
        self.assertEqual(a.others.count(b), 1)
        self.assertEqual(a.others.count(c), 1)
        self.assertEqual(a.others.count(d), 1)

        # list __reversed__ implementation
        self.assertListEqual(list(reversed(a.others)), [d, c, b])
Example #2
0
def _find_kickers(candidates):
    """Given a set of candidates which may be python files or yaml, find kickers
    
    This function was added in order to be able to handle yaml files being
    used with epoxy in order to find kickers that are declared
    dynamically.

    """
    kickers = []
    for candidate in candidates:
        if candidate.endswith('.py'):
            kickers.append(candidate)
        elif candidate.endswith('.yml') or candidate.endswith('.yaml'):
            from epoxy.configuration import YamlConfigurationLoader
            loader = YamlConfigurationLoader(candidate)
            data = loader.load_configuration()
            for component_name, component in data.get('components',
                                                      {}).iteritems():
                class_path = component.get('class', None)
                if class_path is None:
                    continue
                module_name = class_path.split(':')[0]
                (file, pathname, _desc) = _fully_find_module(module_name)
                if os.path.isdir(pathname):
                    pathname = os.path.join(pathname, "__init__.py")
                kickers.append(pathname)

    # remove duplicates
    return list(set(kickers))
Example #3
0
    def test_dependency_list(self):
        mgr = ComponentManager()
        loader = YamlConfigurationLoader(
            os.path.join(os.path.dirname(__file__),
                         "test_dependency_list.yml"))
        mgr.launch_configuration(loader.load_configuration())
        a = mgr.components["a"]
        b = mgr.components["b"]
        c = mgr.components["c"]
        d = mgr.components["d"]

        self.assertListEqual(a.others.get_list(), [b, c, d])

        for comp in (b, c, d):
            self.assertListEqual(comp.others.get_list(), [])

        # list.index implementation
        self.assertEqual(a.others.index(b), 0)
        self.assertEqual(a.others.index(c), 1)
        self.assertEqual(a.others.index(d), 2)

        # list subscript implementation
        self.assertEqual(a.others[0], b)
        self.assertEqual(a.others[1], c)
        self.assertEqual(a.others[2], d)

        # list.count implementation
        self.assertEqual(a.others.count(b), 1)
        self.assertEqual(a.others.count(c), 1)
        self.assertEqual(a.others.count(d), 1)

        # list __reversed__ implementation
        self.assertListEqual(list(reversed(a.others)), [d, c, b])
Example #4
0
def _find_kickers(candidates):
    """Given a set of candidates which may be python files or yaml, find kickers
    
    This function was added in order to be able to handle yaml files being
    used with epoxy in order to find kickers that are declared
    dynamically.

    """
    kickers = []
    for candidate in candidates:
        if candidate.endswith(".py"):
            kickers.append(candidate)
        elif candidate.endswith(".yml") or candidate.endswith(".yaml"):
            from epoxy.configuration import YamlConfigurationLoader

            loader = YamlConfigurationLoader(candidate)
            data = loader.load_configuration()
            for component_name, component in data.get("components", {}).iteritems():
                class_path = component.get("class", None)
                if class_path is None:
                    continue
                module_name = class_path.split(":")[0]
                (file, pathname, _desc) = _fully_find_module(module_name)
                if os.path.isdir(pathname):
                    pathname = os.path.join(pathname, "__init__.py")
                kickers.append(pathname)

    # remove duplicates
    return list(set(kickers))
Example #5
0
 def test_graph_ordering(self):
     mgr = ComponentManager()
     loader = YamlConfigurationLoader(os.path.join(os.path.dirname(__file__), "test.yml"))
     graph = mgr.build_component_graph(loader.load_configuration())
     ordering = graph.get_ordering()
     o = [x.name for x in ordering]
     self.assertEqual(len(ordering), 5)  # our 4 plus component_manager
     self.assert_(o.index("b") > o.index("a"))
     self.assert_(o.index("c") > o.index("a"))
     self.assert_(o.index("d") > o.index("c"))
Example #6
0
    def test_configuration_extension(self):
        mgr = ComponentManager()
        loader = YamlConfigurationLoader(
            os.path.join(os.path.dirname(__file__),
                         "test_configuration_child.yml"))
        mgr.launch_configuration(loader.load_configuration(), debug=3)
        a = mgr.components["a"]
        b = mgr.components["b"]

        self.assertEqual(b.next, a)
Example #7
0
    def test_configuration_extension(self):
        mgr = ComponentManager()
        loader = YamlConfigurationLoader(
            os.path.join(os.path.dirname(__file__),
                         "test_configuration_child.yml"))
        mgr.launch_configuration(loader.load_configuration(), debug=3)
        a = mgr.components["a"]
        b = mgr.components["b"]

        self.assertEqual(b.next, a)
Example #8
0
    def test_invalid_class(self):
        mgr = ComponentManager()
        loader = YamlConfigurationLoader(os.path.join(os.path.dirname(__file__), "test.yml"))
        configuration = loader.load_configuration()

        # Change class to invalid component
        configuration["components"]["a"]["class"] = "epoxy.test.test_core:InvalidComponent"

        with self.assertRaises(AttributeError):
            mgr.launch_subgraph(configuration, "d:main")
Example #9
0
    def test_subgraph_cycle_detection(self):
        mgr = ComponentManager()
        loader = YamlConfigurationLoader(os.path.join(os.path.dirname(__file__), "test.yml"))
        configuration = loader.load_configuration()

        # Change class to invalid component
        configuration["components"]["a"]["dependencies"] = {"previous": "d"}

        with self.assertRaises(ValueError):
            mgr.launch_subgraph(configuration, "d:main")
Example #10
0
    def test_missing_component(self):
        mgr = ComponentManager()
        loader = YamlConfigurationLoader(os.path.join(os.path.dirname(__file__), "test.yml"))
        configuration = loader.load_configuration()

        # Delete required component
        del configuration["components"]["a"]

        with self.assertRaises(ValueError):
            mgr.launch_subgraph(configuration, "d:main")
Example #11
0
    def test_missing_component(self):
        mgr = ComponentManager()
        loader = YamlConfigurationLoader(
            os.path.join(os.path.dirname(__file__), "test.yml"))
        configuration = loader.load_configuration()

        # Delete required component
        del configuration['components']['a']

        with self.assertRaises(ValueError):
            mgr.launch_subgraph(configuration, 'd:main')
Example #12
0
 def test_graph_ordering(self):
     mgr = ComponentManager()
     loader = YamlConfigurationLoader(
         os.path.join(os.path.dirname(__file__), "test.yml"))
     graph = mgr.build_component_graph(loader.load_configuration())
     ordering = graph.get_ordering()
     o = [x.name for x in ordering]
     self.assertEqual(len(ordering), 5)  # our 4 plus component_manager
     self.assert_(o.index("b") > o.index("a"))
     self.assert_(o.index("c") > o.index("a"))
     self.assert_(o.index("d") > o.index("c"))
Example #13
0
    def test_subgraph_cycle_detection(self):
        mgr = ComponentManager()
        loader = YamlConfigurationLoader(
            os.path.join(os.path.dirname(__file__), "test.yml"))
        configuration = loader.load_configuration()

        # Change class to invalid component
        configuration['components']['a']['dependencies'] = {'previous': 'd'}

        with self.assertRaises(ValueError):
            mgr.launch_subgraph(configuration, 'd:main')
Example #14
0
 def test_graph_construction(self):
     mgr = ComponentManager()
     loader = YamlConfigurationLoader(os.path.join(os.path.dirname(__file__), "test.yml"))
     mgr.launch_configuration(loader.load_configuration())
     a = mgr.components["a"]
     b = mgr.components["b"]
     c = mgr.components["c"]
     d = mgr.components["d"]
     self.assertEqual(a.previous, None)
     self.assertEqual(b.previous, a)
     self.assertEqual(c.previous, a)
     self.assertEqual(d.previous, c)
Example #15
0
    def test_missing_item_in_dep_list(self):
        mgr = ComponentManager()
        loader = YamlConfigurationLoader(
            os.path.join(os.path.dirname(__file__),
                         "test_dependency_list.yml"))
        configuration = loader.load_configuration()

        # Delete component b
        del configuration['components']['b']

        with self.assertRaises(ValueError):
            mgr.launch_configuration(configuration)
Example #16
0
    def test_missing_item_in_dep_list(self):
        mgr = ComponentManager()
        loader = YamlConfigurationLoader(
            os.path.join(os.path.dirname(__file__),
                         "test_dependency_list.yml"))
        configuration = loader.load_configuration()

        # Delete component b
        del configuration['components']['b']

        with self.assertRaises(ValueError):
            mgr.launch_configuration(configuration)
Example #17
0
    def test_invalid_class(self):
        mgr = ComponentManager()
        loader = YamlConfigurationLoader(
            os.path.join(os.path.dirname(__file__), "test.yml"))
        configuration = loader.load_configuration()

        # Change class to invalid component
        configuration['components']['a']['class'] = \
            'epoxy.test.test_core:InvalidComponent'

        with self.assertRaises(AttributeError):
            mgr.launch_subgraph(configuration, 'd:main')
Example #18
0
 def test_graph_construction(self):
     mgr = ComponentManager()
     loader = YamlConfigurationLoader(
         os.path.join(os.path.dirname(__file__), "test.yml"))
     mgr.launch_configuration(loader.load_configuration())
     a = mgr.components["a"]
     b = mgr.components["b"]
     c = mgr.components["c"]
     d = mgr.components["d"]
     self.assertEqual(a.previous, None)
     self.assertEqual(b.previous, a)
     self.assertEqual(c.previous, a)
     self.assertEqual(d.previous, c)
Example #19
0
    def test_subgraph_construction(self):
        mgr = ComponentManager()
        loader = YamlConfigurationLoader(os.path.join(os.path.dirname(__file__), "test.yml"))
        mgr.launch_subgraph(loader.load_configuration(), "d:main")

        a = mgr.components["a"]
        with self.assertRaises(KeyError):
            mgr.components["b"]
        c = mgr.components["c"]
        d = mgr.components["d"]

        self.assertEqual(a.previous, None)
        self.assertEqual(c.previous, a)
        self.assertEqual(d.previous, c)

        self.assertFalse(a.is_main)
        self.assertFalse(c.is_main)
        self.assertTrue(d.is_main)
Example #20
0
    def test_subgraph_construction(self):
        mgr = ComponentManager()
        loader = YamlConfigurationLoader(
            os.path.join(os.path.dirname(__file__), "test.yml"))
        mgr.launch_subgraph(loader.load_configuration(), 'd:main')

        a = mgr.components["a"]
        with self.assertRaises(KeyError):
            mgr.components["b"]
        c = mgr.components["c"]
        d = mgr.components["d"]

        self.assertEqual(a.previous, None)
        self.assertEqual(c.previous, a)
        self.assertEqual(d.previous, c)

        self.assertFalse(a.is_main)
        self.assertFalse(c.is_main)
        self.assertTrue(d.is_main)
Example #21
0
    def test_entry_point(self):
        mgr = ComponentManager()
        loader = YamlConfigurationLoader(os.path.join(os.path.dirname(__file__), "test.yml"))
        configuration = loader.load_configuration()

        # Add entry-point to configuration
        configuration["entry-point"] = "d:main"

        mgr.launch_configuration(configuration)

        a = mgr.components["a"]
        b = mgr.components["b"]
        c = mgr.components["c"]
        d = mgr.components["d"]

        self.assertFalse(a.is_main)
        self.assertFalse(b.is_main)
        self.assertFalse(c.is_main)
        self.assertTrue(d.is_main)
Example #22
0
    def test_entry_point(self):
        mgr = ComponentManager()
        loader = YamlConfigurationLoader(
            os.path.join(os.path.dirname(__file__), "test.yml"))
        configuration = loader.load_configuration()

        # Add entry-point to configuration
        configuration['entry-point'] = 'd:main'

        mgr.launch_configuration(configuration)

        a = mgr.components["a"]
        b = mgr.components["b"]
        c = mgr.components["c"]
        d = mgr.components["d"]

        self.assertFalse(a.is_main)
        self.assertFalse(b.is_main)
        self.assertFalse(c.is_main)
        self.assertTrue(d.is_main)
Example #23
0
 def setUp(self):
     self.mgr = ComponentManager()
     self.loader = YamlConfigurationLoader(VALID_TEST_YAML)
     self.invalid_loader = YamlConfigurationLoader(INVALID_TEST_YAML)
     self.log = mock.Mock()
     epoxy_core.log = self.log
Example #24
0
class TestDependencyGraphResolution(unittest.TestCase):

    def setUp(self):
        self.mgr = ComponentManager()
        self.loader = YamlConfigurationLoader(VALID_TEST_YAML)
        self.invalid_loader = YamlConfigurationLoader(INVALID_TEST_YAML)
        self.log = mock.Mock()
        epoxy_core.log = self.log

    def test_graph_ordering(self):
        graph = self.mgr.build_component_graph(self.loader.load_configuration())
        ordering = graph.get_ordering()
        o = [x.name for x in ordering]
        self.assertEqual(len(ordering), 5)  # our 4 plus component_manager
        self.assert_(o.index("b") > o.index("a"))
        self.assert_(o.index("c") > o.index("a"))
        self.assert_(o.index("d") > o.index("c"))

    def test_graph_construction(self):
        self.mgr.launch_configuration(self.loader.load_configuration())
        a = self.mgr.components["a"]
        b = self.mgr.components["b"]
        c = self.mgr.components["c"]
        d = self.mgr.components["d"]
        self.assertEqual(a.previous, None)
        self.assertEqual(b.previous, a)
        self.assertEqual(c.previous, a)
        self.assertEqual(d.previous, c)

    def test_subgraph_construction(self):
        self.mgr.launch_subgraph(self.loader.load_configuration(), 'd:main')

        a = self.mgr.components["a"]
        with self.assertRaises(KeyError):
            self.mgr.components["b"]
        c = self.mgr.components["c"]
        d = self.mgr.components["d"]

        self.assertEqual(a.previous, None)
        self.assertEqual(c.previous, a)
        self.assertEqual(d.previous, c)

        self.assertFalse(a.is_main)
        self.assertFalse(c.is_main)
        self.assertTrue(d.is_main)

    def test_subgraph_bad_entry_point(self):
        with self.assertRaises(AttributeError):
            self.mgr.launch_subgraph(self.loader.load_configuration(), 'd:fake')
        last_log_message = self.log.call_args_list[0][0][0]
        self.assertEqual(last_log_message, "Bad entry point 'd:fake'")

    def test_bad_entry_point(self):
        cfg = self.invalid_loader.load_configuration()
        with self.assertRaises(AttributeError):
            self.mgr.launch_configuration(cfg)
        last_log_message = self.log.call_args_list[0][0][0]
        self.assertEqual(last_log_message, "Bad entry point 'a:fake_method'")

    def test_entry_point(self):
        configuration = self.loader.load_configuration()

        # Add entry-point to configuration
        configuration['entry-point'] = 'd:main'

        self.mgr.launch_configuration(configuration)

        a = self.mgr.components["a"]
        b = self.mgr.components["b"]
        c = self.mgr.components["c"]
        d = self.mgr.components["d"]

        self.assertFalse(a.is_main)
        self.assertFalse(b.is_main)
        self.assertFalse(c.is_main)
        self.assertTrue(d.is_main)

    def test_invalid_class(self):
        configuration = self.loader.load_configuration()

        # Change class to invalid component
        invalid_comp = 'epoxy.test.test_core:InvalidComponent'
        configuration['components']['a']['class'] = invalid_comp

        with self.assertRaises(AttributeError):
            self.mgr.launch_subgraph(configuration, 'd:main')
        last_logged_msg = self.log.call_args_list[0][0][0]
        self.assertEqual(last_logged_msg,
                         "Class path '%s' is invalid, check your epoxy config" % invalid_comp)

    def test_missing_component(self):
        configuration = self.loader.load_configuration()

        # Delete required component
        del configuration['components']['a']

        with self.assertRaises(ValueError):
            self.mgr.launch_subgraph(configuration, 'd:main')

    def test_cycle_detection(self):
        configuration = self.loader.load_configuration()

        # Change class to invalid component
        configuration['components']['a']['dependencies'] = {'previous': 'd'}

        with self.assertRaises(ValueError):
            self.mgr.launch_configuration(configuration)

    def test_subgraph_cycle_detection(self):
        configuration = self.loader.load_configuration()

        # Change class to invalid component
        configuration['components']['a']['dependencies'] = {'previous': 'd'}

        with self.assertRaises(ValueError):
            self.mgr.launch_subgraph(configuration, 'd:main')

    def test_settings(self):
        config = self.loader.load_configuration()
        self.mgr.launch_configuration(config)
        a = self.mgr.components["a"]
        b = self.mgr.components["b"]
        c = self.mgr.components["c"]
        d = self.mgr.components["d"]
        self.assertEqual(a.name, 'alfred')
        self.assertEqual(b.name, 'barry')
        self.assertEqual(c.name, 'charles')
        self.assertEqual(d.name, 'daniel')
Example #25
0
def _perform_build(build_config):
    src_to_analyze = _find_kickers(build_config.kickers)

    # This will check for source files in build_config.source_directory_path other than KICKER.
    addl_files = [
        src_file
        for src_file in os.listdir(build_config.source_directory_path)
        if (
            os.path.isfile(src_file)
            and os.path.splitext(src_file)[1] in (".py", ".pyc")
            and src_file not in src_to_analyze
        )
    ]
    if addl_files:
        addl_files_script = os.path.join((build_config.tmp_directory_path), "addlfiles.py")
        f = open(addl_files_script, "w")
        try:
            for src_file in addl_files:
                f.write("import %s\n" % src_file)
        finally:
            f.close()
        src_to_analyze.append(addl_files_script)

    temp_dir = tempfile.mkdtemp(dir=build_config.tmp_directory_path)
    mf = modulefinder.ModuleFinder(excludes=build_config.exclude_modules)

    for src_file in src_to_analyze:
        src_file = os.path.join(build_config.source_directory_path, src_file)
        logger.info("Analyzing: %s", src_file)
        mf.load_file(src_file)

    for (name, mod) in mf.modules.iteritems():
        logger.debug("References: %s", name)
        if not _matches_any_glob(name, build_config.exclude_modules):
            if mod.__file__:
                filename = mod.__file__
                if not (build_config.exclude_stdlib and _is_stdlib(filename)):
                    if filename.endswith(".py"):
                        first_line = open(filename, "r").readline()
                        matches = re.findall("PLATFORM:(\w+)", first_line)
                        if len(matches) == 0 or TARGET_PLATFORM_MATCHER(matches[0]):
                            start_dir = "."
                            for path in sys.path:
                                if filename.startswith(path) and len(path) > len(start_dir):
                                    start_dir = path
                            dst = join(temp_dir, relpath(filename, start_dir)) + "c"
                            if not os.path.isdir(os.path.dirname(dst)):
                                os.makedirs(os.path.dirname(dst))
                            logger.debug("..compiling %s --> %s", filename, dst)
                            compile(filename, dst)
                        else:
                            logger.debug(".. skipping (PLATFORM: %s)" % matches[0])
                    else:
                        logger.debug(".. skipping (stdlib)")
                else:
                    logger.debug("..skipping (not Python file)")
            else:
                logger.debug("..skipping (builtin)")
        else:
            logger.debug("..skipping (in EXCLUDE_MODULES)")

    # check for static resources that should be included based on filters
    for dirpath, dirnames, filenames in os.walk(build_config.source_directory_path):
        for filename in filenames:
            full_filename = os.path.abspath(os.path.join(dirpath, filename))
            relative_path = relpath(full_filename, build_config.source_directory_path)
            if _matches_any_glob(relative_path, build_config.resource_filters):
                dst_path = join(temp_dir, relative_path)
                if not os.path.isdir(os.path.dirname(dst_path)):
                    os.makedirs(os.path.dirname(dst_path))
                shutil.copyfile(full_filename, dst_path)
                print "STATIC RESOURCE %s" % full_filename

    package_file = join(build_config.tmp_directory_path, build_config.out_zip)
    z = zipfile.ZipFile(file=package_file, mode="w", compression=zipfile.ZIP_DEFLATED)
    for root, dirs, files in os.walk(temp_dir):
        root = root.replace(temp_dir, "")
        if root.startswith(os.sep):
            root = root[len(os.sep) :]
        if not ("__init__.pyc" in files or "__init__.py" in files) and len(root) > 0:
            files.append("__init__.py")
            filename = os.path.join(root, "__init__.py")
            src = os.path.join(temp_dir, filename)
            f = open(os.path.join(temp_dir, filename), "wb")
            try:
                f.write("")
            finally:
                f.close()
        for filename in files:
            filename = os.path.join(root, filename)
            src = os.path.join(temp_dir, filename)
            logger.debug("Writing %s --> %s", src, os.path.join(package_file, filename))
            z.write(src, filename)

    for path in sys.path:
        for dirpath in _find_dirs(path, build_config.output_directory_path):
            for root, dirs, files in os.walk(dirpath):
                rel_root = root.replace(dirpath, "")
                if rel_root.startswith(os.sep):
                    rel_root = rel_root[len(os.sep) :]
                for filename in files:
                    src = os.path.join(root, filename)
                    filename = os.path.join(rel_root, filename)
                    logger.debug("Writing %s --> %s", src, os.path.join(package_file, filename))
                    z.write(src, filename)

    files_to_copy = [(package_file, os.path.basename(package_file))]
    for f in build_config.kickers:
        if f.endswith(".yml"):
            from epoxy.configuration import YamlConfigurationLoader

            loader = YamlConfigurationLoader(f)
            data = loader.load_configuration()
            try:
                del data["extends"]
            except:
                pass

            tmp_path = tempfile.mktemp()
            tmp = open(tmp_path, "wb")
            if build_config.epoxy_use_dict_config:
                try:
                    tmp.write("config = %s" % pprint.pformat(data))
                finally:
                    tmp.close()
                if build_config.epoxy_config_to_zipfile:
                    z.write(tmp_path, "appconfig.py")
                if build_config.epoxy_config_to_fs:
                    files_to_copy.append((tmp_path, "appconfig.py"))
            else:
                import yaml

                try:
                    yaml.dump(data, tmp)
                finally:
                    tmp.close()
                files_to_copy.append((tmp_path, "app.yml"))
        else:
            source_file_path = os.path.join(build_config.source_directory_path, f)
            if os.path.exists(source_file_path):
                files_to_copy.append((source_file_path, f))
            elif os.path.exists(f):
                files_to_copy.append((f, f))
    z.close()

    files_to_copy.extend(
        [(os.path.join(build_config.source_directory_path, src_file), src_file) for src_file in addl_files]
    )

    shutil.rmtree(temp_dir, ignore_errors=True)

    return files_to_copy
Example #26
0
class TestDependencyGraphResolution(unittest.TestCase):
    def setUp(self):
        self.mgr = ComponentManager()
        self.loader = YamlConfigurationLoader(VALID_TEST_YAML)
        self.invalid_loader = YamlConfigurationLoader(INVALID_TEST_YAML)
        self.log = mock.Mock()
        epoxy_core.log = self.log

    def test_graph_ordering(self):
        graph = self.mgr.build_component_graph(
            self.loader.load_configuration())
        ordering = graph.get_ordering()
        o = [x.name for x in ordering]
        self.assertEqual(len(ordering), 5)  # our 4 plus component_manager
        self.assert_(o.index("b") > o.index("a"))
        self.assert_(o.index("c") > o.index("a"))
        self.assert_(o.index("d") > o.index("c"))

    def test_graph_construction(self):
        self.mgr.launch_configuration(self.loader.load_configuration())
        a = self.mgr.components["a"]
        b = self.mgr.components["b"]
        c = self.mgr.components["c"]
        d = self.mgr.components["d"]
        self.assertEqual(a.previous, None)
        self.assertEqual(b.previous, a)
        self.assertEqual(c.previous, a)
        self.assertEqual(d.previous, c)

    def test_subgraph_construction(self):
        self.mgr.launch_subgraph(self.loader.load_configuration(), 'd:main')

        a = self.mgr.components["a"]
        with self.assertRaises(KeyError):
            self.mgr.components["b"]
        c = self.mgr.components["c"]
        d = self.mgr.components["d"]

        self.assertEqual(a.previous, None)
        self.assertEqual(c.previous, a)
        self.assertEqual(d.previous, c)

        self.assertFalse(a.is_main)
        self.assertFalse(c.is_main)
        self.assertTrue(d.is_main)

    def test_subgraph_bad_entry_point(self):
        with self.assertRaises(AttributeError):
            self.mgr.launch_subgraph(self.loader.load_configuration(),
                                     'd:fake')
        last_log_message = self.log.call_args_list[0][0][0]
        self.assertEqual(last_log_message, "Bad entry point 'd:fake'")

    def test_bad_entry_point(self):
        cfg = self.invalid_loader.load_configuration()
        with self.assertRaises(AttributeError):
            self.mgr.launch_configuration(cfg)
        last_log_message = self.log.call_args_list[0][0][0]
        self.assertEqual(last_log_message, "Bad entry point 'a:fake_method'")

    def test_entry_point(self):
        configuration = self.loader.load_configuration()

        # Add entry-point to configuration
        configuration['entry-point'] = 'd:main'

        self.mgr.launch_configuration(configuration)

        a = self.mgr.components["a"]
        b = self.mgr.components["b"]
        c = self.mgr.components["c"]
        d = self.mgr.components["d"]

        self.assertFalse(a.is_main)
        self.assertFalse(b.is_main)
        self.assertFalse(c.is_main)
        self.assertTrue(d.is_main)

    def test_invalid_class(self):
        configuration = self.loader.load_configuration()

        # Change class to invalid component
        invalid_comp = 'epoxy.test.test_core:InvalidComponent'
        configuration['components']['a']['class'] = invalid_comp

        with self.assertRaises(AttributeError):
            self.mgr.launch_subgraph(configuration, 'd:main')
        last_logged_msg = self.log.call_args_list[0][0][0]
        self.assertEqual(
            last_logged_msg,
            "Class path '%s' is invalid, check your epoxy config" %
            invalid_comp)

    def test_missing_component(self):
        configuration = self.loader.load_configuration()

        # Delete required component
        del configuration['components']['a']

        with self.assertRaises(ValueError):
            self.mgr.launch_subgraph(configuration, 'd:main')

    def test_cycle_detection(self):
        configuration = self.loader.load_configuration()

        # Change class to invalid component
        configuration['components']['a']['dependencies'] = {'previous': 'd'}

        with self.assertRaises(ValueError):
            self.mgr.launch_configuration(configuration)

    def test_subgraph_cycle_detection(self):
        configuration = self.loader.load_configuration()

        # Change class to invalid component
        configuration['components']['a']['dependencies'] = {'previous': 'd'}

        with self.assertRaises(ValueError):
            self.mgr.launch_subgraph(configuration, 'd:main')

    def test_settings(self):
        config = self.loader.load_configuration()
        self.mgr.launch_configuration(config)
        a = self.mgr.components["a"]
        b = self.mgr.components["b"]
        c = self.mgr.components["c"]
        d = self.mgr.components["d"]
        self.assertEqual(a.name, 'alfred')
        self.assertEqual(b.name, 'barry')
        self.assertEqual(c.name, 'charles')
        self.assertEqual(d.name, 'daniel')
Example #27
0
def _perform_build(build_config):
    src_to_analyze = _find_kickers(build_config.kickers)

    # This will check for source files in build_config.source_directory_path other than KICKER.
    addl_files = [
        src_file for src_file in os.listdir(build_config.source_directory_path)
        if (os.path.isfile(src_file) and os.path.splitext(src_file)[1] in (
            '.py', '.pyc') and src_file not in src_to_analyze)
    ]
    if addl_files:
        addl_files_script = os.path.join((build_config.tmp_directory_path),
                                         'addlfiles.py')
        f = open(addl_files_script, 'w')
        try:
            for src_file in addl_files:
                f.write('import %s\n' % src_file)
        finally:
            f.close()
        src_to_analyze.append(addl_files_script)

    temp_dir = tempfile.mkdtemp(dir=build_config.tmp_directory_path)
    mf = modulefinder.ModuleFinder(excludes=build_config.exclude_modules)

    for src_file in src_to_analyze:
        src_file = os.path.join(build_config.source_directory_path, src_file)
        logger.info("Analyzing: %s", src_file)
        mf.load_file(src_file)

    for (name, mod) in mf.modules.iteritems():
        logger.debug("References: %s", name)
        if not _matches_any_glob(name, build_config.exclude_modules):
            if mod.__file__:
                filename = mod.__file__
                if not (build_config.exclude_stdlib and _is_stdlib(filename)):
                    if filename.endswith(".py"):
                        first_line = open(filename, 'r').readline()
                        matches = re.findall("PLATFORM:(\w+)", first_line)
                        if len(matches) == 0 or TARGET_PLATFORM_MATCHER(
                                matches[0]):
                            start_dir = '.'
                            for path in sys.path:
                                if filename.startswith(
                                        path) and len(path) > len(start_dir):
                                    start_dir = path
                            dst = join(temp_dir, relpath(filename,
                                                         start_dir)) + "c"
                            if not os.path.isdir(os.path.dirname(dst)):
                                os.makedirs(os.path.dirname(dst))
                            logger.debug("..compiling %s --> %s", filename,
                                         dst)
                            compile(filename, dst)
                        else:
                            logger.debug(".. skipping (PLATFORM: %s)" %
                                         matches[0])
                    else:
                        logger.debug(".. skipping (stdlib)")
                else:
                    logger.debug("..skipping (not Python file)")
            else:
                logger.debug("..skipping (builtin)")
        else:
            logger.debug("..skipping (in EXCLUDE_MODULES)")

    # check for static resources that should be included based on filters
    for dirpath, dirnames, filenames in os.walk(
            build_config.source_directory_path):
        for filename in filenames:
            full_filename = os.path.abspath(os.path.join(dirpath, filename))
            relative_path = relpath(full_filename,
                                    build_config.source_directory_path)
            if _matches_any_glob(relative_path, build_config.resource_filters):
                dst_path = join(temp_dir, relative_path)
                if not os.path.isdir(os.path.dirname(dst_path)):
                    os.makedirs(os.path.dirname(dst_path))
                shutil.copyfile(full_filename, dst_path)
                print "STATIC RESOURCE %s" % full_filename

    package_file = join(build_config.tmp_directory_path, build_config.out_zip)
    z = zipfile.ZipFile(file=package_file,
                        mode="w",
                        compression=zipfile.ZIP_DEFLATED)
    for root, dirs, files in os.walk(temp_dir):
        root = root.replace(temp_dir, "")
        if root.startswith(os.sep):
            root = root[len(os.sep):]
        if not ("__init__.pyc" in files
                or "__init__.py" in files) and len(root) > 0:
            files.append("__init__.py")
            filename = os.path.join(root, "__init__.py")
            src = os.path.join(temp_dir, filename)
            f = open(os.path.join(temp_dir, filename), "wb")
            try:
                f.write("")
            finally:
                f.close()
        for filename in files:
            filename = os.path.join(root, filename)
            src = os.path.join(temp_dir, filename)
            logger.debug("Writing %s --> %s", src,
                         os.path.join(package_file, filename))
            z.write(src, filename)

    for path in sys.path:
        for dirpath in _find_dirs(path, build_config.output_directory_path):
            for root, dirs, files in os.walk(dirpath):
                rel_root = root.replace(dirpath, "")
                if rel_root.startswith(os.sep):
                    rel_root = rel_root[len(os.sep):]
                for filename in files:
                    src = os.path.join(root, filename)
                    filename = os.path.join(rel_root, filename)
                    logger.debug("Writing %s --> %s", src,
                                 os.path.join(package_file, filename))
                    z.write(src, filename)

    files_to_copy = [(package_file, os.path.basename(package_file))]
    for f in build_config.kickers:
        if f.endswith('.yml'):
            from epoxy.configuration import YamlConfigurationLoader
            loader = YamlConfigurationLoader(f)
            data = loader.load_configuration()
            try:
                del data['extends']
            except:
                pass

            tmp_path = tempfile.mktemp()
            tmp = open(tmp_path, 'wb')
            if build_config.epoxy_use_dict_config:
                try:
                    tmp.write('config = %s' % pprint.pformat(data))
                finally:
                    tmp.close()
                if build_config.epoxy_config_to_zipfile:
                    z.write(tmp_path, 'appconfig.py')
                if build_config.epoxy_config_to_fs:
                    files_to_copy.append((tmp_path, 'appconfig.py'))
            else:
                import yaml
                try:
                    yaml.dump(data, tmp)
                finally:
                    tmp.close()
                files_to_copy.append((tmp_path, 'app.yml'))
        else:
            source_file_path = os.path.join(build_config.source_directory_path,
                                            f)
            if os.path.exists(source_file_path):
                files_to_copy.append((source_file_path, f))
            elif os.path.exists(f):
                files_to_copy.append((f, f))
    z.close()

    files_to_copy.extend([(os.path.join(build_config.source_directory_path,
                                        src_file), src_file)
                          for src_file in addl_files])

    shutil.rmtree(temp_dir, ignore_errors=True)

    return files_to_copy
Example #28
0
 def setUp(self):
     self.mgr = ComponentManager()
     self.loader = YamlConfigurationLoader(VALID_TEST_YAML)
     self.invalid_loader = YamlConfigurationLoader(INVALID_TEST_YAML)
     self.log = mock.Mock()
     epoxy_core.log = self.log