TestIMdsalApiManager with naturally sorted flows 99/53399/5
authorMichael Vorburger <vorburger@redhat.com>
Thu, 16 Mar 2017 12:33:47 +0000 (13:33 +0100)
committerMichael Vorburger <vorburger@redhat.com>
Fri, 17 Mar 2017 10:51:58 +0000 (11:51 +0100)
This leads to much clearer failure messages in assertFlowsInAnyOrder()

Change-Id: Ic7c07d7eb29a8937b88d3b094c2fcdcdad755ee4
Signed-off-by: Michael Vorburger <vorburger@redhat.com>
mdsalutil/mdsalutil-api/src/test/java/org/opendaylight/genius/mdsalutil/interfaces/testutils/TestIMdsalApiManager.java

index 50bf75f02633c7e0a6b6835f1124c7188d714018..a6707428baf9fdf2130a226231463f62c2bca1c6 100644 (file)
@@ -12,6 +12,7 @@ import static org.junit.Assert.assertTrue;
 import static org.opendaylight.mdsal.binding.testutils.AssertDataObjects.assertEqualBeans;
 import static org.opendaylight.yangtools.testutils.mockito.MoreAnswers.realOrException;
 
+import com.google.common.collect.ComparisonChain;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
@@ -19,6 +20,7 @@ import com.google.common.util.concurrent.CheckedFuture;
 import com.google.common.util.concurrent.Futures;
 import java.math.BigInteger;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import org.mockito.Mockito;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
@@ -89,6 +91,9 @@ public abstract class TestIMdsalApiManager implements IMdsalApiManager {
         // TODO Support Iterable <-> List directly within XtendBeanGenerator
         List<FlowEntity> expectedFlowsAsNewArrayList = Lists.newArrayList(expectedFlows);
 
+        List<FlowEntity> sortedFlows = sortFlows(flows);
+        List<FlowEntity> sortedExpectedFlows = sortFlows(expectedFlowsAsNewArrayList);
+
         // FYI: This containsExactlyElementsIn() assumes that FlowEntity, and everything in it,
         // has correctly working equals() implementations.  assertEqualBeans() does not assume
         // that, and would work even without equals, because it only uses property reflection.
@@ -106,7 +111,7 @@ public abstract class TestIMdsalApiManager implements IMdsalApiManager {
         // is not a good idea (different instances can have same hashCode), and e.g. on
         // System#identityHashCode even less so.
         try {
-            assertThat(flows).containsExactlyElementsIn(expectedFlowsAsNewArrayList);
+            assertThat(sortedFlows).containsExactlyElementsIn(sortedExpectedFlows);
         } catch (AssertionError e) {
             // We LOG the AssertionError just for clarity why containsExactlyElementsIn() failed
             LOG.warn("assert containsExactlyElementsIn() failed", e);
@@ -115,15 +120,26 @@ public abstract class TestIMdsalApiManager implements IMdsalApiManager {
             // hard to read (the diff printed subsequently by assertEqualBeans
             // is, much, more readable), there are cases when looking more closely
             // at the full toString() output of the flows is still useful, so:
-            LOG.warn("assert failed [order ignored!]; expected flows: {}", expectedFlowsAsNewArrayList);
-            LOG.warn("assert failed [order ignored!]; actual flows  : {}", flows);
+            LOG.warn("assert failed [order ignored!]; expected flows: {}", sortedExpectedFlows);
+            LOG.warn("assert failed [order ignored!]; actual flows  : {}", sortedFlows);
             // The point of this is basically just that our assertEqualBeans output,
             // in case of a comparison failure, is *A LOT* more clearly readable
             // than what G Truth (or Hamcrest) can do based on toString.
-            assertEqualBeans(expectedFlowsAsNewArrayList, flows);
+            assertEqualBeans(sortedExpectedFlows, sortedFlows);
         }
     }
 
+    private List<FlowEntity> sortFlows(Iterable<FlowEntity> flowsToSort) {
+        List<FlowEntity> sortedFlows = Lists.newArrayList(flowsToSort);
+        Collections.sort(sortedFlows,
+            (flow1, flow2) -> ComparisonChain.start()
+                .compare(flow1.getTableId(),  flow2.getTableId())
+                .compare(flow1.getPriority(), flow2.getPriority())
+                .compare(flow1.getFlowId(),   flow2.getFlowId())
+                .result());
+        return sortedFlows;
+    }
+
     @Override
     public synchronized void installFlow(FlowEntity flowEntity) {
         getOrNewFlows().add(flowEntity);