def test_request_flow(self, with_exception=False): start_low = kronos_time_now() self.middleware.process_request(self.request) start_high = kronos_time_now() time.sleep(0.2) # To get some deterministic `duration`. if with_exception: try: raise ValueError('I am a dummy error.') except ValueError, exception: self.middleware.process_exception(self.request, exception)
def test_put_and_get(self): for i in xrange(2): stream = '%s_%s' % (self.stream, i) self.client.put({stream: [{'a': 1}, {'a': 2}]}) self.client.put({stream: [{'a': 3}, {'a': 4}]}) time.sleep(self.sleep_time) for i in xrange(2): stream = '%s_%s' % (self.stream, i) events = list(self.client.get(stream, self.start_time, kronos_time_now())) self.assertEqual(len(events), 4) self.assertEqual({1, 2, 3, 4}, set(map(lambda event: event['a'], events))) # Test with `datetime` timestamps. start_time = datetime.utcnow() for i in xrange(2): stream = '%s_%s' % (self.stream, i) self.client.put({stream: [{'a': 1, TIMESTAMP_FIELD: datetime.utcnow()}, {'a': 2, TIMESTAMP_FIELD: datetime.utcnow()}]}) self.client.put({stream: [{'a': 3, TIMESTAMP_FIELD: datetime.utcnow()}, {'a': 4, TIMESTAMP_FIELD: datetime.utcnow()}]}) time.sleep(self.sleep_time) for i in xrange(2): stream = '%s_%s' % (self.stream, i) events = list(self.client.get(stream, start_time, datetime.utcnow())) self.assertEqual(len(events), 4) self.assertEqual({1, 2, 3, 4}, set(map(lambda event: event['a'], events)))
def put(self, event_dict, namespace=None): """ Sends a dictionary of `event_dict` of the form {stream_name: [event, ...], ...} to the server. """ # Copy the input, in case we need to modify it by adding a timestamp. event_dict = copy.deepcopy(event_dict) # Ensure that all events have a timestamp. timestamp = kronos_time_now() for events in event_dict.itervalues(): for event in events: if TIMESTAMP_FIELD not in event: event[TIMESTAMP_FIELD] = timestamp else: if isinstance(event[TIMESTAMP_FIELD], types.StringTypes): event[TIMESTAMP_FIELD] = parse(event[TIMESTAMP_FIELD]) if isinstance(event[TIMESTAMP_FIELD], datetime): event[TIMESTAMP_FIELD] = datetime_to_kronos_time( event[TIMESTAMP_FIELD]) event[LIBRARY_FIELD] = { 'version': pykronos.__version__, 'name': 'pykronos' } namespace = namespace or self.namespace if self._blocking: return self._put(namespace, event_dict) else: with self._put_lock: self._put_queue.append((namespace, event_dict))
def test_log_function(self): def getter_x(*args, **kwargs): return args[0] def getter_y(*args, **kwargs): return kwargs.get('y') def getter_z(*args, **kwargs): return args[0] * kwargs.get('y', 0) @self.client.log_function(self.stream, properties={ 'x': getter_x, 'y': getter_y, 'z': getter_z }) def my_function(x, y=None): return start = time.time() my_function(2, y=3) end = time.time() time.sleep(self.sleep_time) events = list( self.client.get(self.stream, self.start_time, kronos_time_now())) self.assertEqual(len(events), 1) event = events[0] self.assertEqual(event['x'], 2) self.assertEqual(event['y'], 3) self.assertEqual(event['z'], 6) self.assertTrue(event['duration'] < end - start)
def process_request(self, request): request._kronos_event = { 'start_time': time.time(), '@time': kronos_time_now(), 'method': request.method.upper(), 'path': request.path, 'client_ip': self._get_ip(request) } get_dict = request.GET.dict() if get_dict: request._kronos_event['get_params'] = get_dict try: if not request.body: return except: # The following exception is thrown if the body could not be read. # Exception("You cannot access body after reading from request's data # stream") return post_dict = request.POST.dict() if (len(post_dict) == 1 and post_dict.values()[0] == '' and post_dict.keys()[0] == request.body): # There is no real *form* POST. try: request._kronos_event['body'] = json.loads(request.body) except ValueError: request._kronos_event['body'] = request.body else: request._kronos_event['post_params'] = post_dict
def test_log_scope(self): x = 1 y = 2 start = time.time() with self.client.log_scope(self.stream, properties={'x': x, 'y': y}) as event: event['hello'] = 'world' raise Exception('boom') end = time.time() time.sleep(self.sleep_time) events = list(self.client.get(self.stream, self.start_time, kronos_time_now())) self.assertEqual(len(events), 1) event = events[0] self.assertEqual(event['x'], 1) self.assertEqual(event['y'], 2) self.assertTrue(event['duration'] < end - start) self.assertEqual(event['hello'], 'world') self.assertTrue('exception' in event) self.assertEqual(event['exception']['class'], 'Exception') self.assertEqual(event['exception']['message'], 'boom')
def test_log_scope(self): x = 1 y = 2 start = time.time() with self.client.log_scope(self.stream, properties={ 'x': x, 'y': y }) as event: event['hello'] = 'world' raise Exception('boom') end = time.time() time.sleep(self.sleep_time) events = list( self.client.get(self.stream, self.start_time, kronos_time_now())) self.assertEqual(len(events), 1) event = events[0] self.assertEqual(event['x'], 1) self.assertEqual(event['y'], 2) self.assertTrue(event['duration'] < end - start) self.assertEqual(event['hello'], 'world') self.assertTrue('exception' in event) self.assertEqual(event['exception']['class'], 'Exception') self.assertEqual(event['exception']['message'], 'boom')
def test_log_function(self): def getter_x(*args, **kwargs): return args[0] def getter_y(*args, **kwargs): return kwargs.get('y') def getter_z(*args, **kwargs): return args[0] * kwargs.get('y', 0) @self.client.log_function(self.stream, properties={'x': getter_x, 'y': getter_y, 'z': getter_z}) def my_function(x, y=None): return start = time.time() my_function(2, y=3) end = time.time() time.sleep(self.sleep_time) events = list(self.client.get(self.stream, self.start_time, kronos_time_now())) self.assertEqual(len(events), 1) event = events[0] self.assertEqual(event['x'], 2) self.assertEqual(event['y'], 3) self.assertEqual(event['z'], 6) self.assertTrue(event['duration'] < end - start)
def wrapper(self): for i, client in enumerate([self.blocking_client, self.nonblocking_client]): self.stream = 'KronosClientTest_%s_%s' % (function.__name__, i) self.start_time = kronos_time_now() self.sleep_time = i * 0.4 # Will be 0 for blocking. self.client = client function(self)
def wrapper(self): for i, client in enumerate( [self.blocking_client, self.nonblocking_client]): self.stream = 'KronosClientTest_%s_%s' % (function.__name__, i) self.start_time = kronos_time_now() self.sleep_time = i * 0.4 # Will be 0 for blocking. self.client = client function(self)
def test_delete(self): self.client.put({self.stream: [{'a': 1}, {'a': 2}]}) mid_time = kronos_time_now() self.client.put({self.stream: [{'a': 3}, {'a': 4}]}) time.sleep(self.sleep_time) events = list( self.client.get(self.stream, self.start_time, kronos_time_now())) self.assertEqual(len(events), 4) self.assertEqual({1, 2, 3, 4}, set(map(lambda event: event['a'], events))) response = self.client.delete(self.stream, mid_time, kronos_time_now()) self.assertEqual(response[self.stream]['memory']['num_deleted'], 2) events = list( self.client.get(self.stream, self.start_time, kronos_time_now())) self.assertEqual(len(events), 2) self.assertEqual({1, 2}, set(map(lambda event: event['a'], events)))
def test_delete(self): self.client.put({self.stream: [{'a': 1}, {'a': 2}]}) mid_time = kronos_time_now() self.client.put({self.stream: [{'a': 3}, {'a': 4}]}) time.sleep(self.sleep_time) events = list(self.client.get(self.stream, self.start_time, kronos_time_now())) self.assertEqual(len(events), 4) self.assertEqual({1, 2, 3, 4}, set(map(lambda event: event['a'], events))) response = self.client.delete(self.stream, mid_time, kronos_time_now()) self.assertEqual(response[self.stream]['memory']['num_deleted'], 2) events = list(self.client.get(self.stream, self.start_time, kronos_time_now())) self.assertEqual(len(events), 2) self.assertEqual({1, 2}, set(map(lambda event: event['a'], events)))
def test_put_and_get(self): for i in xrange(2): stream = '%s_%s' % (self.stream, i) self.client.put({stream: [{'a': 1}, {'a': 2}]}) self.client.put({stream: [{'a': 3}, {'a': 4}]}) time.sleep(self.sleep_time) for i in xrange(2): stream = '%s_%s' % (self.stream, i) events = list( self.client.get(stream, self.start_time, kronos_time_now())) self.assertEqual(len(events), 4) self.assertEqual({1, 2, 3, 4}, set(map(lambda event: event['a'], events))) # Test with `datetime` timestamps. start_time = datetime.utcnow() for i in xrange(2): stream = '%s_%s' % (self.stream, i) self.client.put({ stream: [{ 'a': 1, TIMESTAMP_FIELD: datetime.utcnow() }, { 'a': 2, TIMESTAMP_FIELD: datetime.utcnow() }] }) self.client.put({ stream: [{ 'a': 3, TIMESTAMP_FIELD: datetime.utcnow() }, { 'a': 4, TIMESTAMP_FIELD: datetime.utcnow() }] }) time.sleep(self.sleep_time) for i in xrange(2): stream = '%s_%s' % (self.stream, i) events = list( self.client.get(stream, start_time, datetime.utcnow())) self.assertEqual(len(events), 4) self.assertEqual({1, 2, 3, 4}, set(map(lambda event: event['a'], events)))
def put(self, event_dict, namespace=None): """ Sends a dictionary of `event_dict` of the form {stream_name: [event, ...], ...} to the server. The `blocking` parameter allows the request to block until the server responds, and returns some information on the response. Here's an example: {u'stream_name_1': 3, u'stream_name_2': 1, u'@took': u'1ms'} -> put 3 events on stream_name_1 -> put 1 event on stream_name_2 -> put took 1ms to complete If `blocking` is false and the process running the client ends before flushing the pending data to the server, you might lose that data. Calling `flush` will block until all pending data has been acknowledged by the server. """ # Copy the input, in case we need to modify it by adding a timestamp. event_dict = copy.deepcopy(event_dict) # Ensure that all events have a timestamp. timestamp = kronos_time_now() for events in event_dict.itervalues(): for event in events: if TIMESTAMP_FIELD not in event: event[TIMESTAMP_FIELD] = timestamp else: if isinstance(event[TIMESTAMP_FIELD], types.StringTypes): event[TIMESTAMP_FIELD] = parse(event[TIMESTAMP_FIELD]) if isinstance(event[TIMESTAMP_FIELD], datetime): event[TIMESTAMP_FIELD] = datetime_to_kronos_time( event[TIMESTAMP_FIELD]) event[LIBRARY_FIELD] = { 'version': pykronos.__version__, 'name': 'pykronos' } namespace = namespace or self.namespace if self._blocking: return self._put(namespace, event_dict) else: with self._put_lock: self._put_queue.append((namespace, event_dict))