[test][virtwl] Update test.

We saw some flakes in this test. Restructure some of the waiting to be
more defensive against races.

  * Reading the next used descriptor will wait until a timeout occurs
    or a descriptor is found.
  * Normalize the way this waiting is done to make it less error-prone
    in tests.

FLK-51 #comment

Test: fx run-test vmm_tests
Change-Id: I7b190c22aa66492724040232895f3d7884d34a84
diff --git a/garnet/bin/guest/vmm/device/virtio_wl_unittest.cc b/garnet/bin/guest/vmm/device/virtio_wl_unittest.cc
index c036215..9197298 100644
--- a/garnet/bin/guest/vmm/device/virtio_wl_unittest.cc
+++ b/garnet/bin/guest/vmm/device/virtio_wl_unittest.cc
@@ -106,7 +106,7 @@
       return status;
     }
 
-    auto used_elem = out_queue_.NextUsed();
+    auto used_elem = NextUsed(&out_queue_);
     if (!used_elem || used_elem->id != descriptor_id ||
         used_elem->len != sizeof(*response) ||
         response->hdr.type != VIRTIO_WL_RESP_VFD_NEW || !response->pfn ||
@@ -141,7 +141,7 @@
       return status;
     }
 
-    auto used_elem = out_queue_.NextUsed();
+    auto used_elem = NextUsed(&out_queue_);
     return (used_elem && used_elem->id == descriptor_id &&
             used_elem->len == sizeof(*response) &&
             response->hdr.type == VIRTIO_WL_RESP_VFD_NEW)
@@ -173,7 +173,7 @@
       return status;
     }
 
-    auto used_elem = out_queue_.NextUsed();
+    auto used_elem = NextUsed(&out_queue_);
     return (used_elem && used_elem->id == descriptor_id &&
             used_elem->len == sizeof(*response) &&
             response->hdr.type == VIRTIO_WL_RESP_VFD_NEW)
@@ -181,6 +181,14 @@
                : ZX_ERR_INTERNAL;
   }
 
+  std::optional<VirtioQueueFake::UsedElement> NextUsed(VirtioQueueFake* queue) {
+    auto elem = queue->NextUsed();
+    while (!elem && WaitOnInterrupt() == ZX_OK) {
+      elem = queue->NextUsed();
+    }
+    return elem;
+  }
+
  protected:
   TestWaylandDispatcher wl_dispatcher_;
   fuchsia::guest::device::VirtioWaylandSyncPtr wl_;
@@ -203,9 +211,8 @@
             ZX_OK);
 
   ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_OUT), ZX_OK);
-  ASSERT_EQ(WaitOnInterrupt(), ZX_OK);
 
-  auto used_elem = out_queue_.NextUsed();
+  auto used_elem = NextUsed(&out_queue_);
   EXPECT_TRUE(used_elem);
   EXPECT_EQ(used_elem->id, descriptor_id);
   EXPECT_EQ(used_elem->len, sizeof(*response));
@@ -234,8 +241,7 @@
             ZX_OK);
 
   ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_OUT), ZX_OK);
-  ASSERT_EQ(WaitOnInterrupt(), ZX_OK);
-  auto used_elem = out_queue_.NextUsed();
+  auto used_elem = NextUsed(&out_queue_);
   EXPECT_TRUE(used_elem);
   EXPECT_EQ(used_elem->id, descriptor_id);
   EXPECT_EQ(used_elem->len, sizeof(*response));
@@ -255,8 +261,7 @@
             ZX_OK);
 
   ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_OUT), ZX_OK);
-  ASSERT_EQ(WaitOnInterrupt(), ZX_OK);
-  auto used_elem = out_queue_.NextUsed();
+  auto used_elem = NextUsed(&out_queue_);
   EXPECT_TRUE(used_elem);
   EXPECT_EQ(used_elem->id, descriptor_id);
   EXPECT_EQ(used_elem->len, sizeof(*response));
@@ -285,8 +290,7 @@
             ZX_OK);
 
   ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_OUT), ZX_OK);
-  ASSERT_EQ(WaitOnInterrupt(), ZX_OK);
-  auto used_elem = out_queue_.NextUsed();
+  auto used_elem = NextUsed(&out_queue_);
   EXPECT_TRUE(used_elem);
   EXPECT_EQ(used_elem->id, descriptor_id);
   EXPECT_EQ(used_elem->len, sizeof(*response));
@@ -312,9 +316,7 @@
             ZX_OK);
 
   ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_OUT), ZX_OK);
-  ASSERT_EQ(WaitOnInterrupt(), ZX_OK);
-
-  auto used_elem = out_queue_.NextUsed();
+  auto used_elem = NextUsed(&out_queue_);
   EXPECT_TRUE(used_elem);
   EXPECT_EQ(used_elem->id, descriptor_id);
   EXPECT_EQ(used_elem->len, sizeof(*response));
@@ -354,8 +356,7 @@
             ZX_OK);
 
   ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_OUT), ZX_OK);
-  ASSERT_EQ(WaitOnInterrupt(), ZX_OK);
-  auto used_elem = out_queue_.NextUsed();
+  auto used_elem = NextUsed(&out_queue_);
   EXPECT_TRUE(used_elem);
   EXPECT_EQ(used_elem->id, descriptor_id);
   EXPECT_EQ(used_elem->len, sizeof(*response));
@@ -399,8 +400,7 @@
       reinterpret_cast<virtio_wl_ctrl_vfd_recv_t*>(buffer);
 
   ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_IN), ZX_OK);
-  ASSERT_EQ(WaitOnInterrupt(), ZX_OK);
-  used_elem = in_queue_.NextUsed();
+  used_elem = NextUsed(&in_queue_);
   EXPECT_TRUE(used_elem);
   EXPECT_EQ(used_elem->id, descriptor_id);
   EXPECT_EQ(used_elem->len, buffer_size);
@@ -471,28 +471,19 @@
   // first.
 
   // descriptor_id[1] -> NEW_VFD (VMO)
-  ASSERT_EQ(WaitOnInterrupt(), ZX_OK);
-  auto used_elem = in_queue_.NextUsed();
+  auto used_elem = NextUsed(&in_queue_);
   EXPECT_TRUE(used_elem);
   EXPECT_EQ(used_elem->id, descriptor_id[1]);
   EXPECT_EQ(used_elem->len, sizeof(virtio_wl_ctrl_vfd_new_t));
 
   // descriptor_id[2] -> NEW_VFD (SOCKET)
-  used_elem = in_queue_.NextUsed();
-  if (!used_elem) {
-    ASSERT_EQ(WaitOnInterrupt(), ZX_OK);
-    used_elem = in_queue_.NextUsed();
-  }
+  used_elem = NextUsed(&in_queue_);
   EXPECT_TRUE(used_elem);
   EXPECT_EQ(used_elem->id, descriptor_id[2]);
   EXPECT_EQ(used_elem->len, sizeof(virtio_wl_ctrl_vfd_new_t));
 
   // descriptor_id[0] -> RECV
-  used_elem = in_queue_.NextUsed();
-  if (!used_elem) {
-    ASSERT_EQ(WaitOnInterrupt(), ZX_OK);
-    used_elem = in_queue_.NextUsed();
-  }
+  used_elem = NextUsed(&in_queue_);
   EXPECT_TRUE(used_elem);
   EXPECT_EQ(used_elem->id, descriptor_id[0]);
   EXPECT_EQ(used_elem->len, buffer_size);
@@ -535,8 +526,7 @@
               ZX_OK);
 
     ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_OUT), ZX_OK);
-    ASSERT_EQ(WaitOnInterrupt(), ZX_OK);
-    used_elem = out_queue_.NextUsed();
+    used_elem = NextUsed(&out_queue_);
     EXPECT_TRUE(used_elem);
     EXPECT_EQ(used_elem->id, descriptor_id);
     EXPECT_EQ(used_elem->len, sizeof(*response));
@@ -561,8 +551,7 @@
         ZX_OK);
 
     ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_OUT), ZX_OK);
-    ASSERT_EQ(WaitOnInterrupt(), ZX_OK);
-    used_elem = out_queue_.NextUsed();
+    used_elem = NextUsed(&out_queue_);
     EXPECT_TRUE(used_elem);
     EXPECT_EQ(used_elem->id, descriptor_id);
     EXPECT_EQ(used_elem->len, sizeof(*send_response));
@@ -596,8 +585,7 @@
             ZX_OK);
 
   ASSERT_EQ(wl_->NotifyQueue(VIRTWL_VQ_IN), ZX_OK);
-  ASSERT_EQ(WaitOnInterrupt(), ZX_OK);
-  auto used_elem = in_queue_.NextUsed();
+  auto used_elem = NextUsed(&in_queue_);
   EXPECT_TRUE(used_elem);
   EXPECT_EQ(used_elem->id, descriptor_id);
   EXPECT_EQ(used_elem->len, sizeof(*header));