Add travis test and Refactoring

Closes #22
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..50d98a9
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,34 @@
+sudo: required
+
+language: python
+
+jdk:
+  - oraclejdk8
+
+python:
+  - 2.7
+  - 3.4
+  - 3.5
+  - 3.6
+
+cache:
+  directories:
+    - $HOME/.ivy2/cache
+    - $HOME/.sbt/boot
+    - $HOME/.sbt/launchers
+
+install:
+  - pip install tox tox-travis
+  - pip install coverage coveralls
+
+before_script:
+  - java -version
+  - ./tests/before_script.travis.sh
+  - export PATH=$PATH:$PWD/predictionio-setup/predictionio/bin
+
+script:
+  - pio status
+  - tox -r
+
+after_script:
+  - ./tests/after_script.travis.sh
diff --git a/README.txt b/README.txt
index 2a542a0..4740ff5 100644
--- a/README.txt
+++ b/README.txt
@@ -1,63 +1,59 @@
-PredictionIO Python SDK

-=======================

-

-

-Installation

-============

-

-To install the module from PyPI, you may

-

-    $ pip install predictionio

-

-or

-

-    $ easy_install predictionio

-

-If you have cloned the repository and want to install directly from there,

-do the following in the root directory of the repository:

-

-    $ python setup.py install

-

-This will install the "predictionio" module to your Python distribution.

-

-

-Usage

-=====

-

-To use predictionio in your Python script,

-

-    >>> import predictionio

-

-

-Documentation

-=============

-

-The latest documentation is located at http://pythonhosted.org/PredictionIO/

-

-If you want to build a local copy, please install Sphinx

-(http://sphinx-doc.org/install.html).

-

-To generate documentation,

-

-    % cd docs

-    % make html

-

-To view the generated documentation, go to docs/build/html/index.html.

-

-

-SUPPORT

-=======

-

-

-Forum

------

-

-https://groups.google.com/group/predictionio-user

-

-

-Issue Tracker

--------------

-

-https://predictionio.atlassian.net

-

-If you are unsure whether a behavior is an issue, bringing it up in the forum is highly encouraged.

+PredictionIO Python SDK
+=======================
+
+
+Installation
+============
+
+To install the module from PyPI, you may
+
+    $ pip install predictionio
+
+or
+
+    $ easy_install predictionio
+
+If you have cloned the repository and want to install directly from there,
+do the following in the root directory of the repository:
+
+    $ python setup.py install
+
+This will install the "predictionio" module to your Python distribution.
+
+
+Usage
+=====
+
+To use predictionio in your Python script,
+
+    >>> import predictionio
+
+
+Documentation
+=============
+
+The latest documentation is located at http://pythonhosted.org/PredictionIO/
+
+If you want to build a local copy, please install Sphinx
+(http://sphinx-doc.org/install.html).
+
+To generate documentation,
+
+    % cd docs
+    % make html
+
+To view the generated documentation, go to docs/build/html/index.html.
+
+
+SUPPORT
+=======
+
+http://predictionio.incubator.apache.org/support/
+
+
+Issue Tracker
+-------------
+
+https://issues.apache.org/jira/projects/PIO
+
+If you are unsure whether a behavior is an issue, bringing it up in the forum is highly encouraged.
diff --git a/predictionio/__init__.py b/predictionio/__init__.py
index b429b4e..01ac045 100644
--- a/predictionio/__init__.py
+++ b/predictionio/__init__.py
@@ -21,6 +21,12 @@
   # pylint: disable=F0401,E0611
   from urllib.parse import urlencode
 
+try:
+  from urllib import quote
+except ImportError:
+  # pylint: disable=F0401,E0611
+  from urllib.parse import quote
+
 import json
 import urllib
 
@@ -260,7 +266,7 @@
     if self.channel is not None:
       qparam["channel"] = self.channel
 
-    enc_event_id = urllib.quote(event_id, "") # replace special char with %xx
+    enc_event_id = quote(event_id, "") # replace special char with %xx
     path = "/events/%s.json" % (enc_event_id, )
     request = AsyncRequest("GET", path, **qparam)
     request.set_rfunc(self._aget_resp)
@@ -335,7 +341,7 @@
     if self.channel is not None:
       qparam["channel"] = self.channel
 
-    enc_event_id = urllib.quote(event_id, "") # replace special char with %xx
+    enc_event_id = quote(event_id, "") # replace special char with %xx
     path = "/events/%s.json" % (enc_event_id, )
     request = AsyncRequest("DELETE", path, **qparam)
     request.set_rfunc(self._adelete_resp)
@@ -519,7 +525,7 @@
 
   def create_event(self, event, entity_type, entity_id,
       target_entity_type=None, target_entity_id=None, properties=None,
-      event_time=None):
+      event_time=None, ensure_ascii=True):
     """Create an event and write to the file.
     (please refer to EventClient's create_event())
     """
@@ -544,7 +550,7 @@
     et_str = et.strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + et.strftime("%z")
     data["eventTime"] = et_str
 
-    j = json.dumps(data)
+    j = json.dumps(data, ensure_ascii=ensure_ascii)
     self._file.write(j+"\n")
 
   def close(self):
diff --git a/tests-obsolete/conversion_test.py b/tests-obsolete/conversion_test.py
deleted file mode 100644
index b9dca97..0000000
--- a/tests-obsolete/conversion_test.py
+++ /dev/null
@@ -1,16 +0,0 @@
-import timeit
-
-if __name__ == "__main__":
-    a = True
-
-    t = timeit.Timer("json.dumps(True)", "import json")
-
-    t_bool2json = t.timeit(1000) / 1000
-    print("bool 2 json")
-    print(t_bool2json)
-
-    t = timeit.Timer("str(True).lower()", "")
-
-    t_bool2string = t.timeit(1000) / 1000
-    print("bool 2 string")
-    print(t_bool2string)
diff --git a/tests-obsolete/import_testdata.py b/tests-obsolete/import_testdata.py
deleted file mode 100644
index e5338c0..0000000
--- a/tests-obsolete/import_testdata.py
+++ /dev/null
@@ -1,46 +0,0 @@
-"""
-Import simple test data for testing getting itemrec
-"""
-import predictionio
-
-APP_KEY = "gDx1XuMUC9vu1YWWPRZkLRTftoq7m73mlj2MtnZEjncPlZ1JxUS2s7oajwP9xrZQ"
-API_URL = "http://localhost:7070"
-
-MIN_VERSION = '0.5.0'
-if predictionio.__version__ < MIN_VERSION:
-    err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
-    raise Exception(err)
-
-if __name__ == "__main__":
-    client = predictionio.Client(APP_KEY, 1, API_URL)
-
-    client.create_user("u0")
-    client.create_user("u1")
-    client.create_user("u2")
-    client.create_user("u3")
-
-    client.create_item("i0", ("t1",), {"custom1": "i0c1"})
-    client.create_item("i1", ("t1", "t2"), {"custom1": "i1c1", "custom2": "i1c2"})
-    client.create_item("i2", ("t1", "t2"), {"custom2": "i2c2"})
-    client.create_item("i3", ("t1",))
-
-    client.identify("u0")
-    client.record_action_on_item("rate", "i0", {"pio_rate": 2})
-    client.record_action_on_item("rate", "i1", {"pio_rate": 3})
-    client.record_action_on_item("rate", "i2", {"pio_rate": 4})
-
-    client.identify("u1")
-    client.record_action_on_item("rate", "i2", {"pio_rate": 4})
-    client.record_action_on_item("rate", "i3", {"pio_rate": 1})
-
-    client.identify("u2")
-    client.record_action_on_item("rate", "i1", {"pio_rate": 2})
-    client.record_action_on_item("rate", "i2", {"pio_rate": 1})
-    client.record_action_on_item("rate", "i3", {"pio_rate": 3})
-
-    client.identify("u3")
-    client.record_action_on_item("rate", "i0", {"pio_rate": 5})
-    client.record_action_on_item("rate", "i1", {"pio_rate": 3})
-    client.record_action_on_item("rate", "i3", {"pio_rate": 2})
-
-    client.close()
diff --git a/tests-obsolete/import_testdata_id_mismatch.py b/tests-obsolete/import_testdata_id_mismatch.py
deleted file mode 100644
index 104f75c..0000000
--- a/tests-obsolete/import_testdata_id_mismatch.py
+++ /dev/null
@@ -1,46 +0,0 @@
-"""
-Import simple test data for testing getting itemrec
-"""
-import predictionio
-
-APP_KEY = "gDx1XuMUC9vu1YWWPRZkLRTftoq7m73mlj2MtnZEjncPlZ1JxUS2s7oajwP9xrZQ"
-API_URL = "http://localhost:8000"
-
-MIN_VERSION = '0.5.0'
-if predictionio.__version__ < MIN_VERSION:
-    err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
-    raise Exception(err)
-
-if __name__ == "__main__":
-    client = predictionio.Client(APP_KEY, 1, API_URL)
-
-    client.create_user("u0")
-    client.create_user("u1")
-    client.create_user("u2")
-    client.create_user("u3")
-
-    client.create_item("i0", ("t1",), {"custom1": "i0c1"})
-    client.create_item("i1", ("t1", "t2"), {"custom1": "i1c1", "custom2": "i1c2"})
-    client.create_item("i2", ("t1", "t2"), {"custom2": "i2c2"})
-    client.create_item("i3", ("t1",))
-
-    client.identify("u0x")
-    client.record_action_on_item("rate", "i0", {"pio_rate": 2})
-    client.record_action_on_item("rate", "i1", {"pio_rate": 3})
-    client.record_action_on_item("rate", "i2", {"pio_rate": 4})
-
-    client.identify("u1x")
-    client.record_action_on_item("rate", "i2", {"pio_rate": 4})
-    client.record_action_on_item("rate", "i3", {"pio_rate": 1})
-
-    client.identify("u2x")
-    client.record_action_on_item("rate", "i1", {"pio_rate": 2})
-    client.record_action_on_item("rate", "i2", {"pio_rate": 1})
-    client.record_action_on_item("rate", "i3", {"pio_rate": 3})
-
-    client.identify("u3x")
-    client.record_action_on_item("rate", "i0", {"pio_rate": 5})
-    client.record_action_on_item("rate", "i1", {"pio_rate": 3})
-    client.record_action_on_item("rate", "i3", {"pio_rate": 2})
-
-    client.close()
diff --git a/tests-obsolete/import_testdata_special_char.py b/tests-obsolete/import_testdata_special_char.py
deleted file mode 100644
index c047b6a..0000000
--- a/tests-obsolete/import_testdata_special_char.py
+++ /dev/null
@@ -1,46 +0,0 @@
-"""
-Import simple test data (id with special characters) for testing getting itemrec
-"""
-import predictionio
-
-APP_KEY = "gDx1XuMUC9vu1YWWPRZkLRTftoq7m73mlj2MtnZEjncPlZ1JxUS2s7oajwP9xrZQ"
-API_URL = "http://localhost:8000"
-
-MIN_VERSION = '0.5.0'
-if predictionio.__version__ < MIN_VERSION:
-    err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
-    raise Exception(err)
-
-if __name__ == "__main__":
-    client = predictionio.Client(APP_KEY, 1, API_URL)
-
-    client.create_user("u0@u.n")
-    client.create_user("u1@u.n")
-    client.create_user("http://u2.com")
-    client.create_user("u3@u.n")
-
-    client.create_item("http://i0.com", ("t1",), {"custom1": "i0c1"})
-    client.create_item("i1@i1", ("t1", "t2"), {"custom1": "i1c1", "custom2": "i1c2"})
-    client.create_item("i2.org", ("t1", "t2"), {"custom2": "i2c2"})
-    client.create_item("i3", ("t1",))
-
-    client.identify("u0@u.n")
-    client.record_action_on_item("rate", "http://i0.com", {"pio_rate": 2})
-    client.record_action_on_item("rate", "i1@i1", {"pio_rate": 3})
-    client.record_action_on_item("rate", "i2.org", {"pio_rate": 4})
-
-    client.identify("u1@u.n")
-    client.record_action_on_item("rate", "i2.org", {"pio_rate": 4})
-    client.record_action_on_item("rate", "i3", {"pio_rate": 1})
-
-    client.identify("http://u2.com")
-    client.record_action_on_item("rate", "i1@i1", {"pio_rate": 2})
-    client.record_action_on_item("rate", "i2.org", {"pio_rate": 1})
-    client.record_action_on_item("rate", "i3", {"pio_rate": 3})
-
-    client.identify("u3@u.n")
-    client.record_action_on_item("rate", "http://i0.com", {"pio_rate": 5})
-    client.record_action_on_item("rate", "i1@i1", {"pio_rate": 3})
-    client.record_action_on_item("rate", "i3", {"pio_rate": 2})
-
-    client.close()
diff --git a/tests-obsolete/predictionio_itemrec_test.py b/tests-obsolete/predictionio_itemrec_test.py
deleted file mode 100644
index 3105f0f..0000000
--- a/tests-obsolete/predictionio_itemrec_test.py
+++ /dev/null
@@ -1,336 +0,0 @@
-"""
-Test getting itemrec after algo training completes.
-"""
-
-from __future__ import print_function
-
-import unittest
-
-import predictionio
-
-
-APP_KEY = "gDx1XuMUC9vu1YWWPRZkLRTftoq7m73mlj2MtnZEjncPlZ1JxUS2s7oajwP9xrZQ"  # replace this with your AppKey
-API_URL = "http://localhost:8000"  # PredictoinIO Server
-
-DEBUG = True
-
-MIN_VERSION = '0.6.0'
-if predictionio.__version__ < MIN_VERSION:
-    err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
-    raise Exception(err)
-
-
-class TestPredictionIO(unittest.TestCase):
-    def setUp(self):
-        pass
-
-    def tearDown(self):
-        pass
-
-    def test_get_itemrec_exception_deprecated(self):
-        client = predictionio.Client(APP_KEY, 1, API_URL)
-
-        try:
-            client.get_itemrec("uidwithoutrec", 10, "python-itemrec-engine")
-        except predictionio.ItemRecNotFoundError as e:  # noqa
-            pass  # expected exception
-        except:
-            raise
-
-        client.close()
-
-    def test_get_itemrec_exception(self):
-        client = predictionio.Client(APP_KEY, 1, API_URL)
-
-        client.identify("uidwithoutrec")
-
-        try:
-            client.get_itemrec_topn("python-itemrec-engine", 10)
-        except predictionio.ItemRecNotFoundError as e:  # noqa
-            pass  # expected exception
-        except:
-            raise
-
-        try:
-            client.get_itemrec_topn("python-itemrec-engine", 10,
-                                    {"pio_itypes": ("t1",), "pio_latlng": [1.34, 5.67], "pio_within": 5.0,
-                                     "pio_unit": "km", "pio_attributes": ["custom1", "custom2"]})
-        except predictionio.ItemRecNotFoundError as e:  # noqa
-            pass  # expected exception
-        except:
-            raise
-
-        client.close()
-
-    def test_get_itemrec_deprecated(self):
-        client = predictionio.Client(APP_KEY, 1, API_URL)
-
-        # request more
-        try:
-            itemrec = client.get_itemrec("u0", 10, "python-itemrec-engine")
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-        if DEBUG:
-            print(itemrec)
-        self.assertEqual(itemrec, {"pio_iids": ["i2", "i3", "i1", "i0"]})
-
-        try:
-            itemrec = client.get_itemrec("u1", 10, "python-itemrec-engine")
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-        if DEBUG:
-            print(itemrec)
-
-        self.assertTrue((itemrec == {"pio_iids": ["i2", "i1", "i0", "i3"]}) or
-                        (itemrec == {"pio_iids": ["i2", "i0", "i1", "i3"]}))
-
-        try:
-            itemrec = client.get_itemrec("u2", 10, "python-itemrec-engine")
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-        if DEBUG:
-            print(itemrec)
-        self.assertTrue((itemrec == {"pio_iids": ["i3", "i0", "i1", "i2"]}) or
-                        (itemrec == {"pio_iids": ["i3", "i1", "i0", "i2"]}))
-
-        try:
-            itemrec = client.get_itemrec("u3", 6, "python-itemrec-engine")
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-        if DEBUG:
-            print(itemrec)
-        self.assertTrue((itemrec == {"pio_iids": ["i0", "i1", "i2", "i3"]}) or
-                        (itemrec == {"pio_iids": ["i0", "i2", "i1", "i3"]}))
-
-        # request less
-        try:
-            itemrec = client.get_itemrec("u0", 1, "python-itemrec-engine")
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-        if DEBUG:
-            print(itemrec)
-        self.assertEqual(itemrec, {"pio_iids": ["i2"]})
-
-        try:
-            itemrec = client.get_itemrec("u0", 2, "python-itemrec-engine")
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-        if DEBUG:
-            print(itemrec)
-        self.assertEqual(itemrec, {"pio_iids": ["i2", "i3"]})
-
-        # request with optional attributes
-
-        # pio_itypes
-        try:
-            itemrec = client.get_itemrec("u0", 10, "python-itemrec-engine", pio_itypes=("t1", "t2"))
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-        if DEBUG:
-            print(itemrec)
-        self.assertEqual(itemrec, {"pio_iids": ["i2", "i3", "i1", "i0"]})
-
-        # subset itypes
-        try:
-            itemrec = client.get_itemrec("u0", 10, "python-itemrec-engine", pio_itypes=("t2",))
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-        if DEBUG:
-            print(itemrec)
-        self.assertEqual(itemrec, {"pio_iids": ["i2", "i1"]})
-
-        # nonexisting itypes
-        try:
-            itemrec = client.get_itemrec("u0", 10, "python-itemrec-engine", pio_itypes=("other-itype",))
-        except predictionio.ItemRecNotFoundError as e:
-            pass  # expected no recommendation
-        except:
-            raise
-
-        # pio_attributes
-        try:
-            itemrec = client.get_itemrec("u0", 10, "python-itemrec-engine", pio_itypes=("t1",),
-                                         pio_attributes=["custom1", "custom2"])
-        except predictionio.ItemRecNotFoundError as e:  # noqa
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertEqual(itemrec, {"pio_iids": ["i2", "i3", "i1", "i0"], "custom1": [None, None, "i1c1", "i0c1"],
-                                   "custom2": ["i2c2", None, "i1c2", None]})
-
-        client.close()
-
-    def test_get_itemrec(self):
-        client = predictionio.Client(APP_KEY, 1, API_URL)
-
-        # request more
-        client.identify("u0")
-        try:
-            itemrec = client.get_itemrec_topn("python-itemrec-engine", 10)
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertEqual(itemrec, {"pio_iids": ["i2", "i3", "i1", "i0"]})
-
-        client.identify("u1")
-        try:
-            itemrec = client.get_itemrec_topn("python-itemrec-engine", 10)
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-        if DEBUG:
-            print(itemrec)
-        self.assertTrue((itemrec == {"pio_iids": ["i2", "i1", "i0", "i3"]}) or
-                        (itemrec == {"pio_iids": ["i2", "i0", "i1", "i3"]}))
-
-        client.identify("u2")
-        try:
-            itemrec = client.get_itemrec_topn("python-itemrec-engine", 10)
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-        if DEBUG:
-            print(itemrec)
-        self.assertTrue((itemrec == {"pio_iids": ["i3", "i0", "i1", "i2"]}) or
-                        (itemrec == {"pio_iids": ["i3", "i1", "i0", "i2"]}))
-
-        client.identify("u3")
-        try:
-            itemrec = client.get_itemrec_topn("python-itemrec-engine", 6)
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-        if DEBUG:
-            print(itemrec)
-        self.assertTrue((itemrec == {"pio_iids": ["i0", "i1", "i2", "i3"]}) or
-                        (itemrec == {"pio_iids": ["i0", "i2", "i1", "i3"]}))
-
-        # request less
-        client.identify("u0")
-        try:
-            itemrec = client.get_itemrec_topn("python-itemrec-engine", 1)
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-        if DEBUG:
-            print(itemrec)
-        self.assertEqual(itemrec, {"pio_iids": ["i2"]})
-
-        client.identify("u0")
-        try:
-            itemrec = client.get_itemrec_topn("python-itemrec-engine", 2)
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-        if DEBUG:
-            print(itemrec)
-        self.assertEqual(itemrec, {"pio_iids": ["i2", "i3"]})
-
-        # request with optional attributes
-
-        # pio_itypes
-        client.identify("u0")
-        try:
-            itemrec = client.get_itemrec_topn("python-itemrec-engine", 10, {"pio_itypes": ("t1", "t2")})
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-        if DEBUG:
-            print(itemrec)
-        self.assertEqual(itemrec, {"pio_iids": ["i2", "i3", "i1", "i0"]})
-
-        # subset itypes
-        client.identify("u0")
-        try:
-            itemrec = client.get_itemrec_topn("python-itemrec-engine", 10, {"pio_itypes": ("t2",)})
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-        if DEBUG:
-            print(itemrec)
-        self.assertEqual(itemrec, {"pio_iids": ["i2", "i1"]})
-
-        # nonexisting itypes
-        client.identify("u0")
-        try:
-            itemrec = client.get_itemrec_topn("python-itemrec-engine", 10, {"pio_itypes": ("other-itype",)})
-        except predictionio.ItemRecNotFoundError as e:
-            pass  # expected no recommendation
-        except:
-            raise
-
-        # pio_attributes
-        client.identify("u0")
-        try:
-            itemrec = client.get_itemrec_topn("python-itemrec-engine", 10,
-                                              {"pio_itypes": ("t1",), "pio_attributes": ["custom1", "custom2"]})
-        except predictionio.ItemRecNotFoundError as e:  # noqa
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertEqual(itemrec, {"pio_iids": ["i2", "i3", "i1", "i0"], "custom1": [None, None, "i1c1", "i0c1"],
-                                   "custom2": ["i2c2", None, "i1c2", None]})
-
-        # TODO pio_latlng
-        # TODO pio_within
-        # TODO pio_unit
-
-        client.close()
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/tests-obsolete/predictionio_itemrec_test_special_char.py b/tests-obsolete/predictionio_itemrec_test_special_char.py
deleted file mode 100644
index a622800..0000000
--- a/tests-obsolete/predictionio_itemrec_test_special_char.py
+++ /dev/null
@@ -1,366 +0,0 @@
-"""
-Test getting itemrec after algo training completes.
-"""
-import unittest
-
-import predictionio
-
-
-APP_KEY = "gDx1XuMUC9vu1YWWPRZkLRTftoq7m73mlj2MtnZEjncPlZ1JxUS2s7oajwP9xrZQ"  # replace this with your AppKey
-API_URL = "http://localhost:8000"  # PredictoinIO Server
-
-DEBUG = True
-
-MIN_VERSION = '0.6.0'
-if predictionio.__version__ < MIN_VERSION:
-    err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
-    raise Exception(err)
-
-
-class TestPredictionIO(unittest.TestCase):
-    def setUp(self):
-        pass
-
-    def tearDown(self):
-        pass
-
-    def test_get_itemrec_deprecated(self):
-        client = predictionio.Client(APP_KEY, 1, API_URL)
-
-        uid0 = "u0@u.n"
-        uid1 = "u1@u.n"
-        uid2 = "http://u2.com"
-        uid3 = "u3@u.n"
-
-        iid0 = "http://i0.com"
-        iid1 = "i1@i1"
-        iid2 = "i2.org"
-        iid3 = "i3"
-
-        engine_name = "itemrec"
-
-        # request more
-        try:
-            itemrec = client.get_itemrec(uid0, 10, engine_name)
-        except predictionio.ItemRecNotFoundError as e:
-            print(e)
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertEqual(itemrec, {"pio_iids": [iid2, iid3, iid1, iid0]})
-
-        try:
-            itemrec = client.get_itemrec(uid1, 10, engine_name)
-        except predictionio.ItemRecNotFoundError as e:
-            print(e)
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertTrue((itemrec == {"pio_iids": [iid2, iid1, iid0, iid3]}) or
-                        (itemrec == {"pio_iids": [iid2, iid0, iid1, iid3]}))
-
-        try:
-            itemrec = client.get_itemrec(uid2, 10, engine_name)
-        except predictionio.ItemRecNotFoundError as e:
-            print(e)
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertTrue((itemrec == {"pio_iids": [iid3, iid0, iid1, iid2]}) or
-                        (itemrec == {"pio_iids": [iid3, iid1, iid0, iid2]}))
-
-        try:
-            itemrec = client.get_itemrec(uid3, 6, engine_name)
-        except predictionio.ItemRecNotFoundError as e:
-            print(e)
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertTrue((itemrec == {"pio_iids": [iid0, iid1, iid2, iid3]}) or
-                        (itemrec == {"pio_iids": [iid0, iid2, iid1, iid3]}))
-
-        # request less
-        try:
-            itemrec = client.get_itemrec(uid0, 1, engine_name)
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertEqual(itemrec, {"pio_iids": [iid2]})
-
-        try:
-            itemrec = client.get_itemrec(uid0, 2, engine_name)
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertEqual(itemrec, {"pio_iids": [iid2, iid3]})
-
-        # request with optional attributes
-
-        # pio_itypes
-        try:
-            itemrec = client.get_itemrec(uid0, 10, engine_name, pio_itypes=("t1", "t2"))
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertEqual(itemrec, {"pio_iids": [iid2, iid3, iid1, iid0]})
-
-        # subset itypes
-        try:
-            itemrec = client.get_itemrec(uid0, 10, engine_name, pio_itypes=("t2",))
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertEqual(itemrec, {"pio_iids": [iid2, iid1]})
-
-        # nonexisting itypes
-        try:
-            client.get_itemrec(uid0, 10, engine_name, pio_itypes=("other-itype",))
-        except predictionio.ItemRecNotFoundError as e:
-            print(e)
-            pass  # expected no recommendation
-        except:
-            raise
-
-        # pio_attributes
-        try:
-            itemrec = client.get_itemrec(uid0, 10, engine_name, pio_itypes=("t1",),
-                                         pio_attributes=["custom1", "custom2"])
-        except predictionio.ItemRecNotFoundError as e:
-            print(e)
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertEqual(itemrec, {"pio_iids": [iid2, iid3, iid1, iid0], "custom1": [None, None, "i1c1", "i0c1"],
-                                   "custom2": ["i2c2", None, "i1c2", None]})
-
-        client.close()
-
-    def test_get_itemrec(self):
-        client = predictionio.Client(APP_KEY, 1, API_URL)
-
-        uid0 = "u0@u.n"
-        uid1 = "u1@u.n"
-        uid2 = "http://u2.com"
-        uid3 = "u3@u.n"
-
-        iid0 = "http://i0.com"
-        iid1 = "i1@i1"
-        iid2 = "i2.org"
-        iid3 = "i3"
-
-        engine_name = "itemrec"
-
-        # request more
-        client.identify(uid0)
-        try:
-            itemrec = client.get_itemrec_topn(engine_name, 10)
-        except predictionio.ItemRecNotFoundError as e:
-            print(e)
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertEqual(itemrec, {"pio_iids": [iid2, iid3, iid1, iid0]})
-
-        client.identify(uid1)
-        try:
-            itemrec = client.get_itemrec_topn(engine_name, 10)
-        except predictionio.ItemRecNotFoundError as e:
-            print(e)
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertTrue((itemrec == {"pio_iids": [iid2, iid1, iid0, iid3]}) or
-                        (itemrec == {"pio_iids": [iid2, iid0, iid1, iid3]}))
-
-        client.identify(uid2)
-        try:
-            itemrec = client.get_itemrec_topn(engine_name, 10)
-        except predictionio.ItemRecNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertTrue((itemrec == {"pio_iids": [iid3, iid0, iid1, iid2]}) or
-                        (itemrec == {"pio_iids": [iid3, iid1, iid0, iid2]}))
-
-        client.identify(uid3)
-        try:
-            itemrec = client.get_itemrec_topn(engine_name, 6)
-        except predictionio.ItemRecNotFoundError as e:
-            print(e)
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertTrue((itemrec == {"pio_iids": [iid0, iid1, iid2, iid3]}) or
-                        (itemrec == {"pio_iids": [iid0, iid2, iid1, iid3]}))
-
-        # request less
-        client.identify(uid0)
-        try:
-            itemrec = client.get_itemrec_topn(engine_name, 1)
-        except predictionio.ItemRecNotFoundError as e:
-            print(e)
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertEqual(itemrec, {"pio_iids": [iid2]})
-
-        client.identify(uid0)
-        try:
-            itemrec = client.get_itemrec_topn(engine_name, 2)
-        except predictionio.ItemRecNotFoundError as e:
-            print(e)
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertEqual(itemrec, {"pio_iids": [iid2, iid3]})
-
-        # request with optional attributes
-
-        # pio_itypes
-        client.identify(uid0)
-        try:
-            itemrec = client.get_itemrec_topn(engine_name, 10, {"pio_itypes": ("t1", "t2")})
-        except predictionio.ItemRecNotFoundError as e:
-            print(e)
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertEqual(itemrec, {"pio_iids": [iid2, iid3, iid1, iid0]})
-
-        # subset itypes
-        client.identify(uid0)
-        try:
-            itemrec = client.get_itemrec_topn(engine_name, 10, {"pio_itypes": ("t2",)})
-        except predictionio.ItemRecNotFoundError as e:
-            print(e)
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertEqual(itemrec, {"pio_iids": [iid2, iid1]})
-
-        # nonexisting itypes
-        client.identify(uid0)
-        try:
-            client.get_itemrec_topn(engine_name, 10, {"pio_itypes": ("other-itype",)})
-        except predictionio.ItemRecNotFoundError as e:
-            print(e)
-            pass  # expected no recommendation
-        except:
-            raise
-
-        # pio_attributes
-        client.identify(uid0)
-        try:
-            itemrec = client.get_itemrec_topn(engine_name, 10,
-                                              {"pio_itypes": ("t1",), "pio_attributes": ["custom1", "custom2"]})
-        except predictionio.ItemRecNotFoundError as e:
-            print(e)
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemrec)
-
-        self.assertEqual(itemrec, {"pio_iids": [iid2, iid3, iid1, iid0], "custom1": [None, None, "i1c1", "i0c1"],
-                                   "custom2": ["i2c2", None, "i1c2", None]})
-
-        # TODO pio_latlng
-        # TODO pio_within
-        # TODO pio_unit
-
-        client.close()
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/tests-obsolete/predictionio_itemsim_test.py b/tests-obsolete/predictionio_itemsim_test.py
deleted file mode 100644
index 45fa151..0000000
--- a/tests-obsolete/predictionio_itemsim_test.py
+++ /dev/null
@@ -1,200 +0,0 @@
-"""
-Test getting itemsim after algo training completes (pdio-itemsimcf with cosine sim).
-"""
-import unittest
-
-import predictionio
-
-
-APP_KEY = "gDx1XuMUC9vu1YWWPRZkLRTftoq7m73mlj2MtnZEjncPlZ1JxUS2s7oajwP9xrZQ"  # replace this with your AppKey
-API_URL = "http://localhost:8000"  # PredictoinIO Server
-
-DEBUG = True
-
-MIN_VERSION = '0.6.0'
-if predictionio.__version__ < MIN_VERSION:
-    err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
-    raise Exception(err)
-
-
-class TestPredictionIO(unittest.TestCase):
-    def setUp(self):
-        pass
-
-    def tearDown(self):
-        pass
-
-    def test_get_itemsim_exception(self):
-        client = predictionio.Client(APP_KEY, 1, API_URL)
-
-        try:
-            client.get_itemsim_topn("python-itemsim-engine", "iidwithoutsim", 10)
-        except predictionio.ItemSimNotFoundError as e:
-            pass  # expected exception
-        except:
-            raise
-
-        try:
-            client.get_itemsim_topn("python-itemsim-engine", "iidwithoutsim", 10,
-                                    {"pio_itypes": ("t1",), "pio_latlng": [1.34, 5.67], "pio_within": 5.0,
-                                     "pio_unit": "km", "pio_attributes": ["custom1", "custom2"]})
-        except predictionio.ItemSimNotFoundError as e:
-            if DEBUG:
-                print(e)
-            pass  # expected exception
-        except:
-            raise
-
-        client.close()
-
-    def test_get_itemsim(self):
-        client = predictionio.Client(APP_KEY, 1, API_URL)
-
-        # request more than what is available
-        try:
-            itemsim = client.get_itemsim_topn("python-itemsim-engine", "i0", 10)
-        except predictionio.ItemSimNotFoundError as e:
-            print
-            "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemsim)
-
-        self.assertTrue((itemsim == {"pio_iids": ["i1", "i2", "i3"]}) or
-                        (itemsim == {"pio_iids": ["i1", "i3", "i2"]}))
-
-        try:
-            itemsim = client.get_itemsim_topn("python-itemsim-engine", "i1", 10)
-        except predictionio.ItemSimNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemsim)
-
-        self.assertTrue((itemsim == {"pio_iids": ["i2", "i3", "i0"]}))
-
-        try:
-            itemsim = client.get_itemsim_topn("python-itemsim-engine", "i2", 10)
-        except predictionio.ItemSimNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemsim)
-
-        self.assertTrue((itemsim == {"pio_iids": ["i1", "i3", "i0"]}))
-
-        try:
-            itemsim = client.get_itemsim_topn("python-itemsim-engine", "i3", 10)
-        except predictionio.ItemSimNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemsim)
-
-        self.assertTrue((itemsim == {"pio_iids": ["i1", "i2", "i0"]}))
-
-        # request less
-        try:
-            itemsim = client.get_itemsim_topn("python-itemsim-engine", "i1", 1)
-        except predictionio.ItemSimNotFoundError as e:
-            print
-            "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemsim)
-
-        self.assertEqual(itemsim, {"pio_iids": ["i2"]})
-
-        try:
-            itemsim = client.get_itemsim_topn("python-itemsim-engine", "i1", 2)
-        except predictionio.ItemSimNotFoundError as e:
-            print
-            "ERROR: have you run import_testdata.py and then wait for the algorithm training completion?"
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemsim)
-
-        self.assertEqual(itemsim, {"pio_iids": ["i2", "i3"]})
-
-        # request with optional attributes
-
-        # pio_itypes
-        try:
-            itemsim = client.get_itemsim_topn("python-itemsim-engine", "i1", 10, {"pio_itypes": ("t1", "t2")})
-        except predictionio.ItemSimNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemsim)
-
-        self.assertEqual(itemsim, {"pio_iids": ["i2", "i3", "i0"]})
-
-        # subset itypes
-        try:
-            itemsim = client.get_itemsim_topn("python-itemsim-engine", "i1", 10, {"pio_itypes": ("t2",)})
-        except predictionio.ItemSimNotFoundError as e:
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemsim)
-
-        self.assertEqual(itemsim, {"pio_iids": ["i2"]})
-
-        # nonexisting itypes
-        try:
-            itemsim = client.get_itemsim_topn("python-itemsim-engine", "i0", 10, {"pio_itypes": ("other-itype",)})
-        except predictionio.ItemSimNotFoundError as e:
-            pass  # expected no recommendation
-        except:
-            raise
-
-        # pio_attributes
-        try:
-            itemsim = client.get_itemsim_topn("python-itemsim-engine", "i1", 10,
-                                              {"pio_itypes": ("t1",), "pio_attributes": ["custom1", "custom2"]})
-        except predictionio.ItemSimNotFoundError as e:
-            print(e)
-            print("ERROR: have you run import_testdata.py and then wait for the algorithm training completion?")
-            raise
-        except:
-            raise
-
-        if DEBUG:
-            print(itemsim)
-
-        self.assertEqual(itemsim, {"pio_iids": ["i2", "i3", "i0"], "custom1": [None, None, "i0c1"],
-                                   "custom2": ["i2c2", None, None]})
-
-        # TODO pio_latlng
-        # TODO pio_within
-        # TODO pio_unit
-
-        client.close()
-
-
-if __name__ == "__main__":
-    unittest.main()
diff --git a/tests-obsolete/predictionio_test.py b/tests-obsolete/predictionio_test.py
deleted file mode 100644
index 696718c..0000000
--- a/tests-obsolete/predictionio_test.py
+++ /dev/null
@@ -1,257 +0,0 @@
-"""
-Test Python SDK
-"""
-import unittest
-
-import predictionio
-import time
-
-
-APP_KEY = "gDx1XuMUC9vu1YWWPRZkLRTftoq7m73mlj2MtnZEjncPlZ1JxUS2s7oajwP9xrZQ"  # replace this with your AppKey
-API_URL = "http://localhost:8000"  # PredictoinIO Server
-
-MIN_VERSION = '0.6.0'
-if predictionio.__version__ < MIN_VERSION:
-    err = "Require PredictionIO Python SDK version >= %s" % MIN_VERSION
-    raise Exception(err)
-
-# print predictionio.__version__
-# predictionio.connection.enable_log()
-
-
-class TestPredictionIO(unittest.TestCase):
-    def setUp(self):
-        pass
-
-    def tearDown(self):
-        pass
-
-    def test_status(self):
-        client = predictionio.Client(APP_KEY, 1, API_URL)
-        status = client.get_status()
-        self.assertEqual(status, "PredictionIO Output API is online.")
-        client.close()
-
-    def _test_user(self, uids):
-        client = predictionio.Client(APP_KEY, 1, API_URL)
-
-        uid1 = uids[0]
-        uid2 = uids[1]
-        uid3 = uids[2]
-        uid4 = uids[3]
-        uid5 = uids[4]
-
-        # create users and get them back
-        client.create_user(uid1)
-        # create user with optional attributes
-        client.create_user(uid2, {"pio_latlng": [1.2, 33.3]})
-        client.create_user(uid3, {"pio_latlng": [4.5, 67.8], "pio_inactive": True})
-        # create user with custom attributes
-        client.create_user(uid4, {"pio_latlng": [1.2, 33.3], "custom1": "value1", "custom2": "value2"})
-        client.create_user(uid5, {"custom1": "u5c1", "custom2": "u5c2"})
-
-        user1 = client.get_user(uid1)
-        user2 = client.get_user(uid2)
-        user3 = client.get_user(uid3)
-        user4 = client.get_user(uid4)
-        user5 = client.get_user(uid5)
-
-        self.assertEqual(user1, {"pio_uid": uid1})
-        self.assertEqual(user2, {"pio_uid": uid2, "pio_latlng": [1.2, 33.3]})
-        self.assertEqual(user3, {"pio_uid": uid3, "pio_latlng": [4.5, 67.8], "pio_inactive": True})
-        self.assertEqual(user4, {"pio_uid": uid4, "pio_latlng": [1.2, 33.3], "custom1": "value1", "custom2": "value2"})
-        self.assertEqual(user5, {"pio_uid": uid5, "custom1": "u5c1", "custom2": "u5c2"})
-
-        # delete user and then try to get it
-        client.delete_user(uid1)
-
-        try:
-            client.get_user(uid1)
-        except predictionio.UserNotFoundError as e:  # noqa
-            pass  # expected exception
-        except:
-            raise
-
-        # other users still exist
-        user2 = client.get_user(uid2)
-        self.assertEqual(user2, {"pio_uid": uid2, "pio_latlng": [1.2, 33.3]})
-
-        # read, modify, write
-        user3 = client.get_user(uid3)
-        self.assertEqual(user3, {"pio_uid": uid3, "pio_latlng": [4.5, 67.8], "pio_inactive": True})
-        del user3["pio_uid"]
-        user3["pio_latlng"] = [5.6, 10.11]
-        user3["pio_inactive"] = False
-        user3["custom1"] = "food"
-        client.create_user(uid3, user3)
-        updated_user3 = client.get_user(uid3)
-        self.assertEqual(updated_user3,
-                         {"pio_uid": uid3, "pio_latlng": [5.6, 10.11], "pio_inactive": False, "custom1": "food"})
-
-        user4 = client.get_user(uid4)
-        self.assertEqual(user4, {"pio_uid": uid4, "pio_latlng": [1.2, 33.3], "custom1": "value1", "custom2": "value2"})
-        del user4["pio_uid"]
-        user4["custom1"] = "new value"
-        client.create_user(uid4, user4)
-        updated_user4 = client.get_user(uid4)
-        self.assertEqual(updated_user4,
-                         {"pio_uid": uid4, "pio_latlng": [1.2, 33.3], "custom1": "new value", "custom2": "value2"})
-
-        client.close()
-
-    def test_user(self):
-        self._test_user(["u1", "u2", "u3", "u4", "u5"])
-        # test special characters in uid
-        self._test_user(["u1@a.com", "u2@ap/ple", "u3@foo.bar", "u4/a/b", "&^%$()u5"])
-
-    def _test_item(self, iids):
-        client = predictionio.Client(APP_KEY, 1, API_URL)
-
-        iid1 = iids[0]
-        iid2 = iids[1]
-        iid3 = iids[2]
-        iid4 = iids[3]
-        iid5 = iids[4]
-
-        # create items and read back
-        client.create_item(iid1, ("t1", "t2", "t3"))
-        client.create_item(iid2, ("t1",))
-        client.create_item(iid3, ("t2",),
-                           {"pio_price": 4.99, "pio_profit": 2.0, "pio_startT": 12345667, "pio_endT": 4567788,
-                            "pio_latlng": [1.345, 9.876], "pio_inactive": True})
-        client.create_item(iid4, ("t2",), {"pio_latlng": [1.2345, 10.11], "custom1": "value1"})
-        client.create_item(iid5, ("t1", "t2"), {"custom1": "i5value1", "custom2": "i5value2"})
-
-        item1 = client.get_item(iid1)
-        item2 = client.get_item(iid2)
-        item3 = client.get_item(iid3)
-        item4 = client.get_item(iid4)
-        item5 = client.get_item(iid5)
-
-        del item1["pio_startT"]  # pio_startT is automatically inserted, don't compare
-        self.assertEqual(item1, {"pio_iid": iid1, "pio_itypes": ("t1", "t2", "t3")})
-        del item2["pio_startT"]
-        self.assertEqual(item2, {"pio_iid": iid2, "pio_itypes": ("t1",)})
-        self.assertEqual(item3, {"pio_iid": iid3, "pio_itypes": ("t2",), "pio_price": 4.99, "pio_profit": 2.0,
-                                 "pio_startT": 12345667, "pio_endT": 4567788, "pio_latlng": [1.345, 9.876],
-                                 "pio_inactive": True})
-        del item4["pio_startT"]
-        self.assertEqual(item4,
-                         {"pio_iid": iid4, "pio_itypes": ("t2",), "pio_latlng": [1.2345, 10.11], "custom1": "value1"})
-        del item5["pio_startT"]
-        self.assertEqual(item5,
-                         {"pio_iid": iid5, "pio_itypes": ("t1", "t2"), "custom1": "i5value1", "custom2": "i5value2"})
-
-        # delete and then try to get it
-        client.delete_item(iid2)
-
-        try:
-            item2 = client.get_item(iid2)
-        except predictionio.ItemNotFoundError as e:  # noqa
-            pass  # expected exception
-        except:
-            raise
-
-        # others still exist
-        item3 = client.get_item(iid3)
-        self.assertEqual(item3, {"pio_iid": iid3, "pio_itypes": ("t2",), "pio_price": 4.99, "pio_profit": 2.0,
-                                 "pio_startT": 12345667, "pio_endT": 4567788, "pio_latlng": [1.345, 9.876],
-                                 "pio_inactive": True})
-
-        # read, modify, write
-        del item3["pio_iid"]
-        item3_itypes = item3.pop("pio_itypes")
-        item3["pio_price"] = 6.99
-        item3["custom1"] = "some value"
-        client.create_item(iid3, item3_itypes, item3)
-        updated_item3 = client.get_item(iid3)
-        self.assertEqual(updated_item3, {"pio_iid": iid3, "pio_itypes": ("t2",), "pio_price": 6.99, "pio_profit": 2.0,
-                                         "pio_startT": 12345667, "pio_endT": 4567788, "pio_latlng": [1.345, 9.876],
-                                         "pio_inactive": True, "custom1": "some value"})
-
-        client.close()
-
-    def test_item(self):
-        self._test_item(["i1", "i2", "i3", "i4", "i5"])
-        # test special characters in iid
-        self._test_item(["i1@abc.com", "i2/f/bar//@@foo", "$$i3%%$~~", "http://www.i4.com", "``i5/apple/"])
-
-    def test_u2iAction_deprecated(self):
-        client = predictionio.Client(APP_KEY, 1, API_URL)
-
-        client.user_like_item("u1", "i1")
-        client.user_dislike_item("u2", "i2")
-        client.user_view_item("u3", "i3")
-        client.user_rate_item("u4", "i4", 4)
-        client.user_conversion_item("u5", "i5")
-
-        client.close()
-
-    def test_u2iAction(self):
-        client = predictionio.Client(APP_KEY, 1, API_URL)
-
-        client.identify("u101")
-
-        # required param
-        client.record_action_on_item("like", "i1")
-        client.record_action_on_item("dislike", "i2")
-        client.record_action_on_item("view", "i3")
-        client.record_action_on_item("rate", "i4", {"pio_rate": 1})
-        client.record_action_on_item("conversion", "i5")
-
-        client.identify("u102")
-
-        # with optional param
-        client.record_action_on_item("like", "i1", {"pio_latlng": [1.23, 4.56]})
-        client.record_action_on_item("dislike", "i2", {"pio_t": 1234567689})
-        client.record_action_on_item("view", "i3", {"pio_latlng": [4.67, 1.44], "pio_t": 3445566778})
-        client.record_action_on_item("rate", "i4", {"pio_rate": 1, "pio_latlng": [66.78, 9.10]})
-        client.record_action_on_item("conversion", "i5", {"pio_price": 12.5})
-
-        # uid and iid with special characters
-        client.identify("u1@a.com")
-        client.record_action_on_item("view", "i3@bb.com")
-        client.record_action_on_item("view", "http://www.yahoo.com")
-
-        client.close()
-
-    def test_pending_requests(self):
-        client = predictionio.Client(APP_KEY, 1, API_URL)
-
-        client.identify("u111")
-        for i in range(100):
-            client.arecord_action_on_item("like", str(i))
-
-        n = 1
-        while n > 0:
-            n = client.pending_requests()
-            time.sleep(0.1)
-            # print n
-
-        client.close()
-
-    def test_qsize(self):
-        client = predictionio.Client(APP_KEY, 1, API_URL, qsize=10)
-
-        client.identify("u222")
-        for i in range(100):
-            client.arecord_action_on_item("like", str(i))
-
-        n = 1
-        while n > 0:
-            n = client.pending_requests()
-            time.sleep(0.1)
-            # print n
-
-        client.close()
-
-
-"""
-to run individual test:
-$ python -m unittest predictionio_test.TestPredictionIO.test_user
-
-to run ALL tests:
-% python predictionio_test.py
-"""
-if __name__ == "__main__":
-    unittest.main()
diff --git a/tests/.keep b/tests/.keep
deleted file mode 100644
index e69de29..0000000
--- a/tests/.keep
+++ /dev/null
diff --git a/tests/after_script.travis.sh b/tests/after_script.travis.sh
new file mode 100755
index 0000000..e2ea03f
--- /dev/null
+++ b/tests/after_script.travis.sh
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+cd predictionio-setup
+./bin/pio-setup stop
+
diff --git a/tests/before_script.travis.sh b/tests/before_script.travis.sh
new file mode 100755
index 0000000..a38a6ee
--- /dev/null
+++ b/tests/before_script.travis.sh
@@ -0,0 +1,27 @@
+#!/bin/sh
+
+mkdir -p predictionio-setup/bin
+cd predictionio-setup
+curl -o bin/pio-setup https://raw.githubusercontent.com/jpioug/predictionio-setup/master/bin/pio-setup
+chmod +x bin/pio-setup
+
+PIO_GIT_USER=apache PIO_GIT_BRANCH=develop PIO_EVENTDATA_REFRESH=true ./bin/pio-setup deploy
+touch target/pio-setup.log
+tail -f target/pio-setup.log &
+
+counter=1
+ret=7
+while [ $ret = 7 -a $counter != 10 ] ; do
+  ./bin/pio-setup start
+  sleep 5
+  curl -v 127.0.0.1:7070/events.json
+  ret=$?
+  echo "Checking Java processes..."
+  ps aux | grep java
+  echo "Checking 7070 port..."
+  netstat | grep 7070
+  counter=`expr $counter + 1`
+done
+
+./bin/pio-setup status
+tail -f ~/pio.log &
diff --git a/tests/engineclient_test.py b/tests/engineclient_test.py
new file mode 100644
index 0000000..276328b
--- /dev/null
+++ b/tests/engineclient_test.py
@@ -0,0 +1,48 @@
+import random
+import subprocess
+import unittest
+
+from predictionio import EventClient
+
+app_name ='EngineClientApp'
+access_key = 'FILE_EXPORT_TEST'
+
+class EngineClientTest(unittest.TestCase):
+
+    def setUp(self):
+        subprocess.call(['pio', 'app', 'new', '--access-key', access_key, app_name])
+
+    def tearDown(self):
+        subprocess.call(['pio', 'app', 'delete', '-f', app_name])
+
+    def test_query(self):
+        random.seed()
+
+        client = EventClient(access_key=access_key, url="http://127.0.0.1:7070")
+
+        # Check status
+        print("Check status")
+        print(client.get_status())
+        self.assertEqual(client.get_status(), {'status': 'alive'})
+
+        user_ids = [str(i) for i in range(1, 3)]
+        for user_id in user_ids:
+            print("Set user", user_id)
+            client.set_user(user_id)
+            # TODO assert
+
+        item_ids = [str(i) for i in range(1, 5)]
+        for item_id in item_ids:
+            print("Set item", item_id)
+            client.set_item(item_id, {"itypes": ['1']})
+            # TODO assert
+
+            # each user randomly views 10 items
+            for user_id in user_ids:
+                for viewed_item in random.sample(item_ids, 2):
+                    print("User", user_id, "views item", viewed_item)
+                    client.record_user_action_on_item("view", user_id, viewed_item)
+                    # TODO assert
+
+        client.close()
+
diff --git a/tests/eventclient_test.py b/tests/eventclient_test.py
new file mode 100644
index 0000000..900c48b
--- /dev/null
+++ b/tests/eventclient_test.py
@@ -0,0 +1,251 @@
+import pytz
+import subprocess
+import unittest
+
+from datetime import datetime
+from predictionio import EventClient
+from predictionio import NotFoundError
+
+app_name ='EventClientApp'
+access_key = 'EVENT_CLIENT_TEST'
+channel = 'Test'
+
+class EventClientTest(unittest.TestCase):
+
+    def setUp(self):
+        subprocess.call(['pio', 'app', 'new', '--access-key', access_key, app_name])
+        subprocess.call(['pio', 'app', 'show', app_name])
+
+    def tearDown(self):
+        subprocess.call(['pio', 'app', 'delete', '-f', app_name])
+
+    def test_eventclient(self):
+        client = EventClient(access_key=access_key, url="http://127.0.0.1:7070")
+
+        # Check status
+        print("Check status")
+        print(client.get_status())
+        self.assertEqual(client.get_status(), {'status': 'alive'})
+
+        # First event
+        first_event_properties = {
+            "prop1": 1,
+            "prop2": "value2",
+            "prop3": [1, 2, 3],
+            "prop4": True,
+            "prop5": ["a", "b", "c"],
+            "prop6": 4.56,
+        }
+        first_event_time = datetime(
+            2004, 12, 13, 21, 39, 45, 618000, pytz.timezone('US/Mountain'))
+        first_event_response = client.create_event(
+            event="my_event",
+            entity_type="user",
+            entity_id="uid",
+            properties=first_event_properties,
+            event_time=first_event_time,
+        )
+        print("First Event response")
+        print(first_event_response)
+        self.assertEqual(first_event_response.status, 201)
+
+        # Second event
+        second_event_properties = {
+            "someProperty": "value1",
+            "anotherProperty": "value2",
+        }
+        second_event_response = client.create_event(
+            event="my_event",
+            entity_type="user",
+            entity_id="uid",
+            target_entity_type="item",
+            target_entity_id="iid",
+            properties=second_event_properties,
+            event_time=datetime(2014, 12, 13, 21, 38, 45, 618000, pytz.utc))
+        print("Second Event response")
+        print(second_event_response)
+        self.assertEqual(second_event_response.status, 201)
+
+
+        # Get the first event from Event Server
+        first_event_id = first_event_response.json_body["eventId"]
+        print("Get Event")
+        event = client.get_event(first_event_id)
+        print(event)
+        self.assertEqual(event.get('eventId'), first_event_id)
+
+
+        # Delete the first event from Event Server
+        print("Delete Event")
+        delete_response = client.delete_event(first_event_id)
+        print(delete_response)
+        self.assertEqual(delete_response.decode('utf-8'), '{"message":"Found"}')
+
+
+        # Delete the first event from Event Server again should yield exception.
+        print("Delete Event Again")
+        try:
+            delete_response = client.delete_event(first_event_id)
+            self.fail()
+        except NotFoundError as ex:
+            print("The expected error: {0}".format(ex))
+
+
+        # "user"-helper methods
+
+        # Set user properties implicitly create a user
+        # This call creates a user "foo", and set the properties of "foo".
+        print("Create user foo")
+        foo_properties = {"city": "sunnyvale", "car": "honda fit"}
+        response = client.set_user("foo", properties=foo_properties)
+        print(response)
+        self.assertEqual(response.status, 201)
+
+        # This call overrides the existing properties for user "foo", setting "car" to
+        # a new "honda odyssey" and create a new property "food" to "seafood".
+        print("Set new properties")
+        foo_properties = {"car": "honda odyssey", "food": "seafood"}
+        response = client.set_user("foo", properties=foo_properties)
+        print(response)
+        self.assertEqual(response.status, 201)
+
+        # This call removes the specified properties. It ignores the value of the dict.
+        # After this call, the "city" will become an unset field.
+        print("Unset properties")
+        foo_properties = {"city": "x"}
+        response = client.unset_user("foo", properties=foo_properties)
+        print(response)
+        self.assertEqual(response.status, 201)
+
+        # This call deletes a user
+        print("Delete user")
+        response = client.delete_user("foo")
+        print(response)
+        self.assertEqual(response.status, 201)
+
+        # The SDK also support specifying the eventTime. It is useful for importing
+        # events happened in the past.
+        foo_time = datetime(2014, 8, 31, 4, 56, tzinfo=pytz.timezone('US/Pacific'))
+        print("Create user at " + str(foo_time))
+        response = client.set_user("Jarvis", {}, foo_time)
+        print(response)
+        self.assertEqual(response.status, 201)
+
+        # "item"-helper methods
+
+        # Set item properties implicitly create a item
+        # This call creates a item "bar", and set the properties of "bar".
+        print("Create item bar")
+        bar_properties = {"city": "santa clara", "weight": 6.9}
+        response = client.set_item("bar", properties=bar_properties)
+        print(response)
+        self.assertEqual(response.status, 201)
+
+        # Similar to user-methods, we can do the same thing with item
+        print("Set new properties")
+        bar_properties = {"weight": 6.2}
+        response = client.set_item("bar", properties=bar_properties)
+        print(response)
+        self.assertEqual(response.status, 201)
+
+        # This call removes the specified properties. It ignores the value of the dict.
+        # After this call, the "city" will become an unset field.
+        print("Unset properties")
+        bar_properties = {"city": None}
+        response = client.unset_item("bar", properties=bar_properties)
+        print(response)
+        self.assertEqual(response.status, 201)
+
+        # This call deletes a item
+        print("Delete item")
+        response = client.delete_item("bar")
+        print(response)
+        self.assertEqual(response.status, 201)
+
+
+        # "record" action helper functions
+
+        # This call creates a event between a user and an item. In particular, this set
+        # the price of the action
+        print("Record user action")
+        action_properties = {"price": 10.0}
+        response = client.record_user_action_on_item("buy", "foo", "bar", action_properties)
+        print(response)
+        self.assertEqual(response.status, 201)
+
+
+    def test_eventclient_channel(self):
+        subprocess.call(['pio', 'app', 'channel-new', app_name, channel])
+
+        client = EventClient(access_key=access_key, url="http://127.0.0.1:7070",
+                             channel=channel)
+
+        # Check status
+        print("Check status")
+        print(client.get_status())
+        self.assertEqual(client.get_status(), {'status': 'alive'})
+
+        # First event
+        first_event_properties = {
+            "prop1" : 1,
+            "prop2" : "value2",
+            "prop3" : [1, 2, 3],
+            "prop4" : True,
+            "prop5" : ["a", "b", "c"],
+            "prop6" : 4.56 ,
+            }
+        first_event_time = datetime(
+            2004, 12, 13, 21, 39, 45, 618000, pytz.timezone('US/Mountain'))
+        first_event_response = client.create_event(
+            event="my_event",
+            entity_type="user",
+            entity_id="uid",
+            properties=first_event_properties,
+            event_time=first_event_time,
+            )
+        print("First Event response")
+        print(first_event_response)
+        self.assertEqual(first_event_response.status, 201)
+
+        # Second event
+        second_event_properties = {
+            "someProperty" : "value1",
+            "anotherProperty" : "value2",
+            }
+        second_event_response = client.create_event(
+            event="my_event",
+            entity_type="user",
+            entity_id="uid",
+            target_entity_type="item",
+            target_entity_id="iid",
+            properties=second_event_properties,
+            event_time=datetime(2014, 12, 13, 21, 38, 45, 618000, pytz.utc))
+        print("Second Event response")
+        print(second_event_response)
+        self.assertEqual(second_event_response.status, 201)
+
+
+        # Get the first event from Event Server
+        first_event_id = first_event_response.json_body["eventId"]
+        print("Get Event")
+        event = client.get_event(first_event_id)
+        print(event)
+        self.assertEqual(event.get('eventId'), first_event_id)
+
+        # Delete the first event from Event Server
+        print("Delete Event")
+        delete_response = client.delete_event(first_event_id)
+        print(delete_response)
+        self.assertEqual(delete_response.decode('utf-8'), '{"message":"Found"}')
+
+        # Delete the first event from Event Server again should yield exception.
+        print("Delete Event Again")
+        try:
+            delete_response = client.delete_event(first_event_id)
+            self.fail()
+        except NotFoundError as ex:
+            print("The expected error: {0}".format(ex))
+
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/tests/fileexport_test.py b/tests/fileexport_test.py
new file mode 100644
index 0000000..0fad97e
--- /dev/null
+++ b/tests/fileexport_test.py
@@ -0,0 +1,74 @@
+import pytz
+import re
+import subprocess
+import unittest
+
+from datetime import datetime
+import predictionio
+from predictionio import EventClient
+
+app_name ='FileExporterApp'
+access_key = 'FILE_EXPORT_TEST'
+filename = 'export_events.json'
+
+class FileExporterTest(unittest.TestCase):
+
+    def setUp(self):
+        subprocess.call(['pio', 'app', 'new', '--access-key', access_key, app_name])
+
+    def tearDown(self):
+        subprocess.call(['pio', 'app', 'delete', '-f', app_name])
+
+    def test_export(self):
+        app_info = subprocess.check_output(['pio', 'app', 'show', app_name])
+        app_id = re.search('App ID: ([0-9]+)', app_info.decode('utf-8')).group(1)
+        print(app_id)
+
+        exporter = predictionio.FileExporter(file_name=filename)
+
+        first_event_properties = {
+            "prop1" : 1,
+            "prop2" : "value2",
+            "prop3" : [1, 2, 3],
+            "prop4" : True,
+            "prop5" : ["a", "b", "c"],
+            "prop6" : 4.56 ,
+            }
+        first_event_time = datetime(
+            2004, 12, 13, 21, 39, 45, 618000, pytz.timezone('US/Mountain'))
+        exporter.create_event(
+            event="my_event",
+            entity_type="user",
+            entity_id="uid",
+            properties=first_event_properties,
+            event_time=first_event_time,
+            )
+
+        # Second event
+        second_event_properties = {
+            "someProperty" : "value1",
+            "anotherProperty" : "value2",
+            }
+        exporter.create_event(
+            event="my_event",
+            entity_type="user",
+            entity_id="uid",
+            target_entity_type="item",
+            target_entity_id="iid",
+            properties=second_event_properties,
+            event_time=datetime(2014, 12, 13, 21, 38, 45, 618000, pytz.utc))
+
+        exporter.close()
+
+        subprocess.call(['pio', 'import', '--appid', app_id, '--input ', filename])
+
+        # TODO
+        # client = EventClient(access_key=access_key, url="http://127.0.0.1:7070")
+        #
+        # print("Get Event")
+        # event = client.get_event(event_id)
+        # print(event)
+        # self.assertEqual(event.get('eventId'), event_id)
+
+if __name__ == "__main__":
+    unittest.main()
diff --git a/tox.ini b/tox.ini
index 87b57e9..6f5cd20 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,13 +1,12 @@
 [tox]
-envlist = py27,py34
+envlist = py27,py34,py35,py36
 
 [testenv]
 deps = flake8
-       pandas
+passenv = HOME TRAVIS*
+commands = python -m unittest discover --pattern=*.py tests
 
 [flake8]
 ignore = E111
 
-
 commands = flake8 --ignore=E501 --filename=*.py --exclude=doc,setup.py,*/tests/*
-           python -m unittest discover --pattern=*.py tests