<commit_before>import logging
from unittest import TestCase

import pytest
import numpy as np
from scipy.spatial import distance

from poissondisk import generate_circ_poisson_points as gpp
from poissondisk import generate_rect_poisson_points as grpp

LG = logging.getLogger('cypoisson')

class TestBase(TestCase):

    def highlight(self, text):
        LG.info(text.center(80, '#'))

    def _plot(self, rect=False):
        points = np.array(self.points)
        lp = len(points)
        import matplotlib
        import matplotlib.pyplot as plt
        from matplotlib.patches import Circle, Rectangle
        from matplotlib.collections import PatchCollection

        fig = plt.figure()
        ax = fig.add_subplot(111)

        patches = []
        for p in points:
            circle = Circle((p.real, p.imag), self.rscat)
            patches.append(circle)

        try:
            w = h = 2*self.rdisk
        except AttributeError:
            w, h = self.w, self.h
        if rect:
            patches.append(Rectangle((-w/2., -h/2.), w, h))
        else:
            patches.append(Circle((0, 0), self.rdisk))

        p = PatchCollection(patches, cmap=matplotlib.cm.rainbow,
                            alpha=0.4)
        ax.add_collection(p)

        pad = 0.05*w
        ax.set_xlim(-w/2. - pad, w/2. + pad)
        ax.set_ylim(-h/2. - pad, h/2. + pad)
        ax.grid(True)
        ax.set_xlabel('x [um]')
        ax.set_ylabel('y [um]')
        ax.set_aspect('equal')

        if rect:
            ax.set_title('%d scatterers (w %g um, h %g um, ff=%g)' % (
                lp, w, h, self.ff))
        else:
            ax.set_title('%d scatterers (diameter %g um, ff=%g)' % (
                lp, self.rdisk*2, self.ff))
        plt.show()

class TestPoisson(TestBase):
    """
    TODO
    unterschiedliche seeds muessen unterschiedliche konfigs erzeugen
    gleiche seeds gleiche konfigs
    distance_border
    max distance ~ ddisk-distanceborder

    """

    def test_1(self):
        self.rdisk = 350.
        self.rscat = 10.
        desired_ff = 0.4
        self.points = gpp(0, rdisk=self.rdisk, rscat=self.rscat,
                          ff=desired_ff)
        lp = len(self.points)
        self.assertGreater(lp, 0)
        ff = lp*self.rscat**2./self.rdisk**2
        LG.info('desired ff %g, actual ff %g', desired_ff, ff)
        self.assertLess(abs(desired_ff - ff), 0.03)
        self.ff, self.desired_ff = ff, desired_ff

    def test_1_rectangle(self):
        self.h = self.w = 700.
        self.rscat = 10.
        desired_ff = 0.45
        self.points = grpp(1, w=self.w, h=self.h, rscat=self.rscat,
                           ff=desired_ff)
        lp = len(self.points)
        self.assertGreater(lp, 0)
        ff = lp*np.pi*self.rscat**2./(self.w*self.h)
        LG.info('desired ff %g, actual ff %g', desired_ff, ff)
        self.assertLess(abs(desired_ff - ff), 0.05)
        self.ff, self.desired_ff = ff, desired_ff

    @pytest.mark.skipif('not config.getvalue("interactive")')
    def test_1_plot(self):
        self.test_1()
        self._plot()

    @pytest.mark.skipif('not config.getvalue("interactive")')
    def test_1_rectangle_plot(self):
        self.test_1_rectangle()
        self._plot(rect=True)

    def test_2(self):
        self.rdisk = 350.
        self.rscat = 10.
        prevlp = 0
        for desired_ff in np.linspace(0.05, 0.4, 8):
            points = gpp(1, rdisk=self.rdisk, rscat=self.rscat, ff=desired_ff)
            ff = len(points)*self.rscat**2./self.rdisk**2
            LG.info('desired ff %g, actual ff %g', desired_ff, ff)
            self.assertLess(abs(desired_ff - ff), 0.03)
            self.assertGreater(len(points), prevlp)
            levlp = len(points)

    def test_3(self):
        """
        collision check
        check that all points lie within a the disk
        """
        self.rdisk = 7.5
        self.rscat = 0.1
        desired_ff = 0.30
        self.points = np.array(gpp(1, rdisk=self.rdisk, rscat=self.rscat,
                                   ff=desired_ff))
        self.assertGreater(len(self.points), 0)
        ff = len(self.points)*self.rscat**2./self.rdisk**2
        LG.info('desired ff %g, actual ff %g', desired_ff, ff)
        self.assertLess(abs(desired_ff - ff), 0.03)
        self.ff, self.desired_ff = ff, desired_ff

        assert all(np.abs(self.points) < self.rdisk - self.rscat)

        # self._plot()

        p = np.c_[self.points.real, self.points.imag]
        dists = distance.cdist(p, p, 'euclidean')
        mindist = dists[dists > 0].min()
        maxdist = dists.max()
        self.assertGreater(mindist, 2*self.rscat)

        LG.info("mindist: %g\tnet mindist: %g\tmaxdist: %g",
                mindist, mindist - 2*self.rscat, maxdist)
        self.assertGreater(maxdist, self.rdisk*2*0.9)

    def test_3_loop(self):
        """
        collision check
        check that all points lie within a the disk
        """
        self.rdisk = 7.5  # ddisk = 15um
        self.rscat = 0.05  # dscat = 100nm
        for desired_ff in [0.05, 0.10, 0.15, 0.2, 0.25, 0.3, 0.35]:
            self.highlight("DESIRED FF %g" % desired_ff)
            self.points = np.array(gpp(1, rdisk=self.rdisk, rscat=self.rscat,
                                       ff=desired_ff))
            self.assertGreater(len(self.points), 0)
            ff = len(self.points)*self.rscat**2./self.rdisk**2
            LG.info('desired ff %g, actual ff %g', desired_ff, ff)
            self.assertLess(abs(desired_ff - ff), 0.03)
            self.ff, self.desired_ff = ff, desired_ff

            assert all(np.abs(self.points) < self.rdisk - self.rscat)

            # self._plot()
            p = np.c_[self.points.real, self.points.imag]
            dists = distance.cdist(p, p, 'euclidean')
            mindist = dists[dists > 0].min()
            maxdist = dists.max()
            self.assertGreater(mindist, 2*self.rscat)

            LG.info("FF %g:\tmindist: %g\tnet mindist: %g\tmaxdist: %g",
                    self.ff, mindist, mindist - 2*self.rscat, maxdist)
            self.assertGreater(maxdist, self.rdisk*2*0.9)

    def test_4(self):
        """
        test distributions where disks intersecting the boundary are allowed
        """
        self.rdisk = 350.
        self.rscat = 10.
        desired_ff = 0.4
        self.points = gpp(0, rdisk=self.rdisk, rscat=self.rscat,
                          ff=desired_ff, allow_disks_on_boundary=True)
        lp = len(self.points)
        self.assertGreater(lp, 0)
        ff = lp*self.rscat**2./self.rdisk**2  # TODO this is not the correct
                                              # expression for the filling
                                              # fraction as some of the
                                              # scatterers lie outside the
                                              # disk
        LG.info('desired ff %g, actual ff %g', desired_ff, ff)
        self.assertLess(abs(desired_ff - ff), 0.01)
        self.ff, self.desired_ff = ff, desired_ff

        expr = [abs(p) > self.rdisk-self.rscat for p in self.points]
        LG.info("%d scats lie on the boundary", sum(expr))
        assert any(expr)

    @pytest.mark.skipif('not config.getvalue("interactive")')
    def test_4_plot(self):
        self.test_4()
        self._plot()
<commit_msg>pytest: use assert statement<commit_after>import logging
from unittest import TestCase

import pytest
import numpy as np
from scipy.spatial import distance

from poissondisk import generate_circ_poisson_points as gpp
from poissondisk import generate_rect_poisson_points as grpp

LG = logging.getLogger('cypoisson')

class TestBase(TestCase):

    def highlight(self, text):
        LG.info(text.center(80, '#'))

    def _plot(self, rect=False):
        points = np.array(self.points)
        lp = len(points)
        import matplotlib
        import matplotlib.pyplot as plt
        from matplotlib.patches import Circle, Rectangle
        from matplotlib.collections import PatchCollection

        fig = plt.figure()
        ax = fig.add_subplot(111)

        patches = []
        for p in points:
            circle = Circle((p.real, p.imag), self.rscat)
            patches.append(circle)

        try:
            w = h = 2*self.rdisk
        except AttributeError:
            w, h = self.w, self.h
        if rect:
            patches.append(Rectangle((-w/2., -h/2.), w, h))
        else:
            patches.append(Circle((0, 0), self.rdisk))

        p = PatchCollection(patches, cmap=matplotlib.cm.rainbow,
                            alpha=0.4)
        ax.add_collection(p)

        pad = 0.05*w
        ax.set_xlim(-w/2. - pad, w/2. + pad)
        ax.set_ylim(-h/2. - pad, h/2. + pad)
        ax.grid(True)
        ax.set_xlabel('x [um]')
        ax.set_ylabel('y [um]')
        ax.set_aspect('equal')

        if rect:
            ax.set_title('%d scatterers (w %g um, h %g um, ff=%g)' % (
                lp, w, h, self.ff))
        else:
            ax.set_title('%d scatterers (diameter %g um, ff=%g)' % (
                lp, self.rdisk*2, self.ff))
        plt.show()

class TestPoisson(TestBase):
    """
    TODO
    unterschiedliche seeds muessen unterschiedliche konfigs erzeugen
    gleiche seeds gleiche konfigs
    distance_border
    max distance ~ ddisk-distanceborder

    """

    def test_1(self):
        self.rdisk = 350.
        self.rscat = 10.
        desired_ff = 0.4
        self.points = gpp(0, rdisk=self.rdisk, rscat=self.rscat,
                          ff=desired_ff)
        lp = len(self.points)
        assert lp > 0
        ff = lp*self.rscat**2./self.rdisk**2
        LG.info('desired ff %g, actual ff %g', desired_ff, ff)
        assert abs(desired_ff - ff) < 0.03
        self.ff, self.desired_ff = ff, desired_ff

    def test_1_rectangle(self):
        self.h = self.w = 700.
        self.rscat = 10.
        desired_ff = 0.45
        self.points = grpp(1, w=self.w, h=self.h, rscat=self.rscat,
                           ff=desired_ff)
        lp = len(self.points)
        assert lp > 0
        ff = lp*np.pi*self.rscat**2./(self.w*self.h)
        LG.info('desired ff %g, actual ff %g', desired_ff, ff)
        assert abs(desired_ff - ff) < .05
        self.ff, self.desired_ff = ff, desired_ff

    @pytest.mark.skipif('not config.getvalue("interactive")')
    def test_1_plot(self):
        self.test_1()
        self._plot()

    @pytest.mark.skipif('not config.getvalue("interactive")')
    def test_1_rectangle_plot(self):
        self.test_1_rectangle()
        self._plot(rect=True)

    def test_2(self):
        self.rdisk = 350.
        self.rscat = 10.
        prevlp = 0
        for desired_ff in np.linspace(0.05, 0.4, 8):
            points = gpp(1, rdisk=self.rdisk, rscat=self.rscat, ff=desired_ff)
            ff = len(points)*self.rscat**2./self.rdisk**2
            LG.info('desired ff %g, actual ff %g', desired_ff, ff)
            assert abs(desired_ff - ff) < 0.03
            assert len(points) > prevlp
            levlp = len(points)

    def test_3(self):
        """
        collision check
        check that all points lie within a the disk
        """
        self.rdisk = 7.5
        self.rscat = 0.1
        desired_ff = 0.30
        self.points = np.array(gpp(1, rdisk=self.rdisk, rscat=self.rscat,
                                   ff=desired_ff))
        self.assertGreater(len(self.points), 0)
        ff = len(self.points)*self.rscat**2./self.rdisk**2
        LG.info('desired ff %g, actual ff %g', desired_ff, ff)
        assert abs(desired_ff - ff) < 0.03
        self.ff, self.desired_ff = ff, desired_ff

        assert all(np.abs(self.points) < self.rdisk - self.rscat)

        # self._plot()

        p = np.c_[self.points.real, self.points.imag]
        dists = distance.cdist(p, p, 'euclidean')
        mindist = dists[dists > 0].min()
        maxdist = dists.max()
        assert mindist > 2*self.rscat

        LG.info("mindist: %g\tnet mindist: %g\tmaxdist: %g",
                mindist, mindist - 2*self.rscat, maxdist)
        assert maxdist > self.rdisk*2*0.9

    def test_3_loop(self):
        """
        collision check
        check that all points lie within a the disk
        """
        self.rdisk = 7.5  # ddisk = 15um
        self.rscat = 0.05  # dscat = 100nm
        for desired_ff in [0.05, 0.10, 0.15, 0.2, 0.25, 0.3, 0.35]:
            self.highlight("DESIRED FF %g" % desired_ff)
            self.points = np.array(gpp(1, rdisk=self.rdisk, rscat=self.rscat,
                                       ff=desired_ff))
            assert len(self.points) > 0
            ff = len(self.points)*self.rscat**2./self.rdisk**2
            LG.info('desired ff %g, actual ff %g', desired_ff, ff)
            abs(desired_ff - ff) < 0.03
            self.ff, self.desired_ff = ff, desired_ff

            assert all(np.abs(self.points) < self.rdisk - self.rscat)

            # self._plot()
            p = np.c_[self.points.real, self.points.imag]
            dists = distance.cdist(p, p, 'euclidean')
            mindist = dists[dists > 0].min()
            maxdist = dists.max()
            assert mindist > 2*self.rscat

            LG.info("FF %g:\tmindist: %g\tnet mindist: %g\tmaxdist: %g",
                    self.ff, mindist, mindist - 2*self.rscat, maxdist)
            assert maxdist > self.rdisk*2*0.9

    def test_4(self):
        """
        test distributions where disks intersecting the boundary are allowed
        """
        self.rdisk = 350.
        self.rscat = 10.
        desired_ff = 0.4
        self.points = gpp(0, rdisk=self.rdisk, rscat=self.rscat,
                          ff=desired_ff, allow_disks_on_boundary=True)
        lp = len(self.points)
        assert lp > 0
        ff = lp*self.rscat**2./self.rdisk**2  # TODO this is not the correct
                                              # expression for the filling
                                              # fraction as some of the
                                              # scatterers lie outside the
                                              # disk
        LG.info('desired ff %g, actual ff %g', desired_ff, ff)
        abs(desired_ff - ff) < .01
        self.ff, self.desired_ff = ff, desired_ff

        expr = [abs(p) > self.rdisk-self.rscat for p in self.points]
        LG.info("%d scats lie on the boundary", sum(expr))
        assert any(expr)

    @pytest.mark.skipif('not config.getvalue("interactive")')
    def test_4_plot(self):
        self.test_4()
        self._plot()
<|endoftext|>


<commit_before>#Import the necesary modules
from context import *

'''In this test we will try three dimensionally
plotting Earth and some of its satellites from
a barycentric persepctive.'''

#Firstly instantiate Earth as a Celestial Body instance
Earth = Celestial_Body('Earth', satellites = True)

#Earth's satellites were already automatically
#instantiated as Satellite instances, so they may
#be readily accesed

#Our time range to plot
#From January 1st to 2nd , 2016 w/ 1000 point resolution
times = np.linspace(2457388.000000, 2457389.000000, 1000)

#Insantate the figure for our plot
fig = plt.figure

#For Earth and 10 of its satellites
for celestial_body, satellite in zip(Celestial_Body._instances, Satellite._instances[:10]):
  #For every time step in our time range
  for time in times:
    #Update the position and velocity of our bodies
    Celestial_Body.Update_Position_and_Velocity(time)
    Satellite.Update_Position_and_Velocity(time)
    pass
  #Now plot their position time-traces
  celestial_body.Plot_3D(fig)
  satellite.Plot_3D(fig)
  pass

#Be patient, this will take about 20 seconds.
#NUMBA JIT compillation will be implemented soon!
<commit_msg>Fixed the example<commit_after>#Import the necesary modules
from context import *

'''In this test we will try three dimensionally
plotting Earth and some of its satellites from
a barycentric persepctive.'''

#Firstly instantiate Earth as a Celestial Body instance
Earth = Celestial_Body('Earth')
Moon = Celestial_Body('Moon')

#Earth's satellites were already automatically
#instantiated as Satellite instances, so they may
#be readily accesed

#Our time range to plot
#From January 1st to 2nd , 2016 w/ 1000 point resolution
times = np.linspace(2457388.000000, 2457388.500000, 1000)

#the figure
fig = plt.figure()

#the satellites
for sat in Satellite._instances[:40]:
  for time in times:
    sat.Update_Position_and_Velocity(time)
    pass
  sat.Plot_3D(fig)
  pass

#the planets
for cb in Celestial_Body._instances:
  for time in times:
    cb.Update_Position_and_Velocity(time)
    pass
  cb.Plot_3D(fig)
  pass

<|endoftext|>


<commit_before># The MIT License (MIT)

# Copyright (c) 2013 Dominic May

# 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.

# setup the test environment
import os
import sys
sys.path.insert(0, 'src')
sys.path.insert(0, os.path.join('..', 'src'))

import webtest
import test_data
import unittest2

def setup_environ():
    if hasattr(setup_environ, '_is_setup'):
        return
    else:
        setup_environ._is_setup = True

    POSSIBLE_LOCATIONS = [
        'C:\\Program Files (x86)\\Google\\google_appengine\\',
        '~/.google_appengine/',
        '.'
    ]

    # locate app-engine SDK
    POSSIBLE_LOCATIONS = map(os.path.expanduser, POSSIBLE_LOCATIONS)
    POSSIBLE_LOCATIONS = filter(os.path.exists, POSSIBLE_LOCATIONS)
    POSSIBLE_LOCATIONS = filter(os.path.isdir, POSSIBLE_LOCATIONS)
    POSSIBLE_LOCATIONS = filter(
        lambda path: os.path.exists(os.path.join(path, 'appcfg.py')),
        POSSIBLE_LOCATIONS
    )
    sys.path.append(POSSIBLE_LOCATIONS[0])

    import dev_appserver
    dev_appserver.fix_sys_path()

class DMSTestCase(unittest2.TestCase):
    def setUp(self):
        # setup the testbed
        self.testbed = testbed.Testbed()
        self.testbed.setup_env(
            APPENGINE_RUNTIME='python27',
            app_id='dcputoolchain-module-site'
        )
        self.testbed.activate()

        # initiate the stubs
        self.testbed.init_datastore_v3_stub()
        self.testbed.init_memcache_stub()
        self.testbed.init_urlfetch_stub()

        # setup data
        memcache.set('client_auth_data', test_data.CLIENT_AUTH_DATA)

    def tearDown(self):
        self.testbed.deactivate()

class DMSHandlerTestCase(DMSTestCase):
    def setUp(self, *args, **kwargs):
        super(DMSHandlerTestCase, self).setUp(*args, **kwargs)

        from main import app
        self.testapp = webtest.TestApp(app)

# this needs to be done before anything to do with gae gets imported
setup_environ()
from google.appengine.ext import testbed
from google.appengine.api import memcache

def main():
    unittest2.main()
<commit_msg>Added assertEqualMemcache helper<commit_after># The MIT License (MIT)

# Copyright (c) 2013 Dominic May

# 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.

# setup the test environment
import os
import sys
sys.path.insert(0, 'src')
sys.path.insert(0, os.path.join('..', 'src'))

import webtest
import test_data
import unittest2

def setup_environ():
    if hasattr(setup_environ, '_is_setup'):
        return
    else:
        setup_environ._is_setup = True

    POSSIBLE_LOCATIONS = [
        'C:\\Program Files (x86)\\Google\\google_appengine\\',
        '~/.google_appengine/',
        '.'
    ]

    # locate app-engine SDK
    POSSIBLE_LOCATIONS = map(os.path.expanduser, POSSIBLE_LOCATIONS)
    POSSIBLE_LOCATIONS = filter(os.path.exists, POSSIBLE_LOCATIONS)
    POSSIBLE_LOCATIONS = filter(os.path.isdir, POSSIBLE_LOCATIONS)
    POSSIBLE_LOCATIONS = filter(
        lambda path: os.path.exists(os.path.join(path, 'appcfg.py')),
        POSSIBLE_LOCATIONS
    )
    sys.path.append(POSSIBLE_LOCATIONS[0])

    import dev_appserver
    dev_appserver.fix_sys_path()

class DMSTestCase(unittest2.TestCase):
    def setUp(self):
        # setup the testbed
        self.testbed = testbed.Testbed()
        self.testbed.setup_env(
            APPENGINE_RUNTIME='python27',
            app_id='dcputoolchain-module-site'
        )
        self.testbed.activate()

        # initiate the stubs
        self.testbed.init_datastore_v3_stub()
        self.testbed.init_memcache_stub()
        self.testbed.init_urlfetch_stub()

        # setup data
        memcache.set('client_auth_data', test_data.CLIENT_AUTH_DATA)

    def tearDown(self):
        self.testbed.deactivate()

    def assertEqualMemcache(self, key, compare_to):
        if type(key) == tuple:
            key = key[1] + key[0]
        value = memcache.get(key)
        self.assertEqual(value, compare_to)

class DMSHandlerTestCase(DMSTestCase):
    def setUp(self, *args, **kwargs):
        super(DMSHandlerTestCase, self).setUp(*args, **kwargs)

        from main import app
        self.testapp = webtest.TestApp(app)

# this needs to be done before anything to do with gae gets imported
setup_environ()
from google.appengine.ext import testbed
from google.appengine.api import memcache

def main():
    unittest2.main()
<|endoftext|>


<commit_before>from subprocess import call, Popen
from tempfile import mkstemp, mkdtemp
import json
import sys
import time
import socket
import ssl
import os
import urllib.request

FNULL = open(os.devnull, 'w')
LOCALHOST = '127.0.0.1'
STATUS_PORT = 13100
TIMEOUT = 5

# Helper to run ghostunnel in integration test mode

def run_ghostunnel(args):
    os.environ["GHOSTUNNEL_INTEGRATION_TEST"] = "true"
    os.environ["GHOSTUNNEL_INTEGRATION_ARGS"] = json.dumps(args)
    print_ok("running with args:\n {0}".format(' \ \n '.join(args)))
    test = os.path.basename(sys.argv[0]).replace('.py', '.out')
    return Popen([
        '../ghostunnel.test',
        '-test.run=TestIntegrationMain',
        '-test.coverprofile=coverage-{0}'.format(test)])

# Gracefully terminate ghostunnel (with timeout)

def terminate(ghostunnel):
    print_ok("terminating ghostunnel instance")
    try:
        if ghostunnel:
            ghostunnel.terminate()
            for i in range(0, 10):
                try:
                    ghostunnel.wait(timeout=1)
                except BaseException:
                    pass
                if ghostunnel.returncode is not None:
                    print_ok("ghostunnel stopped with exit code {0}".format(
                        ghostunnel.returncode))
                    return
                time.sleep(1)
            print_ok("timeout, killing ghostunnel")
            ghostunnel.kill()
    except BaseException:
        pass

# Attempt to dump goroutines via status port/pprof

def dump_goroutines():
    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE
    try:
        sys.stderr.buffer.write(urllib.request.urlopen(
            "https://{0}:{1}/debug/pprof/goroutine?debug=1".format(
                LOCALHOST, STATUS_PORT),
            context=ctx).read())
    except Exception as e:
        print('unable to dump goroutines:', e)

# Helper class to create root + signed certs

class RootCert:
    def __init__(self, name):
        self.name = name
        self.leaf_certs = []
        print_ok("generating {0}.key, {0}.crt".format(name))
        call(
            'openssl genrsa -out {0}.key 1024'.format(name),
            shell=True,
            stderr=FNULL)
        call(
            'openssl req -x509 -new -key {0}.key -days 5 -out {0}_temp.crt -subj /C=US/ST=CA/O=ghostunnel/OU={0}'.format(name),
            shell=True)
        os.rename("{0}_temp.crt".format(name), "{0}.crt".format(name))
        call('chmod 600 {0}.key'.format(name), shell=True)

    def create_signed_cert(self, ou, san="IP:127.0.0.1,IP:::1,DNS:localhost"):
        print_ok("generating {0}.key, {0}.crt, {0}.p12".format(ou))
        fd, openssl_config = mkstemp(dir='.')
        os.write(fd, "extendedKeyUsage=clientAuth,serverAuth\n".encode('utf-8'))
        os.write(fd, "subjectAltName = {0}".format(san).encode('utf-8'))
        call("openssl genrsa -out {0}.key 1024".format(ou),
             shell=True, stderr=FNULL)
        call(
            "openssl req -new -key {0}.key -out {0}.csr -subj /C=US/ST=CA/O=ghostunnel/OU={0}".format(ou),
            shell=True,
            stderr=FNULL)
        call("chmod 600 {0}.key".format(ou), shell=True)
        call(
            "openssl x509 -req -in {0}.csr -CA {1}.crt -CAkey {1}.key -CAcreateserial -out {0}_temp.crt -days 5 -extfile {2}".format(
                ou,
                self.name,
                openssl_config),
            shell=True,
            stderr=FNULL)
        call(
            "openssl pkcs12 -export -out {0}_temp.p12 -in {0}_temp.crt -inkey {0}.key -password pass:".format(ou),
            shell=True)
        os.rename("{0}_temp.crt".format(ou), "{0}.crt".format(ou))
        os.rename("{0}_temp.p12".format(ou), "{0}.p12".format(ou))
        os.close(fd)
        os.remove(openssl_config)
        self.leaf_certs.append(ou)

    def __del__(self):
        RootCert.cleanup_certs([self.name])
        RootCert.cleanup_certs(self.leaf_certs)

    @staticmethod
    def cleanup_certs(names):
        for name in names:
            for ext in ["crt", "key", "csr", "srl", "p12"]:
                try:
                    os.remove('{0}.{1}'.format(name, ext))
                except OSError:
                    pass

def print_ok(msg):
    print(("\033[92m{0}\033[0m".format(msg)))

######################### Abstract #########################

class MySocket():
    def __init__(self):
        self.socket = None

    def get_socket(self):
        return self.socket

    def cleanup(self):
        self.socket = None  # automatically calls close()

######################### TCP #########################

class TcpClient(MySocket):
    def __init__(self, port):
        super().__init__()
        self.port = port

    def connect(self, attempts=1, msg=''):
        for i in range(0, attempts):
            try:
                self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.socket.settimeout(TIMEOUT)
                self.socket.connect((LOCALHOST, self.port))
                print_ok(msg)
                return
            except Exception as e:
                print(e)
            print(
                "failed to connect to {0}. Trying again...".format(self.port))
            time.sleep(1)

        raise Exception("Failed to connect to {0}".format(self.port))

class TcpServer(MySocket):
    def __init__(self, port):
        super().__init__()
        self.port = port
        self.listener = None

    def listen(self):
        self.listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.listener.settimeout(TIMEOUT)
        self.listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.listener.bind((LOCALHOST, self.port))
        self.listener.listen(1)

    def accept(self):
        self.socket, _ = self.listener.accept()
        self.socket.settimeout(TIMEOUT)
        self.listener.close()

    def cleanup(self):
        super().cleanup()
        self.listener = None

######################### TLS #########################

class TlsClient(MySocket):
    def __init__(self, cert, ca, port, ssl_version=ssl.PROTOCOL_SSLv23):
        super().__init__()
        self.cert = cert
        self.ca = ca
        self.port = port
        self.ssl_version = ssl_version
        self.tls_listener = None

    def connect(self, attempts=1, peer=None):
        for i in range(0, attempts):
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(TIMEOUT)
                if self.cert is not None:
                    self.socket = ssl.wrap_socket(sock,
                                                  keyfile='{0}.key'.format(
                                                      self.cert),
                                                  certfile='{0}.crt'.format(
                                                      self.cert),
                                                  ca_certs='{0}.crt'.format(
                                                      self.ca),
                                                  cert_reqs=ssl.CERT_REQUIRED,
                                                  ssl_version=self.ssl_version)
                else:
                    self.socket = ssl.wrap_socket(sock,
                                                  ca_certs='{0}.crt'.format(
                                                      self.ca),
                                                  cert_reqs=ssl.CERT_REQUIRED,
                                                  ssl_version=self.ssl_version)
                self.socket.connect((LOCALHOST, self.port))

                if peer is not None:
                    if self.socket.getpeercert()['subject'][3][0][1] == peer:
                        return self
                    else:
                        print("Did not connect to expected peer: {0}".format(
                            self.socket.getpeercert()))
                else:
                    return self
            except Exception as e:
                print(e)
                if attempts == 1:
                    raise e
            print("Trying to connect to {0}...".format(self.port))
            time.sleep(1)
        raise Exception("did not connect to peer")

class TlsServer(MySocket):
    def __init__(
            self,
            cert,
            ca,
            port,
            cert_reqs=ssl.CERT_REQUIRED,
            ssl_version=ssl.PROTOCOL_SSLv23):
        super().__init__()
        self.cert = cert
        self.ca = ca
        self.port = port
        self.cert_reqs = cert_reqs
        self.ssl_version = ssl_version
        self.tls_listener = None

    def listen(self):
        listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        listener.settimeout(TIMEOUT)
        listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        listener.bind((LOCALHOST, self.port))
        listener.listen(1)
        self.tls_listener = ssl.wrap_socket(listener,
                                            server_side=True,
                                            keyfile='{0}.key'.format(
                                                self.cert),
                                            certfile='{0}.crt'.format(
                                                self.cert),
                                            ca_certs='{0}.crt'.format(self.ca),
                                            cert_reqs=self.cert_reqs,
                                            ssl_version=self.ssl_version)

    def accept(self):
        self.socket, _ = self.tls_listener.accept()
        self.socket.settimeout(TIMEOUT)
        self.tls_listener.close()

    def validate_client_cert(self, ou):
        if self.socket.getpeercert()['subject'][3][0][1] == ou:
            return
        raise Exception("did not connect to expected peer: ",
                        self.socket.getpeercert())

    def cleanup(self):
        super().cleanup()
        self.tls_listener = None

######################### UNIX SOCKET #########################

class UnixClient(MySocket):
    def __init__(self):
        super().__init__()
        self.socket_path = os.path.join(mkdtemp(), 'ghostunnel-test-socket')

    def get_socket_path(self):
        return self.socket_path

    def connect(self, attempts=1, msg=''):
        for i in range(0, attempts):
            try:
                self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
                self.socket.settimeout(TIMEOUT)
                self.socket.connect(self.socket_path)
                print_ok(msg)
                return
            except Exception as e:
                print(e)
            print("failed to connect to {0}. Trying again...".format(
                self.socket_path))
            time.sleep(1)

        raise Exception("Failed to connect to {0}".format(self.socket_path))

    def cleanup(self):
        super().cleanup()
        self.socket = None
        os.remove(self.socket_path)
        os.rmdir(os.path.dirname(self.socket_path))

class UnixServer(MySocket):
    def __init__(self):
        super().__init__()
        self.socket_path = os.path.join(mkdtemp(), 'ghostunnel-test-socket')
        self.listener = None

    def get_socket_path(self):
        return self.socket_path

    def listen(self):
        self.listener = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        self.listener.settimeout(TIMEOUT)
        self.listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.listener.bind(self.socket_path)
        self.listener.listen(1)

    def accept(self):
        self.socket, _ = self.listener.accept()
        self.socket.settimeout(TIMEOUT)

    def cleanup(self):
        super().cleanup()
        self.listener = None
        os.remove(self.socket_path)

######################### SocketPair #########################

# This is whacky but works. This class represents a pair of sockets which
# correspond to each end of the tunnel. The class lets you verify that sending
# data in one socket shows up on the other. It also allows testing that closing
# one socket closes the other.

class SocketPair():
    def __init__(self, client, server):
        self.client = client
        self.server = server
        self.client_sock = None
        self.server_sock = None
        self.connect()

    def cleanup(self):
        self.client.cleanup()
        self.server.cleanup()

    def connect(self):
        # calling accept() on a socket blocks until a connection arrives. Ghostunnel
        # doesn't create the backend connection until a connection arrives. This
        # implies we either need to create threads or we create the server/client
        # sockets in a specific order.
        self.server.listen()

        # note: there might be a bug in the way we handle unix sockets. Ideally,
        # the check below should be the first thing we do in SocketPair().
        TcpClient(STATUS_PORT).connect(20)

        self.client.connect()
        self.server.accept()

    def validate_can_send_from_client(self, string, msg):
        encoded = bytes(string, 'utf-8')
        self.client.get_socket().send(encoded)
        data = self.server.get_socket().recv(len(encoded))
        if data != encoded:
            raise Exception("did not received expected string")
        print_ok(msg)

    def validate_can_send_from_server(self, string, msg):
        encoded = bytes(string, 'utf-8')
        self.server.get_socket().send(encoded)
        data = self.client.get_socket().recv(len(encoded))
        if data != encoded:
            raise Exception("did not received expected string")
        print_ok(msg)

    def validate_closing_client_closes_server(self, msg):
        self.client.get_socket().shutdown(socket.SHUT_RDWR)
        self.client.get_socket().close()
        # if the tunnel doesn't close the connection, recv(1) will raise a
        # Timeout
        self.server.get_socket().recv(1)

    def validate_closing_server_closes_client(self, msg):
        self.server.get_socket().shutdown(socket.SHUT_RDWR)
        self.server.get_socket().close()
        # if the tunnel doesn't close the connection, recv(1) will raise a
        # Timeout
        self.client.get_socket().recv(1)

    def validate_client_cert(self, ou, msg):
        for i in range(1, 20):
            try:
                self.server.validate_client_cert(ou)
                print_ok(msg)
                return
            except Exception as e:
                print(e)
            print("validate client cert failed, trying again...")
            time.sleep(1)
            self.cleanup()
            self.connect()
        raise Exception("did not connect to expected peer.")

    def validate_tunnel_ou(self, ou, msg):
        peercert = self.client.get_socket().getpeercert()
        if peercert['subject'][3][0][1] != ou:
            raise Exception("did not connect to expected peer: ", peercert)
        print_ok(msg)
<commit_msg>Clean up some comments into docstrings<commit_after>from subprocess import call, Popen
from tempfile import mkstemp, mkdtemp
import json
import sys
import time
import socket
import ssl
import os
import urllib.request

FNULL = open(os.devnull, 'w')
LOCALHOST = '127.0.0.1'
STATUS_PORT = 13100
TIMEOUT = 5

def run_ghostunnel(args):
    """Helper to run ghostunnel in integration test mode"""
    os.environ["GHOSTUNNEL_INTEGRATION_TEST"] = "true"
    os.environ["GHOSTUNNEL_INTEGRATION_ARGS"] = json.dumps(args)
    print_ok("running with args:\n {0}".format(' \ \n '.join(args)))
    test = os.path.basename(sys.argv[0]).replace('.py', '.out')
    return Popen([
        '../ghostunnel.test',
        '-test.run=TestIntegrationMain',
        '-test.coverprofile=coverage-{0}'.format(test)])

def terminate(ghostunnel):
    """Gracefully terminate ghostunnel (with timeout)"""
    print_ok("terminating ghostunnel instance")
    try:
        if ghostunnel:
            ghostunnel.terminate()
            for i in range(0, 10):
                try:
                    ghostunnel.wait(timeout=1)
                except BaseException:
                    pass
                if ghostunnel.returncode is not None:
                    print_ok("ghostunnel stopped with exit code {0}".format(
                        ghostunnel.returncode))
                    return
                time.sleep(1)
            print_ok("timeout, killing ghostunnel")
            ghostunnel.kill()
    except BaseException:
        pass

def dump_goroutines():
    """Attempt to dump goroutines via status port/pprof"""
    ctx = ssl.create_default_context()
    ctx.check_hostname = False
    ctx.verify_mode = ssl.CERT_NONE
    try:
        sys.stderr.buffer.write(urllib.request.urlopen(
            "https://{0}:{1}/debug/pprof/goroutine?debug=1".format(
                LOCALHOST, STATUS_PORT),
            context=ctx).read())
    except Exception as e:
        print('unable to dump goroutines:', e)

class RootCert:
    """Helper class to create root + signed certs"""
    def __init__(self, name):
        self.name = name
        self.leaf_certs = []
        print_ok("generating {0}.key, {0}.crt".format(name))
        call(
            'openssl genrsa -out {0}.key 1024'.format(name),
            shell=True,
            stderr=FNULL)
        call(
            'openssl req -x509 -new -key {0}.key -days 5 -out {0}_temp.crt -subj /C=US/ST=CA/O=ghostunnel/OU={0}'.format(name),
            shell=True)
        os.rename("{0}_temp.crt".format(name), "{0}.crt".format(name))
        call('chmod 600 {0}.key'.format(name), shell=True)

    def create_signed_cert(self, ou, san="IP:127.0.0.1,IP:::1,DNS:localhost"):
        print_ok("generating {0}.key, {0}.crt, {0}.p12".format(ou))
        fd, openssl_config = mkstemp(dir='.')
        os.write(fd, "extendedKeyUsage=clientAuth,serverAuth\n".encode('utf-8'))
        os.write(fd, "subjectAltName = {0}".format(san).encode('utf-8'))
        call("openssl genrsa -out {0}.key 1024".format(ou),
             shell=True, stderr=FNULL)
        call(
            "openssl req -new -key {0}.key -out {0}.csr -subj /C=US/ST=CA/O=ghostunnel/OU={0}".format(ou),
            shell=True,
            stderr=FNULL)
        call("chmod 600 {0}.key".format(ou), shell=True)
        call(
            "openssl x509 -req -in {0}.csr -CA {1}.crt -CAkey {1}.key -CAcreateserial -out {0}_temp.crt -days 5 -extfile {2}".format(
                ou,
                self.name,
                openssl_config),
            shell=True,
            stderr=FNULL)
        call(
            "openssl pkcs12 -export -out {0}_temp.p12 -in {0}_temp.crt -inkey {0}.key -password pass:".format(ou),
            shell=True)
        os.rename("{0}_temp.crt".format(ou), "{0}.crt".format(ou))
        os.rename("{0}_temp.p12".format(ou), "{0}.p12".format(ou))
        os.close(fd)
        os.remove(openssl_config)
        self.leaf_certs.append(ou)

    def __del__(self):
        RootCert.cleanup_certs([self.name])
        RootCert.cleanup_certs(self.leaf_certs)

    @staticmethod
    def cleanup_certs(names):
        for name in names:
            for ext in ["crt", "key", "csr", "srl", "p12"]:
                try:
                    os.remove('{0}.{1}'.format(name, ext))
                except OSError:
                    pass

def print_ok(msg):
    print(("\033[92m{0}\033[0m".format(msg)))

######################### Abstract #########################

class MySocket():
    def __init__(self):
        self.socket = None

    def get_socket(self):
        return self.socket

    def cleanup(self):
        self.socket = None  # automatically calls close()

######################### TCP #########################

class TcpClient(MySocket):
    def __init__(self, port):
        super().__init__()
        self.port = port

    def connect(self, attempts=1, msg=''):
        for i in range(0, attempts):
            try:
                self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                self.socket.settimeout(TIMEOUT)
                self.socket.connect((LOCALHOST, self.port))
                print_ok(msg)
                return
            except Exception as e:
                print(e)
            print(
                "failed to connect to {0}. Trying again...".format(self.port))
            time.sleep(1)

        raise Exception("Failed to connect to {0}".format(self.port))

class TcpServer(MySocket):
    def __init__(self, port):
        super().__init__()
        self.port = port
        self.listener = None

    def listen(self):
        self.listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.listener.settimeout(TIMEOUT)
        self.listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.listener.bind((LOCALHOST, self.port))
        self.listener.listen(1)

    def accept(self):
        self.socket, _ = self.listener.accept()
        self.socket.settimeout(TIMEOUT)
        self.listener.close()

    def cleanup(self):
        super().cleanup()
        self.listener = None

######################### TLS #########################

class TlsClient(MySocket):
    def __init__(self, cert, ca, port, ssl_version=ssl.PROTOCOL_SSLv23):
        super().__init__()
        self.cert = cert
        self.ca = ca
        self.port = port
        self.ssl_version = ssl_version
        self.tls_listener = None

    def connect(self, attempts=1, peer=None):
        for i in range(0, attempts):
            try:
                sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                sock.settimeout(TIMEOUT)
                if self.cert is not None:
                    self.socket = ssl.wrap_socket(sock,
                                                  keyfile='{0}.key'.format(
                                                      self.cert),
                                                  certfile='{0}.crt'.format(
                                                      self.cert),
                                                  ca_certs='{0}.crt'.format(
                                                      self.ca),
                                                  cert_reqs=ssl.CERT_REQUIRED,
                                                  ssl_version=self.ssl_version)
                else:
                    self.socket = ssl.wrap_socket(sock,
                                                  ca_certs='{0}.crt'.format(
                                                      self.ca),
                                                  cert_reqs=ssl.CERT_REQUIRED,
                                                  ssl_version=self.ssl_version)
                self.socket.connect((LOCALHOST, self.port))

                if peer is not None:
                    if self.socket.getpeercert()['subject'][3][0][1] == peer:
                        return self
                    else:
                        print("Did not connect to expected peer: {0}".format(
                            self.socket.getpeercert()))
                else:
                    return self
            except Exception as e:
                print(e)
                if attempts == 1:
                    raise e
            print("Trying to connect to {0}...".format(self.port))
            time.sleep(1)
        raise Exception("did not connect to peer")

class TlsServer(MySocket):
    def __init__(
            self,
            cert,
            ca,
            port,
            cert_reqs=ssl.CERT_REQUIRED,
            ssl_version=ssl.PROTOCOL_SSLv23):
        super().__init__()
        self.cert = cert
        self.ca = ca
        self.port = port
        self.cert_reqs = cert_reqs
        self.ssl_version = ssl_version
        self.tls_listener = None

    def listen(self):
        listener = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        listener.settimeout(TIMEOUT)
        listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        listener.bind((LOCALHOST, self.port))
        listener.listen(1)
        self.tls_listener = ssl.wrap_socket(listener,
                                            server_side=True,
                                            keyfile='{0}.key'.format(
                                                self.cert),
                                            certfile='{0}.crt'.format(
                                                self.cert),
                                            ca_certs='{0}.crt'.format(self.ca),
                                            cert_reqs=self.cert_reqs,
                                            ssl_version=self.ssl_version)

    def accept(self):
        self.socket, _ = self.tls_listener.accept()
        self.socket.settimeout(TIMEOUT)
        self.tls_listener.close()

    def validate_client_cert(self, ou):
        if self.socket.getpeercert()['subject'][3][0][1] == ou:
            return
        raise Exception("did not connect to expected peer: ",
                        self.socket.getpeercert())

    def cleanup(self):
        super().cleanup()
        self.tls_listener = None

######################### UNIX SOCKET #########################

class UnixClient(MySocket):
    def __init__(self):
        super().__init__()
        self.socket_path = os.path.join(mkdtemp(), 'ghostunnel-test-socket')

    def get_socket_path(self):
        return self.socket_path

    def connect(self, attempts=1, msg=''):
        for i in range(0, attempts):
            try:
                self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
                self.socket.settimeout(TIMEOUT)
                self.socket.connect(self.socket_path)
                print_ok(msg)
                return
            except Exception as e:
                print(e)
            print("failed to connect to {0}. Trying again...".format(
                self.socket_path))
            time.sleep(1)

        raise Exception("Failed to connect to {0}".format(self.socket_path))

    def cleanup(self):
        super().cleanup()
        self.socket = None
        os.remove(self.socket_path)
        os.rmdir(os.path.dirname(self.socket_path))

class UnixServer(MySocket):
    def __init__(self):
        super().__init__()
        self.socket_path = os.path.join(mkdtemp(), 'ghostunnel-test-socket')
        self.listener = None

    def get_socket_path(self):
        return self.socket_path

    def listen(self):
        self.listener = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
        self.listener.settimeout(TIMEOUT)
        self.listener.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.listener.bind(self.socket_path)
        self.listener.listen(1)

    def accept(self):
        self.socket, _ = self.listener.accept()
        self.socket.settimeout(TIMEOUT)

    def cleanup(self):
        super().cleanup()
        self.listener = None
        os.remove(self.socket_path)

######################### SocketPair #########################

# This is whacky but works. This class represents a pair of sockets which
# correspond to each end of the tunnel. The class lets you verify that sending
# data in one socket shows up on the other. It also allows testing that closing
# one socket closes the other.

class SocketPair():
    def __init__(self, client, server):
        self.client = client
        self.server = server
        self.client_sock = None
        self.server_sock = None
        self.connect()

    def cleanup(self):
        self.client.cleanup()
        self.server.cleanup()

    def connect(self):
        # calling accept() on a socket blocks until a connection arrives. Ghostunnel
        # doesn't create the backend connection until a connection arrives. This
        # implies we either need to create threads or we create the server/client
        # sockets in a specific order.
        self.server.listen()

        # note: there might be a bug in the way we handle unix sockets. Ideally,
        # the check below should be the first thing we do in SocketPair().
        TcpClient(STATUS_PORT).connect(20)

        self.client.connect()
        self.server.accept()

    def validate_can_send_from_client(self, string, msg):
        encoded = bytes(string, 'utf-8')
        self.client.get_socket().send(encoded)
        data = self.server.get_socket().recv(len(encoded))
        if data != encoded:
            raise Exception("did not received expected string")
        print_ok(msg)

    def validate_can_send_from_server(self, string, msg):
        encoded = bytes(string, 'utf-8')
        self.server.get_socket().send(encoded)
        data = self.client.get_socket().recv(len(encoded))
        if data != encoded:
            raise Exception("did not received expected string")
        print_ok(msg)

    def validate_closing_client_closes_server(self, msg):
        self.client.get_socket().shutdown(socket.SHUT_RDWR)
        self.client.get_socket().close()
        # if the tunnel doesn't close the connection, recv(1) will raise a
        # Timeout
        self.server.get_socket().recv(1)

    def validate_closing_server_closes_client(self, msg):
        self.server.get_socket().shutdown(socket.SHUT_RDWR)
        self.server.get_socket().close()
        # if the tunnel doesn't close the connection, recv(1) will raise a
        # Timeout
        self.client.get_socket().recv(1)

    def validate_client_cert(self, ou, msg):
        for i in range(1, 20):
            try:
                self.server.validate_client_cert(ou)
                print_ok(msg)
                return
            except Exception as e:
                print(e)
            print("validate client cert failed, trying again...")
            time.sleep(1)
            self.cleanup()
            self.connect()
        raise Exception("did not connect to expected peer.")

    def validate_tunnel_ou(self, ou, msg):
        peercert = self.client.get_socket().getpeercert()
        if peercert['subject'][3][0][1] != ou:
            raise Exception("did not connect to expected peer: ", peercert)
        print_ok(msg)
<|endoftext|>


<commit_before>import os
from os.path import join

from spec import Spec, skip, eq_, ok_, raises

from invoke.vendor.etcaetera.adapter import File, Adapter

from invoke.config import Config
from invoke.exceptions import AmbiguousEnvVar

from _utils import CleanEnvSpec

def _loads_path(c, path):
    files = [x for x in c.config.adapters if isinstance(x, File)]
    paths = [x.filepath for x in files]
    found = any(x == path for x in paths)
    ok_(found, "{0!r} not found, file adapters: {1!r}".format(path, paths))

CONFIGS_PATH = join('tests', '_support', 'configs')

def _load(key, path):
    path = join(CONFIGS_PATH, key, path)
    c = Config(**{'{0}_prefix'.format(key): path})
    c.load()
    return c

class Config_(CleanEnvSpec):
    class init:
        "__init__"

        def can_be_empty(self):
            eq_(Config().__class__, Config) # derp

        def configure_global_location_prefix(self):
            # This is a bit funky but more useful than just replicating the
            # same test farther down?
            c = Config(global_prefix='meh')
            _loads_path(c, 'meh.yaml')

        def default_global_prefix_is_etc(self):
            # TODO: make this work on Windows somehow without being a total
            # tautology? heh.
            _loads_path(Config(), '/etc/invoke.yaml')

        def configure_user_location_prefix(self):
            c = Config(user_prefix='whatever')
            _loads_path(c, 'whatever.yaml')

        def default_user_prefix_is_homedir(self):
            _loads_path(Config(), '~/.invoke.yaml')

        def configure_project_location(self):
            c = Config(project_home='someproject')
            _loads_path(c, 'someproject/invoke.yaml')

        def configure_runtime_path(self):
            c = Config(runtime_path='some/path.yaml')
            _loads_path(c, 'some/path.yaml')

        def accepts_explicit_adapter_override_list(self):
            c = Config(adapters=[])
            # Slightly encapsulation-breaking. Meh.
            eq_(len(c.config.adapters), 0)

        def accepts_overrides_dict(self):
            c = Config(overrides={'I win': 'always'})
            c.load()
            eq_(c['I win'], 'always')

        def does_not_trigger_config_loading(self):
            # Cuz automatic loading could potentially be surprising.
            # Meh-tastic no-exception-raised test.
            class DummyAdapter(Adapter):
                def load(self, *args, **kwargs):
                    raise Exception("I shouldn't have been called!")
            c = Config(adapters=[DummyAdapter()])

    class basic_API:
        "Basic API components"

        class load:
            "load()"
            # TODO: rename?
            def can_be_called_empty(self):
                c = Config()
                c.load()
                eq_(c.keys(), [])

            def can_be_given_defaults_dict_arg(self):
                c = Config()
                c.load(defaults={'foo': 'bar'})
                eq_(c.foo, 'bar')

            def makes_data_available(self):
                c = Config(overrides={'foo': 'notbar'})
                ok_('foo' not in c.keys())
                c.load()
                ok_('foo' in c.keys())

        def allows_dict_and_attr_access(self):
            # TODO: combine with tests for Context probably
            c = Config({'foo': 'bar'})
            c.load()
            eq_(c.foo, 'bar')
            eq_(c['foo'], 'bar')

        def nested_dict_values_also_allow_dual_access(self):
            # TODO: ditto
            c = Config({'foo': 'bar', 'biz': {'baz': 'boz'}})
            c.load()
            # Sanity check - nested doesn't somehow kill simple top level
            eq_(c.foo, 'bar')
            eq_(c['foo'], 'bar')
            # Actual check
            eq_(c.biz.baz, 'boz')
            eq_(c['biz']['baz'], 'boz')
            eq_(c.biz['baz'], 'boz')
            eq_(c['biz'].baz, 'boz')

        def attr_access_has_useful_errr_msg(self):
            c = Config()
            c.load()
            try:
                c.nope
            except AttributeError as e:
                expected = """
No attribute or config key found for 'nope'

Valid real attributes: ['clone', 'from_data', 'load']

Valid keys: []""".lstrip()
                eq_(str(e), expected)
            else:
                assert False, "Didn't get an AttributeError on bad key!"

        def loaded_keys_are_not_case_munged(self):
            # Looks tautological, but ensures we're suppressing etcaetera's
            # default UPPERCASE_EVERYTHING behavior
            d = {'FOO': 'bar', 'biz': 'baz', 'Boz': 'buzz'}
            c = Config(d)
            c.load()
            for x in d:
                err = "Expected to find {0!r} in {1!r}, didn't"
                ok_(x in c, err.format(x, c.keys()))

        def is_iterable_like_dict(self):
            def expect(c, expected):
                eq_(set(c.keys()), expected)
                eq_(set(list(c)), expected)
            c = Config({'a': 1, 'b': 2})
            expect(c, set())
            c.load()
            expect(c, set(['a', 'b']))

        def supports_readonly_dict_protocols(self):
            # Use single-keypair dict to avoid sorting problems in tests.
            c = Config({'foo': 'bar'})
            c2 = Config({'foo': 'bar'})
            c.load()
            c2.load()
            ok_('foo' in c)
            eq_(c, c2)
            eq_(len(c), 1)
            eq_(c.get('foo'), 'bar')
            eq_(c.has_key('foo'), True)
            eq_(c.items(), [('foo', 'bar')])
            eq_(list(c.iteritems()), [('foo', 'bar')])
            eq_(list(c.iterkeys()), ['foo'])
            eq_(list(c.itervalues()), ['bar'])
            eq_(c.keys(), ['foo'])
            eq_(c.values(), ['bar'])

        def supports_mutation_dict_protocols(self):
            c = Config({'foo': 'bar'})
            c.load()
            eq_(c.pop('foo'), 'bar')
            eq_(len(c), 0)
            c.setdefault('biz', 'baz')
            eq_(c['biz'], 'baz')
            c['boz'] = 'buzz'
            eq_(len(c), 2)
            del c['boz']
            eq_(len(c), 1)
            ok_('boz' not in c)
            eq_(c.popitem(), ('biz', 'baz'))
            eq_(len(c), 0)
            c.update({'foo': 'bar'})
            eq_(c['foo'], 'bar')

    def python_modules_load_lowercase_but_not_special_vars(self):
        # Borrow another test's Python module.
        c = _load('global', join('python-only', 'invoke'))
        # Sanity test that lowercase works
        eq_(c.hooray, 'python')
        # Real test that builtins, etc are stripped out
        for special in ('builtins', 'file', 'package', 'name', 'doc'):
            ok_('__{0}__'.format(special) not in c)

    class system_global:
        "Systemwide conf file"
        def yaml_first(self):
            c = _load('global', join('yaml-only', 'invoke'))
            eq_(c.hooray, 'yaml')

        def json_if_no_yaml(self):
            c = _load('global', join('json-only', 'invoke'))
            eq_(c.hooray, 'json')

        def python_if_no_json_or_yaml(self):
            c = _load('global', join('python-only', 'invoke'))
            eq_(c.hooray, 'python')

    class user_specific:
        "User-specific conf file"
        def yaml_first(self):
            c = _load('user', join('yaml-only', '.invoke'))
            eq_(c.user, 'yaml')

        def json_if_no_yaml(self):
            c = _load('user', join('json-only', '.invoke'))
            eq_(c.user, 'json')

        def python_if_no_json_or_yaml(self):
            c = _load('user', join('python-only', '.invoke'))
            eq_(c.user, 'python')

    class project_specific:
        "Local-to-project conf file"
        def yaml_first(self):
            c = Config(project_home=join(CONFIGS_PATH, 'project', 'yaml-only'))
            c.load()
            eq_(c.project_setting, 'yaml')

        def json_if_no_yaml(self):
            c = Config(project_home=join(CONFIGS_PATH, 'project', 'json-only'))
            c.load()
            eq_(c.project_setting, 'json')

        def python_if_no_json_or_yaml(self):
            c = Config(project_home=join(CONFIGS_PATH, 'project', 'py-only'))
            c.load()
            eq_(c.project_setting, 'python')

        def loads_nothing_if_no_project_home_given(self):
            c = Config()
            c.load()
            eq_(c.keys(), [])

    def honors_conf_file_flag(self):
        c = Config(runtime_path=join(CONFIGS_PATH, 'runtime', 'runtime.yaml'))
        c.load()
        eq_(c["what time?"], "run time!")

    class env_vars:
        "Environment variables"
        def base_case(self):
            os.environ['FOO'] = 'bar'
            c = Config()
            c.load(defaults={'foo': 'notbar'})
            eq_(c.foo, 'bar')

        def non_predeclared_settings_do_not_get_consumed(self):
            os.environ['HELLO'] = "is it me you're looking for?"
            c = Config()
            c.load()
            ok_('HELLO' not in c)
            ok_('hello' not in c)

        def underscores_top_level(self):
            os.environ['FOO_BAR'] = 'biz'
            c = Config()
            c.load(defaults={'foo_bar': 'notbiz'})
            eq_(c.foo_bar, 'biz')

        def underscores_nested(self):
            os.environ['FOO_BAR'] = 'biz'
            c = Config()
            c.load(defaults={'foo': {'bar': 'notbiz'}})
            eq_(c.foo.bar, 'biz')

        def both_types_of_underscores_mixed(self):
            os.environ['FOO_BAR_BIZ'] = 'baz'
            c = Config()
            c.load(defaults={'foo_bar': {'biz': 'notbaz'}})
            eq_(c.foo_bar.biz, 'baz')

        @raises(AmbiguousEnvVar)
        def ambiguous_underscores_dont_guess(self):
            os.environ['FOO_BAR'] = 'biz'
            c = Config()
            c.load(defaults={'foo_bar': 'wat', 'foo': {'bar': 'huh'}})

        class type_casting:
            def strings_replaced_with_env_value(self):
                os.environ['FOO'] = u'myvalue'
                c = Config()
                c.load(defaults={'foo': 'myoldvalue'})
                eq_(c.foo, u'myvalue')
                ok_(isinstance(c.foo, unicode)) # FIXME: py3

            def unicode_replaced_with_env_value(self):
                os.environ['FOO'] = 'myunicode'
                c = Config()
                c.load(defaults={'foo': u'myoldvalue'})
                eq_(c.foo, 'myunicode')
                ok_(isinstance(c.foo, str)) # FIXME: py3

            def None_replaced(self):
                skip()

            def booleans(self):
                # 0 and empty-string -> false
                # all other values true
                # 'false' string is true
                skip()

            def lists_raise_exception(self):
                skip()

            def dicts_raise_exception(self):
                skip()

            def numeric_types_become_casted(self):
                # int
                # float
                # long
                # ???
                skip()

    class hierarchy:
        "Config hierarchy in effect"
        def systemwide_overrides_collection(self):
            skip()

        def user_overrides_systemwide(self):
            skip()

        def user_overrides_collection(self):
            skip()

        def project_overrides_user(self):
            skip()

        def project_overrides_systemwide(self):
            skip()

        def project_overrides_collection(self):
            skip()

        def env_vars_override_project(self):
            skip()

        def env_vars_override_user(self):
            skip()

        def env_vars_override_systemwide(self):
            skip()

        def env_vars_override_collection(self):
            skip()

        def runtime_overrides_env_vars(self):
            skip()

        def runtime_overrides_project(self):
            skip()

        def runtime_overrides_user(self):
            skip()

        def runtime_overrides_systemwide(self):
            skip()

        def runtime_overrides_collection(self):
            skip()

        def e_flag_overrides_all(self):
            "-e overrides run.echo for all other layers"
            skip()

    class clone:
        def setup(self):
            self.c = Config({'foo': {'bar': {'biz': ['baz']}}})

        def load_before_and_after(self):
            c = self.c
            c.load()
            c2 = c.clone()
            c2.load()
            eq_(c, c2)
            ok_(c is not c2)
            ok_(c.config is not c2.config)
            eq_(c.foo.bar.biz, c2.foo.bar.biz)
            ok_(c.foo.bar.biz is not c2.foo.bar.biz)

        def no_loading_at_all(self):
            c = self.c
            c2 = c.clone()
            eq_(c, c2)
            ok_(c is not c2)
            ok_(c.config is not c2.config)
            # Unloaded -> looks empty
            eq_(c.keys(), [])
            eq_(c2.keys(), [])

        def load_after_only(self):
            c = self.c
            c2 = c.clone()
            c2.load()
            eq_(c2.foo.bar.biz, ['baz'])
<commit_msg>Failing typecast tests started<commit_after>import os
from os.path import join

from spec import Spec, skip, eq_, ok_, raises

from invoke.vendor.etcaetera.adapter import File, Adapter

from invoke.config import Config
from invoke.exceptions import AmbiguousEnvVar

from _utils import CleanEnvSpec

def _loads_path(c, path):
    files = [x for x in c.config.adapters if isinstance(x, File)]
    paths = [x.filepath for x in files]
    found = any(x == path for x in paths)
    ok_(found, "{0!r} not found, file adapters: {1!r}".format(path, paths))

CONFIGS_PATH = join('tests', '_support', 'configs')

def _load(key, path):
    path = join(CONFIGS_PATH, key, path)
    c = Config(**{'{0}_prefix'.format(key): path})
    c.load()
    return c

class Config_(CleanEnvSpec):
    class init:
        "__init__"

        def can_be_empty(self):
            eq_(Config().__class__, Config) # derp

        def configure_global_location_prefix(self):
            # This is a bit funky but more useful than just replicating the
            # same test farther down?
            c = Config(global_prefix='meh')
            _loads_path(c, 'meh.yaml')

        def default_global_prefix_is_etc(self):
            # TODO: make this work on Windows somehow without being a total
            # tautology? heh.
            _loads_path(Config(), '/etc/invoke.yaml')

        def configure_user_location_prefix(self):
            c = Config(user_prefix='whatever')
            _loads_path(c, 'whatever.yaml')

        def default_user_prefix_is_homedir(self):
            _loads_path(Config(), '~/.invoke.yaml')

        def configure_project_location(self):
            c = Config(project_home='someproject')
            _loads_path(c, 'someproject/invoke.yaml')

        def configure_runtime_path(self):
            c = Config(runtime_path='some/path.yaml')
            _loads_path(c, 'some/path.yaml')

        def accepts_explicit_adapter_override_list(self):
            c = Config(adapters=[])
            # Slightly encapsulation-breaking. Meh.
            eq_(len(c.config.adapters), 0)

        def accepts_overrides_dict(self):
            c = Config(overrides={'I win': 'always'})
            c.load()
            eq_(c['I win'], 'always')

        def does_not_trigger_config_loading(self):
            # Cuz automatic loading could potentially be surprising.
            # Meh-tastic no-exception-raised test.
            class DummyAdapter(Adapter):
                def load(self, *args, **kwargs):
                    raise Exception("I shouldn't have been called!")
            c = Config(adapters=[DummyAdapter()])

    class basic_API:
        "Basic API components"

        class load:
            "load()"
            # TODO: rename?
            def can_be_called_empty(self):
                c = Config()
                c.load()
                eq_(c.keys(), [])

            def can_be_given_defaults_dict_arg(self):
                c = Config()
                c.load(defaults={'foo': 'bar'})
                eq_(c.foo, 'bar')

            def makes_data_available(self):
                c = Config(overrides={'foo': 'notbar'})
                ok_('foo' not in c.keys())
                c.load()
                ok_('foo' in c.keys())

        def allows_dict_and_attr_access(self):
            # TODO: combine with tests for Context probably
            c = Config({'foo': 'bar'})
            c.load()
            eq_(c.foo, 'bar')
            eq_(c['foo'], 'bar')

        def nested_dict_values_also_allow_dual_access(self):
            # TODO: ditto
            c = Config({'foo': 'bar', 'biz': {'baz': 'boz'}})
            c.load()
            # Sanity check - nested doesn't somehow kill simple top level
            eq_(c.foo, 'bar')
            eq_(c['foo'], 'bar')
            # Actual check
            eq_(c.biz.baz, 'boz')
            eq_(c['biz']['baz'], 'boz')
            eq_(c.biz['baz'], 'boz')
            eq_(c['biz'].baz, 'boz')

        def attr_access_has_useful_errr_msg(self):
            c = Config()
            c.load()
            try:
                c.nope
            except AttributeError as e:
                expected = """
No attribute or config key found for 'nope'

Valid real attributes: ['clone', 'from_data', 'load']

Valid keys: []""".lstrip()
                eq_(str(e), expected)
            else:
                assert False, "Didn't get an AttributeError on bad key!"

        def loaded_keys_are_not_case_munged(self):
            # Looks tautological, but ensures we're suppressing etcaetera's
            # default UPPERCASE_EVERYTHING behavior
            d = {'FOO': 'bar', 'biz': 'baz', 'Boz': 'buzz'}
            c = Config(d)
            c.load()
            for x in d:
                err = "Expected to find {0!r} in {1!r}, didn't"
                ok_(x in c, err.format(x, c.keys()))

        def is_iterable_like_dict(self):
            def expect(c, expected):
                eq_(set(c.keys()), expected)
                eq_(set(list(c)), expected)
            c = Config({'a': 1, 'b': 2})
            expect(c, set())
            c.load()
            expect(c, set(['a', 'b']))

        def supports_readonly_dict_protocols(self):
            # Use single-keypair dict to avoid sorting problems in tests.
            c = Config({'foo': 'bar'})
            c2 = Config({'foo': 'bar'})
            c.load()
            c2.load()
            ok_('foo' in c)
            eq_(c, c2)
            eq_(len(c), 1)
            eq_(c.get('foo'), 'bar')
            eq_(c.has_key('foo'), True)
            eq_(c.items(), [('foo', 'bar')])
            eq_(list(c.iteritems()), [('foo', 'bar')])
            eq_(list(c.iterkeys()), ['foo'])
            eq_(list(c.itervalues()), ['bar'])
            eq_(c.keys(), ['foo'])
            eq_(c.values(), ['bar'])

        def supports_mutation_dict_protocols(self):
            c = Config({'foo': 'bar'})
            c.load()
            eq_(c.pop('foo'), 'bar')
            eq_(len(c), 0)
            c.setdefault('biz', 'baz')
            eq_(c['biz'], 'baz')
            c['boz'] = 'buzz'
            eq_(len(c), 2)
            del c['boz']
            eq_(len(c), 1)
            ok_('boz' not in c)
            eq_(c.popitem(), ('biz', 'baz'))
            eq_(len(c), 0)
            c.update({'foo': 'bar'})
            eq_(c['foo'], 'bar')

    def python_modules_load_lowercase_but_not_special_vars(self):
        # Borrow another test's Python module.
        c = _load('global', join('python-only', 'invoke'))
        # Sanity test that lowercase works
        eq_(c.hooray, 'python')
        # Real test that builtins, etc are stripped out
        for special in ('builtins', 'file', 'package', 'name', 'doc'):
            ok_('__{0}__'.format(special) not in c)

    class system_global:
        "Systemwide conf file"
        def yaml_first(self):
            c = _load('global', join('yaml-only', 'invoke'))
            eq_(c.hooray, 'yaml')

        def json_if_no_yaml(self):
            c = _load('global', join('json-only', 'invoke'))
            eq_(c.hooray, 'json')

        def python_if_no_json_or_yaml(self):
            c = _load('global', join('python-only', 'invoke'))
            eq_(c.hooray, 'python')

    class user_specific:
        "User-specific conf file"
        def yaml_first(self):
            c = _load('user', join('yaml-only', '.invoke'))
            eq_(c.user, 'yaml')

        def json_if_no_yaml(self):
            c = _load('user', join('json-only', '.invoke'))
            eq_(c.user, 'json')

        def python_if_no_json_or_yaml(self):
            c = _load('user', join('python-only', '.invoke'))
            eq_(c.user, 'python')

    class project_specific:
        "Local-to-project conf file"
        def yaml_first(self):
            c = Config(project_home=join(CONFIGS_PATH, 'project', 'yaml-only'))
            c.load()
            eq_(c.project_setting, 'yaml')

        def json_if_no_yaml(self):
            c = Config(project_home=join(CONFIGS_PATH, 'project', 'json-only'))
            c.load()
            eq_(c.project_setting, 'json')

        def python_if_no_json_or_yaml(self):
            c = Config(project_home=join(CONFIGS_PATH, 'project', 'py-only'))
            c.load()
            eq_(c.project_setting, 'python')

        def loads_nothing_if_no_project_home_given(self):
            c = Config()
            c.load()
            eq_(c.keys(), [])

    def honors_conf_file_flag(self):
        c = Config(runtime_path=join(CONFIGS_PATH, 'runtime', 'runtime.yaml'))
        c.load()
        eq_(c["what time?"], "run time!")

    class env_vars:
        "Environment variables"
        def base_case(self):
            os.environ['FOO'] = 'bar'
            c = Config()
            c.load(defaults={'foo': 'notbar'})
            eq_(c.foo, 'bar')

        def non_predeclared_settings_do_not_get_consumed(self):
            os.environ['HELLO'] = "is it me you're looking for?"
            c = Config()
            c.load()
            ok_('HELLO' not in c)
            ok_('hello' not in c)

        def underscores_top_level(self):
            os.environ['FOO_BAR'] = 'biz'
            c = Config()
            c.load(defaults={'foo_bar': 'notbiz'})
            eq_(c.foo_bar, 'biz')

        def underscores_nested(self):
            os.environ['FOO_BAR'] = 'biz'
            c = Config()
            c.load(defaults={'foo': {'bar': 'notbiz'}})
            eq_(c.foo.bar, 'biz')

        def both_types_of_underscores_mixed(self):
            os.environ['FOO_BAR_BIZ'] = 'baz'
            c = Config()
            c.load(defaults={'foo_bar': {'biz': 'notbaz'}})
            eq_(c.foo_bar.biz, 'baz')

        @raises(AmbiguousEnvVar)
        def ambiguous_underscores_dont_guess(self):
            os.environ['FOO_BAR'] = 'biz'
            c = Config()
            c.load(defaults={'foo_bar': 'wat', 'foo': {'bar': 'huh'}})

        class type_casting:
            def strings_replaced_with_env_value(self):
                os.environ['FOO'] = u'myvalue'
                c = Config()
                c.load(defaults={'foo': 'myoldvalue'})
                eq_(c.foo, u'myvalue')
                ok_(isinstance(c.foo, unicode)) # FIXME: py3

            def unicode_replaced_with_env_value(self):
                os.environ['FOO'] = 'myunicode'
                c = Config()
                c.load(defaults={'foo': u'myoldvalue'})
                eq_(c.foo, 'myunicode')
                ok_(isinstance(c.foo, str)) # FIXME: py3

            def None_replaced(self):
                os.environ['FOO'] = 'something'
                c = Config()
                c.load(defaults={'foo': None})
                eq_(c.foo, 'something')

            def booleans(self):
                for input_, result in (
                    ('0', False),
                    ('1', True),
                    ('', False),
                    ('meh', True),
                    ('false', True),
                ):
                    os.environ['FOO'] = input_
                    c = Config()
                    c.load(defaults={'foo': bool()})
                    eq_(c.foo, result)

            def boolean_type_inputs_with_non_boolean_defaults(self):
                # when existing value is NOT boolean, the above all become
                # normal or follow other rules
                skip()

            def lists_raise_exception(self):
                skip()

            def dicts_raise_exception(self):
                skip()

            def numeric_types_become_casted(self):
                # int
                # float
                # long
                # ???
                skip()

    class hierarchy:
        "Config hierarchy in effect"
        def systemwide_overrides_collection(self):
            skip()

        def user_overrides_systemwide(self):
            skip()

        def user_overrides_collection(self):
            skip()

        def project_overrides_user(self):
            skip()

        def project_overrides_systemwide(self):
            skip()

        def project_overrides_collection(self):
            skip()

        def env_vars_override_project(self):
            skip()

        def env_vars_override_user(self):
            skip()

        def env_vars_override_systemwide(self):
            skip()

        def env_vars_override_collection(self):
            skip()

        def runtime_overrides_env_vars(self):
            skip()

        def runtime_overrides_project(self):
            skip()

        def runtime_overrides_user(self):
            skip()

        def runtime_overrides_systemwide(self):
            skip()

        def runtime_overrides_collection(self):
            skip()

        def e_flag_overrides_all(self):
            "-e overrides run.echo for all other layers"
            skip()

    class clone:
        def setup(self):
            self.c = Config({'foo': {'bar': {'biz': ['baz']}}})

        def load_before_and_after(self):
            c = self.c
            c.load()
            c2 = c.clone()
            c2.load()
            eq_(c, c2)
            ok_(c is not c2)
            ok_(c.config is not c2.config)
            eq_(c.foo.bar.biz, c2.foo.bar.biz)
            ok_(c.foo.bar.biz is not c2.foo.bar.biz)

        def no_loading_at_all(self):
            c = self.c
            c2 = c.clone()
            eq_(c, c2)
            ok_(c is not c2)
            ok_(c.config is not c2.config)
            # Unloaded -> looks empty
            eq_(c.keys(), [])
            eq_(c2.keys(), [])

        def load_after_only(self):
            c = self.c
            c2 = c.clone()
            c2.load()
            eq_(c2.foo.bar.biz, ['baz'])
<|endoftext|>


<commit_before>from __future__ import unicode_literals

from django.db import models
from django.utils.encoding import python_2_unicode_compatible

from modelcluster.tags import ClusterTaggableManager
from taggit.models import TaggedItemBase

from modelcluster.fields import ParentalKey
from modelcluster.models import ClusterableModel

@python_2_unicode_compatible
class Band(ClusterableModel):
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name

@python_2_unicode_compatible
class BandMember(models.Model):
    band = ParentalKey('Band', related_name='members')
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name

@python_2_unicode_compatible
class Album(models.Model):
    band = ParentalKey('Band', related_name='albums')
    name = models.CharField(max_length=255)
    release_date = models.DateField(null=True, blank=True)
    sort_order = models.IntegerField(null=True, blank=True, editable=False)

    sort_order_field = 'sort_order'

    def __str__(self):
        return self.name

    class Meta:
        ordering = ['sort_order']

class TaggedPlace(TaggedItemBase):
    content_object = ParentalKey('Place', related_name='tagged_items')

@python_2_unicode_compatible
class Place(ClusterableModel):
    name = models.CharField(max_length=255)
    tags = ClusterTaggableManager(through=TaggedPlace, blank=True)

    def __str__(self):
        return self.name

class Restaurant(Place):
    serves_hot_dogs = models.BooleanField(default=False)
    proprietor = models.ForeignKey('Chef', null=True, blank=True, on_delete=models.SET_NULL, related_name='restaurants')

@python_2_unicode_compatible
class Dish(models.Model):
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name

@python_2_unicode_compatible
class Wine(models.Model):
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name

@python_2_unicode_compatible
class Chef(models.Model):
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name

@python_2_unicode_compatible
class MenuItem(models.Model):
    restaurant = ParentalKey('Restaurant', related_name='menu_items')
    dish = models.ForeignKey('Dish', related_name='+')
    price = models.DecimalField(max_digits=6, decimal_places=2)
    recommended_wine = models.ForeignKey('Wine', null=True, blank=True, on_delete=models.SET_NULL, related_name='+')

    def __str__(self):
        return "%s - %f" % (self.dish, self.price)

@python_2_unicode_compatible
class Review(models.Model):
    place = ParentalKey('Place', related_name='reviews')
    author = models.CharField(max_length=255)
    body = models.TextField()

    def __str__(self):
        return "%s on %s" % (self.author, self.place.name)

@python_2_unicode_compatible
class Log(ClusterableModel):
    time = models.DateTimeField(blank=True, null=True)
    data = models.CharField(max_length=255)

    def __str__(self):
        return "[%s] %s" % (self.time.isoformat(), self.data)
<commit_msg>Update test models<commit_after>from __future__ import unicode_literals

from django.db import models
from django.utils.encoding import python_2_unicode_compatible

from modelcluster.contrib.taggit import ClusterTaggableManager
from taggit.models import TaggedItemBase

from modelcluster.fields import ParentalKey
from modelcluster.models import ClusterableModel

@python_2_unicode_compatible
class Band(ClusterableModel):
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name

@python_2_unicode_compatible
class BandMember(models.Model):
    band = ParentalKey('Band', related_name='members')
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name

@python_2_unicode_compatible
class Album(models.Model):
    band = ParentalKey('Band', related_name='albums')
    name = models.CharField(max_length=255)
    release_date = models.DateField(null=True, blank=True)
    sort_order = models.IntegerField(null=True, blank=True, editable=False)

    sort_order_field = 'sort_order'

    def __str__(self):
        return self.name

    class Meta:
        ordering = ['sort_order']

class TaggedPlace(TaggedItemBase):
    content_object = ParentalKey('Place', related_name='tagged_items')

@python_2_unicode_compatible
class Place(ClusterableModel):
    name = models.CharField(max_length=255)
    tags = ClusterTaggableManager(through=TaggedPlace, blank=True)

    def __str__(self):
        return self.name

class Restaurant(Place):
    serves_hot_dogs = models.BooleanField(default=False)
    proprietor = models.ForeignKey('Chef', null=True, blank=True, on_delete=models.SET_NULL, related_name='restaurants')

@python_2_unicode_compatible
class Dish(models.Model):
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name

@python_2_unicode_compatible
class Wine(models.Model):
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name

@python_2_unicode_compatible
class Chef(models.Model):
    name = models.CharField(max_length=255)

    def __str__(self):
        return self.name

@python_2_unicode_compatible
class MenuItem(models.Model):
    restaurant = ParentalKey('Restaurant', related_name='menu_items')
    dish = models.ForeignKey('Dish', related_name='+')
    price = models.DecimalField(max_digits=6, decimal_places=2)
    recommended_wine = models.ForeignKey('Wine', null=True, blank=True, on_delete=models.SET_NULL, related_name='+')

    def __str__(self):
        return "%s - %f" % (self.dish, self.price)

@python_2_unicode_compatible
class Review(models.Model):
    place = ParentalKey('Place', related_name='reviews')
    author = models.CharField(max_length=255)
    body = models.TextField()

    def __str__(self):
        return "%s on %s" % (self.author, self.place.name)

@python_2_unicode_compatible
class Log(ClusterableModel):
    time = models.DateTimeField(blank=True, null=True)
    data = models.CharField(max_length=255)

    def __str__(self):
        return "[%s] %s" % (self.time.isoformat(), self.data)
<|endoftext|>


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

import sys
import inspect

from chibitest import runner, TestCase

from test_markdown import MarkdownConformanceTest_10, MarkdownConformanceTest_103
from test_renderer import CustomRendererTest
from test_smartypants import SmartypantsTest

help_message = """\
--include and --exclude can be used multiple times and both accept a list
of names (names of the test case classes). The order of --include and
--exclude is not significant. Everything listed in --exclude will be filtered
out of the list of tests.

--list output a list of test cases.

Arguments:
    --include [[[TestCase1] TestCase2] ...]
    --exclude [[[TestCase1] TestCase2] ...]
    --list
    --help
"""

def is_test(n):
    return inspect.isclass(n) and issubclass(n, TestCase) and not n is TestCase

def get_tests():
    return inspect.getmembers(sys.modules[__name__], is_test)

def run_tests(include=[], exclude=[]):
    tests = get_tests()

    if include:
        tests = filter(lambda n: n[0] in include, tests)
    if exclude:
        tests = filter(lambda n: not n[0] in exclude, tests)

    runner([n[1] for n in tests])

if __name__ == '__main__':
    include = []
    exclude = []

    if len(sys.argv) >= 2:
        if sys.argv[1] == '--list':
            for name, testcase in get_tests():
                print(name)
            sys.exit(0)
        elif sys.argv[1] == '--help':
            print(help_message)
            sys.exit(0)
        else:
            last_arg = '--include'

            for arg in sys.argv[1:]:
                if arg in ('--include', '--exclude'):
                    last_arg = arg
                elif not arg.startswith('--'):
                    if last_arg == '--include':
                        include.append(arg)
                    elif last_arg == '--exclude':
                        exclude.append(arg)

    run_tests(include, exclude)
<commit_msg>Add path to Python path.<commit_after># -*- coding: utf-8 -*-

import inspect
import sys
from os.path import dirname, join as jp

sys.path.insert(0, jp(dirname(sys.modules[__name__].__file__), '..'))

from chibitest import runner, TestCase
from test_markdown import MarkdownConformanceTest_10, MarkdownConformanceTest_103
from test_renderer import CustomRendererTest
from test_smartypants import SmartypantsTest

help_message = """\
--include and --exclude can be used multiple times and both accept a list
of names (names of the test case classes). The order of --include and
--exclude is not significant. Everything listed in --exclude will be filtered
out of the list of tests.

--list output a list of test cases.

Arguments:
    --include [[[TestCase1] TestCase2] ...]
    --exclude [[[TestCase1] TestCase2] ...]
    --list
    --help
"""

def is_test(n):
    return inspect.isclass(n) and issubclass(n, TestCase) and not n is TestCase

def get_tests():
    return inspect.getmembers(sys.modules[__name__], is_test)

def run_tests(include=[], exclude=[]):
    tests = get_tests()

    if include:
        tests = filter(lambda n: n[0] in include, tests)
    if exclude:
        tests = filter(lambda n: not n[0] in exclude, tests)

    runner([n[1] for n in tests])

if __name__ == '__main__':
    include = []
    exclude = []

    if len(sys.argv) >= 2:
        if sys.argv[1] == '--list':
            for name, testcase in get_tests():
                print(name)
            sys.exit(0)
        elif sys.argv[1] == '--help':
            print(help_message)
            sys.exit(0)
        else:
            last_arg = '--include'

            for arg in sys.argv[1:]:
                if arg in ('--include', '--exclude'):
                    last_arg = arg
                elif not arg.startswith('--'):
                    if last_arg == '--include':
                        include.append(arg)
                    elif last_arg == '--exclude':
                        exclude.append(arg)

    run_tests(include, exclude)
<|endoftext|>