Adding STC scenario for testing host intent-based connectivity.
Change-Id: I7375a9fdb121a6a288df5d54a23cfbd9d54258f3
diff --git a/cli/src/main/java/org/onosproject/cli/net/IntentRemoveCommand.java b/cli/src/main/java/org/onosproject/cli/net/IntentRemoveCommand.java
index dceed7b..4181dd4 100644
--- a/cli/src/main/java/org/onosproject/cli/net/IntentRemoveCommand.java
+++ b/cli/src/main/java/org/onosproject/cli/net/IntentRemoveCommand.java
@@ -33,6 +33,7 @@
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import static com.google.common.base.Strings.isNullOrEmpty;
import static org.onosproject.net.intent.IntentState.FAILED;
import static org.onosproject.net.intent.IntentState.WITHDRAWN;
@@ -40,17 +41,17 @@
* Removes an intent.
*/
@Command(scope = "onos", name = "remove-intent",
- description = "Removes the specified intent")
+ description = "Removes the specified intent")
public class IntentRemoveCommand extends AbstractShellCommand {
@Argument(index = 0, name = "app",
- description = "Application ID",
- required = true, multiValued = false)
+ description = "Application ID",
+ required = false, multiValued = false)
String applicationIdString = null;
@Argument(index = 1, name = "key",
- description = "Intent Key",
- required = true, multiValued = false)
+ description = "Intent Key",
+ required = false, multiValued = false)
String keyString = null;
@Option(name = "-p", aliases = "--purge",
@@ -69,7 +70,7 @@
CoreService coreService = get(CoreService.class);
ApplicationId appId = appId();
- if (applicationIdString != null) {
+ if (!isNullOrEmpty(applicationIdString)) {
appId = coreService.getAppId(applicationIdString);
if (appId == null) {
print("Cannot find application Id %s", applicationIdString);
@@ -77,73 +78,87 @@
}
}
- final Key key;
- if (keyString.startsWith("0x")) {
- // The intent uses a LongKey
- keyString = keyString.replaceFirst("0x", "");
- key = Key.of(new BigInteger(keyString, 16).longValue(), appId);
- } else {
- // The intent uses a StringKey
- key = Key.of(keyString, appId);
- }
-
- Intent intent = intentService.getIntent(key);
- if (intent != null) {
- IntentListener listener = null;
- final CountDownLatch withdrawLatch, purgeLatch;
- if (purgeAfterRemove || sync) {
- // set up latch and listener to track uninstall progress
- withdrawLatch = new CountDownLatch(1);
- purgeLatch = purgeAfterRemove ? new CountDownLatch(1) : null;
- listener = (IntentEvent event) -> {
- if (Objects.equals(event.subject().key(), key)) {
- if (event.type() == IntentEvent.Type.WITHDRAWN ||
- event.type() == IntentEvent.Type.FAILED) {
- withdrawLatch.countDown();
- } else if (purgeAfterRemove &&
- event.type() == IntentEvent.Type.PURGED) {
- purgeLatch.countDown();
- }
- }
- };
- intentService.addListener(listener);
- } else {
- purgeLatch = null;
- withdrawLatch = null;
+ if (isNullOrEmpty(keyString)) {
+ for (Intent intent : intentService.getIntents()) {
+ if (intent.appId().equals(appId)) {
+ removeIntent(intentService, intent);
+ }
}
- // request the withdraw
- intentService.withdraw(intent);
+ } else {
+ final Key key;
+ if (keyString.startsWith("0x")) {
+ // The intent uses a LongKey
+ keyString = keyString.replaceFirst("0x", "");
+ key = Key.of(new BigInteger(keyString, 16).longValue(), appId);
+ } else {
+ // The intent uses a StringKey
+ key = Key.of(keyString, appId);
+ }
- if (purgeAfterRemove || sync) {
- try { // wait for withdraw event
- withdrawLatch.await(5, TimeUnit.SECONDS);
- } catch (InterruptedException e) {
- print("Timed out waiting for intent {} withdraw", key);
+ Intent intent = intentService.getIntent(key);
+ if (intent != null) {
+ removeIntent(intentService, intent);
+ }
+ }
+ }
+
+ private void removeIntent(IntentService intentService, Intent intent) {
+ IntentListener listener = null;
+ Key key = intent.key();
+ final CountDownLatch withdrawLatch, purgeLatch;
+ if (purgeAfterRemove || sync) {
+ // set up latch and listener to track uninstall progress
+ withdrawLatch = new CountDownLatch(1);
+ purgeLatch = purgeAfterRemove ? new CountDownLatch(1) : null;
+ listener = (IntentEvent event) -> {
+ if (Objects.equals(event.subject().key(), key)) {
+ if (event.type() == IntentEvent.Type.WITHDRAWN ||
+ event.type() == IntentEvent.Type.FAILED) {
+ withdrawLatch.countDown();
+ } else if (purgeAfterRemove &&
+ event.type() == IntentEvent.Type.PURGED) {
+ purgeLatch.countDown();
+ }
}
- // double check the state
- IntentState state = intentService.getIntentState(key);
- if (purgeAfterRemove && (state == WITHDRAWN || state == FAILED)) {
- intentService.purge(intent);
- }
- if (sync) { // wait for purge event
+ };
+ intentService.addListener(listener);
+ } else {
+ purgeLatch = null;
+ withdrawLatch = null;
+ }
+
+ // request the withdraw
+ intentService.withdraw(intent);
+
+ if (purgeAfterRemove || sync) {
+ try { // wait for withdraw event
+ withdrawLatch.await(5, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ print("Timed out waiting for intent {} withdraw", key);
+ }
+ // double check the state
+ IntentState state = intentService.getIntentState(key);
+ if (purgeAfterRemove && (state == WITHDRAWN || state == FAILED)) {
+ intentService.purge(intent);
+ }
+ if (sync) { // wait for purge event
/* TODO
Technically, the event comes before map.remove() is called.
If we depend on sync and purge working together, we will
need to address this.
*/
- try {
- purgeLatch.await(5, TimeUnit.SECONDS);
- } catch (InterruptedException e) {
- print("Timed out waiting for intent {} purge", key);
- }
+ try {
+ purgeLatch.await(5, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ print("Timed out waiting for intent {} purge", key);
}
}
+ }
- if (listener != null) {
- // clean up the listener
- intentService.removeListener(listener);
- }
+ if (listener != null) {
+ // clean up the listener
+ intentService.removeListener(listener);
}
}
}
diff --git a/tools/test/scenarios/net-host-intent.xml b/tools/test/scenarios/net-host-intent.xml
new file mode 100644
index 0000000..d256a58
--- /dev/null
+++ b/tools/test/scenarios/net-host-intent.xml
@@ -0,0 +1,36 @@
+<!--
+ ~ Copyright 2015 Open Networking Laboratory
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<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"
+ exec="onos ${OC1} app deactivate org.onosproject.fwd org.onosproject.ifwd"/>
+
+ <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="Create-Intent" requires="^"
+ exec="onos ${OCI} add-host-intent 00:00:00:00:00:01/-1 00:00:00:00:00:04/-1"/>
+
+ <import file="${ONOS_SCENARIOS}/net-link-down-up.xml" namespace="Host-Intent"/>
+ <dependency name="Host-Intent.Net-Link-Down-Up" requires="Create-Intent"/>
+
+ <step name="Remove-Intent" requires="Host-Intent.Net-Link-Down-Up"
+ exec="onos ${OCI} remove-intent --purge"/>
+ </group>
+</scenario>
\ No newline at end of file
diff --git a/tools/test/scenarios/net-link-up-down.xml b/tools/test/scenarios/net-link-down-up.xml
similarity index 94%
rename from tools/test/scenarios/net-link-up-down.xml
rename to tools/test/scenarios/net-link-down-up.xml
index f421227..fda756a 100644
--- a/tools/test/scenarios/net-link-up-down.xml
+++ b/tools/test/scenarios/net-link-down-up.xml
@@ -13,9 +13,9 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<scenario name="net-link-up-down" description="Network link up-down test">
+<scenario name="net-link-down-up" description="Network link up-down test">
<!-- TODO: parametrize this via recipes -->
- <group name="Net-Link-Up-Down">
+ <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"
diff --git a/tools/test/scenarios/net-smoke.xml b/tools/test/scenarios/net-smoke.xml
index fec1652..87bd38c 100644
--- a/tools/test/scenarios/net-smoke.xml
+++ b/tools/test/scenarios/net-smoke.xml
@@ -17,13 +17,16 @@
<group name="Net-Smoke">
<import file="${ONOS_SCENARIOS}/net-setup.xml"/>
- <import file="${ONOS_SCENARIOS}/net-pingall.xml"/>
- <dependency name="Net-Pingall" requires="Net-Setup"/>
+ <import file="${ONOS_SCENARIOS}/net-pingall.xml" namespace="Reactive-Forwarding"/>
+ <dependency name="Reactive-Forwarding.Net-Pingall" requires="Net-Setup"/>
- <import file="${ONOS_SCENARIOS}/net-link-up-down.xml"/>
- <dependency name="Net-Link-Up-Down" requires="~Net-Pingall"/>
+ <import file="${ONOS_SCENARIOS}/net-link-down-up.xml" namespace="Reactive-Forwarding"/>
+ <dependency name="Reactive-Forwarding.Net-Link-Down-Up" requires="~Reactive-Forwarding.Net-Pingall"/>
+
+ <import file="${ONOS_SCENARIOS}/net-host-intent.xml"/>
+ <dependency name="Host-Intent-Connectivity" requires="~Reactive-Forwarding.Net-Link-Down-Up"/>
<import file="${ONOS_SCENARIOS}/net-teardown.xml"/>
- <dependency name="Net-Teardown" requires="~Net-Link-Up-Down"/>
+ <dependency name="Net-Teardown" requires="~Host-Intent-Connectivity"/>
</group>
</scenario>
\ No newline at end of file