[ASTERIXDB-2755] Fix failed test case caused by GVBC

- user model changes: no
- storage format changes: no
- interface changes: no

Details:
- Fix testAllocateWhileFlushIsScheduled to ensure that writes on
partition 1 are enabled after the flush on partition 0 is completed.
Otherwise, GVBC may flush partition 1 as well, because GVBC is still full,
causing inconsistent component IDs.

Change-Id: I82cc3f30563061ef7d7340747ea81cd8659cdb32
Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/7084
Integration-Tests: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Tested-by: Jenkins <jenkins@fulliautomatix.ics.uci.edu>
Reviewed-by: Luo Chen <cluo8@uci.edu>
Reviewed-by: Murtadha Hubail <mhubail@apache.org>
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/MultiPartitionLSMIndexTest.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/MultiPartitionLSMIndexTest.java
index d43b6d5..67c291f 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/MultiPartitionLSMIndexTest.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/dataflow/MultiPartitionLSMIndexTest.java
@@ -68,6 +68,7 @@
 import org.apache.hyracks.storage.am.lsm.btree.impl.TestLsmBtree;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMDiskComponent;
 import org.apache.hyracks.storage.am.lsm.common.api.ILSMMemoryComponent;
+import org.apache.hyracks.storage.am.lsm.common.api.IVirtualBufferCache;
 import org.apache.hyracks.storage.am.lsm.common.impls.NoMergePolicyFactory;
 import org.junit.After;
 import org.junit.AfterClass;
@@ -284,7 +285,6 @@
                                 }
                             }
                         }
-                        System.out.println("Proceed to flush");
                     }
                 }
             });
@@ -338,31 +338,37 @@
                 }
             }
             // The memory component has been allocated. now we allow the first actor to proceed to schedule flush
-            MutableBoolean flushStarted = new MutableBoolean(false);
+            MutableBoolean flushCompleted = new MutableBoolean(false);
             primaryLsmBtrees[0].addFlushCallback(new ITestOpCallback<Semaphore>() {
                 @Override
                 public void before(Semaphore t) {
-                    synchronized (flushStarted) {
-                        flushStarted.setValue(true);
-                        flushStarted.notifyAll();
-                    }
                 }
 
                 @Override
                 public void after(Semaphore t) {
+                    synchronized (flushCompleted) {
+                        flushCompleted.setValue(true);
+                        flushCompleted.notifyAll();
+                    }
                 }
             });
             synchronized (proceedToScheduleFlush) {
                 proceedToScheduleFlush.setValue(true);
                 proceedToScheduleFlush.notifyAll();
             }
-            // Now we need to know that the flush has been scheduled
-            synchronized (flushStarted) {
-                while (!flushStarted.booleanValue()) {
-                    flushStarted.wait(100);
+            // Must wait for the flush to complete. Otherwise, the GVBC may flush partition 1
+            synchronized (flushCompleted) {
+                while (!flushCompleted.booleanValue()) {
+                    flushCompleted.wait();
                 }
             }
 
+            IVirtualBufferCache gvbc = ncAppCtx.getVirtualBufferCache();
+            while (gvbc.getUsage() > gvbc.getPageBudget() / 2) {
+                // ensure the memory component pages of lsm tree 0 are freed
+                Thread.sleep(100);
+            }
+
             // we now allow the allocation to proceed
             synchronized (proceedToAllocateSecondaryIndex) {
                 proceedToAllocateSecondaryIndex.setValue(true);
@@ -373,6 +379,7 @@
             primaryLsmBtrees[1].clearAllocateCallbacks();
             // check the Ids of the memory components of partition 1
             // This shows the bug
+            Assert.assertNotEquals(null, primaryLsmBtrees[1].getCurrentMemoryComponent().getId());
             Assert.assertEquals(primaryLsmBtrees[1].getCurrentMemoryComponent().getId(),
                     secondaryLsmBtrees[1].getCurrentMemoryComponent().getId());
         } catch (Throwable e) {