Thomas Vachuska

Added check for cyclic dependencies.

Changes intent test scenarios to use the key and added dependencies to make them more robust; h2h still fails intermittently due to a bug.

Increased parallelism of the smoke test scenario.

Change-Id: Ib7fed38d17d1b25c5dd854ef1cd4dc777002c5fc
......@@ -9,16 +9,26 @@
aux=/tmp/stc-$$.log
trap "rm -f $aux $aux.1 $aux.2 2>/dev/null" EXIT
onos ${1:-$OCI} "onos:apps -s -a" | grep -v /bin/client > $aux
cat $aux
for attempt in {1..3}; do
onos ${1:-$OCI} "onos:apps -s -a" | grep -v /bin/client > $aux
cat $aux
# Normalize the installed apps
cut -c7- $aux | grep -v '/bin/client' | cut -d\ -f1 | sort > $aux.1
# Normalize the installed apps
cut -c7- $aux | grep -v '/bin/client' | cut -d\ -f1 | sort > $aux.1
# Normalize the expected apps
apps=${2:-$ONOS_APPS}
apps=${apps:-drivers,openflow}
(for app in ${apps//,/ }; do echo org.onosproject.$app; done) | sort > $aux.2
# Normalize the expected apps
apps=${2:-$ONOS_APPS}
apps=${apps:-drivers,openflow}
(for app in ${apps//,/ }; do echo org.onosproject.$app; done) | sort > $aux.2
# Check for differences
diff $aux.1 $aux.2
# Check for differences
case ${3:-equals} in
equals) diff $aux.1 $aux.2;;
includes) [ $(egrep -c -f $aux.2 $aux.1) -eq $(wc -l $aux.2 | sed "s|$aux.2||g") ];;
excludes) ! egrep -f $aux.2 $aux.1;;
esac
[ $? -eq 0 ] && exit 0 || sleep 1
done
exit 1;
......
......@@ -13,9 +13,9 @@ target=${1:-$OCI}
echo onos-check-intent: $*
set -x
for i in 1 2 3; do
onos $target "onos:intents" > $aux
( cat $aux | grep "id=$2" | grep "state=$3" ) && cat $aux && exit 0
for i in {1..10}; do
onos $target "onos:intents" | tee $aux
( cat $aux | grep "key=$2" | grep "state=$3" ) && cat $aux && exit 0
sleep 1
done
......
......@@ -18,15 +18,5 @@ arg2=$5
set -x
onos $target "onos:add-${type}-intent" "${arg1}" "${arg2}" >> $aux
result=$?
cat $aux
if [ $result -eq 0 ]; then
id=$(cat $aux | sed -e "1d" | sed -e "s/^[a-zA-Z]*{//" | sed -e "s/,.*$//" | sed -e "s/^...//")
echo @stc ${name}Id=${id}
fi
exit $result
onos $target "onos:add-${type}-intent" --key $name "${arg1}" "${arg2}"
......
......@@ -16,36 +16,44 @@
<scenario name="net-host-intent" description="Network host intent connectivity test">
<!-- TODO: parametrize this via recipes -->
<group name="Host-Intent-Connectivity">
<step name="Uninstall-Reactive-Forwarding"
<step name="Host-Intent.Uninstall-Reactive-Forwarding"
exec="onos ${OC1} app deactivate org.onosproject.fwd org.onosproject.ifwd"/>
<step name="Host-Intent.Check-Apps" requires="^"
exec="onos-check-apps ${OC1} fwd,ifwd excludes"/>
<step name="Find-Host-1" requires="^"
exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect ."/>
<step name="Find-Host-2" requires="^"
exec="onos-mininet sendAndExpect h4 ping -c1 h1 --expect ."/>
<step name="Host-Intent.Find-Host-1" requires="^"
exec="onos-mininet sendAndExpect h1 ping -c1 -w1 h4 --expect ."/>
<step name="Host-Intent.Find-Host-2" requires="^"
exec="onos-mininet sendAndExpect h4 ping -c1 -w1 h1 --expect ."/>
<step name="Create-Intent" requires="^"
exec="onos-create-intent ${OC1} hostToHost host 00:00:00:00:00:01/-1 00:00:00:00:00:04/-1"/>
<step name="Validate-Intent-Installed" exec="onos-check-intent ${OC1} ${hostToHostId} INSTALLED"
requires="Create-Intent" />
<step name="Host-Intent.Create-Intent" requires="^"
exec="onos-create-intent ${OC1} h2h host 00:00:00:00:00:01/-1 00:00:00:00:00:04/-1"/>
<step name="Host-Intent.Validate-Intent-Installed" requires="Host-Intent.Create-Intent"
exec="onos-check-intent ${OC1} h2h INSTALLED"/>
<import file="${ONOS_SCENARIOS}/net-link-down-up.xml" namespace="Host-Intent"/>
<dependency name="Host-Intent.Net-Link-Down-Up" requires="Validate-Intent-Installed"/>
<dependency name="Host-Intent.Net-Link-Down-Up"
requires="Host-Intent.Validate-Intent-Installed"/>
<step name="Validate-Intent-Installed-Still" exec="onos-check-intent ${OC1} ${hostToHostId} INSTALLED"
requires="Host-Intent.Link-1-Down" />
<step name="Host-Intent.Validate-Intent-Installed-Still" requires="Host-Intent.Link-1-Down"
exec="onos-check-intent ${OC1} h2h INSTALLED"/>
<step name="Validate-Intent-Failed" exec="onos-check-intent ${OC1} ${hostToHostId} FAILED"
requires="Host-Intent.Link-2-Down" />
<dependency name="Host-Intent.Link-2-Down"
requires="~Host-Intent.Validate-Intent-Installed-Still" />
<step name="Validate-Intent-Installed-Again" exec="onos-check-intent ${OC1} ${hostToHostId} INSTALLED"
requires="Host-Intent.Link-1-Up" />
<dependency name="Host-Intent.Ping-4" requires="Validate-Intent-Installed-Again" />
<step name="Host-Intent.Validate-Intent-Failed" requires="Host-Intent.Link-2-Down"
exec="onos-check-intent ${OC1} h2h FAILED"/>
<step name="Remove-Intent" requires="~Host-Intent.Net-Link-Down-Up"
exec="onos ${OC1} remove-intent -p"/>
<dependency name="Host-Intent.Link-1-Up"
requires="~Host-Intent.Validate-Intent-Failed" />
<step name="Host-Intent.Validate-Intent-Installed-Again" requires="Host-Intent.Link-1-Up"
exec="onos-check-intent ${OC1} h2h INSTALLED"/>
<dependency name="Host-Intent.Ping-4"
requires="~Host-Intent.Validate-Intent-Installed-Again" />
<step name="Host-Intent.Remove-Intent" requires="~Host-Intent.Net-Link-Down-Up"
exec="onos ${OC1} remove-intent -p org.onosproject.cli h2h"/>
</group>
</scenario>
......
......@@ -18,21 +18,21 @@
<group name="Net-Link-Down-Up">
<step name="Ping-1"
exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect \ 0% packet loss"/>
<step name="Link-1-Down" requires="Ping-1"
<step name="Link-1-Down" requires="~Ping-1"
exec="onos-mininet sendAndExpect link s4 s7 down --expect ."/>
<step name="Ping-2" requires="Link-1-Down"
<step name="Ping-2" requires="~Link-1-Down"
exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect \ 0% packet loss"/>
<step name="Link-2-Down" requires="Ping-2"
<step name="Link-2-Down" requires="~Ping-2"
exec="onos-mininet sendAndExpect link s4 s5 down --expect ."/>
<step name="Ping-3" requires="Link-2-Down"
exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect 100% packet loss"/>
<step name="Link-1-Up" requires="Ping-3"
<step name="Ping-3" requires="~Link-2-Down"
exec="onos-mininet sendAndExpect h1 ping -c1 -w1 h4 --expect 100% packet loss"/>
<step name="Link-1-Up" requires="~Ping-3"
exec="onos-mininet sendAndExpect link s4 s7 up --expect ."/>
<step name="Ping-4" requires="Link-1-Up"
<step name="Ping-4" requires="~Link-1-Up"
exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect \ 0% packet loss"/>
<step name="Link-2-Up" requires="Ping-4"
<step name="Link-2-Up" requires="~Ping-4"
exec="onos-mininet sendAndExpect link s4 s5 up --expect ."/>
<step name="Ping-5" requires="Link-2-Up"
<step name="Ping-5" requires="~Link-2-Up"
exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect \ 0% packet loss"/>
</group>
</scenario>
\ No newline at end of file
......
......@@ -18,11 +18,14 @@
<group name="Net-Pingall">
<step name="Install-Apps"
exec="onos ${OC1} app activate org.onosproject.openflow org.onosproject.proxyarp org.onosproject.fwd"/>
<step name="Check-Apps" requires="^"
exec="onos-check-apps ${OC1} drivers,openflow,proxyarp,fwd includes"/>
<step name="Check-Apps" requires="Install-Apps"
exec="onos-check-apps ${OC1} drivers,openflow,proxyarp,fwd"/>
<!-- TODO: take this out when initial pingall sweep is 100% -->
<step name="Initial-Ping-All" requires="Check-Apps"
exec="onos-mininet sendAndExpect py net.pingAll(1) --expect 600 received"/>
<step name="Ping-All-And-Verify" requires="Check-Apps"
<step name="Ping-All-And-Verify" requires="Check-Apps,Initial-Ping-All"
exec="onos-mininet sendAndExpect py net.pingAll(1) --expect 600/600 received"/>
<step name="Check-Summary-For-Hosts" requires="~Ping-All-And-Verify"
......
......@@ -13,44 +13,65 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
<scenario name="net-point-intent" description="Network point to point intent connectivity test">
<scenario name="net-point-intent"
description="Network point to point intent connectivity test">
<!-- TODO: parametrize this via recipes -->
<group name="Point-To-Point-Intent-Connectivity">
<step name="P2P-Uninstall-Reactive-Forwarding"
<group name="P2P-Intent-Connectivity">
<step name="P2P-Intent.Uninstall-Reactive-Forwarding"
exec="onos ${OC1} app deactivate org.onosproject.fwd org.onosproject.ifwd"/>
<step name="P2P-Intent.Check-Apps" requires="^"
exec="onos-check-apps ${OC1} fwd,ifwd excludes"/>
<step name="P2P-Find-Host-1" requires="^"
exec="onos-mininet sendAndExpect h1 ping -c1 h4 --expect ."/>
<step name="P2PFind-Host-2" requires="^"
exec="onos-mininet sendAndExpect h4 ping -c1 h1 --expect ."/>
<step name="P2P-Create-Intent-1-To-4" requires="^"
exec="onos-create-intent ${OC1} oneToFour point of:0000000000000001/1 of:0000000000000004/1"/>
<step name="P2P-Create-Intent-4-To-1" requires="^"
exec="onos-create-intent ${OC1} fourToOne point of:0000000000000004/1 of:0000000000000001/1"/>
<step name="P2P-Validate-Point-Intents-Installed1" exec="onos-check-intent ${OC1} ${fourToOneId} INSTALLED"
requires="^" />
<step name="P2P-Validate-Point-Intents-Installed2" exec="onos-check-intent ${OC1} ${oneToFourId} INSTALLED"
requires="^" />
<import file="${ONOS_SCENARIOS}/net-link-down-up.xml" namespace="Point-To-Point-Intent"/>
<dependency name="Point-To-Point-Intent.Net-Link-Down-Up" requires="P2P-Validate-Point-Intents-Installed2"/>
<step name="P2P-Validate-Intent-Installed-Still" exec="onos-check-intent ${OC1} ${fourToOneId} INSTALLED"
requires="Point-To-Point-Intent.Link-1-Down" />
<step name="P2P-Validate-Intent-Failed" exec="onos-check-intent ${OC1} ${fourToOneId} FAILED"
requires="Point-To-Point-Intent.Link-2-Down" />
<step name="P2P-Validate-Intent-Failed2" exec="onos-check-intent ${OC1} ${oneToFourId} FAILED"
requires="Point-To-Point-Intent.Link-2-Down" />
<step name="P2P-Validate-Intent-Installed-Again" exec="onos-check-intent ${OC1} ${fourToOneId} INSTALLED"
requires="Point-To-Point-Intent.Link-1-Up" />
<dependency name="Point-To-Point-Intent.Ping-4" requires="P2P-Validate-Intent-Installed-Again" />
<step name="P2P-Remove-Intent-4-to-1" requires="~Point-To-Point-Intent.Net-Link-Down-Up"
exec="onos ${OC1} remove-intent -p org.onosproject.cli ${fourToOneId}"/>
<step name="P2P-Remove-Intent-1-to-4" requires="^"
exec="onos ${OC1} remove-intent -p org.onosproject.cli ${oneToFourId}"/>
<step name="P2P-Intent.Find-Host-1" requires="^"
exec="onos-mininet sendAndExpect h1 ping -c1 -w1 h4 --expect ."/>
<step name="P2P-Intent.Find-Host-2" requires="^"
exec="onos-mininet sendAndExpect h4 ping -c1 -w1 h1 --expect ."/>
<step name="P2P-Intent.Create-Intent-XY" requires="^"
exec="onos-create-intent ${OC1} xy point of:0000000000000001/1 of:0000000000000004/1"/>
<step name="P2P-Intent.Create-Intent-YX" requires="^"
exec="onos-create-intent ${OC1} yx point of:0000000000000004/1 of:0000000000000001/1"/>
<step name="P2P-Intent.Validate-Intent-XY-Installed" requires="^"
exec="onos-check-intent ${OC1} yx INSTALLED"/>
<step name="P2P-Intent.Validate-Intent-YX-Installed" requires="^"
exec="onos-check-intent ${OC1} xy INSTALLED"/>
<import file="${ONOS_SCENARIOS}/net-link-down-up.xml" namespace="P2P-Intent"/>
<dependency name="P2P-Intent.Net-Link-Down-Up"
requires="P2P-Intent.Validate-Intent-XY-Installed,
P2P-Intent.Validate-Intent-YX-Installed"/>
<step name="P2P-Intent.Validate-Intent-XY-Installed-Still" requires="P2P-Intent.Link-1-Down"
exec="onos-check-intent ${OC1} xy INSTALLED"/>
<step name="P2P-Intent.Validate-Intent-YX-Installed-Still" requires="P2P-Intent.Link-1-Down"
exec="onos-check-intent ${OC1} yx INSTALLED"/>
<dependency name="P2P-Intent.Link-2-Down"
requires="~P2P-Intent.Validate-Intent-XY-Installed-Still,
~P2P-Intent.Validate-Intent-YX-Installed-Still"/>
<step name="P2P-Intent.Validate-Intent-XY-Failed" requires="P2P-Intent.Link-2-Down"
exec="onos-check-intent ${OC1} xy FAILED"/>
<step name="P2P-Intent.Validate-Intent-YX-Failed" requires="P2P-Intent.Link-2-Down"
exec="onos-check-intent ${OC1} yx FAILED"/>
<dependency name="P2P-Intent.Link-1-Up"
requires="~P2P-Intent.Validate-Intent-XY-Failed,
~P2P-Intent.Validate-Intent-YX-Failed" />
<step name="P2P-Intent.Validate-Intent-XY-Installed-Again" requires="P2P-Intent.Link-1-Up"
exec="onos-check-intent ${OC1} xy INSTALLED"/>
<step name="P2P-Intent.Validate-Intent-YX-Installed-Again" requires="P2P-Intent.Link-1-Up"
exec="onos-check-intent ${OC1} yx INSTALLED"/>
<dependency name="P2P-Intent.Ping-4"
requires="~P2P-Intent.Validate-Intent-XY-Installed-Again,
~P2P-Intent.Validate-Intent-YX-Installed-Again"/>
<step name="P2P-Intent.Remove-Intent-XY" requires="~P2P-Intent.Net-Link-Down-Up"
exec="onos ${OC1} remove-intent -p org.onosproject.cli xy"/>
<step name="P2P-Intent.Remove-Intent-YX" requires="~P2P-Intent.Net-Link-Down-Up"
exec="onos ${OC1} remove-intent -p org.onosproject.cli yx"/>
</group>
</scenario>
......
......@@ -29,7 +29,7 @@
exec="onos-mininet start topos/topo att-onos.py ${ONOS_INSTANCES}"/>
<step name="Wait-For-Mininet" requires="Start-Mininet"
exec="onos-mininet wait 20"/>
exec="onos-mininet wait 10"/>
<step name="Check-Summary" requires="Wait-For-Mininet"
exec="onos-check-summary ${OC1} [0-9]* 25 140 0"/>
......
......@@ -27,9 +27,9 @@
<dependency name="Host-Intent-Connectivity" requires="Net-Setup,~Reactive-Forwarding.Net-Link-Down-Up"/>
<import file="${ONOS_SCENARIOS}/net-point-intent.xml"/>
<dependency name="Point-To-Point-Intent-Connectivity" requires="Net-Setup,~Reactive-Forwarding.Net-Link-Down-Up,Host-Intent-Connectivity"/>
<dependency name="P2P-Intent-Connectivity" requires="Net-Setup,~Reactive-Forwarding.Net-Link-Down-Up,Host-Intent-Connectivity"/>
<import file="${ONOS_SCENARIOS}/net-teardown.xml"/>
<dependency name="Net-Teardown" requires="~Host-Intent-Connectivity,~Point-To-Point-Intent-Connectivity"/>
<dependency name="Net-Teardown" requires="~Host-Intent-Connectivity,~P2P-Intent-Connectivity"/>
</group>
</scenario>
......
......@@ -23,7 +23,7 @@
<dependency name="Net-Smoke" requires="Setup"/>
<import file="${ONOS_SCENARIOS}/archetypes.xml"/>
<dependency name="Archetypes" requires="~Net-Smoke,Setup"/>
<dependency name="Archetypes" requires="Setup"/>
<import file="${ONOS_SCENARIOS}/wrapup.xml"/>
<dependency name="Wrapup" requires="~Archetypes,~Setup,~Net-Smoke"/>
......
......@@ -21,6 +21,7 @@ import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.onlab.graph.DepthFirstSearch;
import java.io.File;
import java.io.FileInputStream;
......@@ -29,10 +30,10 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Preconditions.*;
import static com.google.common.base.Strings.isNullOrEmpty;
import static org.onlab.graph.DepthFirstSearch.EdgeType.BACK_EDGE;
import static org.onlab.graph.GraphPathSearch.ALL_PATHS;
import static org.onlab.stc.Scenario.loadScenario;
/**
......@@ -109,6 +110,8 @@ public class Compiler {
processFlow = new ProcessFlow(ImmutableSet.copyOf(steps.values()),
ImmutableSet.copyOf(dependencies));
scanForCycles();
// Extract the log directory if there was one specified
String defaultPath = DEFAULT_LOG_DIR + scenario.name();
String path = scenario.definition().getString(LOG_DIR, defaultPath);
......@@ -449,6 +452,22 @@ public class Compiler {
}
/**
* Scans the process flow graph for cyclic dependencies.
*/
private void scanForCycles() {
DepthFirstSearch<Step, Dependency> dfs = new DepthFirstSearch<>();
// Use a brute-force method of searching paths from all vertices.
processFlow().getVertexes().forEach(s -> {
DepthFirstSearch<Step, Dependency>.SpanningTreeResult r =
dfs.search(processFlow, s, null, null, ALL_PATHS);
r.edges().forEach((e, et) -> checkArgument(et != BACK_EDGE,
"Process flow has a cycle involving dependency from %s to %s",
e.src().name, e.dst().name));
});
}
/**
* Prints formatted output.
*
* @param format printf format string
......