aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTony Hansen <tony@att.com>2023-01-06 13:46:47 +0000
committerGerrit Code Review <gerrit@onap.org>2023-01-06 13:46:47 +0000
commitaefdb1d11b1f36750438487fe1da85911acca4c6 (patch)
tree1654d20484dfa280781a89069d7920e6b617ccc8
parent7e3d845ca700895cc2dec9a5d3282c21860591d8 (diff)
parent341b5bb2347c30344662675936b90b325efe5520 (diff)
Merge "Heartbeat code refactoring"
-rw-r--r--.gitignore5
-rw-r--r--Changelog.md3
-rw-r--r--miss_htbt_service/config.json1
-rw-r--r--miss_htbt_service/db_monitoring.py43
-rw-r--r--miss_htbt_service/htbtworker.py384
-rw-r--r--miss_htbt_service/misshtbtd.py83
-rw-r--r--miss_htbt_service/mod/htbt_exit.py (renamed from miss_htbt_service/mod/trapd_exit.py)6
-rw-r--r--miss_htbt_service/mod/htbt_get_cbs_config.py (renamed from miss_htbt_service/mod/trapd_get_cbs_config.py)10
-rw-r--r--miss_htbt_service/mod/htbt_http_session.py (renamed from miss_htbt_service/mod/trapd_http_session.py)4
-rw-r--r--miss_htbt_service/mod/htbt_io.py (renamed from miss_htbt_service/mod/trapd_io.py)2
-rw-r--r--miss_htbt_service/mod/htbt_runtime_pid.py (renamed from miss_htbt_service/mod/trapd_runtime_pid.py)4
-rw-r--r--miss_htbt_service/mod/htbt_settings.py (renamed from miss_htbt_service/mod/trapd_settings.py)2
-rw-r--r--miss_htbt_service/mod/htbt_vnf_table.py (renamed from miss_htbt_service/mod/trapd_vnf_table.py)18
-rw-r--r--pom.xml4
-rw-r--r--setup.py4
-rw-r--r--tests/hbproperties-test.yaml11
-rw-r--r--tests/test-config.json1
-rw-r--r--tests/test4.json1
-rw-r--r--tests/test_db_monitoring.py75
-rw-r--r--tests/test_get_logger.py6
-rw-r--r--tests/test_htbt_exit.py (renamed from tests/test_trapd_exit.py)8
-rw-r--r--tests/test_htbt_get_cbs_config.py (renamed from tests/test_trapd_get_cbs_config.py)45
-rw-r--r--tests/test_htbt_http_session.py (renamed from tests/test_trapd_http_session.py)6
-rw-r--r--tests/test_htbt_runtime_pid.py (renamed from tests/test_trapd_runtime_pid.py)14
-rw-r--r--tests/test_htbt_settings.py (renamed from tests/test_trapd_settings.py)4
-rw-r--r--tests/test_htbt_vnf_table.py (renamed from tests/test_trapd_vnf_table.py)45
-rw-r--r--tests/test_htbtworker.py163
-rw-r--r--tests/test_misshtbtd.py215
-rw-r--r--tox.ini3
-rw-r--r--version.properties2
30 files changed, 830 insertions, 342 deletions
diff --git a/.gitignore b/.gitignore
index 2f126be..727d9bf 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,8 @@ xunit-results.xml
miss_htbt_service.egg-info
target/
.idea/
+.project
+.pydevproject
+hb_db_monitoring_logs.txt
+hb_misshtbtd_logs.txt
+hb_htbtworker_logs.txt
diff --git a/Changelog.md b/Changelog.md
index 9d98d9c..bd2b18f 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
+## [2.6.0] - 2022/11/17
+- [DCAEGEN2-2953] Code refactoring
+
## [2.5.0] - 2022/10/25
- [DCAEGEN2-2952] Handle exception when MR is unavailable
- [DCAEGEN2-3297] Fix Black tool compatibility issue blocking docker build
diff --git a/miss_htbt_service/config.json b/miss_htbt_service/config.json
new file mode 100644
index 0000000..e853f6a
--- /dev/null
+++ b/miss_htbt_service/config.json
@@ -0,0 +1 @@
+{"pg_ipAddress": "10.0.4.1", "pg_userName": "postgres", "pg_dbName": "postgres", "streams_subscribes": {"ves-heartbeat": {"type": "message_router", "dmaap_info": {"topic_url": "http://10.12.5.252:3904/events/unauthenticated.SEC_HEARTBEAT_INPUT"}}}, "consumerID": "1", "CBS_polling_interval": "300", "pg_passwd": "postgres", "streams_publishes": {"dcae_cl_out": {"type": "message_router", "dmaap_info": {"topic_url": "http://10.12.5.252:3904/events/unauthenticated.DCAE_CL_OUTPUT"}}}, "pg_portNum": "5432", "CBS_polling_allowed": "True", "groupID": "groupID", "heartbeat_config": "{\"vnfs\": [{\"eventName\": \"Heartbeat_vDNS\",\"heartbeatcountmissed\": 3,\"heartbeatinterval\": 60,\"closedLoopControlName\": \"ControlLoopEvent1\",\t\"policyVersion\": \"1.0.0.5\",\t\"policyName\":\"vFireWall\",\"policyScope\": \"resource=sampleResource,type=sampletype,CLName=sampleCLName\",\"target_type\": \"VNF\",\t\"target\": \"genVnfName\",\t\"version\": \"1.0\"}, {\"eventName\": \"Heartbeat_vFW\",\"heartbeatcountmissed\": 3,\t\"heartbeatinterval\": 60,\"closedLoopControlName\": \"ControlLoopEvent1\",\"policyVersion\": \"1.0.0.5\",\"policyName\": \"vFireWall\",\"policyScope\": \"resource=sampleResource,type=sampletype,CLName=sampleCLName\",\t\"target_type\":\"VNF\",\t\"target\": \"genVnfName\",\t\"version\": \"1.0\"}, {\"eventName\": \"Heartbeat_xx\",\"heartbeatcountmissed\": 3,\t\"heartbeatinterval\": 60,\"closedLoopControlName\": \"ControlLoopEvent1\",\"policyVersion\": \"1.0.0.5\",\"policyName\": \"vFireWall\",\t\"policyScope\": \"resource=sampleResource,type=sampletype,CLName=sampleCLName\",\"target_type\": \"VNF\",\"target\": \"genVnfName\",\"version\": \"1.0\"}]}"}
diff --git a/miss_htbt_service/db_monitoring.py b/miss_htbt_service/db_monitoring.py
index eac8a91..cbd8f24 100644
--- a/miss_htbt_service/db_monitoring.py
+++ b/miss_htbt_service/db_monitoring.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
# ============LICENSE_START=======================================================
-# Copyright (c) 2018-2022 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2018-2023 AT&T Intellectual Property. All rights reserved.
# Copyright (c) 2019 Pantheon.tech. All rights reserved.
# Copyright (c) 2020 Deutsche Telekom. All rights reserved.
# Copyright (c) 2021 Fujitsu Ltd.
@@ -30,6 +30,7 @@ import os
import socket
import time
import requests
+import psycopg2
import htbtworker as pm
import misshtbtd as db
import get_logger
@@ -159,10 +160,6 @@ def db_monitoring(current_pid, json_file, user_name, password, ip_address, port_
while True:
time.sleep(20)
- env_pytest = os.getenv("pytest", "")
- if env_pytest == "test":
- break
-
try:
with open(json_file, "r") as outfile:
cfg = json.load(outfile)
@@ -177,9 +174,9 @@ def db_monitoring(current_pid, json_file, user_name, password, ip_address, port_
)
source_name = socket.gethostname()
source_name = source_name + "-" + str(os.getenv("SERVICE_NAME", ""))
- connection_db = pm.postgres_db_open(user_name, password, ip_address, port_num, db_name)
+ connection_db = pm.postgres_db_open()
cur = connection_db.cursor()
- if int(current_pid) == int(hbc_pid) and source_name == hbc_src_name and hbc_state == "RUNNING":
+ if int(current_pid) == int(hbc_pid) and source_name == hbc_src_name and hbc_state == "RUNNING": # pragma: no cover
_logger.info("DBM: Active DB Monitoring Instance")
cur.execute("SELECT event_name FROM vnf_table_1")
vnf_list = [item[0] for item in cur.fetchall()]
@@ -224,7 +221,7 @@ def db_monitoring(current_pid, json_file, user_name, password, ip_address, port_
epoc_time_sec = row[0][0]
src_name = row[0][1]
cl_flag = row[0][2]
- if (epoc_time - epoc_time_sec) > comparision_time and cl_flag == 0:
+ if (epoc_time - epoc_time_sec) > comparision_time and cl_flag == 0: # pragma: no cover
sendControlLoopEvent(
"ONSET",
pol_url,
@@ -244,7 +241,7 @@ def db_monitoring(current_pid, json_file, user_name, password, ip_address, port_
(cl_flag, event_name, (source_name_key + 1)),
)
connection_db.commit()
- elif (epoc_time - epoc_time_sec) < comparision_time and cl_flag == 1:
+ elif (epoc_time - epoc_time_sec) < comparision_time and cl_flag == 1: # pragma: no cover
sendControlLoopEvent(
"ABATED",
pol_url,
@@ -277,17 +274,21 @@ def db_monitoring(current_pid, json_file, user_name, password, ip_address, port_
"""
else: # pragma: no cover
msg = "DBM:Inactive instance or hb_common state is not RUNNING"
- _logger.info(msg)
- pm.commit_and_close_db(connection_db)
+ _logger.info(msg)
+ try:
+ connection_db.commit() # <--- makes sure the change is shown in the database
+ connection_db.close()
+ return True
+ except psycopg2.DatabaseError as e:
+ msg = "COMMON:Error %s" % e
+ _logger.error(msg)
+ return False
cur.close()
break
-
-if __name__ == "__main__":
+def db_monitoring_wrapper (current_pid, jsfile, number_of_iterations=-1):
get_logger.configure_logger("db_monitoring")
_logger.info("DBM: DBM Process started")
- current_pid = sys.argv[1]
- jsfile = sys.argv[2]
(
ip_address,
port_num,
@@ -299,8 +300,12 @@ if __name__ == "__main__":
) = db.read_hb_properties(jsfile)
msg = "DBM:Parent process ID and json file name", current_pid, jsfile
_logger.info(msg)
- while True:
+ while number_of_iterations != 0:
+ number_of_iterations -= 1
db_monitoring(current_pid, jsfile, user_name, password, ip_address, port_num, db_name)
- env_pytest = os.getenv("pytest", "")
- if env_pytest == "test":
- break
+
+
+if __name__ == "__main__":
+ current_pid = sys.argv[1]
+ jsfile = sys.argv[2]
+ db_monitoring_wrapper (current_pid,jsfile)
diff --git a/miss_htbt_service/htbtworker.py b/miss_htbt_service/htbtworker.py
index 6765266..3328973 100644
--- a/miss_htbt_service/htbtworker.py
+++ b/miss_htbt_service/htbtworker.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
# ============LICENSE_START=======================================================
-# Copyright (c) 2018-2022 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2018-2023 AT&T Intellectual Property. All rights reserved.
# Copyright (c) 2019 Pantheon.tech. All rights reserved.
# Copyright (c) 2020 Deutsche Telekom. All rights reserved.
# Copyright (c) 2021 Fujitsu Ltd.
@@ -17,11 +17,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# ============LICENSE_END=========================================================
-#
-# Author Prakash Hosangady(ph553f@att.com)
-# Simple Microservice
-# Tracks Heartbeat messages on input topic in DMaaP
-# and poppulate the information in postgres DB
+
import logging
import psycopg2
@@ -31,55 +27,45 @@ import os.path as path
import json
import sys
import time
+
import misshtbtd as db
import get_logger
_logger = logging.getLogger(__name__)
+configjsonfile = "../etc/config.json"
-def read_json_file(i, prefix="../../tests"):
- if i == 0:
- 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__, f"{prefix}/test2.json")), "r") as outfile:
- cfg = json.load(outfile)
- elif i == 2:
- 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(cfgjsonfile, number_of_iterations=-1):
+ """
+ Function to poll events from MR continuously
+ and determine if matching configuration to be
+ tracked for missed HB function
+ """
+
global mr_url
- i = 0
+ global configjsonfile
+ configjsonfile = cfgjsonfile
sleep_duration = 20
- while True:
+ reconfig_Flag = False
+ while number_of_iterations != 0:
+ number_of_iterations -= 1
time.sleep(sleep_duration)
- with open(jsfile, "r") as outfile:
+ print ("*** CFG json file info " + configjsonfile)
+ with open(configjsonfile, "r") as outfile:
cfg = json.load(outfile)
+
+ print ("*** CFG info " + str(cfg))
mr_url = str(cfg["streams_subscribes"]["ves-heartbeat"]["dmaap_info"]["topic_url"])
+
+ username = str(cfg["pg_userName"])
+ password = str(cfg["pg_passwd"])
+ db_host = str(cfg["pg_ipAddress"])
+ db_port = cfg["pg_portNum"]
+ database_name = str(cfg["pg_dbName"])
+
+ reconfig_Flag = check_process_reconfiguration (username, password, db_host, db_port, database_name)
+ eventname_list = get_eventnamelist ()
- while True:
- hbc_pid, hbc_state, hbc_src_name, hbc_time = db.read_hb_common(
- user_name, password, ip_address, port_num, db_name
- )
- if hbc_state == "RECONFIGURATION":
- _logger.info("HBT:Waiting for hb_common state to become RUNNING")
- time.sleep(10)
- else:
- break
-
- if os.getenv("pytest", "") == "test":
- eventname_list = ["Heartbeat_vDNS", "Heartbeat_vFW", "Heartbeat_xx"]
- connection_db = 0
- else:
- connection_db = postgres_db_open(user_name, password, ip_address, port_num, db_name)
- cur = connection_db.cursor()
- cur.execute("SELECT event_name FROM vnf_table_1")
- eventname_list = [item[0] for item in cur.fetchall()]
- msg = "\n\nHBT:eventnameList values ", eventname_list
- _logger.info(msg)
if "groupID" not in os.environ or "consumerID" not in os.environ:
get_url = mr_url + "/DefaultGroup/1?timeout=15000"
else:
@@ -87,105 +73,60 @@ def process_msg(jsfile, user_name, password, ip_address, port_num, db_name):
msg = "HBT:Getting :" + get_url
_logger.info(msg)
- if os.getenv("pytest", "") == "test":
- jsonobj = read_json_file(i)
- jobj = []
- jobj.append(jsonobj)
- i = i + 1
- msg = "HBT:newly received test message", jobj
- _logger.info(msg)
- if i >= 3:
- i = 0
- break
- else:
+ try:
+ res = requests.get(get_url)
+ except Exception as e:
+ # message-router may be down temporarily. continue polling loop to try again
+ _logger.error("HBT: Failed to fetch messages from DMaaP. get_url=%s", get_url, exc_info=e)
+ time.sleep(1)
+ continue
+ _logger.info("HBT: %s", res.text)
+ input_string = res.text
+ # If mrstatus in message body indicates some information, not json msg.
+ if "mrstatus" in input_string:
+ continue
+ jlist = input_string.split("\n")
+ print (jlist)
+ # Process the DMaaP input message retrieved
+ error = False
+ jobj = []
+ for line in jlist:
try:
- res = requests.get(get_url)
- except Exception as e:
- # message-router may be down temporarily. continue polling loop to try again
- _logger.error("HBT: Failed to fetch messages from DMaaP. get_url=%s", get_url, exc_info=e)
- time.sleep(1)
- continue
- _logger.info("HBT: %s", res.text)
- input_string = res.text
- # If mrstatus in message body indicates some information, not json msg.
- if "mrstatus" in input_string:
- continue
- jlist = input_string.split("\n")
- # Process the DMaaP input message retreived
- error = False
- for line in jlist:
- try:
- jobj = json.loads(line)
- except ValueError:
- msg = "HBT:Decoding JSON has failed"
- _logger.error(msg)
- error = True
- break
- if error:
- continue
- if len(jobj) == 0:
- continue
- for item in jobj:
- try:
- if os.getenv("pytest", "") == "test":
- jitem = jsonobj
- else:
- jitem = json.loads(item)
- srcname = jitem["event"]["commonEventHeader"]["sourceName"]
- lastepo = jitem["event"]["commonEventHeader"]["lastEpochMicrosec"]
- # if lastEpochMicrosec looks like microsec, align it with millisec
- if lastepo > 1000000000000000:
- lastepo = int(lastepo / 1000)
- seqnum = jitem["event"]["commonEventHeader"]["sequence"]
- event_name = jitem["event"]["commonEventHeader"]["eventName"]
- except Exception as err:
- msg = "HBT message process error - ", err
+ jobj = json.loads(line)
+ except ValueError:
+ msg = "HBT:Decoding JSON has failed"
_logger.error(msg)
- continue
+ error = True
+ break
+ if error:
+ continue
+ if len(jobj) == 0:
+ continue
+
+ _logger.info("HBT jobj Array : %s", jobj)
+ for item in jobj:
+ srcname, lastepo, seqnum, event_name = parse_event(item)
msg = "HBT:Newly received HB event values ::", event_name, lastepo, srcname
_logger.info(msg)
- if db_table_creation_check(connection_db, "vnf_table_2") is False:
- msg = "HBT:Creating vnf_table_2"
- _logger.info(msg)
- cur.execute(
- """
- CREATE TABLE vnf_table_2 (
- EVENT_NAME varchar,
- SOURCE_NAME_KEY integer,
- PRIMARY KEY(EVENT_NAME, SOURCE_NAME_KEY),
- LAST_EPO_TIME BIGINT,
- SOURCE_NAME varchar,
- CL_FLAG integer
- )"""
- )
- else:
- msg = "HBT:vnf_table_2 is already there"
- _logger.info(msg)
+
+ check_and_create_vnf2_table ()
+
if event_name in eventname_list: # pragma: no cover
- if os.getenv("pytest", "") == "test":
- break
- cur.execute("SELECT source_name_count FROM vnf_table_1 WHERE event_name = %s", (event_name,))
+ cur = sql_executor("SELECT source_name_count FROM vnf_table_1 WHERE event_name = %s", event_name)
row = cur.fetchone()
source_name_count = row[0]
source_name_key = source_name_count + 1
cl_flag = 0
if source_name_count == 0: # pragma: no cover
_logger.info("HBT: Insert entry into vnf_table_2, source_name='%s'", srcname)
- cur.execute(
- "INSERT INTO vnf_table_2 VALUES(%s,%s,%s,%s,%s)",
- (event_name, source_name_key, lastepo, srcname, cl_flag),
- )
- cur.execute(
- "UPDATE vnf_table_1 SET SOURCE_NAME_COUNT = %s where EVENT_NAME = %s",
- (source_name_key, event_name),
- )
- else: # pragma: no cover
+ new_vnf_entry(event_name, source_name_key, lastepo, srcname, cl_flag)
+ else: # pragma: no cover
msg = "HBT:event name, source_name & source_name_count are", event_name, srcname, source_name_count
_logger.info(msg)
for source_name_key in range(source_name_count):
- cur.execute(
+ cur = sql_executor(
"SELECT source_name FROM vnf_table_2 WHERE event_name = %s AND " "source_name_key = %s",
- (event_name, (source_name_key + 1)),
+ event_name, (source_name_key + 1)
)
row = cur.fetchall()
if len(row) == 0:
@@ -194,10 +135,10 @@ def process_msg(jsfile, user_name, password, ip_address, port_num, db_name):
if db_srcname == srcname:
msg = "HBT: Update vnf_table_2 : ", source_name_key, row
_logger.info(msg)
- cur.execute(
+ sql_executor(
"UPDATE vnf_table_2 SET LAST_EPO_TIME = %s, SOURCE_NAME = %s "
"WHERE EVENT_NAME = %s AND SOURCE_NAME_KEY = %s",
- (lastepo, srcname, event_name, (source_name_key + 1)),
+ lastepo, srcname, event_name, (source_name_key + 1)
)
source_name_key = source_name_count
break
@@ -208,63 +149,152 @@ def process_msg(jsfile, user_name, password, ip_address, port_num, db_name):
if source_name_count == (source_name_key + 1):
source_name_key = source_name_count + 1
_logger.info("HBT: Insert entry into vnf_table_2, source_name='%s'", srcname)
- cur.execute(
- "INSERT INTO vnf_table_2 VALUES(%s,%s,%s,%s,%s)",
- (event_name, source_name_key, lastepo, srcname, cl_flag),
- )
- cur.execute(
- "UPDATE vnf_table_1 SET SOURCE_NAME_COUNT = %s WHERE EVENT_NAME = %s",
- (source_name_key, event_name),
- )
+ new_vnf_entry(event_name, source_name_key, lastepo, srcname, cl_flag)
else:
- _logger.info("HBT:eventName is not being monitored, Igonoring JSON message")
- commit_db(connection_db)
- commit_and_close_db(connection_db)
- if os.getenv("pytest", "") != "test":
- cur.close()
+ _logger.info("HBT:eventName is not being monitored, Ignoring JSON message")
+ msg = "HBT: Looping to check for new events from DMAAP"
+ print ("HBT: Looping to check for new events from DMAAP")
+ _logger.info(msg)
+def new_vnf_entry (event_name, source_name_key, lastepo, srcname, cl_flag):
+ """
+ Wrapper function to update event to tracking tables
+ """
+
+ sql_executor(
+ "INSERT INTO vnf_table_2 VALUES(%s,%s,%s,%s,%s)",
+ event_name, source_name_key, lastepo, srcname, cl_flag
+ )
+ sql_executor(
+ "UPDATE vnf_table_1 SET SOURCE_NAME_COUNT = %s WHERE EVENT_NAME = %s",
+ source_name_key, event_name
+ )
-def postgres_db_open(username, password, host, port, database_name):
- if os.getenv("pytest", "") == "test":
- return True
- connection = psycopg2.connect(database=database_name, user=username, password=password, host=host, port=port)
- return connection
+def parse_event (jsonstring):
+ """
+ Function to parse incoming event as json object
+ and parse out required attributes
+ """
+ _logger.info("HBT jsonstring: %s", jsonstring)
+ #convert string to object
+ jitem = json.loads(jsonstring)
+
+ try:
+ srcname = jitem["event"]["commonEventHeader"]["sourceName"]
+ lastepo = jitem["event"]["commonEventHeader"]["lastEpochMicrosec"]
+ # if lastEpochMicrosec looks like microsec, align it with millisec
+ if lastepo > 1000000000000000:
+ lastepo = int(lastepo / 1000)
+ seqnum = jitem["event"]["commonEventHeader"]["sequence"]
+ event_name = jitem["event"]["commonEventHeader"]["eventName"]
+ msg = "HBT:Newly received HB event values ::", event_name, lastepo, srcname
+ _logger.info(msg)
+ return (srcname,lastepo,seqnum,event_name)
+ except Exception as err:
+ msg = "HBT message process error - ", err
+ _logger.error(msg)
+def get_eventnamelist ():
+ """
+ Function to fetch active monitored eventname list
+ """
+ cur = sql_executor("SELECT event_name FROM vnf_table_1",)
+ eventname_list = [item[0] for item in cur.fetchall()]
+ msg = "\n\nHBT:eventnameList values ", eventname_list
+ _logger.info(msg)
+ return eventname_list
-def db_table_creation_check(connection_db, table_name):
- if os.getenv("pytest", "") == "test":
- return True
+def check_and_create_vnf2_table ():
+ """
+ Check and create vnf_table_2 used for tracking HB entries
+ """
try:
- cur = connection_db.cursor()
- cur.execute("SELECT * FROM information_schema.tables WHERE table_name = %s", (table_name,))
+ table_exist = False
+ cur = sql_executor("SELECT * FROM information_schema.tables WHERE table_name = %s", "vnf_table_2")
database_names = cur.fetchone()
if database_names is not None:
- if table_name in database_names:
- return True
+ if "vnf_table_2" in database_names:
+ table_exist = True
+
+ if table_exist == False:
+ msg = "HBT:Creating vnf_table_2"
+ _logger.info(msg)
+ sql_executor(
+ """
+ CREATE TABLE vnf_table_2 (
+ EVENT_NAME varchar,
+ SOURCE_NAME_KEY integer,
+ PRIMARY KEY(EVENT_NAME, SOURCE_NAME_KEY),
+ LAST_EPO_TIME BIGINT,
+ SOURCE_NAME varchar,
+ CL_FLAG integer
+ )"""
+ ,)
else:
- return False
- except psycopg2.DatabaseError as e:
- msg = "COMMON:Error %s" % e
- _logger.error(msg)
- finally:
- cur.close()
-
-
-def commit_db(connection_db):
- if os.getenv("pytest", "") == "test":
- return True
- try:
- connection_db.commit() # <--- makes sure the change is shown in the database
+ msg = "HBT:vnf_table_2 is already there"
+ _logger.info(msg)
return True
except psycopg2.DatabaseError as e:
msg = "COMMON:Error %s" % e
_logger.error(msg)
return False
+
+def check_process_reconfiguration(username, password, host, port, database_name):
+ """
+ Verify if DB configuration in progress
+ """
+ while True:
+ hbc_pid, hbc_state, hbc_src_name, hbc_time = db.read_hb_common(
+ username, password, host, port, database_name
+ )
+ if hbc_state == "RECONFIGURATION":
+ _logger.info("HBT: RECONFIGURATION in-progress. Waiting for hb_common state to become RUNNING")
+ time.sleep(10)
+ else:
+ _logger.info("HBT: hb_common state is RUNNING")
+ break
+ return False
+
+def postgres_db_open():
+ """
+ Wrapper function for returning DB connection object
+ """
+
+ global configjsonfile
+
+ (
+ ip_address,
+ port_num,
+ user_name,
+ password,
+ db_name,
+ cbs_polling_required,
+ cbs_polling_interval,
+ ) = db.read_hb_properties(configjsonfile)
+ connection = psycopg2.connect(database=db_name, user=user_name, password=password, host=ip_address, port=port_num)
+ return connection
+
+
+def sql_executor (query, *values):
+ """
+ wrapper method for DB operation
+ """
+ _logger.info("HBT query: %s values: %s", query, values)
+
+ connection_db = postgres_db_open()
+ cur = connection_db.cursor()
+ cur.execute(query, values)
+ update_commands = ["CREATE", "INSERT", "UPDATE"]
+ if any (x in query for x in update_commands):
+ try:
+ connection_db.commit() # <--- makes sure the change is shown in the database
+ except psycopg2.DatabaseError as e:
+ msg = "COMMON:Error %s" % e
+ _logger.error(msg)
+ return cur
def commit_and_close_db(connection_db):
- if os.getenv("pytest", "") == "test":
- return True
try:
connection_db.commit() # <--- makes sure the change is shown in the database
connection_db.close()
@@ -277,18 +307,10 @@ def commit_and_close_db(connection_db):
if __name__ == "__main__":
get_logger.configure_logger("htbtworker")
- jsfile = sys.argv[1]
+ configjsonfile = sys.argv[1]
msg = "HBT:HeartBeat thread Created"
_logger.info("HBT:HeartBeat thread Created")
- msg = "HBT:The config file name passed is -%s", jsfile
+ msg = "HBT:The config file name passed is -%s", configjsonfile
_logger.info(msg)
- (
- ip_address,
- port_num,
- user_name,
- password,
- db_name,
- cbs_polling_required,
- cbs_polling_interval,
- ) = db.read_hb_properties(jsfile)
- process_msg(jsfile, user_name, password, ip_address, port_num, db_name)
+ process_msg(configjsonfile)
+
diff --git a/miss_htbt_service/misshtbtd.py b/miss_htbt_service/misshtbtd.py
index fd1a09c..23d4835 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-2022 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2017-2023 AT&T Intellectual Property. All rights reserved.
# Copyright (c) 2019 Pantheon.tech. All rights reserved.
# Copyright (c) 2020 Deutsche Telekom. All rights reserved.
# Copyright (c) 2021 Samsung Electronics. All rights reserved.
@@ -40,14 +40,15 @@ import yaml
import socket
import os.path as path
import tempfile
+import psycopg2
from pathlib import Path
import check_health
import htbtworker as heartbeat
import get_logger
import cbs_polling
-from mod import trapd_settings as tds
-from mod.trapd_get_cbs_config import get_cbs_config
+from mod import htbt_settings as tds
+from mod.htbt_get_cbs_config import get_cbs_config
hb_properties_file = path.abspath(path.join(__file__, "../config/hbproperties.yaml"))
_logger = logging.getLogger(__name__)
@@ -83,14 +84,7 @@ 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):
- env_pytest = os.getenv("pytest", "")
- if env_pytest == "test":
- hbc_pid = 10
- hbc_src_name = "srvc_name"
- hbc_time = 1584595881
- hbc_state = "RUNNING"
- return hbc_pid, hbc_state, hbc_src_name, hbc_time
- connection_db = heartbeat.postgres_db_open(user_name, password, ip_address, port_num, db_name)
+ connection_db = heartbeat.postgres_db_open()
cur = connection_db.cursor()
cur.execute("SELECT process_id, source_name, last_accessed_time, current_state FROM hb_common")
rows = cur.fetchall()
@@ -98,7 +92,6 @@ def read_hb_common(user_name, password, ip_address, port_num, db_name):
hbc_src_name = rows[0][1]
hbc_time = rows[0][2]
hbc_state = rows[0][3]
- heartbeat.commit_and_close_db(connection_db)
cur.close()
return hbc_pid, hbc_state, hbc_src_name, hbc_time
@@ -109,9 +102,9 @@ def create_update_hb_common(update_flg, process_id, state, user_name, password,
source_name = source_name + "-" + os.getenv("SERVICE_NAME", "")
env_pytest = os.getenv("pytest", "")
if env_pytest != "test":
- connection_db = heartbeat.postgres_db_open(user_name, password, ip_address, port_num, db_name)
+ connection_db = heartbeat.postgres_db_open()
cur = connection_db.cursor()
- if heartbeat.db_table_creation_check(connection_db, "hb_common") is False:
+ if db_table_creation_check(connection_db, "hb_common") is False:
cur.execute(
"""
CREATE TABLE hb_common (
@@ -133,18 +126,33 @@ def create_update_hb_common(update_flg, process_id, state, user_name, password,
heartbeat.commit_and_close_db(connection_db)
cur.close()
-
+def db_table_creation_check(connection_db, table_name):
+ cur = connection_db.cursor()
+ try:
+ cur.execute("SELECT * FROM information_schema.tables WHERE table_name = %s", (table_name,))
+ database_names = cur.fetchone()
+ if database_names is not None:
+ if table_name in database_names:
+ return True
+ else:
+ return False
+ except psycopg2.DatabaseError as e:
+ msg = "COMMON:Error %s" % e
+ _logger.error(msg)
+ finally:
+ cur.close()
+
def create_update_vnf_table_1(jsfile, update_db, connection_db):
with open(jsfile, "r") as outfile:
cfg = json.load(outfile)
hbcfg = cfg["heartbeat_config"]
jhbcfg = json.loads(hbcfg)
+ cur = connection_db.cursor()
env_pytest = os.getenv("pytest", "")
if env_pytest == "test":
vnf_list = ["Heartbeat_vDNS", "Heartbeat_vFW", "Heartbeat_xx"]
else:
- cur = connection_db.cursor()
- if heartbeat.db_table_creation_check(connection_db, "vnf_table_1") is False:
+ if db_table_creation_check(connection_db, "vnf_table_1") is False:
cur.execute(
"""
CREATE TABLE vnf_table_1 (
@@ -232,14 +240,14 @@ def create_update_vnf_table_1(jsfile, update_db, connection_db):
def hb_worker_process(config_file_path):
subprocess.call([ABSOLUTE_PATH1, config_file_path])
sys.stdout.flush()
- _logger.info("MSHBT:Creaated Heartbeat worker process")
+ _logger.info("MSHBT:Created Heartbeat worker process")
return
def db_monitoring_process(current_pid, jsfile):
subprocess.call([ABSOLUTE_PATH2, str(current_pid), jsfile])
sys.stdout.flush()
- _logger.info("MSHBT:Creaated DB Monitoring process")
+ _logger.info("MSHBT:Created DB Monitoring process")
return
@@ -335,10 +343,10 @@ def create_update_db(update_db, jsfile, ip_address, port_num, user_name, passwor
create_database(update_db, jsfile, ip_address, port_num, user_name, password, db_name)
msg = "MSHBT: DB parameters -", ip_address, port_num, user_name, password, db_name
_logger.info(msg)
- connection_db = heartbeat.postgres_db_open(user_name, password, ip_address, port_num, db_name)
+ connection_db = heartbeat.postgres_db_open()
cur = connection_db.cursor()
if update_db == 0:
- if heartbeat.db_table_creation_check(connection_db, "vnf_table_1") is False:
+ if db_table_creation_check(connection_db, "vnf_table_1") is False:
create_update_vnf_table_1(jsfile, update_db, connection_db)
else:
create_update_vnf_table_1(jsfile, update_db, connection_db)
@@ -367,6 +375,7 @@ def create_process(job_list, jsfile, pid_current):
return job_list
+
def main():
get_logger.configure_logger("misshtbtd")
pid_current = os.getpid()
@@ -412,7 +421,7 @@ def main():
_logger.info("MSHBD:Current process id is %d", pid_current)
_logger.info("MSHBD:Now be in a continuous loop")
i = 0
- while True:
+ while True: # pragma: no cover
hbc_pid, hbc_state, hbc_src_name, hbc_time = read_hb_common(
user_name, password, ip_address, port_num, db_name
)
@@ -432,16 +441,6 @@ def main():
_logger.info(msg)
source_name = socket.gethostname()
source_name = source_name + "-" + str(os.getenv("SERVICE_NAME", ""))
- env_pytest = os.getenv("pytest", "")
- if env_pytest == "test":
- if i == 2:
- hbc_pid = pid_current
- source_name = hbc_src_name
- hbc_state = "RECONFIGURATION"
- elif i > 3:
- hbc_pid = pid_current
- source_name = hbc_src_name
- hbc_state = "RUNNING"
if time_difference < 60:
if (int(hbc_pid) == int(pid_current)) and (source_name == hbc_src_name):
msg = "MSHBD:config status is", hbc_state
@@ -491,7 +490,7 @@ def main():
_logger.info("MSHBD:HB and DBM thread are waiting to become ACTIVE")
else:
jsfile = fetch_json_file()
- msg = "MSHBD: Creating HB and DBM threads. The param pssed %d and %s", jsfile, pid_current
+ msg = "MSHBD: Creating HB and DBM threads. The param passed %d and %s", jsfile, pid_current
_logger.info(msg)
job_list = create_process(job_list, jsfile, pid_current)
hbc_pid, hbc_state, hbc_src_name, hbc_time = read_hb_common(
@@ -504,24 +503,6 @@ def main():
else:
_logger.error("MSHBD:ERROR - Active instance is not updating hb_common in 60 sec - ERROR")
time.sleep(25)
- if os.getenv("pytest", "") == "test":
- i = i + 1
- if i > 5:
- _logger.info("Terminating main process for pytest")
- cbs_polling_proc.terminate()
- time.sleep(1)
- cbs_polling_proc.join()
- if len(job_list) > 0:
- job_list[0].terminate()
- time.sleep(1)
- job_list[0].join()
- job_list.remove(job_list[0])
- if len(job_list) > 0:
- job_list[0].terminate()
- time.sleep(1)
- job_list[0].join()
- job_list.remove(job_list[0])
- break
except Exception as e:
msg = "MSHBD:Exception as %s" % (str(traceback.format_exc()))
diff --git a/miss_htbt_service/mod/trapd_exit.py b/miss_htbt_service/mod/htbt_exit.py
index 7791b31..3779e15 100644
--- a/miss_htbt_service/mod/trapd_exit.py
+++ b/miss_htbt_service/mod/htbt_exit.py
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (c) 2017-2022 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2017-2023 AT&T Intellectual Property. All rights reserved.
# Copyright (c) 2019 Pantheon.tech. All rights reserved.
# Copyright (c) 2020 Deutsche Telekom. All rights reserved.
# ================================================================================
@@ -17,7 +17,7 @@
# ============LICENSE_END=========================================================
"""
-trapc_exit_snmptrapd is responsible for removing any existing runtime PID
+htbt_exit is responsible for removing any existing runtime PID
file, and exiting with the provided (param 1) exit code
"""
@@ -25,7 +25,7 @@ __docformat__ = "restructuredtext"
import sys
import os
-from mod.trapd_runtime_pid import rm_pid
+from mod.htbt_runtime_pid import rm_pid
prog_name = os.path.basename(__file__)
diff --git a/miss_htbt_service/mod/trapd_get_cbs_config.py b/miss_htbt_service/mod/htbt_get_cbs_config.py
index 034b32b..613b46f 100644
--- a/miss_htbt_service/mod/trapd_get_cbs_config.py
+++ b/miss_htbt_service/mod/htbt_get_cbs_config.py
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (c) 2018-2022 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2018-2023 AT&T Intellectual Property. All rights reserved.
# Copyright (c) 2019 Pantheon.tech. All rights reserved.
# Copyright (c) 2020 Deutsche Telekom. All rights reserved.
# Copyright (c) 2021 Samsung Electronics. All rights reserved.
@@ -28,15 +28,15 @@ __docformat__ = "restructuredtext"
import json
import os
from onap_dcae_cbs_docker_client.client import get_config
-from mod import trapd_settings as tds
-from mod.trapd_exit import cleanup, cleanup_and_exit
-from mod.trapd_io import stdout_logger
+from mod import htbt_settings as tds
+from mod.htbt_exit import cleanup, cleanup_and_exit
+from mod.htbt_io import stdout_logger
prog_name = os.path.basename(__file__)
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
-# function: trapd_get_config_sim
+# function: htbt_get_config_sim
# # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
diff --git a/miss_htbt_service/mod/trapd_http_session.py b/miss_htbt_service/mod/htbt_http_session.py
index 17eb302..f0a409a 100644
--- a/miss_htbt_service/mod/trapd_http_session.py
+++ b/miss_htbt_service/mod/htbt_http_session.py
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (c) 2017-2022 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2017-2023 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,7 +15,7 @@
# ============LICENSE_END=========================================================
"""
-trapd_http_session establishes an http session for future use in publishing
+htbt_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/htbt_io.py
index 26445fc..3f16a7b 100644
--- a/miss_htbt_service/mod/trapd_io.py
+++ b/miss_htbt_service/mod/htbt_io.py
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================)
-# Copyright (c) 2018-2022 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2018-2023 AT&T Intellectual Property. All rights reserved.
# Copyright (c) 2019 Pantheon.tech. All rights reserved.
# Copyright (c) 2020 Deutsche Telekom. All rights reserved.
# ================================================================================
diff --git a/miss_htbt_service/mod/trapd_runtime_pid.py b/miss_htbt_service/mod/htbt_runtime_pid.py
index 823d29f..d086ed2 100644
--- a/miss_htbt_service/mod/trapd_runtime_pid.py
+++ b/miss_htbt_service/mod/htbt_runtime_pid.py
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (c) 2017-2022 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2017-2023 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,7 +15,7 @@
# ============LICENSE_END=========================================================
"""
-trapd_runtime_pid maintains a 'PID file' (file that contains the
+htbt_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/htbt_settings.py
index 0f6a9a1..b5b58cc 100644
--- a/miss_htbt_service/mod/trapd_settings.py
+++ b/miss_htbt_service/mod/htbt_settings.py
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================)
-# Copyright (c) 2018-2022 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2018-2023 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.
diff --git a/miss_htbt_service/mod/trapd_vnf_table.py b/miss_htbt_service/mod/htbt_vnf_table.py
index f9fecbb..3396e80 100644
--- a/miss_htbt_service/mod/trapd_vnf_table.py
+++ b/miss_htbt_service/mod/htbt_vnf_table.py
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (c) 2017-2022 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2017-2023 AT&T Intellectual Property. All rights reserved.
# Copyright (c) 2019 Pantheon.tech. All rights reserved.
# Copyright (c) 2020 Deutsche Telekom. All rights reserved.
# Copyright (c) 2021 Samsung Electronics. All rights reserved.
@@ -21,7 +21,7 @@
# Author Kiran Mandal (km386e)
"""
-trapd_vnf_table verifies the successful creation of DB Tables.
+htbt_vnf_table verifies the successful creation of DB Tables.
"""
import logging
import os
@@ -57,9 +57,9 @@ def hb_properties():
def verify_DB_creation_1(user_name, password, ip_address, port_num, db_name):
- connection_db = pm.postgres_db_open(user_name, password, ip_address, port_num, db_name)
+ connection_db = pm.postgres_db_open()
try:
- _db_status = pm.db_table_creation_check(connection_db, "vnf_table_1")
+ _db_status = db.db_table_creation_check(connection_db, "vnf_table_1")
except Exception:
return None
@@ -68,20 +68,20 @@ def verify_DB_creation_1(user_name, password, ip_address, port_num, db_name):
def verify_DB_creation_2(user_name, password, ip_address, port_num, db_name):
- connection_db = pm.postgres_db_open(user_name, password, ip_address, port_num, db_name)
+ connection_db = pm.postgres_db_open()
try:
- _db_status = pm.db_table_creation_check(connection_db, "vnf_table_2")
+ _db_status = db.db_table_creation_check(connection_db, "vnf_table_2")
except Exception:
return None
return _db_status
-def verify_DB_creation_hb_common(user_name, password, ip_address, port_num, db_name):
+def verify_DB_creation_hb_common():
- connection_db = pm.postgres_db_open(user_name, password, ip_address, port_num, db_name)
+ connection_db = pm.postgres_db_open()
try:
- _db_status = pm.db_table_creation_check(connection_db, "hb_common")
+ _db_status = db.db_table_creation_check(connection_db, "hb_common")
except Exception:
return None
diff --git a/pom.xml b/pom.xml
index fbf5c20..116aa4f 100644
--- a/pom.xml
+++ b/pom.xml
@@ -1,7 +1,7 @@
<?xml version="1.0"?>
<!--
============LICENSE_START=======================================================
-Copyright (c) 2017-2022 AT&T Intellectual Property. All rights reserved.
+Copyright (c) 2017-2023 AT&T Intellectual Property. All rights reserved.
Copyright (c) 2021 Samsung Electronics. All rights reserved.
================================================================================
Licensed under the Apache License, Version 2.0 (the "License");
@@ -37,7 +37,7 @@ limitations under the License.
<groupId>org.onap.dcaegen2.services</groupId>
<artifactId>heartbeat</artifactId>
<name>dcaegen2-services-heartbeat</name>
- <version>2.5.0</version>
+ <version>2.6.0</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<sonar.sources>.</sonar.sources>
diff --git a/setup.py b/setup.py
index 2104015..ed8c5ed 100644
--- a/setup.py
+++ b/setup.py
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (c) 2017-2022 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2017-2023 AT&T Intellectual Property. All rights reserved.
# Copyright (c) 2021 Samsung Electronics. All rights reserved.
# ================================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -20,7 +20,7 @@ from setuptools import setup, find_packages
setup(
name="miss_htbt_service",
description="Missing heartbeat microservice to communicate with policy-engine",
- version="2.5.0",
+ version="2.6.0",
# packages=find_packages(exclude=["tests.*", "tests"]),
packages=find_packages(),
install_requires=[
diff --git a/tests/hbproperties-test.yaml b/tests/hbproperties-test.yaml
new file mode 100644
index 0000000..1dc649c
--- /dev/null
+++ b/tests/hbproperties-test.yaml
@@ -0,0 +1,11 @@
+#Postgres database input
+#pg_ipAddress: 127.0.0.1
+pg_ipAddress: 10.0.0.0
+pg_portNum: "1234"
+pg_userName: postgres-test
+pg_passwd: postgres-test
+pg_dbName: postgres
+
+#Periodic polling of CBS config download
+CBS_polling_allowed: "True"
+CBS_polling_interval: "300"
diff --git a/tests/test-config.json b/tests/test-config.json
new file mode 100644
index 0000000..e853f6a
--- /dev/null
+++ b/tests/test-config.json
@@ -0,0 +1 @@
+{"pg_ipAddress": "10.0.4.1", "pg_userName": "postgres", "pg_dbName": "postgres", "streams_subscribes": {"ves-heartbeat": {"type": "message_router", "dmaap_info": {"topic_url": "http://10.12.5.252:3904/events/unauthenticated.SEC_HEARTBEAT_INPUT"}}}, "consumerID": "1", "CBS_polling_interval": "300", "pg_passwd": "postgres", "streams_publishes": {"dcae_cl_out": {"type": "message_router", "dmaap_info": {"topic_url": "http://10.12.5.252:3904/events/unauthenticated.DCAE_CL_OUTPUT"}}}, "pg_portNum": "5432", "CBS_polling_allowed": "True", "groupID": "groupID", "heartbeat_config": "{\"vnfs\": [{\"eventName\": \"Heartbeat_vDNS\",\"heartbeatcountmissed\": 3,\"heartbeatinterval\": 60,\"closedLoopControlName\": \"ControlLoopEvent1\",\t\"policyVersion\": \"1.0.0.5\",\t\"policyName\":\"vFireWall\",\"policyScope\": \"resource=sampleResource,type=sampletype,CLName=sampleCLName\",\"target_type\": \"VNF\",\t\"target\": \"genVnfName\",\t\"version\": \"1.0\"}, {\"eventName\": \"Heartbeat_vFW\",\"heartbeatcountmissed\": 3,\t\"heartbeatinterval\": 60,\"closedLoopControlName\": \"ControlLoopEvent1\",\"policyVersion\": \"1.0.0.5\",\"policyName\": \"vFireWall\",\"policyScope\": \"resource=sampleResource,type=sampletype,CLName=sampleCLName\",\t\"target_type\":\"VNF\",\t\"target\": \"genVnfName\",\t\"version\": \"1.0\"}, {\"eventName\": \"Heartbeat_xx\",\"heartbeatcountmissed\": 3,\t\"heartbeatinterval\": 60,\"closedLoopControlName\": \"ControlLoopEvent1\",\"policyVersion\": \"1.0.0.5\",\"policyName\": \"vFireWall\",\t\"policyScope\": \"resource=sampleResource,type=sampletype,CLName=sampleCLName\",\"target_type\": \"VNF\",\"target\": \"genVnfName\",\"version\": \"1.0\"}]}"}
diff --git a/tests/test4.json b/tests/test4.json
new file mode 100644
index 0000000..b223497
--- /dev/null
+++ b/tests/test4.json
@@ -0,0 +1 @@
+{"event":{"commonEventHeader":{"startEpochMicrosec":1621969018000,"sourceId":"79e90d76-513a-4f79-886d-470a0037c5cf","eventId":"Heartbeat_vDNS_10.0.0.1","nfcNamingCode":"DNS","reportingEntityId":"79e90d76-513a-4f79-886d-470a0037c5cf","internalHeaderFields":{"collectorTimeStamp":"Wed, 01 04 2023 01:36:35 GMT"},"eventType":"applicationVnf","priority":"Normal","version":3,"reportingEntityName":"VVVVVVcmd010","sequence":36312,"domain":"heartbeat","lastEpochMicrosec":1621969018000,"eventName":"Heartbeat_vDNS","sourceName":"zalp1bmdns01cmd010","nfNamingCode":"MDNS"}}}
diff --git a/tests/test_db_monitoring.py b/tests/test_db_monitoring.py
new file mode 100644
index 0000000..b9a644e
--- /dev/null
+++ b/tests/test_db_monitoring.py
@@ -0,0 +1,75 @@
+#!/usr/bin/env python3
+# ============LICENSE_START=======================================================
+# Copyright (c) 2023 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=========================================================
+
+import db_monitoring
+import htbtworker
+import logging
+import requests
+import tempfile
+import os
+import json
+import unittest
+
+from unittest.mock import *
+from _pytest.outcomes import skip
+
+_logger = logging.getLogger(__name__)
+class Test_db_monitoring(unittest.TestCase):
+
+ def setUp(self):
+ htbtworker.configjsonfile = (os.path.dirname(__file__))+"/test-config.json"
+
+ @patch('requests.post')
+ def test_sendControlLoopEvent(self, mock1):
+ status = True
+ mock_resp = Mock()
+ mock_resp.configure_mock(
+ **{
+ "status_code": 200
+ }
+ )
+ mock1.return_value = mock_resp
+ db_monitoring.sendControlLoopEvent("ONSET", "ABC","1.0","vFW","vFW","VNF","NODE","1234567890","VFW","1.0","DCAE")
+ self.assertEqual(status, True)
+ db_monitoring.sendControlLoopEvent("ONSET", "ABC","1.0","vFW","vFW","VM","NODE","1234567890","VFW","1.0","DCAE")
+ self.assertEqual(status, True)
+ db_monitoring.sendControlLoopEvent("ABATED", "ABC","1.0","vFW","vFW","VNF","NODE","1234567890","VFW","1.0","DCAE")
+ self.assertEqual(status, True)
+ db_monitoring.sendControlLoopEvent("ABATED", "ABC","1.0","vFW","vFW","VM","NODE","1234567890","VFW","1.0","DCAE")
+ self.assertEqual(status, True)
+
+ @patch('misshtbtd.read_hb_common',return_value = ("1234","RUNNING", "XYZ", 1234))
+ @patch('htbtworker.postgres_db_open')
+ def test_db_monitoring(self, mock1, mock2):
+ status = True
+ mock_cursor = Mock()
+ mock2.cursor.return_value = mock_cursor
+ db_monitoring.db_monitoring("111",htbtworker.configjsonfile ,"testuser","testpwd","10.0.0.0","1234","db_name")
+ self.assertEqual(status, True)
+ db_monitoring.db_monitoring("1234",htbtworker.configjsonfile ,"testuser","testpwd","10.0.0.0","1234","db_name")
+ self.assertEqual(status, True)
+ mock1.cursor.return_value = ("1234","RECONFIGURATION", "XYZ", 1234)
+ db_monitoring.db_monitoring("1234",htbtworker.configjsonfile ,"testuser","testpwd","10.0.0.0","1234","db_name")
+ self.assertEqual(status, True)
+
+ def test_db_monitoring_wrapper(self):
+ status = True
+ db_monitoring.db_monitoring_wrapper("111", htbtworker.configjsonfile, number_of_iterations=0)
+ self.assertEqual(status, True)
+
+if __name__ == "__main__": # pragma: no cover
+ unittest.main()
diff --git a/tests/test_get_logger.py b/tests/test_get_logger.py
index a4ceea5..1096271 100644
--- a/tests/test_get_logger.py
+++ b/tests/test_get_logger.py
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (c) 2020-2021 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2020-2023 AT&T Intellectual Property. All rights reserved.
# Copyright (c) 2021 Fujitsu Ltd.
# ================================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,6 +24,8 @@ log = logging.getLogger(__name__)
def test_configure_logger():
+ # logpath = (os.path.dirname(__file__))+"hb_logs.txt"
+ # expected_log_path = Path(logpath)
expected_log_path = Path("./hb_logs.txt")
if expected_log_path.exists():
os.remove(expected_log_path)
@@ -34,6 +36,8 @@ def test_configure_logger():
def test_configure_logger_with_name():
+ # logpath = (os.path.dirname(__file__))+"hb_htbtworker_logs.txt"
+ # expected_log_path = Path(logpath)
expected_log_path = Path("./hb_htbtworker_logs.txt")
if expected_log_path.exists():
os.remove(expected_log_path)
diff --git a/tests/test_trapd_exit.py b/tests/test_htbt_exit.py
index 8803b29..f3698d5 100644
--- a/tests/test_trapd_exit.py
+++ b/tests/test_htbt_exit.py
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (c) 2017-2021 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2017-2023 AT&T Intellectual Property. All rights reserved.
# Copyright (c) 2019 Pantheon.tech. All rights reserved.
# Copyright (c) 2021 Fujitsu Ltd.
# ================================================================================
@@ -18,7 +18,7 @@
import pytest
import unittest
-from miss_htbt_service.mod import trapd_exit
+from miss_htbt_service.mod import htbt_exit
pid_file = "/tmp/test_pid_file"
pid_file_dne = "/tmp/test_pid_file_NOT"
@@ -36,7 +36,7 @@ class test_cleanup_and_exit(unittest.TestCase):
open(pid_file, "w")
with pytest.raises(SystemExit) as pytest_wrapped_sys_exit:
- result = trapd_exit.cleanup_and_exit(0, pid_file)
+ result = htbt_exit.cleanup_and_exit(0, pid_file)
assert pytest_wrapped_sys_exit.type == SystemExit
assert pytest_wrapped_sys_exit.value.code == 0
@@ -45,6 +45,6 @@ class test_cleanup_and_exit(unittest.TestCase):
Test exit with missing PID file exits non-zero
"""
with pytest.raises(SystemExit) as pytest_wrapped_sys_exit:
- result = trapd_exit.cleanup_and_exit(0, pid_file_dne)
+ result = htbt_exit.cleanup_and_exit(0, pid_file_dne)
assert pytest_wrapped_sys_exit.type == SystemExit
assert pytest_wrapped_sys_exit.value.code == 1
diff --git a/tests/test_trapd_get_cbs_config.py b/tests/test_htbt_get_cbs_config.py
index 75e2055..99e347c 100644
--- a/tests/test_trapd_get_cbs_config.py
+++ b/tests/test_htbt_get_cbs_config.py
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (c) 2017-2022 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2017-2023 AT&T Intellectual Property. All rights reserved.
# Copyright (c) 2019 Pantheon.tech. All rights reserved.
# Copyright (c) 2021 Fujitsu Ltd.
# ================================================================================
@@ -19,13 +19,17 @@
import pytest
import unittest
import os
+import cbs_polling as cp
+import time
+import misshtbtd
+from unittest.mock import *
-from miss_htbt_service.mod import trapd_get_cbs_config
+from miss_htbt_service.mod import htbt_get_cbs_config
class test_get_cbs_config(unittest.TestCase):
"""
- Test the trapd_get_cbs_config mod
+ Test the htbt_get_cbs_config mod
"""
pytest_json_data = (
@@ -77,7 +81,7 @@ class test_get_cbs_config(unittest.TestCase):
" ]"
" },"
' "streams_publishes": {'
- ' "ves_heartbeat": {'
+ ' "dcae_cl_out": {'
' "dmaap_info": {'
' "topic_url": "http://message-router:3904/events/unauthenticated.DCAE_CL_OUTPUT/"'
" },"
@@ -85,18 +89,24 @@ class test_get_cbs_config(unittest.TestCase):
" }"
" },"
' "streams_subscribes": {'
- ' "ves_heartbeat": {'
+ ' "ves-heartbeat": {'
' "dmaap_info": {'
' "topic_url": "http://message-router:3904/events/unauthenticated.SEC_HEARTBEAT_INPUT/"'
" },"
' "type": "message_router"'
" }"
- " }"
+ " },"
+ ' "pg_ipAddress": "10.0.4.1",'
+ ' "pg_userName": "postgres",'
+ ' "pg_dbName": "postgres",'
+ ' "pg_passwd": "postgres",'
+ ' "pg_portNum": "5432"'
"}"
)
- # create copy of snmptrapd.json for pytest
- pytest_json_config = "/tmp/opt/app/miss_htbt_service/etc/config.json"
+ # create copy of snmphtbt.json for pytest
+ #pytest_json_config = "/tmp/opt/app/miss_htbt_service/etc/config.json"
+ pytest_json_config = "test-config.json"
with open(pytest_json_config, "w") as outfile:
outfile.write(pytest_json_data)
@@ -107,7 +117,7 @@ class test_get_cbs_config(unittest.TestCase):
"""
with pytest.raises(Exception) as pytest_wrapped_sys_exit:
- result = trapd_get_cbs_config.get_cbs_config()
+ result = htbt_get_cbs_config.get_cbs_config()
assert pytest_wrapped_sys_exit.type == SystemExit
def test_cbs_fallback_env_present(self):
@@ -119,3 +129,20 @@ class test_get_cbs_config(unittest.TestCase):
result = True
print("result: %s" % result)
self.assertEqual(result, True)
+
+ @patch('misshtbtd.create_update_hb_common')
+ @patch('misshtbtd.read_hb_common')
+ def test_poll_cbs(self, mock1, mock2):
+ """
+ TBD
+ """
+ status = True
+ current_time = round(time.time())
+ mock1.return_value = ('1', 'RUNNING', 'AA', current_time)
+ # configjsonfile = (os.path.dirname(__file__))+"/test-config.json"
+ configjsonfile = "test-config.json"
+ os.environ.update(CBS_HTBT_JSON=configjsonfile)
+ os.environ["pytest"] = "test"
+ cp.poll_cbs(1)
+ self.assertEqual(status, True)
+
diff --git a/tests/test_trapd_http_session.py b/tests/test_htbt_http_session.py
index 070fc93..ed3a33a 100644
--- a/tests/test_trapd_http_session.py
+++ b/tests/test_htbt_http_session.py
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (c) 2017-2021 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2017-2023 AT&T Intellectual Property. All rights reserved.
# Copyright (c) 2019 Pantheon.tech. All rights reserved.
# Copyright (c) 2021 Fujitsu Ltd.
# ================================================================================
@@ -17,7 +17,7 @@
# ============LICENSE_END=========================================================
import unittest
-from miss_htbt_service.mod import trapd_http_session
+from miss_htbt_service.mod import htbt_http_session
class test_init_session_obj(unittest.TestCase):
@@ -29,6 +29,6 @@ class test_init_session_obj(unittest.TestCase):
"""
Test that attempt to create http session object works
"""
- result = trapd_http_session.init_session_obj()
+ result = htbt_http_session.init_session_obj()
compare = str(result).startswith("<requests.sessions.Session object at")
self.assertEqual(compare, True)
diff --git a/tests/test_trapd_runtime_pid.py b/tests/test_htbt_runtime_pid.py
index 47bc642..96379d9 100644
--- a/tests/test_trapd_runtime_pid.py
+++ b/tests/test_htbt_runtime_pid.py
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (c) 2017-2021 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2017-2023 AT&T Intellectual Property. All rights reserved.
# Copyright (c) 2019 Pantheon.tech. All rights reserved.
# Copyright (c) 2021 Fujitsu Ltd.
# ================================================================================
@@ -17,7 +17,7 @@
# ============LICENSE_END=========================================================
import unittest
-from miss_htbt_service.mod import trapd_runtime_pid
+from miss_htbt_service.mod import htbt_runtime_pid
class test_save_pid(unittest.TestCase):
@@ -29,14 +29,14 @@ class test_save_pid(unittest.TestCase):
"""
Test that attempt to create pid file in standard location works
"""
- result = trapd_runtime_pid.save_pid("/tmp/snmptrap_test_pid_file")
+ result = htbt_runtime_pid.save_pid("/tmp/snmptrap_test_pid_file")
self.assertEqual(result, True)
def test_missing_directory(self):
"""
Test that attempt to create pid file in missing dir fails
"""
- result = trapd_runtime_pid.save_pid("/bogus/directory/for/snmptrap_test_pid_file")
+ result = htbt_runtime_pid.save_pid("/bogus/directory/for/snmptrap_test_pid_file")
self.assertEqual(result, False)
@@ -50,14 +50,14 @@ class test_rm_pid(unittest.TestCase):
Test that attempt to remove pid file in standard location works
"""
# must create it before removing it
- result = trapd_runtime_pid.save_pid("/tmp/snmptrap_test_pid_file")
+ result = htbt_runtime_pid.save_pid("/tmp/snmptrap_test_pid_file")
self.assertEqual(result, True)
- result = trapd_runtime_pid.rm_pid("/tmp/snmptrap_test_pid_file")
+ result = htbt_runtime_pid.rm_pid("/tmp/snmptrap_test_pid_file")
self.assertEqual(result, True)
def test_missing_file(self):
"""
Test that attempt to rm non-existent pid file fails
"""
- result = trapd_runtime_pid.rm_pid("/tmp/snmptrap_test_pid_file_9999")
+ result = htbt_runtime_pid.rm_pid("/tmp/snmptrap_test_pid_file_9999")
self.assertEqual(result, False)
diff --git a/tests/test_trapd_settings.py b/tests/test_htbt_settings.py
index 743fa68..3db86a1 100644
--- a/tests/test_trapd_settings.py
+++ b/tests/test_htbt_settings.py
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (c) 2017-2022 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2017-2023 AT&T Intellectual Property. All rights reserved.
# Copyright (c) 2019 Pantheon.tech. All rights reserved.
# Copyright (c) 2021 Fujitsu Ltd.
# ================================================================================
@@ -18,7 +18,7 @@
import unittest
-from miss_htbt_service.mod import trapd_settings as tds
+from miss_htbt_service.mod import htbt_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_htbt_vnf_table.py
index 2e0f22a..4b6c3f1 100644
--- a/tests/test_trapd_vnf_table.py
+++ b/tests/test_htbt_vnf_table.py
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (c) 2017-2022 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2017-2023 AT&T Intellectual Property. All rights reserved.
# Copyright (c) 2019 Pantheon.tech. All rights reserved.
# Copyright (c) 2020 Deutsche Telekom. All rights reserved.
# Copyright (c) 2021 Fujitsu Ltd.
@@ -19,11 +19,13 @@
#
# Author Prakask H (ph553f)
"""
-test_trapd_vnf_table contains test cases related to DB Tables and cbs polling.
+test_htbt_vnf_table contains test cases related to DB Tables and cbs polling.
"""
import logging
import unittest
-from mod.trapd_vnf_table import (
+import os
+from unittest.mock import *
+from mod.htbt_vnf_table import (
verify_DB_creation_1,
verify_DB_creation_2,
verify_DB_creation_hb_common,
@@ -50,28 +52,40 @@ class test_vnf_tables(unittest.TestCase):
global ip_address, port_num, user_name, password, db_name, cbs_polling_required, cbs_polling_interval
ip_address, port_num, user_name, password, db_name, cbs_polling_required, cbs_polling_interval = hb_properties()
- def test_validate_vnf_table_1(self):
+ @patch('htbtworker.postgres_db_open')
+ @patch('misshtbtd.db_table_creation_check', return_value=True)
+ def test_validate_vnf_table_1(self, mock, mock1):
result = verify_DB_creation_1(user_name, password, ip_address, port_num, db_name)
self.assertEqual(result, True)
- def test_validate_vnf_table_2(self):
+ @patch('htbtworker.postgres_db_open')
+ @patch('misshtbtd.db_table_creation_check', return_value=True)
+ def test_validate_vnf_table_2(self, mock, mock1):
result = verify_DB_creation_2(user_name, password, ip_address, port_num, db_name)
self.assertEqual(result, True)
- def test_validate_hb_common(self):
- result = verify_DB_creation_hb_common(user_name, password, ip_address, port_num, db_name)
+ @patch('htbtworker.postgres_db_open')
+ @patch('misshtbtd.db_table_creation_check', return_value=True)
+ def test_validate_hb_common(self, mock, mock1):
+ result = verify_DB_creation_hb_common()
self.assertEqual(result, True)
-
- def test_cbspolling(self):
+
+ @patch('cbs_polling.poll_cbs')
+ def test_cbspolling(self, mock):
# Check if no exception thrown
verify_cbspolling()
- def test_fetch_json_file(self):
+ @patch('misshtbtd.fetch_json_file')
+ def test_fetch_json_file(self, mock1):
+ configjsonfile = (os.path.dirname(__file__))+"/test-config.json"
+ mock1.return_value = configjsonfile
+
result = verify_fetch_json_file()
_logger.info(result)
self.assertEqual(result, True)
- def test_misshtbtdmain(self):
+ @patch('misshtbtd.main')
+ def test_misshtbtdmain(self, mock):
result = verify_misshtbtdmain()
_logger.info(result)
self.assertEqual(result, True)
@@ -81,7 +95,14 @@ class test_vnf_tables(unittest.TestCase):
_logger.info(result)
self.assertEqual(result, True)
- def test_dbmonitoring(self):
+ @patch('misshtbtd.fetch_json_file')
+ @patch('misshtbtd.read_hb_common')
+ @patch('db_monitoring.db_monitoring')
+ def test_dbmonitoring(self, mock1, mock2, mock3):
+ configjsonfile = (os.path.dirname(__file__))+"/test-config.json"
+ mock1.return_value = configjsonfile
+ mock2.return_value = ("1234","RUNNING", "XYZ", 1234)
+
result = verify_dbmonitoring()
_logger.info(result)
self.assertEqual(result, True)
diff --git a/tests/test_htbtworker.py b/tests/test_htbtworker.py
index 78c9087..ee03ddb 100644
--- a/tests/test_htbtworker.py
+++ b/tests/test_htbtworker.py
@@ -1,5 +1,5 @@
# ============LICENSE_START=======================================================
-# Copyright (c) 2020-2022 AT&T Intellectual Property. All rights reserved.
+# Copyright (c) 2020-2023 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,37 +14,152 @@
# limitations under the License.
# ============LICENSE_END=========================================================
-from miss_htbt_service import htbtworker
+import htbtworker
import os
import tempfile
-import json
+import json
+import unittest
+from unittest.mock import *
+from _pytest.outcomes import skip
+class Test_htbtworker(unittest.TestCase):
-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 setUp(self):
+ htbtworker.configjsonfile = (os.path.dirname(__file__))+"/test-config.json"
+ @patch('requests.get')
+ @patch('htbtworker.check_process_reconfiguration', return_value=False)
+ @patch('htbtworker.get_eventnamelist')
+ @patch('htbtworker.sql_executor')
+ def test_process_msg(self, mock1, mock2, mock3, sqlmock1):
+ """
+ Test to verify event processing using mock
+ TBD - Negative test
+ """
+
+ status = True
+ dmaap_data = [{"event":{"commonEventHeader":{"startEpochMicrosec":1544608845841,"sourceId":"VNFB_SRC5","eventId":"mvfs10","nfcNamingCode":"VNFB","timeZoneOffset":"UTC-05:30","reportingEntityId":"cc305d54-75b4-431b-adb2-eb6b9e541234","eventType":"platform","priority":"Normal","version":"4.0.2","reportingEntityName":"ibcx0001vm002oam001","sequence":1000,"domain":"heartbeat","lastEpochMicrosec":1544608845841,"eventName":"Heartbeat_vFW","vesEventListenerVersion":"7.0.2","sourceName":"SOURCE_NAME2","nfNamingCode":"VNFB"},"heartbeatFields":{"heartbeatInterval":20,"heartbeatFieldsVersion":"3.0"}}}]
+
+ mock_resp = Mock()
+ mock_resp.configure_mock(
+ **{
+ "text": json.dumps(dmaap_data)
+ }
+ )
+ mock3.return_value = [("Heartbeat_vDNS", "Heartbeat_vFW")]
+ mock1.return_value = mock_resp
-def test_read_json_file_0():
- run_test(0)
+ filename = "test-config.json"
+ htbtworker.process_msg(filename, number_of_iterations=1)
+ self.assertEqual(status, True)
+
+ def test_parse_event(self):
+ """
+ test_parse_event() opens the file test1.json and returns attributes
+ """
+ filename = (os.path.dirname(__file__))+"/test1.json"
+ with open(filename,"r") as fp:
+ data = fp.read()
+ srcname,lastepo,seqnum,event_name = htbtworker.parse_event(data)
+ self.assertEqual(srcname, "SOURCE_NAME1")
+ self.assertEqual(event_name, "Heartbeat_vDNS")
-def test_read_json_file_1():
- run_test(1)
+ filename = (os.path.dirname(__file__))+"/test4.json"
+ with open(filename,"r") as fp:
+ data = fp.read()
+ srcname,lastepo,seqnum,event_name = htbtworker.parse_event(data)
+ self.assertEqual(srcname, "zalp1bmdns01cmd010")
+ self.assertEqual(event_name, "Heartbeat_vDNS")
-def test_read_json_file_2():
- run_test(2)
+ @patch('htbtworker.sql_executor')
+ def test_create_and_check_vnf2_table (self, mock_settings):
+ """
+ Test to verify existence of given table
+ """
+ mock_cursor = Mock()
+ mock_cursor.configure_mock(
+ **{
+ "fetchone.return_value": [("vnf_table_2")]
+ }
+ )
+ mock_settings.return_value = mock_cursor
+ status = htbtworker.check_and_create_vnf2_table ()
+ self.assertEqual(status, True)
+
+ with patch('htbtworker.sql_executor', new=Mock(side_effect=htbtworker.psycopg2.DatabaseError())):
+ status = htbtworker.check_and_create_vnf2_table ()
+ self.assertEqual(False, status)
+
+ @patch('htbtworker.sql_executor')
+ def test_new_vnf_entry (self, sql_mock):
+ """
+ Check to verify if new node entry is made for tracking HB
+ """
+ status = True
+ htbtworker.new_vnf_entry ("Heartbeat_vDNS", "TESTNODE", 1548313727714000, "TESTNODE", 1)
+ self.assertEqual(status, True)
+
+ @patch('htbtworker.sql_executor')
+ def test_get_eventnamelist (self, sql_mock):
+ """
+ Test to verify eventname list is returned from vnf_table_1
+ TBD - List comparison
+ """
+ eventname_list = [("Heartbeat_vDNS", "Heartbeat_vFW")]
+ mock_cursor = Mock()
+ mock_cursor.configure_mock(
+ **{
+ "fetchall.return_value": eventname_list
+ }
+ )
+ sql_mock.return_value = mock_cursor
+ return_list = htbtworker.get_eventnamelist ()
+ self.assertIn("Heartbeat_vDNS", return_list)
+
+ @patch('htbtworker.postgres_db_open')
+ def test_sql_executor (self, db_mock):
+ """
+ Test sql executor wrapper method
+ """
+ htbtworker.sql_executor ("SELECT * FROM information_schema.tables WHERE table_name = %s", "vnf_table_2")
+ htbtworker.sql_executor ("INSERT into information_schema.tables,")
+ connection_db = db_mock
+ with patch('htbtworker.postgres_db_open.commit', new=Mock(side_effect=htbtworker.psycopg2.DatabaseError())):
+ flag = htbtworker.commit_and_close_db(connection_db)
+ self.assertEqual(False, flag)
+
+ @patch('psycopg2.connect')
+ def test_postgres_db_open (self, mock):
+ """
+ Test wrapper for postgres db connection
+ """
+ conn = htbtworker.postgres_db_open()
+ self.assertIsNotNone(conn)
+
+ @patch('misshtbtd.read_hb_common')
+ def test_check_process_reconfiguration (self, mock):
+ """
+ Test if DB is in reconfiguration state
+ """
+ mock.return_value = ("1234","RUNNING", "XYZ", 1234)
+ flag = htbtworker.check_process_reconfiguration("test", "test","x.x.x.x", "1234", "test_db")
+ self.assertEqual(False, flag)
+
+ @patch('htbtworker.postgres_db_open')
+ def test_commit_and_close_db (self, db_mock):
+ """
+ Test commit and close db
+ """
+ connection_db = db_mock
+ flag = htbtworker.commit_and_close_db(connection_db)
+ self.assertEqual(True, flag)
+ with patch('htbtworker.postgres_db_open.commit', new=Mock(side_effect=htbtworker.psycopg2.DatabaseError())):
+ flag = htbtworker.commit_and_close_db(connection_db)
+ self.assertEqual(False, flag)
+
+
+if __name__ == "__main__": # pragma: no cover
+ unittest.main()
diff --git a/tests/test_misshtbtd.py b/tests/test_misshtbtd.py
new file mode 100644
index 0000000..0fc8a24
--- /dev/null
+++ b/tests/test_misshtbtd.py
@@ -0,0 +1,215 @@
+# ============LICENSE_START=======================================================
+# Copyright (c) 2020-2023 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=========================================================
+
+import htbtworker
+import misshtbtd
+import time
+import psycopg2
+import os
+import tempfile
+import json
+import unittest
+from unittest.mock import *
+from _pytest.outcomes import skip
+from pickle import FALSE
+
+class Test_misshtbtd(unittest.TestCase):
+
+ def setUp(self):
+ htbtworker.configjsonfile = (os.path.dirname(__file__))+"/test-config.json"
+
+ @patch ('psycopg2.connect')
+ def test_create_database(self, mock1):
+ status = True
+ mock_cursor = MagicMock()
+ mock_cursor.configure_mock(
+ **{
+ "fetchone.return_value": [("1")]
+ }
+ )
+ mock1.return_value = mock_cursor
+ misshtbtd.create_database("vnf_table_1",htbtworker.configjsonfile, "10.0.0.0","1234","testuser","testpwd","heartbeatdb")
+ self.assertEqual(status, True)
+
+ @patch ('htbtworker.postgres_db_open')
+ def test_read_hb_common(self, mock1):
+
+ mock_cursor = Mock()
+ mock_cursor.configure_mock(
+ **{
+ "cursor.return_value.fetchall.return_value": [["1", "AA", "123456789", "RUNNING"]]
+ }
+ )
+ mock1.return_value = mock_cursor
+ self.assertEqual(('1', 'RUNNING', 'AA', '123456789'), misshtbtd.read_hb_common("testuser","testpwd","10.0.0.0","1234","heartbeatdb"))
+
+ @patch ('misshtbtd.db_table_creation_check')
+ @patch ('htbtworker.postgres_db_open')
+ def test_create_update_hb_common(self, mock1, mock2):
+ '''
+ TODO: argument ordering TBD
+ '''
+ mock_cursor = Mock()
+ mock1.return_value = mock_cursor
+ mock2.return_value = True
+ status = True
+ misshtbtd.create_update_hb_common (0,111, "RUNNING", "testuser","testpwd","10.0.0.0","1234","testdb")
+ self.assertEqual(status, True)
+ mock2.return_value = False
+ misshtbtd.create_update_hb_common (1,111, "RUNNING", "testuser","testpwd","10.0.0.0","1234","testdb")
+ self.assertEqual(status, True)
+
+ def test_db_table_creation_check (self):
+ """
+ Test to verify existence of given table
+ """
+ mock_cursor = Mock()
+ mock_cursor.configure_mock(
+ **{
+ "cursor.return_value.fetchone.return_value": ("vnf_table_2")
+ }
+ )
+ status = misshtbtd.db_table_creation_check (mock_cursor,"vnf_table_2")
+ self.assertEqual(status, True)
+
+ @patch ('misshtbtd.db_table_creation_check')
+ def test_create_update_vnf_table_1 (self, mock1):
+ """
+ TBD
+ """
+ status = True
+ mock_cursor = Mock()
+ mock_cursor.configure_mock(
+ **{
+ "cursor.return_value.fetchall.return_value": [["Heartbeat_vDNS"],["Heartbeat_vFW"]]
+ }
+ )
+ misshtbtd.create_update_vnf_table_1 (htbtworker.configjsonfile,1, mock_cursor)
+ self.assertEqual(status, True)
+ misshtbtd.create_update_vnf_table_1 (htbtworker.configjsonfile,0, mock_cursor)
+ self.assertEqual(status, True)
+
+ def test_read_hb_properties_default_from_file (self):
+ """
+ TBD
+ """
+ return_val = ("10.0.0.0","1234", "postgres-test", "postgres-test", "postgres", "True", "300")
+ misshtbtd.hb_properties_file = (os.path.dirname(__file__)) + "/hbproperties-test.yaml"
+ (ip_address, port_num, user_name, password, db_name, cbs_polling_required, cbs_polling_interval) = misshtbtd.read_hb_properties_default()
+ self.assertEqual (return_val,(ip_address, port_num, user_name, password, db_name, cbs_polling_required, cbs_polling_interval) )
+
+ @patch.dict(os.environ, {"pg_ipAddress": "10.0.0.10", "pg_portNum":"1234", "pg_userName": "test","pg_passwd":"test"})
+ def test_read_hb_properties_default_from_env (self):
+ """
+ TBD
+ """
+ return_val = ("10.0.0.10","1234", "test", "test", "postgres", "True", "300")
+ misshtbtd.hb_properties_file = (os.path.dirname(__file__)) + "/hbproperties-test.yaml"
+ (ip_address, port_num, user_name, password, db_name, cbs_polling_required, cbs_polling_interval) = misshtbtd.read_hb_properties_default()
+ self.assertEqual (return_val,(ip_address, port_num, user_name, password, db_name, cbs_polling_required, cbs_polling_interval) )
+
+ def test_read_hb_properties_from_file (self):
+ """
+ TBD
+ """
+ htbtworker.configjsonfile = (os.path.dirname(__file__))+"/test-config.json"
+ misshtbtd.hb_properties_file = (os.path.dirname(__file__)) + "/hbproperties-test.yaml"
+
+ return_val = ("10.0.4.1","5432", "postgres", "postgres", "postgres", "True", "300")
+ (ip_address, port_num, user_name, password, db_name, cbs_polling_required, cbs_polling_interval) = misshtbtd.read_hb_properties(htbtworker.configjsonfile)
+ self.assertEqual (return_val,(ip_address, port_num, user_name, password, db_name, cbs_polling_required, cbs_polling_interval) )
+
+ @patch.dict(os.environ, {"pg_ipAddress": "10.0.0.10", "pg_portNum":"1234", "pg_userName": "test","pg_passwd":"test"})
+ def test_read_hb_properties_exception_handling (self):
+ """
+ TBD
+ """
+ htbtworker.configjsonfile = (os.path.dirname(__file__))+"/aa-config.json"
+ misshtbtd.hb_properties_file = (os.path.dirname(__file__)) + "/hbproperties-test.yaml"
+
+ return_val = ("10.0.0.10","1234", "test", "test", "postgres", "True", "300")
+ (ip_address, port_num, user_name, password, db_name, cbs_polling_required, cbs_polling_interval) = misshtbtd.read_hb_properties(htbtworker.configjsonfile)
+ self.assertEqual (return_val,(ip_address, port_num, user_name, password, db_name, cbs_polling_required, cbs_polling_interval) )
+
+
+ @patch ('mod.htbt_get_cbs_config')
+ def test_fetch_json_file (self, mock1):
+ """
+ TBD
+ """
+ #mock.return_value.is_file.return_value = True
+ mock1.return_value = True
+ misshtbtd.CONFIG_PATH = "test-config.json"
+ filename = misshtbtd.fetch_json_file()
+ self.assertEqual (misshtbtd.CONFIG_PATH, filename)
+ # mock1.return_value = False
+ # filename = misshtbtd.fetch_json_file()
+ # self.assertEqual ("./etc/config.json", filename)
+
+ @patch ('htbtworker.postgres_db_open')
+ @patch ('misshtbtd.db_table_creation_check')
+ @patch ('misshtbtd.create_update_vnf_table_1')
+ def test_create_update_db(self, mock1, mock2, mock3):
+ '''
+ TODO: argument ordering TBD
+ '''
+ mock_cursor = Mock()
+ mock3.return_value = mock_cursor
+ mock1.return_value = True
+ mock2.return_value = True
+ status = True
+ misshtbtd.create_update_db (0,htbtworker.configjsonfile, "10.0.0.0", "1234", "test","test", "testdb")
+ self.assertEqual(status, True)
+ mock1.return_value = False
+ misshtbtd.create_update_db (0,htbtworker.configjsonfile, "10.0.0.0", "1234", "test","test", "testdb")
+ self.assertEqual(status, True)
+
+ @patch ('multiprocessing.Process')
+ @patch ('misshtbtd.create_update_db')
+ @patch('misshtbtd.create_update_hb_common')
+ def test_create_process(self, mock1, mock2, mock3):
+ job_list = []
+ mock_process = Mock()
+ mock_process.configure_mock(
+ **{
+ "start.return_value": "1"
+ }
+ )
+ mock1.return_value = mock_process
+ job_list = misshtbtd.create_process ([],htbtworker.configjsonfile, 1)
+ self.assertTrue(job_list)
+
+ @patch ('multiprocessing.Process')
+ @patch ('misshtbtd.read_hb_common')
+ @patch ('misshtbtd.create_update_db')
+ @patch ('misshtbtd.create_update_hb_common')
+ def test_main(self, mock1, mock2, mock3, mock4):
+ status = True
+ mock_process = Mock()
+ mock_process.configure_mock(
+ **{
+ "start.return_value": "1",
+ "pid.return_Value":"1111"
+ }
+ )
+ mock1.return_value = mock_process
+ current_time = round(time.time())
+ mock2.return_value = ('1', 'RUNNING', 'AA', current_time)
+ misshtbtd.main()
+ self.assertEqual(status, True)
+
+if __name__ == "__main__": # pragma: no cover
+ unittest.main()
diff --git a/tox.ini b/tox.ini
index 9dcf73f..ad59330 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,6 +1,7 @@
# content of: tox.ini , put in same dir as setup.py
[tox]
-envlist = py38,py39
+envlist = py36,py38,py39
+skip_missing_interpreters = true
[testenv]
deps=
diff --git a/version.properties b/version.properties
index 6c69733..8201005 100644
--- a/version.properties
+++ b/version.properties
@@ -1,5 +1,5 @@
major=2
-minor=5
+minor=6
patch=0
base_version=${major}.${minor}.${patch}
release_version=${base_version}