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));
     }
 }