class TestBackendPerformance(PerformanceTestCase): """ Makes use of real backend systems to see how long it takes for the backend to commit events to stable storage. """ def setUp(self): super(TestBackendPerformance, self).setUp() self.database_name = 'perf_test_eventtracking_' + str(uuid4()) self.mongo_backend = MongoBackend(database=self.database_name) self.tracker = Tracker({ 'mongo': self.mongo_backend }) def tearDown(self): self.mongo_backend.connection.drop_database(self.database_name) super(TestBackendPerformance, self).tearDown() def test_sequential_events(self): with self.assert_execution_time_less_than_threshold(): for i in range(self.num_events): self.tracker.emit('perf.event', { 'sequence': i, 'payload': self.random_payload })
def setUp(self): super(TestBackendPerformance, self).setUp() self.database_name = 'perf_test_eventtracking_' + str(uuid4()) self.mongo_backend = MongoBackend(database=self.database_name) self.tracker = Tracker({ 'mongo': self.mongo_backend })
def setUp(self): self.database_name = 'test_eventtracking_' + str(uuid4()) self.mongo_backend = MongoBackend(database=self.database_name) self.memory_backend = InMemoryBackend() self.tracker = Tracker({ 'mongo': self.mongo_backend, 'mem': self.memory_backend })
class TestLoggerIntegration(IntegrationTestCase): """ Writes a real log file and ensures the messages are written properly. """ def setUp(self): super(TestLoggerIntegration, self).setUp() logger_name = 'integration.test' test_logger = logging.getLogger(logger_name) test_logger.setLevel(logging.INFO) self.temporary_fd, self.temporary_file_name = tempfile.mkstemp() self.addCleanup(os.remove, self.temporary_file_name) self.temporary_file_handler = logging.FileHandler( self.temporary_file_name, mode='w', encoding='utf_8') self.temporary_file_handler.setFormatter( logging.Formatter(fmt='%(message)s')) test_logger.addHandler(self.temporary_file_handler) self.addCleanup(test_logger.removeHandler, self.temporary_file_handler) self.logger_backend = LoggerBackend(name=logger_name) self.memory_backend = InMemoryBackend() self.tracker = Tracker({ 'logger': self.logger_backend, 'mem': self.memory_backend }) def test_sequential_events(self): now = datetime.now(UTC) for i in range(10): self.tracker.emit( 'org.test.logger.integration', { 'email': '*****@*****.**', 'sequence': i, 'current_time': now }) # The custom JSON encoder will string encode these fields, however # it is not used to decode the events, so we need to compare these # fields as strings. for event in self.memory_backend.events: event['timestamp'] = event['timestamp'].isoformat() event['data']['current_time'] = event['data'][ 'current_time'].isoformat() self.assertEqual(len(self.memory_backend.events), 10) written_events = [] with os.fdopen(self.temporary_fd, 'r') as temporary_file: for line in temporary_file: loaded_event = json.loads(line.strip()) written_events.append(loaded_event) self.assertEqual(written_events, self.memory_backend.events)
class TestLoggerIntegration(IntegrationTestCase): """ Writes a real log file and ensures the messages are written properly. """ def setUp(self): super(TestLoggerIntegration, self).setUp() logger_name = 'integration.test' test_logger = logging.getLogger(logger_name) test_logger.setLevel(logging.INFO) self.temporary_fd, self.temporary_file_name = tempfile.mkstemp() self.addCleanup(os.remove, self.temporary_file_name) self.temporary_file_handler = logging.FileHandler(self.temporary_file_name, mode='w', encoding='utf_8') self.temporary_file_handler.setFormatter(logging.Formatter(fmt='%(message)s')) test_logger.addHandler(self.temporary_file_handler) self.addCleanup(test_logger.removeHandler, self.temporary_file_handler) self.logger_backend = LoggerBackend(name=logger_name) self.memory_backend = InMemoryBackend() self.tracker = Tracker({ 'logger': self.logger_backend, 'mem': self.memory_backend }) def test_sequential_events(self): now = datetime.now(UTC) for i in range(10): self.tracker.emit('org.test.logger.integration', { 'email': '*****@*****.**', 'sequence': i, 'current_time': now }) # The custom JSON encoder will string encode these fields, however # it is not used to decode the events, so we need to compare these # fields as strings. for event in self.memory_backend.events: event['timestamp'] = event['timestamp'].isoformat() event['data']['current_time'] = event['data']['current_time'].isoformat() self.assertEqual(len(self.memory_backend.events), 10) written_events = [] with os.fdopen(self.temporary_fd, 'r') as temporary_file: for line in temporary_file: loaded_event = json.loads(line.strip()) written_events.append(loaded_event) self.assertEqual(written_events, self.memory_backend.events)
def setUp(self): super(TestLoggerIntegration, self).setUp() logger_name = 'integration.test' test_logger = logging.getLogger(logger_name) test_logger.setLevel(logging.INFO) self.temporary_fd, self.temporary_file_name = tempfile.mkstemp() self.addCleanup(os.remove, self.temporary_file_name) self.temporary_file_handler = logging.FileHandler(self.temporary_file_name, mode='w', encoding='utf_8') self.temporary_file_handler.setFormatter(logging.Formatter(fmt='%(message)s')) test_logger.addHandler(self.temporary_file_handler) self.addCleanup(test_logger.removeHandler, self.temporary_file_handler) self.logger_backend = LoggerBackend(name=logger_name) self.memory_backend = InMemoryBackend() self.tracker = Tracker({ 'logger': self.logger_backend, 'mem': self.memory_backend })
def setUp(self): logger_name = 'integration.test' test_logger = logging.getLogger(logger_name) test_logger.setLevel(logging.INFO) self.temporary_fd, self.temporary_file_name = tempfile.mkstemp() self.addCleanup(os.remove, self.temporary_file_name) self.temporary_file_handler = logging.FileHandler(self.temporary_file_name, mode='w', encoding='utf_8') self.temporary_file_handler.setFormatter(logging.Formatter(fmt='%(message)s')) test_logger.addHandler(self.temporary_file_handler) self.addCleanup(test_logger.removeHandler, self.temporary_file_handler) self.logger_backend = LoggerBackend(name=logger_name) self.memory_backend = InMemoryBackend() self.tracker = Tracker({ 'logger': self.logger_backend, 'mem': self.memory_backend })
class TestMongoIntegration(IntegrationTestCase): """ Makes use of a real MongoDB instance to ensure the backend is wired up properly to the external system. These tests require a mongodb instance to be running on localhost listening on the default port. """ def setUp(self): super(TestMongoIntegration, self).setUp() self.database_name = 'test_eventtracking_' + str(uuid4()) self.mongo_backend = MongoBackend(database=self.database_name) self.memory_backend = InMemoryBackend() self.tracker = Tracker({ 'mongo': self.mongo_backend, 'mem': self.memory_backend }) def tearDown(self): self.mongo_backend.connection.drop_database(self.database_name) super(TestMongoIntegration, self).tearDown() def test_sequential_events(self): now = datetime.now(UTC) for i in range(10): self.tracker.emit( 'org.test.user.login', { 'username': '******', 'user_id': 10, 'email': '*****@*****.**', 'sequence': i, 'current_time': now }) # Ensure MongoDB has finished writing out the events before we # run our query. self.mongo_backend.connection.fsync() mem_events = {} for event in self.memory_backend.events: mem_events[event['data']['sequence']] = event self.assertEquals(len(mem_events), 10) cursor = self.mongo_backend.collection.find() self.assertEquals(cursor.count(), 10) for event in cursor: mem_event = mem_events[event['data']['sequence']] mem_event['_id'] = event['_id'] if self.are_results_equal(mem_event, event): del mem_events[event['data']['sequence']] self.assertEquals(len(mem_events), 0) def are_results_equal(self, left, right): """ Ensure two events are equivalent. We use a bit of special logic here when comparing timestamps since MongoDB apparently only stores millisecond precision timestamps. Thus, when comparing we ignore the datetime.millisecond property. """ for event in [left, right]: self.remove_microseconds_from_timestamps(event) return left == right def remove_microseconds_from_timestamps(self, event): """Truncate the microseconds from the event timestamp""" event['timestamp'] = event['timestamp'].replace(microsecond=0) event['data']['current_time'] = event['data']['current_time'].replace( microsecond=0)
from eventtracking.tracker import Tracker from eventtracking.backends.logger import LoggerBackend import logging logging.basicConfig(filename='app.log', filemode='a', format='%(name)s - %(levelname)s - %(message)s') log = logging.getLogger("PythonTest") log.setLevel(logging.INFO) backend = LoggerBackend(name="PythonTest") tracker = Tracker(backends={'PythonTest': backend}) tracker.enter_context('my context name', {'page': 'some specific page context'}) tracker.emit('navigation.request p2e', {'url': 'http://www.edx.org/some/path/1'})
class TestMongoIntegration(IntegrationTestCase): """ Makes use of a real MongoDB instance to ensure the backend is wired up properly to the external system. These tests require a mongodb instance to be running on localhost listening on the default port. """ def setUp(self): self.database_name = 'test_eventtracking_' + str(uuid4()) self.mongo_backend = MongoBackend(database=self.database_name) self.memory_backend = InMemoryBackend() self.tracker = Tracker({ 'mongo': self.mongo_backend, 'mem': self.memory_backend }) def tearDown(self): self.mongo_backend.connection.drop_database(self.database_name) def test_sequential_events(self): now = datetime.now(UTC) for i in range(10): self.tracker.emit('org.test.user.login', { 'username': '******', 'user_id': 10, 'email': '*****@*****.**', 'sequence': i, 'current_time': now }) # Ensure MongoDB has finished writing out the events before we # run our query. self.mongo_backend.connection.fsync() mem_events = {} for event in self.memory_backend.events: mem_events[event['data']['sequence']] = event self.assertEquals(len(mem_events), 10) cursor = self.mongo_backend.collection.find() self.assertEquals(cursor.count(), 10) for event in cursor: mem_event = mem_events[event['data']['sequence']] mem_event['_id'] = event['_id'] if self.are_results_equal(mem_event, event): del mem_events[event['data']['sequence']] self.assertEquals(len(mem_events), 0) def are_results_equal(self, left, right): """ Ensure two events are equivalent. We use a bit of special logic here when comparing timestamps since MongoDB apparently only stores millisecond precision timestamps. Thus, when comparing we ignore the datetime.millisecond property. """ for event in [left, right]: self.remove_microseconds_from_timestamps(event) return left == right def remove_microseconds_from_timestamps(self, event): """Truncate the microseconds from the event timestamp""" event['timestamp'] = event['timestamp'].replace(microsecond=0) event['data']['current_time'] = event['data']['current_time'].replace(microsecond=0)