diff options
author | Moshe <moshehoa@amdocs.com> | 2019-04-11 17:59:26 +0300 |
---|---|---|
committer | Moshe <moshehoa@amdocs.com> | 2019-04-11 18:01:21 +0300 |
commit | 2cc085f9ee3fa0abd793678f5d984423ccf4148d (patch) | |
tree | 37df07dcca1706ee2286eaa29604b8cd8d7799b8 | |
parent | 3b9d9e7d03186f8925548b0ce6db5d80e2dfcb8f (diff) |
add unit tests
Issue-ID: VNFSDK-350
Change-Id: Ib40c66476f5d8e32fbb4032596f67700551a963d
Signed-off-by: Moshe <moshehoa@amdocs.com>
-rw-r--r-- | coverage.xml | 1042 | ||||
-rw-r--r-- | tools/cover.sh | 1 | ||||
-rw-r--r-- | vnftest/runners/iteration.py | 2 | ||||
-rw-r--r-- | vnftest/tests/unit/common/test_ssh.py | 542 | ||||
-rw-r--r-- | vnftest/tests/unit/context/__init__.py | 0 | ||||
-rw-r--r-- | vnftest/tests/unit/context/test_heat.py | 47 | ||||
-rw-r--r-- | vnftest/tests/unit/core/test_task.py | 2 |
7 files changed, 1314 insertions, 322 deletions
diff --git a/coverage.xml b/coverage.xml index 1542bad..cdbd038 100644 --- a/coverage.xml +++ b/coverage.xml @@ -1,12 +1,12 @@ <?xml version="1.0" ?> -<coverage branch-rate="0.2662" branches-covered="238" branches-valid="894" complexity="0" line-rate="0.5148" lines-covered="2125" lines-valid="4128" timestamp="1554966701600" version="4.4.2"> +<coverage branch-rate="0.3523" branches-covered="315" branches-valid="894" complexity="0" line-rate="0.6011" lines-covered="2711" lines-valid="4510" timestamp="1554994388665" version="4.4.2"> <!-- Generated by coverage.py: https://coverage.readthedocs.io --> <!-- Based on https://raw.githubusercontent.com/cobertura/web/master/htdocs/xml/coverage-04.dtd --> <sources> <source>/home/devel/dev/onap/vnfsdk/dovetail-integration/vnftest</source> </sources> <packages> - <package branch-rate="0.01316" complexity="0" line-rate="0.2819" name="."> + <package branch-rate="0.6974" complexity="0" line-rate="0.8154" name="."> <classes> <class branch-rate="0.25" complexity="0" filename="__init__.py" line-rate="0.6389" name="__init__.py"> <methods/> @@ -62,7 +62,7 @@ <line hits="0" number="57"/> </lines> </class> - <class branch-rate="0" complexity="0" filename="ssh.py" line-rate="0.2402" name="ssh.py"> + <class branch-rate="0.7429" complexity="0" filename="ssh.py" line-rate="0.8661" name="ssh.py"> <methods/> <lines> <line hits="1" number="16"/> @@ -103,214 +103,214 @@ <line hits="0" number="110"/> <line hits="0" number="111"/> <line hits="1" number="113"/> - <line hits="0" number="117"/> + <line hits="1" number="117"/> <line hits="1" number="119"/> - <line hits="0" number="130"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="132,134" number="131"/> + <line hits="1" number="130"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="132" number="131"/> <line hits="0" number="132"/> - <line hits="0" number="134"/> - <line hits="0" number="136"/> - <line hits="0" number="137"/> - <line hits="0" number="139"/> - <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 branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="151,153" number="150"/> + <line hits="1" number="134"/> + <line hits="1" number="136"/> + <line hits="1" number="137"/> + <line hits="1" number="139"/> + <line hits="1" number="142"/> + <line hits="1" number="143"/> + <line hits="1" number="144"/> + <line hits="1" number="145"/> + <line hits="1" number="146"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="151" number="150"/> <line hits="0" number="151"/> - <line hits="0" number="153"/> + <line hits="1" number="153"/> <line hits="1" number="155"/> <line hits="1" number="156"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="158,159" number="157"/> - <line hits="0" number="158"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="160,161" number="159"/> - <line hits="0" number="160"/> - <line hits="0" number="161"/> - <line hits="0" number="162"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="159" number="157"/> + <line hits="1" number="158"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="161" number="159"/> + <line hits="1" number="160"/> + <line hits="1" number="161"/> + <line hits="1" number="162"/> <line hits="1" number="172"/> <line hits="1" number="173"/> - <line hits="0" number="174"/> + <line hits="1" number="174"/> <line hits="1" number="176"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="178,179" number="177"/> - <line hits="0" number="178"/> - <line hits="0" number="179"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="181,185" number="180"/> - <line hits="0" number="181"/> - <line hits="0" number="182"/> - <line hits="0" number="183"/> - <line hits="0" number="184"/> - <line hits="0" number="185"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="179" number="177"/> + <line hits="1" number="178"/> + <line hits="1" number="179"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="180"/> + <line hits="1" number="181"/> + <line hits="1" number="182"/> + <line hits="1" number="183"/> + <line hits="1" number="184"/> + <line hits="1" number="185"/> <line hits="1" number="187"/> - <line hits="0" number="189"/> + <line hits="1" number="189"/> <line hits="1" number="191"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="193,194" number="192"/> - <line hits="0" number="193"/> - <line hits="0" number="194"/> - <line hits="0" number="195"/> - <line hits="0" number="196"/> - <line hits="0" number="197"/> - <line hits="0" number="203"/> - <line hits="0" number="204"/> - <line hits="0" number="205"/> - <line hits="0" number="207"/> - <line hits="0" number="208"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="192"/> + <line hits="1" number="193"/> + <line hits="1" number="194"/> + <line hits="1" number="195"/> + <line hits="1" number="196"/> + <line hits="1" number="197"/> + <line hits="1" number="203"/> + <line hits="1" number="204"/> + <line hits="1" number="205"/> + <line hits="1" number="207"/> + <line hits="1" number="208"/> <line hits="1" number="211"/> - <line hits="0" number="212"/> + <line hits="1" number="212"/> <line hits="1" number="222"/> - <line hits="0" number="223"/> + <line hits="1" number="223"/> <line hits="1" number="225"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="exit,227" number="226"/> - <line hits="0" number="227"/> - <line hits="0" number="228"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="exit" number="226"/> + <line hits="1" number="227"/> + <line hits="1" number="228"/> <line hits="1" number="230"/> - <line hits="0" number="252"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="255,257" number="254"/> + <line hits="1" number="252"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="255" number="254"/> <line hits="0" number="255"/> - <line hits="0" number="257"/> + <line hits="1" number="257"/> <line hits="1" number="262"/> - <line hits="0" number="266"/> - <line hits="0" number="267"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="269,270" number="268"/> + <line hits="1" number="266"/> + <line hits="1" number="267"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="269" number="268"/> <line hits="0" number="269"/> - <line hits="0" number="270"/> - <line hits="0" number="271"/> - <line hits="0" number="274"/> - <line hits="0" number="275"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="280,282" number="279"/> - <line hits="0" number="280"/> - <line hits="0" number="282"/> - <line hits="0" number="284"/> - <line hits="0" number="286"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="289,295" number="288"/> - <line hits="0" number="289"/> - <line hits="0" number="290"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="292,293" number="291"/> - <line hits="0" number="292"/> + <line hits="1" number="270"/> + <line hits="1" number="271"/> + <line hits="1" number="274"/> + <line hits="1" number="275"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="279"/> + <line hits="1" number="280"/> + <line hits="1" number="282"/> + <line hits="1" number="284"/> + <line hits="1" number="286"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="288"/> + <line hits="1" number="289"/> + <line hits="1" number="290"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="293" number="291"/> + <line hits="1" number="292"/> <line hits="0" number="293"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="296,303" number="295"/> - <line hits="0" number="296"/> - <line hits="0" number="298"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="300,301" number="299"/> - <line hits="0" number="300"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="295"/> + <line hits="1" number="296"/> + <line hits="1" number="298"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="301" number="299"/> + <line hits="1" number="300"/> <line hits="0" number="301"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="304,322" number="303"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="305,322" number="304"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="306,317" number="305"/> - <line hits="0" number="306"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="308,309" number="307"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="303"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="322" number="304"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="305"/> + <line hits="1" number="306"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="308" number="307"/> <line hits="0" number="308"/> - <line hits="0" number="309"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="313,317" number="311"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="314,317" number="313"/> - <line hits="0" number="314"/> - <line hits="0" number="315"/> - <line hits="0" number="316"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="318,322" number="317"/> - <line hits="0" number="318"/> - <line hits="0" number="320"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="323,325" number="322"/> - <line hits="0" number="323"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="326,329" number="325"/> - <line hits="0" number="326"/> - <line hits="0" number="327"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="284,330" number="329"/> - <line hits="0" number="330"/> - <line hits="0" number="332"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="334,339" number="333"/> - <line hits="0" number="334"/> - <line hits="0" number="335"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="337,338" number="336"/> + <line hits="1" number="309"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="311"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="313"/> + <line hits="1" number="314"/> + <line hits="1" number="315"/> + <line hits="1" number="316"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="317"/> + <line hits="1" number="318"/> + <line hits="1" number="320"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="322"/> + <line hits="1" number="323"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="325"/> + <line hits="1" number="326"/> + <line hits="1" number="327"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="329"/> + <line hits="1" number="330"/> + <line hits="1" number="332"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="333"/> + <line hits="1" number="334"/> + <line hits="1" number="335"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="337" number="336"/> <line hits="0" number="337"/> - <line hits="0" number="338"/> - <line hits="0" number="339"/> + <line hits="1" number="338"/> + <line hits="1" number="339"/> <line hits="1" number="341"/> - <line hits="0" number="350"/> - <line hits="0" number="351"/> - <line hits="0" number="353"/> - <line hits="0" number="356"/> - <line hits="0" number="357"/> - <line hits="0" number="358"/> + <line hits="1" number="350"/> + <line hits="1" number="351"/> + <line hits="1" number="353"/> + <line hits="1" number="356"/> + <line hits="1" number="357"/> + <line hits="1" number="358"/> <line hits="1" number="360"/> - <line hits="0" number="362"/> - <line hits="0" number="363"/> - <line hits="0" number="364"/> - <line hits="0" number="365"/> - <line hits="0" number="366"/> - <line hits="0" number="367"/> - <line hits="0" number="368"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="363,370" number="369"/> - <line hits="0" number="370"/> + <line hits="1" number="362"/> + <line hits="1" number="363"/> + <line hits="1" number="364"/> + <line hits="1" number="365"/> + <line hits="1" number="366"/> + <line hits="1" number="367"/> + <line hits="1" number="368"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="369"/> + <line hits="1" number="370"/> <line hits="1" number="372"/> - <line hits="0" number="373"/> - <line hits="0" number="375"/> - <line hits="0" number="376"/> + <line hits="1" number="373"/> + <line hits="1" number="375"/> + <line hits="1" number="376"/> <line hits="1" number="378"/> - <line hits="0" number="379"/> - <line hits="0" number="381"/> - <line hits="0" number="382"/> + <line hits="1" number="379"/> + <line hits="1" number="381"/> + <line hits="1" number="382"/> <line hits="1" number="385"/> - <line hits="0" number="386"/> - <line hits="0" number="387"/> + <line hits="1" number="386"/> + <line hits="1" number="387"/> <line hits="1" number="389"/> - <line hits="0" number="390"/> - <line hits="0" number="392"/> - <line hits="0" number="393"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="395,396" number="394"/> - <line hits="0" number="395"/> - <line hits="0" number="396"/> + <line hits="1" number="390"/> + <line hits="1" number="392"/> + <line hits="1" number="393"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="394"/> + <line hits="1" number="395"/> + <line hits="1" number="396"/> <line hits="1" number="398"/> <line hits="1" number="400"/> - <line hits="0" number="402"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="404,405" number="403"/> - <line hits="0" number="404"/> - <line hits="0" number="405"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="408,410" number="406"/> - <line hits="0" number="408"/> - <line hits="0" number="410"/> - <line hits="0" number="412"/> + <line hits="1" number="402"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="403"/> + <line hits="1" number="404"/> + <line hits="1" number="405"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="410" number="406"/> + <line hits="1" number="408"/> + <line hits="1" number="410"/> + <line hits="1" number="412"/> <line hits="1" number="414"/> - <line hits="0" number="421"/> - <line hits="0" number="422"/> - <line hits="0" number="423"/> - <line hits="0" number="424"/> + <line hits="1" number="421"/> + <line hits="1" number="422"/> + <line hits="1" number="423"/> + <line hits="1" number="424"/> <line hits="1" number="426"/> - <line hits="0" number="427"/> - <line hits="0" number="429"/> - <line hits="0" number="430"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="exit,432" number="431"/> - <line hits="0" number="432"/> + <line hits="1" number="427"/> + <line hits="1" number="429"/> + <line hits="1" number="430"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="exit" number="431"/> + <line hits="1" number="432"/> <line hits="1" number="434"/> <line hits="0" number="435"/> <line hits="0" number="437"/> <line hits="0" number="438"/> <line hits="1" number="441"/> <line hits="1" number="444"/> - <line hits="0" number="446"/> - <line hits="0" number="447"/> + <line hits="1" number="446"/> + <line hits="1" number="447"/> <line hits="1" number="449"/> <line hits="0" number="450"/> <line hits="0" number="451"/> <line hits="0" number="454"/> <line hits="1" number="456"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="exit,458" number="457"/> - <line hits="0" number="458"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="exit,460" number="459"/> + <line branch="true" condition-coverage="100% (2/2)" hits="1" number="457"/> + <line hits="1" number="458"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="460" number="459"/> <line hits="0" number="460"/> <line hits="1" number="462"/> - <line hits="0" number="464"/> + <line hits="1" number="464"/> <line hits="1" number="466"/> - <line hits="0" number="467"/> - <line hits="0" number="468"/> + <line hits="1" number="467"/> + <line hits="1" number="468"/> <line hits="1" number="470"/> <line hits="0" number="473"/> <line hits="0" number="474"/> <line hits="1" number="477"/> - <line hits="0" number="478"/> - <line hits="0" number="479"/> + <line hits="1" number="478"/> + <line hits="1" number="479"/> <line hits="1" number="481"/> - <line hits="0" number="482"/> - <line hits="0" number="483"/> + <line hits="1" number="482"/> + <line hits="1" number="483"/> <line hits="1" number="485"/> <line hits="0" number="486"/> <line hits="0" number="487"/> @@ -318,7 +318,7 @@ <line hits="0" number="490"/> <line hits="0" number="491"/> <line hits="1" number="493"/> - <line hits="0" number="497"/> + <line hits="1" number="497"/> </lines> </class> </classes> @@ -1486,13 +1486,13 @@ </class> </classes> </package> - <package branch-rate="0.05076" complexity="0" line-rate="0.2744" name="contexts"> + <package branch-rate="0.1675" complexity="0" line-rate="0.4592" name="contexts"> <classes> <class branch-rate="1" complexity="0" filename="contexts/__init__.py" line-rate="1" name="__init__.py"> <methods/> <lines/> </class> - <class branch-rate="0.5556" complexity="0" filename="contexts/base.py" line-rate="0.8" name="base.py"> + <class branch-rate="0.5556" complexity="0" filename="contexts/base.py" line-rate="0.88" name="base.py"> <methods/> <lines> <line hits="1" number="14"/> @@ -1528,23 +1528,23 @@ <line hits="1" number="65"/> <line hits="1" number="66"/> <line hits="1" number="69"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="72,74" number="71"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="72" number="71"/> <line hits="0" number="72"/> - <line hits="0" number="74"/> + <line hits="1" number="74"/> <line hits="1" number="76"/> <line hits="0" number="78"/> <line hits="1" number="80"/> <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="86" number="83"/> - <line branch="true" condition-coverage="100% (2/2)" hits="1" number="84"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="83" number="84"/> <line hits="1" number="85"/> <line hits="0" number="86"/> <line hits="1" number="88"/> <line hits="1" number="92"/> <line hits="1" number="94"/> - <line hits="0" number="95"/> + <line hits="1" number="95"/> <line hits="1" number="97"/> <line hits="1" number="101"/> - <line hits="0" number="104"/> + <line hits="1" number="104"/> </lines> </class> <class branch-rate="1" complexity="0" filename="contexts/csar.py" line-rate="0.8462" name="csar.py"> @@ -1584,7 +1584,7 @@ <line hits="0" number="40"/> </lines> </class> - <class branch-rate="0" complexity="0" filename="contexts/heat.py" line-rate="0.1534" name="heat.py"> + <class branch-rate="0.1586" complexity="0" filename="contexts/heat.py" line-rate="0.4264" name="heat.py"> <methods/> <lines> <line hits="1" number="17"/> @@ -1616,33 +1616,33 @@ <line hits="1" number="53"/> <line hits="1" number="56"/> <line hits="1" number="58"/> - <line hits="0" number="59"/> - <line hits="0" number="60"/> - <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="66"/> - <line hits="0" number="67"/> - <line hits="0" number="68"/> - <line hits="0" number="69"/> - <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="75"/> - <line hits="0" number="76"/> - <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="82"/> - <line hits="0" number="83"/> + <line hits="1" number="59"/> + <line hits="1" number="60"/> + <line hits="1" number="61"/> + <line hits="1" number="62"/> + <line hits="1" number="63"/> + <line hits="1" number="64"/> + <line hits="1" number="65"/> + <line hits="1" number="66"/> + <line hits="1" number="67"/> + <line hits="1" number="68"/> + <line hits="1" number="69"/> + <line hits="1" number="70"/> + <line hits="1" number="71"/> + <line hits="1" number="72"/> + <line hits="1" number="73"/> + <line hits="1" number="74"/> + <line hits="1" number="75"/> + <line hits="1" number="76"/> + <line hits="1" number="77"/> + <line hits="1" number="78"/> + <line hits="1" number="79"/> + <line hits="1" number="80"/> + <line hits="1" number="81"/> + <line hits="1" number="82"/> + <line hits="1" number="83"/> <line hits="1" number="85"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="88,102" number="87"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="88" number="87"/> <line hits="0" number="88"/> <line hits="0" number="89"/> <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="exit,92" number="91"/> @@ -1653,33 +1653,33 @@ <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="99,101" number="97"/> <line hits="0" number="99"/> <line hits="0" number="101"/> - <line hits="0" number="102"/> + <line hits="1" number="102"/> <line hits="1" number="104"/> - <line hits="0" number="106"/> - <line hits="0" number="108"/> - <line hits="0" number="109"/> - <line hits="0" number="111"/> - <line hits="0" number="113"/> - <line hits="0" number="114"/> - <line hits="0" number="116"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="118,121" number="117"/> + <line hits="1" number="106"/> + <line hits="1" number="108"/> + <line hits="1" number="109"/> + <line hits="1" number="111"/> + <line hits="1" number="113"/> + <line hits="1" number="114"/> + <line hits="1" number="116"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="118" number="117"/> <line hits="0" number="118"/> <line hits="0" number="119"/> - <line hits="0" number="121"/> - <line hits="0" number="123"/> - <line hits="0" number="125"/> - <line hits="0" number="127"/> - <line hits="0" number="129"/> - <line hits="0" number="131"/> - <line hits="0" number="135"/> - <line hits="0" number="141"/> - <line hits="0" number="142"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="145,149" number="144"/> + <line hits="1" number="121"/> + <line hits="1" number="123"/> + <line hits="1" number="125"/> + <line hits="1" number="127"/> + <line hits="1" number="129"/> + <line hits="1" number="131"/> + <line hits="1" number="135"/> + <line hits="1" number="141"/> + <line hits="1" number="142"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="145" number="144"/> <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="exit,149" number="145"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="150,153" number="149"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="150" number="149"/> <line hits="0" number="150"/> <line hits="0" number="151"/> - <line hits="0" number="153"/> + <line hits="1" number="153"/> <line hits="1" number="155"/> <line hits="0" number="156"/> <line hits="0" number="157"/> @@ -1694,16 +1694,16 @@ <line hits="1" number="168"/> <line hits="0" number="171"/> <line hits="1" number="173"/> - <line hits="0" number="176"/> + <line hits="1" number="176"/> <line hits="1" number="178"/> <line hits="0" number="181"/> <line hits="1" number="183"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="187,195" number="186"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="188,195" number="187"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="195" number="186"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="188" number="187"/> <line hits="0" number="188"/> <line hits="0" number="189"/> <line hits="0" number="190"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="197,219" number="195"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="197" number="195"/> <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="198,199" number="197"/> <line hits="0" number="198"/> <line hits="0" number="199"/> @@ -1711,21 +1711,21 @@ <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="195,211" number="210"/> <line hits="0" number="211"/> <line hits="0" number="214"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="exit,227" number="219"/> - <line hits="0" number="227"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="229,234" number="228"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="exit" number="219"/> + <line hits="1" number="227"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="229" number="228"/> <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="228,230" number="229"/> <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="229,231" number="230"/> <line hits="0" number="231"/> <line hits="0" number="232"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="235,242" number="234"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="235" number="234"/> <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="234,236" number="235"/> <line hits="0" number="236"/> <line hits="0" number="237"/> <line hits="0" number="238"/> <line hits="0" number="239"/> - <line hits="0" number="242"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="244,268" number="243"/> + <line hits="1" number="242"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="244" number="243"/> <line hits="0" number="244"/> <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="246,249" number="245"/> <line hits="0" number="246"/> @@ -1737,13 +1737,13 @@ <line hits="0" number="258"/> <line hits="0" number="262"/> <line hits="0" number="265"/> - <line hits="0" number="268"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="270,276" number="269"/> + <line hits="1" number="268"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="270" number="269"/> <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="269,271" number="270"/> <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="270,272" number="271"/> <line hits="0" number="272"/> <line hits="0" number="273"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="277,287" number="276"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="277" number="276"/> <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="278,279" number="277"/> <line hits="0" number="278"/> <line hits="0" number="279"/> @@ -1751,9 +1751,9 @@ <line hits="0" number="281"/> <line hits="0" number="282"/> <line hits="0" number="284"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="288,291" number="287"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="288" number="287"/> <line hits="0" number="288"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="exit,293" number="291"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="293" number="291"/> <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="291,294" number="293"/> <line hits="0" number="294"/> <line hits="0" number="296"/> @@ -1784,25 +1784,25 @@ <line hits="0" number="332"/> <line hits="0" number="333"/> <line hits="1" number="335"/> - <line hits="0" number="337"/> - <line hits="0" number="348"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="354,356" number="353"/> - <line hits="0" number="354"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="358,363" number="356"/> + <line hits="1" number="337"/> + <line hits="1" number="348"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="356" number="353"/> + <line hits="1" number="354"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="358" number="356"/> <line hits="0" number="358"/> <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="360,366" number="359"/> <line hits="0" number="360"/> - <line hits="0" number="363"/> - <line hits="0" number="366"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="370,379" number="369"/> + <line hits="1" number="363"/> + <line hits="1" number="366"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="370" number="369"/> <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="371,372" number="370"/> <line hits="0" number="371"/> <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="373,375" number="372"/> <line hits="0" number="373"/> <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="369,376" number="375"/> <line hits="0" number="376"/> - <line hits="0" number="379"/> - <line hits="0" number="380"/> + <line hits="1" number="379"/> + <line hits="1" number="380"/> <line hits="1" number="382"/> <line hits="0" number="384"/> <line hits="0" number="385"/> @@ -1841,41 +1841,41 @@ <line hits="0" number="433"/> <line hits="0" number="436"/> <line hits="1" number="455"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="exit,457" number="456"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="457" number="456"/> <line hits="0" number="457"/> <line hits="0" number="458"/> <line hits="0" number="459"/> <line hits="0" number="460"/> <line hits="0" number="461"/> <line hits="1" number="464"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="467,470" number="466"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="467" number="466"/> <line hits="0" number="467"/> <line hits="0" number="468"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="471,478" number="470"/> - <line hits="0" number="471"/> - <line hits="0" number="472"/> - <line hits="0" number="473"/> - <line hits="0" number="474"/> - <line hits="0" number="476"/> - <line hits="0" number="478"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="478" number="470"/> + <line hits="1" number="471"/> + <line hits="1" number="472"/> + <line hits="1" number="473"/> + <line hits="1" number="474"/> + <line hits="1" number="476"/> + <line hits="1" number="478"/> <line hits="1" number="480"/> <line hits="0" number="482"/> <line hits="0" number="492"/> <line hits="1" number="494"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="500,512" number="499"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="500" number="499"/> <line hits="0" number="500"/> <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="502,505" number="501"/> <line hits="0" number="502"/> <line hits="0" number="505"/> <line hits="0" number="506"/> <line hits="0" number="509"/> - <line hits="0" number="512"/> - <line hits="0" number="513"/> - <line hits="0" number="514"/> - <line hits="0" number="515"/> - <line hits="0" number="516"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="518,520" number="517"/> - <line hits="0" number="518"/> + <line hits="1" number="512"/> + <line hits="1" number="513"/> + <line hits="1" number="514"/> + <line hits="1" number="515"/> + <line hits="1" number="516"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="520" number="517"/> + <line hits="1" number="518"/> <line hits="0" number="520"/> <line hits="0" number="523"/> <line hits="0" number="525"/> @@ -2843,13 +2843,13 @@ </class> </classes> </package> - <package branch-rate="0" complexity="0" line-rate="0.2227" name="orchestrator"> + <package branch-rate="0.02439" complexity="0" line-rate="0.2689" name="orchestrator"> <classes> <class branch-rate="1" complexity="0" filename="orchestrator/__init__.py" line-rate="1" name="__init__.py"> <methods/> <lines/> </class> - <class branch-rate="0" complexity="0" filename="orchestrator/heat.py" line-rate="0.2227" name="heat.py"> + <class branch-rate="0.02439" complexity="0" filename="orchestrator/heat.py" line-rate="0.2689" name="heat.py"> <methods/> <lines> <line hits="1" number="16"/> @@ -2925,24 +2925,24 @@ <line hits="1" number="142"/> <line hits="1" number="143"/> <line hits="1" number="145"/> - <line hits="0" number="146"/> - <line hits="0" number="147"/> - <line hits="0" number="160"/> + <line hits="1" number="146"/> + <line hits="1" number="147"/> + <line hits="1" number="160"/> <line hits="1" number="162"/> - <line hits="0" number="164"/> - <line hits="0" number="165"/> - <line hits="0" number="166"/> - <line hits="0" number="167"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="172,174" number="171"/> + <line hits="1" number="164"/> + <line hits="1" number="165"/> + <line hits="1" number="166"/> + <line hits="1" number="167"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="172" number="171"/> <line hits="0" number="172"/> - <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="175,181" number="174"/> + <line branch="true" condition-coverage="50% (1/2)" hits="1" missing-branches="175" number="174"/> <line hits="0" number="175"/> <line hits="0" number="176"/> <line hits="0" number="177"/> <line hits="0" number="178"/> <line hits="0" number="179"/> - <line hits="0" number="181"/> - <line hits="0" number="183"/> + <line hits="1" number="181"/> + <line hits="1" number="183"/> <line hits="1" number="185"/> <line branch="true" condition-coverage="0% (0/2)" hits="0" missing-branches="190,191" number="189"/> <line hits="0" number="190"/> @@ -3899,7 +3899,7 @@ </class> </classes> </package> - <package branch-rate="0.9706" complexity="0" line-rate="0.8483" name="tests.unit.common"> + <package branch-rate="0.9706" complexity="0" line-rate="0.9129" name="tests.unit.common"> <classes> <class branch-rate="1" complexity="0" filename="tests/unit/common/__init__.py" line-rate="1" name="__init__.py"> <methods/> @@ -4024,6 +4024,358 @@ <line hits="1" number="152"/> </lines> </class> + <class branch-rate="1" complexity="0" filename="tests/unit/common/test_ssh.py" line-rate="1" name="test_ssh.py"> + <methods/> + <lines> + <line hits="1" number="18"/> + <line hits="1" number="19"/> + <line hits="1" number="20"/> + <line hits="1" number="21"/> + <line hits="1" number="22"/> + <line hits="1" number="24"/> + <line hits="1" number="25"/> + <line hits="1" number="26"/> + <line hits="1" number="28"/> + <line hits="1" number="31"/> + <line hits="1" number="32"/> + <line hits="1" number="35"/> + <line hits="1" number="38"/> + <line hits="1" number="39"/> + <line hits="1" number="40"/> + <line hits="1" number="42"/> + <line hits="1" number="44"/> + <line hits="1" number="45"/> + <line hits="1" number="47"/> + <line hits="1" number="48"/> + <line hits="1" number="49"/> + <line hits="1" number="50"/> + <line hits="1" number="51"/> + <line hits="1" number="52"/> + <line hits="1" number="53"/> + <line hits="1" number="55"/> + <line hits="1" number="57"/> + <line hits="1" number="58"/> + <line hits="1" number="62"/> + <line hits="1" number="63"/> + <line hits="1" number="64"/> + <line hits="1" number="65"/> + <line hits="1" number="66"/> + <line hits="1" number="67"/> + <line hits="1" number="69"/> + <line hits="1" number="71"/> + <line hits="1" number="72"/> + <line hits="1" number="76"/> + <line hits="1" number="77"/> + <line hits="1" number="78"/> + <line hits="1" number="79"/> + <line hits="1" number="80"/> + <line hits="1" number="81"/> + <line hits="1" number="83"/> + <line hits="1" number="85"/> + <line hits="1" number="86"/> + <line hits="1" number="90"/> + <line hits="1" number="91"/> + <line hits="1" number="92"/> + <line hits="1" number="93"/> + <line hits="1" number="94"/> + <line hits="1" number="95"/> + <line hits="1" number="97"/> + <line hits="1" number="99"/> + <line hits="1" number="100"/> + <line hits="1" number="104"/> + <line hits="1" number="105"/> + <line hits="1" number="106"/> + <line hits="1" number="107"/> + <line hits="1" number="108"/> + <line hits="1" number="109"/> + <line hits="1" number="111"/> + <line hits="1" number="112"/> + <line hits="1" number="113"/> + <line hits="1" number="114"/> + <line hits="1" number="115"/> + <line hits="1" number="116"/> + <line hits="1" number="117"/> + <line hits="1" number="119"/> + <line hits="1" number="121"/> + <line hits="1" number="122"/> + <line hits="1" number="123"/> + <line hits="1" number="124"/> + <line hits="1" number="125"/> + <line hits="1" number="126"/> + <line hits="1" number="128"/> + <line hits="1" number="129"/> + <line hits="1" number="131"/> + <line hits="1" number="132"/> + <line hits="1" number="133"/> + <line hits="1" number="134"/> + <line hits="1" number="135"/> + <line hits="1" number="136"/> + <line hits="1" number="137"/> + <line hits="1" number="138"/> + <line hits="1" number="139"/> + <line hits="1" number="140"/> + <line hits="1" number="142"/> + <line hits="1" number="143"/> + <line hits="1" number="145"/> + <line hits="1" number="146"/> + <line hits="1" number="147"/> + <line hits="1" number="148"/> + <line hits="1" number="149"/> + <line hits="1" number="150"/> + <line hits="1" number="151"/> + <line hits="1" number="152"/> + <line hits="1" number="153"/> + <line hits="1" number="154"/> + <line hits="1" number="156"/> + <line hits="1" number="157"/> + <line hits="1" number="159"/> + <line hits="1" number="160"/> + <line hits="1" number="161"/> + <line hits="1" number="162"/> + <line hits="1" number="164"/> + <line hits="1" number="165"/> + <line hits="1" number="167"/> + <line hits="1" number="168"/> + <line hits="1" number="176"/> + <line hits="1" number="178"/> + <line hits="1" number="179"/> + <line hits="1" number="181"/> + <line hits="1" number="182"/> + <line hits="1" number="184"/> + <line hits="1" number="185"/> + <line hits="1" number="186"/> + <line hits="1" number="187"/> + <line hits="1" number="188"/> + <line hits="1" number="189"/> + <line hits="1" number="191"/> + <line hits="1" number="193"/> + <line hits="1" number="194"/> + <line hits="1" number="196"/> + <line hits="1" number="197"/> + <line hits="1" number="198"/> + <line hits="1" number="199"/> + <line hits="1" number="200"/> + <line hits="1" number="201"/> + <line hits="1" number="202"/> + <line hits="1" number="204"/> + <line hits="1" number="205"/> + <line hits="1" number="207"/> + <line hits="1" number="208"/> + <line hits="1" number="209"/> + <line hits="1" number="210"/> + <line hits="1" number="211"/> + <line hits="1" number="213"/> + <line hits="1" number="214"/> + <line hits="1" number="215"/> + <line hits="1" number="217"/> + <line hits="1" number="218"/> + <line hits="1" number="219"/> + <line hits="1" number="220"/> + <line hits="1" number="221"/> + <line hits="1" number="223"/> + <line hits="1" number="225"/> + <line hits="1" number="226"/> + <line hits="1" number="229"/> + <line hits="1" number="230"/> + <line hits="1" number="233"/> + <line hits="1" number="235"/> + <line hits="1" number="236"/> + <line hits="1" number="239"/> + <line hits="1" number="240"/> + <line hits="1" number="243"/> + <line hits="1" number="245"/> + <line hits="1" number="246"/> + <line hits="1" number="248"/> + <line hits="1" number="249"/> + <line hits="1" number="253"/> + <line hits="1" number="259"/> + <line hits="1" number="260"/> + <line hits="1" number="262"/> + <line hits="1" number="263"/> + <line hits="1" number="264"/> + <line hits="1" number="266"/> + <line hits="1" number="267"/> + <line hits="1" number="269"/> + <line hits="1" number="270"/> + <line hits="1" number="271"/> + <line hits="1" number="272"/> + <line hits="1" number="273"/> + <line hits="1" number="275"/> + <line hits="1" number="276"/> + <line hits="1" number="278"/> + <line hits="1" number="280"/> + <line hits="1" number="281"/> + <line hits="1" number="282"/> + <line hits="1" number="283"/> + <line hits="1" number="284"/> + <line hits="1" number="285"/> + <line hits="1" number="286"/> + <line hits="1" number="287"/> + <line hits="1" number="288"/> + <line hits="1" number="290"/> + <line hits="1" number="292"/> + <line hits="1" number="293"/> + <line hits="1" number="294"/> + <line hits="1" number="295"/> + <line hits="1" number="296"/> + <line hits="1" number="297"/> + <line hits="1" number="298"/> + <line hits="1" number="300"/> + <line hits="1" number="301"/> + <line hits="1" number="302"/> + <line hits="1" number="305"/> + <line hits="1" number="307"/> + <line hits="1" number="308"/> + <line hits="1" number="310"/> + <line hits="1" number="312"/> + <line hits="1" number="313"/> + <line hits="1" number="314"/> + <line hits="1" number="315"/> + <line hits="1" number="317"/> + <line hits="1" number="319"/> + <line hits="1" number="320"/> + <line hits="1" number="321"/> + <line hits="1" number="322"/> + <line hits="1" number="323"/> + <line hits="1" number="324"/> + <line hits="1" number="327"/> + <line hits="1" number="329"/> + <line hits="1" number="330"/> + <line hits="1" number="331"/> + <line hits="1" number="332"/> + <line hits="1" number="333"/> + <line hits="1" number="334"/> + <line hits="1" number="336"/> + <line hits="1" number="343"/> + <line hits="1" number="344"/> + <line hits="1" number="345"/> + <line hits="1" number="346"/> + <line hits="1" number="347"/> + <line hits="1" number="348"/> + <line hits="1" number="349"/> + <line hits="1" number="351"/> + <line hits="1" number="352"/> + <line hits="1" number="353"/> + <line hits="1" number="354"/> + <line hits="1" number="355"/> + <line hits="1" number="356"/> + <line hits="1" number="359"/> + <line hits="1" number="361"/> + <line hits="1" number="368"/> + <line hits="1" number="369"/> + <line hits="1" number="370"/> + <line hits="1" number="371"/> + <line hits="1" number="372"/> + <line hits="1" number="373"/> + <line hits="1" number="374"/> + <line hits="1" number="375"/> + <line hits="1" number="376"/> + <line hits="1" number="378"/> + <line hits="1" number="380"/> + <line hits="1" number="381"/> + <line hits="1" number="382"/> + <line hits="1" number="384"/> + <line hits="1" number="385"/> + <line hits="1" number="387"/> + <line hits="1" number="388"/> + <line hits="1" number="389"/> + <line hits="1" number="390"/> + <line hits="1" number="392"/> + <line hits="1" number="394"/> + <line hits="1" number="395"/> + <line hits="1" number="396"/> + <line hits="1" number="400"/> + <line hits="1" number="402"/> + <line hits="1" number="403"/> + <line hits="1" number="405"/> + <line hits="1" number="410"/> + <line hits="1" number="412"/> + <line hits="1" number="413"/> + <line hits="1" number="414"/> + <line hits="1" number="418"/> + <line hits="1" number="420"/> + <line hits="1" number="421"/> + <line hits="1" number="423"/> + <line hits="1" number="427"/> + <line hits="1" number="429"/> + <line hits="1" number="430"/> + <line hits="1" number="432"/> + <line hits="1" number="434"/> + <line hits="1" number="436"/> + <line hits="1" number="437"/> + <line hits="1" number="438"/> + <line hits="1" number="439"/> + <line hits="1" number="441"/> + <line hits="1" number="442"/> + <line hits="1" number="443"/> + <line hits="1" number="445"/> + <line hits="1" number="447"/> + <line hits="1" number="448"/> + <line hits="1" number="449"/> + <line hits="1" number="451"/> + <line hits="1" number="452"/> + <line hits="1" number="453"/> + <line hits="1" number="454"/> + <line hits="1" number="456"/> + <line hits="1" number="457"/> + <line hits="1" number="459"/> + <line hits="1" number="462"/> + <line hits="1" number="463"/> + <line hits="1" number="464"/> + <line hits="1" number="465"/> + <line hits="1" number="467"/> + <line hits="1" number="468"/> + <line hits="1" number="470"/> + <line hits="1" number="473"/> + <line hits="1" number="475"/> + <line hits="1" number="476"/> + <line hits="1" number="478"/> + <line hits="1" number="480"/> + <line hits="1" number="482"/> + <line hits="1" number="483"/> + <line hits="1" number="484"/> + <line hits="1" number="485"/> + <line hits="1" number="488"/> + <line hits="1" number="490"/> + <line hits="1" number="491"/> + <line hits="1" number="492"/> + <line hits="1" number="494"/> + <line hits="1" number="495"/> + <line hits="1" number="497"/> + <line hits="1" number="498"/> + <line hits="1" number="500"/> + <line hits="1" number="502"/> + <line hits="1" number="503"/> + <line hits="1" number="504"/> + <line hits="1" number="505"/> + <line hits="1" number="506"/> + <line hits="1" number="507"/> + <line hits="1" number="509"/> + <line hits="1" number="511"/> + <line hits="1" number="512"/> + <line hits="1" number="514"/> + <line hits="1" number="515"/> + <line hits="1" number="516"/> + <line hits="1" number="518"/> + <line hits="1" number="520"/> + <line hits="1" number="521"/> + <line hits="1" number="523"/> + <line hits="1" number="524"/> + <line hits="1" number="525"/> + <line hits="1" number="527"/> + <line hits="1" number="528"/> + <line hits="1" number="529"/> + <line hits="1" number="530"/> + <line hits="1" number="532"/> + <line hits="1" number="533"/> + <line hits="1" number="535"/> + <line hits="1" number="536"/> + <line hits="1" number="537"/> + <line hits="1" number="538"/> + <line hits="1" number="539"/> + <line hits="1" number="540"/> + </lines> + </class> <class branch-rate="1" complexity="0" filename="tests/unit/common/test_template_format.py" line-rate="1" name="test_template_format.py"> <methods/> <lines> @@ -4400,7 +4752,40 @@ </class> </classes> </package> - <package branch-rate="0.8333" complexity="0" line-rate="0.9961" name="tests.unit.core"> + <package branch-rate="1" complexity="0" line-rate="1" name="tests.unit.context"> + <classes> + <class branch-rate="1" complexity="0" filename="tests/unit/context/__init__.py" line-rate="1" name="__init__.py"> + <methods/> + <lines/> + </class> + <class branch-rate="1" complexity="0" filename="tests/unit/context/test_heat.py" line-rate="1" name="test_heat.py"> + <methods/> + <lines> + <line hits="1" number="15"/> + <line hits="1" number="17"/> + <line hits="1" number="18"/> + <line hits="1" number="20"/> + <line hits="1" number="22"/> + <line hits="1" number="23"/> + <line hits="1" number="24"/> + <line hits="1" number="27"/> + <line hits="1" number="29"/> + <line hits="1" number="30"/> + <line hits="1" number="31"/> + <line hits="1" number="32"/> + <line hits="1" number="33"/> + <line hits="1" number="35"/> + <line hits="1" number="42"/> + <line hits="1" number="43"/> + <line hits="1" number="44"/> + <line hits="1" number="45"/> + <line hits="1" number="46"/> + <line hits="1" number="47"/> + </lines> + </class> + </classes> + </package> + <package branch-rate="0.8333" complexity="0" line-rate="0.7778" name="tests.unit.core"> <classes> <class branch-rate="1" complexity="0" filename="tests/unit/core/__init__.py" line-rate="1" name="__init__.py"> <methods/> @@ -4580,7 +4965,7 @@ <line hits="1" number="58"/> </lines> </class> - <class branch-rate="1" complexity="0" filename="tests/unit/core/test_task.py" line-rate="0.9875" name="test_task.py"> + <class branch-rate="1" complexity="0" filename="tests/unit/core/test_task.py" line-rate="0.3684" name="test_task.py"> <methods/> <lines> <line hits="1" number="17"/> @@ -4614,55 +4999,70 @@ <line hits="1" number="67"/> <line hits="1" number="68"/> <line hits="1" number="69"/> + <line hits="1" number="70"/> <line hits="1" number="71"/> - <line hits="1" number="72"/> - <line hits="1" number="73"/> <line hits="1" number="74"/> - <line hits="1" number="76"/> - <line hits="1" number="78"/> - <line hits="1" number="79"/> - <line hits="1" number="80"/> - <line hits="1" number="81"/> - <line hits="1" number="83"/> - <line hits="1" number="84"/> - <line hits="1" number="85"/> - <line hits="1" number="86"/> - <line hits="1" number="88"/> - <line hits="1" number="90"/> - <line hits="1" number="91"/> - <line hits="1" number="93"/> - <line hits="1" number="94"/> - <line hits="1" number="96"/> - <line hits="1" number="97"/> - <line hits="1" number="98"/> - <line hits="1" number="99"/> - <line hits="1" number="101"/> - <line hits="1" number="103"/> - <line hits="1" number="104"/> - <line hits="1" number="105"/> - <line hits="1" number="106"/> - <line hits="1" number="108"/> - <line hits="1" number="109"/> - <line hits="1" number="110"/> - <line hits="1" number="111"/> - <line hits="1" number="113"/> - <line hits="1" number="115"/> - <line hits="1" number="116"/> - <line hits="1" number="118"/> - <line hits="1" number="119"/> - <line hits="1" number="121"/> - <line hits="1" number="122"/> - <line hits="1" number="123"/> - <line hits="1" number="125"/> - <line hits="1" number="126"/> - <line hits="1" number="127"/> - <line hits="1" number="128"/> - <line hits="1" number="130"/> - <line hits="1" number="131"/> - <line hits="1" number="132"/> - <line hits="1" number="133"/> - <line hits="1" number="135"/> + <line hits="1" number="75"/> + <line hits="0" number="77"/> + <line hits="0" number="87"/> + <line hits="0" number="88"/> + <line hits="0" number="89"/> + <line hits="0" number="90"/> + <line hits="0" number="91"/> + <line hits="0" number="92"/> + <line hits="0" number="93"/> + <line hits="0" number="94"/> + <line hits="0" number="95"/> + <line hits="0" number="96"/> + <line hits="0" number="98"/> + <line hits="0" number="99"/> + <line hits="0" number="100"/> + <line hits="0" number="101"/> + <line hits="0" number="103"/> + <line hits="0" number="105"/> + <line hits="0" number="106"/> + <line hits="0" number="107"/> + <line hits="0" number="108"/> + <line hits="0" number="110"/> + <line hits="0" number="111"/> + <line hits="0" number="112"/> + <line hits="0" number="113"/> + <line hits="0" number="115"/> + <line hits="0" number="117"/> + <line hits="0" number="118"/> + <line hits="0" number="120"/> + <line hits="0" number="121"/> + <line hits="0" number="123"/> + <line hits="0" number="124"/> + <line hits="0" number="125"/> + <line hits="0" number="126"/> + <line hits="0" number="128"/> + <line hits="0" number="130"/> + <line hits="0" number="131"/> + <line hits="0" number="132"/> + <line hits="0" number="133"/> + <line hits="0" number="135"/> <line hits="0" number="136"/> + <line hits="0" number="137"/> + <line hits="0" number="138"/> + <line hits="0" number="140"/> + <line hits="0" number="142"/> + <line hits="0" number="143"/> + <line hits="0" number="145"/> + <line hits="0" number="146"/> + <line hits="0" number="148"/> + <line hits="0" number="149"/> + <line hits="0" number="150"/> + <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="158"/> + <line hits="0" number="159"/> + <line hits="0" number="160"/> + <line hits="0" number="162"/> + <line hits="0" number="163"/> </lines> </class> <class branch-rate="1" complexity="0" filename="tests/unit/core/test_testcase.py" line-rate="1" name="test_testcase.py"> diff --git a/tools/cover.sh b/tools/cover.sh index e9b9cc5..dc6785b 100644 --- a/tools/cover.sh +++ b/tools/cover.sh @@ -31,6 +31,7 @@ run_coverage_test() { coverage run -p -m unittest discover ./vnftest/tests/unit/core coverage run -p -m unittest discover ./vnftest/tests/unit/onap coverage run -p -m unittest discover ./vnftest/tests/unit/common + coverage run -p -m unittest discover ./vnftest/tests/unit/context coverage combine coverage xml coverage erase diff --git a/vnftest/runners/iteration.py b/vnftest/runners/iteration.py index 1d62bca..03bfa0f 100644 --- a/vnftest/runners/iteration.py +++ b/vnftest/runners/iteration.py @@ -57,7 +57,7 @@ def _worker_process(result_queue, cls, method_name, step_cfg, method = getattr(step, method_name) - sla_action = None + sla_action = "assert" if "sla" in step_cfg: sla_action = step_cfg["sla"].get("action", "assert") if "run" in run_step: diff --git a/vnftest/tests/unit/common/test_ssh.py b/vnftest/tests/unit/common/test_ssh.py new file mode 100644 index 0000000..a571f29 --- /dev/null +++ b/vnftest/tests/unit/common/test_ssh.py @@ -0,0 +1,542 @@ +############################################################################## +# Copyright 2018 EuropeanSoftwareMarketingLtd. +# =================================================================== +# Licensed under the ApacheLicense, Version2.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 +# +# 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 +############################################################################## +# vnftest comment: this is a modified copy of +# yardstick/tests/unit/test_ssh.py + + +import os +import socket +import unittest +from io import StringIO +from itertools import count + +import mock +from oslo_utils import encodeutils +from vnftest import ssh + +from vnftest.ssh import SSHError, AutoConnectSSH, SSHTimeout, SSH + + +class FakeParamikoException(Exception): + pass + + +class SSHTestCase(unittest.TestCase): + """Test all small SSH methods.""" + + def setUp(self): + super(SSHTestCase, self).setUp() + self.test_client = ssh.SSH("root", "example.net") + + @mock.patch("vnftest.ssh.SSH._get_pkey") + def test_construct(self, mock_ssh__get_pkey): + mock_ssh__get_pkey.return_value = "pkey" + test_ssh = ssh.SSH("root", "example.net", port=33, pkey="key", + key_filename="kf", password="secret") + mock_ssh__get_pkey.assert_called_once_with("key") + self.assertEqual("root", test_ssh.user) + self.assertEqual("example.net", test_ssh.host) + self.assertEqual(33, test_ssh.port) + self.assertEqual("pkey", test_ssh.pkey) + self.assertEqual("kf", test_ssh.key_filename) + self.assertEqual("secret", test_ssh.password) + + @mock.patch("vnftest.ssh.SSH._get_pkey") + def test_ssh_from_node(self, mock_ssh__get_pkey): + mock_ssh__get_pkey.return_value = "pkey" + node = { + "user": "root", "ip": "example.net", "ssh_port": 33, + "key_filename": "kf", "password": "secret" + } + test_ssh = ssh.SSH.from_node(node) + self.assertEqual("root", test_ssh.user) + self.assertEqual("example.net", test_ssh.host) + self.assertEqual(33, test_ssh.port) + self.assertEqual("kf", test_ssh.key_filename) + self.assertEqual("secret", test_ssh.password) + + @mock.patch("vnftest.ssh.SSH._get_pkey") + def test_ssh_from_node_password_default(self, mock_ssh__get_pkey): + mock_ssh__get_pkey.return_value = "pkey" + node = { + "user": "root", "ip": "example.net", "ssh_port": 33, + "key_filename": "kf" + } + test_ssh = ssh.SSH.from_node(node) + self.assertEqual("root", test_ssh.user) + self.assertEqual("example.net", test_ssh.host) + self.assertEqual(33, test_ssh.port) + self.assertEqual("kf", test_ssh.key_filename) + self.assertIsNone(test_ssh.password) + + @mock.patch("vnftest.ssh.SSH._get_pkey") + def test_ssh_from_node_ssh_port_default(self, mock_ssh__get_pkey): + mock_ssh__get_pkey.return_value = "pkey" + node = { + "user": "root", "ip": "example.net", + "key_filename": "kf", "password": "secret" + } + test_ssh = ssh.SSH.from_node(node) + self.assertEqual("root", test_ssh.user) + self.assertEqual("example.net", test_ssh.host) + self.assertEqual(ssh.SSH.SSH_PORT, test_ssh.port) + self.assertEqual("kf", test_ssh.key_filename) + self.assertEqual("secret", test_ssh.password) + + @mock.patch("vnftest.ssh.SSH._get_pkey") + def test_ssh_from_node_key_filename_default(self, mock_ssh__get_pkey): + mock_ssh__get_pkey.return_value = "pkey" + node = { + "user": "root", "ip": "example.net", "ssh_port": 33, + "password": "secret" + } + test_ssh = ssh.SSH.from_node(node) + self.assertEqual("root", test_ssh.user) + self.assertEqual("example.net", test_ssh.host) + self.assertEqual(33, test_ssh.port) + self.assertIsNone(test_ssh.key_filename) + self.assertEqual("secret", test_ssh.password) + + def test_construct_default(self): + self.assertEqual("root", self.test_client.user) + self.assertEqual("example.net", self.test_client.host) + self.assertEqual(22, self.test_client.port) + self.assertIsNone(self.test_client.pkey) + self.assertIsNone(self.test_client.key_filename) + self.assertIsNone(self.test_client.password) + + @mock.patch("vnftest.ssh.paramiko") + def test__get_pkey_invalid(self, mock_paramiko): + mock_paramiko.SSHException = FakeParamikoException + rsa = mock_paramiko.rsakey.RSAKey + dss = mock_paramiko.dsskey.DSSKey + rsa.from_private_key.side_effect = mock_paramiko.SSHException + dss.from_private_key.side_effect = mock_paramiko.SSHException + self.assertRaises(SSHError, self.test_client._get_pkey, "key") + + @mock.patch("vnftest.ssh.six.moves.StringIO") + @mock.patch("vnftest.ssh.paramiko") + def test__get_pkey_dss(self, mock_paramiko, mock_string_io): + mock_paramiko.SSHException = FakeParamikoException + mock_string_io.return_value = "string_key" + mock_paramiko.dsskey.DSSKey.from_private_key.return_value = "dss_key" + rsa = mock_paramiko.rsakey.RSAKey + rsa.from_private_key.side_effect = mock_paramiko.SSHException + key = self.test_client._get_pkey("key") + dss_calls = mock_paramiko.dsskey.DSSKey.from_private_key.mock_calls + self.assertEqual([mock.call("string_key")], dss_calls) + self.assertEqual(key, "dss_key") + mock_string_io.assert_called_once_with("key") + + @mock.patch("vnftest.ssh.six.moves.StringIO") + @mock.patch("vnftest.ssh.paramiko") + def test__get_pkey_rsa(self, mock_paramiko, mock_string_io): + mock_paramiko.SSHException = FakeParamikoException + mock_string_io.return_value = "string_key" + mock_paramiko.rsakey.RSAKey.from_private_key.return_value = "rsa_key" + dss = mock_paramiko.dsskey.DSSKey + dss.from_private_key.side_effect = mock_paramiko.SSHException + key = self.test_client._get_pkey("key") + rsa_calls = mock_paramiko.rsakey.RSAKey.from_private_key.mock_calls + self.assertEqual([mock.call("string_key")], rsa_calls) + self.assertEqual(key, "rsa_key") + mock_string_io.assert_called_once_with("key") + + @mock.patch("vnftest.ssh.SSH._get_pkey") + @mock.patch("vnftest.ssh.paramiko") + def test__get_client(self, mock_paramiko, mock_ssh__get_pkey): + mock_ssh__get_pkey.return_value = "key" + fake_client = mock.Mock() + mock_paramiko.SSHClient.return_value = fake_client + mock_paramiko.AutoAddPolicy.return_value = "autoadd" + + test_ssh = ssh.SSH("admin", "example.net", pkey="key") + client = test_ssh._get_client() + + self.assertEqual(fake_client, client) + client_calls = [ + mock.call.set_missing_host_key_policy("autoadd"), + mock.call.connect("example.net", username="admin", + port=22, pkey="key", key_filename=None, + password=None, + allow_agent=False, look_for_keys=False, + timeout=1), + ] + self.assertEqual(client_calls, client.mock_calls) + + @mock.patch("vnftest.ssh.SSH._get_pkey") + @mock.patch("vnftest.ssh.paramiko") + def test__get_client_with_exception(self, mock_paramiko, mock_ssh__get_pkey): + class MyError(Exception): + pass + + mock_ssh__get_pkey.return_value = "pkey" + fake_client = mock.Mock() + fake_client.connect.side_effect = MyError + fake_client.set_missing_host_key_policy.return_value = None + mock_paramiko.SSHClient.return_value = fake_client + mock_paramiko.AutoAddPolicy.return_value = "autoadd" + + test_ssh = ssh.SSH("admin", "example.net", pkey="key") + + with self.assertRaises(SSHError) as raised: + test_ssh._get_client() + + mock_paramiko.SSHClient.assert_called_once() + mock_paramiko.AutoAddPolicy.assert_called_once() + fake_client.set_missing_host_key_policy.assert_called_once() + fake_client.connect.assert_called_once() + exc_str = str(raised.exception) + self.assertIn('raised during connect', exc_str) + self.assertIn('MyError', exc_str) + + @mock.patch("vnftest.ssh.SSH._get_pkey") + @mock.patch("vnftest.ssh.paramiko") + def test_copy(self, mock_paramiko, mock_ssh__get_pkey): + mock_ssh__get_pkey.return_value = "pkey" + fake_client = mock.Mock() + fake_client.connect.side_effect = IOError + mock_paramiko.SSHClient.return_value = fake_client + mock_paramiko.AutoAddPolicy.return_value = "autoadd" + + test_ssh = ssh.SSH("admin", "example.net", pkey="key") + result = test_ssh.copy() + self.assertIsNot(test_ssh, result) + + def test_close(self): + with mock.patch.object(self.test_client, "_client") as m_client: + self.test_client.close() + m_client.close.assert_called_once_with() + self.assertFalse(self.test_client._client) + + @mock.patch("vnftest.ssh.time") + def test_wait_timeout(self, mock_time): + mock_time.time.side_effect = [1, 50, 150] + self.test_client.execute = mock.Mock(side_effect=[SSHError, + SSHError, + 0]) + self.assertRaises(SSHTimeout, self.test_client.wait) + self.assertEqual([mock.call("uname")] * 2, + self.test_client.execute.mock_calls) + + @mock.patch("vnftest.ssh.time") + def test_wait(self, mock_time): + mock_time.time.side_effect = [1, 50, 100] + self.test_client.execute = mock.Mock(side_effect=[SSHError, + SSHError, + 0]) + self.test_client.wait() + self.assertEqual([mock.call("uname")] * 3, + self.test_client.execute.mock_calls) + + @mock.patch("vnftest.ssh.paramiko") + def test_send_command(self, _): + paramiko_sshclient = self.test_client._get_client() + with mock.patch.object(paramiko_sshclient, "exec_command") \ + as mock_paramiko_exec_command: + self.test_client.send_command('cmd') + mock_paramiko_exec_command.assert_called_once_with('cmd', + get_pty=True) + + +class SSHRunTestCase(unittest.TestCase): + """Test SSH.run method in different aspects. + + Also tested method "execute". + """ + + def setUp(self): + super(SSHRunTestCase, self).setUp() + + self.fake_client = mock.Mock() + self.fake_session = mock.Mock() + self.fake_transport = mock.Mock() + + self.fake_transport.open_session.return_value = self.fake_session + self.fake_client.get_transport.return_value = self.fake_transport + + self.fake_session.recv_ready.return_value = False + self.fake_session.recv_stderr_ready.return_value = False + self.fake_session.send_ready.return_value = False + self.fake_session.exit_status_ready.return_value = True + self.fake_session.recv_exit_status.return_value = 0 + + self.test_client = ssh.SSH("admin", "example.net") + self.test_client._get_client = mock.Mock(return_value=self.fake_client) + + @mock.patch("vnftest.ssh.select") + def test_execute(self, mock_select): + mock_select.select.return_value = ([], [], []) + self.fake_session.recv_ready.side_effect = [1, 0, 0] + self.fake_session.recv_stderr_ready.side_effect = [1, 0] + self.fake_session.recv.return_value = "ok" + self.fake_session.recv_stderr.return_value = "error" + self.fake_session.exit_status_ready.return_value = 1 + self.fake_session.recv_exit_status.return_value = 127 + self.assertEqual((127, "ok", "error"), self.test_client.execute("cmd")) + self.fake_session.exec_command.assert_called_once_with("cmd") + + @mock.patch("vnftest.ssh.select") + def test_execute_args(self, mock_select): + mock_select.select.return_value = ([], [], []) + self.fake_session.recv_ready.side_effect = [1, 0, 0] + self.fake_session.recv_stderr_ready.side_effect = [1, 0] + self.fake_session.recv.return_value = "ok" + self.fake_session.recv_stderr.return_value = "error" + self.fake_session.exit_status_ready.return_value = 1 + self.fake_session.recv_exit_status.return_value = 127 + + result = self.test_client.execute("cmd arg1 'arg2 with space'") + self.assertEqual((127, "ok", "error"), result) + self.fake_session.exec_command.assert_called_once_with( + "cmd arg1 'arg2 with space'") + + @mock.patch("vnftest.ssh.select") + def test_run(self, mock_select): + mock_select.select.return_value = ([], [], []) + self.assertEqual(0, self.test_client.run("cmd")) + + @mock.patch("vnftest.ssh.select") + def test_run_nonzero_status(self, mock_select): + mock_select.select.return_value = ([], [], []) + self.fake_session.recv_exit_status.return_value = 1 + self.assertRaises(SSHError, self.test_client.run, "cmd") + self.assertEqual(1, self.test_client.run("cmd", raise_on_error=False)) + + @mock.patch("vnftest.ssh.select") + def test_run_stdout(self, mock_select): + mock_select.select.return_value = ([], [], []) + self.fake_session.recv_ready.side_effect = [True, True, False] + self.fake_session.recv.side_effect = ["ok1", "ok2"] + stdout = mock.Mock() + self.test_client.run("cmd", stdout=stdout) + self.assertEqual([mock.call("ok1"), mock.call("ok2")], + stdout.write.mock_calls) + + @mock.patch("vnftest.ssh.select") + def test_run_stderr(self, mock_select): + mock_select.select.return_value = ([], [], []) + self.fake_session.recv_stderr_ready.side_effect = [True, False] + self.fake_session.recv_stderr.return_value = "error" + stderr = mock.Mock() + self.test_client.run("cmd", stderr=stderr) + stderr.write.assert_called_once_with("error") + + @mock.patch("vnftest.ssh.select") + def test_run_stdin(self, mock_select): + """Test run method with stdin. + + Third send call was called with "e2" because only 3 bytes was sent + by second call. So remainig 2 bytes of "line2" was sent by third call. + """ + mock_select.select.return_value = ([], [], []) + self.fake_session.exit_status_ready.side_effect = [0, 0, 0, True] + self.fake_session.send_ready.return_value = True + self.fake_session.send.side_effect = [5, 3, 2] + fake_stdin = mock.Mock() + fake_stdin.read.side_effect = ["line1", "line2", ""] + fake_stdin.closed = False + + def close(): + fake_stdin.closed = True + fake_stdin.close = mock.Mock(side_effect=close) + self.test_client.run("cmd", stdin=fake_stdin) + call = mock.call + send_calls = [call(encodeutils.safe_encode("line1", "utf-8")), + call(encodeutils.safe_encode("line2", "utf-8")), + call(encodeutils.safe_encode("e2", "utf-8"))] + self.assertEqual(send_calls, self.fake_session.send.mock_calls) + + @mock.patch("vnftest.ssh.select") + def test_run_stdin_keep_open(self, mock_select): + """Test run method with stdin. + + Third send call was called with "e2" because only 3 bytes was sent + by second call. So remainig 2 bytes of "line2" was sent by third call. + """ + mock_select.select.return_value = ([], [], []) + self.fake_session.exit_status_ready.side_effect = [0, 0, 0, True] + self.fake_session.send_ready.return_value = True + self.fake_session.send.side_effect = len + fake_stdin = StringIO(u"line1\nline2\n") + self.test_client.run("cmd", stdin=fake_stdin, keep_stdin_open=True) + call = mock.call + send_calls = [call(encodeutils.safe_encode("line1\nline2\n", "utf-8"))] + self.assertEqual(send_calls, self.fake_session.send.mock_calls) + + @mock.patch("vnftest.ssh.select") + def test_run_select_error(self, mock_select): + self.fake_session.exit_status_ready.return_value = False + mock_select.select.return_value = ([], [], [True]) + self.assertRaises(SSHError, self.test_client.run, "cmd") + + @mock.patch("vnftest.ssh.time") + @mock.patch("vnftest.ssh.select") + def test_run_timemout(self, mock_select, mock_time): + mock_time.time.side_effect = [1, 3700] + mock_select.select.return_value = ([], [], []) + self.fake_session.exit_status_ready.return_value = False + self.assertRaises(SSHTimeout, self.test_client.run, "cmd") + + @mock.patch("vnftest.ssh.open", create=True) + def test__put_file_shell(self, mock_open): + with mock.patch.object(self.test_client, "run") as run_mock: + self.test_client._put_file_shell("localfile", "remotefile", 0o42) + run_mock.assert_called_once_with( + 'cat > "remotefile"&& chmod -- 042 "remotefile"', + stdin=mock_open.return_value.__enter__.return_value) + + @mock.patch("vnftest.ssh.open", create=True) + def test__put_file_shell_space(self, mock_open): + with mock.patch.object(self.test_client, "run") as run_mock: + self.test_client._put_file_shell("localfile", + "filename with space", 0o42) + run_mock.assert_called_once_with( + 'cat > "filename with space"&& chmod -- 042 "filename with ' + 'space"', + stdin=mock_open.return_value.__enter__.return_value) + + @mock.patch("vnftest.ssh.open", create=True) + def test__put_file_shell_tilde(self, mock_open): + with mock.patch.object(self.test_client, "run") as run_mock: + self.test_client._put_file_shell("localfile", "~/remotefile", 0o42) + run_mock.assert_called_once_with( + 'cat > ~/"remotefile"&& chmod -- 042 ~/"remotefile"', + stdin=mock_open.return_value.__enter__.return_value) + + @mock.patch("vnftest.ssh.open", create=True) + def test__put_file_shell_tilde_spaces(self, mock_open): + with mock.patch.object(self.test_client, "run") as run_mock: + self.test_client._put_file_shell("localfile", "~/file with space", + 0o42) + run_mock.assert_called_once_with( + 'cat > ~/"file with space"&& chmod -- 042 ~/"file with space"', + stdin=mock_open.return_value.__enter__.return_value) + + @mock.patch("vnftest.ssh.os.stat") + def test__put_file_sftp(self, mock_stat): + sftp = self.fake_client.open_sftp.return_value = mock.MagicMock() + sftp.__enter__.return_value = sftp + + mock_stat.return_value = os.stat_result([0o753] + [0] * 9) + + self.test_client._put_file_sftp("localfile", "remotefile") + + sftp.put.assert_called_once_with("localfile", "remotefile") + mock_stat.assert_any_call("localfile") + sftp.chmod.assert_any_call("remotefile", 0o753) + sftp.__exit__.assert_called_once_with(None, None, None) + + def test__put_file_sftp_mode(self): + sftp = self.fake_client.open_sftp.return_value = mock.MagicMock() + sftp.__enter__.return_value = sftp + + self.test_client._put_file_sftp("localfile", "remotefile", mode=0o753) + + sftp.put.assert_called_once_with("localfile", "remotefile") + sftp.chmod.assert_called_once_with("remotefile", 0o753) + sftp.__exit__.assert_called_once_with(None, None, None) + + def test_put_file_SSHException(self): + exc = ssh.paramiko.SSHException + self.test_client._put_file_sftp = mock.Mock(side_effect=exc()) + self.test_client._put_file_shell = mock.Mock() + + self.test_client.put_file("foo", "bar", 42) + self.test_client._put_file_sftp.assert_called_once_with("foo", "bar", + mode=42) + self.test_client._put_file_shell.assert_called_once_with("foo", "bar", + mode=42) + + def test_put_file_socket_error(self): + exc = socket.error + self.test_client._put_file_sftp = mock.Mock(side_effect=exc()) + self.test_client._put_file_shell = mock.Mock() + + self.test_client.put_file("foo", "bar", 42) + self.test_client._put_file_sftp.assert_called_once_with("foo", "bar", + mode=42) + self.test_client._put_file_shell.assert_called_once_with("foo", "bar", + mode=42) + + @mock.patch("vnftest.ssh.os.stat") + def test_put_file_obj_with_mode(self, mock_stat): + sftp = self.fake_client.open_sftp.return_value = mock.MagicMock() + sftp.__enter__.return_value = sftp + + mock_stat.return_value = os.stat_result([0o753] + [0] * 9) + + self.test_client.put_file_obj("localfile", "remotefile", 'my_mode') + + sftp.__enter__.assert_called_once() + sftp.putfo.assert_called_once_with("localfile", "remotefile") + sftp.chmod.assert_called_once_with("remotefile", 'my_mode') + sftp.__exit__.assert_called_once_with(None, None, None) + + +class TestAutoConnectSSH(unittest.TestCase): + + def test__connect_loop(self): + auto_connect_ssh = AutoConnectSSH('user1', 'host1', wait=0) + auto_connect_ssh._get_client = mock__get_client = mock.Mock() + + auto_connect_ssh._connect() + mock__get_client.assert_called_once() + + def test_get_class(self): + auto_connect_ssh = AutoConnectSSH('user1', 'host1') + + self.assertEqual(auto_connect_ssh.get_class(), AutoConnectSSH) + + def test_drop_connection(self): + auto_connect_ssh = AutoConnectSSH('user1', 'host1') + self.assertFalse(auto_connect_ssh._client) + auto_connect_ssh._client = True + auto_connect_ssh.drop_connection() + self.assertFalse(auto_connect_ssh._client) + + @mock.patch('vnftest.ssh.SCPClient') + def test_put(self, mock_scp_client_type): + auto_connect_ssh = AutoConnectSSH('user1', 'host1') + auto_connect_ssh._client = mock.Mock() + + auto_connect_ssh.put('a', 'z') + with mock_scp_client_type() as mock_scp_client: + mock_scp_client.put.assert_called_once() + + @mock.patch('vnftest.ssh.SCPClient') + def test_get(self, mock_scp_client_type): + auto_connect_ssh = AutoConnectSSH('user1', 'host1') + auto_connect_ssh._client = mock.Mock() + + auto_connect_ssh.get('a', 'z') + with mock_scp_client_type() as mock_scp_client: + mock_scp_client.get.assert_called_once() + + def test_put_file(self): + auto_connect_ssh = AutoConnectSSH('user1', 'host1') + auto_connect_ssh._client = mock.Mock() + auto_connect_ssh._put_file_sftp = mock_put_sftp = mock.Mock() + + auto_connect_ssh.put_file('a', 'b') + mock_put_sftp.assert_called_once() + + def test_execute(self): + auto_connect_ssh = AutoConnectSSH('user1', 'host1') + auto_connect_ssh._client = mock.Mock() + auto_connect_ssh.run = mock.Mock(return_value=0) + exit_code, _, _ = auto_connect_ssh.execute('') + self.assertEqual(exit_code, 0) + + diff --git a/vnftest/tests/unit/context/__init__.py b/vnftest/tests/unit/context/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/vnftest/tests/unit/context/__init__.py diff --git a/vnftest/tests/unit/context/test_heat.py b/vnftest/tests/unit/context/test_heat.py new file mode 100644 index 0000000..89799b6 --- /dev/null +++ b/vnftest/tests/unit/context/test_heat.py @@ -0,0 +1,47 @@ +############################################################################## +# Copyright 2018 EuropeanSoftwareMarketingLtd. +# =================================================================== +# Licensed under the ApacheLicense, Version2.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 +# +# 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 +############################################################################## + +import unittest + +import mock +import os + +from vnftest.contexts.heat import HeatContext + +from vnftest.common import constants as consts +from vnftest.core import task +from vnftest.common import openstack_utils + + +class HeatTestCase(unittest.TestCase): + + @mock.patch.object(HeatContext, 'check_environment') + @mock.patch.object(HeatContext, '_create_new_stack') + @mock.patch.object(HeatContext, 'get_neutron_info') + @mock.patch.object(openstack_utils, 'get_shade_client') + @mock.patch.object(openstack_utils, 'get_shade_operator_client') + def test_heat(self, mock_check_env, mock_create, mocke_neutron, shade_client, operator_client): + params = { + "task_id": "123", + "name": "heat-test", + "image": "test_image", + "flavor" : "test_flavor", + "user": "test_user", + "servers": {}} + mock_create.return_value = {} + h = HeatContext() + h.init(params) + h.deploy() + h._get_server("dummy") + h.undeploy() diff --git a/vnftest/tests/unit/core/test_task.py b/vnftest/tests/unit/core/test_task.py index 7f26d61..abec5ae 100644 --- a/vnftest/tests/unit/core/test_task.py +++ b/vnftest/tests/unit/core/test_task.py @@ -67,6 +67,8 @@ class TaskTestCase(unittest.TestCase): mock_base_runner.Runner.get.return_value = runner t._run([step], 'dummy_case', False, "vnftest.out", {}) self.assertTrue(runner.run.called) + results = t.task_info.result() + self.assertEqual(results["testcases"][0]["status"], "FINISHED") def test_parse_suite_no_constraint_no_args(self): SAMPLE_step_PATH = "no_constraint_no_args_step_sample.yaml" |