class QuickStartTest(BaseTestCase): def setUp(self): self.log.info("Setting up the engine") template_path = pjoin(self.test_context.engine_directory, "recommendation-engine") engine_json_path = pjoin(self.test_context.data_directory, "quickstart_test/engine.json") self.training_data_path = pjoin(self.test_context.data_directory, "quickstart_test/training_data.txt") # downloading training data srun('curl https://raw.githubusercontent.com/apache/spark/master/' \ 'data/mllib/sample_movielens_data.txt --create-dirs -o {}' .format(self.training_data_path)) app_context = AppContext(name="MyRecommender", template=template_path, engine_json_path=engine_json_path) self.app = AppEngine(self.test_context, app_context) def engine_dir_test(self): self.log.info("Stopping deployed engine") self.app.stop() self.log.info("Creating dummy directory") engine_path = self.app.engine_path dummy_path = "{}/dummy".format(engine_path) srun("mkdir -p {}".format(dummy_path)) self.log.info("Testing pio commands in dummy directory with " + "--engine-dir argument") self.app.engine_path = dummy_path self.log.info("Building an engine...") self.app.build(engine_dir=engine_path) self.log.info("Training...") self.app.train(engine_dir=engine_path) self.log.info("Deploying and waiting 30s for it to start...") self.app.deploy(wait_time=30, engine_dir=engine_path) self.log.info("Sending a single query and checking results") user_query = {"user": 1, "num": 4} r = self.app.query(user_query) self.assertEqual(200, r.status_code) result = r.json() self.assertEqual(4, len(result['itemScores'])) self.log.info("Deleting dummy directory") srun("rm -rf {}".format(dummy_path)) self.app.engine_path = engine_path def runTest(self): self.log.info("Adding a new application") self.app.new() event1 = { "event": "rate", "entityType": "user", "entityId": "u0", "targetEntityType": "item", "targetEntityId": "i0", "properties": { "rating": 5 }, "eventTime": "2014-11-02T09:39:45.618-08:00" } event2 = { "event": "buy", "entityType": "user", "entityId": "u1", "targetEntityType": "item", "targetEntityId": "i2", "eventTime": "2014-11-10T12:34:56.123-08:00" } self.log.info("Sending two test events") self.assertListEqual( [201, 201], [self.app.send_event(e).status_code for e in [event1, event2]]) self.log.info("Checking the number of events stored on the server") r = self.app.get_events() self.assertEquals(200, r.status_code) stored_events = r.json() self.assertEqual(2, len(stored_events)) self.log.info("Importing many events") new_events = read_events(self.training_data_path) for ev in new_events: r = self.app.send_event(ev) self.assertEqual(201, r.status_code) self.log.info("Checking the number of events stored on eventserver") r = self.app.get_events(params={'limit': -1}) self.assertEquals(200, r.status_code) stored_events = r.json() self.assertEquals(len(new_events) + 2, len(stored_events)) self.log.info("Building an engine...") self.app.build() self.log.info("Training...") self.app.train() self.log.info("Deploying and waiting 35s for it to start...") self.app.deploy(wait_time=35) self.log.info("Testing pio commands outside of engine directory") self.engine_dir_test() self.log.info("Sending a single query and checking results") user_query = {"user": 1, "num": 4} r = self.app.query(user_query) self.assertEqual(200, r.status_code) result = r.json() self.assertEqual(4, len(result['itemScores'])) def tearDown(self): self.log.info("Stopping deployed engine") self.app.stop() self.log.info("Deleting all related data") self.app.delete_data() self.log.info("Removing an app") self.app.delete()
class EventserverTest(BaseTestCase): """ Integration test for PredictionIO Eventserver API Refer to below for further information: http://predictionio.incubator.apache.org/datacollection/eventmodel/ http://predictionio.incubator.apache.org/datacollection/eventapi/ """ # Helper methods def eventserver_url(self, path=None): url = 'http://{}:{}'.format(self.test_context.es_ip, self.test_context.es_port) if path: url += '/{}'.format(path) return url def load_events(self, json_file): file_path = pjoin(self.test_context.data_directory, 'eventserver_test/{}'.format(json_file)) return json.loads(open(file_path).read()) def setUp(self): template_path = pjoin(self.test_context.engine_directory, "recommendation-engine") app_context = AppContext(name="MyRecommender", template=template_path) self.app = AppEngine(self.test_context, app_context) def runTest(self): self.log.info("Check if Eventserver is alive and running") r = requests.get(self.eventserver_url()) self.assertDictEqual(r.json(), {"status": "alive"}) self.log.info("Cannot view events with empty accessKey") r = requests.get(self.eventserver_url(path='events.json')) self.assertDictEqual(r.json(), {"message": "Missing accessKey."}) self.log.info("Cannot view events with invalid accessKey") r = requests.get(self.eventserver_url(path='events.json'), params={'accessKey': ''}) self.assertDictEqual(r.json(), {"message": "Invalid accessKey."}) self.log.info("Adding new pio application") self.app.new() self.log.info("No events have been sent yet") r = self.app.get_events() self.assertDictEqual(r.json(), {"message": "Not Found"}) # Testing POST self.log.info("Sending single event") event1 = {'event': 'test', 'entityType': 'test', 'entityId': 't1'} r = self.app.send_event(event1) self.assertEqual(201, r.status_code) self.log.info("Sending batch of events") r = self.app.send_events_batch(self.load_events("rate_events_25.json")) self.assertEqual(200, r.status_code) self.log.info("Cannot send more than 50 events per batch") r = self.app.send_events_batch( self.load_events("signup_events_51.json")) self.assertEqual(400, r.status_code) self.log.info( "Importing events from file does not have batch size limit") self.app.import_events_batch(self.load_events("signup_events_51.json")) self.log.info( "Individual events may fail when sending events as batch") r = self.app.send_events_batch( self.load_events("partially_malformed_events.json")) self.assertEqual(200, r.status_code) self.assertEqual(201, r.json()[0]['status']) self.assertEqual(400, r.json()[1]['status']) # Testing GET for different parameters params = {'event': 'rate'} r = self.app.get_events(params=params) self.assertEqual(20, len(r.json())) self.assertEqual('rate', r.json()[0]['event']) params = {'event': 'rate', 'limit': -1} r = self.app.get_events(params=params) self.assertEqual(25, len(r.json())) self.assertEqual('rate', r.json()[0]['event']) params = {'event': 'rate', 'limit': 10} r = self.app.get_events(params=params) self.assertEqual(10, len(r.json())) self.assertEqual('rate', r.json()[0]['event']) params = {'event': 'rate', 'entityType': 'user', 'entityId': '1'} r = self.app.get_events(params=params) self.assertEqual(5, len(r.json())) self.assertEqual('1', r.json()[0]['entityId']) params = { 'event': 'rate', 'targetEntityType': 'item', 'targetEntityId': '1' } r = self.app.get_events(params=params) self.assertEqual(5, len(r.json())) self.assertEqual('1', r.json()[0]['targetEntityId']) params = { 'event': 'rate', 'entityType': 'user', 'entityId': '1', 'startTime': '2014-11-01T09:39:45.618-08:00', 'untilTime': '2014-11-04T09:39:45.618-08:00' } r = self.app.get_events(params=params) self.assertEqual(3, len(r.json())) self.assertEqual('1', r.json()[0]['entityId']) params = { 'event': 'rate', 'entityType': 'user', 'entityId': '1', 'reversed': 'true' } r = self.app.get_events(params=params) self.assertEqual(5, len(r.json())) event_time = dateutil.parser.parse( r.json()[0]['eventTime']).astimezone(pytz.utc) self.assertEqual('2014-11-05 17:39:45.618000+00:00', str(event_time)) def tearDown(self): self.log.info("Deleting all app data") self.app.delete_data() self.log.info("Deleting app") self.app.delete()
class EventserverTest(BaseTestCase): """ Integration test for PredictionIO Eventserver API Refer to below for further information: http://predictionio.apache.org/datacollection/eventmodel/ http://predictionio.apache.org/datacollection/eventapi/ """ # Helper methods def eventserver_url(self, path=None): url = 'http://{}:{}'.format( self.test_context.es_ip, self.test_context.es_port) if path: url += '/{}'.format(path) return url def load_events(self, json_file): file_path = pjoin(self.test_context.data_directory, 'eventserver_test/{}'.format(json_file)) return json.loads(open(file_path).read()) def setUp(self): template_path = pjoin( self.test_context.engine_directory, "recommendation-engine") app_context = AppContext( name="MyRecommender", template=template_path) self.app = AppEngine(self.test_context, app_context) def runTest(self): self.log.info("Check if Eventserver is alive and running") r = requests.get(self.eventserver_url()) self.assertDictEqual(r.json(), {"status": "alive"}) self.log.info("Cannot view events with empty accessKey") r = requests.get(self.eventserver_url(path='events.json')) self.assertDictEqual(r.json(), {"message": "Missing accessKey."}) self.log.info("Cannot view events with invalid accessKey") r = requests.get(self.eventserver_url(path='events.json'), params={'accessKey': ''}) self.assertDictEqual(r.json(), {"message": "Invalid accessKey."}) self.log.info("Adding new pio application") self.app.new() self.log.info("No events have been sent yet") r = self.app.get_events() self.assertDictEqual(r.json(), {"message": "Not Found"}) # Testing POST self.log.info("Sending single event") event1 = { 'event' : 'test', 'entityType' : 'test', 'entityId' : 't1' } r = self.app.send_event(event1) self.assertEqual(201, r.status_code) self.log.info("Sending batch of events") r = self.app.send_events_batch( self.load_events("rate_events_25.json")) self.assertEqual(200, r.status_code) self.log.info("Cannot send more than 50 events per batch") r = self.app.send_events_batch( self.load_events("signup_events_51.json")) self.assertEqual(400, r.status_code) self.log.info("Importing events from file does not have batch size limit") self.app.import_events_batch( self.load_events("signup_events_51.json")) self.log.info("Individual events may fail when sending events as batch") r = self.app.send_events_batch( self.load_events("partially_malformed_events.json")) self.assertEqual(200, r.status_code) self.assertEqual(201, r.json()[0]['status']) self.assertEqual(400, r.json()[1]['status']) # Testing GET for different parameters params = {'event': 'rate'} r = self.app.get_events(params=params) self.assertEqual(20, len(r.json())) self.assertEqual('rate', r.json()[0]['event']) params = { 'event': 'rate', 'limit': -1 } r = self.app.get_events(params=params) self.assertEqual(25, len(r.json())) self.assertEqual('rate', r.json()[0]['event']) params = { 'event': 'rate', 'limit': 10 } r = self.app.get_events(params=params) self.assertEqual(10, len(r.json())) self.assertEqual('rate', r.json()[0]['event']) params = { 'event': 'rate', 'entityType': 'user', 'entityId': '1' } r = self.app.get_events(params=params) self.assertEqual(5, len(r.json())) self.assertEqual('1', r.json()[0]['entityId']) params = { 'event': 'rate', 'targetEntityType': 'item', 'targetEntityId': '1' } r = self.app.get_events(params=params) self.assertEqual(5, len(r.json())) self.assertEqual('1', r.json()[0]['targetEntityId']) params = { 'event': 'rate', 'entityType': 'user', 'entityId': '1', 'startTime': '2014-11-01T09:39:45.618-08:00', 'untilTime': '2014-11-04T09:39:45.618-08:00' } r = self.app.get_events(params=params) self.assertEqual(3, len(r.json())) self.assertEqual('1', r.json()[0]['entityId']) params = { 'event': 'rate', 'entityType': 'user', 'entityId': '1', 'reversed': 'true' } r = self.app.get_events(params=params) self.assertEqual(5, len(r.json())) event_time = dateutil.parser.parse(r.json()[0]['eventTime']).astimezone(pytz.utc) self.assertEqual('2014-11-05 17:39:45.618000+00:00', str(event_time)) def tearDown(self): self.log.info("Deleting all app data") self.app.delete_data() self.log.info("Deleting app") self.app.delete()
class QuickStartTest(BaseTestCase): def setUp(self): self.log.info("Setting up the engine") template_path = pjoin( self.test_context.engine_directory, "recommendation-engine") engine_json_path = pjoin( self.test_context.data_directory, "quickstart_test/engine.json") self.training_data_path = pjoin( self.test_context.data_directory, "quickstart_test/training_data.txt") # downloading training data srun('curl https://raw.githubusercontent.com/apache/spark/master/' \ 'data/mllib/sample_movielens_data.txt --create-dirs -o {}' .format(self.training_data_path)) app_context = AppContext( name="MyRecommender", template=template_path, engine_json_path=engine_json_path) self.app = AppEngine(self.test_context, app_context) def runTest(self): self.log.info("Adding a new application") self.app.new() event1 = { "event" : "rate", "entityType" : "user", "entityId" : "u0", "targetEntityType" : "item", "targetEntityId" : "i0", "properties" : { "rating" : 5 }, "eventTime" : "2014-11-02T09:39:45.618-08:00" } event2 = { "event" : "buy", "entityType" : "user", "entityId" : "u1", "targetEntityType" : "item", "targetEntityId" : "i2", "eventTime" : "2014-11-10T12:34:56.123-08:00" } self.log.info("Sending two test events") self.assertListEqual( [201, 201], [self.app.send_event(e).status_code for e in [event1, event2]]) self.log.info("Checking the number of events stored on the server") r = self.app.get_events() self.assertEquals(200, r.status_code) stored_events = r.json() self.assertEqual(2, len(stored_events)) self.log.info("Importing many events") new_events = read_events(self.training_data_path) for ev in new_events: r = self.app.send_event(ev) self.assertEqual(201, r.status_code) self.log.info("Checking the number of events stored on the server after the update") r = self.app.get_events(params={'limit': -1}) self.assertEquals(200, r.status_code) stored_events = r.json() self.assertEquals(len(new_events) + 2, len(stored_events)) self.log.info("Building an engine...") self.app.build() self.log.info("Training...") self.app.train() self.log.info("Deploying and waiting 15s for it to start...") self.app.deploy(wait_time=15) self.log.info("Sending a single query and checking results") user_query = { "user": 1, "num": 4 } r = self.app.query(user_query) self.assertEqual(200, r.status_code) result = r.json() self.assertEqual(4, len(result['itemScores'])) def tearDown(self): self.log.info("Stopping deployed engine") self.app.stop() self.log.info("Deleting all related data") self.app.delete_data() self.log.info("Removing an app") self.app.delete()