Exemple #1
0
    def test_single_request(self, mock_request):
        # mock http server
        Response = NamedTuple('Response',
                              status_code=int,
                              text=str,
                              url=str,
                              method=str)

        def fake_response(method, url):
            return Response(200, 'ok', url, method)

        mock_request.side_effect = fake_response

        # overwrite `Context` used by client
        ctx = Context()
        ctx.create_redis = lambda: self.redis_resource.rds

        # create routing record
        self.rtbl.set_routing(
            RoutingRecord('myservice', ['localhost:8000'], [1]))

        # make request
        response = single_request(ClientConfig('myservice'),
                                  ctx,
                                  router_type='SymmetryHostRouter')

        self.assertEqual(200, response.status_code)
Exemple #2
0
    def spawn(self, service, num: int = 1, client: str = None, parameters: dict = None,
              worker_labels: dict = None) -> ClientGroup:
        """
        Spawn clients for the given service and distribute them across workers. If no client app is specified, a default
        http client will be created that creates http requests from the (optional) parameters::

            spawn('myservice', parameters={'method': 'get', 'path': '/', 'kwargs': None}

        is equivalent to::

            spawn('myservice')

        Another example::

            spawn('myservice', 2, parameters={'method': 'post', 'path': '/', 'kwargs': {'data': 'my post data'}})

        will result is POST requests to the path '/' where the 'kwargs' dict is passed to the python
        ``requests.request`` call as keyword arguments.

        :param service: the service name
        :param num: the number of clients
        :param client: the client app name (optional, if not given will use service name)
        :param parameters: parameters for the app (optional, e.g.: '{ "size": "small" }'
        :param worker_labels: labels that workers must match to be part of the group
        :return a new ClientGroup for the created clients
        """
        cfg = ClientConfig(service, client=client, parameters=parameters, worker_labels=worker_labels)
        clients = self.ctrl.create_clients(cfg, num)
        return ClientGroup(self.ctrl, clients, cfg)
Exemple #3
0
    def test_debug_router(self):
        env = dict(os.environ)
        env['galileo_router_type'] = 'DebugRouter'

        client_id = 'unittest_client'
        ctx = Context(env)
        trace_queue = Queue()

        description = ClientDescription(client_id, 'unittest_worker',
                                        ClientConfig('aservice'))
        # ctx: Context, trace_queue: Queue, description: ClientDescription

        client = Client(ctx,
                        trace_queue,
                        description,
                        eventbus=SimpleEventBus())
        client.request_generator = StaticRequestGenerator(
            [ServiceRequest('aservice') for _ in range(self.n)])

        then = time.time()
        client.run()
        now = time.time()

        total = now - then

        print('DebugRouter: %.2f req/sec (%.4fs total)' %
              (self.n / total, total))
Exemple #4
0
    def request(self, service, client: str = None, parameters: dict = None, router_type='SymmetryHostRouter',
                worker_labels: dict = None):
        """
        Send a request with the given configuration like a client would. See ``spawn`` for the parameters. An additional
        parameter is the ``router_type`` which specifies which router to use (see `Context.create_router`)
        """
        cfg = ClientConfig(service, client=client, parameters=parameters, worker_labels=worker_labels)
        resp = single_request(cfg, router_type=router_type)

        return resp
Exemple #5
0
    def test_symmetry_router(self, mock_request):
        # mock http server
        Response = NamedTuple('Response',
                              status_code=int,
                              text=str,
                              url=str,
                              method=str)

        def fake_response(method, url):
            return Response(200, 'ok', url, method)

        mock_request.side_effect = fake_response

        self.rtbl.set_routing(
            RoutingRecord('aservice', ['host1', 'host2', 'host3'], [1, 2, 3]))

        env = dict(os.environ)
        env['galileo_router_type'] = 'CachingSymmetryHostRouter'

        client_id = 'unittest_client'
        ctx = Context(env)
        ctx.create_redis = lambda: self.rds
        trace_queue = Queue()

        description = ClientDescription(client_id, 'unittest_worker',
                                        ClientConfig('aservice'))
        # ctx: Context, trace_queue: Queue, description: ClientDescription

        client = Client(ctx,
                        trace_queue,
                        description,
                        eventbus=SimpleEventBus())
        client.request_generator = StaticRequestGenerator(
            [ServiceRequest('aservice') for _ in range(self.n)])

        then = time.time()
        client.run()
        now = time.time()

        total = now - then

        print('CachingSymmetryHostRouter: %.2f req/sec (%.4f total)' %
              (self.n / total, total))
Exemple #6
0
    def test_with_router_fault(self):
        class FaultInjectingRouter(DebugRouter):
            def request(self, req: ServiceRequest) -> 'requests.Response':
                if req.path == '/api/nonexisting':
                    raise ValueError('some error')

                return super().request(req)

        router = FaultInjectingRouter()

        ctx = Context()
        ctx.create_router = lambda: router
        client_id = 'unittest_client'
        trace_queue = Queue()

        description = ClientDescription(client_id, 'unittest_worker',
                                        ClientConfig('aservice'))
        # ctx: Context, trace_queue: Queue, description: ClientDescription

        client = Client(ctx,
                        trace_queue,
                        description,
                        eventbus=SimpleEventBus())

        client.request_generator = StaticRequestGenerator([
            ServiceRequest('aservice', path='/api/nonexisting'),
            ServiceRequest('aservice', path='/api/unittest'),
        ])

        client.run()

        trace1 = trace_queue.get(timeout=2)
        trace2 = trace_queue.get(timeout=2)

        self.assertEqual(-1, trace1.sent)
        self.assertAlmostEqual(trace2.sent, time.time(), delta=2)
Exemple #7
0
    def test_client_integration(self):
        env = dict(os.environ)
        env['galileo_router_type'] = 'DebugRouter'

        client_id = 'unittest_client'
        ctx = Context(env)
        trace_queue = Queue()

        description = ClientDescription(client_id, 'unittest_worker',
                                        ClientConfig('aservice'))
        # ctx: Context, trace_queue: Queue, description: ClientDescription

        client = Client(ctx,
                        trace_queue,
                        description,
                        eventbus=SimpleEventBus())

        client.request_generator = StaticRequestGenerator([
            ServiceRequest('aservice'),
            ServiceRequest('aservice'),
        ])

        client.run()

        trace1 = trace_queue.get(timeout=2)
        trace2 = trace_queue.get(timeout=2)

        self.assertEqual('aservice', trace1.service)
        self.assertEqual('aservice', trace2.service)

        self.assertEqual('debughost', trace1.server)
        self.assertEqual('debughost', trace2.server)

        now = time.time()
        self.assertAlmostEqual(now, trace1.done, delta=2)
        self.assertAlmostEqual(now, trace2.done, delta=2)