Beispiel #1
0
 def generate_optimized_static_assets(self):
     """
     Collect static assets using test_static_optimized.py which generates
     optimized files to a dedicated test static root.
     """
     print colorize("green", "Generating optimized static assets...")
     sh("paver update_assets --settings=test_static_optimized")
    def __init__(self, *args, **kwargs):
        super(SystemTestSuite, self).__init__(*args, **kwargs)
        self.test_id = kwargs.get('test_id', self._default_test_id)
        self.fasttest = kwargs.get('fasttest', False)

        self.processes = kwargs.get('processes', None)
        self.randomize = kwargs.get('randomize', None)
        self.settings = kwargs.get('settings', Env.TEST_SETTINGS)

        if self.processes is None:
            # Don't use multiprocessing by default
            self.processes = 0

        self.processes = int(self.processes)

        if self.randomize is None:
            self.randomize = self.root == 'lms'

        if self.processes != 0 and self.verbosity > 1:
            print colorize(
                'red',
                "The TestId module and multiprocessing module can't be run "
                "together in verbose mode. Disabling TestId for {} tests.".format(self.root)
            )
            self.use_ids = False
def test_acceptance(options):
    """
    Run the acceptance tests for the either lms or cms
    """
    opts = {
        'fasttest': getattr(options, 'fasttest', False),
        'system': getattr(options, 'system', None),
        'default_store': getattr(options, 'default_store', None),
        'verbosity': getattr(options, 'verbosity', 3),
        'extra_args': getattr(options, 'extra_args', ''),
        'pdb': getattr(options, 'pdb', False),
    }

    if opts['system'] not in ['cms', 'lms']:
        msg = colorize(
            'red',
            'No system specified, running tests for both cms and lms.'
        )
        print msg
    if opts['default_store'] not in ['draft', 'split']:
        msg = colorize(
            'red',
            'No modulestore specified, running tests for both draft and split.'
        )
        print msg

    suite = AcceptanceTestSuite('{} acceptance'.format(opts['system']), **opts)
    suite.run()
Beispiel #4
0
    def __init__(self, *args, **kwargs):
        super(SystemTestSuite, self).__init__(*args, **kwargs)
        self.test_id = kwargs.get('test_id', self._default_test_id)
        self.fasttest = kwargs.get('fasttest', False)

        self.processes = kwargs.get('processes', None)
        self.randomize = kwargs.get('randomize', None)

        if self.processes is None:
            # Use one process per core for LMS tests, and no multiprocessing
            # otherwise.
            self.processes = 0

        self.processes = int(self.processes)

        if self.randomize is None:
            self.randomize = False

        if self.processes != 0 and self.verbosity > 1:
            print colorize(
                'red',
                "The TestId module and multiprocessing module can't be run "
                "together in verbose mode. Disabling TestId for {} tests.".format(self.root)
            )
            self.use_ids = False
Beispiel #5
0
    def __enter__(self):
        super(BokChoyTestSuite, self).__enter__()

        # Ensure that we have a directory to put logs and reports
        self.log_dir.makedirs_p()
        self.report_dir.makedirs_p()
        test_utils.clean_reports_dir()

        msg = colorize("green", "Checking for mongo, memchache, and mysql...")
        print(msg)
        bokchoy_utils.check_services()

        if not self.fasttest:
            # Process assets and set up database for bok-choy tests
            # Reset the database
            sh("{}/scripts/reset-test-db.sh".format(Env.REPO_ROOT))

            # Collect static assets
            sh("paver update_assets --settings=bok_choy")

        # Clear any test data already in Mongo or MySQLand invalidate
        # the cache
        bokchoy_utils.clear_mongo()
        self.cache.flush_all()

        sh("./manage.py lms --settings bok_choy loaddata --traceback" " common/test/db_fixtures/*.json")

        # Ensure the test servers are available
        msg = colorize("green", "Starting test servers...")
        print(msg)
        bokchoy_utils.start_servers()

        msg = colorize("green", "Waiting for servers to start...")
        print(msg)
        bokchoy_utils.wait_for_test_servers()
    def get_test_course(self):
        """
        Fetches the test course.
        """
        self.imports_dir.makedirs_p()
        zipped_course = self.imports_dir + 'demo_course.tar.gz'

        msg = colorize('green', "Fetching the test course from github...")
        print msg

        sh(
            'wget {tar_gz_file} -O {zipped_course}'.format(
                tar_gz_file=self.tar_gz_file,
                zipped_course=zipped_course,
            )
        )

        msg = colorize('green', "Uncompressing the test course...")
        print msg

        sh(
            'tar zxf {zipped_course} -C {courses_dir}'.format(
                zipped_course=zipped_course,
                courses_dir=self.imports_dir,
            )
        )
Beispiel #7
0
def format_message(status):
    sender = console.colorize('red', '@%s' % status.GetSenderScreenName())
    recipient = console.colorize('red', '@%s' % status.GetRecipientScreenName())
    date = console.colorize('blue', '\t\t%s' % status.GetCreatedAt())
    arrow = console.colorize('darkgray', ' -> ')
    text = console.colorize('black', '\t%s' % format_text(status.GetText()))
    return '\n'.join([sender + arrow + recipient + date, text])
    def __enter__(self):
        super(BokChoyTestSuite, self).__enter__()

        # Ensure that we have a directory to put logs and reports
        self.log_dir.makedirs_p()
        self.har_dir.makedirs_p()
        self.report_dir.makedirs_p()
        test_utils.clean_reports_dir()

        if not (self.fasttest or self.skip_clean):
            test_utils.clean_test_files()

        msg = colorize('green', "Checking for mongo, memchache, and mysql...")
        print msg
        bokchoy_utils.check_services()

        if not self.testsonly:
            self.prepare_bokchoy_run()

        msg = colorize('green', "Confirming servers have started...")
        print msg
        bokchoy_utils.wait_for_test_servers()
        try:
            # Create course in order to seed forum data underneath. This is
            # a workaround for a race condition. The first time a course is created;
            # role permissions are set up for forums.
            CourseFixture('foobar_org', '1117', 'seed_forum', 'seed_foo').install()
            print 'Forums permissions/roles data has been seeded'
        except FixtureError:
            # this means it's already been done
            pass

        if self.serversonly:
            self.run_servers_continuously()
Beispiel #9
0
    def report_test_results(self):
        """
        Writes a list of failed_suites to sys.stderr
        """
        if self.failed_suites:
            msg = colorize('red', "\n\n{bar}\nTests failed in the following suites:\n* ".format(bar="=" * 48))
            msg += colorize('red', '\n* '.join([s.root for s in self.failed_suites]) + '\n\n')
        else:
            msg = colorize('green', "\n\n{bar}\nNo test failures ".format(bar="=" * 48))

        print msg
Beispiel #10
0
    def report_test_results(self):
        """
        Writes a list of failed_suites to sys.stderr
        """
        if len(self.failed_suites) > 0:
            msg = colorize("red", "\n\n{bar}\nTests failed in the following suites:\n* ".format(bar="=" * 48))
            msg += colorize("red", "\n* ".join([s.root for s in self.failed_suites]) + "\n\n")
        else:
            msg = colorize("green", "\n\n{bar}\nNo test failures ".format(bar="=" * 48))

        print (msg)
Beispiel #11
0
 def generate_optimized_static_assets(self, log_dir=None):
     """
     Collect static assets using test_static_optimized.py which generates
     optimized files to a dedicated test static root. Optionally use
     a log directory for collectstatic output.
     """
     print colorize('green', "Generating optimized static assets...")
     if not log_dir:
         sh("paver update_assets --settings=test_static_optimized")
     else:
         sh("paver update_assets --settings=test_static_optimized --collect-log={log_dir}".format(
             log_dir=log_dir
         ))
    def __exit__(self, exc_type, exc_value, traceback):
        super(BokChoyTestSuite, self).__exit__(exc_type, exc_value, traceback)

        # Using testsonly will leave all fixtures in place (Note: the db will also be dirtier.)
        if self.testsonly:
            msg = colorize('green', 'Running in testsonly mode... SKIPPING database cleanup.')
            print msg
        else:
            # Clean up data we created in the databases
            msg = colorize('green', "Cleaning up databases...")
            print msg
            sh("./manage.py lms --settings bok_choy flush --traceback --noinput")
            bokchoy_utils.clear_mongo()
Beispiel #13
0
 def __init__(self, **options):
     Formatter.__init__(self, **options)
     self.compress = get_choice_opt(options, 'compress',
                                    ['', 'none', 'gz', 'bz2'], '')
     self.error_color = options.get('error_color', None)
     if self.error_color is True:
         self.error_color = 'red'
     if self.error_color is not None:
         try:
             colorize(self.error_color, '')
         except KeyError:
             raise ValueError("Invalid color %r specified" %
                              self.error_color)
Beispiel #14
0
 def __init__(self, **options):
     Formatter.__init__(self, **options)
     if self.encoding:
         raise OptionError("the raw formatter does not support the " "encoding option")
     self.encoding = "utf-8"  # let pygments.format() do the right thing
     self.compress = get_choice_opt(options, "compress", ["", "none", "gz", "bz2"], "")
     self.error_color = options.get("error_color", None)
     if self.error_color is True:
         self.error_color = "red"
     if self.error_color is not None:
         try:
             colorize(self.error_color, "")
         except KeyError:
             raise ValueError("Invalid color %r specified" % self.error_color)
Beispiel #15
0
    def restart(self):
        self.cls()
        print "%s" % console.reset_color()
        self.cls()

        op = raw_input(console.colorize('green', 'Timing again? ') +
                       console.colorize('turquoise', '(y/n)') +
                       console.colorize('green', ': '))
        if op in ("y", "Y"):
            self.clocking()
        elif op in ("n", "N"):
            print console.reset_color()
            self.cls()
            sys.exit(EXIT)
        else:
            self.restart()
Beispiel #16
0
def pretty_run(to_run):
    if isinstance(to_run, basestring):
        text = to_run
    else:
        text = " ".join(to_run)
    sys.stderr.write(colorize("green", text + "\n"))
    return run(to_run)
 def section(self, message, opts={}):
     if 'plain' != self.settings['highlight']:
         message = colorize('bold', message)
     else:
         message += "\n" + '-' * len(message)
         pass
     self.msg(message)
Beispiel #18
0
    def run_test(self):
        """
        Runs a self.cmd in a subprocess and waits for it to finish.
        It returns False if errors or failures occur. Otherwise, it
        returns True.
        """
        cmd = self.cmd
        sys.stdout.write(cmd)

        msg = colorize(
            "green", "\n{bar}\n Running tests for {suite_name} \n{bar}\n".format(suite_name=self.root, bar="=" * 40)
        )

        sys.stdout.write(msg)
        sys.stdout.flush()

        kwargs = {"shell": True, "cwd": None}
        process = None

        try:
            process = subprocess.Popen(cmd, **kwargs)
            process.communicate()
        except KeyboardInterrupt:
            kill_process(process)
            sys.exit(1)
        else:
            return process.returncode == 0
    def prepare_bokchoy_run(self):
        """
        Sets up and starts servers for a Bok Choy run. If --fasttest is not
        specified then static assets are collected
        """
        sh("{}/scripts/reset-test-db.sh".format(Env.REPO_ROOT))

        if not self.fasttest:
            self.generate_optimized_static_assets()

        # Clear any test data already in Mongo or MySQLand invalidate
        # the cache
        bokchoy_utils.clear_mongo()
        self.cache.flush_all()

        # load data in db_fixtures
        self.load_data()

        # load courses if self.imports_dir is set
        self.load_courses()

        # Ensure the test servers are available
        msg = colorize('green', "Confirming servers are running...")
        print msg
        bokchoy_utils.start_servers(self.default_store, self.coveragerc)
Beispiel #20
0
def generate_pr_table(start_ref, end_ref):
    """
    Return a UTF-8 string corresponding to a pull request table to embed in Confluence.
    """
    header = "|| Merged By || Author || Title || PR || JIRA || Release Notes? || Verified? ||"
    pr_link = "[#{num}|https://github.com/edx/edx-platform/pull/{num}]"
    user_link = "[@{user}|https://github.com/{user}]"
    rows = [header]
    prbe = prs_by_email(start_ref, end_ref)
    for email, pull_requests in prbe.items():
        for i, pull_request in enumerate(pull_requests):
            try:
                pr_info = get_pr_info(pull_request)
                title = pr_info["title"] or ""
                body = pr_info["body"] or ""
                author = pr_info["user"]["login"]
            except requests.exceptions.RequestException as e:
                message = (
                    "Warning: could not fetch data for #{num}: "
                    "{message}".format(num=pull_request, message=e.message)
                )
                print(colorize("red", message), file=sys.stderr)
                title = "?"
                body = "?"
                author = ""
            rows.append("| {merged_by} | {author} | {title} | {pull_request} | {jira} | {release_notes} | {verified} |".format(
                merged_by=email if i == 0 else "",
                author=user_link.format(user=author) if author else "",
                title=title.replace("|", "\|").replace('{', '\{').replace('}', '\}'),
                pull_request=pr_link.format(num=pull_request),
                jira=", ".join(parse_ticket_references(body)),
                release_notes="",
                verified="",
            ))
    return "\n".join(rows).encode("utf8")
Beispiel #21
0
    def format(self, tokensource, outfile):
        if self.compress == 'gz':
            import gzip
            outfile = gzip.GzipFile('', 'wb', 9, outfile)
            write = outfile.write
            flush = outfile.flush
        elif self.compress == 'bz2':
            import bz2
            compressor = bz2.BZ2Compressor(9)
            def write(text):
                outfile.write(compressor.compress(text))
            def flush():
                outfile.write(compressor.flush())
                outfile.flush()
        else:
            write = outfile.write
            flush = outfile.flush

        lasttype = None
        lastval = u''
        if self.error_color:
            for ttype, value in tokensource:
                line = "%s\t%r\n" % (ttype, value)
                if ttype is Token.Error:
                    write(colorize(self.error_color, line))
                else:
                    write(line)
        else:
            for ttype, value in tokensource:
                write("%s\t%r\n" % (ttype, value))
        flush()
Beispiel #22
0
    def run_test(self):
        """
        Runs a self.cmd in a subprocess and waits for it to finish.
        It returns False if errors or failures occur. Otherwise, it
        returns True.
        """
        cmd = " ".join(self.cmd)

        if tasks.environment.dry_run:
            tasks.environment.info(cmd)
            return

        sys.stdout.write(cmd)

        msg = colorize(
            'green',
            '\n{bar}\n Running tests for {suite_name} \n{bar}\n'.format(suite_name=self.root, bar='=' * 40),
        )

        sys.stdout.write(msg)
        sys.stdout.flush()

        kwargs = {'shell': True, 'cwd': None}
        process = None

        try:
            process = subprocess.Popen(cmd, **kwargs)
            process.communicate()
        except KeyboardInterrupt:
            kill_process(process)
            sys.exit(1)
        else:
            return process.returncode == 0
Beispiel #23
0
def diff_coverage(options):
    """
    Build the diff coverage reports
    """
    compare_branch = getattr(options, "compare_branch", "origin/master")

    # Find all coverage XML files (both Python and JavaScript)
    xml_reports = []

    for filepath in Env.REPORT_DIR.walk():
        if filepath.basename() == "coverage.xml":
            xml_reports.append(filepath)

    if not xml_reports:
        err_msg = colorize("red", "No coverage info found.  Run `paver test` before running `paver coverage`.\n")
        sys.stderr.write(err_msg)
    else:
        xml_report_str = " ".join(xml_reports)
        diff_html_path = os.path.join(Env.REPORT_DIR, "diff_coverage_combined.html")

        # Generate the diff coverage reports (HTML and console)
        sh(
            "diff-cover {xml_report_str} --compare-branch={compare_branch} "
            "--html-report {diff_html_path}".format(
                xml_report_str=xml_report_str, compare_branch=compare_branch, diff_html_path=diff_html_path
            )
        )

        print("\n")
Beispiel #24
0
 def __init__(self, **options):
     Formatter.__init__(self, **options)
     # We ignore self.encoding if it is set, since it gets set for lexer
     # and formatter if given with -Oencoding on the command line.
     self.encoding = 'ascii'  # let pygments.format() do the right thing
     self.compress = get_choice_opt(options, 'compress',
                                    ['', 'none', 'gz', 'bz2'], '')
     self.error_color = options.get('error_color', None)
     if self.error_color is True:
         self.error_color = 'red'
     if self.error_color is not None:
         try:
             colorize(self.error_color, '')
         except KeyError:
             raise ValueError("Invalid color %r specified" %
                              self.error_color)
Beispiel #25
0
def diff_coverage(options):
    """
    Build the diff coverage reports
    """
    compare_branch = options.get('compare_branch', 'origin/master')

    # Find all coverage XML files (both Python and JavaScript)
    xml_reports = []

    for filepath in Env.REPORT_DIR.walk():
        if bool(re.match(r'^coverage.*\.xml$', filepath.basename())):
            xml_reports.append(filepath)

    if not xml_reports:
        err_msg = colorize(
            'red',
            "No coverage info found.  Run `paver test` before running "
            "`paver coverage`.\n"
        )
        sys.stderr.write(err_msg)
    else:
        xml_report_str = ' '.join(xml_reports)
        diff_html_path = os.path.join(Env.REPORT_DIR, 'diff_coverage_combined.html')

        # Generate the diff coverage reports (HTML and console)
        sh(
            "diff-cover {xml_report_str} --compare-branch={compare_branch} "
            "--html-report {diff_html_path}".format(
                xml_report_str=xml_report_str,
                compare_branch=compare_branch,
                diff_html_path=diff_html_path,
            )
        )

        print "\n"
Beispiel #26
0
def coverage():
    """
    Build the html, xml, and diff coverage reports
    """
    report_dir = Env.REPORT_DIR
    rcfile = Env.PYTHON_COVERAGERC

    if not (report_dir / '.coverage').isfile():
        # This may be that the coverage files were generated using -p,
        # try to combine them to the one file that we need.
        sh("coverage combine --rcfile={}".format(rcfile))

    if not os.path.getsize(report_dir / '.coverage') > 50:
        # Check if the .coverage data file is larger than the base file,
        # because coverage combine will always at least make the "empty" data
        # file even when there isn't any data to be combined.
        err_msg = colorize(
            'red',
            "No coverage info found.  Run `paver test` before running "
            "`paver coverage`.\n"
        )
        sys.stderr.write(err_msg)
        return

    # Generate the coverage.py XML report
    sh("coverage xml --rcfile={}".format(rcfile))
    # Generate the coverage.py HTML report
    sh("coverage html --rcfile={}".format(rcfile))
    diff_coverage()  # pylint: disable=no-value-for-parameter
Beispiel #27
0
 def __init__(self, **options):
     Formatter.__init__(self, **options)
     if self.encoding:
         raise OptionError('the raw formatter does not support the '
                           'encoding option')
     self.encoding = 'ascii'  # let pygments.format() do the right thing
     self.compress = get_choice_opt(options, 'compress',
                                    ['', 'none', 'gz', 'bz2'], '')
     self.error_color = options.get('error_color', None)
     if self.error_color is True:
         self.error_color = 'red'
     if self.error_color is not None:
         try:
             colorize(self.error_color, '')
         except KeyError:
             raise ValueError("Invalid color %r specified" %
                              self.error_color)
Beispiel #28
0
    def __enter__(self):
        super(BokChoyTestSuite, self).__enter__()

        # Ensure that we have a directory to put logs and reports
        self.log_dir.makedirs_p()
        self.har_dir.makedirs_p()
        self.report_dir.makedirs_p()
        test_utils.clean_reports_dir()  # pylint: disable=no-value-for-parameter

        # Set the environment so that webpack understands where to compile its resources.
        # This setting is expected in other environments, so we are setting it for the
        # bok-choy test run.
        os.environ['EDX_PLATFORM_SETTINGS'] = 'test_static_optimized'

        if not (self.fasttest or self.skip_clean or self.testsonly):
            test_utils.clean_test_files()

        msg = colorize('green', "Checking for mongo, memchache, and mysql...")
        print msg
        check_services()

        if not self.testsonly:
            call_task('prepare_bokchoy_run', options={'log_dir': self.log_dir})
        else:
            # load data in db_fixtures
            load_bok_choy_data()  # pylint: disable=no-value-for-parameter
            update_fixtures()

        msg = colorize('green', "Confirming servers have started...")
        print msg
        wait_for_test_servers()
        try:
            # Create course in order to seed forum data underneath. This is
            # a workaround for a race condition. The first time a course is created;
            # role permissions are set up for forums.
            dry(
                "Installing course fixture for forums",
                CourseFixture('foobar_org', '1117', 'seed_forum', 'seed_foo').install
            )
            print 'Forums permissions/roles data has been seeded'
        except FixtureError:
            # this means it's already been done
            pass

        if self.serversonly:
            self.run_servers_continuously()
def check_mysql():
    """
    Check that mysql is running
    """
    if not is_mysql_running():
        msg = colorize('red', "MySQL is not running locally.")
        print(msg)
        sys.exit(1)
Beispiel #30
0
def parse_coverage(report_dir, coveragerc):
    """
    Generate coverage reports for bok-choy or a11y tests
    """
    report_dir.makedirs_p()

    msg = colorize('green', "Combining coverage reports")
    print msg

    sh("coverage combine --rcfile={}".format(coveragerc))

    msg = colorize('green', "Generating coverage reports")
    print msg

    sh("coverage html --rcfile={}".format(coveragerc))
    sh("coverage xml --rcfile={}".format(coveragerc))
    sh("coverage report --rcfile={}".format(coveragerc))
Beispiel #31
0
 def set_prompt(self, prompt="trepan2"):
     if self.thread_name and self.thread_name != "MainThread":
         prompt += ":" + self.thread_name
         pass
     self.prompt_str = "%s%s%s" % (
         "(" * self.debug_nest,
         prompt,
         ")" * self.debug_nest,
     )
     highlight = self.debugger.settings["highlight"]
     if highlight and highlight in ("light", "dark"):
         self.prompt_str = colorize("underline", self.prompt_str)
     self.prompt_str += " "
Beispiel #32
0
def load_courses(options):
    """
    Loads courses from options.imports_dir.

    Note: options.imports_dir is the directory that contains the directories
    that have courses in them. For example, if the course is located in
    `test_root/courses/test-example-course/`, options.imports_dir should be
    `test_root/courses/`.
    """
    if 'imports_dir' in options:
        msg = colorize(
            'green',
            u"Importing courses from {}...".format(options.imports_dir))
        print(msg)

        sh(u"DEFAULT_STORE={default_store}"
           " ./manage.py cms --settings={settings} import {import_dir}".format(
               default_store=options.default_store,
               import_dir=options.imports_dir,
               settings=Env.SETTINGS))
    else:
        print(colorize('blue', "--imports-dir not set, skipping import"))
Beispiel #33
0
def run_bokchoy(**opts):
    """
    Runs BokChoyTestSuite with the given options.
    """
    test_suite = BokChoyTestSuite('bok-choy', **opts)
    msg = colorize(
        'green',
        'Running tests using {default_store} modulestore.'.format(
            default_store=test_suite.default_store,
        )
    )
    print msg
    test_suite.run()
Beispiel #34
0
    def get_test_course(self):
        """
        Fetches the test course.
        """
        self.imports_dir.makedirs_p()
        zipped_course = self.imports_dir + 'demo_course.tar.gz'

        msg = colorize('green', "Fetching the test course from github...")
        print msg

        sh('wget {tar_gz_file} -O {zipped_course}'.format(
            tar_gz_file=self.tar_gz_file,
            zipped_course=zipped_course,
        ))

        msg = colorize('green', "Uncompressing the test course...")
        print msg

        sh('tar zxf {zipped_course} -C {courses_dir}'.format(
            zipped_course=zipped_course,
            courses_dir=self.imports_dir,
        ))
Beispiel #35
0
def run_bokchoy(options, passthrough_options):
    """
    Runs BokChoyTestSuite with the given options.
    """
    test_suite = BokChoyTestSuite('bok-choy', passthrough_options=passthrough_options, **options)
    msg = colorize(
        'green',
        u'Running tests using {default_store} modulestore.'.format(
            default_store=test_suite.default_store,
        )
    )
    print(msg)
    test_suite.run()
Beispiel #36
0
def prepare_bokchoy_run(options):
    """
    Sets up and starts servers for a Bok Choy run. If --fasttest is not
    specified then static assets are collected
    """
    if not options.get('fasttest', False):

        print(colorize('green', "Generating optimized static assets..."))
        if options.get('log_dir') is None:
            call_task('update_assets',
                      args=['--settings', 'test_static_optimized'])
        else:
            call_task('update_assets',
                      args=[
                          '--settings', 'test_static_optimized',
                          '--collect-log', options.log_dir
                      ])

    # Ensure the test servers are available
    msg = colorize('green', "Confirming servers are running...")
    print(msg)
    start_servers()  # pylint: disable=no-value-for-parameter
Beispiel #37
0
    def __enter__(self):
        super(BokChoyTestSuite, self).__enter__()

        # Ensure that we have a directory to put logs and reports
        self.log_dir.makedirs_p()
        self.har_dir.makedirs_p()
        self.report_dir.makedirs_p()
        test_utils.clean_reports_dir()  # pylint: disable=no-value-for-parameter

        if not (self.fasttest or self.skip_clean or self.testsonly):
            test_utils.clean_test_files()

        msg = colorize('green', "Checking for mongo, memchache, and mysql...")
        print msg
        bokchoy_utils.check_services()

        if not self.testsonly:
            self.prepare_bokchoy_run()
        else:
            # load data in db_fixtures
            self.load_data()

        msg = colorize('green', "Confirming servers have started...")
        print msg
        bokchoy_utils.wait_for_test_servers()
        try:
            # Create course in order to seed forum data underneath. This is
            # a workaround for a race condition. The first time a course is created;
            # role permissions are set up for forums.
            CourseFixture('foobar_org', '1117', 'seed_forum',
                          'seed_foo').install()
            print 'Forums permissions/roles data has been seeded'
        except FixtureError:
            # this means it's already been done
            pass

        if self.serversonly:
            self.run_servers_continuously()
def get_test_course(options):
    """
    Fetches the test course.
    """

    if options.get('imports_dir'):
        print(
            colorize("green",
                     "--imports-dir specified, skipping fetch of test course"))
        return

    if not options.get('should_fetch_course', False):
        print(
            colorize("green",
                     "--skip-fetch specified, skipping fetch of test course"))
        return

    # Set the imports_dir for use by other tasks
    options.imports_dir = DEMO_COURSE_IMPORT_DIR

    options.imports_dir.makedirs_p()
    zipped_course = options.imports_dir + 'demo_course.tar.gz'

    msg = colorize('green', "Fetching the test course from github...")
    print(msg)

    sh('wget {tar_gz_file} -O {zipped_course}'.format(
        tar_gz_file=DEMO_COURSE_TAR_GZ,
        zipped_course=zipped_course,
    ))

    msg = colorize('green', "Uncompressing the test course...")
    print(msg)

    sh('tar zxf {zipped_course} -C {courses_dir}'.format(
        zipped_course=zipped_course,
        courses_dir=options.imports_dir,
    ))
Beispiel #39
0
    def __enter__(self):
        super(BokChoyTestSuite, self).__enter__()

        # Ensure that we have a directory to put logs and reports
        self.log_dir.makedirs_p()
        self.report_dir.makedirs_p()
        test_utils.clean_reports_dir()

        msg = colorize('green', "Checking for mongo, memchache, and mysql...")
        print(msg)
        bokchoy_utils.check_services()

        if not self.fasttest:
            # Process assets and set up database for bok-choy tests
            # Reset the database
            sh("{}/scripts/reset-test-db.sh".format(Env.REPO_ROOT))

            # Collect static assets
            sh("paver update_assets --settings=bok_choy")

        # Clear any test data already in Mongo or MySQLand invalidate
        # the cache
        bokchoy_utils.clear_mongo()
        self.cache.flush_all()

        sh(
            "./manage.py lms --settings bok_choy loaddata --traceback"
            " common/test/db_fixtures/*.json"
        )

        # Ensure the test servers are available
        msg = colorize('green', "Starting test servers...")
        print(msg)
        bokchoy_utils.start_servers()

        msg = colorize('green', "Waiting for servers to start...")
        print(msg)
        bokchoy_utils.wait_for_test_servers()
Beispiel #40
0
def wait_for_test_servers():
    """
    Wait until we get a successful response from the servers or time out
    """

    for service, info in Env.BOK_CHOY_SERVERS.iteritems():
        ready = wait_for_server(info['host'], info['port'])
        if not ready:
            msg = colorize(
                "red",
                "Could not contact {} test server".format(service)
            )
            print msg
            sys.exit(1)
Beispiel #41
0
def update_fixtures():
    """
    Use the correct domain for the current test environment in each Site
    fixture.  This currently differs between devstack cms, devstack lms,
    and Jenkins.
    """
    msg = colorize('green', "Updating the Site fixture domains...")
    print(msg)

    sh(
        u" ./manage.py lms --settings={settings} update_fixtures".format(
            settings=Env.SETTINGS
        )
    )
Beispiel #42
0
    def __init__(self, *args, **kwargs):
        super(SystemTestSuite, self).__init__(*args, **kwargs)
        self.test_id = kwargs.get('test_id', self._default_test_id)
        self.fasttest = kwargs.get('fasttest', False)

        self.processes = kwargs.get('processes', None)
        self.randomize = kwargs.get('randomize', None)

        if self.processes is None:
            # Don't use multiprocessing by default
            self.processes = 0

        self.processes = int(self.processes)

        if self.randomize is None:
            self.randomize = self.root == 'lms'

        if self.processes != 0 and self.verbosity > 1:
            print colorize(
                'red',
                "The TestId module and multiprocessing module can't be run "
                "together in verbose mode. Disabling TestId for {} tests.".
                format(self.root))
            self.use_ids = False
Beispiel #43
0
    def __enter__(self):
        super(BokChoyTestSuite, self).__enter__()

        # Ensure that we have a directory to put logs and reports
        self.log_dir.makedirs_p()
        self.har_dir.makedirs_p()
        self.report_dir.makedirs_p()
        test_utils.clean_reports_dir()

        if not self.skip_clean:
            test_utils.clean_test_files()

        msg = colorize('green', "Checking for mongo, memchache, and mysql...")
        print msg
        bokchoy_utils.check_services()

        if not self.testsonly:
            self.prepare_bokchoy_run()

        msg = colorize('green', "Confirming servers have started...")
        print msg
        bokchoy_utils.wait_for_test_servers()
        if self.serversonly:
            self.run_servers_continuously()
Beispiel #44
0
def i18n_validate_transifex_config():
    """
    Make sure config file with username/password exists
    """
    home = path('~').expanduser()
    config = home / '.transifexrc'

    if not config.isfile or config.getsize == 0:
        msg = colorize(
            'red', "Cannot connect to Transifex, config file is missing"
            " or empty: {config} \nSee "
            "http://help.transifex.com/features/client/#transifexrc \n".format(
                config=config, ))

        sys.stderr.write(msg)
        sys.exit(1)
Beispiel #45
0
def i18n_push():
    # Re extract after code replace
    sh("i18n_tool extract")
    sh("paver i18n_third_party")
    sh("i18n_tool validate")
    sh("i18n_tool generate --strict")
    sh("python manage.py cms compilejsi18n")
    sh("python manage.py lms compilejsi18n")

    msg = colorize('green',
                   "Please checking your code after update and replace.")
    print msg

    con = raw_input("Are you want to replace all sources in transifex (y/n)? ")
    if con.lower() == 'y':
        sh("tx push -s -t -l zh_CN")
Beispiel #46
0
def coverage(options):
    """
    Build the html, xml, and diff coverage reports
    """
    compare_branch = getattr(options, 'compare_branch', 'origin/master')

    for directory in Env.LIB_TEST_DIRS + ['cms', 'lms']:
        report_dir = Env.REPORT_DIR / directory

        if (report_dir / '.coverage').isfile():
            # Generate the coverage.py HTML report
            sh("coverage html --rcfile={dir}/.coveragerc".format(dir=directory))

            # Generate the coverage.py XML report
            sh("coverage xml -o {report_dir}/coverage.xml --rcfile={dir}/.coveragerc".format(
                report_dir=report_dir,
                dir=directory
            ))

    # Find all coverage XML files (both Python and JavaScript)
    xml_reports = []

    for filepath in Env.REPORT_DIR.walk():
        if filepath.basename() == 'coverage.xml':
            xml_reports.append(filepath)

    if not xml_reports:
        err_msg = colorize(
            'red',
            "No coverage info found.  Run `paver test` before running `paver coverage`.\n"
        )
        sys.stderr.write(err_msg)
    else:
        xml_report_str = ' '.join(xml_reports)
        diff_html_path = os.path.join(Env.REPORT_DIR, 'diff_coverage_combined.html')

        # Generate the diff coverage reports (HTML and console)
        sh(
            "diff-cover {xml_report_str} --compare-branch={compare_branch} "
            "--html-report {diff_html_path}".format(
                xml_report_str=xml_report_str,
                compare_branch=compare_branch,
                diff_html_path=diff_html_path,
            )
        )

        print("\n")
Beispiel #47
0
def i18n_validate_gettext():
    """
    Make sure GNU gettext utilities are available
    """

    returncode = subprocess.call(['which', 'xgettext'])

    if returncode != 0:
        msg = colorize(
            'red', "Cannot locate GNU gettext utilities, which are "
            "required by django for internationalization.\n (see "
            "https://docs.djangoproject.com/en/dev/topics/i18n/"
            "translation/#message-files)\nTry downloading them from "
            "http://www.gnu.org/software/gettext/ \n")

        sys.stderr.write(msg)
        sys.exit(1)
Beispiel #48
0
def run_bokchoy(**opts):
    """
    Runs BokChoyTestSuite with the given options.
    If a default store is not specified, runs the test suite for 'split' as the default store.
    """
    if opts['default_store'] not in ['draft', 'split']:
        msg = colorize('red',
                       'No modulestore specified, running tests for split.')
        print(msg)
        stores = ['split']
    else:
        stores = [opts['default_store']]

    for store in stores:
        opts['default_store'] = store
        test_suite = BokChoyTestSuite('bok-choy', **opts)
        test_suite.run()
def test_acceptance(options):
    """
    Run the acceptance tests for the either lms or cms
    """
    opts = {
        'fasttest': getattr(options, 'fasttest', False),
        'system': getattr(options, 'system', None),
        'verbosity': getattr(options, 'verbosity', 3),
        'extra_args': getattr(options, 'extra_args', ''),
    }

    if opts['system'] not in ['cms', 'lms']:
        msg = colorize(
            'red', 'No system specified, running tests for both cms and lms.')
        print(msg)

    suite = AcceptanceTestSuite('{} acceptance'.format(opts['system']), **opts)
    suite.run()
Beispiel #50
0
    def load_courses(self):
        """
        Loads courses from self.imports_dir.

        Note: self.imports_dir is the directory that contains the directories
        that have courses in them. For example, if the course is located in
        `test_root/courses/test-example-course/`, self.imports_dir should be
        `test_root/courses/`.
        """
        msg = colorize('green',
                       "Importing courses from {}...".format(self.imports_dir))
        print msg

        if self.imports_dir:
            sh("DEFAULT_STORE={default_store}"
               " ./manage.py cms --settings=bok_choy import {import_dir}".
               format(default_store=self.default_store,
                      import_dir=self.imports_dir))
Beispiel #51
0
    def format(self, tokensource, outfile):
        try:
            outfile.write(b(''))
        except TypeError:
            raise TypeError('The raw tokens formatter needs a binary '
                            'output file')
        if self.compress == 'gz':
            import gzip
            outfile = gzip.GzipFile('', 'wb', 9, outfile)

            def write(text):
                outfile.write(text.encode())

            flush = outfile.flush
        elif self.compress == 'bz2':
            import bz2
            compressor = bz2.BZ2Compressor(9)

            def write(text):
                outfile.write(compressor.compress(text.encode()))

            def flush():
                outfile.write(compressor.flush())
                outfile.flush()
        else:

            def write(text):
                outfile.write(text.encode())

            flush = outfile.flush

        lasttype = None
        lastval = u''
        if self.error_color:
            for ttype, value in tokensource:
                line = "%s\t%r\n" % (ttype, value)
                if ttype is Token.Error:
                    write(colorize(self.error_color, line))
                else:
                    write(line)
        else:
            for ttype, value in tokensource:
                write("%s\t%r\n" % (ttype, value))
        flush()
Beispiel #52
0
def prs_by_email(start_ref, end_ref):
    """
    Returns an ordered dictionary of {email: pr_list}
    Email is the email address of the person who merged the pull request
    The dictionary is alphabetically ordered by email address
    The pull request list is ordered by merge date
    """
    # `emails` maps from other_emails to primary email, based on people.yaml.
    emails = {}
    try:
        people_resp = requests.get(PEOPLE_YAML)
        people_resp.raise_for_status()
        people = yaml.safe_load(people_resp.text)
    except requests.exceptions.RequestException as e:
        # Hmm, muddle through without canonicalized emails...
        message = (
            "Warning: could not fetch people.yaml: {message}".format(message=e.message)
        )
        print(colorize("red", message), file=sys.stderr)
    else:
        for person in people.itervalues():
            if 'other_emails' in person:
                for other_email in person['other_emails']:
                    emails[other_email] = person['email']

    unordered_data = collections.defaultdict(set)
    for pr_num in get_merged_prs(start_ref, end_ref):
        ref = "refs/remotes/edx/pr/{num}".format(num=pr_num)
        branch = SymbolicReference(repo, ref)
        try:
            merge = get_merge_commit(branch.commit, end_ref)
        except DoesNotExist:
            pass  # this commit will be included in the commits_without_prs table
        else:
            email = emails.get(merge.author.email, merge.author.email)
            unordered_data[email].add((pr_num, merge))

    ordered_data = collections.OrderedDict()
    for email in sorted(unordered_data.keys()):
        ordered = sorted(unordered_data[email], key=lambda pair: pair[1].authored_date)
        ordered_data[email] = [num for num, merge in ordered]
    return ordered_data
    def prepare_bokchoy_run(self):
        """
        Sets up and starts servers for bok-choy run. This includes any stubbed servers.
        """
        sh("{}/scripts/reset-test-db.sh".format(Env.REPO_ROOT))

        if not self.fasttest:
            # Process assets and set up database for bok-choy tests
            # Reset the database

            # Collect static assets
            sh("paver update_assets --settings=bok_choy")

        # Clear any test data already in Mongo or MySQLand invalidate
        # the cache
        bokchoy_utils.clear_mongo()
        self.cache.flush_all()

        sh(
            "DEFAULT_STORE={default_store}"
            " ./manage.py lms --settings bok_choy loaddata --traceback"
            " common/test/db_fixtures/*.json".format(
                default_store=self.default_store,
            )
        )

        if self.imports_dir:
            sh(
                "DEFAULT_STORE={default_store}"
                " ./manage.py cms --settings=bok_choy import {import_dir}".format(
                    default_store=self.default_store,
                    import_dir=self.imports_dir
                )
            )

        # Ensure the test servers are available
        msg = colorize('green', "Confirming servers are running...")
        print msg
        bokchoy_utils.start_servers(self.default_store)
Beispiel #54
0
 def in_set_time(self):
     try:
         print (console.colorize('green', 'Enter the time for timing'))
         print (console.colorize('blue', '0') +
                console.colorize('green', ' to') +
                console.colorize('blue', ' exit'))
         print (console.colorize('green', 'nothing to ') +
                console.colorize('blue', '5 ') +
                console.colorize('green', 'minutes'))
         timing = raw_input(console.colorize('red', '>> '))
     except:
         sys.exit(ERROR)
     if timing == '0':
         sys.exit(EXIT)
     try:
         if timing:
             timing = float(timing)
         else:
             timing = 5
     except:
         sys.exit(ERROR)
     if timing < 0:
         timing *= -1
     self.timing = int(timing * 60)
Beispiel #55
0
def generate_pr_table(start_ref, end_ref):
    """
    Return a UTF-8 string corresponding to a pull request table to embed in Confluence.
    """
    header = "|| Merged By || Author || Title || PR || JIRA || Release Notes? || Verified? ||"
    pr_link = "[#{num}|https://github.com/edx/edx-platform/pull/{num}]"
    user_link = "[@{user}|https://github.com/{user}]"
    rows = [header]
    prbe = prs_by_email(start_ref, end_ref)
    for email, pull_requests in prbe.items():
        for i, pull_request in enumerate(pull_requests):
            try:
                pr_info = get_pr_info(pull_request)
                title = pr_info["title"] or ""
                body = pr_info["body"] or ""
                author = pr_info["user"]["login"]
            except requests.exceptions.RequestException as e:
                message = ("Warning: could not fetch data for #{num}: "
                           "{message}".format(num=pull_request,
                                              message=e.message))
                print(colorize("red", message), file=sys.stderr)
                title = "?"
                body = "?"
                author = ""
            rows.append(
                "| {merged_by} | {author} | {title} | {pull_request} | {jira} | {release_notes} | {verified} |"
                .format(
                    merged_by=email if i == 0 else "",
                    author=user_link.format(user=author) if author else "",
                    title=title.replace("|",
                                        "\|").replace('{',
                                                      '\{').replace('}', '\}'),
                    pull_request=pr_link.format(num=pull_request),
                    jira=", ".join(parse_ticket_references(body)),
                    release_notes="",
                    verified="",
                ))
    return "\n".join(rows).encode("utf8")
    def prepare_bokchoy_run(self):
        """
        Sets up and starts servers for a Bok Choy run. If --fasttest is not
        specified then static assets are collected
        """
        sh("{}/scripts/reset-test-db.sh".format(Env.REPO_ROOT))

        if not self.fasttest:
            self.generate_optimized_static_assets()

        # Clear any test data already in Mongo or MySQLand invalidate
        # the cache
        bokchoy_utils.clear_mongo()
        self.cache.flush_all()

        sh(
            "DEFAULT_STORE={default_store}"
            " ./manage.py lms --settings bok_choy loaddata --traceback"
            " common/test/db_fixtures/*.json".format(
                default_store=self.default_store,
            )
        )

        if self.imports_dir:
            sh(
                "DEFAULT_STORE={default_store}"
                " ./manage.py cms --settings=bok_choy import {import_dir}".format(
                    default_store=self.default_store,
                    import_dir=self.imports_dir
                )
            )

        # Ensure the test servers are available
        msg = colorize('green', "Confirming servers are running...")
        print msg
        bokchoy_utils.start_servers(self.default_store, self.coveragerc)
Beispiel #57
0
def diff_coverage(options):
    """
    Build the diff coverage reports
    """
    compare_branch = options.get('compare_branch', 'origin/master')

    # Find all coverage XML files (both Python and JavaScript)
    xml_reports = []

    for filepath in Env.REPORT_DIR.walk():
        if bool(re.match(r'^coverage.*\.xml$', filepath.basename())):
            xml_reports.append(filepath)

    if not xml_reports:
        err_msg = colorize(
            'red',
            "No coverage info found.  Run `paver test` before running "
            "`paver coverage`.\n"
        )
        sys.stderr.write(err_msg)
    else:
        xml_report_str = ' '.join(xml_reports)
        diff_html_path = os.path.join(Env.REPORT_DIR, 'diff_coverage_combined.html')

        # Generate the diff coverage reports (HTML and console)
        # The --diff-range-notation parameter is a workaround for https://github.com/Bachmann1234/diff_cover/issues/153
        sh(
            "diff-cover {xml_report_str} --diff-range-notation '..' --compare-branch={compare_branch} "
            "--html-report {diff_html_path}".format(
                xml_report_str=xml_report_str,
                compare_branch=compare_branch,
                diff_html_path=diff_html_path,
            )
        )

        print("\n")
Beispiel #58
0
    def run(self, args):
        proc = self.proc
        dbg_obj  = self.core.debugger
        listsize = dbg_obj.settings['listsize']
        filename, first, last = parse_list_cmd(proc, args, listsize)
        curframe = proc.curframe

        if filename is None: return

        # Sometimes such as due to decompilation we might not really
        # have an idea based on the listing where we really are.
        # Setting "show_marks" to false will disable marking breakpoint
        # and current line numbers.
        show_marks = True

        filename = pyficache.unmap_file(pyficache.pyc2py(filename))

        if filename == "<string>" and proc.curframe.f_code:
            # Deparse the code object into a temp file and remap the line from code
            # into the corresponding line of the tempfile
            co = proc.curframe.f_code
            temp_filename, name_for_code = deparse_and_cache(co, proc.errmsg)
            if temp_filename:
                filename = temp_filename
                show_marks = False
            pass

        # We now have range information. Do the listing.
        max_line = pyficache.size(filename)
        if max_line is None:
            self.errmsg('No file %s found; using "deparse" command instead to show source' %
                        filename)
            proc.commands['deparse'].run(['deparse'])
            return

        canonic_filename = os.path.realpath(os.path.normcase(filename))

        if first > max_line:
            self.errmsg('Bad start line %d - file "%s" has only %d lines'
                        % (first, filename, max_line))
            return

        if last > max_line:
            self.msg('End position changed to last line %d ' % max_line)
            last = max_line

        bplist = self.core.bpmgr.bplist
        opts = {
            'reload_on_change' : self.settings['reload'],
            'output'           : self.settings['highlight'],
            'strip_nl'         : False,
            }

        if 'style' in self.settings:
            opts['style'] = self.settings['style']

        if first <= 0:
            first = 1
        try:
            for lineno in range(first, last+1):
                line = pyficache.getline(filename, lineno, opts)
                if line is None:
                    line = linecache.getline(filename, lineno,
                                             proc.frame.f_globals)
                    pass
                if line is None:
                    self.msg('[EOF]')
                    break
                else:
                    line = line.rstrip('\n')
                    s = proc._saferepr(lineno).rjust(3)
                    if len(s) < 5: s += ' '
                    if (show_marks and
                        (canonic_filename, lineno,) in list(bplist.keys())):
                        bp    = bplist[(canonic_filename, lineno,)][0]
                        a_pad = '%02d' % bp.number
                        s    += bp.icon_char()
                    else:
                        s    += ' '
                        a_pad = '  '
                        pass
                    if (curframe and lineno == inspect.getlineno(curframe)
                        and show_marks):
                        s += '->'
                        if 'plain' != self.settings['highlight']:
                            s = colorize('bold', s)
                    else:
                        s += a_pad
                        pass
                    self.msg(s + '\t' + line)
                    proc.list_lineno = lineno
                    pass
                pass
            pass
        except KeyboardInterrupt:
            pass
        return False
Beispiel #59
0
 def test_functions(self):
     self.assertEqual(console.reset_color(), console.codes['reset'])
     self.assertEqual(console.colorize('blue', 'text'),
                      console.codes['blue'] + 'text' + console.codes['reset'])
Beispiel #60
0
    def run(self, args):
        filename, first, last = self.parse_list_cmd(args[1:])
        curframe = self.proc.curframe
        if filename is None: return
        m = re.search('^<frozen (.*)>', filename)
        if m and m.group(1):
            filename = m.group(1)
            canonic_filename = pyficache.unmap_file(filename)
        else:
            filename = pyc2py(filename)
            canonic_filename = os.path.realpath(os.path.normcase(filename))

        max_line = pyficache.size(filename)
        # FIXME: Should use the below:
        # max_line = pyficache.maxline(filename)

        # We now have range information. Do the listing.
        if max_line is None:
            self.errmsg('No file %s found' % filename)
            return

        if first > max_line:
            self.errmsg('Bad start line %d - file "%s" has only %d lines'
                        % (first, filename, max_line))
            return

        if last > max_line:
            self.msg('End position changed to last line %d ' % max_line)
            last = max_line

        bplist = self.core.bpmgr.bplist
        opts = {
            'reload_on_change' : self.settings['reload'],
            'output'           : self.settings['highlight'],
            'strip_nl'         : False,
            }

        if 'style' in self.settings:
            opts['style'] = self.settings['style']

        try:
            for lineno in range(first, last+1):
                line = pyficache.getline(filename, lineno, opts)
                if line is None:
                    line = linecache.getline(filename, lineno,
                                             self.proc.frame.f_globals)
                    pass
                if line is None:
                    self.msg('[EOF]')
                    break
                else:
                    line = line.rstrip('\n')
                    s = self.proc._saferepr(lineno).rjust(3)
                    if len(s) < 5: s += ' '
                    if (canonic_filename, lineno,) in list(bplist.keys()):
                        bp    = bplist[(canonic_filename, lineno,)][0]
                        a_pad = '%02d' % bp.number
                        s    += bp.icon_char()
                    else:
                        s    += ' '
                        a_pad = '  '
                        pass
                    if curframe and lineno == inspect.getlineno(curframe):
                        s += '->'
                        if 'plain' != self.settings['highlight']:
                            s = colorize('bold', s)
                    else:
                        s += a_pad
                        pass
                    self.msg(s + '\t' + line)
                    self.proc.list_lineno = lineno
                    pass
                pass
        except KeyboardInterrupt:
            pass
        return False