# Path: chaosmonkey/modules/module_store.py
# class ModulesStore:
#     """
#     Load and store modules from outside the app package
#     """
#     modules = []
# 
#     def __init__(self, klass):
#         self.klass = klass
#         self.modules = []
#         self.log = logging.getLogger('%s.%s' % (__name__, klass.__name__))
# 
#     def load(self, path):
#         """
#         Loads all modules found in a given path.
#         It adds the path to the sys.path and import all modules found
# 
#         :param path: path for lookup modules
#         """
# 
#         self._validate_path(path)
# 
#         sys.path.insert(0, path)
# 
#         module_names = self._get_module_names(path)
#         try:
#             for name in module_names:
#                 if not name.endswith('_test'):
#                     self.log.debug('added module %s', name)
#                     module = __import__(name)
#                     self.modules.append(module)
#         except ImportError:
#             self.log.debug('error importing module %s', name)
#             raise ValueError('Unable to import %s' % name)
# 
#     def set_modules(self, modules):
#         self.modules = modules
# 
#     def get_modules(self):
#         return self.modules
# 
#     def list(self):
#         """
#         List all loaded modules names. It will return a list withe the
#         __name__ of each module
#         :return:
#         """
#         module_names = []
#         for module in self.get_modules():
#             module_name = getattr(module, '__name__')
#             for name, data in inspect.getmembers(module):
#                 if inspect.isclass(data) and self._has_klass_ancestor(data):
#                     module_names.append(module_name + ':' + name)
# 
#         return module_names
# 
#     def add(self, module):
#         self.modules.append(module)
# 
#     def remove(self, module_name):
#         for module in self.modules:
#             if module_name == getattr(module, '__name__'):
#                 self.modules.remove(module)
# 
#     def get(self, ref):
#         """
#         Given a str reference of a class in a module (eg. ModuleName.ClassName)
#         return the class so it can be instantiated
# 
#         The module with the class must be loaded first using load or add method.
# 
#         :param ref: str representation of a class in a module
#         :return: class ready for instantation
#         """
#         return self._ref_to_obj(ref)
# 
#     def _has_klass_ancestor(self, cls):
#         if hasattr(cls, '__bases__') and self.klass in cls.__bases__:
#             return True
#         return False
# 
#     @staticmethod
#     def _validate_path(path):
#         '''
#         Check for a valid path
#         '''
#         if not isdir(path):
#             raise ValueError('invalid path ' + path)
# 
#     @staticmethod
#     def _get_module_names(path):
#         '''Inspect a path and return all file names without extension'''
#         names = []
#         for f in listdir(path):
#             if isfile(join(path, f)):
#                 names.append(splitext(f)[0])
#         return names
# 
#     def _ref_to_obj(self, ref):
#         """
#         Return the object pointed to by ``ref``.
#         :type ref: str
#         """
#         if not isinstance(ref, str):
#             raise TypeError('References must be strings')
#         if ':' not in ref:
#             raise ValueError('Invalid reference')
# 
#         module_name, class_name = ref.split(':', 1)
#         for module in self.modules:
#             attr_name = getattr(module, '__name__')
#             if attr_name == module_name:
#                 try:
#                     self.log.debug(attr_name + ' found on module store!')
#                     return getattr(module, class_name)
#                 except Exception:
#                     raise ModuleLookupError('Error resolving reference %s: not found in modules' % ref)
# 
# Path: chaosmonkey/attacks/attack.py
# class Attack:
#     """
#     Base class for attacks. Every attack must extend from this class
#     """
# 
#     ref = None      #: **string** Unique identifier for the attack. Must be module_name.AttackClass
#     schema = None   #: **dict** Valid jsonSchema to validate the attack attributes in the API
#     #: **dict** example for using when calling add plan endpoint
#     example = None
# 
#     def __init__(self, attack_config):
#         self.attack_config = attack_config
# 
#     def run(self):
#         """
#         This method is called by an executor to perform the actual attack.
#         You can access the self.attack_config that holds the configuration
#         used when calling the endpoint to plan the attacks.
#         """
#         raise NotImplementedError("Attacks should implement this!")
# 
#     @staticmethod
#     def to_dict():
#         """
#         You should implement to_dict to return an Attack._to_dict(ref, schema, example)
#         using the attack attributes
# 
#         Example::
# 
#             @staticmethod
#             def to_dict():
#                 return Attack._to_dict(
#                     TerminateEC2Instance.ref,
#                     TerminateEC2Instance.schema,
#                     TerminateEC2Instance.example
#                 )
#         """
# 
#         raise NotImplementedError("Attacks should implement this!")
# 
#     @staticmethod
#     def _to_dict(ref, schema, example):
#         return {
#             "ref": ref,
#             "schema": schema,
#             "example": example,
#         }


from unittest.mock import patch
from chaosmonkey.modules.module_store import ModulesStore
from chaosmonkey.attacks.attack import Attack
import sys
import pytest
import chaosmonkey.attacks.attack as module_attack


class AttackMock(Attack):
    @staticmethod
    def to_dict():
        pass

    def run(self):
        pass


def test_load_raise_exception_for_invalid_path():

# Path: chaosmonkey/modules/module_store.py
# class ModulesStore:
#     """
#     Load and store modules from outside the app package
#     """
#     modules = []
# 
#     def __init__(self, klass):
#         self.klass = klass
#         self.modules = []
#         self.log = logging.getLogger('%s.%s' % (__name__, klass.__name__))
# 
#     def load(self, path):
#         """
#         Loads all modules found in a given path.
#         It adds the path to the sys.path and import all modules found
# 
#         :param path: path for lookup modules
#         """
# 
#         self._validate_path(path)
# 
#         sys.path.insert(0, path)
# 
#         module_names = self._get_module_names(path)
#         try:
#             for name in module_names:
#                 if not name.endswith('_test'):
#                     self.log.debug('added module %s', name)
#                     module = __import__(name)
#                     self.modules.append(module)
#         except ImportError:
#             self.log.debug('error importing module %s', name)
#             raise ValueError('Unable to import %s' % name)
# 
#     def set_modules(self, modules):
#         self.modules = modules
# 
#     def get_modules(self):
#         return self.modules
# 
#     def list(self):
#         """
#         List all loaded modules names. It will return a list withe the
#         __name__ of each module
#         :return:
#         """
#         module_names = []
#         for module in self.get_modules():
#             module_name = getattr(module, '__name__')
#             for name, data in inspect.getmembers(module):
#                 if inspect.isclass(data) and self._has_klass_ancestor(data):
#                     module_names.append(module_name + ':' + name)
# 
#         return module_names
# 
#     def add(self, module):
#         self.modules.append(module)
# 
#     def remove(self, module_name):
#         for module in self.modules:
#             if module_name == getattr(module, '__name__'):
#                 self.modules.remove(module)
# 
#     def get(self, ref):
#         """
#         Given a str reference of a class in a module (eg. ModuleName.ClassName)
#         return the class so it can be instantiated
# 
#         The module with the class must be loaded first using load or add method.
# 
#         :param ref: str representation of a class in a module
#         :return: class ready for instantation
#         """
#         return self._ref_to_obj(ref)
# 
#     def _has_klass_ancestor(self, cls):
#         if hasattr(cls, '__bases__') and self.klass in cls.__bases__:
#             return True
#         return False
# 
#     @staticmethod
#     def _validate_path(path):
#         '''
#         Check for a valid path
#         '''
#         if not isdir(path):
#             raise ValueError('invalid path ' + path)
# 
#     @staticmethod
#     def _get_module_names(path):
#         '''Inspect a path and return all file names without extension'''
#         names = []
#         for f in listdir(path):
#             if isfile(join(path, f)):
#                 names.append(splitext(f)[0])
#         return names
# 
#     def _ref_to_obj(self, ref):
#         """
#         Return the object pointed to by ``ref``.
#         :type ref: str
#         """
#         if not isinstance(ref, str):
#             raise TypeError('References must be strings')
#         if ':' not in ref:
#             raise ValueError('Invalid reference')
# 
#         module_name, class_name = ref.split(':', 1)
#         for module in self.modules:
#             attr_name = getattr(module, '__name__')
#             if attr_name == module_name:
#                 try:
#                     self.log.debug(attr_name + ' found on module store!')
#                     return getattr(module, class_name)
#                 except Exception:
#                     raise ModuleLookupError('Error resolving reference %s: not found in modules' % ref)
# 
# Path: chaosmonkey/attacks/attack.py
# class Attack:
#     """
#     Base class for attacks. Every attack must extend from this class
#     """
# 
#     ref = None      #: **string** Unique identifier for the attack. Must be module_name.AttackClass
#     schema = None   #: **dict** Valid jsonSchema to validate the attack attributes in the API
#     #: **dict** example for using when calling add plan endpoint
#     example = None
# 
#     def __init__(self, attack_config):
#         self.attack_config = attack_config
# 
#     def run(self):
#         """
#         This method is called by an executor to perform the actual attack.
#         You can access the self.attack_config that holds the configuration
#         used when calling the endpoint to plan the attacks.
#         """
#         raise NotImplementedError("Attacks should implement this!")
# 
#     @staticmethod
#     def to_dict():
#         """
#         You should implement to_dict to return an Attack._to_dict(ref, schema, example)
#         using the attack attributes
# 
#         Example::
# 
#             @staticmethod
#             def to_dict():
#                 return Attack._to_dict(
#                     TerminateEC2Instance.ref,
#                     TerminateEC2Instance.schema,
#                     TerminateEC2Instance.example
#                 )
#         """
# 
#         raise NotImplementedError("Attacks should implement this!")
# 
#     @staticmethod
#     def _to_dict(ref, schema, example):
#         return {
#             "ref": ref,
#             "schema": schema,
#             "example": example,
#         }


# Path: test/unit/chaosmonkey/modules/module_store_test.py
from unittest.mock import patch
from chaosmonkey.modules.module_store import ModulesStore
from chaosmonkey.attacks.attack import Attack
import sys
import pytest
import chaosmonkey.attacks.attack as module_attack



class AttackMock(Attack):
    @staticmethod
    def to_dict():
        pass

    def run(self):
        pass


def test_load_raise_exception_for_invalid_path():

    modules = ModulesStore(Attack)