summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--coverage.xml1042
-rw-r--r--tools/cover.sh1
-rw-r--r--vnftest/runners/iteration.py2
-rw-r--r--vnftest/tests/unit/common/test_ssh.py542
-rw-r--r--vnftest/tests/unit/context/__init__.py0
-rw-r--r--vnftest/tests/unit/context/test_heat.py47
-rw-r--r--vnftest/tests/unit/core/test_task.py2
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"