Beispiel #1
0
    def run(self):
        parser = self.get_argparse()
        self.args = args = parser.parse_args(sys.argv[1:])
        self.console = Console()

        if args.subcommand not in ['install']:
            self.home_dir = args.home or os.environ.get(
                'MOYA_SERVICE_HOME', None) or DEFAULT_HOME_DIR
            settings_path = os.path.join(self.home_dir, 'moya.conf')
            try:
                with io.open(settings_path, 'rt') as f:
                    self.settings = SettingsContainer.read_from_file(f)
            except IOError:
                self.error('unable to read {}'.format(settings_path))
                return -1

        method_name = "run_" + args.subcommand.replace('-', '_')
        try:
            return getattr(self, method_name)() or 0
        except CommandError as e:
            self.error(text_type(e))
        except Exception as e:
            if args.debug:
                raise
            self.error(text_type(e))
Beispiel #2
0
 def add_error(self, element, error):
     console = Console(text=True, width=120)
     console.obj(self.context, error)
     trace = console.get_text()
     self._test_result('error',
                       element=element,
                       error=error,
                       trace=trace,
                       description=self.case.description,
                       msg=safe_to_string(error))
Beispiel #3
0
 def add_error(self, element, error):
     console = Console(text=True, width=120)
     console.obj(self.context, error)
     trace = console.get_text()
     self._test_result('error',
                       element=element,
                       error=error,
                       trace=trace,
                       description=self.case.description,
                       msg=safe_to_string(error))
Beispiel #4
0
    def setUp(self):

        try:
            os.remove("dbtest.sqlite")
        except OSError:
            pass

        build_result = build_server(join(curdir, 'dbtest/'), "settings.ini")
        archive = build_result.archive
        base_context = build_result.context

        archive.populate_context(build_result.context)
        console = Console()
        db.sync_all(build_result.archive, console)

        context = base_context.clone()
        root = context.root
        root['_dbsessions'] = db.get_session_map(archive)
        archive.call("dbtest#setup", context, None, id=1)
        db.commit_sessions(context)

        build_result = build_server(join(curdir, 'dbtest/'), "settings.ini")
        self.archive = build_result.archive
        self.base_context = build_result.context

        self.context = self.base_context.clone()
        archive.populate_context(self.context)

        root = self.context.root
        root[u'_dbsessions'] = db.get_session_map(self.archive)
Beispiel #5
0
 def setUp(self):
     path = os.path.abspath(os.path.dirname(__file__))
     self.fs = fsopendir(path)
     self.context = Context()
     self.context['console'] = Console()
     self.archive = Archive()
     import_fs = self.fs.opendir("archivetest")
     self.archive.load_library(import_fs)
     self.archive.finalize()
Beispiel #6
0
 def setUp(self):
     self.called = False
     path = os.path.abspath(os.path.dirname(__file__))
     self.fs = open_fs(path)
     self.context = Context()
     self.context["console"] = Console()
     self.archive = Archive()
     import_fs = self.fs.opendir("archivetest")
     self.archive.load_library(import_fs)
     self.archive.finalize()
    def setUp(self):
        _path = os.path.abspath(os.path.dirname(__file__))
        path = os.path.join(_path, 'testproject')
        self.application = WSGIApplication(path,
                                           'settings.ini',
                                           strict=True,
                                           validate_db=False,
                                           disable_autoreload=True)
        console = Console()
        self.archive = self.application.archive
        db.sync_all(self.archive, console)
        self.context = context = Context()

        self.application.populate_context(context)
        set_dynamic(context)
        context['.console'] = console
Beispiel #8
0
    def run(self):
        parser = self.get_argparse()
        self.args = args = parser.parse_args(sys.argv[1:])
        self.console = Console()

        self.home_dir = args.home or os.environ.get('MOYA_SRV_HOME', None) or DEFAULT_HOME_DIR

        settings_path = os.path.join(self.home_dir, 'moya.conf')
        try:
            with io.open(settings_path, 'rt') as f:
                self.settings = SettingsContainer.read_from_file(f)
        except IOError:
            self.error('unable to read {}'.format(settings_path))
            return -1

        method_name = "run_" + args.subcommand.replace('-', '_')
        try:
            return getattr(self, method_name)() or 0
        except CommandError as e:
            self.error(text_type(e))
        except Exception as e:
            if args.debug:
                raise
            self.error(text_type(e))
Beispiel #9
0
        return [self[key] for key in self.keys()]

    def items(self):
        return [(key, self[key]) for key in self.keys()]


if __name__ == "__main__":

    enum = ContextEnum("moya.admin#enum.hobbits")
    enum.add_value("bilbo", description="Bilbo Baggins")
    enum.add_value("sam", description="Sam")
    enum.add_value("isembard", description="Isembard Took")

    from moya.console import Console

    console = Console()
    console.obj(context, enum)

    e = enum["sam"]
    console.obj(context, e)
    print(e)
    print(int(e))
    print(text_type(e))
    print(enum.values())
    print(list(enum))
    print(e == 2)
    print(e == "sam")
    print(e == "bilbo")
    print(e == 3)

    print(list(enum))
Beispiel #10
0
    def values(self):
        return [self[key] for key in self.keys()]

    def items(self):
        return [(key, self[key]) for key in self.keys()]


if __name__ == "__main__":

    enum = ContextEnum("moya.admin#enum.hobbits")
    enum.add_value("bilbo", description="Bilbo Baggins")
    enum.add_value("sam", description="Sam")
    enum.add_value("isembard", description="Isembard Took")

    from moya.console import Console
    console = Console()
    console.obj(context, enum)

    e = enum['sam']
    console.obj(context, e)
    print(e)
    print(int(e))
    print(text_type(e))
    print(enum.values())
    print(list(enum))
    print(e == 2)
    print(e == 'sam')
    print(e == 'bilbo')
    print(e == 3)

    print(list(enum))
Beispiel #11
0
    def run(self):
        args = self.args
        location = args.location

        console = self.console
        if args.output is not None:
            from moya.console import Console
            console = Console(html=True)

        def write_output():
            if args.output is not None:
                from moya import consolehtml
                html = console.get_text()
                html = consolehtml.render_console_html(html)
                with open(args.output, 'wb') as f:
                    f.write(html.encode('utf-8'))

        test_libs = []
        for location in args.location:
            archive, lib = build.build_lib(location, tests=True)
            lib_name = lib.long_name

            if archive.failed_documents:
                sys.stderr.write('library build failed\n')
                build.render_failed_documents(archive, console)
                write_output()
                return -1

            test_libs.append(lib)

        for lib_name in test_libs:
            if not lib.load_tests():
                sys.stderr.write('no tests for {}\n'.format(lib))
                return -1

        archive.finalize()

        if archive.failed_documents:
            sys.stderr.write('tests build failed\n')
            build.render_failed_documents(archive, console)
            write_output()
            return -1

        if args.automated:
            archive.suppress_breakpoints = True

        all_results = []

        for lib in test_libs:
            suites = list(lib.get_elements_by_type((namespaces.test, 'suite')))

            for suite_no, suite in enumerate(suites, 1):

                try:
                    suite_description = suite.description
                except:
                    suite_description = suite.libid

                if args.quick and suite.slow:
                    with self.console.progress("{} {} (skipped slow test)".format(lib, suite_description), 0):
                        pass
                    continue

                if args.exclude and suite.group is not None and suite.group in args.exclude:
                    with self.console.progress("{} {} (excluded group)".format(lib, suite_description), 0):
                        pass
                    continue

                if args.group and suite.group not in args.group:
                    with self.console.progress("{} {} (not in group)".format(lib, suite_description), 0):
                        pass
                    continue

                steps = 0
                setup = suite.get_child((namespaces.test, 'setup'))
                teardown = suite.get_child((namespaces.test, 'teardown'))
                if setup is not None:
                    setup_callable = archive.get_callable_from_element(setup)
                    steps += 1
                if teardown is not None:
                    teardown_callable = archive.get_callable_from_element(teardown)
                    steps += 1
                tests = list(suite.children((namespaces.test, 'case')))
                steps += len(tests)

                test_runner = {}
                context = Context({'_test_runner': test_runner})

                results = TestResults(context, lib, suite.description)
                results.group = suite._definition
                all_results.append(results)

                context['._test_results'] = results
                test_info = "({} of {})".format(suite_no, len(suites))
                progress_text = "{} {} {}".format(lib, suite_description, test_info)

                with self.console.progress(progress_text, steps) as progress:
                    if steps == 0:
                        progress.step()
                    else:
                        try:
                            with TestRunner(context, results):
                                if setup is not None:
                                    setup_callable(context)
                                    progress.step()
                        except Exception as e:
                            results.add_setup_error(setup, e)
                            progress.step('setup failed')
                        else:
                            with TestRunner(context, results):
                                for test in tests:
                                    results.case = test
                                    test_callable = archive.get_callable_from_element(test)
                                    try:
                                        test_return = test_callable(context)
                                    except Exception as e:
                                        results.add_error(test, e)
                                    else:
                                        if test_return != 'fail':
                                            results.add_pass(test)
                                    finally:
                                        progress.step()

                            try:
                                with TestRunner(context, results):
                                    if teardown is not None:
                                        teardown_callable(context)
                                        progress.step()
                            except Exception as e:
                                results.add_teardown_error(teardown, e)

        all_totals = {'pass': 0, 'fail': 0, 'error': 0}
        for result in all_results:
            _pass, fail, error = result.stats
            all_totals['pass'] += _pass
            all_totals['fail'] += fail
            all_totals['error'] += error
        summary = "{fail} fail(s), {error} error(s), {pass} pass(es)".format(**all_totals)

        if args.quick:
            console.div("Test results (quick) {}".format(datetime.now().ctime()))
        else:
            console.div("Test results {}".format(datetime.now().ctime()))
        test_count = sum(len(r.tests) for r in all_results)
        console.text('Ran {} test(s) in {} test suite(s) - {}'.format(test_count, len(all_results), summary))
        for results in all_results:
            results.report(console,
                           show_trace=not args.summary,
                           show_passes=args.verbose or args.summary,
                           verbose=args.verbose)

        header = ['lib', 'suite', 'passes', 'fails', 'errors']
        table = []
        passes = 0
        fails = 0
        errors = 0
        for result in all_results:
            _pass, fail, error = result.stats
            passes += _pass
            fails += fail
            errors += error
            _pass = Cell(_pass, fg="green" if _pass else 'white', bold=True)
            fail = Cell(fail, fg="red" if fail else "green", bold=True)
            error = Cell(error, fg="red" if error else "green", bold=True)
            table.append([result.lib.long_name, result.suite, _pass, fail, error])

        if not args.summary or args.verbose:
            console.nl()
            console.table(table, header_row=header)

        summary = "{fails} fail(s), {errors} error(s), {passes} pass(es)".format(fails=fails, errors=errors, passes=passes)
        if errors or fails:
            console.text(summary, fg="red", bold=True)
        else:
            console.text(summary, fg="green", bold=True)

        write_output()

        return fails
Beispiel #12
0
 def get_output(self):
     text = self.context['.console'].get_text()
     self.context['.console'] = Console(text=True)
     return text
Beispiel #13
0
            self.console.text(self.msg)
        else:
            self.render(line_end='\n')


class ProgressContext(object):
    def __init__(self, progress):
        self.progress = progress

    def __enter__(self):
        self.progress.console.show_cursor(False)
        self.progress.render()
        return self.progress

    def __exit__(self, *args, **kwargs):
        self.progress.done()
        self.progress.console.show_cursor(True)


if __name__ == "__main__":
    from time import sleep
    from moya.console import Console
    c = Console()
    p = Progress(c, "Extracting...", 100)
    p.render()

    for step in xrange(100):
        sleep(.01)
        p.step()
    p.render()
    print
Beispiel #14
0
 def __enter__(self):
     self.console = Console(text=True)
     self.context['.console'] = self.console
Beispiel #15
0
class MoyaSrv(object):
    """Moya Service"""
    def get_argparse(self):
        parser = argparse.ArgumentParser(prog="moya-srv",
                                         description=self.__doc__)

        parser.add_argument('-d',
                            '--debug',
                            dest="debug",
                            action="store_true",
                            help="enable debug information (show tracebacks)")
        parser.add_argument('--home',
                            dest="home",
                            metavar="PATH",
                            default=None,
                            help="moya service directory")

        subparsers = parser.add_subparsers(title="available sub-commands",
                                           dest="subcommand",
                                           help="sub-command help")

        list_parser = subparsers.add_parser(
            'list', help="list projects", description="list enabled projects")
        list_parser

        where_parser = subparsers.add_parser(
            'where',
            help='find project directory',
            description="output the location of the project")

        where_parser.add_argument(dest="name",
                                  metavar="PROJECT",
                                  help="name of a project")

        restart_parser = subparsers.add_parser('restart',
                                               help='restart a project server',
                                               description="restart a server")

        restart_parser.add_argument(dest="name",
                                    metavar="PROJECT",
                                    help="name of a project")

        install_parser = subparsers.add_parser(
            'install',
            help='install moya service',
            description="install moya service")

        install_parser.add_argument(
            '--home',
            dest="home",
            metavar="PATH",
            default=DEFAULT_HOME_DIR,
            help="where to install service conf",
        )
        install_parser.add_argument('--force',
                                    dest="force",
                                    action="store_true",
                                    help="overwrite files that exist")

        install_parser

        return parser

    def error(self, msg, code=-1):
        sys.stderr.write(msg + '\n')
        sys.exit(code)

    def run(self):
        parser = self.get_argparse()
        self.args = args = parser.parse_args(sys.argv[1:])
        self.console = Console()

        if args.subcommand not in ['install']:
            self.home_dir = args.home or os.environ.get(
                'MOYA_SERVICE_HOME', None) or DEFAULT_HOME_DIR
            settings_path = os.path.join(self.home_dir, 'moya.conf')
            try:
                with io.open(settings_path, 'rt') as f:
                    self.settings = SettingsContainer.read_from_file(f)
            except IOError:
                self.error('unable to read {}'.format(settings_path))
                return -1

        method_name = "run_" + args.subcommand.replace('-', '_')
        try:
            return getattr(self, method_name)() or 0
        except CommandError as e:
            self.error(text_type(e))
        except Exception as e:
            if args.debug:
                raise
            self.error(text_type(e))

    def _get_projects(self):
        project_paths = self.settings.get_list('projects', 'read')
        paths = []
        cwd = os.getcwd()
        try:
            os.chdir(self.home_dir)
            for path in project_paths:
                glob_paths = glob.glob(path)
                paths.extend([os.path.abspath(p) for p in glob_paths])
        finally:
            os.chdir(cwd)
        return paths

    def project_exists(self, name):
        for path in self._get_projects():
            settings = self.read_project(path)
            if settings.get('service', 'name', None) == name:
                return True
        return False

    def read_project(self, path):
        settings = SettingsContainer.read_os(path)
        return settings

    def run_list(self):
        table = []
        for path in self._get_projects():
            settings = self.read_project(path)
            location = settings.get('service', 'location', '?')
            name = settings.get('service', 'name', '?')
            domains = "\n".join(settings.get_list('service', 'domains', ""))
            table.append([name, domains, path, location])
        table.sort(key=lambda row: row[0].lower())
        self.console.table(
            table, header_row=['name', 'domain(s)', 'conf', 'location'])

    def run_where(self):
        name = self.args.name
        location = None
        for path in self._get_projects():
            settings = self.read_project(path)
            if settings.get('service', 'name', None) == name:
                location = settings.get('service', 'location', None)
        if location is None:
            self.error("no project '{}'".format(name))
            return -1
        sys.stdout.write(location)
        return 0

    def run_restart(self):
        name = self.args.name
        if not self.project_exists(name):
            self.error("no project '{}'".format(name))
        temp_dir = os.path.join(
            self.settings.get('service', 'temp_dir', tempfile.gettempdir()),
            'moyasrv')
        try:
            os.makedirs(temp_dir)
        except OSError:
            pass
        change_path = os.path.join(temp_dir, "{}.changes".format(name))
        try:
            with open(change_path, 'a'):
                os.utime(change_path, None)
        except IOError as e:
            sys.stderr.write("{}\n".format(text_type(e)))
            return -1

    def run_install(self):
        home_dir = self.args.home or DEFAULT_HOME_DIR

        def create_dir(_path):
            path = os.path.join(home_dir, _path)
            try:
                if not os.path.exists(path):
                    os.makedirs(path)
                    sys.stdout.write("created '{}'\n".format(path))
            except OSError as e:
                if e.errno != 17:
                    raise

        for dirpath in ["", "sites-enabled", "sites-available"]:
            try:
                create_dir(dirpath)
            except OSError as e:
                if e.errno == 13:
                    sys.stderr.write('permission denied (do you need sudo)?\n')
                    return -1
                raise

        def write_file(_path, contents):
            path = os.path.join(home_dir, _path)
            if not self.args.force and os.path.exists(path):
                sys.stdout.write(
                    "not overwriting '{}' (use --force to overwrite)\n".format(
                        path))
                return

            with open(path, 'wt') as f:
                f.write(contents)
            sys.stdout.write("wrote '{}'\n".format(path))

        for path, contents in [('moya.conf', DEFAULT_CONF),
                               ('logging.ini', DEFAULT_LOGGING),
                               ('bashtools', BASH_TOOLS)]:
            try:
                write_file(path, contents)
            except IOError as e:
                if e.errno == 13:
                    sys.stdout.write(
                        "permission denied writing '{}' (do you need sudo)?\n".
                        format(path))
                    return -1
                else:
                    raise

        TOOLS_PATH = "~/.bashrc"
        bashtools_path = os.path.join(home_dir, 'bashtools')
        try:
            cmd = b'\n# Added by moya-srv install\nsource {}\n'.format(
                bashtools_path)
            bashrc_path = os.path.expanduser(TOOLS_PATH)
            if os.path.exists(bashrc_path):
                with open(bashrc_path, 'rb') as f:
                    bashrc = f.read()
            else:
                bashrc = b''
            if cmd not in bashrc:
                with open(bashrc_path, 'ab') as f:
                    f.write(cmd)
        except Exception as e:
            sys.stdout.write(
                'unable to add moya service bash tools ({})\n'.format(e))
        else:
            sys.stdout.write(
                'Added Moya service bash tools to {}\n'.format(TOOLS_PATH))
            sys.stdout.write(
                "Tools will be available when you next log in (or run 'source {})\n"
                .format(bashtools_path))

        sys.stdout.write('Moya service was installed in {}\n'.format(home_dir))
Beispiel #16
0
class MoyaSrv(object):
    """Moya Service"""
    def get_argparse(self):
        parser = argparse.ArgumentParser(prog="moya-srv",
                                         description=self.__doc__)

        parser.add_argument('-d',
                            '--debug',
                            dest="debug",
                            action="store_true",
                            help="enable debug information (show tracebacks)")
        parser.add_argument('--home',
                            dest="home",
                            metavar="PATH",
                            default=None,
                            help="moya service directory")

        subparsers = parser.add_subparsers(title="available sub-commands",
                                           dest="subcommand",
                                           help="sub-command help")

        list_parser = subparsers.add_parser(
            'list', help="list projects", description="list enabled projects")

        where_parser = subparsers.add_parser(
            'where',
            help='find project directory',
            description="output the location of the project")

        where_parser.add_argument(dest="name",
                                  metavar="PROJECT",
                                  help="name of a project")

        restart_parser = subparsers.add_parser('restart',
                                               help='restart a project server',
                                               description="restart a server")

        restart_parser.add_argument(dest="name",
                                    metavar="PROJECT",
                                    help="name of a project")

        return parser

    def error(self, msg, code=-1):
        sys.stderr.write(msg + '\n')
        sys.exit(code)

    def run(self):
        parser = self.get_argparse()
        self.args = args = parser.parse_args(sys.argv[1:])
        self.console = Console()

        self.home_dir = args.home or os.environ.get('MOYA_SRV_HOME',
                                                    None) or DEFAULT_HOME_DIR

        settings_path = os.path.join(self.home_dir, 'moya.conf')
        try:
            with io.open(settings_path, 'rt') as f:
                self.settings = SettingsContainer.read_from_file(f)
        except IOError:
            self.error('unable to read {}'.format(settings_path))
            return -1

        method_name = "run_" + args.subcommand.replace('-', '_')
        try:
            return getattr(self, method_name)() or 0
        except CommandError as e:
            self.error(text_type(e))
        except Exception as e:
            if args.debug:
                raise
            self.error(text_type(e))

    def _get_projects(self):
        project_paths = self.settings.get_list('projects', 'read')
        paths = []
        cwd = os.getcwd()
        try:
            os.chdir(self.home_dir)
            for path in project_paths:
                glob_paths = glob.glob(path)
                paths.extend([os.path.abspath(p) for p in glob_paths])
        finally:
            os.chdir(cwd)
        return paths

    def project_exists(self, name):
        for path in self._get_projects():
            settings = self.read_project(path)
            if settings.get('service', 'name', None) == name:
                return True
        return False

    def read_project(self, path):
        settings = SettingsContainer.read_os(path)
        return settings

    def run_list(self):
        table = []
        for path in self._get_projects():
            settings = self.read_project(path)
            location = settings.get('service', 'location', '?')
            name = settings.get('service', 'name', '?')
            domains = "\n".join(settings.get_list('service', 'domains', ""))
            table.append([name, domains, path, location])
        self.console.table(
            table, header_row=['name', 'domain(s)', 'conf', 'location'])

    def run_where(self):
        name = self.args.name
        location = None
        for path in self._get_projects():
            settings = self.read_project(path)
            if settings.get('service', 'name', None) == name:
                location = settings.get('service', 'location', None)
        if location is None:
            self.error("no project '{}'".format(name))
        sys.stdout.write(location)

    def run_restart(self):
        name = self.args.name
        if not self.project_exists(name):
            self.error("no project '{}'".format(name))
        temp_dir = os.path.join(
            self.settings.get('service', 'temp_dir', tempfile.gettempdir()),
            'moyasrv')
        try:
            os.makedirs(temp_dir)
        except OSError:
            pass
        change_path = os.path.join(temp_dir, "{}.changes".format(name))
        try:
            with open(change_path, 'a'):
                os.utime(change_path, None)
        except IOError as e:
            sys.stderr.write("{}\n".format(text_type(e)))
            return -1
Beispiel #17
0
            break

        lib_ini_url = package_select["download"] + "/lib.ini"
        lib_settings_response = requests.get(lib_ini_url, verify=False)
        lib_settings = settings.SettingsContainer.read_from_file(
            io.StringIO(lib_settings_response.text))

        def make_app_name(dep):
            long_name = versioning.VersionSpec(dep).name
            return long_name.split(".", 1)[-1].replace(".", "")

        if "requires" in lib_settings:
            for dep in lib_settings.get_list("requires", "install", ""):
                app_name = make_app_name(dep)
                package_stack.append((app_name, None, dep))
                dependancy = True
            for dep in lib_settings.get_list("requires", "mount", ""):
                app_name = make_app_name(dep)
                package_stack.append((app_name, "/{}/".format(app_name), dep))

    return requirements


if __name__ == "__main__":
    from moya.console import Console

    rpc = jsonrpc.JSONRPC("https://packages.moyaproject.com/jsonrpc/",
                          ssl_verify=False)
    req = gather_dependencies(rpc, "moya.logins==0.1.1-beta", Console())
    print(req)
Beispiel #18
0
class MoyaSrv(object):
    """Moya Service"""

    def get_argparse(self):
        parser = argparse.ArgumentParser(prog="moya-srv",
                                         description=self.__doc__)

        parser.add_argument('-d', '--debug', dest="debug", action="store_true",
                            help="enable debug information (show tracebacks)")
        parser.add_argument('--home', dest="home", metavar="PATH", default=None,
                            help="moya service directory")

        subparsers = parser.add_subparsers(title="available sub-commands",
                                           dest="subcommand",
                                           help="sub-command help")

        list_parser = subparsers.add_parser('list',
                                            help="list projects",
                                            description="list enabled projects")
        list_parser

        where_parser = subparsers.add_parser('where',
                                             help='find project directory',
                                             description="output the location of the project")

        where_parser.add_argument(dest="name", metavar="PROJECT",
                                  help="name of a project")

        restart_parser = subparsers.add_parser('restart',
                                               help='restart a project server',
                                               description="restart a server")

        restart_parser.add_argument(dest="name", metavar="PROJECT",
                                    help="name of a project")

        return parser

    def error(self, msg, code=-1):
        sys.stderr.write(msg + '\n')
        sys.exit(code)

    def run(self):
        parser = self.get_argparse()
        self.args = args = parser.parse_args(sys.argv[1:])
        self.console = Console()

        self.home_dir = args.home or os.environ.get('MOYA_SRV_HOME', None) or DEFAULT_HOME_DIR

        settings_path = os.path.join(self.home_dir, 'moya.conf')
        try:
            with io.open(settings_path, 'rt') as f:
                self.settings = SettingsContainer.read_from_file(f)
        except IOError:
            self.error('unable to read {}'.format(settings_path))
            return -1

        method_name = "run_" + args.subcommand.replace('-', '_')
        try:
            return getattr(self, method_name)() or 0
        except CommandError as e:
            self.error(text_type(e))
        except Exception as e:
            if args.debug:
                raise
            self.error(text_type(e))

    def _get_projects(self):
        project_paths = self.settings.get_list('projects', 'read')
        paths = []
        cwd = os.getcwd()
        try:
            os.chdir(self.home_dir)
            for path in project_paths:
                glob_paths = glob.glob(path)
                paths.extend([os.path.abspath(p) for p in glob_paths])
        finally:
            os.chdir(cwd)
        return paths

    def project_exists(self, name):
        for path in self._get_projects():
            settings = self.read_project(path)
            if settings.get('service', 'name', None) == name:
                return True
        return False

    def read_project(self, path):
        settings = SettingsContainer.read_os(path)
        return settings

    def run_list(self):
        table = []
        for path in self._get_projects():
            settings = self.read_project(path)
            location = settings.get('service', 'location', '?')
            name = settings.get('service', 'name', '?')
            domains = "\n".join(settings.get_list('service', 'domains', ""))
            table.append([name, domains, path, location])
        self.console.table(table, header_row=['name', 'domain(s)', 'conf', 'location'])

    def run_where(self):
        name = self.args.name
        location = None
        for path in self._get_projects():
            settings = self.read_project(path)
            if settings.get('service', 'name', None) == name:
                location = settings.get('service', 'location', None)
        if location is None:
            self.error("no project '{}'".format(name))
        sys.stdout.write(location)

    def run_restart(self):
        name = self.args.name
        if not self.project_exists(name):
            self.error("no project '{}'".format(name))
        temp_dir = os.path.join(self.settings.get('service', 'temp_dir', tempfile.gettempdir()), 'moyasrv')
        try:
            os.makedirs(temp_dir)
        except OSError:
            pass
        change_path = os.path.join(temp_dir, "{}.changes".format(name))
        try:
            with open(change_path, 'a'):
                os.utime(change_path, None)
        except IOError as e:
            sys.stderr.write("{}\n".format(text_type(e)))
            return -1
Beispiel #19
0
    def run(self):
        args = self.args
        location = args.location

        console = self.console
        if args.output is not None:
            from moya.console import Console
            console = Console(html=True)

        def write_output():
            if args.output is not None:
                from moya import consolehtml
                html = console.get_text()
                html = consolehtml.render_console_html(html)
                with open(args.output, 'wb') as f:
                    f.write(html.encode('utf-8'))

        test_libs = []
        for location in args.location:
            archive, lib = build.build_lib(location)
            lib_name = lib.long_name

            if archive.failed_documents:
                sys.stderr.write('library build failed\n')
                build.render_failed_documents(archive, console)
                write_output()
                return -1

            test_libs.append(lib)

        for lib_name in test_libs:
            if not lib.load_tests():
                sys.stderr.write('no tests for {}\n'.format(lib))
                return -1

        archive.finalize()

        if archive.failed_documents:
            sys.stderr.write('tests build failed\n')
            build.render_failed_documents(archive, console)
            write_output()
            return -1

        if args.automated:
            archive.suppress_breakpoints = True

        all_results = []

        for lib in test_libs:
            suites = list(lib.get_elements_by_type((namespaces.test, 'suite')))

            for suite_no, suite in enumerate(suites, 1):

                try:
                    suite_description = suite.description
                except:
                    suite_description = suite.libid

                if args.quick and suite.slow:
                    with self.console.progress("{} {} (skipped slow test)".format(lib, suite_description), 0):
                        pass
                    continue

                if args.exclude and suite.group is not None and suite.group in args.exclude:
                    with self.console.progress("{} {} (excluded group)".format(lib, suite_description), 0):
                        pass
                    continue

                if args.group and suite.group not in args.group:
                    with self.console.progress("{} {} (not in group)".format(lib, suite_description), 0):
                        pass
                    continue

                steps = 0
                setup = suite.get_child((namespaces.test, 'setup'))
                teardown = suite.get_child((namespaces.test, 'teardown'))
                if setup is not None:
                    setup_callable = archive.get_callable_from_element(setup)
                    steps += 1
                if teardown is not None:
                    teardown_callable = archive.get_callable_from_element(teardown)
                    steps += 1
                tests = list(suite.children((namespaces.test, 'case')))
                steps += len(tests)

                #test_runner = {"break": args._break}
                test_runner = {}
                context = Context({'_test_runner': test_runner})

                results = TestResults(context, lib, suite.description)
                results.group = suite._definition
                all_results.append(results)

                context['._test_results'] = results
                test_info = "({} of {})".format(suite_no, len(suites))
                progress_text = "{} {} {}".format(lib, suite_description, test_info)

                with self.console.progress(progress_text, steps) as progress:
                    if steps == 0:
                        progress.step()
                    else:
                        try:
                            with TestRunner(context, results):
                                if setup is not None:
                                    setup_callable(context)
                                    progress.step()
                        except Exception as e:
                            results.add_setup_error(setup, e)
                            progress.step('setup failed')
                        else:
                            with TestRunner(context, results):
                                for test in tests:
                                    results.case = test
                                    test_callable = archive.get_callable_from_element(test)
                                    try:
                                        test_return = test_callable(context)
                                    except Exception as e:
                                        results.add_error(test, e)
                                    else:
                                        if test_return != 'fail':
                                            results.add_pass(test)
                                    finally:
                                        progress.step()

                            try:
                                with TestRunner(context, results):
                                    if teardown is not None:
                                        teardown_callable(context)
                                        progress.step()
                            except Exception as e:
                                results.add_teardown_error(teardown, e)

        all_totals = {'pass': 0, 'fail': 0, 'error': 0}
        for result in all_results:
            _pass, fail, error = result.stats
            all_totals['pass'] += _pass
            all_totals['fail'] += fail
            all_totals['error'] += error
        summary = "{fail} fail(s), {error} error(s), {pass} pass(es)".format(**all_totals)

        #self.console.nl()
        if args.quick:
            console.div("Test results (quick) {}".format(datetime.now().ctime()))
        else:
            console.div("Test results {}".format(datetime.now().ctime()))
        test_count = sum(len(r.tests) for r in all_results)
        console.text('Ran {} test(s) in {} test suite(s) - {}'.format(test_count, len(all_results), summary))
        for results in all_results:
            results.report(console,
                           show_trace=not args.summary,
                           show_passes=args.verbose or args.summary,
                           verbose=args.verbose)

        header = ['lib', 'suite', 'passes', 'fails', 'errors']
        table = []
        passes = 0
        fails = 0
        errors = 0
        for result in all_results:
            _pass, fail, error = result.stats
            passes += _pass
            fails += fail
            errors += error
            _pass = Cell(_pass, fg="green" if _pass else 'white', bold=True)
            fail = Cell(fail, fg="red" if fail else "green", bold=True)
            error = Cell(error, fg="red" if error else "green", bold=True)
            table.append([result.lib.long_name, result.suite, _pass, fail, error])

        if not args.summary or args.verbose:
            console.nl()
            console.table(table, header_row=header)

        summary = "{fails} fail(s), {errors} error(s), {passes} pass(es)".format(fails=fails, errors=errors, passes=passes)
        if errors or fails:
            console.text(summary, fg="red", bold=True)
        else:
            console.text(summary, fg="green", bold=True)

        write_output()

        return fails