summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Dockerfile2
-rw-r--r--coverage.xml695
-rw-r--r--pom.xml3
-rw-r--r--setup.py14
-rw-r--r--snmptrap/__init__.py21
-rw-r--r--snmptrap/mod/__init__.py21
-rw-r--r--snmptrap/mod/trapd_exit.py (renamed from bin/mod/trapd_exit.py)4
-rw-r--r--snmptrap/mod/trapd_get_cbs_config.py (renamed from bin/mod/trapd_get_cbs_config.py)8
-rw-r--r--snmptrap/mod/trapd_http_session.py (renamed from bin/mod/trapd_http_session.py)0
-rw-r--r--snmptrap/mod/trapd_io.py (renamed from bin/mod/trapd_file_utils.py)173
-rw-r--r--snmptrap/mod/trapd_logging.py (renamed from bin/mod/trapd_logging.py)0
-rw-r--r--snmptrap/mod/trapd_runtime_pid.py (renamed from bin/mod/trapd_runtime_pid.py)0
-rw-r--r--snmptrap/mod/trapd_settings.py (renamed from bin/mod/trapd_settings.py)0
-rw-r--r--snmptrap/snmptrapd.py (renamed from bin/snmptrapd.py)355
-rw-r--r--[-rwxr-xr-x]snmptrap/snmptrapd.sh (renamed from bin/snmptrapd.sh)0
-rw-r--r--tests/__init__.py21
-rw-r--r--tests/_test_trapd_get_cbs_config.py44
-rw-r--r--tests/conftest.py12
-rw-r--r--tests/snmp.setup.py (renamed from tests/setup.py)0
-rw-r--r--tests/test_snmptrapd.py100
-rw-r--r--tests/test_trapd_get_cbs_config.py61
-rw-r--r--tests/test_trapd_settings.py73
-rw-r--r--tests/tox.ini15
-rw-r--r--tox.ini15
24 files changed, 1364 insertions, 273 deletions
diff --git a/Dockerfile b/Dockerfile
index 9475936..d967b0c 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -12,7 +12,7 @@ WORKDIR ${APPDIR}
EXPOSE 162:162/udp
# Copy the current directory contents into the container at ${APPDIR}
-COPY ./bin/ ./bin/
+COPY ./snmptrap/ ./bin/
COPY ./etc/ ./etc/
COPY requirements.txt ./
RUN pip install -r requirements.txt
diff --git a/coverage.xml b/coverage.xml
new file mode 100644
index 0000000..96da2c6
--- /dev/null
+++ b/coverage.xml
@@ -0,0 +1,695 @@
+<?xml version="1.0" ?>
+<coverage branch-rate="0" branches-covered="0" branches-valid="0" complexity="0" line-rate="0.07154" lines-covered="45" lines-valid="629" timestamp="1522110803348" version="4.5.1">
+ <!-- Generated by coverage.py: https://coverage.readthedocs.io -->
+ <!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd -->
+ <sources>
+ <source>C:\Users\vv770d\git\onap\snmptrap\snmptrap</source>
+ </sources>
+ <packages>
+ <package branch-rate="0" complexity="0" line-rate="0" name=".">
+ <classes>
+ <class branch-rate="0" complexity="0" filename="__init__.py" line-rate="1" name="__init__.py">
+ <methods/>
+ <lines/>
+ </class>
+ <class branch-rate="0" complexity="0" filename="snmptrapd.py" line-rate="0" name="snmptrapd.py">
+ <methods/>
+ <lines>
+ <line hits="0" number="21"/>
+ <line hits="0" number="36"/>
+ <line hits="0" number="39"/>
+ <line hits="0" number="40"/>
+ <line hits="0" number="41"/>
+ <line hits="0" number="42"/>
+ <line hits="0" number="43"/>
+ <line hits="0" number="44"/>
+ <line hits="0" number="45"/>
+ <line hits="0" number="46"/>
+ <line hits="0" number="47"/>
+ <line hits="0" number="48"/>
+ <line hits="0" number="49"/>
+ <line hits="0" number="50"/>
+ <line hits="0" number="51"/>
+ <line hits="0" number="52"/>
+ <line hits="0" number="53"/>
+ <line hits="0" number="54"/>
+ <line hits="0" number="55"/>
+ <line hits="0" number="56"/>
+ <line hits="0" number="57"/>
+ <line hits="0" number="58"/>
+ <line hits="0" number="59"/>
+ <line hits="0" number="60"/>
+ <line hits="0" number="63"/>
+ <line hits="0" number="64"/>
+ <line hits="0" number="66"/>
+ <line hits="0" number="67"/>
+ <line hits="0" number="70"/>
+ <line hits="0" number="71"/>
+ <line hits="0" number="72"/>
+ <line hits="0" number="73"/>
+ <line hits="0" number="74"/>
+ <line hits="0" number="76"/>
+ <line hits="0" number="77"/>
+ <line hits="0" number="79"/>
+ <line hits="0" number="80"/>
+ <line hits="0" number="87"/>
+ <line hits="0" number="98"/>
+ <line hits="0" number="99"/>
+ <line hits="0" number="100"/>
+ <line hits="0" number="108"/>
+ <line hits="0" number="125"/>
+ <line hits="0" number="126"/>
+ <line hits="0" number="128"/>
+ <line hits="0" number="133"/>
+ <line hits="0" number="134"/>
+ <line hits="0" number="136"/>
+ <line hits="0" number="137"/>
+ <line hits="0" number="138"/>
+ <line hits="0" number="139"/>
+ <line hits="0" number="140"/>
+ <line hits="0" number="141"/>
+ <line hits="0" number="145"/>
+ <line hits="0" number="146"/>
+ <line hits="0" number="147"/>
+ <line hits="0" number="148"/>
+ <line hits="0" number="156"/>
+ <line hits="0" number="159"/>
+ <line hits="0" number="160"/>
+ <line hits="0" number="161"/>
+ <line hits="0" number="162"/>
+ <line hits="0" number="163"/>
+ <line hits="0" number="164"/>
+ <line hits="0" number="165"/>
+ <line hits="0" number="166"/>
+ <line hits="0" number="167"/>
+ <line hits="0" number="168"/>
+ <line hits="0" number="171"/>
+ <line hits="0" number="172"/>
+ <line hits="0" number="173"/>
+ <line hits="0" number="174"/>
+ <line hits="0" number="177"/>
+ <line hits="0" number="181"/>
+ <line hits="0" number="198"/>
+ <line hits="0" number="199"/>
+ <line hits="0" number="201"/>
+ <line hits="0" number="209"/>
+ <line hits="0" number="214"/>
+ <line hits="0" number="215"/>
+ <line hits="0" number="217"/>
+ <line hits="0" number="218"/>
+ <line hits="0" number="219"/>
+ <line hits="0" number="221"/>
+ <line hits="0" number="223"/>
+ <line hits="0" number="224"/>
+ <line hits="0" number="226"/>
+ <line hits="0" number="234"/>
+ <line hits="0" number="245"/>
+ <line hits="0" number="247"/>
+ <line hits="0" number="248"/>
+ <line hits="0" number="249"/>
+ <line hits="0" number="251"/>
+ <line hits="0" number="254"/>
+ <line hits="0" number="255"/>
+ <line hits="0" number="258"/>
+ <line hits="0" number="260"/>
+ <line hits="0" number="261"/>
+ <line hits="0" number="263"/>
+ <line hits="0" number="264"/>
+ <line hits="0" number="266"/>
+ <line hits="0" number="267"/>
+ <line hits="0" number="268"/>
+ <line hits="0" number="269"/>
+ <line hits="0" number="271"/>
+ <line hits="0" number="273"/>
+ <line hits="0" number="277"/>
+ <line hits="0" number="279"/>
+ <line hits="0" number="281"/>
+ <line hits="0" number="287"/>
+ <line hits="0" number="289"/>
+ <line hits="0" number="291"/>
+ <line hits="0" number="293"/>
+ <line hits="0" number="294"/>
+ <line hits="0" number="295"/>
+ <line hits="0" number="296"/>
+ <line hits="0" number="298"/>
+ <line hits="0" number="300"/>
+ <line hits="0" number="303"/>
+ <line hits="0" number="304"/>
+ <line hits="0" number="306"/>
+ <line hits="0" number="309"/>
+ <line hits="0" number="310"/>
+ <line hits="0" number="312"/>
+ <line hits="0" number="315"/>
+ <line hits="0" number="317"/>
+ <line hits="0" number="318"/>
+ <line hits="0" number="320"/>
+ <line hits="0" number="322"/>
+ <line hits="0" number="324"/>
+ <line hits="0" number="326"/>
+ <line hits="0" number="327"/>
+ <line hits="0" number="329"/>
+ <line hits="0" number="332"/>
+ <line hits="0" number="333"/>
+ <line hits="0" number="334"/>
+ <line hits="0" number="335"/>
+ <line hits="0" number="342"/>
+ <line hits="0" number="345"/>
+ <line hits="0" number="349"/>
+ <line hits="0" number="357"/>
+ <line hits="0" number="378"/>
+ <line hits="0" number="381"/>
+ <line hits="0" number="384"/>
+ <line hits="0" number="385"/>
+ <line hits="0" number="387"/>
+ <line hits="0" number="389"/>
+ <line hits="0" number="391"/>
+ <line hits="0" number="392"/>
+ <line hits="0" number="393"/>
+ <line hits="0" number="396"/>
+ <line hits="0" number="397"/>
+ <line hits="0" number="398"/>
+ <line hits="0" number="399"/>
+ <line hits="0" number="401"/>
+ <line hits="0" number="402"/>
+ <line hits="0" number="403"/>
+ <line hits="0" number="404"/>
+ <line hits="0" number="406"/>
+ <line hits="0" number="408"/>
+ <line hits="0" number="409"/>
+ <line hits="0" number="411"/>
+ <line hits="0" number="413"/>
+ <line hits="0" number="416"/>
+ <line hits="0" number="418"/>
+ <line hits="0" number="419"/>
+ <line hits="0" number="423"/>
+ <line hits="0" number="424"/>
+ <line hits="0" number="425"/>
+ <line hits="0" number="426"/>
+ <line hits="0" number="428"/>
+ <line hits="0" number="429"/>
+ <line hits="0" number="430"/>
+ <line hits="0" number="431"/>
+ <line hits="0" number="434"/>
+ <line hits="0" number="435"/>
+ <line hits="0" number="436"/>
+ <line hits="0" number="438"/>
+ <line hits="0" number="439"/>
+ <line hits="0" number="441"/>
+ <line hits="0" number="442"/>
+ <line hits="0" number="444"/>
+ <line hits="0" number="446"/>
+ <line hits="0" number="447"/>
+ <line hits="0" number="448"/>
+ <line hits="0" number="449"/>
+ <line hits="0" number="451"/>
+ <line hits="0" number="452"/>
+ <line hits="0" number="454"/>
+ <line hits="0" number="455"/>
+ <line hits="0" number="462"/>
+ <line hits="0" number="480"/>
+ <line hits="0" number="482"/>
+ <line hits="0" number="485"/>
+ <line hits="0" number="486"/>
+ <line hits="0" number="487"/>
+ <line hits="0" number="489"/>
+ <line hits="0" number="490"/>
+ <line hits="0" number="491"/>
+ <line hits="0" number="493"/>
+ <line hits="0" number="494"/>
+ <line hits="0" number="495"/>
+ <line hits="0" number="496"/>
+ <line hits="0" number="500"/>
+ <line hits="0" number="502"/>
+ <line hits="0" number="503"/>
+ <line hits="0" number="504"/>
+ <line hits="0" number="505"/>
+ <line hits="0" number="507"/>
+ <line hits="0" number="511"/>
+ <line hits="0" number="512"/>
+ <line hits="0" number="517"/>
+ <line hits="0" number="538"/>
+ <line hits="0" number="539"/>
+ <line hits="0" number="542"/>
+ <line hits="0" number="554"/>
+ <line hits="0" number="555"/>
+ <line hits="0" number="556"/>
+ <line hits="0" number="559"/>
+ <line hits="0" number="560"/>
+ <line hits="0" number="561"/>
+ <line hits="0" number="565"/>
+ <line hits="0" number="569"/>
+ <line hits="0" number="573"/>
+ <line hits="0" number="576"/>
+ <line hits="0" number="581"/>
+ <line hits="0" number="586"/>
+ <line hits="0" number="588"/>
+ <line hits="0" number="589"/>
+ <line hits="0" number="592"/>
+ <line hits="0" number="593"/>
+ <line hits="0" number="595"/>
+ <line hits="0" number="596"/>
+ <line hits="0" number="597"/>
+ <line hits="0" number="598"/>
+ <line hits="0" number="599"/>
+ <line hits="0" number="600"/>
+ <line hits="0" number="602"/>
+ <line hits="0" number="604"/>
+ <line hits="0" number="607"/>
+ <line hits="0" number="610"/>
+ <line hits="0" number="611"/>
+ <line hits="0" number="613"/>
+ <line hits="0" number="615"/>
+ <line hits="0" number="616"/>
+ <line hits="0" number="617"/>
+ <line hits="0" number="618"/>
+ <line hits="0" number="620"/>
+ <line hits="0" number="627"/>
+ <line hits="0" number="629"/>
+ <line hits="0" number="631"/>
+ <line hits="0" number="635"/>
+ <line hits="0" number="638"/>
+ <line hits="0" number="639"/>
+ <line hits="0" number="642"/>
+ <line hits="0" number="643"/>
+ <line hits="0" number="646"/>
+ <line hits="0" number="649"/>
+ <line hits="0" number="652"/>
+ <line hits="0" number="653"/>
+ <line hits="0" number="655"/>
+ <line hits="0" number="665"/>
+ <line hits="0" number="668"/>
+ <line hits="0" number="669"/>
+ <line hits="0" number="670"/>
+ <line hits="0" number="671"/>
+ <line hits="0" number="674"/>
+ <line hits="0" number="677"/>
+ <line hits="0" number="678"/>
+ <line hits="0" number="679"/>
+ <line hits="0" number="680"/>
+ <line hits="0" number="683"/>
+ <line hits="0" number="685"/>
+ <line hits="0" number="686"/>
+ <line hits="0" number="687"/>
+ <line hits="0" number="688"/>
+ <line hits="0" number="691"/>
+ <line hits="0" number="694"/>
+ <line hits="0" number="696"/>
+ <line hits="0" number="697"/>
+ <line hits="0" number="698"/>
+ <line hits="0" number="701"/>
+ <line hits="0" number="705"/>
+ <line hits="0" number="713"/>
+ <line hits="0" number="714"/>
+ <line hits="0" number="715"/>
+ <line hits="0" number="717"/>
+ <line hits="0" number="718"/>
+ <line hits="0" number="724"/>
+ <line hits="0" number="725"/>
+ <line hits="0" number="727"/>
+ <line hits="0" number="728"/>
+ <line hits="0" number="729"/>
+ <line hits="0" number="731"/>
+ <line hits="0" number="732"/>
+ <line hits="0" number="733"/>
+ <line hits="0" number="734"/>
+ <line hits="0" number="747"/>
+ <line hits="0" number="748"/>
+ <line hits="0" number="749"/>
+ <line hits="0" number="751"/>
+ <line hits="0" number="752"/>
+ <line hits="0" number="758"/>
+ <line hits="0" number="759"/>
+ <line hits="0" number="761"/>
+ <line hits="0" number="762"/>
+ <line hits="0" number="763"/>
+ <line hits="0" number="765"/>
+ <line hits="0" number="766"/>
+ <line hits="0" number="767"/>
+ <line hits="0" number="768"/>
+ <line hits="0" number="778"/>
+ <line hits="0" number="781"/>
+ <line hits="0" number="787"/>
+ <line hits="0" number="794"/>
+ <line hits="0" number="796"/>
+ <line hits="0" number="799"/>
+ <line hits="0" number="800"/>
+ <line hits="0" number="801"/>
+ <line hits="0" number="802"/>
+ <line hits="0" number="803"/>
+ <line hits="0" number="804"/>
+ </lines>
+ </class>
+ </classes>
+ </package>
+ <package branch-rate="0" complexity="0" line-rate="0.1466" name="mod">
+ <classes>
+ <class branch-rate="0" complexity="0" filename="mod/__init__.py" line-rate="1" name="__init__.py">
+ <methods/>
+ <lines/>
+ </class>
+ <class branch-rate="0" complexity="0" filename="mod/trapd_exit.py" line-rate="1" name="trapd_exit.py">
+ <methods/>
+ <lines>
+ <line hits="1" number="21"/>
+ <line hits="1" number="26"/>
+ <line hits="1" number="28"/>
+ <line hits="1" number="29"/>
+ <line hits="1" number="30"/>
+ <line hits="1" number="31"/>
+ <line hits="1" number="33"/>
+ <line hits="1" number="41"/>
+ <line hits="1" number="59"/>
+ <line hits="1" number="61"/>
+ <line hits="1" number="62"/>
+ <line hits="1" number="63"/>
+ </lines>
+ </class>
+ <class branch-rate="0" complexity="0" filename="mod/trapd_file_utils.py" line-rate="0" name="trapd_file_utils.py">
+ <methods/>
+ <lines>
+ <line hits="0" number="21"/>
+ <line hits="0" number="24"/>
+ <line hits="0" number="27"/>
+ <line hits="0" number="28"/>
+ <line hits="0" number="29"/>
+ <line hits="0" number="30"/>
+ <line hits="0" number="31"/>
+ <line hits="0" number="32"/>
+ <line hits="0" number="33"/>
+ <line hits="0" number="34"/>
+ <line hits="0" number="35"/>
+ <line hits="0" number="36"/>
+ <line hits="0" number="37"/>
+ <line hits="0" number="38"/>
+ <line hits="0" number="41"/>
+ <line hits="0" number="42"/>
+ <line hits="0" number="43"/>
+ <line hits="0" number="45"/>
+ <line hits="0" number="53"/>
+ <line hits="0" number="61"/>
+ <line hits="0" number="63"/>
+ <line hits="0" number="65"/>
+ <line hits="0" number="67"/>
+ <line hits="0" number="68"/>
+ <line hits="0" number="69"/>
+ <line hits="0" number="70"/>
+ <line hits="0" number="72"/>
+ <line hits="0" number="73"/>
+ <line hits="0" number="74"/>
+ <line hits="0" number="75"/>
+ <line hits="0" number="77"/>
+ <line hits="0" number="78"/>
+ <line hits="0" number="79"/>
+ <line hits="0" number="80"/>
+ <line hits="0" number="81"/>
+ <line hits="0" number="84"/>
+ <line hits="0" number="86"/>
+ <line hits="0" number="87"/>
+ <line hits="0" number="88"/>
+ <line hits="0" number="89"/>
+ <line hits="0" number="91"/>
+ <line hits="0" number="92"/>
+ <line hits="0" number="95"/>
+ <line hits="0" number="97"/>
+ <line hits="0" number="98"/>
+ <line hits="0" number="99"/>
+ <line hits="0" number="100"/>
+ <line hits="0" number="102"/>
+ <line hits="0" number="103"/>
+ <line hits="0" number="112"/>
+ <line hits="0" number="117"/>
+ <line hits="0" number="120"/>
+ <line hits="0" number="122"/>
+ <line hits="0" number="124"/>
+ <line hits="0" number="125"/>
+ <line hits="0" number="126"/>
+ <line hits="0" number="127"/>
+ <line hits="0" number="129"/>
+ <line hits="0" number="130"/>
+ <line hits="0" number="132"/>
+ <line hits="0" number="134"/>
+ <line hits="0" number="135"/>
+ <line hits="0" number="136"/>
+ <line hits="0" number="137"/>
+ <line hits="0" number="139"/>
+ <line hits="0" number="140"/>
+ <line hits="0" number="142"/>
+ <line hits="0" number="143"/>
+ <line hits="0" number="144"/>
+ <line hits="0" number="145"/>
+ <line hits="0" number="146"/>
+ <line hits="0" number="148"/>
+ <line hits="0" number="149"/>
+ <line hits="0" number="151"/>
+ <line hits="0" number="152"/>
+ <line hits="0" number="153"/>
+ <line hits="0" number="154"/>
+ <line hits="0" number="155"/>
+ <line hits="0" number="157"/>
+ <line hits="0" number="164"/>
+ <line hits="0" number="169"/>
+ <line hits="0" number="173"/>
+ <line hits="0" number="176"/>
+ <line hits="0" number="177"/>
+ <line hits="0" number="178"/>
+ <line hits="0" number="179"/>
+ <line hits="0" number="180"/>
+ <line hits="0" number="183"/>
+ <line hits="0" number="192"/>
+ <line hits="0" number="197"/>
+ <line hits="0" number="200"/>
+ <line hits="0" number="201"/>
+ <line hits="0" number="202"/>
+ <line hits="0" number="203"/>
+ <line hits="0" number="204"/>
+ <line hits="0" number="205"/>
+ <line hits="0" number="211"/>
+ <line hits="0" number="216"/>
+ <line hits="0" number="218"/>
+ <line hits="0" number="219"/>
+ <line hits="0" number="220"/>
+ <line hits="0" number="221"/>
+ <line hits="0" number="222"/>
+ <line hits="0" number="224"/>
+ <line hits="0" number="225"/>
+ </lines>
+ </class>
+ <class branch-rate="0" complexity="0" filename="mod/trapd_get_cbs_config.py" line-rate="0" name="trapd_get_cbs_config.py">
+ <methods/>
+ <lines>
+ <line hits="0" number="21"/>
+ <line hits="0" number="27"/>
+ <line hits="0" number="29"/>
+ <line hits="0" number="30"/>
+ <line hits="0" number="31"/>
+ <line hits="0" number="32"/>
+ <line hits="0" number="33"/>
+ <line hits="0" number="34"/>
+ <line hits="0" number="35"/>
+ <line hits="0" number="37"/>
+ <line hits="0" number="38"/>
+ <line hits="0" number="39"/>
+ <line hits="0" number="40"/>
+ <line hits="0" number="42"/>
+ <line hits="0" number="50"/>
+ <line hits="0" number="58"/>
+ <line hits="0" number="61"/>
+ <line hits="0" number="62"/>
+ <line hits="0" number="63"/>
+ <line hits="0" number="64"/>
+ <line hits="0" number="65"/>
+ <line hits="0" number="68"/>
+ <line hits="0" number="69"/>
+ <line hits="0" number="70"/>
+ <line hits="0" number="72"/>
+ <line hits="0" number="73"/>
+ <line hits="0" number="74"/>
+ <line hits="0" number="75"/>
+ <line hits="0" number="76"/>
+ <line hits="0" number="77"/>
+ <line hits="0" number="79"/>
+ <line hits="0" number="80"/>
+ <line hits="0" number="81"/>
+ <line hits="0" number="82"/>
+ <line hits="0" number="84"/>
+ <line hits="0" number="86"/>
+ <line hits="0" number="87"/>
+ <line hits="0" number="88"/>
+ <line hits="0" number="89"/>
+ <line hits="0" number="90"/>
+ <line hits="0" number="92"/>
+ <line hits="0" number="93"/>
+ <line hits="0" number="96"/>
+ <line hits="0" number="97"/>
+ <line hits="0" number="98"/>
+ <line hits="0" number="99"/>
+ <line hits="0" number="102"/>
+ <line hits="0" number="103"/>
+ <line hits="0" number="104"/>
+ <line hits="0" number="105"/>
+ <line hits="0" number="108"/>
+ <line hits="0" number="109"/>
+ <line hits="0" number="110"/>
+ <line hits="0" number="111"/>
+ <line hits="0" number="113"/>
+ <line hits="0" number="114"/>
+ <line hits="0" number="115"/>
+ <line hits="0" number="116"/>
+ <line hits="0" number="118"/>
+ </lines>
+ </class>
+ <class branch-rate="0" complexity="0" filename="mod/trapd_http_session.py" line-rate="0.8333" name="trapd_http_session.py">
+ <methods/>
+ <lines>
+ <line hits="1" number="21"/>
+ <line hits="1" number="26"/>
+ <line hits="1" number="28"/>
+ <line hits="1" number="29"/>
+ <line hits="1" number="30"/>
+ <line hits="1" number="32"/>
+ <line hits="1" number="38"/>
+ <line hits="1" number="53"/>
+ <line hits="1" number="54"/>
+ <line hits="0" number="55"/>
+ <line hits="0" number="56"/>
+ <line hits="1" number="58"/>
+ </lines>
+ </class>
+ <class branch-rate="0" complexity="0" filename="mod/trapd_logging.py" line-rate="0" name="trapd_logging.py">
+ <methods/>
+ <lines>
+ <line hits="0" number="21"/>
+ <line hits="0" number="24"/>
+ <line hits="0" number="27"/>
+ <line hits="0" number="28"/>
+ <line hits="0" number="29"/>
+ <line hits="0" number="30"/>
+ <line hits="0" number="31"/>
+ <line hits="0" number="32"/>
+ <line hits="0" number="33"/>
+ <line hits="0" number="34"/>
+ <line hits="0" number="35"/>
+ <line hits="0" number="36"/>
+ <line hits="0" number="37"/>
+ <line hits="0" number="38"/>
+ <line hits="0" number="40"/>
+ <line hits="0" number="42"/>
+ <line hits="0" number="50"/>
+ <line hits="0" number="124"/>
+ <line hits="0" number="132"/>
+ <line hits="0" number="133"/>
+ <line hits="0" number="140"/>
+ <line hits="0" number="141"/>
+ <line hits="0" number="142"/>
+ <line hits="0" number="144"/>
+ <line hits="0" number="145"/>
+ <line hits="0" number="147"/>
+ <line hits="0" number="149"/>
+ <line hits="0" number="150"/>
+ <line hits="0" number="152"/>
+ <line hits="0" number="153"/>
+ <line hits="0" number="155"/>
+ <line hits="0" number="157"/>
+ <line hits="0" number="158"/>
+ <line hits="0" number="160"/>
+ <line hits="0" number="162"/>
+ <line hits="0" number="170"/>
+ <line hits="0" number="172"/>
+ <line hits="0" number="174"/>
+ <line hits="0" number="181"/>
+ <line hits="0" number="196"/>
+ <line hits="0" number="199"/>
+ </lines>
+ </class>
+ <class branch-rate="0" complexity="0" filename="mod/trapd_runtime_pid.py" line-rate="0.8846" name="trapd_runtime_pid.py">
+ <methods/>
+ <lines>
+ <line hits="1" number="21"/>
+ <line hits="1" number="26"/>
+ <line hits="1" number="28"/>
+ <line hits="1" number="29"/>
+ <line hits="1" number="30"/>
+ <line hits="1" number="31"/>
+ <line hits="1" number="32"/>
+ <line hits="1" number="34"/>
+ <line hits="1" number="40"/>
+ <line hits="1" number="54"/>
+ <line hits="1" number="55"/>
+ <line hits="1" number="56"/>
+ <line hits="1" number="57"/>
+ <line hits="1" number="58"/>
+ <line hits="1" number="59"/>
+ <line hits="1" number="60"/>
+ <line hits="1" number="66"/>
+ <line hits="1" number="72"/>
+ <line hits="1" number="85"/>
+ <line hits="1" number="86"/>
+ <line hits="1" number="87"/>
+ <line hits="1" number="88"/>
+ <line hits="1" number="90"/>
+ <line hits="0" number="92"/>
+ <line hits="0" number="93"/>
+ <line hits="0" number="94"/>
+ </lines>
+ </class>
+ <class branch-rate="0" complexity="0" filename="mod/trapd_settings.py" line-rate="0" name="trapd_settings.py">
+ <methods/>
+ <lines>
+ <line hits="0" number="21"/>
+ <line hits="0" number="24"/>
+ <line hits="0" number="27"/>
+ <line hits="0" number="32"/>
+ <line hits="0" number="43"/>
+ <line hits="0" number="45"/>
+ <line hits="0" number="50"/>
+ <line hits="0" number="52"/>
+ <line hits="0" number="55"/>
+ <line hits="0" number="57"/>
+ <line hits="0" number="60"/>
+ <line hits="0" number="62"/>
+ <line hits="0" number="65"/>
+ <line hits="0" number="67"/>
+ <line hits="0" number="70"/>
+ <line hits="0" number="72"/>
+ <line hits="0" number="74"/>
+ <line hits="0" number="79"/>
+ <line hits="0" number="81"/>
+ <line hits="0" number="83"/>
+ <line hits="0" number="85"/>
+ <line hits="0" number="87"/>
+ <line hits="0" number="89"/>
+ <line hits="0" number="94"/>
+ <line hits="0" number="96"/>
+ <line hits="0" number="98"/>
+ <line hits="0" number="100"/>
+ <line hits="0" number="102"/>
+ <line hits="0" number="104"/>
+ <line hits="0" number="106"/>
+ <line hits="0" number="108"/>
+ <line hits="0" number="113"/>
+ <line hits="0" number="118"/>
+ <line hits="0" number="120"/>
+ <line hits="0" number="125"/>
+ <line hits="0" number="127"/>
+ <line hits="0" number="132"/>
+ <line hits="0" number="141"/>
+ <line hits="0" number="142"/>
+ <line hits="0" number="143"/>
+ <line hits="0" number="144"/>
+ <line hits="0" number="145"/>
+ <line hits="0" number="146"/>
+ <line hits="0" number="155"/>
+ <line hits="0" number="156"/>
+ <line hits="0" number="157"/>
+ <line hits="0" number="158"/>
+ <line hits="0" number="159"/>
+ <line hits="0" number="160"/>
+ <line hits="0" number="161"/>
+ <line hits="0" number="164"/>
+ <line hits="0" number="167"/>
+ </lines>
+ </class>
+ </classes>
+ </package>
+ </packages>
+</coverage>
diff --git a/pom.xml b/pom.xml
index 17b54e7..5ce191a 100644
--- a/pom.xml
+++ b/pom.xml
@@ -34,7 +34,7 @@ ECOMP is a trademark and service mark of AT&T Intellectual Property.
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <sonar.skip>true</sonar.skip>
+ <sonar.skip>false</sonar.skip>
<sonar.sources>.</sonar.sources>
<!-- customize the SONARQUBE URL -->
<!-- sonar.host.url>http://localhost:9000</sonar.host.url -->
@@ -43,6 +43,7 @@ ECOMP is a trademark and service mark of AT&T Intellectual Property.
<sonar.language>py</sonar.language>
<sonar.pluginName>Python</sonar.pluginName>
<sonar.inclusions>**/*.py</sonar.inclusions>
+ <sonar.exclusions>target/**,tests/**,setup.py,**/__init__.py</sonar.exclusions>
<!-- for JavaScaript -->
<!--
<sonar.language>js</sonar.language>
diff --git a/setup.py b/setup.py
index 54b785d..edb5aa3 100644
--- a/setup.py
+++ b/setup.py
@@ -20,19 +20,23 @@
import os
import string
import sys
+import setuptools
+from setuptools import setup, find_packages
-install_reqs = parse_requirements("requirements.txt", session=PipSession())
-reqs = [str(ir.req) for ir in install_reqs]
setup(
- name = "dcaegen2-collectors-snmptrap",
+ name = "snmptrap",
description = "snmp trap receiver for ONAP docker image",
version = "1.3.0",
packages=find_packages(),
+ install_requires=[
+ "pysnmp==4.4.2",
+ "requests==2.18.3",
+ "onap_dcae_cbs_docker_client==0.0.3"
+ ],
author = "Dave L",
author_email = "dl3158@att.com",
license='Apache 2',
keywords = "",
- url = "",
- install_requires=reqs
+ url = ""
)
diff --git a/snmptrap/__init__.py b/snmptrap/__init__.py
new file mode 100644
index 0000000..1875bf6
--- /dev/null
+++ b/snmptrap/__init__.py
@@ -0,0 +1,21 @@
+# ================================================================================
+# Copyright (c) 2018 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=========================================================
+#
+# 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/snmptrap/mod/__init__.py b/snmptrap/mod/__init__.py
new file mode 100644
index 0000000..1875bf6
--- /dev/null
+++ b/snmptrap/mod/__init__.py
@@ -0,0 +1,21 @@
+# ================================================================================
+# Copyright (c) 2018 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=========================================================
+#
+# 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/bin/mod/trapd_exit.py b/snmptrap/mod/trapd_exit.py
index a7ffc8a..ef7a2ae 100644
--- a/bin/mod/trapd_exit.py
+++ b/snmptrap/mod/trapd_exit.py
@@ -56,8 +56,8 @@ def cleanup_and_exit(_loc_exit_code, _pid_file_name):
number of parameters passed to module
"""
- _num_params = len(locals())
+ # _num_params = len(locals())
- if _num_params == 2:
+ if _pid_file_name is not None:
rc = rm_pid(_pid_file_name)
sys.exit(_loc_exit_code)
diff --git a/bin/mod/trapd_get_cbs_config.py b/snmptrap/mod/trapd_get_cbs_config.py
index e0f5ca8..524f1c2 100644
--- a/bin/mod/trapd_get_cbs_config.py
+++ b/snmptrap/mod/trapd_get_cbs_config.py
@@ -37,7 +37,7 @@ import collections
import trapd_settings as tds
from onap_dcae_cbs_docker_client.client import get_config
from trapd_exit import cleanup_and_exit
-from trapd_logging import stdout_logger
+from trapd_io import stdout_logger
prog_name = os.path.basename(__file__)
@@ -74,12 +74,12 @@ def get_cbs_config():
except Exception as e:
msg = "CBS_SIM_JSON not defined - FATAL ERROR, exiting"
stdout_logger(msg)
- cleanup_and_exit(1, pid_file_name)
+ cleanup_and_exit(1,None)
if _cbs_sim_json_file == "None":
msg = "CBS_SIM_JSON not defined - FATAL ERROR, exiting"
stdout_logger(msg)
- cleanup_and_exit(1, pid_file_name)
+ cleanup_and_exit(1,None)
else:
msg = ("ONAP controller override specified via CBS_SIM_JSON: %s" %
_cbs_sim_json_file)
@@ -90,7 +90,7 @@ def get_cbs_config():
msg = "Unable to load CBS_SIM_JSON " + _cbs_sim_json_file + \
" (invalid json?) - FATAL ERROR, exiting"
stdout_logger(msg)
- cleanup_and_exit(1, tds.pid_file_name)
+ cleanup_and_exit(1,None)
# recalc timeout, set default if not present
try:
diff --git a/bin/mod/trapd_http_session.py b/snmptrap/mod/trapd_http_session.py
index b34c19d..b34c19d 100644
--- a/bin/mod/trapd_http_session.py
+++ b/snmptrap/mod/trapd_http_session.py
diff --git a/bin/mod/trapd_file_utils.py b/snmptrap/mod/trapd_io.py
index e62b528..8667750 100644
--- a/bin/mod/trapd_file_utils.py
+++ b/snmptrap/mod/trapd_io.py
@@ -39,7 +39,6 @@ import unicodedata
# dcae_snmptrap
import trapd_settings as tds
-from trapd_logging import ecomp_logger, stdout_logger
from trapd_exit import cleanup_and_exit
prog_name = os.path.basename(__file__)
@@ -223,3 +222,175 @@ def close_file(_loc_fd, _loc_filename):
_loc_filename, str(e))
ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_FATAL, tds.CODE_GENERAL, msg)
return False
+
+# # # # # # # # # # # # # # # # # # #
+# fx: ecomp_logger -> log in eelf format until standard
+# is released for python via LOG-161
+# # # # # # # # # # ## # # # # # # #
+
+def ecomp_logger(_log_type, _sev, _error_code, _msg):
+ """
+ Log to ecomp-style logfiles. Logs include:
+
+ Note: this will be updated when https://jira.onap.org/browse/LOG-161
+ is closed/available; until then, we resort to a generic format with
+ valuable info in "extra=" field (?)
+
+ :Parameters:
+ _msg -
+ :Exceptions:
+ none
+ :Keywords:
+ eelf logging
+ :Log Styles:
+
+ :error.log:
+
+ if CommonLogger.verbose: print("using CommonLogger.ErrorFile")
+ self._logger.log(50, '%s|%s|%s|%s|%s|%s|%s|%s|%s|%s' \
+ % (requestID, threadID, serviceName, partnerName, targetEntity, targetServiceName,
+ errorCategory, errorCode, errorDescription, detailMessage))
+
+ error.log example:
+
+ 2018-02-20T07:21:34,007+00:00||MainThread|snmp_log_monitor||||FATAL|900||Tue Feb 20 07:21:11 UTC 2018 CRITICAL: [a0cae74e-160e-11e8-8f9f-0242ac110002] ALL publish attempts failed to DMAPP server: dcae-mrtr-zltcrdm5bdce1.1dff83.rdm5b.tci.att.com, topic: DCAE-COLLECTOR-UCSNMP, 339 trap(s) not published in epoch_serno range: 15191112530000 - 15191112620010
+
+ :debug.log:
+
+ if CommonLogger.verbose: print("using CommonLogger.DebugFile")
+ self._logger.log(50, '%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s' \
+ % (requestID, threadID, serverName, serviceName, instanceUUID, upperLogLevel,
+ severity, serverIPAddress, server, IPAddress, className, timer, detailMessage))
+
+ debug.log example:
+
+ none available
+
+ :audit.log:
+
+ if CommonLogger.verbose: print("using CommonLogger.AuditFile")
+ endAuditTime, endAuditMsec = self._getTime()
+ if self._begTime is not None:
+ d = {'begtime': self._begTime, 'begmsecs': self._begMsec, 'endtime': endAuditTime,
+ 'endmsecs': endAuditMsec}
+ else:
+ d = {'begtime': endAuditTime, 'begmsecs': endAuditMsec, 'endtime': endAuditTime,
+ 'endmsecs': endAuditMsec}
+
+ self._logger.log(50, '%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s' \
+ % (requestID, serviceInstanceID, threadID, serverName, serviceName, partnerName,
+ statusCode, responseCode, responseDescription, instanceUUID, upperLogLevel,
+ severity, serverIPAddress, timer, server, IPAddress, className, unused,
+ processKey, customField1, customField2, customField3, customField4,
+ detailMessage), extra=d)
+
+
+ :metrics.log:
+
+ self._logger.log(50,'%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s|%s' \
+ % (requestID, serviceInstanceID, threadID, serverName, serviceName, partnerName,
+ targetEntity, targetServiceName, statusCode, responseCode, responseDescription,
+ instanceUUID, upperLogLevel, severity, serverIPAddress, timer, server,
+ IPAddress,
+ className, unused, processKey, targetVirtualEntity, customField1, customField2,
+ customField3, customField4, detailMessage), extra=d)
+
+ metrics.log example:
+
+ none available
+
+
+ """
+
+ unused = ""
+
+ # ct = time.time()
+ # lt = time.localtime(ct)
+ # t_hman = time.strftime(DateFmt, lt)
+ # t_ms = (ct - int(ct)) * 1000
+ # above were various attempts at setting time string found in other
+ # libs; instead, let's keep it real:
+ t_out = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S,%f")[:-3]
+ calling_fx = inspect.stack()[1][3]
+
+ # FIXME: this entire module is a hack to override concept of prog logging
+ # written across multiple files (???), making diagnostics IMPOSSIBLE!
+ # Hoping to leverage ONAP logging libraries & standards when available
+
+ # catch invalid log type
+ if _log_type < 1 or _log_type > 5:
+ msg = ("INVALID log type: %s " % _log_type)
+ _out_rec = ("%s|%s|%s|%s|%s|%s|%s|%s|%s"
+ % ((calling_fx, "snmptrapd", unused, unused, unused, tds.SEV_TYPES[_sev], _error_code, unused, (msg + _msg))))
+ try:
+ tds.eelf_error_fd.write('%s|%s\n' % (t_out, str(_out_rec)))
+ except Exception as e:
+ stdout_logger(str(_out_rec))
+
+ return False
+
+ if _sev >= tds.minimum_severity_to_log:
+ # log to appropriate eelf log (different files ??)
+ if _log_type == tds.LOG_TYPE_ERROR:
+ _out_rec = ('%s|%s|%s|%s|%s|%s|%s|%s|%s'
+ % ((calling_fx, "snmptrapd", unused, unused, unused, tds.SEV_TYPES[_sev], _error_code, unused, _msg)))
+ try:
+ tds.eelf_error_fd.write('%s|%s\n' % (t_out, str(_out_rec)))
+ except Exception as e:
+ stdout_logger(str(_out_rec))
+ elif _log_type == tds.LOG_TYPE_AUDIT:
+ # log message in AUDIT format
+ _out_rec = ('%s|%s|%s|%s|%s|%s|%s|%s|%s'
+ % ((calling_fx, "snmptrapd", unused, unused, unused, tds.SEV_TYPES[_sev], _error_code, unused, _msg)))
+ try:
+ tds.eelf_audit_fd.write('%s|%s\n' % (t_out, str(_out_rec)))
+ except Exception as e:
+ stdout_logger(str(_out_rec))
+ elif _log_type == tds.LOG_TYPE_METRICS:
+ # log message in METRICS format
+ _out_rec = ('%s|%s|%s|%s|%s|%s|%s|%s|%s'
+ % ((calling_fx, "snmptrapd", unused, unused, unused, tds.SEV_TYPES[_sev], _error_code, unused, _msg)))
+ try:
+ tds.eelf_metrics_fd.write('%s|%s\n' % (t_out, str(_out_rec)))
+ except Exception as e:
+ stdout_logger(str(_out_rec))
+
+ # DEBUG *AND* others - there *MUST BE* a single time-sequenced log for diagnostics!
+ # FIXME: too much I/O !!!
+ # always write to debug; we need ONE logfile that has time-sequence full view !!!
+ # if (_log_type == tds.LOG_TYPE_DEBUG and _sev >= tds.current_min_sev_log_level) or (_log_type != tds.LOG_TYPE_DEBUG):
+
+ # log message in DEBUG format
+ _out_rec = ("%s|%s|%s|%s|%s|%s|%s|%s|%s"
+ % ((calling_fx, "snmptrapd", unused, unused, unused, tds.SEV_TYPES[_sev], _error_code, unused, _msg)))
+ try:
+ tds.eelf_debug_fd.write('%s|%s\n' % (t_out, str(_out_rec)))
+ except Exception as e:
+ stdout_logger(str(_out_rec))
+
+ return True
+
+# # # # # # # # # # # # #
+# fx: stdout_logger
+# # # # # # # # # # # # #
+
+
+def stdout_logger(_msg):
+ """
+ Log info/errors to stdout. This is done:
+ - for critical runtime issues
+
+ :Parameters:
+ _msg
+ message to print
+ :Exceptions:
+ none
+ :Keywords:
+ log stdout
+ :Variables:
+ """
+
+ t_out = datetime.datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S,%f")[:-3]
+ # calling_fx = inspect.stack()[1][3]
+
+ print('%s %s' % (t_out, _msg))
diff --git a/bin/mod/trapd_logging.py b/snmptrap/mod/trapd_logging.py
index ae5a1a0..ae5a1a0 100644
--- a/bin/mod/trapd_logging.py
+++ b/snmptrap/mod/trapd_logging.py
diff --git a/bin/mod/trapd_runtime_pid.py b/snmptrap/mod/trapd_runtime_pid.py
index c6ef76e..c6ef76e 100644
--- a/bin/mod/trapd_runtime_pid.py
+++ b/snmptrap/mod/trapd_runtime_pid.py
diff --git a/bin/mod/trapd_settings.py b/snmptrap/mod/trapd_settings.py
index be87e26..be87e26 100644
--- a/bin/mod/trapd_settings.py
+++ b/snmptrap/mod/trapd_settings.py
diff --git a/bin/snmptrapd.py b/snmptrap/snmptrapd.py
index 3765746..9cf828c 100644
--- a/bin/snmptrapd.py
+++ b/snmptrap/snmptrapd.py
@@ -73,8 +73,7 @@ from trapd_get_cbs_config import get_cbs_config
from trapd_exit import cleanup_and_exit
from trapd_http_session import init_session_obj
-from trapd_file_utils import roll_all_logs, open_eelf_logs, roll_file, open_file, close_file
-from trapd_logging import ecomp_logger, stdout_logger
+from trapd_io import roll_all_logs, open_eelf_logs, roll_file, open_file, close_file, ecomp_logger, stdout_logger
prog_name = os.path.basename(__file__)
verbose = False
@@ -146,7 +145,18 @@ def load_all_configs(_signum, _frame):
msg = "error (re)loading CBS config - FATAL ERROR, exiting"
stdout_logger(msg)
cleanup_and_exit(1, tds.pid_file_name)
+ else:
+ current_runtime_config_file_name = tds.c_config['files.runtime_base_dir'] + \
+ "/tmp/current_config.json"
+
+ msg = "current config logged to : %s" % current_runtime_config_file_name
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+
+ with open(current_runtime_config_file_name, 'w') as outfile:
+ json.dump(tds.c_config, outfile)
+ # if here, config re-read successfully
+ return True
# # # # # # # # # # # # #
# fx: log_all_arriving_traps
@@ -624,181 +634,184 @@ def notif_receiver_cb(snmp_engine, stateReference, contextEngineId, contextName,
# Main MAIN Main MAIN
# # # # # # # # # # # # #
# parse command line args
-parser = argparse.ArgumentParser(description='Post SNMP traps '
- 'to message bus')
-parser.add_argument('-v', action="store_true", dest="verbose",
- help="verbose logging")
-parser.add_argument('-?', action="store_true", dest="usage_requested",
- help="show command line use")
-
-# parse args
-args = parser.parse_args()
-
-# set vars from args
-verbose = args.verbose
-usage_requested = args.usage_requested
-# if usage, just display and exit
-if usage_requested:
- usage_err()
-
-# init vars
-tds.init()
-
-# Set initial startup hour for rolling logfile
-tds.last_hour = datetime.datetime.now().hour
-
-# get config binding service (CBS) values (either broker, or json file override)
-load_all_configs(0, 0)
-msg = "%s : %s version %s starting" % (
- prog_name, tds.c_config['snmptrap.title'], tds.c_config['snmptrap.version'])
-stdout_logger(msg)
-
-# Avoid this unless needed for testing; it prints sensitive data to log
-#
-# msg = "Running config: "
-# stdout_logger(msg)
-# msg = json.dumps(c_config, sort_keys=False, indent=4)
-# stdout_logger(msg)
-
-# open various ecomp logs
-open_eelf_logs()
-
-# bump up logging level if overridden at command line
-if verbose:
- msg = "WARNING: '-v' argument present. All messages will be logged. This can slow things down, use only when needed."
- tds.minimum_severity_to_log = 0
+if __name__ == "__main__":
+
+ parser = argparse.ArgumentParser(description='Post SNMP traps '
+ 'to message bus')
+ parser.add_argument('-v', action="store_true", dest="verbose",
+ help="verbose logging")
+ parser.add_argument('-?', action="store_true", dest="usage_requested",
+ help="show command line use")
+
+ # parse args
+ args = parser.parse_args()
+
+ # set vars from args
+ verbose = args.verbose
+ usage_requested = args.usage_requested
+
+ # if usage, just display and exit
+ if usage_requested:
+ usage_err()
+
+ # init vars
+ tds.init()
+
+ # Set initial startup hour for rolling logfile
+ tds.last_hour = datetime.datetime.now().hour
+
+ # get config binding service (CBS) values (either broker, or json file override)
+ load_all_configs(0, 0)
+ msg = "%s : %s version %s starting" % (
+ prog_name, tds.c_config['snmptrap.title'], tds.c_config['snmptrap.version'])
stdout_logger(msg)
-
-# name and open arriving trap log
-tds.arriving_traps_filename = tds.c_config['files.runtime_base_dir'] + "/" + \
- tds.c_config['files.log_dir'] + "/" + \
- (tds.c_config['files.arriving_traps_log'])
-tds.arriving_traps_fd = open_file(tds.arriving_traps_filename)
-msg = ("arriving traps logged to: %s" % tds.arriving_traps_filename)
-stdout_logger(msg)
-ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
-
-# name and open json trap log
-tds.json_traps_filename = tds.c_config['files.runtime_base_dir'] + "/" + tds.c_config['files.log_dir'] + "/" + "DMAAP_" + (
- tds.c_config['streams_publishes']['sec_fault_unsecure']['dmaap_info']['topic_url'].split('/')[-1]) + ".json"
-tds.json_traps_fd = open_file(tds.json_traps_filename)
-msg = ("published traps logged to: %s" % tds.json_traps_filename)
-stdout_logger(msg)
-ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
-
-# setup signal handling for config reload
-signal.signal(signal.SIGUSR1, load_all_configs)
-
-# save current PID for future/external reference
-tds.pid_file_name = tds.c_config['files.runtime_base_dir'] + \
- '/' + tds.c_config['files.pid_dir'] + '/' + prog_name + ".pid"
-msg = "Runtime PID file: %s" % tds.pid_file_name
-ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
-rc = save_pid(tds.pid_file_name)
-
-# Get the event loop for this thread
-loop = asyncio.get_event_loop()
-
-# Create SNMP engine with autogenernated engineID pre-bound
-# to socket transport dispatcher
-snmp_engine = engine.SnmpEngine()
-
-# # # # # # # # # # # #
-# Transport setup
-# # # # # # # # # # # #
-
-# UDP over IPv4
-# FIXME: add check for presense of ipv4_interface prior to attempting add OR just put entire thing in try/except clause
-try:
- ipv4_interface = tds.c_config['protocols.ipv4_interface']
- ipv4_port = tds.c_config['protocols.ipv4_port']
-
+
+ # Avoid this unless needed for testing; it prints sensitive data to log
+ #
+ # msg = "Running config: "
+ # stdout_logger(msg)
+ # msg = json.dumps(c_config, sort_keys=False, indent=4)
+ # stdout_logger(msg)
+
+ # open various ecomp logs
+ open_eelf_logs()
+
+ # bump up logging level if overridden at command line
+ if verbose:
+ msg = "WARNING: '-v' argument present. All diagnostic messages will be logged. This can slow things down, use only when needed."
+ tds.minimum_severity_to_log = 0
+ stdout_logger(msg)
+
+ # name and open arriving trap log
+ tds.arriving_traps_filename = tds.c_config['files.runtime_base_dir'] + "/" + \
+ tds.c_config['files.log_dir'] + "/" + \
+ (tds.c_config['files.arriving_traps_log'])
+ tds.arriving_traps_fd = open_file(tds.arriving_traps_filename)
+ msg = ("arriving traps logged to: %s" % tds.arriving_traps_filename)
+ stdout_logger(msg)
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+
+ # name and open json trap log
+ tds.json_traps_filename = tds.c_config['files.runtime_base_dir'] + "/" + tds.c_config['files.log_dir'] + "/" + "DMAAP_" + (
+ tds.c_config['streams_publishes']['sec_fault_unsecure']['dmaap_info']['topic_url'].split('/')[-1]) + ".json"
+ tds.json_traps_fd = open_file(tds.json_traps_filename)
+ msg = ("published traps logged to: %s" % tds.json_traps_filename)
+ stdout_logger(msg)
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+
+ # setup signal handling for config reload
+ signal.signal(signal.SIGUSR1, load_all_configs)
+
+ # save current PID for future/external reference
+ tds.pid_file_name = tds.c_config['files.runtime_base_dir'] + \
+ '/' + tds.c_config['files.pid_dir'] + '/' + prog_name + ".pid"
+ msg = "Runtime PID file: %s" % tds.pid_file_name
+ ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+ rc = save_pid(tds.pid_file_name)
+
+ # Get the event loop for this thread
+ loop = asyncio.get_event_loop()
+
+ # Create SNMP engine with autogenernated engineID pre-bound
+ # to socket transport dispatcher
+ snmp_engine = engine.SnmpEngine()
+
+ # # # # # # # # # # # #
+ # Transport setup
+ # # # # # # # # # # # #
+
+ # UDP over IPv4
+ # FIXME: add check for presense of ipv4_interface prior to attempting add OR just put entire thing in try/except clause
try:
- config.addTransport(
- snmp_engine,
- udp.domainName + (1,),
- udp.UdpTransport().openServerMode(
- (ipv4_interface, ipv4_port))
- )
+ ipv4_interface = tds.c_config['protocols.ipv4_interface']
+ ipv4_port = tds.c_config['protocols.ipv4_port']
+
+ try:
+ config.addTransport(
+ snmp_engine,
+ udp.domainName + (1,),
+ udp.UdpTransport().openServerMode(
+ (ipv4_interface, ipv4_port))
+ )
+ except Exception as e:
+ msg = "Unable to bind to %s:%s - %s" % (
+ ipv4_interface, ipv4_port, str(e))
+ ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_FATAL, tds.CODE_GENERAL, msg)
+ stdout_logger(msg)
+ cleanup_and_exit(1, tds.pid_file_name)
+
except Exception as e:
- msg = "Unable to bind to %s:%s - %s" % (
- ipv4_interface, ipv4_port, str(e))
- ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_FATAL, tds.CODE_GENERAL, msg)
+ msg = "IPv4 interface and/or port not specified in config - not listening for IPv4 traps"
stdout_logger(msg)
- cleanup_and_exit(1, tds.pid_file_name)
-
-except Exception as e:
- msg = "IPv4 interface and/or port not specified in config - not listening for IPv4 traps"
- stdout_logger(msg)
- ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_WARN, tds.CODE_GENERAL, msg)
-
-
-# UDP over IPv4, second listening interface/port example if you don't want to listen on all
-# config.addTransport(
-# snmp_engine,
-# udp.domainName + (2,),
-# udp.UdpTransport().openServerMode(('127.0.0.1', 2162))
-# )
-
-
-# UDP over IPv6
-# FIXME: add check for presense of ipv6_interface prior to attempting add OR just put entire thing in try/except clause
-try:
- ipv6_interface = tds.c_config['protocols.ipv6_interface']
- ipv6_port = tds.c_config['protocols.ipv6_port']
-
+ ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_WARN, tds.CODE_GENERAL, msg)
+
+
+ # UDP over IPv4, second listening interface/port example if you don't want to listen on all
+ # config.addTransport(
+ # snmp_engine,
+ # udp.domainName + (2,),
+ # udp.UdpTransport().openServerMode(('127.0.0.1', 2162))
+ # )
+
+
+ # UDP over IPv6
+ # FIXME: add check for presense of ipv6_interface prior to attempting add OR just put entire thing in try/except clause
try:
- config.addTransport(
- snmp_engine,
- udp6.domainName,
- udp6.Udp6Transport().openServerMode(
- (ipv6_interface, ipv6_port))
- )
+ ipv6_interface = tds.c_config['protocols.ipv6_interface']
+ ipv6_port = tds.c_config['protocols.ipv6_port']
+
+ try:
+ config.addTransport(
+ snmp_engine,
+ udp6.domainName,
+ udp6.Udp6Transport().openServerMode(
+ (ipv6_interface, ipv6_port))
+ )
+ except Exception as e:
+ msg = "Unable to bind to %s:%s - %s" % (
+ ipv6_interface, ipv6_port, str(e))
+ stdout_logger(msg)
+ ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_FATAL, tds.CODE_GENERAL, msg)
+ cleanup_and_exit(1, tds.pid_file_name)
+
except Exception as e:
- msg = "Unable to bind to %s:%s - %s" % (
- ipv6_interface, ipv6_port, str(e))
+ msg = "IPv6 interface and/or port not specified in config - not listening for IPv6 traps"
stdout_logger(msg)
- ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_FATAL, tds.CODE_GENERAL, msg)
+ ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_WARN, tds.CODE_GENERAL, msg)
+
+
+ # # # # # # # # # # # #
+ # SNMPv1/2c setup
+ # # # # # # # # # # # #
+
+ # SecurityName <-> CommunityName mapping
+ # to restrict trap reception to only those with specific community
+ # strings
+ config.addV1System(snmp_engine, 'my-area', 'public')
+
+ # register comm_string_rewrite_observer for message arrival
+ snmp_engine.observer.registerObserver(
+ comm_string_rewrite_observer,
+ 'rfc2576.processIncomingMsg:writable'
+ )
+
+ # register snmp_engine_observer_cb for message arrival
+ snmp_engine.observer.registerObserver(
+ snmp_engine_observer_cb,
+ 'rfc3412.receiveMessage:request',
+ 'rfc3412.returnResponsePdu',
+ )
+
+ # Register SNMP Application at the SNMP engine
+ ntfrcv.NotificationReceiver(snmp_engine, notif_receiver_cb)
+
+ snmp_engine.transportDispatcher.jobStarted(1) # loop forever
+
+ # Run I/O dispatcher which will receive traps
+ try:
+ snmp_engine.transportDispatcher.runDispatcher()
+ except Exception as e:
+ snmp_engine.observer.unregisterObserver()
+ snmp_engine.transportDispatcher.closeDispatcher()
cleanup_and_exit(1, tds.pid_file_name)
-
-except Exception as e:
- msg = "IPv6 interface and/or port not specified in config - not listening for IPv6 traps"
- stdout_logger(msg)
- ecomp_logger(tds.LOG_TYPE_ERROR, tds.SEV_WARN, tds.CODE_GENERAL, msg)
-
-
-# # # # # # # # # # # #
-# SNMPv1/2c setup
-# # # # # # # # # # # #
-
-# SecurityName <-> CommunityName mapping
-# to restrict trap reception to only those with specific community
-# strings
-config.addV1System(snmp_engine, 'my-area', 'public')
-
-# register comm_string_rewrite_observer for message arrival
-snmp_engine.observer.registerObserver(
- comm_string_rewrite_observer,
- 'rfc2576.processIncomingMsg:writable'
-)
-
-# register snmp_engine_observer_cb for message arrival
-snmp_engine.observer.registerObserver(
- snmp_engine_observer_cb,
- 'rfc3412.receiveMessage:request',
- 'rfc3412.returnResponsePdu',
-)
-
-# Register SNMP Application at the SNMP engine
-ntfrcv.NotificationReceiver(snmp_engine, notif_receiver_cb)
-
-snmp_engine.transportDispatcher.jobStarted(1) # loop forever
-
-# Run I/O dispatcher which will receive traps
-try:
- snmp_engine.transportDispatcher.runDispatcher()
-except Exception as e:
- snmp_engine.observer.unregisterObserver()
- snmp_engine.transportDispatcher.closeDispatcher()
- cleanup_and_exit(1, tds.pid_file_name)
diff --git a/bin/snmptrapd.sh b/snmptrap/snmptrapd.sh
index c4712f6..c4712f6 100755..100644
--- a/bin/snmptrapd.sh
+++ b/snmptrap/snmptrapd.sh
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644
index 0000000..1875bf6
--- /dev/null
+++ b/tests/__init__.py
@@ -0,0 +1,21 @@
+# ================================================================================
+# Copyright (c) 2018 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=========================================================
+#
+# 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/tests/_test_trapd_get_cbs_config.py b/tests/_test_trapd_get_cbs_config.py
deleted file mode 100644
index 5fcfc2a..0000000
--- a/tests/_test_trapd_get_cbs_config.py
+++ /dev/null
@@ -1,44 +0,0 @@
-import pytest
-import unittest
-import os
-from onap_dcae_cbs_docker_client.client import get_config
-from trapd_exit import cleanup_and_exit
-from trapd_logging import stdout_logger
-import trapd_get_cbs_config
-
-class test_get_cbs_config(unittest.TestCase):
- """
- Test the trapd_get_cbs_config mod
- """
-
- def test_cbs_env_present(self):
- """
- Test that CBS env variable exists and we can get config even
- if CONSUL_HOST doesn't provide
- """
- os.environ.update(CONSUL_HOST='nosuchhost')
- result = trapd_get_cbs_config.trapd_get_cbs_config()
- compare = str(result).startswith("{'snmptrap': ")
- self.assertEqual(compare, False)
-
- def test_cbs_fallback_env_present(self):
- """
- Test that CBS fallback env variable exists and we can get config
- from fallback env var
- """
- os.environ.update(CBS_SIM_JSON='../etc/snmptrapd.json')
- result = trapd_get_cbs_config.trapd_get_cbs_config()
- compare = str(result).startswith("{'snmptrap': ")
- self.assertEqual(compare, False)
-
- def test_cbs_fallback_env_not_present(self):
- """
- Test that CBS fallback env variable does not exists fails
- """
- os.environ.update(CBS_SIM_JSON='../etc/no_such_file.json')
- result = trapd_get_cbs_config.trapd_get_cbs_config()
- compare = str(result).startswith("{'snmptrap': ")
- self.assertEqual(compare, False)
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/tests/conftest.py b/tests/conftest.py
new file mode 100644
index 0000000..d78ed5e
--- /dev/null
+++ b/tests/conftest.py
@@ -0,0 +1,12 @@
+import pytest
+
+@pytest.fixture
+
+def test_var(_var_name):
+
+ try:
+ _var_name
+ except NameError:
+ return False
+ else:
+ return True
diff --git a/tests/setup.py b/tests/snmp.setup.py
index 5a12f10..5a12f10 100644
--- a/tests/setup.py
+++ b/tests/snmp.setup.py
diff --git a/tests/test_snmptrapd.py b/tests/test_snmptrapd.py
index 2f1783c..2cc11d7 100644
--- a/tests/test_snmptrapd.py
+++ b/tests/test_snmptrapd.py
@@ -1,46 +1,88 @@
+import os
import pytest
import unittest
+import snmptrapd
+import datetime
+
+import trapd_settings as tds
+import trapd_http_session
import trapd_runtime_pid
-
-class test_save_pid(unittest.TestCase):
+import trapd_io
+import trapd_logging
+import trapd_get_cbs_config
+
+class test_snmptrapd(unittest.TestCase):
"""
Test the save_pid mod
"""
- def test_correct_usage(self):
+ def test_usage_err(self):
"""
- Test that attempt to create pid file in standard location works
+ Test usage error
"""
- result = trapd_runtime_pid.save_pid('/tmp/snmptrap_test_pid_file')
- self.assertEqual(result, True)
+
+ with pytest.raises(SystemExit) as pytest_wrapped_sys_exit:
+ result = snmptrapd.usage_err()
+ assert pytest_wrapped_sys_exit.type == SystemExit
+ assert pytest_wrapped_sys_exit.value.code == 1
+
- def test_missing_directory(self):
+ def test_load_all_configs(self):
"""
- Test that attempt to create pid file in missing dir fails
+ Test load of all configs
"""
- result = trapd_runtime_pid.save_pid('/bogus/directory/for/snmptrap_test_pid_file')
- self.assertEqual(result, False)
-
-class test_rm_pid(unittest.TestCase):
- """
- Test the rm_pid mod
- """
-
- def test_correct_usage(self):
- """
- 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 = trapd_runtime_pid.rm_pid('/tmp/snmptrap_test_pid_file')
+
+ # init vars
+ tds.init()
+
+ # request load of CBS data
+ os.environ.update(CBS_SIM_JSON='/opt/app/snmptrap/etc/snmptrapd.json')
+ result = trapd_get_cbs_config.get_cbs_config()
self.assertEqual(result, True)
-
- def test_missing_file(self):
+
+ # request load of CBS data
+ result = snmptrapd.load_all_configs(0, 1)
+ self.assertEqual(result, True)
+
+ def test_log_all_arriving_traps(self):
"""
- Test that attempt to rm non-existent pid file fails
+ Test logging of traps
"""
- result = trapd_runtime_pid.rm_pid('/tmp/snmptrap_test_pid_file_9999')
- self.assertEqual(result, False)
-
+
+ # init vars
+ tds.init()
+
+ # request load of CBS data
+ os.environ.update(CBS_SIM_JSON='/opt/app/snmptrap/etc/snmptrapd.json')
+ result = trapd_get_cbs_config.get_cbs_config()
+
+ # set last day to current
+ tds.last_day = datetime.datetime.now().day
+
+ # trap dict for logging
+ tds.trap_dict = {'uuid': '06f6e91c-3236-11e8-9953-005056865aac', 'agent address': '1.2.3.4', 'agent name': 'test-agent.nodomain.com', 'cambria.partition': 'test-agent.nodomain.com', 'community': '', 'community len': 0, 'epoch_serno': 15222068260000, 'protocol version': 'v2c', 'time received': 1522206826.2938566, 'trap category': 'ONAP-COLLECTOR-SNMPTRAP', 'sysUptime': '218567736', 'notify OID': '1.3.6.1.4.1.9999.9.9.999', 'notify OID len': 10}
+
+ # open eelf logs
+ trapd_io.open_eelf_logs()
+
+ # open trap logs
+ tds.arriving_traps_filename = tds.c_config['files.runtime_base_dir'] + "/" + \
+ tds.c_config['files.log_dir'] + "/" + \
+ (tds.c_config['files.arriving_traps_log'])
+ tds.arriving_traps_fd = trapd_io.open_file(tds.arriving_traps_filename)
+
+ # name and open json trap log
+ tds.json_traps_filename = tds.c_config['files.runtime_base_dir'] + "/" + tds.c_config['files.log_dir'] + "/" + "DMAAP_" + (
+ tds.c_config['streams_publishes']['sec_fault_unsecure']['dmaap_info']['topic_url'].split('/')[-1]) + ".json"
+ tds.json_traps_fd = trapd_io.open_file(tds.json_traps_filename)
+ msg = ("published traps logged to: %s" % tds.json_traps_filename)
+ trapd_io.stdout_logger(msg)
+ trapd_logging.ecomp_logger(tds.LOG_TYPE_DEBUG, tds.SEV_INFO, tds.CODE_GENERAL, msg)
+
+ # don't open files, but try to log - should raise exception
+ with pytest.raises(Exception) as pytest_wrapped_exception:
+ result = snmptrapd.log_all_arriving_traps()
+ assert pytest_wrapped_exception.type == AttributeError
+
if __name__ == '__main__':
unittest.main()
diff --git a/tests/test_trapd_get_cbs_config.py b/tests/test_trapd_get_cbs_config.py
new file mode 100644
index 0000000..415c951
--- /dev/null
+++ b/tests/test_trapd_get_cbs_config.py
@@ -0,0 +1,61 @@
+import pytest
+import unittest
+import os
+
+from onap_dcae_cbs_docker_client.client import get_config
+from trapd_exit import cleanup_and_exit
+from trapd_io import stdout_logger, ecomp_logger
+import trapd_settings as tds
+import trapd_get_cbs_config
+
+class test_get_cbs_config(unittest.TestCase):
+ """
+ Test the trapd_get_cbs_config mod
+ """
+
+ def test_cbs_env_present(self):
+ """
+ Test that CBS env variable exists and we can get config even
+ if CONSUL_HOST doesn't provide
+ """
+ os.environ.update(CONSUL_HOST='nosuchhost')
+ # result = trapd_get_cbs_config.get_cbs_config()
+ # print("result: %s" % result)
+ # compare = str(result).startswith("{'snmptrap': ")
+ # self.assertEqual(compare, False)
+
+ with pytest.raises(Exception) as pytest_wrapped_sys_exit:
+ result = trapd_get_cbs_config.get_cbs_config()
+ assert pytest_wrapped_sys_exit.type == SystemExit
+ # assert pytest_wrapped_sys_exit.value.code == 1
+
+
+ def test_cbs_override_env_invalid(self):
+ """
+ """
+ os.environ.update(CBS_SIM_JSON='/opt/app/snmptrap/etc/nosuchfile.json')
+ # result = trapd_get_cbs_config.get_cbs_config()
+ # print("result: %s" % result)
+ # compare = str(result).startswith("{'snmptrap': ")
+ # self.assertEqual(compare, False)
+
+ with pytest.raises(SystemExit) as pytest_wrapped_sys_exit:
+ result = trapd_get_cbs_config.get_cbs_config()
+ assert pytest_wrapped_sys_exit.type == SystemExit
+ assert pytest_wrapped_sys_exit.value.code == 1
+
+
+ def test_cbs_fallback_env_present(self):
+ """
+ Test that CBS fallback env variable exists and we can get config
+ from fallback env var
+ """
+ os.environ.update(CBS_SIM_JSON='/opt/app/snmptrap/etc/snmptrapd.json')
+ result = trapd_get_cbs_config.get_cbs_config()
+ print("result: %s" % result)
+ # compare = str(result).startswith("{'snmptrap': ")
+ # self.assertEqual(compare, True)
+ self.assertEqual(result, True)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/tests/test_trapd_settings.py b/tests/test_trapd_settings.py
new file mode 100644
index 0000000..ab64426
--- /dev/null
+++ b/tests/test_trapd_settings.py
@@ -0,0 +1,73 @@
+import pytest
+import unittest
+import trapd_exit
+
+pid_file="/tmp/test_pid_file"
+pid_file_dne="/tmp/test_pid_file_NOT"
+
+import trapd_settings as tds
+from conftest import test_var
+
+class test_cleanup_and_exit(unittest.TestCase):
+ """
+ Test for presense of required vars
+ """
+
+
+ def test_nonexistent_dict(self):
+ """
+ Test nosuch var
+ """
+ tds.init()
+ try:
+ tds.no_such_var
+ result = True
+ except:
+ result = False
+
+ self.assertEqual(result, False)
+
+ def test_config_dict(self):
+ """
+ Test config dict
+ """
+ tds.init()
+ try:
+ tds.c_config
+ result = True
+ except:
+ result = False
+
+ self.assertEqual(result, True)
+
+ def test_dns_cache_ip_to_name(self):
+ """
+ Test dns cache name dict
+ """
+
+ tds.init()
+ try:
+ tds.dns_cache_ip_to_name
+ result = True
+ except:
+ result = False
+
+ self.assertEqual(result, True)
+
+ def test_dns_cache_ip_expires(self):
+ """
+ Test dns cache ip expires dict
+ """
+
+ tds.init()
+ try:
+ tds.dns_cache_ip_expires
+ result = True
+ except:
+ result = False
+
+ self.assertEqual(result, True)
+
+if __name__ == '__main__':
+ # tds.init()
+ unittest.main()
diff --git a/tests/tox.ini b/tests/tox.ini
deleted file mode 100644
index 3d8e842..0000000
--- a/tests/tox.ini
+++ /dev/null
@@ -1,15 +0,0 @@
-[tox]
-envlist = py36
-
-[testenv]
-deps = coverage
-commands = coverage erase
-
-[testenv:py36]
-deps = coverage pytest
-commands = coverage run ../bin/snmptrapd.py &
- pytest test_trapd_exit.py
- pytest test_trapd_http_session.py
- pytest test_trapd_runtime_pid.py
- ./test_snmptrapd_send_test_trap.py &
- coverage report -m
diff --git a/tox.ini b/tox.ini
new file mode 100644
index 0000000..4159d31
--- /dev/null
+++ b/tox.ini
@@ -0,0 +1,15 @@
+# content of: tox.ini , put in same dir as setup.py
+[tox]
+envlist = py27
+
+[testenv]
+deps=
+ -rrequirements.txt
+ pytest
+ coverage
+ pytest-cov
+setenv =
+ PYTHONPATH={toxinidir}
+recreate = True
+commands=
+ pytest --cov snmptrap --cov-report=xml --cov-report=term tests --verbose