From 616729e97fef2a96f6f0db073b30c3e65fec97fa Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Wed, 13 Mar 2019 21:07:29 -0400 Subject: [PATCH 1/9] full coverage for init full coverage for init - 100% coverage of db operations --- Pipfile | 1 + Pipfile.lock | 24 +++++- bumper/__init__.py | 11 ++- bumper/confserver.py | 24 +++--- tests/test_bumper.py | 182 +++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 217 insertions(+), 25 deletions(-) diff --git a/Pipfile b/Pipfile index f63f750..cf677ac 100644 --- a/Pipfile +++ b/Pipfile @@ -13,6 +13,7 @@ pyyaml = ">=4.2b1" black = "*" nose = "*" coverage = "*" +mock = "*" [pipenv] allow_prereleases = true diff --git a/Pipfile.lock b/Pipfile.lock index a17abe8..80de24c 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "e23347a7d680cf62879fd5c1acfd6431c4d56ff46c30533478629e220623e585" + "sha256": "4119ce02f0331e2eae79e97097a00614ec5fb641345868b4cac63f7dd6127a32" }, "pipfile-spec": 6, "requires": {}, @@ -272,6 +272,14 @@ "index": "pypi", "version": "==5.0a4" }, + "mock": { + "hashes": [ + "sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1", + "sha256:b158b6df76edd239b8208d481dc46b6afd45a846b7812ff0ce58971cf5bc8bba" + ], + "index": "pypi", + "version": "==2.0.0" + }, "nose": { "hashes": [ "sha256:9ff7c6cc443f8c51994b34a667bbcf45afd6d945be7477b52e97516fd17c53ac", @@ -281,6 +289,20 @@ "index": "pypi", "version": "==1.3.7" }, + "pbr": { + "hashes": [ + "sha256:8257baf496c8522437e8a6cfe0f15e00aedc6c0e0e7c9d55eeeeab31e0853843", + "sha256:8c361cc353d988e4f5b998555c88098b9d5964c2e11acf7b0d21925a66bb5824" + ], + "version": "==5.1.3" + }, + "six": { + "hashes": [ + "sha256:3350809f0555b11f552448330d0b52d5f24c91a322ea4a15ef22629740f3761c", + "sha256:d16a0141ec1a18405cd4ce8b4613101da75da0e9a7aec5bdd4fa804d0e0eba73" + ], + "version": "==1.12.0" + }, "toml": { "hashes": [ "sha256:229f81c57791a41d65e399fc06bf0848bab550a9dfd5ed66df18ce5f05e73d5c", diff --git a/bumper/__init__.py b/bumper/__init__.py index d7a02ed..c678719 100644 --- a/bumper/__init__.py +++ b/bumper/__init__.py @@ -43,11 +43,6 @@ xmppserverlog = logging.getLogger("xmppserver") # xmppserverlog.setLevel(logging.INFO) -def __init__(self, db=None): - if db: - self.db = db - - def get_milli_time(timetoconvert): return int(round(timetoconvert * 1000)) @@ -55,11 +50,15 @@ def get_milli_time(timetoconvert): def db_file(): if db: return db + + return os_db_path() + +def os_db_path(): if platform.system() == "Windows": return os.path.join(os.getenv("APPDATA"), "bumper.db") else: - return os.path.expanduser("~/.config/bumper.db") + return os.path.expanduser("~/.config/bumper.db") def db_get(): diff --git a/bumper/confserver.py b/bumper/confserver.py index 0125a2a..af0c491 100644 --- a/bumper/confserver.py +++ b/bumper/confserver.py @@ -200,7 +200,7 @@ class ConfServer: "username": "fusername_{}".format(user["userid"]), }, "msg": "操作成功", - "time": bumper.get_milli_time(time.time()), + "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), } return web.json_response(body) @@ -208,7 +208,7 @@ class ConfServer: "code": bumper.ERR_USER_NOT_ACTIVATED, "data": None, "msg": "当前密码错误", - "time": bumper.get_milli_time(time.time()), + "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), } return web.json_response(body) @@ -233,7 +233,7 @@ class ConfServer: "username": "fusername_{}".format(user["userid"]), }, "msg": "操作成功", - "time": bumper.get_milli_time(time.time()), + "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), } return web.json_response(body) @@ -242,7 +242,7 @@ class ConfServer: "code": bumper.ERR_TOKEN_INVALID, "data": None, "msg": "当前密码错误", - "time": bumper.get_milli_time(time.time()), + "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), } return web.json_response(body) @@ -295,7 +295,7 @@ class ConfServer: "username": "fusername_{}".format(tmpuser["userid"]), }, "msg": "操作成功", - "time": bumper.get_milli_time(time.time()), + "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), } return body @@ -319,7 +319,7 @@ class ConfServer: "code": bumper.RETURN_API_SUCCESS, "data": None, "msg": "操作成功", - "time": bumper.get_milli_time(time.time()), + "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), } return web.json_response(body) @@ -355,7 +355,7 @@ class ConfServer: "ecovacsUid": request.query["uid"], }, "msg": "操作成功", - "time": bumper.get_milli_time(time.time()), + "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), } return web.json_response(body) @@ -363,7 +363,7 @@ class ConfServer: "code": bumper.ERR_TOKEN_INVALID, "data": None, "msg": "当前密码错误", - "time": bumper.get_milli_time(time.time()), + "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), } return web.json_response(body) @@ -385,7 +385,7 @@ class ConfServer: "v": None, }, "msg": "操作成功", - "time": bumper.get_milli_time(time.time()), + "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), } return web.json_response(body) @@ -399,7 +399,7 @@ class ConfServer: "code": bumper.RETURN_API_SUCCESS, "data": [], "msg": "操作成功", - "time": bumper.get_milli_time(time.time()), + "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), } return web.json_response(body) @@ -421,10 +421,10 @@ class ConfServer: "hasCampaign": "N", "imageUrl": None, "nextAlertTime": nextAlert, - "serverTime": bumper.get_milli_time(time.time()), + "serverTime": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), }, "msg": "操作成功", - "time": bumper.get_milli_time(time.time()), + "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), } return web.json_response(body) diff --git a/tests/test_bumper.py b/tests/test_bumper.py index 084b7c1..d0f213c 100644 --- a/tests/test_bumper.py +++ b/tests/test_bumper.py @@ -1,14 +1,184 @@ from nose.tools import * +import nose +import mock from tinydb.storages import MemoryStorage from tinydb import TinyDB, Query import bumper +import os +import datetime, time +import platform -def test_useradd(): - btest = bumper - btest.db = "tests/tmp.db" - btest.user_add("testuser") +def test_get_milli_time(): + assert_equals( + bumper.get_milli_time( + datetime.datetime( + 2018, 1, 1, 1, 0, 0, 0, tzinfo=datetime.timezone.utc + ).timestamp() + ), + 1514768400000, + ) + + +def test_user_db(): + if os.path.exists("tests/tmp.db"): + os.remove("tests/tmp.db") # Remove existing db + + # Test os_db_path + platform.system = mock.MagicMock(return_value="Windows") + p = platform.system() + os.getenv = mock.MagicMock(return_value="C:\AppData") + o = os.getenv("APPDATA") + assert_equals(bumper.os_db_path(), os.path.join(os.getenv("APPDATA"), "bumper.db")) + + platform.system = mock.MagicMock(return_value="Linux") + assert_equals(bumper.os_db_path(), os.path.expanduser("~/.config/bumper.db")) + + bumper.db = "tests/tmp.db" # Set db location for testing + bumper.user_add("testuser") # Add testuser + + assert_equals( + bumper.user_get("testuser")["userid"], "testuser" + ) # Test that testuser was created and returned + + bumper.user_add_device("testuser", "dev_1234") # Add device to testuser + + assert_equals( + bumper.user_by_deviceid("dev_1234")["userid"], "testuser" + ) # Test that testuser was found by deviceid + + bumper.user_remove_device("testuser", "dev_1234") # Remove device from testuser + + assert_true( + "dev_1234" not in bumper.user_get("testuser")["devices"] + ) # Test that dev_1234 was not found in testuser devices + + bumper.user_add_bot("testuser", "bot_1234") # Add bot did to testuser + + assert_true( + "bot_1234" in bumper.user_get("testuser")["bots"] + ) # Test that bot was found in testuser's bot list + + bumper.user_remove_bot("testuser", "bot_1234") # Remove bot did from testuser + + assert_true( + "bot_1234" not in bumper.user_get("testuser")["bots"] + ) # Test that bot was not found in testuser's bot list + + bumper.user_add_token("testuser", "token_1234") # Add token to testuser + + assert_true( + bumper.check_token("testuser", "token_1234") + ) # Test that token was found for testuser + + assert_true( + bumper.user_get_token("testuser", "token_1234") + ) # Test that token was returned for testuser + + bumper.user_add_authcode( + "testuser", "token_1234", "auth_1234" + ) # Add authcode to token_1234 for testuser + assert_true( + bumper.check_authcode("testuser", "auth_1234") + ) # Test that authcode was found for testuser + + bumper.user_revoke_authcode( + "testuser", "token_1234", "auth_1234" + ) # Remove authcode from testuser + assert_false( + bumper.check_authcode("testuser", "auth_1234") + ) # Test that authcode was not found for testuser + bumper.user_revoke_token("testuser", "token_1234") # Remove token from testuser + assert_false( + bumper.check_token("testuser", "token_1234") + ) # Test that token was not found for testuser + bumper.user_add_token("testuser", "token_1234") # Add token_1234 + bumper.user_add_token("testuser", "token_4321") # Add token_4321 + assert_equals( + len(bumper.user_get_tokens("testuser")), 2 + ) # Test 2 tokens are available + bumper.user_revoke_all_tokens("testuser") # Revoke all tokens + assert_equals( + len(bumper.user_get_tokens("testuser")), 0 + ) # Test 0 tokens are available db = TinyDB("tests/tmp.db") - users = db.table("users").search(Query().userid == "testuser") - assert_equals(len(users), 1) + tokens = db.table("tokens") + tokens.insert( + { + "userid": "testuser", + "token": "token_1234", + "expiration": "{}".format( + datetime.datetime.now() + datetime.timedelta(seconds=-10) + ), + } + ) # Add expired token + db.close() + assert_equals( + len(bumper.user_get_tokens("testuser")), 1 + ) # Test 1 tokens are available + bumper.user_revoke_expired_tokens("testuser") # Revoke expired tokens + assert_equals( + len(bumper.user_get_tokens("testuser")), 0 + ) # Test 0 tokens are available + + db = TinyDB("tests/tmp.db") + tokens = db.table("tokens") + tokens.insert( + { + "userid": "testuser", + "token": "token_1234", + "expiration": "{}".format( + datetime.datetime.now() + datetime.timedelta(seconds=-10) + ), + } + ) # Add expired token + db.close() + assert_equals( + len(bumper.user_get_tokens("testuser")), 1 + ) # Test 1 tokens are available + bumper.revoke_expired_tokens() # Revoke expired tokens + assert_equals( + len(bumper.user_get_tokens("testuser")), 0 + ) # Test 0 tokens are available + + +def test_bot_db(): + bumper.db = "tests/tmp.db" # Set db location for testing + bumper.bot_add("sn_123", "did_123", "dev_123", "res_123", "co_123") + assert_true(bumper.bot_get("did_123")) # Test that bot was added to db + + bumper.bot_set_nick("did_123", "nick_123") + assert_equals( + bumper.bot_get("did_123")["nick"], "nick_123" + ) # Test that nick was added to bot + + bumper.bot_set_mqtt("did_123", True) + assert_true( + bumper.bot_get("did_123")["mqtt_connection"] + ) # Test that mqtt was set True for bot + + bumper.bot_set_xmpp("did_123", True) + assert_true( + bumper.bot_get("did_123")["xmpp_connection"] + ) # Test that xmpp was set True for bot + + bumper.bot_remove("did_123") + assert_false(bumper.bot_get("did_123")) # Test that bot is no longer in db + + +def test_client_db(): + bumper.db = "tests/tmp.db" # Set db location for testing + bumper.client_add("user_123", "realm_123", "resource_123") + assert_true(bumper.client_get("resource_123")) # Test client was added + + bumper.client_set_mqtt("resource_123", True) + assert_true( + bumper.client_get("resource_123")["mqtt_connection"] + ) # Test that mqtt was set True for client + + bumper.client_set_xmpp("resource_123", False) + assert_false( + bumper.client_get("resource_123")["xmpp_connection"] + ) # Test that xmpp was set False for client + assert_equals(len(bumper.get_disconnected_xmpp_clients()), 1) # Test len of connected xmpp clients is 1 \ No newline at end of file -- 2.39.5 From 747eeda4a51cdd94129579feb35f3509c702e90b Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Thu, 14 Mar 2019 09:35:37 -0400 Subject: [PATCH 2/9] Start adding tests for confserver Start adding tests for confserver --- bumper/__init__.py | 9 +-- bumper/confserver.py | 132 +++++++++++++++++++++------------------ tests/test_confserver.py | 128 +++++++++++++++++++++++++++++++++++++ 3 files changed, 203 insertions(+), 66 deletions(-) create mode 100644 tests/test_confserver.py diff --git a/bumper/__init__.py b/bumper/__init__.py index c678719..649f580 100644 --- a/bumper/__init__.py +++ b/bumper/__init__.py @@ -66,9 +66,9 @@ def db_get(): db = TinyDB(db_file()) # Will create the tables if they don't exist - users_table = db.table("users") - clients_table = db.table("clients") - bots_table = db.table("bots") + users_table = db.table("users", cache_size=0) + clients_table = db.table("clients", cache_size=0) + bots_table = db.table("bots", cache_size=0) return db @@ -95,7 +95,7 @@ def user_add(userid): def user_get(userid): users = db_get().table("users") - User = Query() + User = Query() return users.get(User.userid == userid) @@ -169,6 +169,7 @@ def user_add_token(userid, token): tokens = db_get().table("tokens") tmptoken = tokens.get((Query().userid == userid) & (Query().token == token)) if not tmptoken: + bumperlog.debug("Adding token {} for userid {}".format(token, userid)) tokens.insert( { "userid": userid, diff --git a/bumper/confserver.py b/bumper/confserver.py index af0c491..16d9a1e 100644 --- a/bumper/confserver.py +++ b/bumper/confserver.py @@ -42,6 +42,7 @@ class ConfServer: self.usessl = usessl self.address = address self.confthread = None + self.app = None def run(self, run_async=False): try: @@ -72,62 +73,61 @@ class ConfServer: loop = asyncio.new_event_loop() try: + self.confserver_app() loop.run_until_complete(self.start_server()) loop.run_forever() except Exception as e: confserverlog.exception("{}".format(e)) + def confserver_app(self): + self.app = web.Application() + + self.app.add_routes( + [ + web.get("", self.handle_base), + web.get( + "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/login", + self.handle_login, + ), + web.get( + "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkLogin", + self.handle_login, + ), + web.get( + "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/logout", + self.handle_logout, + ), + web.get( + "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getAuthCode", + self.handle_getAuthCode, + ), + web.get( + "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkAgreement", + self.handle_checkAgreement, + ), + web.get( + "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/checkVersion", + self.handle_checkVersion, + ), + web.get( + "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/campaign/homePageAlert", + self.handle_homePageAlert, + ), + web.post("/api/users/user.do", self.handle_usersapi), + web.get("/api/users/user.do", self.handle_usersapi), + web.post( + "/api/pim/product/getProductIotMap", self.handle_getProductIotMap + ), + web.post("/api/iot/devmanager.do", self.handle_devmanager_botcommand), + web.post("/lookup.do", self.handle_lookup), + ] + ) + # Direct register from app: + # /{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/directRegister + async def start_server(self): try: - app = web.Application() - - app.add_routes( - [ - web.get("", self.handle_base), - web.get( - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/login", - self.handle_login, - ), - web.get( - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkLogin", - self.handle_login, - ), - web.get( - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/logout", - self.handle_logout, - ), - web.get( - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/getAuthCode", - self.handle_getAuthCode, - ), - web.get( - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/checkAgreement", - self.handle_checkAgreement, - ), - web.get( - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/common/checkVersion", - self.handle_checkVersion, - ), - web.get( - "/{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/campaign/homePageAlert", - self.handle_homePageAlert, - ), - web.post("/api/users/user.do", self.handle_usersapi), - web.get("/api/users/user.do", self.handle_usersapi), - web.post( - "/api/pim/product/getProductIotMap", - self.handle_getProductIotMap, - ), - web.post( - "/api/iot/devmanager.do", self.handle_devmanager_botcommand - ), - web.post("/lookup.do", self.handle_lookup), - ] - ) - # Direct register from app: - # /{apiversion}/private/{country}/{language}/{devid}/{apptype}/{appversion}/{devtype}/{aid}/user/directRegister - - runner = web.AppRunner(app) + runner = web.AppRunner(self.app) await runner.setup() if self.usessl: @@ -200,7 +200,9 @@ class ConfServer: "username": "fusername_{}".format(user["userid"]), }, "msg": "操作成功", - "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), + "time": bumper.get_milli_time( + datetime.utcnow().timestamp() + ), } return web.json_response(body) @@ -208,7 +210,9 @@ class ConfServer: "code": bumper.ERR_USER_NOT_ACTIVATED, "data": None, "msg": "当前密码错误", - "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), + "time": bumper.get_milli_time( + datetime.utcnow().timestamp() + ), } return web.json_response(body) @@ -233,7 +237,7 @@ class ConfServer: "username": "fusername_{}".format(user["userid"]), }, "msg": "操作成功", - "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), + "time": bumper.get_milli_time(datetime.utcnow().timestamp()), } return web.json_response(body) @@ -242,7 +246,7 @@ class ConfServer: "code": bumper.ERR_TOKEN_INVALID, "data": None, "msg": "当前密码错误", - "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), + "time": bumper.get_milli_time(datetime.utcnow().timestamp()), } return web.json_response(body) @@ -276,7 +280,7 @@ class ConfServer: if "checkLogin" in request.path: # If request was to check a token do so checkToken = self.check_token( - countrycode, user, request.query["accessToken"] + countrycode, tmpuser, request.query["accessToken"] ) isGood = json.loads(checkToken.text) if isGood["code"] == "0000": @@ -295,7 +299,7 @@ class ConfServer: "username": "fusername_{}".format(tmpuser["userid"]), }, "msg": "操作成功", - "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), + "time": bumper.get_milli_time(datetime.utcnow().timestamp()), } return body @@ -319,7 +323,7 @@ class ConfServer: "code": bumper.RETURN_API_SUCCESS, "data": None, "msg": "操作成功", - "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), + "time": bumper.get_milli_time(datetime.utcnow().timestamp()), } return web.json_response(body) @@ -355,7 +359,9 @@ class ConfServer: "ecovacsUid": request.query["uid"], }, "msg": "操作成功", - "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), + "time": bumper.get_milli_time( + datetime.utcnow().timestamp() + ), } return web.json_response(body) @@ -363,7 +369,7 @@ class ConfServer: "code": bumper.ERR_TOKEN_INVALID, "data": None, "msg": "当前密码错误", - "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), + "time": bumper.get_milli_time(datetime.utcnow().timestamp()), } return web.json_response(body) @@ -385,7 +391,7 @@ class ConfServer: "v": None, }, "msg": "操作成功", - "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), + "time": bumper.get_milli_time(datetime.utcnow().timestamp()), } return web.json_response(body) @@ -399,7 +405,7 @@ class ConfServer: "code": bumper.RETURN_API_SUCCESS, "data": [], "msg": "操作成功", - "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), + "time": bumper.get_milli_time(datetime.utcnow().timestamp()), } return web.json_response(body) @@ -421,10 +427,12 @@ class ConfServer: "hasCampaign": "N", "imageUrl": None, "nextAlertTime": nextAlert, - "serverTime": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), + "serverTime": bumper.get_milli_time( + datetime.utcnow().timestamp() + ), }, "msg": "操作成功", - "time": bumper.get_milli_time(datetime.datetime.utcnow().timestamp()), + "time": bumper.get_milli_time(datetime.utcnow().timestamp()), } return web.json_response(body) diff --git a/tests/test_confserver.py b/tests/test_confserver.py new file mode 100644 index 0000000..dcf6030 --- /dev/null +++ b/tests/test_confserver.py @@ -0,0 +1,128 @@ +from nose.tools import * +import mock +import bumper +import asyncio +import os +import json +import tinydb +from aiohttp.test_utils import TestClient, TestServer, loop_context +from aiohttp import request + +confserver = bumper.ConfServer("127.0.0.1:11111", False, None) +confserver.confserver_app() +app = confserver.app + + +def test_base(): + if os.path.exists("tests/tmp.db"): + os.remove("tests/tmp.db") # Remove existing db + bumper.db = "tests/tmp.db" # Set db location for testing + loop = asyncio.get_event_loop() + client = TestClient(TestServer(app), loop=loop) + loop.run_until_complete(client.start_server()) + root = "http://{}".format(confserver.address) + + async def test_handle_base(): + resp = await client.get("/") + assert resp.status == 200 + text = await resp.text() + assert "Bumper!" in text + + loop.run_until_complete(test_handle_base()) # Test handle_base + + loop.run_until_complete( + client.close() + ) # Close test server after all tests are done + + +def test_login(): + if os.path.exists("tests/tmp.db"): + os.remove("tests/tmp.db") # Remove existing db + bumper.db = "tests/tmp.db" # Set db location for testing + loop = asyncio.get_event_loop() + client = TestClient(TestServer(app), loop=loop) + loop.run_until_complete(client.start_server()) + root = "http://{}".format(confserver.address) + + async def test_handle_login(): + resp = await client.get("/1/private/us/en/dev_1234/ios/1/0/0/user/login") + assert resp.status == 200 + text = await resp.text() + loginresp = json.loads(text) + if loginresp: + assert loginresp["code"] == "0000" + assert "accessToken" in loginresp["data"] + assert "uid" in loginresp["data"] + assert "username" in loginresp["data"] + else: + assert loginresp + + loop.run_until_complete(test_handle_login()) # Test handle_login + + #Add a user to db and test with existing users + bumper.user_add("testuser") + loop.run_until_complete(test_handle_login()) # Test handle_login with user in db + + #Add a bot to db that will be added to user + bumper.bot_add("sn_123", "did_123", "dev_123", "res_123", "com_123") + loop.run_until_complete(test_handle_login()) # Test handle_login with user in db + + loop.run_until_complete( + client.close() + ) # Close test server after all tests are done + +def test_check_login(): + if os.path.exists("tests/tmp.db"): + os.remove("tests/tmp.db") # Remove existing db + bumper.db = "tests/tmp.db" # Set db location for testing + loop = asyncio.get_event_loop() + client = TestClient(TestServer(app), loop=loop) + loop.run_until_complete(client.start_server()) + root = "http://{}".format(confserver.address) + + async def test_handle_checkLogin_nouser(): + resp = await client.get("/1/private/us/en/dev_1234/ios/1/0/0/user/checkLogin?accessToken=token_1234") + assert resp.status == 200 + text = await resp.text() + loginresp = json.loads(text) + if loginresp: + assert loginresp["code"] == "0000" + assert "accessToken" in loginresp["data"] + assert loginresp["data"]["accessToken"] != "token_1234" + assert "uid" in loginresp["data"] + assert "username" in loginresp["data"] + else: + assert loginresp + + async def test_handle_checkLogin_withuser(): + resp = await client.get("/1/private/us/en/dev_1234/ios/1/0/0/user/checkLogin?accessToken=token_1234") + assert resp.status == 200 + text = await resp.text() + loginresp = json.loads(text) + if loginresp: + assert loginresp["code"] == "0000" + assert "accessToken" in loginresp["data"] + assert loginresp["data"]["accessToken"] == "token_1234" + assert "uid" in loginresp["data"] + assert "username" in loginresp["data"] + else: + assert loginresp + + loop.run_until_complete(test_handle_checkLogin_nouser()) # Test handle_login no user + + #Add a user to db and test with existing users + bumper.user_add("testuser") + loop.run_until_complete(test_handle_checkLogin_nouser()) # Test handle_login with user in db + + #Remove dev from tmpuser + bumper.user_remove_device("tmpuser","dev_1234") + + #Add a token to user and test + bumper.user_add("testuser") + bumper.user_add_device("testuser","dev_1234") + bumper.user_add_token("testuser", "token_1234") + loop.run_until_complete(test_handle_checkLogin_withuser()) # Test handle_login with user in db + + loop.run_until_complete( + client.close() + ) # Close test server after all tests are done -- 2.39.5 From 5392bef74f68b73d880937fbb4044e9805b31e56 Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Fri, 15 Mar 2019 09:05:54 -0400 Subject: [PATCH 3/9] Additional tests for confserver Additional tests for confserver --- bumper/__init__.py | 6 +- bumper/confserver.py | 103 ++++----- tests/test_confserver.py | 473 ++++++++++++++++++++++++++++++++++----- tests/tests.md | 16 ++ 4 files changed, 494 insertions(+), 104 deletions(-) create mode 100644 tests/tests.md diff --git a/bumper/__init__.py b/bumper/__init__.py index 649f580..d8f78dd 100644 --- a/bumper/__init__.py +++ b/bumper/__init__.py @@ -50,7 +50,7 @@ def get_milli_time(timetoconvert): def db_file(): if db: return db - + return os_db_path() @@ -58,7 +58,7 @@ def os_db_path(): if platform.system() == "Windows": return os.path.join(os.getenv("APPDATA"), "bumper.db") else: - return os.path.expanduser("~/.config/bumper.db") + return os.path.expanduser("~/.config/bumper.db") def db_get(): @@ -95,7 +95,7 @@ def user_add(userid): def user_get(userid): users = db_get().table("users") - User = Query() + User = Query() return users.get(User.userid == userid) diff --git a/bumper/confserver.py b/bumper/confserver.py index 16d9a1e..f826a54 100644 --- a/bumper/confserver.py +++ b/bumper/confserver.py @@ -210,9 +210,7 @@ class ConfServer: "code": bumper.ERR_USER_NOT_ACTIVATED, "data": None, "msg": "当前密码错误", - "time": bumper.get_milli_time( - datetime.utcnow().timestamp() - ), + "time": bumper.get_milli_time(datetime.utcnow().timestamp()), } return web.json_response(body) @@ -427,9 +425,7 @@ class ConfServer: "hasCampaign": "N", "imageUrl": None, "nextAlertTime": nextAlert, - "serverTime": bumper.get_milli_time( - datetime.utcnow().timestamp() - ), + "serverTime": bumper.get_milli_time(datetime.utcnow().timestamp()), }, "msg": "操作成功", "time": bumper.get_milli_time(datetime.utcnow().timestamp()), @@ -519,65 +515,70 @@ class ConfServer: confserverlog.exception("{}".format(e)) async def handle_usersapi(self, request): - try: + if not request.method == "GET": # Skip GET for now + try: - body = {} - postbody = {} - if request.content_type == "application/x-www-form-urlencoded": - postbody = await request.post() + body = {} + postbody = {} + if request.content_type == "application/x-www-form-urlencoded": + postbody = await request.post() - else: - postbody = json.loads(await request.text()) + else: + postbody = json.loads(await request.text()) - todo = postbody["todo"] - if todo == "FindBest": - service = postbody["service"] - if service == "EcoMsgNew": + todo = postbody["todo"] + if todo == "FindBest": + service = postbody["service"] + if service == "EcoMsgNew": + body = { + "result": "ok", + "ip": socket.gethostbyname(socket.gethostname()), + "port": 5223, + } + elif service == "EcoUpdate": + body = {"result": "ok", "ip": "47.88.66.164", "port": 8005} + + elif todo == "loginByItToken": + if bumper.check_authcode(postbody["userId"], postbody["token"]): + body = { + "resource": postbody["resource"], + "result": "ok", + "todo": "result", + "token": postbody["token"], + "userId": postbody["userId"], + } + + elif todo == "GetDeviceList": body = { - "result": "ok", - "ip": socket.gethostbyname(socket.gethostname()), - "port": 5223, - } - elif service == "EcoUpdate": - body = {"result": "ok", "ip": "47.88.66.164", "port": 8005} - - elif todo == "loginByItToken": - if bumper.check_authcode(postbody["userId"], postbody["token"]): - body = { - "resource": postbody["resource"], + "devices": bumper.db_get().table("bots").all(), "result": "ok", "todo": "result", - "token": postbody["token"], - "userId": postbody["userId"], } - elif todo == "GetDeviceList": - body = { - "devices": bumper.db_get().table("bots").all(), - "result": "ok", - "todo": "result", - } + elif todo == "SetDeviceNick": + bumper.bot_set_nick(postbody["did"], postbody["nick"]) + body = {"result": "ok", "todo": "result"} - elif todo == "SetDeviceNick": - bumper.bot_set_nick(postbody["did"], postbody["nick"]) - body = {"result": "ok", "todo": "result"} + elif todo == "AddOneDevice": + bumper.bot_set_nick(postbody["did"], postbody["nick"]) + body = {"result": "ok", "todo": "result"} - elif todo == "AddOneDevice": - bumper.bot_set_nick(postbody["did"], postbody["nick"]) - body = {"result": "ok", "todo": "result"} + elif todo == "DeleteOneDevice": + bumper.bot_remove(postbody["did"]) + body = {"result": "ok", "todo": "result"} - elif todo == "DeleteOneDevice": - bumper.bot_remove(postbody["did"]) - body = {"result": "ok", "todo": "result"} + confserverlog.debug( + "\r\n POST: {} \r\n Response: {}".format(postbody, body) + ) - confserverlog.debug( - "\r\n POST: {} \r\n Response: {}".format(postbody, body) - ) + return web.json_response(body) - return web.json_response(body) + except Exception as e: + confserverlog.exception("{}".format(e)) - except Exception as e: - confserverlog.exception("{}".format(e)) + # Return fail for GET + body = {"result": "fail", "todo": "result"} + return web.json_response(body) async def handle_lookup(self, request): try: diff --git a/tests/test_confserver.py b/tests/test_confserver.py index dcf6030..ef6cdb0 100644 --- a/tests/test_confserver.py +++ b/tests/test_confserver.py @@ -28,7 +28,8 @@ def test_base(): text = await resp.text() assert "Bumper!" in text - loop.run_until_complete(test_handle_base()) # Test handle_base + # Test + loop.run_until_complete(test_handle_base()) loop.run_until_complete( client.close() @@ -48,30 +49,34 @@ def test_login(): resp = await client.get("/1/private/us/en/dev_1234/ios/1/0/0/user/login") assert resp.status == 200 text = await resp.text() - loginresp = json.loads(text) - if loginresp: - assert loginresp["code"] == "0000" - assert "accessToken" in loginresp["data"] - assert "uid" in loginresp["data"] - assert "username" in loginresp["data"] + jsonresp = json.loads(text) + if jsonresp: + assert jsonresp["code"] == bumper.RETURN_API_SUCCESS + assert "accessToken" in jsonresp["data"] + assert "uid" in jsonresp["data"] + assert "username" in jsonresp["data"] else: - assert loginresp + assert jsonresp - loop.run_until_complete(test_handle_login()) # Test handle_login + # Test + loop.run_until_complete(test_handle_login()) - #Add a user to db and test with existing users + # Add a user to db and test with existing users bumper.user_add("testuser") - loop.run_until_complete(test_handle_login()) # Test handle_login with user in db + # Test + loop.run_until_complete(test_handle_login()) - #Add a bot to db that will be added to user + # Add a bot to db that will be added to user bumper.bot_add("sn_123", "did_123", "dev_123", "res_123", "com_123") - loop.run_until_complete(test_handle_login()) # Test handle_login with user in db + # Test + loop.run_until_complete(test_handle_login()) loop.run_until_complete( client.close() ) # Close test server after all tests are done -def test_check_login(): + +def test_logout(): if os.path.exists("tests/tmp.db"): os.remove("tests/tmp.db") # Remove existing db bumper.db = "tests/tmp.db" # Set db location for testing @@ -80,49 +85,417 @@ def test_check_login(): loop.run_until_complete(client.start_server()) root = "http://{}".format(confserver.address) - async def test_handle_checkLogin_nouser(): - resp = await client.get("/1/private/us/en/dev_1234/ios/1/0/0/user/checkLogin?accessToken=token_1234") + async def test_handle_logout(token=None): + resp = await client.get( + "/1/private/us/en/dev_1234/ios/1/0/0/user/logout?accessToken={}".format( + token + ) + ) assert resp.status == 200 text = await resp.text() - loginresp = json.loads(text) - if loginresp: - assert loginresp["code"] == "0000" - assert "accessToken" in loginresp["data"] - assert loginresp["data"]["accessToken"] != "token_1234" - assert "uid" in loginresp["data"] - assert "username" in loginresp["data"] + jsonresp = json.loads(text) + if jsonresp: + assert jsonresp["code"] == bumper.RETURN_API_SUCCESS else: - assert loginresp + assert jsonresp - async def test_handle_checkLogin_withuser(): - resp = await client.get("/1/private/us/en/dev_1234/ios/1/0/0/user/checkLogin?accessToken=token_1234") - assert resp.status == 200 - text = await resp.text() - loginresp = json.loads(text) - if loginresp: - assert loginresp["code"] == "0000" - assert "accessToken" in loginresp["data"] - assert loginresp["data"]["accessToken"] == "token_1234" - assert "uid" in loginresp["data"] - assert "username" in loginresp["data"] - else: - assert loginresp - - loop.run_until_complete(test_handle_checkLogin_nouser()) # Test handle_login no user - - #Add a user to db and test with existing users + # Add a token to user and test bumper.user_add("testuser") - loop.run_until_complete(test_handle_checkLogin_nouser()) # Test handle_login with user in db - - #Remove dev from tmpuser - bumper.user_remove_device("tmpuser","dev_1234") - - #Add a token to user and test - bumper.user_add("testuser") - bumper.user_add_device("testuser","dev_1234") + bumper.user_add_device("testuser", "dev_1234") bumper.user_add_token("testuser", "token_1234") - loop.run_until_complete(test_handle_checkLogin_withuser()) # Test handle_login with user in db + # Test + loop.run_until_complete(test_handle_logout(token="token_1234")) loop.run_until_complete( client.close() ) # Close test server after all tests are done + + +def test_checkLogin(): + if os.path.exists("tests/tmp.db"): + os.remove("tests/tmp.db") # Remove existing db + bumper.db = "tests/tmp.db" # Set db location for testing + loop = asyncio.get_event_loop() + client = TestClient(TestServer(app), loop=loop) + loop.run_until_complete(client.start_server()) + root = "http://{}".format(confserver.address) + + async def test_handle_checkLogin(token=None): + resp = await client.get( + "/1/private/us/en/dev_1234/ios/1/0/0/user/checkLogin?accessToken={}".format( + token + ) + ) + assert resp.status == 200 + text = await resp.text() + jsonresp = json.loads(text) + if jsonresp: + assert jsonresp["code"] == bumper.RETURN_API_SUCCESS + assert "accessToken" in jsonresp["data"] + if not token: + assert jsonresp["data"]["accessToken"] != "token_1234" + else: + assert jsonresp["data"]["accessToken"] == "token_1234" + + assert "uid" in jsonresp["data"] + assert "username" in jsonresp["data"] + else: + assert jsonresp + + # Test + loop.run_until_complete(test_handle_checkLogin()) + + # Add a user to db and test with existing users + bumper.user_add("testuser") + # Test + loop.run_until_complete(test_handle_checkLogin()) + + # Remove dev from tmpuser + bumper.user_remove_device("tmpuser", "dev_1234") + + # Add a token to user and test + bumper.user_add("testuser") + bumper.user_add_device("testuser", "dev_1234") + bumper.user_add_token("testuser", "token_1234") + # Test + loop.run_until_complete(test_handle_checkLogin(token="token_1234")) + + loop.run_until_complete( + client.close() + ) # Close test server after all tests are done + + +def test_getAuthCode(): + if os.path.exists("tests/tmp.db"): + os.remove("tests/tmp.db") # Remove existing db + bumper.db = "tests/tmp.db" # Set db location for testing + loop = asyncio.get_event_loop() + client = TestClient(TestServer(app), loop=loop) + loop.run_until_complete(client.start_server()) + root = "http://{}".format(confserver.address) + + async def test_handle_getAuthCode(uid=None, token=None): + resp = await client.get( + "/1/private/us/en/dev_1234/ios/1/0/0/user/getAuthCode?uid={}&accessToken={}".format( + uid, token + ) + ) + assert resp.status == 200 + text = await resp.text() + jsonresp = json.loads(text) + if jsonresp: + if token: + assert jsonresp["code"] == bumper.RETURN_API_SUCCESS + assert "authCode" in jsonresp["data"] + assert "ecovacsUid" in jsonresp["data"] + else: + assert jsonresp["code"] == bumper.ERR_TOKEN_INVALID + else: + assert jsonresp + + # Test without user or token + loop.run_until_complete(test_handle_getAuthCode()) + + # Add a token to user and test + bumper.user_add("testuser") + bumper.user_add_device("testuser", "dev_1234") + bumper.user_add_token("testuser", "token_1234") + # Test + loop.run_until_complete(test_handle_getAuthCode(uid="testuser", token="token_1234")) + + # The above should have added an authcode to token, try again to test with existing authcode + # Test + loop.run_until_complete(test_handle_getAuthCode(uid="testuser", token="token_1234")) + + loop.run_until_complete( + client.close() + ) # Close test server after all tests are done + + +def test_checkAgreement(): + if os.path.exists("tests/tmp.db"): + os.remove("tests/tmp.db") # Remove existing db + bumper.db = "tests/tmp.db" # Set db location for testing + loop = asyncio.get_event_loop() + client = TestClient(TestServer(app), loop=loop) + loop.run_until_complete(client.start_server()) + root = "http://{}".format(confserver.address) + + async def test_handle_checkAgreement(): + resp = await client.get( + "/1/private/us/en/dev_1234/ios/1/0/0/user/checkAgreement" + ) + assert resp.status == 200 + text = await resp.text() + jsonresp = json.loads(text) + if jsonresp: + assert jsonresp["code"] == bumper.RETURN_API_SUCCESS + else: + assert jsonresp + + # Test + loop.run_until_complete(test_handle_checkAgreement()) + + loop.run_until_complete( + client.close() + ) # Close test server after all tests are done + + +def test_homePageAlert(): + if os.path.exists("tests/tmp.db"): + os.remove("tests/tmp.db") # Remove existing db + bumper.db = "tests/tmp.db" # Set db location for testing + loop = asyncio.get_event_loop() + client = TestClient(TestServer(app), loop=loop) + loop.run_until_complete(client.start_server()) + root = "http://{}".format(confserver.address) + + async def test_handle_homePageAlert(): + resp = await client.get( + "/1/private/us/en/dev_1234/ios/1/0/0/campaign/homePageAlert" + ) + assert resp.status == 200 + text = await resp.text() + jsonresp = json.loads(text) + if jsonresp: + assert jsonresp["code"] == bumper.RETURN_API_SUCCESS + else: + assert jsonresp + + # Test + loop.run_until_complete(test_handle_homePageAlert()) + + loop.run_until_complete( + client.close() + ) # Close test server after all tests are done + + +def test_checkVersion(): + if os.path.exists("tests/tmp.db"): + os.remove("tests/tmp.db") # Remove existing db + bumper.db = "tests/tmp.db" # Set db location for testing + loop = asyncio.get_event_loop() + client = TestClient(TestServer(app), loop=loop) + loop.run_until_complete(client.start_server()) + root = "http://{}".format(confserver.address) + + async def test_handle_checkVersion(): + resp = await client.get( + "/1/private/us/en/dev_1234/ios/1/0/0/common/checkVersion" + ) + assert resp.status == 200 + text = await resp.text() + jsonresp = json.loads(text) + if jsonresp: + assert jsonresp["code"] == bumper.RETURN_API_SUCCESS + else: + assert jsonresp + + # Test + loop.run_until_complete(test_handle_checkVersion()) + + loop.run_until_complete( + client.close() + ) # Close test server after all tests are done + + +def test_getProductIotMap(): + if os.path.exists("tests/tmp.db"): + os.remove("tests/tmp.db") # Remove existing db + bumper.db = "tests/tmp.db" # Set db location for testing + loop = asyncio.get_event_loop() + client = TestClient(TestServer(app), loop=loop) + loop.run_until_complete(client.start_server()) + root = "http://{}".format(confserver.address) + + async def test_handle_getProductIotMap(): + resp = await client.post("/api/pim/product/getProductIotMap") + assert resp.status == 200 + text = await resp.text() + jsonresp = json.loads(text) + if jsonresp: + assert jsonresp["code"] == bumper.RETURN_API_SUCCESS + else: + assert jsonresp + + # Test + loop.run_until_complete(test_handle_getProductIotMap()) + + loop.run_until_complete( + client.close() + ) # Close test server after all tests are done + + +def test_getUsersAPI(): + if os.path.exists("tests/tmp.db"): + os.remove("tests/tmp.db") # Remove existing db + bumper.db = "tests/tmp.db" # Set db location for testing + loop = asyncio.get_event_loop() + client = TestClient(TestServer(app), loop=loop) + loop.run_until_complete(client.start_server()) + root = "http://{}".format(confserver.address) + + async def test_handle_getUsersApi(): + resp = await client.get("/api/users/user.do") + assert resp.status == 200 + text = await resp.text() + jsonresp = json.loads(text) + if jsonresp: + assert jsonresp["result"] == "fail" + else: + assert jsonresp + + # Test + loop.run_until_complete(test_handle_getUsersApi()) + + loop.run_until_complete( + client.close() + ) # Close test server after all tests are done + + +def test_postUsersAPI(): + if os.path.exists("tests/tmp.db"): + os.remove("tests/tmp.db") # Remove existing db + bumper.db = "tests/tmp.db" # Set db location for testing + loop = asyncio.get_event_loop() + client = TestClient(TestServer(app), loop=loop) + loop.run_until_complete(client.start_server()) + root = "http://{}".format(confserver.address) + + async def test_handle_postUsersApi(postbody=None): + resp = await client.post("/api/users/user.do", json=postbody) + + assert resp.status == 200 + text = await resp.text() + jsonresp = json.loads(text) + if jsonresp: + assert jsonresp["result"] == "ok" + else: + assert jsonresp + + # Test FindBest + postbody = {"todo": "FindBest", "service": "EcoMsgNew"} + # Test + loop.run_until_complete(test_handle_postUsersApi(postbody)) + + # Test EcoUpdate + postbody = {"todo": "FindBest", "service": "EcoUpdate"} + # Test + loop.run_until_complete(test_handle_postUsersApi(postbody)) + + # Test loginByItToken - Uses the authcode + bumper.user_add("testuser") + bumper.user_add_device("testuser", "dev_1234") + bumper.user_add_token("testuser", "token_1234") + bumper.user_add_authcode("testuser", "token_1234", "auth_1234") + bumper.user_add_bot("testuser", "did_1234") + bumper.bot_add("sn_1234", "did_1234", "class_1234", "res_1234", "com_1234") + # Test + postbody = { + "country": "US", + "last": "", + "realm": "ecouser.net", + "resource": "dev_1234", + "todo": "loginByItToken", + "token": "auth_1234", + "userId": "testuser", + } + loop.run_until_complete(test_handle_postUsersApi(postbody)) + + # Test GetDeviceList + postbody = { + "auth": { + "realm": "ecouser.net", + "resource": "dev_1234", + "token": "token_1234", + "userid": "testuser", + "with": "users", + }, + "todo": "GetDeviceList", + "userid": "testuser", + } + loop.run_until_complete(test_handle_postUsersApi(postbody)) + + # Test SetDeviceNick + postbody = { + "auth": { + "realm": "ecouser.net", + "resource": "dev_1234", + "token": "token_1234", + "userid": "testuser", + "with": "users", + }, + "todo": "SetDeviceNick", + "nick": "botnick", + "did": "did_1234", + } + loop.run_until_complete(test_handle_postUsersApi(postbody)) + + # Test AddOneDevice - Same as set nick for some bots + postbody = { + "auth": { + "realm": "ecouser.net", + "resource": "dev_1234", + "token": "token_1234", + "userid": "testuser", + "with": "users", + }, + "todo": "AddOneDevice", + "nick": "botnick", + "did": "did_1234", + } + loop.run_until_complete(test_handle_postUsersApi(postbody)) + + # Test DeleteOneDevice - remove bot + postbody = { + "auth": { + "realm": "ecouser.net", + "resource": "dev_1234", + "token": "token_1234", + "userid": "testuser", + "with": "users", + }, + "todo": "DeleteOneDevice", + "did": "did_1234", + } + loop.run_until_complete(test_handle_postUsersApi(postbody)) + + loop.run_until_complete( + client.close() + ) # Close test server after all tests are done + + +def test_postLookup(): + if os.path.exists("tests/tmp.db"): + os.remove("tests/tmp.db") # Remove existing db + bumper.db = "tests/tmp.db" # Set db location for testing + loop = asyncio.get_event_loop() + client = TestClient(TestServer(app), loop=loop) + loop.run_until_complete(client.start_server()) + root = "http://{}".format(confserver.address) + + async def test_handle_lookup(postbody=None): + resp = await client.post("/lookup.do", json=postbody) + + assert resp.status == 200 + text = await resp.text() + jsonresp = json.loads(text) + if jsonresp: + assert jsonresp["result"] == "ok" + else: + assert jsonresp + + # Test FindBest + postbody = {"todo": "FindBest", "service": "EcoMsgNew"} + # Test + loop.run_until_complete(test_handle_lookup(postbody)) + + # Test EcoUpdate + postbody = {"todo": "FindBest", "service": "EcoUpdate"} + # Test + loop.run_until_complete(test_handle_lookup(postbody)) + + loop.run_until_complete( + client.close() + ) # Close test server after all tests are done + diff --git a/tests/tests.md b/tests/tests.md new file mode 100644 index 0000000..d4756ce --- /dev/null +++ b/tests/tests.md @@ -0,0 +1,16 @@ +# Bumper tests +Bumper uses nosetests for the majority of test cases. Install requirements using `pipenv install --dev` + +## Testing +Enter pipenv shell `pipenv shell` + +### Run tests +`nosetests` + +### Run tests with coverage +`nosetests --cover-package bumper --with-coverage` + +### Run tests with coverage html report +`nosetests --cover-package bumper --with-coverage --cover-html-dir="tests/report" --cover-html` + +The report will be output into tests/report/index.html for further analysis. \ No newline at end of file -- 2.39.5 From 4080f0f950cba4e0bd2739f47ffdaf55e7b97a96 Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Sun, 17 Mar 2019 11:02:53 -0400 Subject: [PATCH 4/9] More confserver tests More confserver tests, coverage 75% --- tests/test_confserver.py | 67 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 66 insertions(+), 1 deletion(-) diff --git a/tests/test_confserver.py b/tests/test_confserver.py index ef6cdb0..0de11dc 100644 --- a/tests/test_confserver.py +++ b/tests/test_confserver.py @@ -8,10 +8,17 @@ import tinydb from aiohttp.test_utils import TestClient, TestServer, loop_context from aiohttp import request -confserver = bumper.ConfServer("127.0.0.1:11111", False, None) +confserver = bumper.ConfServer("127.0.0.1:11111", False, mock.MagicMock) confserver.confserver_app() app = confserver.app +def async_return(result): + f = asyncio.Future() + f.set_result(result) + return f + +def test_disconnect(): + confserver.disconnect() def test_base(): if os.path.exists("tests/tmp.db"): @@ -499,3 +506,61 @@ def test_postLookup(): client.close() ) # Close test server after all tests are done +def test_devmgr(): + if os.path.exists("tests/tmp.db"): + os.remove("tests/tmp.db") # Remove existing db + bumper.db = "tests/tmp.db" # Set db location for testing + loop = asyncio.get_event_loop() + client = TestClient(TestServer(app), loop=loop) + loop.run_until_complete(client.start_server()) + root = "http://{}".format(confserver.address) + + async def test_devmanager(postbody=None, command=False): + resp = await client.post("/api/iot/devmanager.do", json=postbody) + + assert resp.status == 200 + text = await resp.text() + jsonresp = json.loads(text) + if jsonresp: + if not command: + assert jsonresp["ret"] == "ok" + else: + if "ret" in jsonresp: + if jsonresp["ret"] == "ok": + assert jsonresp["resp"] + else: + assert jsonresp["errno"] + else: + assert jsonresp + + # Test PollSCResult + postbody = {"td": "PollSCResult"} + # Test + loop.run_until_complete(test_devmanager(postbody, command=False)) + + # Test BotCommand + bumper.bot_add("sn_1234", "did_1234", "dev_1234", "res_1234", "eco-ng") + bumper.bot_set_mqtt("did_1234", True) + postbody = {"toId": "did_1234"} + + # Test return get status + command_getstatus_resp = { "id": "resp_1234", "resp": "", "ret": "ok" } + confserver.helperbot.send_command = mock.MagicMock(return_value=async_return(command_getstatus_resp)) + # Test + loop.run_until_complete(test_devmanager(postbody, command=True)) + + # Test return fail timeout + command_timeout_resp = {"id": "resp_1234", "errno": "timeout", "ret": "fail"} + confserver.helperbot.send_command = mock.MagicMock(return_value=async_return(command_timeout_resp)) + # Test + loop.run_until_complete(test_devmanager(postbody, command=True)) + + # Set bot not on mqtt + bumper.bot_set_mqtt("did_1234", False) + confserver.helperbot.send_command = mock.MagicMock(return_value=async_return(command_getstatus_resp)) + # Test + loop.run_until_complete(test_devmanager(postbody, command=True)) + + loop.run_until_complete( + client.close() + ) # Close test server after all tests are done -- 2.39.5 From a1ff95cc231339cb5c38fac0a40cd6590ff6659e Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Sun, 17 Mar 2019 11:35:52 -0400 Subject: [PATCH 5/9] Add session to mqtt Add session to mqtt --- bumper/mqttserver.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bumper/mqttserver.py b/bumper/mqttserver.py index 8f61a66..cce5f57 100644 --- a/bumper/mqttserver.py +++ b/bumper/mqttserver.py @@ -339,6 +339,7 @@ class BumperMQTTServer_Plugin: tmpbotdetail[1], "eco-ng", ) + mqttserverlog.debug( "new bot authenticated SN: {} DID: {}".format( username, didsplit[0] @@ -372,7 +373,7 @@ class BumperMQTTServer_Plugin: authenticated = False except Exception as e: - mqttserverlog.exception("{}".format(e)) + mqttserverlog.exception("Session: {} - {}".format((kwargs.get("session", None)),e)) authenticated = False return authenticated -- 2.39.5 From 70b88a4e263fcf3d2836ff2c832f4506c012e795 Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Mon, 18 Mar 2019 23:16:30 -0400 Subject: [PATCH 6/9] Create .travis.yml --- .travis.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..2a896d1 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,10 @@ +language: python +python: + - "3.4" + - "3.5" + - "3.6" +install: + - pip install pipenv + - pipenv install --dev + +script: nosetests -- 2.39.5 From ccbfc2d58fab933e5fe728b1cfed58d8726fb456 Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Mon, 18 Mar 2019 23:18:55 -0400 Subject: [PATCH 7/9] Update .travis.yml --- .travis.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2a896d1..2a0e7cf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,6 @@ language: python python: - - "3.4" - - "3.5" - - "3.6" + - "3.7" install: - pip install pipenv - pipenv install --dev -- 2.39.5 From d2a95f01686732f5d2045d8fe1218231f3af650c Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Mon, 18 Mar 2019 23:23:28 -0400 Subject: [PATCH 8/9] Update .travis.yml --- .travis.yml | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2a0e7cf..ccfe3d7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,10 @@ language: python -python: - - "3.7" +# Enable python 3.7 without globally enabling sudo and dist: xenial for other build jobs +matrix: + include: + - python: 3.7 + dist: xenial + sudo: true install: - pip install pipenv - pipenv install --dev -- 2.39.5 From f29c9a70ffd6916c5901bad9afab50902fbb2eb0 Mon Sep 17 00:00:00 2001 From: Brian Martin Date: Mon, 18 Mar 2019 23:33:35 -0400 Subject: [PATCH 9/9] Create appveyor.yml --- appveyor.yml | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 appveyor.yml diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..26f3592 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,22 @@ +environment: + + matrix: + + # For Python versions available on Appveyor, see + # http://www.appveyor.com/docs/installed-software#python + + - PYTHON: "C:\\Python37" + +install: + - pip install pipenv + - pipenv --python 3 + - pipenv install --dev + +build: off + +test_script: + # Put your test command here. + # Note that you must use the environment variable %PYTHON% to refer to + # the interpreter you're using - Appveyor does not do anything special + # to put the Python version you want to use on PATH. +- "pipenv run nosetests" -- 2.39.5