ONOS-6468 Fix for race condition between compilation and installation complete state.
- Fix for a bug where intent compilation complete state,
can overwrites intent installation complete state,
if intent installation completes before compilation complete state is written to the store.
- Introduced internalState version on IntentData,
which is effectively mutation count, in order to avoid
batch write of compilation result overwriting installation result
Change-Id: I5d77dfbe496e690ebdf2b4f9643d2b64c4233182
diff --git a/core/api/src/test/java/org/onosproject/net/intent/IntentDataTest.java b/core/api/src/test/java/org/onosproject/net/intent/IntentDataTest.java
index f7bb7a3..62ad289 100644
--- a/core/api/src/test/java/org/onosproject/net/intent/IntentDataTest.java
+++ b/core/api/src/test/java/org/onosproject/net/intent/IntentDataTest.java
@@ -25,6 +25,7 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertTrue;
+import static org.onosproject.net.intent.IntentState.FAILED;
import static org.onosproject.net.intent.IntentTestsMocks.MockIntent;
import static org.onosproject.net.intent.IntentTestsMocks.MockTimestamp;
@@ -50,6 +51,7 @@
IdGenerator idGenerator;
+ @Override
@Before
public void setUp() {
super.setUp();
@@ -102,17 +104,18 @@
assertFalse(IntentData.isUpdateAcceptable(data2, data1));
IntentData installing = new IntentData(intent1, IntentState.INSTALLING, timestamp1);
- IntentData installed = new IntentData(intent1, IntentState.INSTALLED, timestamp1);
+ IntentData installed = IntentData.nextState(installing, IntentState.INSTALLED);
IntentData withdrawing = new IntentData(intent1, IntentState.WITHDRAWING, timestamp1);
- IntentData withdrawn = new IntentData(intent1, IntentState.WITHDRAWN, timestamp1);
+ IntentData withdrawn = IntentData.nextState(withdrawing, IntentState.WITHDRAWN);
IntentData failed = new IntentData(intent1, IntentState.FAILED, timestamp1);
- IntentData purgeReq = new IntentData(intent1, IntentState.PURGE_REQ, timestamp1);
IntentData compiling = new IntentData(intent1, IntentState.COMPILING, timestamp1);
IntentData recompiling = new IntentData(intent1, IntentState.RECOMPILING, timestamp1);
- IntentData installReq = new IntentData(intent1, IntentState.INSTALL_REQ, timestamp1);
- IntentData withdrawReq = new IntentData(intent1, IntentState.WITHDRAW_REQ, timestamp1);
+
+ IntentData installReq = new IntentData(intent1, IntentState.INSTALL_REQ, timestamp2);
+ IntentData withdrawReq = new IntentData(intent1, IntentState.WITHDRAW_REQ, timestamp2);
+ IntentData purgeReq = new IntentData(intent1, IntentState.PURGE_REQ, timestamp2);
// We can't change to the same state
assertFalse(IntentData.isUpdateAcceptable(installing, installing));
@@ -120,6 +123,8 @@
// From installing we can change to installed
assertTrue(IntentData.isUpdateAcceptable(installing, installed));
+ // transition in reverse should be rejected
+ assertFalse(IntentData.isUpdateAcceptable(installed, installing));
// Sanity checks in case the manager submits bogus state transitions
assertFalse(IntentData.isUpdateAcceptable(installing, withdrawing));
@@ -144,10 +149,10 @@
assertFalse(IntentData.isUpdateAcceptable(failed, failed));
// But we can go from any install* or withdraw* state to failed
- assertTrue(IntentData.isUpdateAcceptable(installing, failed));
- assertTrue(IntentData.isUpdateAcceptable(installed, failed));
- assertTrue(IntentData.isUpdateAcceptable(withdrawing, failed));
- assertTrue(IntentData.isUpdateAcceptable(withdrawn, failed));
+ assertTrue(IntentData.isUpdateAcceptable(installing, IntentData.nextState(installing, FAILED)));
+ assertTrue(IntentData.isUpdateAcceptable(installed, IntentData.nextState(installed, FAILED)));
+ assertTrue(IntentData.isUpdateAcceptable(withdrawing, IntentData.nextState(withdrawing, FAILED)));
+ assertTrue(IntentData.isUpdateAcceptable(withdrawn, IntentData.nextState(withdrawn, FAILED)));
// We can go from anything to purgeReq
assertTrue(IntentData.isUpdateAcceptable(installing, purgeReq));
@@ -165,7 +170,7 @@
// We're never allowed to store transient states
assertFalse(IntentData.isUpdateAcceptable(installing, compiling));
assertFalse(IntentData.isUpdateAcceptable(installing, recompiling));
- assertFalse(IntentData.isUpdateAcceptable(installing, installReq));
- assertFalse(IntentData.isUpdateAcceptable(installing, withdrawReq));
+ assertFalse(IntentData.isUpdateAcceptable(installing, installing));
+ assertFalse(IntentData.isUpdateAcceptable(installing, withdrawing));
}
}