예제 #1
0
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()