Exemplo n.º 1
0
 def setUp(self):
     self.store = Store(stamp=0.0)
     self.timer = StoreTimer(store=self.store, duration=1.0)
     self.baseDirpath = tempfile.mkdtemp(prefix="raet",  suffix="base", dir=TEMPDIR)
     self.stack = None
     # This has to be set to True in the only one process that would perform tearDown steps
     self.engine = True
     stacking.RoadStack.BurstSize = 100
Exemplo n.º 2
0
    def setUp(self):
        self.store = storing.Store(stamp=0.0)
        self.timer = StoreTimer(store=self.store, duration=1.0)

        self.saltDirpath = tempfile.mkdtemp(prefix="salt",
                                            suffix="main",
                                            dir='/tmp')

        pkiDirpath = os.path.join(self.saltDirpath, 'pki')
        if not os.path.exists(pkiDirpath):
            os.makedirs(pkiDirpath)

        acceptedDirpath = os.path.join(pkiDirpath, 'accepted')
        if not os.path.exists(acceptedDirpath):
            os.makedirs(acceptedDirpath)

        pendingDirpath = os.path.join(pkiDirpath, 'pending')
        if not os.path.exists(pendingDirpath):
            os.makedirs(pendingDirpath)

        rejectedDirpath = os.path.join(pkiDirpath, 'rejected')
        if not os.path.exists(rejectedDirpath):
            os.makedirs(rejectedDirpath)

        self.localFilepath = os.path.join(pkiDirpath, 'local.key')
        if os.path.exists(self.localFilepath):
            mode = os.stat(self.localFilepath).st_mode
            os.chmod(self.localFilepath, mode | stat.S_IWUSR | stat.S_IWUSR)

        self.cacheDirpath = os.path.join(self.saltDirpath, 'cache')
        self.sockDirpath = os.path.join(self.saltDirpath, 'sock')

        self.opts = dict(
            __role='master',
            id='master',
            pki_dir=pkiDirpath,
            sock_dir=self.sockDirpath,
            cachedir=self.cacheDirpath,
            open_mode=False,
            auto_accept=True,
            transport='raet',
        )

        self.mainKeeper = RaetKey(opts=self.opts)
        self.baseDirpath = tempfile.mkdtemp(prefix="salt",
                                            suffix="base",
                                            dir='/tmp')
Exemplo n.º 3
0
    def setUp(self):
        self.store = Store(stamp=0.0)
        self.timer = StoreTimer(store=self.store, duration=1.0)

        self.baseDirpath=tempfile.mkdtemp(prefix="raet",  suffix="base", dir=TEMPDIR)
        stacking.RoadStack.Bk = raeting.BodyKind.json.value

        #main stack
        mainName = "main"
        mainDirpath = os.path.join(self.baseDirpath, 'road', 'keep', mainName)
        signer = nacling.Signer()
        mainSignKeyHex = signer.keyhex
        privateer = nacling.Privateer()
        mainPriKeyHex = privateer.keyhex


        #other stack
        otherName = "other"
        otherDirpath = os.path.join(self.baseDirpath, 'road', 'keep', otherName)
        signer = nacling.Signer()
        otherSignKeyHex = signer.keyhex
        privateer = nacling.Privateer()
        otherPriKeyHex = privateer.keyhex


        keeping.clearAllKeep(mainDirpath)
        keeping.clearAllKeep(otherDirpath)

        self.main = stacking.RoadStack(store=self.store,
                                       name=mainName,
                                       main=True,
                                       auto=raeting.AutoMode.once.value,
                                       sigkey=mainSignKeyHex,
                                       prikey=mainPriKeyHex,
                                       dirpath=mainDirpath,
                                       )

        self.other = stacking.RoadStack(store=self.store,
                                        name=otherName,
                                        auto=raeting.AutoMode.once.value,
                                        ha=("", raeting.RAET_TEST_PORT),
                                        sigkey=otherSignKeyHex,
                                        prikey=otherPriKeyHex,
                                        dirpath=otherDirpath,
                                        )
Exemplo n.º 4
0
 def streamGet():
     """
     Create test server sent event stream that sends count events
     """
     timer = StoreTimer(store, duration=2.0)
     bottle.response.set_header('Content-Type',
                                'text/event-stream')  #text
     bottle.response.set_header('Cache-Control', 'no-cache')
     # HTTP 1.1 servers detect text/event-stream and use Transfer-Encoding: chunked
     # Set client-side auto-reconnect timeout, ms.
     yield 'retry: 1000\n\n'
     i = 0
     yield 'id: {0}\n'.format(i)
     i += 1
     yield 'data: START\n\n'
     n = 1
     while not timer.expired:
         yield 'id: {0}\n'.format(i)
         i += 1
         yield 'data: {0}\n\n'.format(n)
         n += 1
     yield "data: END\n\n"
Exemplo n.º 5
0
    def setUp(self):
        self.store = Store(stamp=0.0)
        self.timer = StoreTimer(store=self.store, duration=1.0)

        if sys.platform == 'win32':
            self.tempDirpath = tempfile.mktemp(prefix="raet",  suffix="base",
                                               dir=TEMPDIR)
        else:
            self.tempDirpath = tempfile.mkdtemp(prefix="raet",  suffix="base",
                                                dir=TEMPDIR)

        self.baseDirpath = os.path.join(self.tempDirpath, 'lane', 'keep')

        # main stack
        self.main = stacking.LaneStack(name='main',
                                       uid=1,
                                       lanename='cherry',
                                       sockdirpath=self.baseDirpath)

        #other stack
        self.other = stacking.LaneStack(name='other',
                                        uid=1,
                                        lanename='cherry',
                                        sockdirpath=self.baseDirpath)
Exemplo n.º 6
0
    def __init__(self,
                 stack,
                 uid=None,
                 fuid=0,
                 main=False,
                 kind=0,
                 verkey=None,
                 pubkey=None,
                 acceptance=None,
                 joined=None,
                 rsid=0,
                 **kwa):
        '''
        Setup instance

        stack is required parameter

        verkey is either nacl VerifyKey or raw or hex encoded key
        pubkey is either nacl PublicKey or raw or hex encoded key

        acceptance is accepted state of remote on Road

        rsid is last received session id used by remotely initiated transaction


        '''
        if uid is None:
            uid = stack.nextUid()
            while uid in stack.remotes or uid == stack.local.uid:
                uid = stack.nextUid()

        if 'ha' not in kwa:
            kwa['ha'] = ('127.0.0.1', raeting.RAET_TEST_PORT)
        super(RemoteEstate, self).__init__(stack, uid=uid, **kwa)
        self.fuid = fuid
        self.main = main
        self.kind = kind
        self.joined = joined
        self.allowed = None
        self.alived = None
        self.reaped = None
        self.acceptance = acceptance
        self.privee = nacling.Privateer()  # short term key manager
        self.publee = nacling.Publican(
        )  # correspondent short term key  manager
        self.verfer = nacling.Verifier(
            verkey)  # correspondent verify key manager
        self.pubber = nacling.Publican(
            pubkey)  # correspondent long term key manager

        self.rsid = rsid  # last sid received from remote when RmtFlag is True

        # persistence keep alive heartbeat timer. Initial duration has offset so
        # not synced with other side persistence heatbeet
        # by default do not use offset on main
        if self.stack.main:
            duration = self.stack.period
        else:
            duration = self.stack.period + self.stack.offset
        self.timer = StoreTimer(store=self.stack.store, duration=duration)

        self.reapTimer = StoreTimer(self.stack.store,
                                    duration=self.stack.interim)
        self.messages = deque(
        )  # deque of saved stale message body data to remote.uid
Exemplo n.º 7
0
 def addDoneTransaction(self, index):
     self.doneTransactions[index] = StoreTimer(
         self.stack.store, duration=self.stack.MsgStaleTimeout)
Exemplo n.º 8
0
 def setUp(self):
     self.store = storing.Store(stamp=0.0)
     self.timer = StoreTimer(store=self.store, duration=1.0)
     self.port = 4506
     self.opts = dict(master_port=self.port)
Exemplo n.º 9
0
 def setUp(self):
     self.store = Store(stamp=0.0)
     self.timer = StoreTimer(store=self.store, duration=1.0)
Exemplo n.º 10
0
    def setUp(self):
        self.store = Store(stamp=0.0)
        self.timer = StoreTimer(store=self.store, duration=1.0)

        self.dirpathBase = tempfile.mkdtemp(prefix="raet",
                                            suffix="base",
                                            dir=TEMPDIR)
        stacking.RoadStack.Bk = raeting.BodyKind.json.value

        #main stack
        mainName = "main"
        mainDirpath = os.path.join(self.dirpathBase, 'road', 'keep', mainName)
        signer = nacling.Signer()
        mainSignKeyHex = signer.keyhex
        mainVerKeyHex = signer.verhex
        privateer = nacling.Privateer()
        mainPriKeyHex = privateer.keyhex
        mainPubKeyHex = privateer.pubhex

        #other stack
        otherName = "other"
        otherDirpath = os.path.join(self.dirpathBase, 'road', 'keep',
                                    otherName)
        signer = nacling.Signer()
        otherSignKeyHex = signer.keyhex
        otherVerKeyHex = signer.verhex
        privateer = nacling.Privateer()
        otherPriKeyHex = privateer.keyhex
        otherPubKeyHex = privateer.pubhex

        keeping.clearAllKeep(mainDirpath)
        keeping.clearAllKeep(otherDirpath)

        self.main = stacking.RoadStack(name=mainName,
                                       uid=1,
                                       sigkey=mainSignKeyHex,
                                       prikey=mainPriKeyHex,
                                       auto=raeting.AutoMode.once.value,
                                       main=True,
                                       dirpath=mainDirpath,
                                       store=self.store)

        remote1 = estating.RemoteEstate(
            stack=self.main,
            uid=2,
            name=otherName,
            ha=("127.0.0.1", raeting.RAET_TEST_PORT),
            verkey=otherVerKeyHex,
            pubkey=otherPubKeyHex,
        )
        self.main.addRemote(remote1)

        self.other = stacking.RoadStack(name=otherName,
                                        uid=2,
                                        auto=raeting.AutoMode.once.value,
                                        ha=("", raeting.RAET_TEST_PORT),
                                        sigkey=otherSignKeyHex,
                                        prikey=otherPriKeyHex,
                                        dirpath=otherDirpath,
                                        store=self.store)

        remote0 = estating.RemoteEstate(
            stack=self.other,
            uid=3,
            name=mainName,
            ha=('127.0.0.1', raeting.RAET_PORT),
            verkey=mainVerKeyHex,
            pubkey=mainPubKeyHex,
        )
        self.other.addRemote(remote0)

        remote0.publee = nacling.Publican(key=remote1.privee.pubhex)
        remote1.publee = nacling.Publican(key=remote0.privee.pubhex)

        stuff = []
        for i in range(300):
            stuff.append(str(i).rjust(4, " "))
        self.stuff = ns2b("".join(stuff))

        self.data = odict(hk=raeting.HeadKind.raet.value)
Exemplo n.º 11
0
    def testValetServiceBottleSecure(self):
        """
        Test Valet WSGI service secure TLS request response
        """
        console.terse("{0}\n".format(
            self.testValetServiceBottleSecure.__doc__))

        try:
            import bottle
        except ImportError as ex:
            console.terse("Bottle not available.\n")
            return

        store = storing.Store(stamp=0.0)

        app = bottle.default_app()  # create bottle app

        @app.get('/echo')
        @app.get('/echo/<action>')
        @app.post('/echo')
        @app.post('/echo/<action>')
        def echoGet(action=None):
            """
            Echo back request data
            """
            query = dict(bottle.request.query.items())
            body = bottle.request.json
            raw = bottle.request.body.read()
            form = odict(bottle.request.forms)

            data = odict(verb=bottle.request.method,
                         url=bottle.request.url,
                         action=action,
                         query=query,
                         form=form,
                         content=body)
            return data

        console.terse("{0}\n".format("Building Valet ...\n"))
        wireLogAlpha = wiring.WireLog(buffify=True, same=True)
        result = wireLogAlpha.reopen()

        serverCertCommonName = 'localhost'  # match hostname uses servers's cert commonname
        #serverKeypath = '/etc/pki/tls/certs/server_key.pem'  # local server private key
        #serverCertpath = '/etc/pki/tls/certs/server_cert.pem'  # local server public cert
        #clientCafilepath = '/etc/pki/tls/certs/client.pem' # remote client public cert

        serverKeypath = self.certdirpath + '/server_key.pem'  # local server private key
        serverCertpath = self.certdirpath + '/server_cert.pem'  # local server public cert
        clientCafilepath = self.certdirpath + '/client.pem'  # remote client public cert

        alpha = serving.Valet(
            port=6101,
            bufsize=131072,
            wlog=wireLogAlpha,
            store=store,
            app=app,
            scheme='https',
            keypath=serverKeypath,
            certpath=serverCertpath,
            cafilepath=clientCafilepath,
        )
        self.assertIs(alpha.servant.reopen(), True)
        self.assertEqual(alpha.servant.ha, ('0.0.0.0', 6101))
        self.assertEqual(alpha.servant.eha, ('127.0.0.1', 6101))

        console.terse("{0}\n".format("Building Patron ...\n"))
        wireLogBeta = wiring.WireLog(buffify=True, same=True)
        result = wireLogBeta.reopen()

        #clientKeypath = '/etc/pki/tls/certs/client_key.pem'  # local client private key
        #clientCertpath = '/etc/pki/tls/certs/client_cert.pem'  # local client public cert
        #serverCafilepath = '/etc/pki/tls/certs/server.pem' # remote server public cert

        clientKeypath = self.certdirpath + '/client_key.pem'  # local client private key
        clientCertpath = self.certdirpath + '/client_cert.pem'  # local client public cert
        serverCafilepath = self.certdirpath + '/server.pem'  # remote server public cert

        path = "https://{0}:{1}/".format('localhost', alpha.servant.eha[1])

        beta = clienting.Patron(bufsize=131072,
                                wlog=wireLogBeta,
                                store=store,
                                path=path,
                                reconnectable=True,
                                scheme='https',
                                certedhost=serverCertCommonName,
                                keypath=clientKeypath,
                                certpath=clientCertpath,
                                cafilepath=serverCafilepath)

        self.assertIs(beta.connector.reopen(), True)
        self.assertIs(beta.connector.accepted, False)
        self.assertIs(beta.connector.connected, False)
        self.assertIs(beta.connector.cutoff, False)

        request = odict([
            ('method', u'GET'),
            ('path', u'/echo?name=fame'),
            ('qargs', odict()),
            ('fragment', u''),
            ('headers',
             odict([('Accept', 'application/json'), ('Content-Length', 0)])),
        ])

        beta.requests.append(request)
        timer = StoreTimer(store, duration=1.0)
        while (beta.requests or beta.connector.txes or not beta.responses
               or not alpha.idle()):
            alpha.serviceAll()
            time.sleep(0.05)
            beta.serviceAll()
            time.sleep(0.05)
            store.advanceStamp(0.1)

        self.assertIs(beta.connector.accepted, True)
        self.assertIs(beta.connector.connected, True)
        self.assertIs(beta.connector.cutoff, False)

        self.assertEqual(len(alpha.servant.ixes), 1)
        self.assertEqual(len(alpha.reqs), 1)
        self.assertEqual(len(alpha.reps), 1)
        requestant = alpha.reqs.values()[0]
        self.assertEqual(requestant.method, request['method'])
        self.assertEqual(requestant.url, request['path'])
        self.assertEqual(
            requestant.headers, {
                'accept': 'application/json',
                'accept-encoding': 'identity',
                'content-length': '0',
                'host': 'localhost:6101'
            })

        self.assertEqual(len(beta.responses), 1)
        response = beta.responses.popleft()
        self.assertEqual(response['status'], 200)
        self.assertEqual(response['reason'], 'OK')
        self.assertEqual(response['body'], bytearray(b''))
        self.assertEqual(
            response['data'],
            {
                'action': None,
                'content': None,
                'form': {},
                'query': {
                    'name': 'fame'
                },
                'url': 'https://localhost:6101/echo?name=fame',
                'verb': 'GET'
            },
        )

        responder = alpha.reps.values()[0]
        self.assertTrue(responder.status.startswith, str(response['status']))
        self.assertEqual(responder.headers, response['headers'])

        alpha.servant.closeAll()
        beta.connector.close()

        wireLogAlpha.close()
        wireLogBeta.close()
Exemplo n.º 12
0
    def testValetServiceBottleStream(self):
        """
        Test Valet WSGI service request response stream sse
        """
        console.terse("{0}\n".format(
            self.testValetServiceBottleStream.__doc__))

        try:
            import bottle
        except ImportError as ex:
            console.terse("Bottle not available.\n")
            return

        store = storing.Store(stamp=0.0)

        app = bottle.default_app()  # create bottle app

        @app.get('/stream')
        def streamGet():
            """
            Create test server sent event stream that sends count events
            """
            timer = StoreTimer(store, duration=2.0)
            bottle.response.set_header('Content-Type',
                                       'text/event-stream')  #text
            bottle.response.set_header('Cache-Control', 'no-cache')
            # HTTP 1.1 servers detect text/event-stream and use Transfer-Encoding: chunked
            # Set client-side auto-reconnect timeout, ms.
            yield 'retry: 1000\n\n'
            i = 0
            yield 'id: {0}\n'.format(i)
            i += 1
            yield 'data: START\n\n'
            n = 1
            while not timer.expired:
                yield 'id: {0}\n'.format(i)
                i += 1
                yield 'data: {0}\n\n'.format(n)
                n += 1
            yield "data: END\n\n"

        console.terse("{0}\n".format("Building Valet ...\n"))
        wireLogAlpha = wiring.WireLog(buffify=True, same=True)
        result = wireLogAlpha.reopen()

        alpha = serving.Valet(port=6101,
                              bufsize=131072,
                              wlog=wireLogAlpha,
                              store=store,
                              app=app)
        self.assertIs(alpha.servant.reopen(), True)
        self.assertEqual(alpha.servant.ha, ('0.0.0.0', 6101))
        self.assertEqual(alpha.servant.eha, ('127.0.0.1', 6101))

        console.terse("{0}\n".format("Building Patron ...\n"))
        wireLogBeta = wiring.WireLog(buffify=True, same=True)
        result = wireLogBeta.reopen()

        path = "http://{0}:{1}/".format('localhost', alpha.servant.eha[1])

        beta = clienting.Patron(
            bufsize=131072,
            wlog=wireLogBeta,
            store=store,
            path=path,
            reconnectable=True,
        )

        self.assertIs(beta.connector.reopen(), True)
        self.assertIs(beta.connector.accepted, False)
        self.assertIs(beta.connector.connected, False)
        self.assertIs(beta.connector.cutoff, False)

        request = odict([
            ('method', u'GET'),
            ('path', u'/stream'),
            ('qargs', odict()),
            ('fragment', u''),
            ('headers',
             odict([('Accept', 'application/json'), ('Content-Length', 0)])),
            ('body', None),
        ])

        beta.requests.append(request)
        timer = StoreTimer(store, duration=1.0)
        while (not timer.expired):
            alpha.serviceAll()
            time.sleep(0.05)
            beta.serviceAll()
            time.sleep(0.05)
            store.advanceStamp(0.1)

        self.assertIs(beta.connector.accepted, True)
        self.assertIs(beta.connector.connected, True)
        self.assertIs(beta.connector.cutoff, False)

        self.assertEqual(len(alpha.servant.ixes), 1)
        self.assertEqual(len(alpha.reqs), 1)
        self.assertEqual(len(alpha.reps), 1)
        requestant = alpha.reqs.values()[0]
        self.assertEqual(requestant.method, request['method'])
        self.assertEqual(requestant.url, request['path'])
        self.assertEqual(
            requestant.headers, {
                'accept': 'application/json',
                'accept-encoding': 'identity',
                'content-length': '0',
                'host': 'localhost:6101'
            })

        #timed out while stream still open so no responses in .responses
        self.assertIs(beta.waited, True)
        self.assertIs(beta.respondent.ended, False)
        self.assertEqual(len(beta.responses), 0)
        self.assertIn('content-type', beta.respondent.headers)
        self.assertEqual(beta.respondent.headers['content-type'],
                         'text/event-stream')
        self.assertIn('transfer-encoding', beta.respondent.headers)
        self.assertEqual(beta.respondent.headers['transfer-encoding'],
                         'chunked')

        self.assertTrue(len(beta.events) >= 3)
        self.assertEqual(beta.respondent.retry, 1000)
        self.assertTrue(int(beta.respondent.leid) >= 2)
        event = beta.events.popleft()
        self.assertEqual(event, {'id': '0', 'name': '', 'data': 'START'})
        event = beta.events.popleft()
        self.assertEqual(event, {'id': '1', 'name': '', 'data': '1'})
        event = beta.events.popleft()
        self.assertEqual(event, {'id': '2', 'name': '', 'data': '2'})
        beta.events.clear()

        #keep going until ended
        timer.restart(duration=1.5)
        while (not timer.expired):
            alpha.serviceAll()
            time.sleep(0.05)
            beta.serviceAll()
            time.sleep(0.05)
            store.advanceStamp(0.1)

        self.assertTrue(len(beta.events) >= 3)
        self.assertEqual(beta.respondent.leid, '9')
        self.assertEqual(beta.events[-2], {'id': '9', 'name': '', 'data': '9'})
        self.assertEqual(beta.events[-1], {
            'id': '9',
            'name': '',
            'data': 'END'
        })
        beta.events.clear()

        alpha.servant.closeAll()
        beta.connector.close()

        wireLogAlpha.close()
        wireLogBeta.close()
Exemplo n.º 13
0
    def __init__(
        self,
        store=None,
        version=raeting.VERSION,
        main=None,
        puid=None,
        local=None,  #passed up from subclass
        name='',
        uid=None,
        server=None,
        ha=None,
        bufcnt=2,
        rxMsgs=None,
        txMsgs=None,
        rxes=None,
        txes=None,
        stats=None,
    ):
        '''
        Setup Stack instance
        '''
        self.store = store or Store(stamp=0.0)

        self.version = version
        self.main = main

        if getattr(self, 'puid', None) is None:
            self.puid = puid if puid is not None else self.Uid

        self.local = local or lotting.Lot(
            stack=self,
            name=name,
            uid=uid,
            ha=ha,
        )
        self.local.stack = self

        self.remotes = self.uidRemotes = odict()  # remotes indexed by uid
        self.nameRemotes = odict()  # remotes indexed by name

        self.bufcnt = bufcnt
        if not server:
            server = self.serverFromLocal()

        self.server = server
        if self.server:
            if not self.server.reopen():  # open socket
                raise raeting.StackError(
                    "Stack '{0}': Failed opening server at"
                    " '{1}'\n".format(self.name, self.server.ha))

            self.ha = self.server.ha  # update local host address after open

            console.verbose("Stack '{0}': Opened server at '{1}'\n".format(
                self.name, self.ha))

        self.rxMsgs = rxMsgs if rxMsgs is not None else deque(
        )  # messages received
        self.txMsgs = txMsgs if txMsgs is not None else deque(
        )  # messages to transmit
        self.rxes = rxes if rxes is not None else deque(
        )  # udp packets received
        self.txes = txes if txes is not None else deque(
        )  # udp packet to transmit
        self.stats = stats if stats is not None else odict()  # udp statistics
        self.statTimer = StoreTimer(self.store)
Exemplo n.º 14
0
def test_get_backend():
    """
    """
    print("Testing Falcon Example Backend Call")

    store = Store(stamp=0.0)  # create store
    priming.setupTest()

    valet = Valet(
        port=8101,
        bufsize=131072,
        store=store,
        app=exapp,
    )

    result = valet.open()
    assert result
    assert valet.servant.ha == ('0.0.0.0', 8101)
    assert valet.servant.eha == ('127.0.0.1', 8101)

    path = "http://{}:{}{}".format('localhost', valet.servant.eha[1],
                                   "/example/backend")
    headers = odict([('Accept', 'application/json'), ('Content-Length', 0)])
    patron = Patron(
        bufsize=131072,
        store=store,
        method='GET',
        path=path,
        headers=headers,
        reconnectable=True,
    )

    assert patron.connector.reopen()
    assert patron.connector.accepted == False
    assert patron.connector.connected == False
    assert patron.connector.cutoff == False

    patron.transmit()
    timer = StoreTimer(store, duration=1.0)
    while (patron.requests or patron.connector.txes or not patron.responses
           or not valet.idle()):
        valet.serviceAll()
        time.sleep(0.05)
        patron.serviceAll()
        time.sleep(0.05)
        store.advanceStamp(0.1)

    assert patron.connector.accepted == True
    assert patron.connector.connected == True
    assert patron.connector.cutoff == False

    assert len(valet.servant.ixes) == 1
    assert len(valet.reqs) == 1
    assert len(valet.reps) == 1
    requestant = valet.reqs.values()[0]
    assert requestant.method == patron.requester.method
    assert requestant.url == patron.requester.path
    assert requestant.headers == {
        'accept': 'application/json',
        'accept-encoding': 'identity',
        'content-length': '0',
        'host': 'localhost:8101'
    }

    assert len(patron.responses) == 1
    rep = patron.responses.popleft()
    assert rep['status'] == 200
    assert rep['reason'] == 'OK'
    assert rep['body'] == bytearray(
        b'{\n  "approved": true,\n  "body": "\\nHello World\\n\\n"\n}')
    assert rep['data'] == odict([('approved', True),
                                 ('body', '\nHello World\n\n')])

    responder = valet.reps.values()[0]
    assert responder.status.startswith(str(rep['status']))
    assert responder.headers == rep['headers']

    # test for error by sending query arg path
    #request = odict([('method', 'GET'),
    #('path', '/example/backend'),
    #('qargs', odict(path='/unknown')),
    #('fragment', u''),
    #('headers', odict([('Accept', 'application/json'),
    #('Content-Length', 0)])),
    #])

    #patron.requests.append(request)

    headers = odict([('Accept', 'application/json'), ('Content-Length', 0)])
    patron.request(method='GET',
                   path='/example/backend',
                   qargs=odict(path='/unknown'),
                   headers=headers)
    timer = StoreTimer(store, duration=1.0)
    while (patron.requests or patron.connector.txes or not patron.responses
           or not valet.idle()):
        valet.serviceAll()
        time.sleep(0.05)
        patron.serviceAll()
        time.sleep(0.05)
        store.advanceStamp(0.1)

    assert len(patron.responses) == 1
    rep = patron.responses.popleft()
    assert rep['status'] == 404
    assert rep['reason'] == 'Not Found'
    assert rep['body'] == bytearray(b'404 Not Found\nBackend Validation'
                                    b' Error\nError backend validation.'
                                    b' unknown\n')
    assert not rep['data']

    valet.close()
    patron.close()
    print("Done Test")