<commit_before># -*- coding: utf-8 -*-
import sys
import logging

logger = logging.getLogger(__name__)
sublogger = logging.getLogger(__name__+'.baz')

u = (lambda x: x.decode('utf-8')) if sys.version_info < (3,) else (lambda x: x)

def test_fixture_help(testdir):
    result = testdir.runpytest('--fixtures')
    result.stdout.fnmatch_lines(['*caplog*'])

def test_change_level(caplog):
    caplog.set_level(logging.INFO)
    logger.debug('handler DEBUG level')
    logger.info('handler INFO level')

    caplog.set_level(logging.CRITICAL, logger=sublogger.name)
    sublogger.warning('logger WARNING level')
    sublogger.critical('logger CRITICAL level')

    assert 'DEBUG' not in caplog.text
    assert 'INFO' in caplog.text
    assert 'WARNING' not in caplog.text
    assert 'CRITICAL' in caplog.text

def test_with_statement(caplog):
    with caplog.at_level(logging.INFO):
        logger.debug('handler DEBUG level')
        logger.info('handler INFO level')

        with caplog.at_level(logging.CRITICAL, logger=sublogger.name):
            sublogger.warning('logger WARNING level')
            sublogger.critical('logger CRITICAL level')

    assert 'DEBUG' not in caplog.text
    assert 'INFO' in caplog.text
    assert 'WARNING' not in caplog.text
    assert 'CRITICAL' in caplog.text

def test_log_access(caplog):
    logger.info('boo %s', 'arg')
    assert caplog.records[0].levelname == 'INFO'
    assert caplog.records[0].msg == 'boo %s'
    assert 'boo arg' in caplog.text

def test_record_tuples(caplog):
    logger.info('boo %s', 'arg')

    assert caplog.record_tuples == [
        (__name__, logging.INFO, 'boo arg'),
    ]

def test_unicode(caplog):
    logger.info(u('bū'))
    assert caplog.records[0].levelname == 'INFO'
    assert caplog.records[0].msg == u('bū')
    assert u('bū') in caplog.text

def test_clear(caplog):
    logger.info(u('bū'))
    assert len(caplog.records)
    caplog.clear()
    assert not len(caplog.records)
<commit_msg>Remove unicode literal compat code<commit_after># -*- coding: utf-8 -*-
import logging

logger = logging.getLogger(__name__)
sublogger = logging.getLogger(__name__+'.baz')

def test_fixture_help(testdir):
    result = testdir.runpytest('--fixtures')
    result.stdout.fnmatch_lines(['*caplog*'])

def test_change_level(caplog):
    caplog.set_level(logging.INFO)
    logger.debug('handler DEBUG level')
    logger.info('handler INFO level')

    caplog.set_level(logging.CRITICAL, logger=sublogger.name)
    sublogger.warning('logger WARNING level')
    sublogger.critical('logger CRITICAL level')

    assert 'DEBUG' not in caplog.text
    assert 'INFO' in caplog.text
    assert 'WARNING' not in caplog.text
    assert 'CRITICAL' in caplog.text

def test_with_statement(caplog):
    with caplog.at_level(logging.INFO):
        logger.debug('handler DEBUG level')
        logger.info('handler INFO level')

        with caplog.at_level(logging.CRITICAL, logger=sublogger.name):
            sublogger.warning('logger WARNING level')
            sublogger.critical('logger CRITICAL level')

    assert 'DEBUG' not in caplog.text
    assert 'INFO' in caplog.text
    assert 'WARNING' not in caplog.text
    assert 'CRITICAL' in caplog.text

def test_log_access(caplog):
    logger.info('boo %s', 'arg')
    assert caplog.records[0].levelname == 'INFO'
    assert caplog.records[0].msg == 'boo %s'
    assert 'boo arg' in caplog.text

def test_record_tuples(caplog):
    logger.info('boo %s', 'arg')

    assert caplog.record_tuples == [
        (__name__, logging.INFO, 'boo arg'),
    ]

def test_unicode(caplog):
    logger.info(u'bū')
    assert caplog.records[0].levelname == 'INFO'
    assert caplog.records[0].msg == u'bū'
    assert u'bū' in caplog.text

def test_clear(caplog):
    logger.info(u'bū')
    assert len(caplog.records)
    caplog.clear()
    assert not len(caplog.records)
<|endoftext|>


<commit_before># Copyright (C) 2014 Linaro Limited
#
# Author: Milosz Wasilewski <milosz.wasilewski@linaro.org>
#
# This file is part of Testmanager.
#
# Testmanager is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License version 3
# as published by the Free Software Foundation
#
# Testmanager is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Testmanager.  If not, see <http://www.gnu.org/licenses/>.

from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.http import (
    HttpResponse,
    HttpResponseServerError,
    HttpResponseRedirect
)
from django.shortcuts import get_object_or_404
from django.template import RequestContext, loader

from testmanager.testrunner.models import (
    JenkinsJob,
    JenkinsBuild,
    LavaJob,
    LavaJobTestResult,
)
from testmanager.testrunner.forms import ResultComparisonForm

@login_required
def index(request):
    jenkins_jobs = JenkinsJob.objects.all()
    template = loader.get_template('testrunner/index.html')
    context = RequestContext(request, {
        'jenkins_jobs': jenkins_jobs,
    })
    return HttpResponse(template.render(context))

@login_required
def jenkins_job_view(request, job_name):
    jenkins_job = get_object_or_404(JenkinsJob, name=job_name)
    jenkins_builds = jenkins_job.builds.filter(is_umbrella=False).order_by("-timestamp")[:10]
    template = loader.get_template('testrunner/jenkins_job_view.html')
    context = RequestContext(request, {
        'jenkins_job': jenkins_job,
        'jenkins_builds': jenkins_builds
    })
    return HttpResponse(template.render(context))

@login_required
def jenkins_build_view(request, job_name, build_number):
    jenkins_job = get_object_or_404(JenkinsJob, name=job_name)
    jenkins_build = jenkins_job.builds.filter(number = build_number)
    jenkins_umbrella_build = jenkins_build.filter(is_umbrella = True)
    if jenkins_umbrella_build.all():
        jenkins_build = jenkins_umbrella_build
    template = loader.get_template('testrunner/jenkins_build_view.html')
    context = RequestContext(request, {
        'jenkins_build': jenkins_build,
        'lava_url': settings.LAVA_JOB_ID_REGEXP.rsplit("/", 1)[0],
    })
    return HttpResponse(template.render(context))

@login_required
def lava_job_view(request, job_name, build_number, lava_job_number):
    lava_job = get_object_or_404(LavaJob, number=lava_job_number)
    template = loader.get_template('testrunner/lava_job_view.html')
    context = RequestContext(request, {
        'lava_job': lava_job,
        'lava_url': settings.LAVA_JOB_ID_REGEXP.rsplit("/", 1)[0],
    })
    return HttpResponse(template.render(context))

@login_required
def compare_results(request):
    if request.method == "GET":
        form = ResultComparisonForm(request.GET)
        if form.is_valid():
            testsets = form.cleaned_data['testresults']
            testcase_names = LavaJobTestResult.objects.filter(
                lava_job_result__in=testsets).order_by("test_case_id").values("test_case_id").distinct("test_case_id")
            testcase_list = []
            for testcase in testcase_names:
                tc_id = testcase['test_case_id']
                testcase_list.append({'name': tc_id, 'results': [], 'is_different': False})
                for testset in testsets:
                    result = testset.lavajobtestresult_set.filter(test_case_id=tc_id)
                    if result:
                        testcase_list[-1]['results'].append(result[0].status.name) # there should be only one?
                    else:
                        testcase_list[-1]['results'].append("-")
                if len(set(testcase_list[-1]['results'])) > 1:
                    testcase_list[-1]['is_different'] = True

            template = loader.get_template('testrunner/compare_results.html')
            context = RequestContext(request, {
                'testsets': testsets,
                'testcases': testcase_list,
            })
            return HttpResponse(template.render(context))
    return HttpResponseRedirect(request.META['HTTP_REFERER'])
<commit_msg>unused imports<commit_after># Copyright (C) 2014 Linaro Limited
#
# Author: Milosz Wasilewski <milosz.wasilewski@linaro.org>
#
# This file is part of Testmanager.
#
# Testmanager is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License version 3
# as published by the Free Software Foundation
#
# Testmanager is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with Testmanager.  If not, see <http://www.gnu.org/licenses/>.

from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.http import (
    HttpResponse,
    HttpResponseRedirect
)
from django.shortcuts import get_object_or_404
from django.template import RequestContext, loader

from testmanager.testrunner.models import (
    JenkinsJob,
    JenkinsBuild,
    LavaJob,
    LavaJobTestResult,
)
from testmanager.testrunner.forms import ResultComparisonForm

@login_required
def index(request):
    jenkins_jobs = JenkinsJob.objects.all()
    template = loader.get_template('testrunner/index.html')
    context = RequestContext(request, {
        'jenkins_jobs': jenkins_jobs,
    })
    return HttpResponse(template.render(context))

@login_required
def jenkins_job_view(request, job_name):
    jenkins_job = get_object_or_404(JenkinsJob, name=job_name)
    jenkins_builds = jenkins_job.builds.filter(is_umbrella=False).order_by("-timestamp")[:10]
    template = loader.get_template('testrunner/jenkins_job_view.html')
    context = RequestContext(request, {
        'jenkins_job': jenkins_job,
        'jenkins_builds': jenkins_builds
    })
    return HttpResponse(template.render(context))

@login_required
def jenkins_build_view(request, job_name, build_number):
    jenkins_job = get_object_or_404(JenkinsJob, name=job_name)
    jenkins_build = jenkins_job.builds.filter(number = build_number)
    jenkins_umbrella_build = jenkins_build.filter(is_umbrella = True)
    if jenkins_umbrella_build.all():
        jenkins_build = jenkins_umbrella_build
    template = loader.get_template('testrunner/jenkins_build_view.html')
    context = RequestContext(request, {
        'jenkins_build': jenkins_build,
        'lava_url': settings.LAVA_JOB_ID_REGEXP.rsplit("/", 1)[0],
    })
    return HttpResponse(template.render(context))

@login_required
def lava_job_view(request, job_name, build_number, lava_job_number):
    lava_job = get_object_or_404(LavaJob, number=lava_job_number)
    template = loader.get_template('testrunner/lava_job_view.html')
    context = RequestContext(request, {
        'lava_job': lava_job,
        'lava_url': settings.LAVA_JOB_ID_REGEXP.rsplit("/", 1)[0],
    })
    return HttpResponse(template.render(context))

@login_required
def compare_results(request):
    if request.method == "GET":
        form = ResultComparisonForm(request.GET)
        if form.is_valid():
            testsets = form.cleaned_data['testresults']
            testcase_names = LavaJobTestResult.objects.filter(
                lava_job_result__in=testsets).order_by("test_case_id").values("test_case_id").distinct("test_case_id")
            testcase_list = []
            for testcase in testcase_names:
                tc_id = testcase['test_case_id']
                testcase_list.append({'name': tc_id, 'results': [], 'is_different': False})
                for testset in testsets:
                    result = testset.lavajobtestresult_set.filter(test_case_id=tc_id)
                    if result:
                        testcase_list[-1]['results'].append(result[0].status.name) # there should be only one?
                    else:
                        testcase_list[-1]['results'].append("-")
                if len(set(testcase_list[-1]['results'])) > 1:
                    testcase_list[-1]['is_different'] = True

            template = loader.get_template('testrunner/compare_results.html')
            context = RequestContext(request, {
                'testsets': testsets,
                'testcases': testcase_list,
            })
            return HttpResponse(template.render(context))
    return HttpResponseRedirect(request.META['HTTP_REFERER'])
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- encoding: utf-8 -*-
from indic_transliteration import sanscript
from sanskrit_parser.parser.sandhi_analyzer import LexicalSandhiAnalyzer
from sanskrit_parser.base.sanskrit_base import SanskritObject, outputctx
import pandas as pd
import multiprocessing
import os.path
import inspect

le = LexicalSandhiAnalyzer()

def get_kosh_entries(test_count=0):
    kosh_entries = []
    base_dir = os.path.dirname(os.path.abspath(
        inspect.getfile(inspect.currentframe())))
    data_dir = os.path.join(base_dir, 'SandhiKosh')
    aa_kosh = pd.read_excel(os.path.join(data_dir, "Astaadhyaayii Corpus.xls"))[['S. No.', 'Word', 'Split']]
    aa_kosh['File'] = "Astaadhyaayii Corpus.xls"
    bg_kosh = pd.read_excel(os.path.join(data_dir, "Bhagvad_Gita Corpus.xls"))[['S. No.', 'Word', 'Split']]
    bg_kosh['File'] = "Bhagvad_Gita Corpus.xls"
    uoh_kosh = pd.read_excel(os.path.join(data_dir, "UoH_Corpus.xls"))[['S. No.', 'Word', 'Split']]
    uoh_kosh['File'] = "UoH_Corpus.xls"
    lit_kosh_dict = pd.read_excel(os.path.join(data_dir, "Rule-based Corpus and Literature Corpus.xls"), sheet_name=None)
    for k in ['Internal', 'External', 'Literature']:
        t_kosh = lit_kosh_dict[k].loc[:, ['S. No.', 'Word', 'Split']]
        t_kosh['File'] = f"Rule-based Corpus and Literature Corpus.xls:{k}"
        kosh_entries.extend(t_kosh.to_dict(orient='records'))
    kosh_entries.extend(bg_kosh.to_dict(orient='records'))
    kosh_entries.extend(uoh_kosh.to_dict(orient='records'))
    kosh_entries.extend(aa_kosh.to_dict(orient='records'))
    return kosh_entries[:test_count] if test_count > 0 else kosh_entries

def sort_file_splits(kosh_entry):
    global le
    clean_input = False
    f = kosh_entry['Word']
    s = kosh_entry['Split']
    clean_input = True
    with outputctx(False):
        i = SanskritObject(f, encoding=sanscript.DEVANAGARI, strict_io=True, replace_ending_visarga=None)
        if not(isinstance(s, str)):
            # Bad input
            return "Bad_Input"
        if clean_input:
            sl = [SanskritObject(x, encoding=sanscript.DEVANAGARI, strict_io=True,
                                 replace_ending_visarga=None).canonical()
                  for x in s.strip().replace(" ", "+").split('+')]
        else:
            sl = [SanskritObject(x, encoding=sanscript.DEVANAGARI, strict_io=True, replace_ending_visarga=None).canonical() for x in s.split('+')]
        graph = le.getSandhiSplits(i)
        if graph is not None:
            splits = graph.find_all_paths(max_paths=300, sort=False)
            if sl in [list(map(str, ss)) for ss in splits]:
                # Pass
                print("P", end='', flush=True)
                return "Pass"
            else:
                print("F", end='', flush=True)
                return "Fail"
        else:
            print("S", end='', flush=True)
            return "Split_Fail"

entries = get_kosh_entries()
print(f"Collected {len(entries)} tests")
with multiprocessing.Pool(4) as p:
    result = p.map(sort_file_splits, entries)
# result = map(sort_file_splits, entries)
print("")  # Newline
odf = pd.DataFrame.from_records(entries)
odf['Status'] = result
odf.to_excel("Result.xls")
print("Wrote to Result.xls")
passcount = result.count("Pass")
failcount = result.count("Fail")
splitfailcount = result.count("Split_Fail")
badcount = result.count("Bad_Input")
print(f"{passcount} Passed, {failcount} Failed, {splitfailcount} No_Split, {badcount} Bad tests")
<commit_msg>Disabling multiprocessing for SandhiKosh/manual_test in Windows<commit_after>#!/usr/bin/env python
# -*- encoding: utf-8 -*-
from indic_transliteration import sanscript
from sanskrit_parser.parser.sandhi_analyzer import LexicalSandhiAnalyzer
from sanskrit_parser.base.sanskrit_base import SanskritObject, outputctx
import pandas as pd
import multiprocessing
import os.path
import inspect
import sys

le = LexicalSandhiAnalyzer()

def get_kosh_entries(test_count=0):
    kosh_entries = []
    base_dir = os.path.dirname(os.path.abspath(
        inspect.getfile(inspect.currentframe())))
    data_dir = os.path.join(base_dir, 'SandhiKosh')
    aa_kosh = pd.read_excel(os.path.join(data_dir, "Astaadhyaayii Corpus.xls"))[['S. No.', 'Word', 'Split']]
    aa_kosh['File'] = "Astaadhyaayii Corpus.xls"
    bg_kosh = pd.read_excel(os.path.join(data_dir, "Bhagvad_Gita Corpus.xls"))[['S. No.', 'Word', 'Split']]
    bg_kosh['File'] = "Bhagvad_Gita Corpus.xls"
    uoh_kosh = pd.read_excel(os.path.join(data_dir, "UoH_Corpus.xls"))[['S. No.', 'Word', 'Split']]
    uoh_kosh['File'] = "UoH_Corpus.xls"
    lit_kosh_dict = pd.read_excel(os.path.join(data_dir, "Rule-based Corpus and Literature Corpus.xls"), sheet_name=None)
    for k in ['Internal', 'External', 'Literature']:
        t_kosh = lit_kosh_dict[k].loc[:, ['S. No.', 'Word', 'Split']]
        t_kosh['File'] = f"Rule-based Corpus and Literature Corpus.xls:{k}"
        kosh_entries.extend(t_kosh.to_dict(orient='records'))
    kosh_entries.extend(bg_kosh.to_dict(orient='records'))
    kosh_entries.extend(uoh_kosh.to_dict(orient='records'))
    kosh_entries.extend(aa_kosh.to_dict(orient='records'))
    return kosh_entries[:test_count] if test_count > 0 else kosh_entries

def sort_file_splits(kosh_entry):
    global le
    clean_input = False
    f = kosh_entry['Word']
    s = kosh_entry['Split']
    clean_input = True
    with outputctx(False):
        i = SanskritObject(f, encoding=sanscript.DEVANAGARI, strict_io=True, replace_ending_visarga=None)
        if not(isinstance(s, str)):
            # Bad input
            return "Bad_Input"
        if clean_input:
            sl = [SanskritObject(x, encoding=sanscript.DEVANAGARI, strict_io=True,
                                 replace_ending_visarga=None).canonical()
                  for x in s.strip().replace(" ", "+").split('+')]
        else:
            sl = [SanskritObject(x, encoding=sanscript.DEVANAGARI, strict_io=True, replace_ending_visarga=None).canonical() for x in s.split('+')]
        graph = le.getSandhiSplits(i)
        if graph is not None:
            splits = graph.find_all_paths(max_paths=300, sort=False)
            if sl in [list(map(str, ss)) for ss in splits]:
                # Pass
                print("P", end='', flush=True)
                return "Pass"
            else:
                print("F", end='', flush=True)
                return "Fail"
        else:
            print("S", end='', flush=True)
            return "Split_Fail"

if __name__ == '__main__':
    import logging
    rootlogger = logging.getLogger()
    for h in rootlogger.handlers:
        rootlogger.removeHandler(h)
    rootlogger.addHandler(logging.NullHandler())

    entries = get_kosh_entries()
    print(f"Collected {len(entries)} tests")
    if sys.platform == 'linux':
        with multiprocessing.Pool(4) as p:
            result = p.map(sort_file_splits, entries)
    else:
        result = list(map(sort_file_splits, entries))
    print("")  # Newline
    odf = pd.DataFrame.from_records(entries)
    odf['Status'] = result
    odf.to_excel("Result.xls")
    print("Wrote to Result.xls")
    passcount = result.count("Pass")
    failcount = result.count("Fail")
    splitfailcount = result.count("Split_Fail")
    badcount = result.count("Bad_Input")
    print(f"{passcount} Passed, {failcount} Failed, {splitfailcount} No_Split, {badcount} Bad tests")
<|endoftext|>


<commit_before>from __future__ import print_function
from __future__ import unicode_literals
from py._path.local import LocalPath as Path
import pytest

from testing import (
    TOP,
    requirements,
    run,
    strip_coverage_warnings,
    uncolor,
    venv_update,
    venv_update_symlink_pwd,
)

from sys import version_info
PY33 = (version_info >= (3, 3))

def test_trivial(tmpdir):
    tmpdir.chdir()
    requirements('')
    venv_update()

def enable_coverage(tmpdir):
    venv = tmpdir.join('virtualenv_run')
    if not venv.isdir():
        run('virtualenv', venv.strpath)
    run(
        venv.join('bin/python').strpath,
        '-m', 'pip.__main__',
        'install',
        '-r', TOP.join('requirements.d/coverage.txt').strpath,
    )

def install_twice(tmpdir, between):
    """install twice, and the second one should be faster, due to whl caching"""
    tmpdir.chdir()

    # Arbitrary packages that takes a bit of time to install:
    # Should I make a fixture c-extension to remove these dependencies?
    # NOTE: Avoid projects that use 2to3 (urwid). It makes the runtime vary too widely.
    requirements('''\
simplejson==3.6.5
pyyaml==3.11
pylint==1.4.0
pytest==2.6.4
unittest2==0.8.0
six<=1.8.0
chroniker
''')

    from time import time
    enable_coverage(tmpdir)
    assert pip_freeze() == '\n'.join((
        'cov-core==1.15.0',
        'coverage==4.0a1',
        ''
    ))

    start = time()
    venv_update()
    time1 = time() - start
    assert pip_freeze() == '\n'.join((
        'PyYAML==3.11',
        'astroid==1.3.2',
        'chroniker==0.0.0',
        'logilab-common==0.63.2',
        'py==1.4.26',
        'pylint==1.4.0',
        'pytest==2.6.4',
        'simplejson==3.6.5',
        'six==1.8.0',
        'unittest2==0.8.0',
        'wheel==0.24.0',
        ''
    ))

    between()

    enable_coverage(tmpdir)
    # there may be more or less packages depending on what exactly happened between
    assert 'cov-core==1.15.0\ncoverage==4.0a1\n' in pip_freeze()

    start = time()
    # second install should also need no network access
    # these are arbitrary invalid addresses
    venv_update(
        http_proxy='foo-proxy',
        https_proxy='bar-proxy',
        ftp_proxy='quux-proxy',
    )
    time2 = time() - start
    assert pip_freeze() == '\n'.join((
        'PyYAML==3.11',
        'astroid==1.3.2',
        'chroniker==0.0.0',
        'logilab-common==0.63.2',
        'py==1.4.26',
        'pylint==1.4.0',
        'pytest==2.6.4',
        'simplejson==3.6.5',
        'six==1.8.0',
        'unittest2==0.8.0',
        'wheel==0.24.0',
        ''
    ))

    # second install should be at least twice as fast
    ratio = time1 / time2
    print('%.2fx speedup' % ratio)
    return ratio

@pytest.mark.flaky(reruns=2)
def test_noop_install_faster(tmpdir):
    def do_nothing():
        pass

    # constrain both ends, to show that we know what's going on
    # performance log: (clear when numbers become invalidated)
    #   2014-12-22 travis py26: 9.4-12
    #   2014-12-22 travis py27: 10-13
    #   2014-12-22 travis py34: 6-14
    #   2014-12-22 travis pypy: 5.5-7.5
    #   2015-01-07 linux py27: 17-34
    assert 10 < install_twice(tmpdir, between=do_nothing) < 40

@pytest.mark.flaky(reruns=2)
def test_cached_clean_install_faster(tmpdir):
    def clean():
        venv = tmpdir.join('virtualenv_run')
        assert venv.isdir()
        venv.remove()
        assert not venv.exists()

    # I get ~4x locally, but only 2.5x on travis
    # constrain both ends, to show that we know what's going on
    # performance log: (clear when numbers become invalidated)
    #   2014-12-22 travis py26: 4-6
    #   2014-12-22 travis py27: 3.2-5.5
    #   2014-12-22 travis py34: 3.7-6
    #   2014-12-22 travis pypy: 3.5-4
    #   2014-12-24 travis pypy: 2.9-3.5
    #   2014-12-24 osx pypy: 3.9
    assert 2.5 < install_twice(tmpdir, between=clean) < 7

def test_arguments_version(tmpdir):
    """Show that we can pass arguments through to virtualenv"""
    tmpdir.chdir()

    from subprocess import CalledProcessError
    with pytest.raises(CalledProcessError) as excinfo:
        # should show virtualenv version, then crash
        venv_update('--version')

    assert excinfo.value.returncode == 1
    out, err = excinfo.value.result
    lasterr = err.rsplit('\n', 2)[-2]
    assert lasterr.startswith('virtualenv executable not found: /'), err
    assert lasterr.endswith('/virtualenv_run/bin/python'), err

    lines = [uncolor(line) for line in out.split('\n')]
    assert len(lines) == 3, lines
    assert lines[0].endswith(' -m virtualenv virtualenv_run --version'), repr(lines[0])

def test_arguments_system_packages(tmpdir):
    """Show that we can pass arguments through to virtualenv"""
    tmpdir.chdir()
    requirements('')

    venv_update('--system-site-packages', 'virtualenv_run', 'requirements.txt')

    out, err = run('virtualenv_run/bin/python', '-c', '''\
import sys
for p in sys.path:
    if p.startswith(sys.real_prefix) and p.endswith("-packages"):
        print(p)
        break
''')
    assert err == ''
    out = out.rstrip('\n')
    assert out and Path(out).isdir()

def pip_freeze():
    out, err = run('./virtualenv_run/bin/pip', 'freeze', '--local')

    # Most python distributions which have argparse in the stdlib fail to
    # expose it to setuptools as an installed package (it seems all but ubuntu
    # do this). This results in argparse sometimes being installed locally,
    # sometimes not, even for a specific version of python.
    # We normalize by never looking at argparse =/
    out = out.replace('argparse==1.2.1\n', '', 1)

    assert err == ''
    return out

def test_update_while_active(tmpdir):
    tmpdir.chdir()
    requirements('virtualenv<2')

    venv_update()
    assert 'mccabe' not in pip_freeze()

    # An arbitrary small package: mccabe
    requirements('virtualenv<2\nmccabe')

    venv_update_symlink_pwd()
    out, err = run('sh', '-c', '. virtualenv_run/bin/activate && python venv_update.py')

    assert err == ''
    assert out.startswith('Keeping virtualenv from previous run.\n')
    assert 'mccabe' in pip_freeze()

def test_update_invalidated_while_active(tmpdir):
    tmpdir.chdir()
    requirements('virtualenv<2')

    venv_update()
    assert 'mccabe' not in pip_freeze()

    # An arbitrary small package: mccabe
    requirements('virtualenv<2\nmccabe')

    venv_update_symlink_pwd()
    out, err = run('sh', '-c', '. virtualenv_run/bin/activate && python venv_update.py --system-site-packages')

    assert err == ''
    assert out.startswith('Removing invalidated virtualenv.\n')
    assert 'mccabe' in pip_freeze()

def test_eggless_url(tmpdir):
    tmpdir.chdir()
    requirements('')

    venv_update()
    assert 'venv-update' not in pip_freeze()

    # An arbitrary git-url requirement.
    requirements('git+git://github.com/Yelp/venv-update.git')

    venv_update()
    assert 'venv-update' in pip_freeze()

def test_scripts_left_behind(tmpdir):
    tmpdir.chdir()
    requirements('')

    venv_update()

    # an arbitrary small package with a script: pep8
    script_path = Path('virtualenv_run/bin/pep8')
    assert not script_path.exists()

    run('virtualenv_run/bin/pip', 'install', 'pep8')
    assert script_path.exists()

    venv_update()
    assert not script_path.exists()

def assert_timestamps(*reqs):
    firstreq = Path(reqs[0])
    lastreq = Path(reqs[-1])

    venv_update('--python=python', 'virtualenv_run', *reqs)

    assert firstreq.mtime() < Path('virtualenv_run').mtime()

    # garbage, to cause a failure
    lastreq.write('-w wat')

    from subprocess import CalledProcessError
    with pytest.raises(CalledProcessError) as excinfo:
        venv_update('virtualenv_run', *reqs)

    assert excinfo.value.returncode == 1
    assert firstreq.mtime() > Path('virtualenv_run').mtime()

    # blank requirements should succeed
    lastreq.write('')

    venv_update('virtualenv_run', *reqs)
    assert Path(reqs[0]).mtime() < Path('virtualenv_run').mtime()

def test_timestamps_single(tmpdir):
    tmpdir.chdir()
    requirements('')
    assert_timestamps('requirements.txt')

def test_timestamps_multiple(tmpdir):
    tmpdir.chdir()
    requirements('')
    Path('requirements2.txt').write('')
    assert_timestamps('requirements.txt', 'requirements2.txt')

def pipe_output(read, write):
    from os import environ
    environ = environ.copy()
    environ['HOME'] = str(Path('.').realpath())

    from subprocess import Popen
    vupdate = Popen(
        ('venv-update', '--version'),
        env=environ,
        stdout=write,
        close_fds=True,
    )

    from os import close
    from testing.capture_subprocess import read_all
    close(write)
    result = read_all(read)
    vupdate.wait()

    result = result.decode('US-ASCII')
    uncolored = uncolor(result)
    assert uncolored.startswith('> ')
    # FIXME: Sometimes this is 'python -m', sometimes 'python2.7 -m'. Weird.
    assert uncolored.endswith('''\
 -m virtualenv virtualenv_run --version
1.11.6
''')

    return result, uncolored

def test_colored_tty(tmpdir):
    tmpdir.chdir()

    from os import openpty
    read, write = openpty()

    from testing.capture_subprocess import pty_normalize_newlines
    pty_normalize_newlines(read)

    out, uncolored = pipe_output(read, write)

    assert out != uncolored

def test_uncolored_pipe(tmpdir):
    tmpdir.chdir()

    from os import pipe
    read, write = pipe()

    out, uncolored = pipe_output(read, write)

    assert out == uncolored

def test_args_backward(tmpdir):
    tmpdir.chdir()
    requirements('')

    from subprocess import CalledProcessError
    with pytest.raises(CalledProcessError) as excinfo:
        venv_update('requirements.txt', 'myvenv')

    # py26 doesn't have a consistent exit code:
    #   http://bugs.python.org/issue15033
    assert excinfo.value.returncode != 0
    _, err = excinfo.value.result
    lasterr = strip_coverage_warnings(err).rsplit('\n', 2)[-2]
    errname = 'NotADirectoryError' if PY33 else 'OSError'
    assert lasterr.startswith(errname + ': [Errno 20] Not a directory'), err

    assert Path('requirements.txt').isfile()
    assert Path('requirements.txt').read() == ''
    assert not Path('myvenv').exists()

def test_wrong_wheel(tmpdir):
    tmpdir.chdir()

    requirements('')
    venv_update('venv1', 'requirements.txt', '-ppython2.7')
    # A different python
    # Before fixing, this would install argparse using the `py2-none-any`
    # wheel, even on py3
    ret2out, _ = venv_update('venv2', 'requirements.txt', '-ppython3.3')

    assert 'py2-none-any' not in ret2out
<commit_msg>adjust invalid addresses, again<commit_after>from __future__ import print_function
from __future__ import unicode_literals
from py._path.local import LocalPath as Path
import pytest

from testing import (
    TOP,
    requirements,
    run,
    strip_coverage_warnings,
    uncolor,
    venv_update,
    venv_update_symlink_pwd,
)

from sys import version_info
PY33 = (version_info >= (3, 3))

def test_trivial(tmpdir):
    tmpdir.chdir()
    requirements('')
    venv_update()

def enable_coverage(tmpdir):
    venv = tmpdir.join('virtualenv_run')
    if not venv.isdir():
        run('virtualenv', venv.strpath)
    run(
        venv.join('bin/python').strpath,
        '-m', 'pip.__main__',
        'install',
        '-r', TOP.join('requirements.d/coverage.txt').strpath,
    )

def install_twice(tmpdir, between):
    """install twice, and the second one should be faster, due to whl caching"""
    tmpdir.chdir()

    # Arbitrary packages that takes a bit of time to install:
    # Should I make a fixture c-extension to remove these dependencies?
    # NOTE: Avoid projects that use 2to3 (urwid). It makes the runtime vary too widely.
    requirements('''\
simplejson==3.6.5
pyyaml==3.11
pylint==1.4.0
pytest==2.6.4
unittest2==0.8.0
six<=1.8.0
chroniker
''')

    from time import time
    enable_coverage(tmpdir)
    assert pip_freeze() == '\n'.join((
        'cov-core==1.15.0',
        'coverage==4.0a1',
        ''
    ))

    start = time()
    venv_update()
    time1 = time() - start
    assert pip_freeze() == '\n'.join((
        'PyYAML==3.11',
        'astroid==1.3.2',
        'chroniker==0.0.0',
        'logilab-common==0.63.2',
        'py==1.4.26',
        'pylint==1.4.0',
        'pytest==2.6.4',
        'simplejson==3.6.5',
        'six==1.8.0',
        'unittest2==0.8.0',
        'wheel==0.24.0',
        ''
    ))

    between()

    enable_coverage(tmpdir)
    # there may be more or less packages depending on what exactly happened between
    assert 'cov-core==1.15.0\ncoverage==4.0a1\n' in pip_freeze()

    start = time()
    # second install should also need no network access
    # these are localhost addresses with arbitrary invalid ports
    venv_update(
        http_proxy='http://127.0.0.1:111111',
        https_proxy='https://127.0.0.1:222222',
        ftp_proxy='ftp://127.0.0.1:333333',
    )
    time2 = time() - start
    assert pip_freeze() == '\n'.join((
        'PyYAML==3.11',
        'astroid==1.3.2',
        'chroniker==0.0.0',
        'logilab-common==0.63.2',
        'py==1.4.26',
        'pylint==1.4.0',
        'pytest==2.6.4',
        'simplejson==3.6.5',
        'six==1.8.0',
        'unittest2==0.8.0',
        'wheel==0.24.0',
        ''
    ))

    # second install should be at least twice as fast
    ratio = time1 / time2
    print('%.2fx speedup' % ratio)
    return ratio

@pytest.mark.flaky(reruns=2)
def test_noop_install_faster(tmpdir):
    def do_nothing():
        pass

    # constrain both ends, to show that we know what's going on
    # performance log: (clear when numbers become invalidated)
    #   2014-12-22 travis py26: 9.4-12
    #   2014-12-22 travis py27: 10-13
    #   2014-12-22 travis py34: 6-14
    #   2014-12-22 travis pypy: 5.5-7.5
    #   2015-01-07 linux py27: 17-34
    assert 10 < install_twice(tmpdir, between=do_nothing) < 40

@pytest.mark.flaky(reruns=2)
def test_cached_clean_install_faster(tmpdir):
    def clean():
        venv = tmpdir.join('virtualenv_run')
        assert venv.isdir()
        venv.remove()
        assert not venv.exists()

    # I get ~4x locally, but only 2.5x on travis
    # constrain both ends, to show that we know what's going on
    # performance log: (clear when numbers become invalidated)
    #   2014-12-22 travis py26: 4-6
    #   2014-12-22 travis py27: 3.2-5.5
    #   2014-12-22 travis py34: 3.7-6
    #   2014-12-22 travis pypy: 3.5-4
    #   2014-12-24 travis pypy: 2.9-3.5
    #   2014-12-24 osx pypy: 3.9
    assert 2.5 < install_twice(tmpdir, between=clean) < 7

def test_arguments_version(tmpdir):
    """Show that we can pass arguments through to virtualenv"""
    tmpdir.chdir()

    from subprocess import CalledProcessError
    with pytest.raises(CalledProcessError) as excinfo:
        # should show virtualenv version, then crash
        venv_update('--version')

    assert excinfo.value.returncode == 1
    out, err = excinfo.value.result
    lasterr = err.rsplit('\n', 2)[-2]
    assert lasterr.startswith('virtualenv executable not found: /'), err
    assert lasterr.endswith('/virtualenv_run/bin/python'), err

    lines = [uncolor(line) for line in out.split('\n')]
    assert len(lines) == 3, lines
    assert lines[0].endswith(' -m virtualenv virtualenv_run --version'), repr(lines[0])

def test_arguments_system_packages(tmpdir):
    """Show that we can pass arguments through to virtualenv"""
    tmpdir.chdir()
    requirements('')

    venv_update('--system-site-packages', 'virtualenv_run', 'requirements.txt')

    out, err = run('virtualenv_run/bin/python', '-c', '''\
import sys
for p in sys.path:
    if p.startswith(sys.real_prefix) and p.endswith("-packages"):
        print(p)
        break
''')
    assert err == ''
    out = out.rstrip('\n')
    assert out and Path(out).isdir()

def pip_freeze():
    out, err = run('./virtualenv_run/bin/pip', 'freeze', '--local')

    # Most python distributions which have argparse in the stdlib fail to
    # expose it to setuptools as an installed package (it seems all but ubuntu
    # do this). This results in argparse sometimes being installed locally,
    # sometimes not, even for a specific version of python.
    # We normalize by never looking at argparse =/
    out = out.replace('argparse==1.2.1\n', '', 1)

    assert err == ''
    return out

def test_update_while_active(tmpdir):
    tmpdir.chdir()
    requirements('virtualenv<2')

    venv_update()
    assert 'mccabe' not in pip_freeze()

    # An arbitrary small package: mccabe
    requirements('virtualenv<2\nmccabe')

    venv_update_symlink_pwd()
    out, err = run('sh', '-c', '. virtualenv_run/bin/activate && python venv_update.py')

    assert err == ''
    assert out.startswith('Keeping virtualenv from previous run.\n')
    assert 'mccabe' in pip_freeze()

def test_update_invalidated_while_active(tmpdir):
    tmpdir.chdir()
    requirements('virtualenv<2')

    venv_update()
    assert 'mccabe' not in pip_freeze()

    # An arbitrary small package: mccabe
    requirements('virtualenv<2\nmccabe')

    venv_update_symlink_pwd()
    out, err = run('sh', '-c', '. virtualenv_run/bin/activate && python venv_update.py --system-site-packages')

    assert err == ''
    assert out.startswith('Removing invalidated virtualenv.\n')
    assert 'mccabe' in pip_freeze()

def test_eggless_url(tmpdir):
    tmpdir.chdir()
    requirements('')

    venv_update()
    assert 'venv-update' not in pip_freeze()

    # An arbitrary git-url requirement.
    requirements('git+git://github.com/Yelp/venv-update.git')

    venv_update()
    assert 'venv-update' in pip_freeze()

def test_scripts_left_behind(tmpdir):
    tmpdir.chdir()
    requirements('')

    venv_update()

    # an arbitrary small package with a script: pep8
    script_path = Path('virtualenv_run/bin/pep8')
    assert not script_path.exists()

    run('virtualenv_run/bin/pip', 'install', 'pep8')
    assert script_path.exists()

    venv_update()
    assert not script_path.exists()

def assert_timestamps(*reqs):
    firstreq = Path(reqs[0])
    lastreq = Path(reqs[-1])

    venv_update('--python=python', 'virtualenv_run', *reqs)

    assert firstreq.mtime() < Path('virtualenv_run').mtime()

    # garbage, to cause a failure
    lastreq.write('-w wat')

    from subprocess import CalledProcessError
    with pytest.raises(CalledProcessError) as excinfo:
        venv_update('virtualenv_run', *reqs)

    assert excinfo.value.returncode == 1
    assert firstreq.mtime() > Path('virtualenv_run').mtime()

    # blank requirements should succeed
    lastreq.write('')

    venv_update('virtualenv_run', *reqs)
    assert Path(reqs[0]).mtime() < Path('virtualenv_run').mtime()

def test_timestamps_single(tmpdir):
    tmpdir.chdir()
    requirements('')
    assert_timestamps('requirements.txt')

def test_timestamps_multiple(tmpdir):
    tmpdir.chdir()
    requirements('')
    Path('requirements2.txt').write('')
    assert_timestamps('requirements.txt', 'requirements2.txt')

def pipe_output(read, write):
    from os import environ
    environ = environ.copy()
    environ['HOME'] = str(Path('.').realpath())

    from subprocess import Popen
    vupdate = Popen(
        ('venv-update', '--version'),
        env=environ,
        stdout=write,
        close_fds=True,
    )

    from os import close
    from testing.capture_subprocess import read_all
    close(write)
    result = read_all(read)
    vupdate.wait()

    result = result.decode('US-ASCII')
    uncolored = uncolor(result)
    assert uncolored.startswith('> ')
    # FIXME: Sometimes this is 'python -m', sometimes 'python2.7 -m'. Weird.
    assert uncolored.endswith('''\
 -m virtualenv virtualenv_run --version
1.11.6
''')

    return result, uncolored

def test_colored_tty(tmpdir):
    tmpdir.chdir()

    from os import openpty
    read, write = openpty()

    from testing.capture_subprocess import pty_normalize_newlines
    pty_normalize_newlines(read)

    out, uncolored = pipe_output(read, write)

    assert out != uncolored

def test_uncolored_pipe(tmpdir):
    tmpdir.chdir()

    from os import pipe
    read, write = pipe()

    out, uncolored = pipe_output(read, write)

    assert out == uncolored

def test_args_backward(tmpdir):
    tmpdir.chdir()
    requirements('')

    from subprocess import CalledProcessError
    with pytest.raises(CalledProcessError) as excinfo:
        venv_update('requirements.txt', 'myvenv')

    # py26 doesn't have a consistent exit code:
    #   http://bugs.python.org/issue15033
    assert excinfo.value.returncode != 0
    _, err = excinfo.value.result
    lasterr = strip_coverage_warnings(err).rsplit('\n', 2)[-2]
    errname = 'NotADirectoryError' if PY33 else 'OSError'
    assert lasterr.startswith(errname + ': [Errno 20] Not a directory'), err

    assert Path('requirements.txt').isfile()
    assert Path('requirements.txt').read() == ''
    assert not Path('myvenv').exists()

def test_wrong_wheel(tmpdir):
    tmpdir.chdir()

    requirements('')
    venv_update('venv1', 'requirements.txt', '-ppython2.7')
    # A different python
    # Before fixing, this would install argparse using the `py2-none-any`
    # wheel, even on py3
    ret2out, _ = venv_update('venv2', 'requirements.txt', '-ppython3.3')

    assert 'py2-none-any' not in ret2out
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-

# Copyright 2015 2016 Juca Crispim <juca@poraodojuca.net>

# This file is part of toxicbuild.

# toxicbuild is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# toxicbuild is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with toxicbuild. If not, see <http://www.gnu.org/licenses/>.

import asyncio
from toxicbuild.core import BaseToxicClient
from toxicbuild.master.scheduler import scheduler
from toxicbuild.master import settings
from tests import async_test
from tests.functional import BaseFunctionalTest, REPO_DIR

scheduler.stop()

class DummyUIClient(BaseToxicClient):

    @asyncio.coroutine
    def request2server(self, action, body):

        data = {'action': action, 'body': body,
                'token': '123'}
        yield from self.write(data)
        response = yield from self.get_response()
        return response['body'][action]

    @asyncio.coroutine
    def create_slave(self):
        action = 'slave-add'
        body = {'slave_name': 'test-slave',
                'slave_host': 'localhost',
                'slave_port': settings.SLAVE_PORT,
                'slave_token': '123'}

        resp = yield from self.request2server(action, body)
        return resp

    @asyncio.coroutine
    def create_repo(self):
        action = 'repo-add'
        body = {'repo_name': 'test-repo', 'repo_url': REPO_DIR,
                'vcs_type': 'git', 'update_seconds': 1,
                'slaves': ['test-slave']}

        resp = yield from self.request2server(action, body)

        return resp

    @asyncio.coroutine
    def start_build(self):

        action = 'repo-start-build'
        body = {'repo_name': 'test-repo',
                # 'builder_name': 'test-builder',
                'branch': 'master'}
        resp = yield from self.request2server(action, body)

        return resp

    def get_stream(self):

        action = 'stream'
        self.write({'action': action, 'body': {}})

        resp = yield from self.get_response()
        while resp:
            yield resp
            resp = yield from self.get_response()

@asyncio.coroutine
def get_dummy_client():
    dc = DummyUIClient(settings.HOLE_ADDR, settings.HOLE_PORT)
    yield from dc.connect()
    return dc

class ToxicMasterTest(BaseFunctionalTest):

    @classmethod
    def tearDownClass(cls):
        try:
            cls._delete_test_data()
        except OSError:
            pass

        super().tearDownClass()

    @async_test
    def test_01_create_slave(self):

        with (yield from get_dummy_client()) as client:
            response = yield from client.create_slave()
        self.assertTrue(response)

    @async_test
    def test_02_list_slaves(self):
        with (yield from get_dummy_client()) as client:
            slaves = yield from client.request2server('slave-list', {})

        self.assertEqual(len(slaves), 1)

    @async_test
    def test_03_create_repo(self):
        with (yield from get_dummy_client()) as client:
            response = yield from client.create_repo()

        self.assertTrue(response)

    @async_test
    def test_04_list_repos(self):
        with (yield from get_dummy_client()) as client:
            repos = yield from client.request2server('repo-list', {})

        self.assertEqual(len(repos), 1)
        self.assertEqual(len(repos[0]['slaves']), 1)

    @async_test
    def test_05_repo_add_slave(self):
        with (yield from get_dummy_client()) as client:
            yield from client.request2server('slave-add',
                                             {'slave_name': 'test-slave2',
                                              'slave_host': 'localhost',
                                              'slave_port': 1234,
                                              'slave_token': '123'})
        with (yield from get_dummy_client()) as client:
            resp = yield from client.request2server(
                'repo-add-slave',
                {'repo_name': 'test-repo', 'slave_name': 'test-slave2'})
        self.assertTrue(resp)

    @async_test
    def test_06_repo_remove_slave(self):
        with (yield from get_dummy_client()) as client:
            resp = yield from client.request2server(
                'repo-remove-slave',
                {'repo_name': 'test-repo', 'slave_name': 'test-slave'})
        self.assertTrue(resp)

    @async_test
    def test_07_slave_get(self):
        with (yield from get_dummy_client()) as client:
            resp = yield from client.request2server('slave-get',
                                                    {'slave_name':
                                                     'test-slave2'})
        self.assertTrue(resp)

    @async_test
    def test_08_repo_get(self):
        with (yield from get_dummy_client()) as client:
            resp = yield from client.request2server('repo-get',
                                                    {'repo_name':
                                                     'test-repo'})
        self.assertTrue(resp)

    @async_test
    def test_09_slave_remove(self):
        with (yield from get_dummy_client()) as client:
            resp = yield from client.request2server('slave-remove',
                                                    {'slave_name':
                                                     'test-slave2'})
        self.assertTrue(resp)

    @async_test
    def test_10_repo_start_build(self):
        # we need to wait so we have time to clone and create revs
        yield from asyncio.sleep(2)
        with (yield from get_dummy_client()) as client:
            yield from client.start_build()

        with (yield from get_dummy_client()) as client:
            yield from client.write({'action': 'stream', 'token': '123',
                                     'body': {}})

            while True:
                response = yield from client.get_response()
                body = response['body'] if response else {}
                if 'steps' not in body and body.get('finished'):
                    break

        self.assertEqual(response['body']['status'], 'success',
                         response['body'])

    @classmethod
    def _delete_test_data(cls):
        loop = asyncio.get_event_loop()
        with loop.run_until_complete(get_dummy_client()) as client:
            loop.run_until_complete(
                client.request2server('slave-remove',
                                      {'slave_name': 'test-slave'}))

            loop.run_until_complete(client.connect())

            loop.run_until_complete(
                client.request2server('repo-remove',
                                      {'repo_name': 'test-repo'}))
<commit_msg>correcting test<commit_after># -*- coding: utf-8 -*-

# Copyright 2015 2016 Juca Crispim <juca@poraodojuca.net>

# This file is part of toxicbuild.

# toxicbuild is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# toxicbuild is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with toxicbuild. If not, see <http://www.gnu.org/licenses/>.

import asyncio
from toxicbuild.core import BaseToxicClient
from toxicbuild.master.scheduler import scheduler
from toxicbuild.master import settings
from tests import async_test
from tests.functional import BaseFunctionalTest, REPO_DIR

scheduler.stop()

class DummyUIClient(BaseToxicClient):

    @asyncio.coroutine
    def request2server(self, action, body):

        data = {'action': action, 'body': body,
                'token': '123'}
        yield from self.write(data)
        response = yield from self.get_response()
        return response['body'][action]

    @asyncio.coroutine
    def create_slave(self):
        action = 'slave-add'
        body = {'slave_name': 'test-slave',
                'slave_host': 'localhost',
                'slave_port': settings.SLAVE_PORT,
                'slave_token': '123'}

        resp = yield from self.request2server(action, body)
        return resp

    @asyncio.coroutine
    def create_repo(self):
        action = 'repo-add'
        body = {'repo_name': 'test-repo', 'repo_url': REPO_DIR,
                'vcs_type': 'git', 'update_seconds': 1,
                'slaves': ['test-slave']}

        resp = yield from self.request2server(action, body)

        return resp

    @asyncio.coroutine
    def start_build(self):

        action = 'repo-start-build'
        body = {'repo_name': 'test-repo',
                # 'builder_name': 'test-builder',
                'branch': 'master'}
        resp = yield from self.request2server(action, body)

        return resp

    def get_stream(self):

        action = 'stream'
        self.write({'action': action, 'body': {}})

        resp = yield from self.get_response()
        while resp:
            yield resp
            resp = yield from self.get_response()

@asyncio.coroutine
def get_dummy_client():
    dc = DummyUIClient(settings.HOLE_ADDR, settings.HOLE_PORT)
    yield from dc.connect()
    return dc

class ToxicMasterTest(BaseFunctionalTest):

    @classmethod
    def tearDownClass(cls):
        try:
            cls._delete_test_data()
        except OSError:
            pass

        super().tearDownClass()

    @async_test
    def test_01_create_slave(self):

        with (yield from get_dummy_client()) as client:
            response = yield from client.create_slave()
        self.assertTrue(response)

    @async_test
    def test_02_list_slaves(self):
        with (yield from get_dummy_client()) as client:
            slaves = yield from client.request2server('slave-list', {})

        self.assertEqual(len(slaves), 1)

    @async_test
    def test_03_create_repo(self):
        with (yield from get_dummy_client()) as client:
            response = yield from client.create_repo()

        self.assertTrue(response)

    @async_test
    def test_04_list_repos(self):
        with (yield from get_dummy_client()) as client:
            repos = yield from client.request2server('repo-list', {})

        self.assertEqual(len(repos), 1)
        self.assertEqual(len(repos[0]['slaves']), 1)

    @async_test
    def test_05_repo_add_slave(self):
        with (yield from get_dummy_client()) as client:
            yield from client.request2server('slave-add',
                                             {'slave_name': 'test-slave2',
                                              'slave_host': 'localhost',
                                              'slave_port': 1234,
                                              'slave_token': '123'})
        with (yield from get_dummy_client()) as client:
            resp = yield from client.request2server(
                'repo-add-slave',
                {'repo_name': 'test-repo', 'slave_name': 'test-slave2'})
        self.assertTrue(resp)

    @async_test
    def test_06_repo_remove_slave(self):
        with (yield from get_dummy_client()) as client:
            resp = yield from client.request2server(
                'repo-remove-slave',
                {'repo_name': 'test-repo', 'slave_name': 'test-slave'})
        self.assertTrue(resp)

    @async_test
    def test_07_slave_get(self):
        with (yield from get_dummy_client()) as client:
            resp = yield from client.request2server('slave-get',
                                                    {'slave_name':
                                                     'test-slave2'})
        self.assertTrue(resp)

    @async_test
    def test_08_repo_get(self):
        with (yield from get_dummy_client()) as client:
            resp = yield from client.request2server('repo-get',
                                                    {'repo_name':
                                                     'test-repo'})
        self.assertTrue(resp)

    @async_test
    def test_09_slave_remove(self):
        with (yield from get_dummy_client()) as client:
            resp = yield from client.request2server('slave-remove',
                                                    {'slave_name':
                                                     'test-slave2'})
        self.assertTrue(resp)

    @async_test
    def test_10_repo_start_build(self):
        # we need to wait so we have time to clone and create revs
        yield from asyncio.sleep(2)
        with (yield from get_dummy_client()) as client:
            yield from client.start_build()

        with (yield from get_dummy_client()) as client:
            yield from client.write({'action': 'stream', 'token': '123',
                                     'body': {}})

            while True:
                response = yield from client.get_response()
                body = response['body'] if response else {}
                if body.get('event_type') == 'build_finished':
                    break

        self.assertEqual(response['body']['status'], 'success',
                         response['body'])

    @classmethod
    def _delete_test_data(cls):
        loop = asyncio.get_event_loop()
        with loop.run_until_complete(get_dummy_client()) as client:
            loop.run_until_complete(
                client.request2server('slave-remove',
                                      {'slave_name': 'test-slave'}))

            loop.run_until_complete(client.connect())

            loop.run_until_complete(
                client.request2server('repo-remove',
                                      {'repo_name': 'test-repo'}))
<|endoftext|>


<commit_before># -*- coding: utf-8 -*-
import pytest
from datetime import datetime
from inbox.util.threading import cleanup_subject, thread_messages
from collections import namedtuple

def test_message_cleanup():
    assert cleanup_subject("Re: Birthday") == "Birthday"
    assert cleanup_subject("Re:Birthday") == "Birthday"
    assert cleanup_subject("Re:FWD:   Birthday") == "Birthday"
    assert (cleanup_subject("Re: RE: Alors, comment ça s'est passé ?")
                == "Alors, comment ça s'est passé ?")
    assert cleanup_subject("Re: FWD:FWD: Re:La chaise") == "La chaise"

def test_threading():
    Message = namedtuple('Message', ['message_id_header', 'references',
                                     'received_date'])
    messages = [Message("aaa_header", [], datetime(1999, 1, 23)),
                Message("bbb_header", ["aaa_header"], datetime(2000, 12, 23)),
                Message("ccc_header", ["bbb_header"], datetime(2000, 12, 24))]

    assert thread_messages(messages) == messages

    messages2 = [Message("aaa_header", [], datetime(1999, 1, 23)),
                 Message("bbb_header", ["aaa_header"], datetime(2000, 12, 23)),
                 Message("ccc_header", ["aaa_header"], datetime(2000, 12, 24)),
                 Message("ddd_header", ["bbb_header"], datetime(2000, 12, 25))]

    assert thread_messages(messages2) == messages2

    messages3 = [Message("aaa_header", [], datetime(1999, 1, 23)),
                 Message("bbb_header", ["aaa_header"], datetime(2000, 12, 23)),
                 Message("ccc_header", [], datetime(2000, 12, 23)),
                 Message("ddd_header", ["bbb_header"], datetime(2000, 12, 23))]

    print thread_messages(messages3)
    assert thread_messages(messages3) == messages3

# hack but my test won't run in the test runner. All the
# tests hang.
if __name__ == '__main__':
    pytest.main([__file__])
<commit_msg>forgot debug printf<commit_after># -*- coding: utf-8 -*-
import pytest
from datetime import datetime
from inbox.util.threading import cleanup_subject, thread_messages
from collections import namedtuple

def test_message_cleanup():
    assert cleanup_subject("Re: Birthday") == "Birthday"
    assert cleanup_subject("Re:Birthday") == "Birthday"
    assert cleanup_subject("Re:FWD:   Birthday") == "Birthday"
    assert (cleanup_subject("Re: RE: Alors, comment ça s'est passé ?")
                == "Alors, comment ça s'est passé ?")
    assert cleanup_subject("Re: FWD:FWD: Re:La chaise") == "La chaise"

def test_threading():
    Message = namedtuple('Message', ['message_id_header', 'references',
                                     'received_date'])
    messages = [Message("aaa_header", [], datetime(1999, 1, 23)),
                Message("bbb_header", ["aaa_header"], datetime(2000, 12, 23)),
                Message("ccc_header", ["bbb_header"], datetime(2000, 12, 24))]

    assert thread_messages(messages) == messages

    messages2 = [Message("aaa_header", [], datetime(1999, 1, 23)),
                 Message("bbb_header", ["aaa_header"], datetime(2000, 12, 23)),
                 Message("ccc_header", ["aaa_header"], datetime(2000, 12, 24)),
                 Message("ddd_header", ["bbb_header"], datetime(2000, 12, 25))]

    assert thread_messages(messages2) == messages2

    messages3 = [Message("aaa_header", [], datetime(1999, 1, 23)),
                 Message("bbb_header", ["aaa_header"], datetime(2000, 12, 23)),
                 Message("ccc_header", [], datetime(2000, 12, 23)),
                 Message("ddd_header", ["bbb_header"], datetime(2000, 12, 23))]

    assert thread_messages(messages3) == messages3

# hack but my test won't run in the test runner. All the
# tests hang.
if __name__ == '__main__':
    pytest.main([__file__])
<|endoftext|>


<commit_before>import logging
from unittest2 import TestCase
from raven.base import Client
from raven.handlers.logging import SentryHandler
from raven.utils.stacks import iter_stack_frames

class TempStoreClient(Client):
    def __init__(self, servers=None, **kwargs):
        self.events = []
        super(TempStoreClient, self).__init__(servers=servers, **kwargs)

    def send(self, **kwargs):
        self.events.append(kwargs)

class LoggingIntegrationTest(TestCase):
    def setUp(self):
        self.client = TempStoreClient(include_paths=['tests', 'raven'])
        self.handler = SentryHandler(self.client)
        self.logger = logging.getLogger(__name__)
        self.logger.handlers = []
        self.logger.addHandler(self.handler)

    def test_logger_basic(self):
        self.logger.error('This is a test error')

        self.assertEquals(len(self.client.events), 1)
        event = self.client.events.pop(0)
        self.assertEquals(event['logger'], __name__)
        self.assertEquals(event['level'], logging.ERROR)
        self.assertEquals(event['message'], 'This is a test error')
        self.assertFalse('sentry.interfaces.Stacktrace' in event)
        self.assertFalse('sentry.interfaces.Exception' in event)
        self.assertTrue('sentry.interfaces.Message' in event)
        msg = event['sentry.interfaces.Message']
        self.assertEquals(msg['message'], 'This is a test error')
        self.assertEquals(msg['params'], ())

    def test_logger_warning(self):
        self.logger.warning('This is a test warning')
        self.assertEquals(len(self.client.events), 1)
        event = self.client.events.pop(0)
        self.assertEquals(event['logger'], __name__)
        self.assertEquals(event['level'], logging.WARNING)
        self.assertEquals(event['message'], 'This is a test warning')
        self.assertFalse('sentry.interfaces.Stacktrace' in event)
        self.assertFalse('sentry.interfaces.Exception' in event)
        self.assertTrue('sentry.interfaces.Message' in event)
        msg = event['sentry.interfaces.Message']
        self.assertEquals(msg['message'], 'This is a test warning')
        self.assertEquals(msg['params'], ())

    def test_logger_extra_data(self):
        self.logger.info('This is a test info with a url', extra=dict(
            data=dict(
                url='http://example.com',
            ),
        ))
        self.assertEquals(len(self.client.events), 1)
        event = self.client.events.pop(0)
        self.assertEquals(event['extra']['url'], 'http://example.com')
        self.assertFalse('sentry.interfaces.Stacktrace' in event)
        self.assertFalse('sentry.interfaces.Exception' in event)
        self.assertTrue('sentry.interfaces.Message' in event)
        msg = event['sentry.interfaces.Message']
        self.assertEquals(msg['message'], 'This is a test info with a url')
        self.assertEquals(msg['params'], ())

    def test_logger_exc_info(self):
        try:
            raise ValueError('This is a test ValueError')
        except ValueError:
            self.logger.info('This is a test info with an exception', exc_info=True)

        self.assertEquals(len(self.client.events), 1)
        event = self.client.events.pop(0)

        self.assertEquals(event['message'], 'This is a test info with an exception')
        self.assertTrue('sentry.interfaces.Stacktrace' in event)
        self.assertTrue('sentry.interfaces.Exception' in event)
        exc = event['sentry.interfaces.Exception']
        self.assertEquals(exc['type'], 'ValueError')
        self.assertEquals(exc['value'], 'This is a test ValueError')
        self.assertTrue('sentry.interfaces.Message' in event)
        msg = event['sentry.interfaces.Message']
        self.assertEquals(msg['message'], 'This is a test info with an exception')
        self.assertEquals(msg['params'], ())

    def test_message_params(self):
        self.logger.info('This is a test of %s', 'args')
        self.assertEquals(len(self.client.events), 1)
        event = self.client.events.pop(0)
        self.assertEquals(event['message'], 'This is a test of args')
        self.assertFalse('sentry.interfaces.Stacktrace' in event)
        self.assertFalse('sentry.interfaces.Exception' in event)
        self.assertTrue('sentry.interfaces.Message' in event)
        msg = event['sentry.interfaces.Message']
        self.assertEquals(msg['message'], 'This is a test of %s')
        self.assertEquals(msg['params'], ('args',))

    def test_record_stack(self):
        self.logger.info('This is a test of stacks', extra={'stack': True})
        self.assertEquals(len(self.client.events), 1)
        event = self.client.events.pop(0)
        self.assertTrue('sentry.interfaces.Stacktrace' in event)
        frames = event['sentry.interfaces.Stacktrace']['frames']
        self.assertNotEquals(len(frames), 1)
        frame = frames[0]
        self.assertEquals(frame['module'], __name__)
        self.assertFalse('sentry.interfaces.Exception' in event)
        self.assertTrue('sentry.interfaces.Message' in event)
        msg = event['sentry.interfaces.Message']
        self.assertEquals(msg['message'], 'This is a test of stacks')
        self.assertEquals(msg['params'], ())
        self.assertEquals(event['culprit'], 'tests.handlers.logging.tests.test_record_stack')
        self.assertEquals(event['message'], 'This is a test of stacks')

    def test_no_record_stack(self):
        self.logger.info('This is a test of no stacks', extra={'stack': False})
        self.assertEquals(len(self.client.events), 1)
        event = self.client.events.pop(0)
        self.assertEquals(event.get('culprit'), None)
        self.assertEquals(event['message'], 'This is a test of no stacks')
        self.assertFalse('sentry.interfaces.Stacktrace' in event)
        self.assertFalse('sentry.interfaces.Exception' in event)
        self.assertTrue('sentry.interfaces.Message' in event)
        msg = event['sentry.interfaces.Message']
        self.assertEquals(msg['message'], 'This is a test of no stacks')
        self.assertEquals(msg['params'], ())

    def test_explicit_stack(self):
        self.logger.info('This is a test of stacks', extra={'stack': iter_stack_frames()})
        self.assertEquals(len(self.client.events), 1)
        event = self.client.events.pop(0)
        self.assertEquals(event['culprit'], 'tests.handlers.logging.tests.test_explicit_stack')
        self.assertEquals(event['message'], 'This is a test of stacks')
        self.assertFalse('sentry.interfaces.Exception' in event)
        self.assertTrue('sentry.interfaces.Message' in event)
        msg = event['sentry.interfaces.Message']
        self.assertEquals(msg['message'], 'This is a test of stacks')
        self.assertEquals(msg['params'], ())
        self.assertTrue('sentry.interfaces.Stacktrace' in event)

    def test_extra_culprit(self):
        self.logger.info('This is a test of stacks', extra={'culprit': 'foo.bar'})
        self.assertEquals(len(self.client.events), 1)
        event = self.client.events.pop(0)
        self.assertEquals(event['culprit'], 'foo.bar')

class LoggingHandlerTest(TestCase):
    def test_client_arg(self):
        client = TempStoreClient(include_paths=['tests'])
        handler = SentryHandler(client)
        self.assertEquals(handler.client, client)

    def test_client_kwarg(self):
        client = TempStoreClient(include_paths=['tests'])
        handler = SentryHandler(client=client)
        self.assertEquals(handler.client, client)

    def test_args_as_servers_and_key(self):
        handler = SentryHandler(['http://sentry.local/api/store/'], 'KEY')
        self.assertTrue(isinstance(handler.client, Client))

    def test_first_arg_as_dsn(self):
        handler = SentryHandler('http://public:secret@example.com/1')
        self.assertTrue(isinstance(handler.client, Client))

    def test_custom_client_class(self):
        handler = SentryHandler('http://public:secret@example.com/1', client_cls=TempStoreClient)
        self.assertTrue(type(handler.client), TempStoreClient)

    def test_invalid_first_arg_type(self):
        self.assertRaises(ValueError, SentryHandler, object)
<commit_msg>Test to confirm logging.exception works as expected (refs GH-75)<commit_after>import logging
from unittest2 import TestCase
from raven.base import Client
from raven.handlers.logging import SentryHandler
from raven.utils.stacks import iter_stack_frames

class TempStoreClient(Client):
    def __init__(self, servers=None, **kwargs):
        self.events = []
        super(TempStoreClient, self).__init__(servers=servers, **kwargs)

    def send(self, **kwargs):
        self.events.append(kwargs)

class LoggingIntegrationTest(TestCase):
    def setUp(self):
        self.client = TempStoreClient(include_paths=['tests', 'raven'])
        self.handler = SentryHandler(self.client)
        self.logger = logging.getLogger(__name__)
        self.logger.handlers = []
        self.logger.addHandler(self.handler)

    def test_logger_basic(self):
        self.logger.error('This is a test error')

        self.assertEquals(len(self.client.events), 1)
        event = self.client.events.pop(0)
        self.assertEquals(event['logger'], __name__)
        self.assertEquals(event['level'], logging.ERROR)
        self.assertEquals(event['message'], 'This is a test error')
        self.assertFalse('sentry.interfaces.Stacktrace' in event)
        self.assertFalse('sentry.interfaces.Exception' in event)
        self.assertTrue('sentry.interfaces.Message' in event)
        msg = event['sentry.interfaces.Message']
        self.assertEquals(msg['message'], 'This is a test error')
        self.assertEquals(msg['params'], ())

    def test_logger_warning(self):
        self.logger.warning('This is a test warning')
        self.assertEquals(len(self.client.events), 1)
        event = self.client.events.pop(0)
        self.assertEquals(event['logger'], __name__)
        self.assertEquals(event['level'], logging.WARNING)
        self.assertEquals(event['message'], 'This is a test warning')
        self.assertFalse('sentry.interfaces.Stacktrace' in event)
        self.assertFalse('sentry.interfaces.Exception' in event)
        self.assertTrue('sentry.interfaces.Message' in event)
        msg = event['sentry.interfaces.Message']
        self.assertEquals(msg['message'], 'This is a test warning')
        self.assertEquals(msg['params'], ())

    def test_logger_extra_data(self):
        self.logger.info('This is a test info with a url', extra=dict(
            data=dict(
                url='http://example.com',
            ),
        ))
        self.assertEquals(len(self.client.events), 1)
        event = self.client.events.pop(0)
        self.assertEquals(event['extra']['url'], 'http://example.com')
        self.assertFalse('sentry.interfaces.Stacktrace' in event)
        self.assertFalse('sentry.interfaces.Exception' in event)
        self.assertTrue('sentry.interfaces.Message' in event)
        msg = event['sentry.interfaces.Message']
        self.assertEquals(msg['message'], 'This is a test info with a url')
        self.assertEquals(msg['params'], ())

    def test_logger_exc_info(self):
        try:
            raise ValueError('This is a test ValueError')
        except ValueError:
            self.logger.info('This is a test info with an exception', exc_info=True)

        self.assertEquals(len(self.client.events), 1)
        event = self.client.events.pop(0)

        self.assertEquals(event['message'], 'This is a test info with an exception')
        self.assertTrue('sentry.interfaces.Stacktrace' in event)
        self.assertTrue('sentry.interfaces.Exception' in event)
        exc = event['sentry.interfaces.Exception']
        self.assertEquals(exc['type'], 'ValueError')
        self.assertEquals(exc['value'], 'This is a test ValueError')
        self.assertTrue('sentry.interfaces.Message' in event)
        msg = event['sentry.interfaces.Message']
        self.assertEquals(msg['message'], 'This is a test info with an exception')
        self.assertEquals(msg['params'], ())

    def test_message_params(self):
        self.logger.info('This is a test of %s', 'args')
        self.assertEquals(len(self.client.events), 1)
        event = self.client.events.pop(0)
        self.assertEquals(event['message'], 'This is a test of args')
        self.assertFalse('sentry.interfaces.Stacktrace' in event)
        self.assertFalse('sentry.interfaces.Exception' in event)
        self.assertTrue('sentry.interfaces.Message' in event)
        msg = event['sentry.interfaces.Message']
        self.assertEquals(msg['message'], 'This is a test of %s')
        self.assertEquals(msg['params'], ('args',))

    def test_record_stack(self):
        self.logger.info('This is a test of stacks', extra={'stack': True})
        self.assertEquals(len(self.client.events), 1)
        event = self.client.events.pop(0)
        self.assertTrue('sentry.interfaces.Stacktrace' in event)
        frames = event['sentry.interfaces.Stacktrace']['frames']
        self.assertNotEquals(len(frames), 1)
        frame = frames[0]
        self.assertEquals(frame['module'], __name__)
        self.assertFalse('sentry.interfaces.Exception' in event)
        self.assertTrue('sentry.interfaces.Message' in event)
        msg = event['sentry.interfaces.Message']
        self.assertEquals(msg['message'], 'This is a test of stacks')
        self.assertEquals(msg['params'], ())
        self.assertEquals(event['culprit'], 'tests.handlers.logging.tests.test_record_stack')
        self.assertEquals(event['message'], 'This is a test of stacks')

    def test_no_record_stack(self):
        self.logger.info('This is a test of no stacks', extra={'stack': False})
        self.assertEquals(len(self.client.events), 1)
        event = self.client.events.pop(0)
        self.assertEquals(event.get('culprit'), None)
        self.assertEquals(event['message'], 'This is a test of no stacks')
        self.assertFalse('sentry.interfaces.Stacktrace' in event)
        self.assertFalse('sentry.interfaces.Exception' in event)
        self.assertTrue('sentry.interfaces.Message' in event)
        msg = event['sentry.interfaces.Message']
        self.assertEquals(msg['message'], 'This is a test of no stacks')
        self.assertEquals(msg['params'], ())

    def test_explicit_stack(self):
        self.logger.info('This is a test of stacks', extra={'stack': iter_stack_frames()})
        self.assertEquals(len(self.client.events), 1)
        event = self.client.events.pop(0)
        self.assertEquals(event['culprit'], 'tests.handlers.logging.tests.test_explicit_stack')
        self.assertEquals(event['message'], 'This is a test of stacks')
        self.assertFalse('sentry.interfaces.Exception' in event)
        self.assertTrue('sentry.interfaces.Message' in event)
        msg = event['sentry.interfaces.Message']
        self.assertEquals(msg['message'], 'This is a test of stacks')
        self.assertEquals(msg['params'], ())
        self.assertTrue('sentry.interfaces.Stacktrace' in event)

    def test_extra_culprit(self):
        self.logger.info('This is a test of stacks', extra={'culprit': 'foo.bar'})
        self.assertEquals(len(self.client.events), 1)
        event = self.client.events.pop(0)
        self.assertEquals(event['culprit'], 'foo.bar')

    def test_logger_exception(self):
        try:
            raise ValueError('This is a test ValueError')
        except ValueError:
            self.logger.exception('This is a test with an exception')

        self.assertEquals(len(self.client.events), 1)
        event = self.client.events.pop(0)

        self.assertEquals(event['message'], 'This is a test with an exception')
        self.assertTrue('sentry.interfaces.Stacktrace' in event)
        self.assertTrue('sentry.interfaces.Exception' in event)
        exc = event['sentry.interfaces.Exception']
        self.assertEquals(exc['type'], 'ValueError')
        self.assertEquals(exc['value'], 'This is a test ValueError')
        self.assertTrue('sentry.interfaces.Message' in event)
        msg = event['sentry.interfaces.Message']
        self.assertEquals(msg['message'], 'This is a test with an exception')
        self.assertEquals(msg['params'], ())

class LoggingHandlerTest(TestCase):
    def test_client_arg(self):
        client = TempStoreClient(include_paths=['tests'])
        handler = SentryHandler(client)
        self.assertEquals(handler.client, client)

    def test_client_kwarg(self):
        client = TempStoreClient(include_paths=['tests'])
        handler = SentryHandler(client=client)
        self.assertEquals(handler.client, client)

    def test_args_as_servers_and_key(self):
        handler = SentryHandler(['http://sentry.local/api/store/'], 'KEY')
        self.assertTrue(isinstance(handler.client, Client))

    def test_first_arg_as_dsn(self):
        handler = SentryHandler('http://public:secret@example.com/1')
        self.assertTrue(isinstance(handler.client, Client))

    def test_custom_client_class(self):
        handler = SentryHandler('http://public:secret@example.com/1', client_cls=TempStoreClient)
        self.assertTrue(type(handler.client), TempStoreClient)

    def test_invalid_first_arg_type(self):
        self.assertRaises(ValueError, SentryHandler, object)
<|endoftext|>


<commit_before># Copyright (c) 2015 Uber Technologies, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

from __future__ import absolute_import

import pytest
import tornado
import tornado.gen
from mock import patch

from tchannel import retry
from tchannel.errors import ProtocolError
from tchannel.errors import TChannelError
from tchannel.errors import TimeoutError
from tchannel.messages import ErrorCode
from tchannel.tornado import Request
from tchannel.tornado import TChannel
from tchannel.tornado.stream import InMemStream

@tornado.gen.coroutine
def handler_error(request, response, proxy):
    yield tornado.gen.sleep(0.01)
    response.connection.send_error(
        ErrorCode.busy,
        "retry",
        response.id,
    )
    # stop normal response streams
    response.set_exception(TChannelError("stop stream"))

@tornado.gen.coroutine
def handler_success(request, response, proxy):
    response.set_body_s(InMemStream("success"))

def server(endpoint):
    tchannel_server = TChannel(name='testserver', hostport='localhost:0')
    tchannel_server.register(endpoint, 'raw', handler_error)
    tchannel_server.listen()
    return tchannel_server

def chain(number_of_peers, endpoint):
    tchannel = TChannel(name='test')
    for i in range(number_of_peers):
        tchannel.peers.get(server(endpoint).hostport)

    return tchannel

@pytest.mark.gen_test
def test_retry_timeout():
    endpoint = b'tchannelretrytest'
    tchannel = chain(3, endpoint)
    with (
        patch(
            'tchannel.tornado.Request.should_retry_on_error',
            autospec=True)
    ) as mock_should_retry_on_error:
        mock_should_retry_on_error.return_value = True
        with pytest.raises(TimeoutError):
            yield tchannel.request(
                score_threshold=0,
            ).send(
                endpoint,
                "test",
                "test",
                headers={
                    're': retry.CONNECTION_ERROR_AND_TIMEOUT
                },
                ttl=0.005,
                retry_limit=3,
            )

@pytest.mark.gen_test
def test_retry_on_error_fail():
    endpoint = b'tchannelretrytest'
    tchannel = chain(3, endpoint)

    with (
        patch(
            'tchannel.tornado.Request.should_retry_on_error',
            autospec=True)
    ) as mock_should_retry_on_error:
        mock_should_retry_on_error.return_value = True
        with pytest.raises(ProtocolError) as e:
            yield tchannel.request(
                score_threshold=0
            ).send(
                endpoint,
                "test",
                "test",
                headers={
                    're': retry.CONNECTION_ERROR_AND_TIMEOUT
                },
                ttl=0.02,
                retry_limit=3,
            )

        assert mock_should_retry_on_error.called
        assert mock_should_retry_on_error.call_count == (
            retry.DEFAULT_RETRY_LIMIT)
        assert e.value.code == ErrorCode.busy

@pytest.mark.gen_test
def test_retry_on_error_success():

    endpoint = b'tchannelretrytest'
    tchannel = chain(2, endpoint)

    tchannel_success = TChannel(name='test', hostport='localhost:0')
    tchannel_success.register(endpoint, 'raw', handler_success)
    tchannel_success.listen()
    tchannel.peers.get(tchannel_success.hostport)

    with (
        patch(
            'tchannel.tornado.Request.should_retry_on_error',
            autospec=True)
    ) as mock_should_retry_on_error:
        mock_should_retry_on_error.return_value = True
        response = yield tchannel.request(
            score_threshold=0
        ).send(
            endpoint,
            "test",
            "test",
            headers={
                're': retry.CONNECTION_ERROR_AND_TIMEOUT,
            },
            ttl=0.01,
            retry_limit=3,
        )

        header = yield response.get_header()
        body = yield response.get_body()
        assert body == "success"
        assert header == ""

@pytest.mark.gen_test
@pytest.mark.parametrize('retry_flag, error_code, result', [
    (retry.CONNECTION_ERROR, ErrorCode.busy, True),
    (retry.CONNECTION_ERROR, ErrorCode.declined, True),
    (retry.CONNECTION_ERROR, ErrorCode.timeout, False),
    (retry.CONNECTION_ERROR_AND_TIMEOUT, ErrorCode.timeout, True),
    (retry.TIMEOUT, ErrorCode.unexpected, False),
    (retry.TIMEOUT, ErrorCode.network_error, False),
    (retry.CONNECTION_ERROR, ErrorCode.network_error, True),
    (retry.NEVER, ErrorCode.network_error, False),
    (retry.CONNECTION_ERROR_AND_TIMEOUT, ErrorCode.cancelled, False),
    (retry.CONNECTION_ERROR_AND_TIMEOUT, ErrorCode.bad_request, False),
    (retry.CONNECTION_ERROR, ErrorCode.fatal, True),
    (retry.TIMEOUT, ErrorCode.fatal, False),
    (retry.TIMEOUT, ErrorCode.unhealthy, False),
    (retry.CONNECTION_ERROR_AND_TIMEOUT, ErrorCode.unhealthy, False),
],
    ids=lambda arg: str(arg)
)
def test_should_retry_on_error(retry_flag, error_code, result):
    request = Request(
        headers={'re': retry_flag},
    )

    error = ProtocolError(code=error_code, description="retry")
    assert request.should_retry_on_error(error) == result
<commit_msg>add test that request.id == response.id during event<commit_after># Copyright (c) 2015 Uber Technologies, Inc.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

from __future__ import absolute_import

import pytest
from tchannel.event import EventHook
import tornado
import tornado.gen
from mock import patch

from tchannel import retry
from tchannel.errors import ProtocolError
from tchannel.errors import TChannelError
from tchannel.errors import TimeoutError
from tchannel.messages import ErrorCode
from tchannel.tornado import Request
from tchannel.tornado import TChannel
from tchannel.tornado.stream import InMemStream

@tornado.gen.coroutine
def handler_error(request, response, proxy):
    yield tornado.gen.sleep(0.01)
    response.connection.send_error(
        ErrorCode.busy,
        "retry",
        response.id,
    )
    # stop normal response streams
    response.set_exception(TChannelError("stop stream"))

@tornado.gen.coroutine
def handler_success(request, response, proxy):
    response.set_body_s(InMemStream("success"))

def server(endpoint):
    tchannel_server = TChannel(name='testserver', hostport='localhost:0')
    tchannel_server.register(endpoint, 'raw', handler_error)
    tchannel_server.listen()
    return tchannel_server

def chain(number_of_peers, endpoint):
    tchannel = TChannel(name='test')
    for i in range(number_of_peers):
        tchannel.peers.get(server(endpoint).hostport)

    return tchannel

@pytest.mark.gen_test
def test_retry_timeout():
    endpoint = b'tchannelretrytest'
    tchannel = chain(3, endpoint)
    with (
        patch(
            'tchannel.tornado.Request.should_retry_on_error',
            autospec=True)
    ) as mock_should_retry_on_error:
        mock_should_retry_on_error.return_value = True
        with pytest.raises(TimeoutError):
            yield tchannel.request(
                score_threshold=0,
            ).send(
                endpoint,
                "test",
                "test",
                headers={
                    're': retry.CONNECTION_ERROR_AND_TIMEOUT
                },
                ttl=0.005,
                retry_limit=3,
            )

@pytest.mark.gen_test
def test_retry_on_error_fail():
    endpoint = b'tchannelretrytest'
    tchannel = chain(3, endpoint)

    with (
        patch(
            'tchannel.tornado.Request.should_retry_on_error',
            autospec=True)
    ) as mock_should_retry_on_error:
        mock_should_retry_on_error.return_value = True
        with pytest.raises(ProtocolError) as e:
            yield tchannel.request(
                score_threshold=0
            ).send(
                endpoint,
                "test",
                "test",
                headers={
                    're': retry.CONNECTION_ERROR_AND_TIMEOUT
                },
                ttl=0.02,
                retry_limit=3,
            )

        assert mock_should_retry_on_error.called
        assert mock_should_retry_on_error.call_count == (
            retry.DEFAULT_RETRY_LIMIT)
        assert e.value.code == ErrorCode.busy

class TestHook(EventHook):
    def __init__(self):
        self.test_obj = None

    def after_receive_response(self, request, response):
        self.test_obj = object()
        assert request.id == response.id

    def after_receive_error(self, request, error):
        self.test_obj = object()
        assert request.id == error.id

@pytest.mark.gen_test
def test_retry_on_error_success():
    endpoint = b'tchannelretrytest'
    tchannel = chain(2, endpoint)
    hook = TestHook()
    tchannel.hooks.register(hook)

    tchannel_success = TChannel(name='test', hostport='localhost:0')
    tchannel_success.register(endpoint, 'raw', handler_success)
    tchannel_success.listen()
    tchannel.peers.get(tchannel_success.hostport)

    with (
        patch(
            'tchannel.tornado.Request.should_retry_on_error',
            autospec=True)
    ) as mock_should_retry_on_error:
        mock_should_retry_on_error.return_value = True
        response = yield tchannel.request(
            score_threshold=0
        ).send(
            endpoint,
            "test",
            "test",
            headers={
                're': retry.CONNECTION_ERROR_AND_TIMEOUT,
            },
            ttl=0.01,
            retry_limit=3,
        )

        header = yield response.get_header()
        body = yield response.get_body()
        assert body == "success"
        assert header == ""

    assert hook.test_obj

@pytest.mark.gen_test
@pytest.mark.parametrize('retry_flag, error_code, result', [
    (retry.CONNECTION_ERROR, ErrorCode.busy, True),
    (retry.CONNECTION_ERROR, ErrorCode.declined, True),
    (retry.CONNECTION_ERROR, ErrorCode.timeout, False),
    (retry.CONNECTION_ERROR_AND_TIMEOUT, ErrorCode.timeout, True),
    (retry.TIMEOUT, ErrorCode.unexpected, False),
    (retry.TIMEOUT, ErrorCode.network_error, False),
    (retry.CONNECTION_ERROR, ErrorCode.network_error, True),
    (retry.NEVER, ErrorCode.network_error, False),
    (retry.CONNECTION_ERROR_AND_TIMEOUT, ErrorCode.cancelled, False),
    (retry.CONNECTION_ERROR_AND_TIMEOUT, ErrorCode.bad_request, False),
    (retry.CONNECTION_ERROR, ErrorCode.fatal, True),
    (retry.TIMEOUT, ErrorCode.fatal, False),
    (retry.TIMEOUT, ErrorCode.unhealthy, False),
    (retry.CONNECTION_ERROR_AND_TIMEOUT, ErrorCode.unhealthy, False),
],
    ids=lambda arg: str(arg)
)
def test_should_retry_on_error(retry_flag, error_code, result):
    request = Request(
        headers={'re': retry_flag},
    )

    error = ProtocolError(code=error_code, description="retry")
    assert request.should_retry_on_error(error) == result
<|endoftext|>