From db08ae5dac684a1155dedfd199ae4e372c82e9df Mon Sep 17 00:00:00 2001 From: "Hansen, Tony (th1395)" Date: Mon, 27 Jan 2020 22:28:34 +0000 Subject: increase code coverage Change-Id: I30632d2e34401f8eff6e67b9b3d8abba32e80050 Signed-off-by: Hansen, Tony (th1395) Issue-ID: DCAEGEN2-1902 Signed-off-by: Hansen, Tony (th1395) --- .gitignore | 11 + LICENSE.txt | 5 +- makefile | 4 + miss_htbt_service/__init__.py | 5 +- miss_htbt_service/cbs_polling.py | 2 +- miss_htbt_service/check_health.py | 10 +- miss_htbt_service/config_notif.py | 47 +-- miss_htbt_service/db_monitoring.py | 2 +- miss_htbt_service/get_logger.py | 4 +- miss_htbt_service/htbtworker.py | 12 +- miss_htbt_service/makefile | 2 + miss_htbt_service/misshtbt.sh | 3 - miss_htbt_service/misshtbtd.py | 13 +- miss_htbt_service/mod/__init__.py | 4 +- miss_htbt_service/mod/trapd_exit.py | 6 +- miss_htbt_service/mod/trapd_get_cbs_config.py | 6 +- miss_htbt_service/mod/trapd_http_session.py | 6 +- miss_htbt_service/mod/trapd_io.py | 6 +- miss_htbt_service/mod/trapd_runtime_pid.py | 6 +- miss_htbt_service/mod/trapd_settings.py | 6 +- miss_htbt_service/mod/trapd_vnf_table.py | 9 +- mvn-phase-script.sh | 3 - pom.xml | 2 - setup.py | 22 +- tests/__init__.py | 4 +- tests/makefile | 2 + tests/monkey_psycopg2.py | 207 ++++++++++++ tests/test_binding.py | 5 +- tests/test_check_health.py | 65 ++++ tests/test_config_notif.py | 435 ++++++++++++++++++++++++++ tests/test_get_logger.py | 35 +++ tests/test_htbtworker.py | 45 +++ tests/test_trapd_exit.py | 4 +- tests/test_trapd_get_cbs_config.py | 4 +- tests/test_trapd_http_session.py | 4 +- tests/test_trapd_runtime_pid.py | 4 +- tests/test_trapd_settings.py | 5 +- tests/test_trapd_vnf_table.py | 4 +- tox.ini | 4 +- 39 files changed, 894 insertions(+), 129 deletions(-) create mode 100644 .gitignore create mode 100644 makefile create mode 100644 miss_htbt_service/makefile create mode 100644 tests/makefile create mode 100644 tests/monkey_psycopg2.py create mode 100644 tests/test_check_health.py create mode 100644 tests/test_config_notif.py create mode 100644 tests/test_get_logger.py create mode 100644 tests/test_htbtworker.py diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f1e4e3b --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +coverage.xml +xunit-tests.xml +*~ +*.sv +.tox +__pycache__ +htmlcov +hb_logs.txt +.coverage +xunit-results.xml +miss_htbt_service.egg-info diff --git a/LICENSE.txt b/LICENSE.txt index 9536f0b..aba4f3c 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -1,7 +1,7 @@ /* * ============LICENSE_START========================================== * =================================================================== -* Copyright (c) 2017 AT&T Intellectual Property. All rights reserved. +* Copyright (c) 2017-2020 AT&T Intellectual Property. All rights reserved. * =================================================================== * * Unless otherwise specified, all software contained herein is licensed @@ -33,8 +33,5 @@ * limitations under the License. * * ============LICENSE_END============================================ -* -* ECOMP is a trademark and service mark of AT&T Intellectual Property. -* */ diff --git a/makefile b/makefile new file mode 100644 index 0000000..494f08c --- /dev/null +++ b/makefile @@ -0,0 +1,4 @@ +runtox: + . ~/bin/set_proxies; \ + tox test | cat + coverage html diff --git a/miss_htbt_service/__init__.py b/miss_htbt_service/__init__.py index 8da7cd3..1ae08ca 100644 --- a/miss_htbt_service/__init__.py +++ b/miss_htbt_service/__init__.py @@ -1,5 +1,5 @@ # ================================================================================ -# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2018-2020 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,9 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. - # empty __init__.py so that pytest can add correct path to coverage report, -- per pytest # best practice guideline diff --git a/miss_htbt_service/cbs_polling.py b/miss_htbt_service/cbs_polling.py index 01f30bb..7d19610 100644 --- a/miss_htbt_service/cbs_polling.py +++ b/miss_htbt_service/cbs_polling.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright 2018 AT&T Intellectual Property, Inc. All rights reserved. +# Copyright 2018-2020 AT&T Intellectual Property, Inc. All rights reserved. # Copyright (c) 2019 Pantheon.tech. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/miss_htbt_service/check_health.py b/miss_htbt_service/check_health.py index 5732749..03c390b 100644 --- a/miss_htbt_service/check_health.py +++ b/miss_htbt_service/check_health.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # ============LICENSE_START======================================================= -# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2020 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,8 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. from http.server import HTTPServer, BaseHTTPRequestHandler from urllib import parse @@ -45,18 +43,18 @@ class GetHandler(BaseHTTPRequestHandler): ]) self.send_response(200) self.end_headers() - self.wfile.write(message) + self.wfile.write(bytes(message, 'utf-8')) return def do_POST(self): - content_len = int(self.headers.getheader('content-length')) + content_len = int(self.headers.get('content-length', 0)) post_body = self.rfile.read(content_len) self.send_response(200) self.end_headers() data = json.loads(post_body) - self.wfile.write(data['health']) + self.wfile.write(bytes(data['health'], 'utf-8')) return if __name__ == '__main__': diff --git a/miss_htbt_service/config_notif.py b/miss_htbt_service/config_notif.py index a1d2d8b..6b54bad 100644 --- a/miss_htbt_service/config_notif.py +++ b/miss_htbt_service/config_notif.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright 2018 AT&T Intellectual Property, Inc. All rights reserved. +# Copyright 2018-2020 AT&T Intellectual Property, Inc. All rights reserved. # Copyright (c) 2019 Pantheon.tech. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -29,7 +29,9 @@ import psycopg2 from pathlib import Path import os.path as path from .mod import trapd_settings as tds -from .mod.trapd_get_cbs_config import get_cbs_config +# use the fully qualified name here to let monkeypatching work +# from .mod.trapd_get_cbs_config import get_cbs_config +import miss_htbt_service.mod.trapd_get_cbs_config hb_properties_file = path.abspath(path.join(__file__, "../config/hbproperties.yaml")) @@ -37,39 +39,42 @@ def postgres_db_open(username,password,host,port,database_name): envPytest = os.getenv('pytest', "") if (envPytest == 'test'): return True - try: #pragma: no cover - connection = psycopg2.connect(database=database_name, user = username, password = password, host = host, port =port) + try: + connection = psycopg2.connect(database=database_name, user = username, password = password, host = host, port =port) except Exception as e: - print("HB_Notif::postgress connect error: %s" % e) - connection = True + print("HB_Notif::postgress connect error: %s" % e) + connection = True return connection def db_table_creation_check(connection_db,table_name): envPytest = os.getenv('pytest', "") if (envPytest == 'test'): return True - try: #pragma: no cover + cur = None + try: cur = connection_db.cursor() query_db = "select * from information_schema.tables where table_name='%s'" %(table_name) cur.execute(query_db) database_names = cur.fetchone() - if(database_names is not None): - if(table_name in database_names): - print("HB_Notif::Postgres already has table - %s" % table_name) - return True + if (database_names is not None) and (table_name in database_names): + print(f"FOUND the table {table_name}") + print("HB_Notif::Postgres already has table - %s" % table_name) + return True else: + print(f"did NOT find the table {table_name}") print("HB_Notif::Postgres does not have table - %s" % table_name) return False except psycopg2.DatabaseError as e: print('COMMON:Error %s' % e) finally: - cur.close() + if cur: + cur.close() def commit_and_close_db(connection_db): envPytest = os.getenv('pytest', "") if (envPytest == 'test'): return True - try: #pragma: no cover + try: connection_db.commit() # <--- makes sure the change is shown in the database connection_db.close() return True @@ -96,6 +101,8 @@ def read_hb_properties_default(): cbs_polling_required = a['CBS_polling_allowed'] cbs_polling_interval = a['CBS_polling_interval'] s.close() + # TODO: there is a mismatch here between read_hb_properties_default and read_hb_properties. + # read_hb_properties() forces all of the variables returned here to be strings, while the code here does not. return ip_address, port_num, user_name, password, db_name, cbs_polling_required, cbs_polling_interval def read_hb_properties(jsfile): @@ -134,6 +141,7 @@ def read_hb_common(user_name,password,ip_address,port_num,db_name): query_value = "SELECT process_id,source_name,last_accessed_time,current_state FROM hb_common;" cur.execute(query_value) rows = cur.fetchall() + # TODO: What if rows returned None or empty? print("HB_Notif::hb_common contents - %s" % rows) hbc_pid = rows[0][0] hbc_srcName = rows[0][1] @@ -158,9 +166,11 @@ def update_hb_common(update_flg, process_id, state, user_name,password,ip_addres cur.close() return True -def fetch_json_file(): - if get_cbs_config(): - current_runtime_config_file_name = "../etc/download1.json" +def fetch_json_file(download_json = "../etc/download1.json", config_json = "../etc/config.json"): + # use the fully qualified name here to let monkeypatching work + # if get_cbs_config(): + if miss_htbt_service.mod.trapd_get_cbs_config.get_cbs_config(): + current_runtime_config_file_name = download_json envPytest = os.getenv('pytest', "") if (envPytest == 'test'): jsfile = "../etc/config.json" @@ -171,7 +181,7 @@ def fetch_json_file(): jsfile = current_runtime_config_file_name else: print("MSHBD:CBS Config not available, using local config") - jsfile = "../etc/config.json" + jsfile = config_json print("Config_N: The json file is - %s" % jsfile) return jsfile @@ -187,11 +197,12 @@ def config_notif_run(): if(db_table_creation_check(connection_db,"hb_common") == False): print("HB_Notif::ERROR::hb_common table not exists - No config download") connection_db.close() - else: #pragma: no cover + else: hbc_pid, hbc_state, hbc_srcName, hbc_time = read_hb_common(user_name,password,ip_address,port_num,db_name) state = "RECONFIGURATION" update_flg = 1 ret = update_hb_common(update_flg, hbc_pid, state, user_name,password,ip_address,port_num,db_name) + # TODO: There is no way for update_hb_common() to return false if (ret == True): print("HB_Notif::hb_common table updated with RECONFIGURATION state") commit_and_close_db(connection_db) diff --git a/miss_htbt_service/db_monitoring.py b/miss_htbt_service/db_monitoring.py index 95b2dbe..6ab7732 100644 --- a/miss_htbt_service/db_monitoring.py +++ b/miss_htbt_service/db_monitoring.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright 2018 AT&T Intellectual Property, Inc. All rights reserved. +# Copyright 2018-2020 AT&T Intellectual Property, Inc. All rights reserved. # Copyright (c) 2019 Pantheon.tech. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/miss_htbt_service/get_logger.py b/miss_htbt_service/get_logger.py index 7afbc92..7d9d8d6 100644 --- a/miss_htbt_service/get_logger.py +++ b/miss_htbt_service/get_logger.py @@ -1,5 +1,5 @@ # ============LICENSE_START======================================================= -# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2020 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,8 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. import os import logging diff --git a/miss_htbt_service/htbtworker.py b/miss_htbt_service/htbtworker.py index c02f817..db0561f 100644 --- a/miss_htbt_service/htbtworker.py +++ b/miss_htbt_service/htbtworker.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -# Copyright 2018 AT&T Intellectual Property, Inc. All rights reserved. +# Copyright 2018-2020 AT&T Intellectual Property, Inc. All rights reserved. # Copyright (c) 2019 Pantheon.tech. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -30,19 +30,19 @@ from . import get_logger _logger = get_logger.get_logger(__name__) -def read_json_file(i): +def read_json_file(i, prefix="../../tests"): if (i==0): - with open (path.abspath(path.join(__file__, "../../tests/test1.json")), "r") as outfile: + with open (path.abspath(path.join(__file__, f"{prefix}/test1.json")), "r") as outfile: cfg = json.load(outfile) elif (i == 1): - with open (path.abspath(path.join(__file__, "../../tests/test2.json")), "r") as outfile: + with open (path.abspath(path.join(__file__, f"{prefix}/test2.json")), "r") as outfile: cfg = json.load(outfile) elif (i ==2): - with open( path.abspath(path.join(__file__, "../../tests/test3.json")), 'r') as outfile: + with open( path.abspath(path.join(__file__, f"{prefix}/test3.json")), 'r') as outfile: cfg = json.load(outfile) return cfg -def process_msg(jsfile,user_name, password, ip_address, port_num, db_name): +def process_msg(jsfile, user_name, password, ip_address, port_num, db_name): global mr_url i=0 sleep_duration = 20 diff --git a/miss_htbt_service/makefile b/miss_htbt_service/makefile new file mode 100644 index 0000000..9901727 --- /dev/null +++ b/miss_htbt_service/makefile @@ -0,0 +1,2 @@ +runtox: + cd .. && $(MAKE) runtox diff --git a/miss_htbt_service/misshtbt.sh b/miss_htbt_service/misshtbt.sh index 5b598b1..df453b4 100644 --- a/miss_htbt_service/misshtbt.sh +++ b/miss_htbt_service/misshtbt.sh @@ -17,9 +17,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. -# # get to where we are supposed to be for startup cd /opt/app/misshtbt/bin diff --git a/miss_htbt_service/misshtbtd.py b/miss_htbt_service/misshtbtd.py index 790ab6a..c56ad99 100644 --- a/miss_htbt_service/misshtbtd.py +++ b/miss_htbt_service/misshtbtd.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # ============LICENSE_START======================================================= -# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2020 AT&T Intellectual Property. All rights reserved. # Copyright (c) 2019 Pantheon.tech. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,7 +16,6 @@ # limitations under the License. # ============LICENSE_END========================================================= # -# ECOMP is a trademark and service mark of AT&T Intellectual Property. # This is a main process that does the following # - Creates the CBS polling process that indicates the periodic download of # configuration file from CBS @@ -109,11 +108,11 @@ def create_database(update_db, jsfile, ip_address, port_num, user_name, password def read_hb_common(user_name,password,ip_address,port_num,db_name): envPytest = os.getenv('pytest', "") if (envPytest == 'test'): - hbc_pid = 10 - hbc_srcName = "srvc_name" - hbc_time = 1584595881 - hbc_state = "RUNNING" - return hbc_pid, hbc_state, hbc_srcName, hbc_time + hbc_pid = 10 + hbc_srcName = "srvc_name" + hbc_time = 1584595881 + hbc_state = "RUNNING" + return hbc_pid, hbc_state, hbc_srcName, hbc_time connection_db = heartbeat.postgres_db_open(user_name,password,ip_address,port_num,db_name) cur = connection_db.cursor() query_value = "SELECT process_id,source_name,last_accessed_time,current_state FROM hb_common;" diff --git a/miss_htbt_service/mod/__init__.py b/miss_htbt_service/mod/__init__.py index 1875bf6..8e53efc 100644 --- a/miss_htbt_service/mod/__init__.py +++ b/miss_htbt_service/mod/__init__.py @@ -1,5 +1,5 @@ # ================================================================================ -# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2018-2020 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,8 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. # empty __init__.py so that pytest can add correct path to coverage report, -- per pytest diff --git a/miss_htbt_service/mod/trapd_exit.py b/miss_htbt_service/mod/trapd_exit.py index 80ed1b0..b1bd68f 100644 --- a/miss_htbt_service/mod/trapd_exit.py +++ b/miss_htbt_service/mod/trapd_exit.py @@ -1,7 +1,7 @@ # ============LICENSE_START======================================================= # org.onap.dcae # ================================================================================ -# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2020 AT&T Intellectual Property. All rights reserved. # Copyright (c) 2019 Pantheon.tech. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,9 +16,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. -# + """ trapc_exit_snmptrapd is responsible for removing any existing runtime PID file, and exiting with the provided (param 1) exit code diff --git a/miss_htbt_service/mod/trapd_get_cbs_config.py b/miss_htbt_service/mod/trapd_get_cbs_config.py index 86e621f..d0b8110 100644 --- a/miss_htbt_service/mod/trapd_get_cbs_config.py +++ b/miss_htbt_service/mod/trapd_get_cbs_config.py @@ -1,7 +1,7 @@ # ============LICENSE_START======================================================= # org.onap.dcae # ================================================================================ -# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2018-2020 AT&T Intellectual Property. All rights reserved. # Copyright (c) 2019 Pantheon.tech. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,9 +16,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. -# + """ Look for CBS broker and return application config; if not present, look for env variable that specifies JSON equiv of CBS config (typically used for diff --git a/miss_htbt_service/mod/trapd_http_session.py b/miss_htbt_service/mod/trapd_http_session.py index b34c19d..0d7f220 100644 --- a/miss_htbt_service/mod/trapd_http_session.py +++ b/miss_htbt_service/mod/trapd_http_session.py @@ -1,7 +1,7 @@ # ============LICENSE_START======================================================= # org.onap.dcae # ================================================================================ -# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2020 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,9 +15,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. -# + """ trapd_http_session establishes an http session for future use in publishing messages to the dmaap cluster. diff --git a/miss_htbt_service/mod/trapd_io.py b/miss_htbt_service/mod/trapd_io.py index 063f3ee..4f0904e 100644 --- a/miss_htbt_service/mod/trapd_io.py +++ b/miss_htbt_service/mod/trapd_io.py @@ -1,7 +1,7 @@ # ============LICENSE_START=======================================================) # org.onap.dcae # ================================================================================ -# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2018-2020 AT&T Intellectual Property. All rights reserved. # Copyright (c) 2019 Pantheon.tech. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); @@ -16,9 +16,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. -# + """ """ diff --git a/miss_htbt_service/mod/trapd_runtime_pid.py b/miss_htbt_service/mod/trapd_runtime_pid.py index c6ef76e..7194b8f 100644 --- a/miss_htbt_service/mod/trapd_runtime_pid.py +++ b/miss_htbt_service/mod/trapd_runtime_pid.py @@ -1,7 +1,7 @@ # ============LICENSE_START======================================================= # org.onap.dcae # ================================================================================ -# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2020 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,9 +15,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. -# + """ trapd_runtime_pid maintains a 'PID file' (file that contains the PID of currently running trap receiver) diff --git a/miss_htbt_service/mod/trapd_settings.py b/miss_htbt_service/mod/trapd_settings.py index be87e26..0c8457f 100644 --- a/miss_htbt_service/mod/trapd_settings.py +++ b/miss_htbt_service/mod/trapd_settings.py @@ -1,7 +1,7 @@ # ============LICENSE_START=======================================================) # org.onap.dcae # ================================================================================ -# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2018-2020 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,9 +15,7 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. -# + """ """ diff --git a/miss_htbt_service/mod/trapd_vnf_table.py b/miss_htbt_service/mod/trapd_vnf_table.py index 56aedbb..eeb4dc6 100644 --- a/miss_htbt_service/mod/trapd_vnf_table.py +++ b/miss_htbt_service/mod/trapd_vnf_table.py @@ -1,7 +1,7 @@ # ============LICENSE_START======================================================= # org.onap.dcae # ================================================================================ -# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2020 AT&T Intellectual Property. All rights reserved. # Copyright (c) 2019 Pantheon.tech. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,9 +17,8 @@ # limitations under the License. # ============LICENSE_END========================================================= # -# ECOMP is a trademark and service mark of AT&T Intellectual Property. -# ## Author Kiran Mandal (km386e) + """ trapd_vnf_table verifies the successful creation of DB Tables. """ @@ -120,7 +119,9 @@ def verify_cbspolling(): try: _cbspolling=cbs.pollCBS(10) except Exception as e: - #print("CBSP error - %s" % e) + # print("CBSP error - %s" % e) + # print("CBSP error - %s" % e, file=sys.stderr) + # print("Stack: {0}".format(traceback.format_exc()), file=sys.stderr) return None os.unsetenv('pytest') diff --git a/mvn-phase-script.sh b/mvn-phase-script.sh index d0d633a..b17056b 100755 --- a/mvn-phase-script.sh +++ b/mvn-phase-script.sh @@ -15,9 +15,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. - set -e diff --git a/pom.xml b/pom.xml index 29d3f36..a59c656 100644 --- a/pom.xml +++ b/pom.xml @@ -15,8 +15,6 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ============LICENSE_END========================================================= - -ECOMP is a trademark and service mark of AT&T Intellectual Property. --> 4.0.0 diff --git a/setup.py b/setup.py index 0ac0c9b..c8aef86 100644 --- a/setup.py +++ b/setup.py @@ -13,8 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. import os import string @@ -22,16 +20,16 @@ import sys import setuptools from setuptools import setup, find_packages -#from pip.req import parse_requirements -try: # for pip >= 10 - from pip._internal.req import parse_requirements -except ImportError: # for pip <= 9.0.3 - from pip.req import parse_requirements -#from pip.download import PipSession -try: # for pip >= 10 - from pip._internal.download import PipSession -except ImportError: # for pip <= 9.0.3 - from pip.download import PipSession +## #from pip.req import parse_requirements +## try: # for pip >= 10 +## from pip._internal.req import parse_requirements +## except ImportError: # for pip <= 9.0.3 +## from pip.req import parse_requirements +## #from pip.download import PipSession +## try: # for pip >= 10 +## from pip._internal.download import PipSession +## except ImportError: # for pip <= 9.0.3 +## from pip.download import PipSession setup( name='miss_htbt_service', diff --git a/tests/__init__.py b/tests/__init__.py index 1875bf6..8e53efc 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,5 +1,5 @@ # ================================================================================ -# Copyright (c) 2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2018-2020 AT&T Intellectual Property. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -13,8 +13,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. # empty __init__.py so that pytest can add correct path to coverage report, -- per pytest diff --git a/tests/makefile b/tests/makefile new file mode 100644 index 0000000..9901727 --- /dev/null +++ b/tests/makefile @@ -0,0 +1,2 @@ +runtox: + cd .. && $(MAKE) runtox diff --git a/tests/monkey_psycopg2.py b/tests/monkey_psycopg2.py new file mode 100644 index 0000000..05f44b4 --- /dev/null +++ b/tests/monkey_psycopg2.py @@ -0,0 +1,207 @@ +# ============LICENSE_START==================================================== +# ============================================================================= +# Copyright (c) 2017-2020 AT&T Intellectual Property. All rights reserved. +# ============================================================================= +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END====================================================== + +""" + +This is a mock psycopg2 module. + +""" + +import psycopg2 + +# These FORCE variables are set by monkey_psycopg2.monkey_reset_forces(). +# If set, they will cause a connection failure, cursor failure, execute failure, +# commit failure, and close failure, respectively. +FORCE_CONNECT_FAILURE = False +FORCE_CURSOR_FAILURE = False +FORCE_EXECUTE_FAILURE = False +FORCE_COMMIT_FAILURE = False +FORCE_CLOSE_FAILURE = False + +# This variable is used by monkey_psycopg2.monkey_set_defaults(multiDbInfo) +# to set up default values to be returned by cursors statements. +DEFAULT_MULTI_DBINFO = { } + +class MockConn(object): + """ + mock Connection interface returned by psycopg2.connect() + """ + + def __init__(self, dbInfo = None): + self.curCmd = None + self.curCursor = None + self.monkey_setDbInfo(dbInfo) + + def monkey_setDbInfo(self, dbInfo): + """ + Set up a set of defaults for the cursors on "select" statements. + The outer scope is a string that will be matched against the currently-active + select statement being executed. + If there is a match, the specified values are returned by the cursor. + dbconn.monkey_setDbInfo({ + "hb_common": [ + [ 1, "sn1", 31, "st1" ], + [ 2, "sn2", 32, "st2" ] + ] + }) + """ + self.dbInfo = dbInfo + + def commit(self): + """ + mock commit. + Do nothing unless FORCE_COMMIT_FAILURE is set. + + Will raise an exception if value of 'FORCE_COMMIT_FAILURE' is true. + Used to force failure for certain code paths. + """ + if FORCE_COMMIT_FAILURE: + raise psycopg2.DatabaseError(f"Unable to commit: force_commit_failure=<{FORCE_COMMIT_FAILURE}>") + + def close(self): + """ + mock close + Do nothing unless FORCE_CLOSE_FAILURE is set. + + Will raise an exception if value of 'FORCE_CLOSE_FAILURE' is true. + Used to force failure for certain code paths. + """ + if FORCE_CLOSE_FAILURE: + raise psycopg2.DatabaseError(f"Unable to close: force_close_failure=<{FORCE_CLOSE_FAILURE}>") + + def __enter__(self): + """ + method needed to implement a context manager + """ + return self + + # pylint: disable=redefined-outer-name,redefined-builtin + def __exit__(self, type, value, traceback): + """ + method needed to implement a context manager + """ + pass + + def cursor(self): + """ + mock cursor + + Will raise an exception if value of 'FORCE_CURSOR_FAILURE' is true. + Used to force failure for certain code paths. + """ + if FORCE_CURSOR_FAILURE: + raise psycopg2.DatabaseError(f"Unable to return cursor: force_cursor_failure=<{FORCE_CURSOR_FAILURE}>") + + print(f"cursor()") + self.curCursor = None + return self + + def execute(self, cmd, args = None): + """ + mock execute + + Will raise an exception if value of 'FORCE_EXECUTE_FAILURE' is true. + Used to force failure for certain code paths. + + A side affect is that the cursor's values will be set based on a match + with the command (lower-cased) being executed. + """ + # pylint: disable=global-statement,no-self-use + + print(f"execute({cmd},{args})") + self.curCmd = cmd + if FORCE_EXECUTE_FAILURE: + raise Exception("postgres execute command throwing exception. cmd=<{}>".format(cmd)) + + if self.dbInfo: + curCmdLower = cmd.lower() + for cmd, val in self.dbInfo.items(): + print(f"cmd={cmd}, val={val}") + if cmd in curCmdLower: + self.curCursor = val + break + + def fetchone(self): + """ + return a single row from the current cursor + """ + if not self.curCursor: + print(f"fetchone() returning None") + return None + print(f"fetchone() returning {self.curCursor[0]}") + return self.curCursor[0] + + def fetchall(self): + """ + return all rows from the current cursor + """ + if not self.curCursor: + print(f"fetchall() returning None") + return None + print(f"fetchall() returning {self.curCursor}") + return self.curCursor + +def monkey_reset_forces(connect=False, cursor=False, execute=False, commit=False, close=False): + print(f"monkey_reset_forces({connect}, {cursor}, {execute}, {commit}, {close})") + global FORCE_CONNECT_FAILURE + FORCE_CONNECT_FAILURE = connect + global FORCE_CURSOR_FAILURE + FORCE_CURSOR_FAILURE = cursor + global FORCE_EXECUTE_FAILURE + FORCE_EXECUTE_FAILURE = cursor + global FORCE_COMMIT_FAILURE + FORCE_COMMIT_FAILURE = commit + global FORCE_CLOSE_FAILURE + FORCE_CLOSE_FAILURE = close + +def monkey_set_defaults(multiDbInfo): + """ + Set up a set of defaults for the cursors on "select" statements. + The outer scope gives a database name. + The next level is a string that will be matched against the currently-active + select statement being executed. + If both match, the specified values are returned by the cursor. + monkey_psycopg2.monkey_set_defaults({ + "testdb1": { + "hb_common": [ + [ 1, "sn1", 31, "st1" ], + [ 2, "sn2", 32, "st2" ] + ] + } + }) + """ + global DEFAULT_MULTI_DBINFO + DEFAULT_MULTI_DBINFO = multiDbInfo + +def monkey_connect(database=None, host=None, port=None, user=None, password=None): + """ + Mock psycopg2 connection. + Returns a mock connection. + + Will raise an exception if value of 'FORCE_CONNECT_FAILURE' is true. + (Used to force failure for certain code paths.) + + Also set up any DbInfo values, based on the database name. + (See monkey_set_defaults(), which must have been called prior to this being invoked.) + """ + if FORCE_CONNECT_FAILURE: + raise Exception("Unable to connect to the database. password=<{}> force_connect_failure=<{}>".format(password, FORCE_CONNECT_FAILURE)) + + if database in DEFAULT_MULTI_DBINFO: + return MockConn(DEFAULT_MULTI_DBINFO[database]) + else: + return MockConn() diff --git a/tests/test_binding.py b/tests/test_binding.py index 0ef6c5d..170e8b1 100644 --- a/tests/test_binding.py +++ b/tests/test_binding.py @@ -1,5 +1,5 @@ # ============LICENSE_START======================================================= -# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2020 AT&T Intellectual Property. All rights reserved. # Copyright (c) 2019 Pantheon.tech. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,8 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. import os import io @@ -37,7 +35,6 @@ from miss_htbt_service import db_monitoring from miss_htbt_service.mod.trapd_vnf_table import hb_properties import unittest - MODULE_EXTENSIONS = ('.py', '.pyc', '.pyo') def package_contents(package_name): diff --git a/tests/test_check_health.py b/tests/test_check_health.py new file mode 100644 index 0000000..a159212 --- /dev/null +++ b/tests/test_check_health.py @@ -0,0 +1,65 @@ +# ============LICENSE_START======================================================= +# Copyright (c) 2017-2020 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2019 Pantheon.tech. All rights reserved. +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END========================================================= + +# code loosely based on https://stackoverflow.com/questions/25369068/python-how-to-unit-test-a-custom-http-request-handler + +from miss_htbt_service import check_health + +import io + +class MockSocket(object): + def getsockname(self): + return ('sockname',) + +class MockRequest(object): + _sock = MockSocket() + + def __init__(self, rqtype, path, body=None): + self._path = path + self._rqtype = rqtype if rqtype else "GET" + self._body = body + + def makefile(self, *args, **kwargs): + if args[0] == 'rb': + if self._rqtype == 'GET': + return io.BytesIO(bytes("%s %s HTTP/1.0" % (self._rqtype, self._path), 'utf-8')) + else: + return io.BytesIO(bytes("%s %s HTTP/1.0\r\nContent-Length: %s\r\n\r\n%s" % (self._rqtype, self._path, len(self._body), self._body), 'utf-8')) + elif args[0] == 'wb': + return io.BytesIO(b'') + else: + raise ValueError("Unknown file type to make", args, kwargs) + + def sendall(self, bstr): + pass + +class MockServer(object): + def __init__(self, rqtype, path, ip_port, Handler, body=None): + handler = Handler(MockRequest(rqtype, path, body), ip_port, self) + +def test_check_health_get(): + """ + test the check_health GET and POST handlers using a mock server + """ + server = MockServer('GET', '/', ('0.0.0.0', 8888), check_health.GetHandler) + +def test_check_health_post(): + """ + test the check_health GET and POST handlers using a mock server + """ + server = MockServer('POST', '/', ('0.0.0.0', 8888), check_health.GetHandler, + '{ "health": "" }') diff --git a/tests/test_config_notif.py b/tests/test_config_notif.py new file mode 100644 index 0000000..b59696e --- /dev/null +++ b/tests/test_config_notif.py @@ -0,0 +1,435 @@ +# ============LICENSE_START======================================================= +# Copyright (c) 2020 AT&T Intellectual Property. All rights reserved. +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END========================================================= + +from miss_htbt_service import config_notif +# from miss_htbt_service.mod.trapd_get_cbs_config import get_cbs_config +import miss_htbt_service.mod.trapd_get_cbs_config +import miss_htbt_service.mod.trapd_settings + +from . import monkey_psycopg2 +import psycopg2 +import tempfile, sys, json, os + +def assert_default_values(ip_address, port_num, user_name, password, db_name, cbs_polling_required, cbs_polling_interval): + """ + used in the test_read_hb_properties*() tests + """ + assert(str(port_num) == "5432") + assert(str(user_name) == "postgres") + assert(str(db_name) == "postgres") + assert(str(password) == "postgres") + +def test_read_hb_properties_default(): + """ + run read_hb_properties_default() + """ + ( ip_address, port_num, user_name, password, db_name, cbs_polling_required, cbs_polling_interval ) = config_notif.read_hb_properties_default() + assert_default_values(ip_address, port_num, user_name, password, db_name, cbs_polling_required, cbs_polling_interval) + +def test_read_hb_properties_success(): + """ + run read_hb_properties() to read properties from a file + """ + tmp = tempfile.NamedTemporaryFile(mode="w+") + testdata = { + "pg_ipAddress": "10.0.0.99", + "pg_portNum": 65432, + "pg_dbName": "dbname", + "pg_userName": "pguser", + "pg_passwd": "pgpswd", + "CBS_polling_allowed": True, + "CBS_polling_interval": 30, + "SERVICE_NAME": "service_name" + } + json.dump(testdata, tmp) + tmp.flush() + ( ip_address, port_num, user_name, password, db_name, cbs_polling_required, cbs_polling_interval ) = config_notif.read_hb_properties(tmp.name) + assert(str(ip_address) == str(testdata["pg_ipAddress"])) + assert(str(port_num) == str(testdata["pg_portNum"])) + assert(str(user_name) == str(testdata["pg_userName"])) + assert(str(password) == str(testdata["pg_passwd"])) + assert(str(db_name) == str(testdata["pg_dbName"])) + assert(str(cbs_polling_required) == str(testdata["CBS_polling_allowed"])) + assert(str(cbs_polling_interval) == str(testdata["CBS_polling_interval"])) + assert(str(os.environ['SERVICE_NAME']) == str(testdata["SERVICE_NAME"])) + +def test_read_hb_properties_fail_bad_json(): + """ + failure case for read_hb_properties: bad json in the file + """ + tmp = tempfile.NamedTemporaryFile(mode="w+") + print("bad json", file=tmp) + tmp.flush() + ( ip_address, port_num, user_name, password, db_name, cbs_polling_required, cbs_polling_interval ) = config_notif.read_hb_properties(tmp.name) + assert_default_values(ip_address, port_num, user_name, password, db_name, cbs_polling_required, cbs_polling_interval) + +def test_read_hb_properties_fail_missing_parameter(): + """ + failure case for read_hb_properties: CBS_polling_allowed is missing + """ + tmp = tempfile.NamedTemporaryFile(mode="w+") + testdata = { + "pg_ipAddress": "10.0.0.99", + "pg_portNum": 65432, + "pg_dbName": "dbname", + "pg_userName": "pguser", + "pg_passwd": "pgpswd", + # "CBS_polling_allowed": True, # missing CBS_polling_allowed + "CBS_polling_interval": 30, + "SERVICE_NAME": "service_name" + } + json.dump(testdata, tmp) + tmp.flush() + ( ip_address, port_num, user_name, password, db_name, cbs_polling_required, cbs_polling_interval ) = config_notif.read_hb_properties(tmp.name) + assert_default_values(ip_address, port_num, user_name, password, db_name, cbs_polling_required, cbs_polling_interval) + +def test_postgres_db_open(monkeypatch): + """ + test postgres_db_open() + """ + monkeypatch.setattr(psycopg2, 'connect', monkey_psycopg2.monkey_connect) + monkey_psycopg2.monkey_reset_forces() + dbconn = config_notif.postgres_db_open("test", "testpswd", "testsite", 5432, "dbname") + assert(type(dbconn) is monkey_psycopg2.MockConn) + +def test_postgres_db_open_fail(monkeypatch): + """ + failure ase for postgres_db_open() + """ + monkeypatch.setattr(psycopg2, 'connect', monkey_psycopg2.monkey_connect) + monkey_psycopg2.monkey_reset_forces(connect=True) + dbconn = config_notif.postgres_db_open("test", "badpassword", "testsite", 5432, "dbname") + assert(type(dbconn) is not monkey_psycopg2.MockConn) + +def test_db_table_creation_check(monkeypatch): + """ + test db_table_creation_check() + """ + monkeypatch.setattr(psycopg2, 'connect', monkey_psycopg2.monkey_connect) + monkey_psycopg2.monkey_reset_forces() + dbconn = config_notif.postgres_db_open("test", "testpswd", "testsite", 5432, "dbname") + dbconn.monkey_setDbInfo({ "select * from information_schema.tables": [ [ "testtable" ] ] }) + assert(type(dbconn) is monkey_psycopg2.MockConn) + ret = config_notif.db_table_creation_check(dbconn, "testtable") + assert(ret == True) + ret2 = config_notif.db_table_creation_check(dbconn, "missingtable") + monkey_psycopg2.monkey_reset_forces(cursor=True) + ret3 = config_notif.db_table_creation_check(dbconn, "testtable") + assert(ret3 is None) + +def test_commit_and_close_db(monkeypatch): + """ + test commit_and_close_db() + """ + monkeypatch.setattr(psycopg2, 'connect', monkey_psycopg2.monkey_connect) + monkey_psycopg2.monkey_reset_forces() + dbconn = config_notif.postgres_db_open("test", "testpswd", "testsite", 5432, "dbname") + assert(type(dbconn) is monkey_psycopg2.MockConn) + print("commit_and_close_db(): no forced failures") + ret = config_notif.commit_and_close_db(dbconn) + assert(ret == True) + +def test_commit_and_close_db_fail1(monkeypatch): + """ + failure case for commit_and_close_db(): dbconn.close() fails + """ + monkeypatch.setattr(psycopg2, 'connect', monkey_psycopg2.monkey_connect) + monkey_psycopg2.monkey_reset_forces() + dbconn = config_notif.postgres_db_open("test", "testpswd", "testsite", 5432, "dbname") + assert(type(dbconn) is monkey_psycopg2.MockConn) + print("commit_and_close_db() - close failure") + monkey_psycopg2.monkey_reset_forces(close=True) + ret = config_notif.commit_and_close_db(dbconn) + assert(ret == False) + +def test_commit_and_close_db_fail2(monkeypatch): + """ + failure case for commit_and_close_db(): dbconn.commit() fails + """ + monkeypatch.setattr(psycopg2, 'connect', monkey_psycopg2.monkey_connect) + monkey_psycopg2.monkey_reset_forces() + dbconn = config_notif.postgres_db_open("test", "testpswd", "testsite", 5432, "dbname") + assert(type(dbconn) is monkey_psycopg2.MockConn) + print("commit_and_close_db() - commit failure") + monkey_psycopg2.monkey_reset_forces(commit=True) + ret = config_notif.commit_and_close_db(dbconn) + assert(ret == False) + +def test_read_hb_properties_default(monkeypatch): + """ + test read_hb_properties_default() + """ + monkeypatch.setattr(psycopg2, 'connect', monkey_psycopg2.monkey_connect) + monkey_psycopg2.monkey_reset_forces() + monkey_psycopg2.monkey_set_defaults({ + "testdb1": { + "hb_common": [ + [ 1, "sn1", 31, "st1" ], + [ 2, "sn2", 32, "st2" ] + ] + } + }) + + output = config_notif.read_hb_common("test", "testpswd", "testsite", 5432, "testdb1") + assert(output[0] == 1) + assert(output[1] == "st1") + assert(output[2] == "sn1") + assert(output[3] == 31) + +def test_update_hb_common(monkeypatch): + """ + test update_hb_common() + """ + monkeypatch.setattr(psycopg2, 'connect', monkey_psycopg2.monkey_connect) + monkey_psycopg2.monkey_reset_forces() + output = config_notif.update_hb_common(None, 1234, "st1234", "test", "testpswd", "testsite", 5432, "testdb1") + assert(output == True) + +def monkeypatch_get_cbs_config_False(): + """ + monkeypatch for get_cbs_config() to force it to return False + Required side affect: c_config is set to a json value + """ + print("monkeypatch_get_cbs_config_False()") + miss_htbt_service.mod.trapd_settings.c_config = { "patch": "false" } + return False + +def monkeypatch_get_cbs_config_True(): + """ + monkeypatch for get_cbs_config() to force it to return False + Required side affect: c_config is set to a json value + """ + print("monkeypatch_get_cbs_config_True()") + miss_htbt_service.mod.trapd_settings.c_config = { "patch": "true" } + return True + +def test_fetch_json_file_get_cbs_config_is_true(monkeypatch): + """ + test fetch_json_file() with get_cbs_config() returning True + """ + monkeypatch.setattr(miss_htbt_service.mod.trapd_get_cbs_config, 'get_cbs_config', monkeypatch_get_cbs_config_True) + tmp1 = tempfile.NamedTemporaryFile(mode="w+") + tmp2 = tempfile.NamedTemporaryFile(mode="w+") + output = config_notif.fetch_json_file(download_json = tmp1.name, config_json = tmp2.name) + assert(output == tmp1.name) + with open(tmp1.name, "r") as fp: + j1 = json.load(fp) + print(f"j1={j1}") + assert("patch" in j1 and j1["patch"] == "true") + +def test_fetch_json_file_get_cbs_config_is_false(monkeypatch): + """ + test fetch_json_file() with get_cbs_config() returning False + """ + monkeypatch.setattr(miss_htbt_service.mod.trapd_get_cbs_config, 'get_cbs_config', monkeypatch_get_cbs_config_False) + tmp1 = tempfile.NamedTemporaryFile(mode="w+") + tmp2 = tempfile.NamedTemporaryFile(mode="w+") + output = config_notif.fetch_json_file(download_json = tmp1.name, config_json = tmp2.name) + assert(output == tmp2.name) + +FETCH_JSON_FILE = None + +def monkeypatch_fetch_json_file(): + """ + Monkeypatch for fetch_json_file() to test config_notif_run() + """ + print("monkeypatch_fetch_json_file()") + return FETCH_JSON_FILE + +def monkeypatch_return_False(*args, **kwargs): + """ + Monkeypatch that can be used to force a function to return False + """ + print("monkeypatch_return_False()") + return False + + +def test_config_notif_run_good(monkeypatch): + """ + test config_notif_run() + everything good: "dbname" found (from below JSON info), "hb_common" listed in tables + and hb_common has data. + """ + monkeypatch.setattr(miss_htbt_service.config_notif, 'fetch_json_file', monkeypatch_fetch_json_file) + + tmp = tempfile.NamedTemporaryFile(mode="w+") + global FETCH_JSON_FILE + FETCH_JSON_FILE = tmp.name + + monkeypatch.setattr(psycopg2, 'connect', monkey_psycopg2.monkey_connect) + monkey_psycopg2.monkey_reset_forces() + + monkey_psycopg2.monkey_set_defaults({ + "dbname": { + "from information_schema.tables": [ + [ "hb_common" ] + ], + "from hb_common": [ + [ 1, "sn1", 31, "st1" ], + [ 2, "sn2", 32, "st2" ] + ] + } + }) + + testdata = { + "pg_ipAddress": "10.0.0.99", + "pg_portNum": 65432, + "pg_dbName": "dbname", + "pg_userName": "pguser", + "pg_passwd": "pgpswd", + "CBS_polling_allowed": True, + "CBS_polling_interval": 30, + "SERVICE_NAME": "service_name" + } + json.dump(testdata, tmp) + tmp.flush() + + output = config_notif.config_notif_run() + print(f"output={output}") + assert(output == True) + +def test_config_notif_run_fail1(monkeypatch): + """ + test config_notif_run() + Failure case 1: "dbname" NOT found (from below JSON info), "hb_common" listed in tables + and hb_common has data. + """ + monkeypatch.setattr(miss_htbt_service.config_notif, 'fetch_json_file', monkeypatch_fetch_json_file) + + tmp = tempfile.NamedTemporaryFile(mode="w+") + global FETCH_JSON_FILE + FETCH_JSON_FILE = tmp.name + + monkeypatch.setattr(psycopg2, 'connect', monkey_psycopg2.monkey_connect) + monkey_psycopg2.monkey_reset_forces() + + monkey_psycopg2.monkey_set_defaults({ + "dbnameNOTHERE": { + "from information_schema.tables": [ + [ "hb_common" ] + ], + "from hb_common": [ + [ 1, "sn1", 31, "st1" ], + [ 2, "sn2", 32, "st2" ] + ] + } + }) + + testdata = { + "pg_ipAddress": "10.0.0.99", + "pg_portNum": 65432, + "pg_dbName": "dbname", + "pg_userName": "pguser", + "pg_passwd": "pgpswd", + "CBS_polling_allowed": True, + "CBS_polling_interval": 30, + "SERVICE_NAME": "service_name" + } + json.dump(testdata, tmp) + tmp.flush() + + output = config_notif.config_notif_run() + print(f"output={output}") + assert(output is None) + +def test_config_notif_run_fail2(monkeypatch): + """ + test config_notif_run() + Failure case 2: "dbname" found (from below JSON info), "hb_common" NOT listed in tables + and hb_common has data. + """ + monkeypatch.setattr(miss_htbt_service.config_notif, 'fetch_json_file', monkeypatch_fetch_json_file) + + tmp = tempfile.NamedTemporaryFile(mode="w+") + global FETCH_JSON_FILE + FETCH_JSON_FILE = tmp.name + + monkeypatch.setattr(psycopg2, 'connect', monkey_psycopg2.monkey_connect) + monkey_psycopg2.monkey_reset_forces() + + monkey_psycopg2.monkey_set_defaults({ + "dbname": { + "from information_schema.tables": [ + [ "hb_commonNOTHERE" ] + ], + "from hb_common": [ + [ 1, "sn1", 31, "st1" ], + [ 2, "sn2", 32, "st2" ] + ] + } + }) + + testdata = { + "pg_ipAddress": "10.0.0.99", + "pg_portNum": 65432, + "pg_dbName": "dbname", + "pg_userName": "pguser", + "pg_passwd": "pgpswd", + "CBS_polling_allowed": True, + "CBS_polling_interval": 30, + "SERVICE_NAME": "service_name" + } + json.dump(testdata, tmp) + tmp.flush() + + output = config_notif.config_notif_run() + print(f"output={output}") + assert(output is None) + +def test_config_notif_run_fail3(monkeypatch): + """ + test config_notif_run() + Failure case 3: "dbname" found (from below JSON info), "hb_common" listed in tables + and update_hb_common() fails + """ + monkeypatch.setattr(miss_htbt_service.config_notif, 'fetch_json_file', monkeypatch_fetch_json_file) + monkeypatch.setattr(miss_htbt_service.config_notif, 'update_hb_common', monkeypatch_return_False) + + tmp = tempfile.NamedTemporaryFile(mode="w+") + global FETCH_JSON_FILE + FETCH_JSON_FILE = tmp.name + + monkeypatch.setattr(psycopg2, 'connect', monkey_psycopg2.monkey_connect) + monkey_psycopg2.monkey_reset_forces() + + monkey_psycopg2.monkey_set_defaults({ + "dbname": { + "from information_schema.tables": [ + [ "hb_common" ] + ], + "from hb_common": [ + [ 1, "sn1", 31, "st1" ], + [ 2, "sn2", 32, "st2" ] + ] + } + }) + + testdata = { + "pg_ipAddress": "10.0.0.99", + "pg_portNum": 65432, + "pg_dbName": "dbname", + "pg_userName": "pguser", + "pg_passwd": "pgpswd", + "CBS_polling_allowed": True, + "CBS_polling_interval": 30, + "SERVICE_NAME": "service_name" + } + json.dump(testdata, tmp) + tmp.flush() + + output = config_notif.config_notif_run() + print(f"output={output}") + assert(output == False) diff --git a/tests/test_get_logger.py b/tests/test_get_logger.py new file mode 100644 index 0000000..a643e0f --- /dev/null +++ b/tests/test_get_logger.py @@ -0,0 +1,35 @@ +# ============LICENSE_START======================================================= +# Copyright (c) 2020 AT&T Intellectual Property. All rights reserved. +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END========================================================= + +from miss_htbt_service import get_logger + +import os + +def test_get_logger(): + try: + os.remove("hb_logs.txt") + except: + pass + log = get_logger.get_logger() + log.info("hi there") + +def test_get_logger_node(): + try: + os.remove("hb_logs.txt") + except: + pass + log = get_logger.get_logger("node") + log.info("hi there node") diff --git a/tests/test_htbtworker.py b/tests/test_htbtworker.py new file mode 100644 index 0000000..97e61b4 --- /dev/null +++ b/tests/test_htbtworker.py @@ -0,0 +1,45 @@ +# ============LICENSE_START======================================================= +# Copyright (c) 2020 AT&T Intellectual Property. All rights reserved. +# ================================================================================ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ============LICENSE_END========================================================= + +from miss_htbt_service import htbtworker + +import os, tempfile, json + +def run_test(i): + """ + read_json_file() opens the file CWD/prefix/test{j}.json and returns the json value found there + """ + j = i + 1 + tdir = tempfile.TemporaryDirectory() + prefix = "../../../../../../../../../../../../.." + pdir = f"{prefix}{tdir.name}" + fname = f"{tdir.name}/test{j}.json" + with open(fname, "w") as fp: + json.dump({ "test": i }, fp) + assert(os.path.isfile(f"{tdir.name}/test{j}.json")) + assert(os.path.isfile(f"{pdir}/test{j}.json")) + cfg = htbtworker.read_json_file(i, prefix=pdir) + assert(cfg["test"] == i) + +def test_read_json_file_0(): + run_test(0) + +def test_read_json_file_1(): + run_test(1) + +def test_read_json_file_2(): + run_test(2) + diff --git a/tests/test_trapd_exit.py b/tests/test_trapd_exit.py index 4fa8586..abb6bf4 100644 --- a/tests/test_trapd_exit.py +++ b/tests/test_trapd_exit.py @@ -1,5 +1,5 @@ # ============LICENSE_START======================================================= -# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2020 AT&T Intellectual Property. All rights reserved. # Copyright (c) 2019 Pantheon.tech. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,8 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. import pytest import unittest diff --git a/tests/test_trapd_get_cbs_config.py b/tests/test_trapd_get_cbs_config.py index 92d0dde..8691a89 100644 --- a/tests/test_trapd_get_cbs_config.py +++ b/tests/test_trapd_get_cbs_config.py @@ -1,5 +1,5 @@ # ============LICENSE_START======================================================= -# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2020 AT&T Intellectual Property. All rights reserved. # Copyright (c) 2019 Pantheon.tech. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,8 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. import pytest import unittest diff --git a/tests/test_trapd_http_session.py b/tests/test_trapd_http_session.py index 00ee867..948dd5e 100644 --- a/tests/test_trapd_http_session.py +++ b/tests/test_trapd_http_session.py @@ -1,5 +1,5 @@ # ============LICENSE_START======================================================= -# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2020 AT&T Intellectual Property. All rights reserved. # Copyright (c) 2019 Pantheon.tech. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,8 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. import pytest import unittest diff --git a/tests/test_trapd_runtime_pid.py b/tests/test_trapd_runtime_pid.py index 222ce58..ecb063c 100644 --- a/tests/test_trapd_runtime_pid.py +++ b/tests/test_trapd_runtime_pid.py @@ -1,5 +1,5 @@ # ============LICENSE_START======================================================= -# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2020 AT&T Intellectual Property. All rights reserved. # Copyright (c) 2019 Pantheon.tech. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,8 +14,6 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. import pytest import unittest diff --git a/tests/test_trapd_settings.py b/tests/test_trapd_settings.py index 53b24c8..33fb0ab 100644 --- a/tests/test_trapd_settings.py +++ b/tests/test_trapd_settings.py @@ -1,5 +1,5 @@ # ============LICENSE_START======================================================= -# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2020 AT&T Intellectual Property. All rights reserved. # Copyright (c) 2019 Pantheon.tech. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); @@ -14,15 +14,12 @@ # See the License for the specific language governing permissions and # limitations under the License. # ============LICENSE_END========================================================= -# -# ECOMP is a trademark and service mark of AT&T Intellectual Property. import pytest import unittest from miss_htbt_service.mod import trapd_settings as tds - pid_file="/tmp/test_pid_file" pid_file_dne="/tmp/test_pid_file_NOT" diff --git a/tests/test_trapd_vnf_table.py b/tests/test_trapd_vnf_table.py index f38d4af..4f5cace 100644 --- a/tests/test_trapd_vnf_table.py +++ b/tests/test_trapd_vnf_table.py @@ -1,7 +1,7 @@ # ============LICENSE_START======================================================= # org.onap.dcae # ================================================================================ -# Copyright (c) 2017-2018 AT&T Intellectual Property. All rights reserved. +# Copyright (c) 2017-2020 AT&T Intellectual Property. All rights reserved. # Copyright (c) 2019 Pantheon.tech. All rights reserved. # ================================================================================ # Licensed under the Apache License, Version 2.0 (the "License"); @@ -17,8 +17,6 @@ # limitations under the License. # ============LICENSE_END========================================================= # -# ECOMP is a trademark and service mark of AT&T Intellectual Property. -# ## Author Prakask H (ph553f) """ test_trapd_vnf_table contains test cases related to DB Tables and cbs polling. diff --git a/tox.ini b/tox.ini index fcec640..9d75d5c 100644 --- a/tox.ini +++ b/tox.ini @@ -1,6 +1,6 @@ # content of: tox.ini , put in same dir as setup.py [tox] -envlist = py36 +envlist = py36,py37 [testenv] deps= @@ -16,5 +16,5 @@ commands= mkdir -p /tmp/opt/app/miss_htbt_service/tmp/ mkdir -p /tmp/opt/app/miss_htbt_service/etc/ mkdir -p /tmp/opt/app/miss_htbt_service/data/ - pytest --junitxml xunit-results.xml --cov miss_htbt_service --cov-report xml --cov-report term tests --verbose + pytest --junitxml xunit-results.xml --cov miss_htbt_service --cov-report xml --cov-report term tests --verbose whitelist_externals = mkdir -- cgit 1.2.3-korg