[storage] Add a Flush call TransactionHandler.

The journal will soon need to be able to send flush calls.

Bug: 53973
Change-Id: I78a40102cbfb2c8dab78cc98682c12d78a5a0cee
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/442495
Commit-Queue: Chris Suter <csuter@google.com>
Reviewed-by: Abdulla Kamar <abdulla@google.com>
Reviewed-by: Vikram Auradkar <auradkar@google.com>
Testability-Review: Vikram Auradkar <auradkar@google.com>
Testability-Review: Chris Suter <csuter@google.com>
diff --git a/bundles/bringup/BUILD.gn b/bundles/bringup/BUILD.gn
index 8812367..7737246 100644
--- a/bundles/bringup/BUILD.gn
+++ b/bundles/bringup/BUILD.gn
@@ -77,7 +77,6 @@
     "//zircon/system/ulib/fs/metrics/test:metrics-inspect-bootfs-test",
     "//zircon/system/ulib/fs/test:fs-connection-bootfs-test",
     "//zircon/system/ulib/fs/test:fs-vnode-bootfs-test",
-    "//zircon/system/ulib/fs/transaction/test:fs-transaction-bootfs-test",
     "//zircon/system/ulib/gpt/test:gpt-unit-bootfs-test",
     "//zircon/system/ulib/hwreg/test:libhwreg-bootfs-test",
     "//zircon/system/ulib/hwreg/test:libhwreg-i2c-bootfs-test",
diff --git a/zircon/system/ulib/fs/transaction/device_transaction_handler.cc b/zircon/system/ulib/fs/transaction/device_transaction_handler.cc
index 6926a98..8dc1bda 100644
--- a/zircon/system/ulib/fs/transaction/device_transaction_handler.cc
+++ b/zircon/system/ulib/fs/transaction/device_transaction_handler.cc
@@ -52,4 +52,9 @@
   return GetDevice()->FifoTransaction(&block_requests[0], operations.size());
 }
 
+zx_status_t DeviceTransactionHandler::Flush() {
+  block_fifo_request_t request = {.opcode = BLOCKIO_FLUSH};
+  return GetDevice()->FifoTransaction(&request, 1);
+}
+
 }  // namespace fs
diff --git a/zircon/system/ulib/fs/transaction/include/fs/transaction/device_transaction_handler.h b/zircon/system/ulib/fs/transaction/include/fs/transaction/device_transaction_handler.h
index 0069e7e..0d3e67c 100644
--- a/zircon/system/ulib/fs/transaction/include/fs/transaction/device_transaction_handler.h
+++ b/zircon/system/ulib/fs/transaction/include/fs/transaction/device_transaction_handler.h
@@ -13,11 +13,12 @@
 // Provides a reasonable implementation of RunRequests that issues requests to a BlockDevice.
 class DeviceTransactionHandler : public TransactionHandler {
  public:
-  zx_status_t RunRequests(
-      const std::vector<storage::BufferedOperation>& operations) override;
+  zx_status_t RunRequests(const std::vector<storage::BufferedOperation>& operations) override;
 
   // Returns the backing block device that is associated with this TransactionHandler.
   virtual block_client::BlockDevice* GetDevice() = 0;
+
+  zx_status_t Flush() override;
 };
 
 }  // namespace fs
diff --git a/zircon/system/ulib/fs/transaction/include/fs/transaction/transaction_handler.h b/zircon/system/ulib/fs/transaction/include/fs/transaction/transaction_handler.h
index 32c6ae7..e353a42 100644
--- a/zircon/system/ulib/fs/transaction/include/fs/transaction/transaction_handler.h
+++ b/zircon/system/ulib/fs/transaction/include/fs/transaction/transaction_handler.h
@@ -40,7 +40,8 @@
   // filesystem-level block numbers.  This method blocks until the operation completes, so it is
   // suitable for host-based reads and writes and for simple Fuchsia-based reads. Regular Fuchsia IO
   // is expected to be issued using the RunRequests method.  A default implementation is provided.
-  virtual zx_status_t RunOperation(const storage::Operation& operation, storage::BlockBuffer* buffer);
+  virtual zx_status_t RunOperation(const storage::Operation& operation,
+                                   storage::BlockBuffer* buffer);
 
   // Runs the provided operations against the backing block device.
   // The values inside |operations| are expected to be filesystem-level block numbers.
@@ -49,6 +50,8 @@
   // upgraded to be fully asynchronous at some point.
   // The caller should use a BufferedOperationsBuilder to construct the request.
   virtual zx_status_t RunRequests(const std::vector<storage::BufferedOperation>& operations) = 0;
+
+  virtual zx_status_t Flush() { return ZX_ERR_NOT_SUPPORTED; }
 };
 
 }  // namespace fs
diff --git a/zircon/system/ulib/fs/transaction/test/BUILD.gn b/zircon/system/ulib/fs/transaction/test/BUILD.gn
index 93be8d8..0287b27 100644
--- a/zircon/system/ulib/fs/transaction/test/BUILD.gn
+++ b/zircon/system/ulib/fs/transaction/test/BUILD.gn
@@ -13,39 +13,28 @@
        "This file can only be used in the Fuchsia GN build.")
 
 import("//build/test.gni")
-import("//build/testing/bootfs_test.gni")
+import("//src/sys/build/fuchsia_unittest_package.gni")
 
 group("tests") {
   testonly = true
-  deps = [ ":fs-transaction($host_toolchain)" ]
+  deps = [ ":fs-transaction-tests" ]
 }
 
 test("fs-transaction") {
-  output_name = "fs-transaction-test"
-  if (is_fuchsia) {
-    configs += [ "//build/unification/config:zircon-migrated" ]
-  }
-  if (is_fuchsia) {
-    fdio_config = [ "//build/config/fuchsia:fdio_config" ]
-    if (configs + fdio_config - fdio_config != configs) {
-      configs -= fdio_config
-    }
-  }
+  output_name = "fs_transaction_test"
   deps = [
-    "//zircon/public/lib/zxtest",
+    "//src/lib/fxl/test:gtest_main",
+    "//zircon/system/ulib/block-client:fake-device",
     "//zircon/system/ulib/fs/transaction",
   ]
-  if (is_fuchsia) {
-    sources = [
-      "buffered_operations_builder_test.cc",
-      "device_transaction_handler_test.cc",
-      "writeback_test.cc",
-    ]
-    deps += [ "//zircon/system/ulib/block-client:fake-device" ]
-  }
+  sources = [
+    "buffered_operations_builder_test.cc",
+    "device_transaction_handler_test.cc",
+    "writeback_test.cc",
+  ]
 }
 
-bootfs_test("fs-transaction-bootfs-test") {
-  name = "fs-transaction-test"
+fuchsia_unittest_package("fs-transaction-tests") {
+  manifest = "meta/fs_transaction_tests.cml"
   deps = [ ":fs-transaction" ]
 }
diff --git a/zircon/system/ulib/fs/transaction/test/buffered_operations_builder_test.cc b/zircon/system/ulib/fs/transaction/test/buffered_operations_builder_test.cc
index ce90af3..8d0babc 100644
--- a/zircon/system/ulib/fs/transaction/test/buffered_operations_builder_test.cc
+++ b/zircon/system/ulib/fs/transaction/test/buffered_operations_builder_test.cc
@@ -4,9 +4,9 @@
 
 #include "fs/transaction/buffered_operations_builder.h"
 
+#include <gtest/gtest.h>
 #include <storage/buffer/vmo_buffer.h>
 #include <storage/buffer/vmoid_registry.h>
-#include <zxtest/zxtest.h>
 
 namespace {
 
@@ -62,7 +62,7 @@
   builder.Add(operation, &buffer);
 
   auto requests = builder.TakeOperations();
-  ASSERT_EQ(1, requests.size());
+  ASSERT_EQ(1u, requests.size());
   EXPECT_EQ(kVmoid1, requests[0].vmoid);
   EXPECT_EQ(OperationType::kWrite, requests[0].op.type);
   EXPECT_EQ(operation.vmo_offset, requests[0].op.vmo_offset);
@@ -93,17 +93,17 @@
   builder.Add(operation, &buffer_2);
 
   auto requests = builder.TakeOperations();
-  ASSERT_EQ(2, requests.size());
+  ASSERT_EQ(2u, requests.size());
   EXPECT_EQ(kVmoid1, requests[0].vmoid);
   EXPECT_EQ(kVmoid2, requests[1].vmoid);
   EXPECT_EQ(OperationType::kWrite, requests[0].op.type);
   EXPECT_EQ(OperationType::kWrite, requests[1].op.type);
-  EXPECT_EQ(0, requests[0].op.vmo_offset);
-  EXPECT_EQ(0, requests[0].op.dev_offset);
-  EXPECT_EQ(1, requests[0].op.length);
-  EXPECT_EQ(1, requests[1].op.vmo_offset);
-  EXPECT_EQ(1, requests[1].op.dev_offset);
-  EXPECT_EQ(1, requests[1].op.length);
+  EXPECT_EQ(0u, requests[0].op.vmo_offset);
+  EXPECT_EQ(0u, requests[0].op.dev_offset);
+  EXPECT_EQ(1u, requests[0].op.length);
+  EXPECT_EQ(1u, requests[1].op.vmo_offset);
+  EXPECT_EQ(1u, requests[1].op.dev_offset);
+  EXPECT_EQ(1u, requests[1].op.length);
 }
 
 TEST(BufferedOperationsBuilderTest, TwoRequestMergeOperations) {
@@ -125,12 +125,12 @@
   builder.Add(operation, &buffer);
 
   auto requests = builder.TakeOperations();
-  ASSERT_EQ(1, requests.size());
+  ASSERT_EQ(1u, requests.size());
   EXPECT_EQ(kVmoid1, requests[0].vmoid);
   EXPECT_EQ(OperationType::kWrite, requests[0].op.type);
-  EXPECT_EQ(0, requests[0].op.vmo_offset);
-  EXPECT_EQ(0, requests[0].op.dev_offset);
-  EXPECT_EQ(2, requests[0].op.length);
+  EXPECT_EQ(0u, requests[0].op.vmo_offset);
+  EXPECT_EQ(0u, requests[0].op.dev_offset);
+  EXPECT_EQ(2u, requests[0].op.length);
 }
 
 TEST(BufferedOperationsBuilderTest, TwoRequestDifferentType) {
@@ -153,17 +153,17 @@
   builder.Add(operation, &buffer);
 
   auto requests = builder.TakeOperations();
-  ASSERT_EQ(2, requests.size());
+  ASSERT_EQ(2u, requests.size());
   EXPECT_EQ(kVmoid1, requests[0].vmoid);
   EXPECT_EQ(kVmoid1, requests[1].vmoid);
   EXPECT_EQ(OperationType::kWrite, requests[0].op.type);
   EXPECT_EQ(OperationType::kRead, requests[1].op.type);
-  EXPECT_EQ(0, requests[0].op.vmo_offset);
-  EXPECT_EQ(0, requests[0].op.dev_offset);
-  EXPECT_EQ(1, requests[0].op.length);
-  EXPECT_EQ(1, requests[1].op.vmo_offset);
-  EXPECT_EQ(1, requests[1].op.dev_offset);
-  EXPECT_EQ(1, requests[1].op.length);
+  EXPECT_EQ(0u, requests[0].op.vmo_offset);
+  EXPECT_EQ(0u, requests[0].op.dev_offset);
+  EXPECT_EQ(1u, requests[0].op.length);
+  EXPECT_EQ(1u, requests[1].op.vmo_offset);
+  EXPECT_EQ(1u, requests[1].op.dev_offset);
+  EXPECT_EQ(1u, requests[1].op.length);
 }
 
 TEST(BufferedOperationsBuilderTest, TwoRequestVmoGap) {
@@ -185,17 +185,17 @@
   builder.Add(operation, &buffer);
 
   auto requests = builder.TakeOperations();
-  ASSERT_EQ(2, requests.size());
+  ASSERT_EQ(2u, requests.size());
   EXPECT_EQ(kVmoid1, requests[0].vmoid);
   EXPECT_EQ(kVmoid1, requests[1].vmoid);
   EXPECT_EQ(OperationType::kWrite, requests[0].op.type);
   EXPECT_EQ(OperationType::kWrite, requests[1].op.type);
-  EXPECT_EQ(0, requests[0].op.vmo_offset);
-  EXPECT_EQ(0, requests[0].op.dev_offset);
-  EXPECT_EQ(1, requests[0].op.length);
-  EXPECT_EQ(2, requests[1].op.vmo_offset);
-  EXPECT_EQ(1, requests[1].op.dev_offset);
-  EXPECT_EQ(1, requests[1].op.length);
+  EXPECT_EQ(0u, requests[0].op.vmo_offset);
+  EXPECT_EQ(0u, requests[0].op.dev_offset);
+  EXPECT_EQ(1u, requests[0].op.length);
+  EXPECT_EQ(2u, requests[1].op.vmo_offset);
+  EXPECT_EQ(1u, requests[1].op.dev_offset);
+  EXPECT_EQ(1u, requests[1].op.length);
 }
 
 TEST(BufferedOperationsBuilderTest, TwoRequestDeviceGap) {
@@ -217,17 +217,17 @@
   builder.Add(operation, &buffer);
 
   auto requests = builder.TakeOperations();
-  ASSERT_EQ(2, requests.size());
+  ASSERT_EQ(2u, requests.size());
   EXPECT_EQ(kVmoid1, requests[0].vmoid);
   EXPECT_EQ(kVmoid1, requests[1].vmoid);
   EXPECT_EQ(OperationType::kWrite, requests[0].op.type);
   EXPECT_EQ(OperationType::kWrite, requests[1].op.type);
-  EXPECT_EQ(0, requests[0].op.vmo_offset);
-  EXPECT_EQ(0, requests[0].op.dev_offset);
-  EXPECT_EQ(1, requests[0].op.length);
-  EXPECT_EQ(1, requests[1].op.vmo_offset);
-  EXPECT_EQ(2, requests[1].op.dev_offset);
-  EXPECT_EQ(1, requests[1].op.length);
+  EXPECT_EQ(0u, requests[0].op.vmo_offset);
+  EXPECT_EQ(0u, requests[0].op.dev_offset);
+  EXPECT_EQ(1u, requests[0].op.length);
+  EXPECT_EQ(1u, requests[1].op.vmo_offset);
+  EXPECT_EQ(2u, requests[1].op.dev_offset);
+  EXPECT_EQ(1u, requests[1].op.length);
 }
 
 TEST(BufferedOperationsBuilderTest, TwoRequestReplaceOperation) {
@@ -248,12 +248,12 @@
   builder.Add(operation, &buffer);
 
   auto requests = builder.TakeOperations();
-  ASSERT_EQ(1, requests.size());
+  ASSERT_EQ(1u, requests.size());
   EXPECT_EQ(kVmoid1, requests[0].vmoid);
   EXPECT_EQ(OperationType::kRead, requests[0].op.type);
-  EXPECT_EQ(0, requests[0].op.vmo_offset);
-  EXPECT_EQ(0, requests[0].op.dev_offset);
-  EXPECT_EQ(2, requests[0].op.length);
+  EXPECT_EQ(0u, requests[0].op.vmo_offset);
+  EXPECT_EQ(0u, requests[0].op.dev_offset);
+  EXPECT_EQ(2u, requests[0].op.length);
 }
 
 TEST(BufferedOperationsBuilderTest, TwoRequestDifferentDeviceOffset) {
@@ -275,17 +275,17 @@
   builder.Add(operation, &buffer);
 
   auto requests = builder.TakeOperations();
-  ASSERT_EQ(2, requests.size());
+  ASSERT_EQ(2u, requests.size());
   EXPECT_EQ(kVmoid1, requests[0].vmoid);
   EXPECT_EQ(kVmoid1, requests[1].vmoid);
   EXPECT_EQ(OperationType::kRead, requests[0].op.type);
   EXPECT_EQ(OperationType::kRead, requests[1].op.type);
-  EXPECT_EQ(0, requests[0].op.vmo_offset);
-  EXPECT_EQ(0, requests[0].op.dev_offset);
-  EXPECT_EQ(1, requests[0].op.length);
-  EXPECT_EQ(0, requests[1].op.vmo_offset);
-  EXPECT_EQ(2, requests[1].op.dev_offset);
-  EXPECT_EQ(2, requests[1].op.length);
+  EXPECT_EQ(0u, requests[0].op.vmo_offset);
+  EXPECT_EQ(0u, requests[0].op.dev_offset);
+  EXPECT_EQ(1u, requests[0].op.length);
+  EXPECT_EQ(0u, requests[1].op.vmo_offset);
+  EXPECT_EQ(2u, requests[1].op.dev_offset);
+  EXPECT_EQ(2u, requests[1].op.length);
 }
 
 TEST(BufferedOperationsBuilderTest, TwoRequestDifferentVmoOffset) {
@@ -307,17 +307,17 @@
   builder.Add(operation, &buffer);
 
   auto requests = builder.TakeOperations();
-  ASSERT_EQ(2, requests.size());
+  ASSERT_EQ(2u, requests.size());
   EXPECT_EQ(kVmoid1, requests[0].vmoid);
   EXPECT_EQ(kVmoid1, requests[1].vmoid);
   EXPECT_EQ(OperationType::kRead, requests[0].op.type);
   EXPECT_EQ(OperationType::kRead, requests[1].op.type);
-  EXPECT_EQ(0, requests[0].op.vmo_offset);
-  EXPECT_EQ(0, requests[0].op.dev_offset);
-  EXPECT_EQ(1, requests[0].op.length);
-  EXPECT_EQ(2, requests[1].op.vmo_offset);
-  EXPECT_EQ(0, requests[1].op.dev_offset);
-  EXPECT_EQ(2, requests[1].op.length);
+  EXPECT_EQ(0u, requests[0].op.vmo_offset);
+  EXPECT_EQ(0u, requests[0].op.dev_offset);
+  EXPECT_EQ(1u, requests[0].op.length);
+  EXPECT_EQ(2u, requests[1].op.vmo_offset);
+  EXPECT_EQ(0u, requests[1].op.dev_offset);
+  EXPECT_EQ(2u, requests[1].op.length);
 }
 
 }  // namespace
diff --git a/zircon/system/ulib/fs/transaction/test/device_transaction_handler_test.cc b/zircon/system/ulib/fs/transaction/test/device_transaction_handler_test.cc
index 14120ea..12db5eb 100644
--- a/zircon/system/ulib/fs/transaction/test/device_transaction_handler_test.cc
+++ b/zircon/system/ulib/fs/transaction/test/device_transaction_handler_test.cc
@@ -7,13 +7,13 @@
 #include <vector>
 
 #include <block-client/cpp/fake-device.h>
+#include <gtest/gtest.h>
 #include <sanitizer/lsan_interface.h>
-#include <zxtest/zxtest.h>
 
 namespace {
 
-using storage::BufferedOperation;
 using storage::BlockBuffer;
+using storage::BufferedOperation;
 using storage::Operation;
 using storage::OperationType;
 
@@ -63,11 +63,9 @@
   MockBlockDevice device_;
 };
 
-class TransactionHandlerTest : public zxtest::Test {
+class TransactionHandlerTest : public testing::Test {
  public:
-  void SetUp() final {
-    handler_ = std::make_unique<MockTransactionHandler>();
-  }
+  void SetUp() final { handler_ = std::make_unique<MockTransactionHandler>(); }
 
  protected:
   std::unique_ptr<MockTransactionHandler> handler_;
@@ -75,36 +73,36 @@
 
 TEST_F(TransactionHandlerTest, RunRequestsNoRequests) {
   std::vector<BufferedOperation> operations;
-  EXPECT_OK(handler_->RunRequests(operations));
-  EXPECT_EQ(0, handler_->GetRequests().size());
+  EXPECT_EQ(handler_->RunRequests(operations), ZX_OK);
+  EXPECT_EQ(0u, handler_->GetRequests().size());
 }
 
 TEST_F(TransactionHandlerTest, RunRequestsOneRequest) {
   const vmoid_t kVmoid = 4;
   std::vector<BufferedOperation> operations = {{kVmoid, {OperationType::kWrite, 1, 2, 3}}};
-  EXPECT_OK(handler_->RunRequests(operations));
+  EXPECT_EQ(handler_->RunRequests(operations), ZX_OK);
 
   const std::vector<block_fifo_request_t>& requests = handler_->GetRequests();
-  EXPECT_EQ(1, requests.size());
+  EXPECT_EQ(1u, requests.size());
   EXPECT_EQ(1 * kBlockRatio, requests[0].vmo_offset);
   EXPECT_EQ(2 * kBlockRatio, requests[0].dev_offset);
   EXPECT_EQ(3 * kBlockRatio, requests[0].length);
   EXPECT_EQ(kVmoid, requests[0].vmoid);
-  EXPECT_EQ(BLOCKIO_WRITE, requests[0].opcode);
+  EXPECT_EQ(unsigned{BLOCKIO_WRITE}, requests[0].opcode);
 }
 
 TEST_F(TransactionHandlerTest, RunRequestsTrim) {
   const vmoid_t kVmoid = 4;
   std::vector<BufferedOperation> operations = {{kVmoid, {OperationType::kTrim, 1, 2, 3}}};
-  EXPECT_OK(handler_->RunRequests(operations));
+  EXPECT_EQ(handler_->RunRequests(operations), ZX_OK);
 
   const std::vector<block_fifo_request_t>& requests = handler_->GetRequests();
-  EXPECT_EQ(1, requests.size());
+  EXPECT_EQ(1u, requests.size());
   EXPECT_EQ(1 * kBlockRatio, requests[0].vmo_offset);
   EXPECT_EQ(2 * kBlockRatio, requests[0].dev_offset);
   EXPECT_EQ(3 * kBlockRatio, requests[0].length);
   EXPECT_EQ(kVmoid, requests[0].vmoid);
-  EXPECT_EQ(BLOCKIO_TRIM, requests[0].opcode);
+  EXPECT_EQ(unsigned{BLOCKIO_TRIM}, requests[0].opcode);
 }
 
 TEST_F(TransactionHandlerTest, RunRequestsManyRequests) {
@@ -112,24 +110,24 @@
   operations.push_back({10, {OperationType::kRead, 11, 12, 13}});
   operations.push_back({20, {OperationType::kRead, 24, 25, 26}});
   operations.push_back({30, {OperationType::kRead, 37, 38, 39}});
-  EXPECT_OK(handler_->RunRequests(operations));
+  EXPECT_EQ(handler_->RunRequests(operations), ZX_OK);
 
   const std::vector<block_fifo_request_t>& requests = handler_->GetRequests();
-  EXPECT_EQ(3, requests.size());
-  EXPECT_EQ(BLOCKIO_READ, requests[0].opcode);
+  EXPECT_EQ(3u, requests.size());
+  EXPECT_EQ(unsigned{BLOCKIO_READ}, requests[0].opcode);
   EXPECT_EQ(10, requests[0].vmoid);
   EXPECT_EQ(11 * kBlockRatio, requests[0].vmo_offset);
   EXPECT_EQ(12 * kBlockRatio, requests[0].dev_offset);
   EXPECT_EQ(13 * kBlockRatio, requests[0].length);
 
-  EXPECT_EQ(BLOCKIO_READ, requests[1].opcode);
-  EXPECT_EQ(20, requests[1].vmoid);
+  EXPECT_EQ(unsigned{BLOCKIO_READ}, requests[1].opcode);
+  EXPECT_EQ(20u, requests[1].vmoid);
   EXPECT_EQ(24 * kBlockRatio, requests[1].vmo_offset);
   EXPECT_EQ(25 * kBlockRatio, requests[1].dev_offset);
   EXPECT_EQ(26 * kBlockRatio, requests[1].length);
 
-  EXPECT_EQ(BLOCKIO_READ, requests[2].opcode);
-  EXPECT_EQ(30, requests[2].vmoid);
+  EXPECT_EQ(unsigned{BLOCKIO_READ}, requests[2].opcode);
+  EXPECT_EQ(30u, requests[2].vmoid);
   EXPECT_EQ(37 * kBlockRatio, requests[2].vmo_offset);
   EXPECT_EQ(38 * kBlockRatio, requests[2].dev_offset);
   EXPECT_EQ(39 * kBlockRatio, requests[2].length);
@@ -137,24 +135,37 @@
 
 TEST_F(TransactionHandlerTest, RunRequestsFails) {
   std::vector<BufferedOperation> operations = {{0, {OperationType::kWrite, 1, 2, 3}}};
-  EXPECT_OK(handler_->RunRequests(operations));
+  EXPECT_EQ(handler_->RunRequests(operations), ZX_OK);
 
-  EXPECT_NOT_OK(handler_->RunRequests(operations));
+  EXPECT_NE(handler_->RunRequests(operations), ZX_OK);
 }
 
+TEST_F(TransactionHandlerTest, FlushCallsFlush) {
+  handler_->Flush();
+  const std::vector<block_fifo_request_t>& requests = handler_->GetRequests();
+  EXPECT_EQ(1u, requests.size());
+  EXPECT_EQ(unsigned{BLOCKIO_FLUSH}, requests[0].opcode);
+}
+
+#if ZX_DEBUG_ASSERT_IMPLEMENTED
+
 using TransactionHandlerCrashTest = TransactionHandlerTest;
 
 TEST_F(TransactionHandlerCrashTest, RunRequestsMixedRequests) {
   std::vector<BufferedOperation> operations;
   operations.push_back({10, {OperationType::kRead, 11, 12, 13}});
   operations.push_back({20, {OperationType::kWrite, 24, 25, 26}});
-  ASSERT_DEATH(([this, operations]() {
+  ASSERT_DEATH(
+      {
 #if __has_feature(address_sanitizer) || __has_feature(leak_sanitizer)
-    // Disable LSAN, this thread is expected to leak by way of a crash.
-    __lsan::ScopedDisabler _;
+        // Disable LSAN, this thread is expected to leak by way of a crash.
+        __lsan::ScopedDisabler _;
 #endif
-    handler_->RunRequests(operations);
-  }));
+        handler_->RunRequests(operations);
+      },
+      "");
 }
 
+#endif  // ZX_DEBUG_ASSERT_IMPLEMENTED
+
 }  // namespace
diff --git a/zircon/system/ulib/fs/transaction/test/meta/fs_transaction_tests.cml b/zircon/system/ulib/fs/transaction/test/meta/fs_transaction_tests.cml
new file mode 100644
index 0000000..13844fb
--- /dev/null
+++ b/zircon/system/ulib/fs/transaction/test/meta/fs_transaction_tests.cml
@@ -0,0 +1,18 @@
+{
+    program: {
+        binary: "test/fs_transaction_test",
+    },
+    capabilities: [
+        { protocol: "fuchsia.test.Suite" },
+    ],
+    use: [
+        { runner: "gtest_runner" },
+        { protocol: "fuchsia.process.Launcher" },
+    ],
+    expose: [
+        {
+            protocol: "fuchsia.test.Suite",
+            from: "self",
+        },
+    ],
+}
diff --git a/zircon/system/ulib/fs/transaction/test/writeback_test.cc b/zircon/system/ulib/fs/transaction/test/writeback_test.cc
index ff691d7..1df016a 100644
--- a/zircon/system/ulib/fs/transaction/test/writeback_test.cc
+++ b/zircon/system/ulib/fs/transaction/test/writeback_test.cc
@@ -2,11 +2,10 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <fs/transaction/writeback.h>
-
 #include <zircon/assert.h>
 
-#include <zxtest/zxtest.h>
+#include <fs/transaction/writeback.h>
+#include <gtest/gtest.h>
 
 namespace fs {
 namespace {
@@ -57,7 +56,7 @@
     }
   } handler;
   fbl::Vector<storage::BufferedOperation> operations;
-  EXPECT_OK(FlushRequests(&handler, operations));
+  EXPECT_EQ(FlushRequests(&handler, operations), ZX_OK);
 }
 
 TEST(FlushRequestsTest, FlushOneRequest) {
@@ -65,7 +64,7 @@
   class TestTransactionHandler : public MockTransactionHandler {
     zx_status_t Transaction(block_fifo_request_t* requests, size_t count) final {
       if (count != 1) {
-        ADD_FAILURE("Unexpected count");
+        ADD_FAILURE() << "Unexpected count";
         return ZX_ERR_OUT_OF_RANGE;
       }
       EXPECT_EQ(1 * kDiskBlockRatio, requests[0].vmo_offset);
@@ -78,7 +77,7 @@
   fbl::Vector<storage::BufferedOperation> operations;
   operations.push_back(storage::BufferedOperation{
       kVmoid, storage::Operation{storage::OperationType::kWrite, 1, 2, 3}});
-  EXPECT_OK(FlushRequests(&handler, operations));
+  EXPECT_EQ(FlushRequests(&handler, operations), ZX_OK);
 }
 
 TEST(FlushRequestsTest, FlushManyRequests) {
@@ -87,7 +86,7 @@
   class TestTransactionHandler : public MockTransactionHandler {
     zx_status_t Transaction(block_fifo_request_t* requests, size_t count) final {
       if (count != 2) {
-        ADD_FAILURE("Unexpected count");
+        ADD_FAILURE() << "Unexpected count";
         return ZX_ERR_OUT_OF_RANGE;
       }
       EXPECT_EQ(1 * kDiskBlockRatio, requests[0].vmo_offset);
@@ -106,7 +105,7 @@
       kVmoidA, storage::Operation{storage::OperationType::kWrite, 1, 2, 3}});
   operations.push_back(storage::BufferedOperation{
       kVmoidB, storage::Operation{storage::OperationType::kWrite, 4, 5, 6}});
-  EXPECT_OK(FlushRequests(&handler, operations));
+  EXPECT_EQ(FlushRequests(&handler, operations), ZX_OK);
 }
 
 // This acts as a regression test against a previous implementation of
@@ -119,7 +118,7 @@
   class TestTransactionHandler : public MockTransactionHandler {
     zx_status_t Transaction(block_fifo_request_t* requests, size_t count) final {
       if (count != kOperationCount) {
-        ADD_FAILURE("Unexpected count");
+        ADD_FAILURE() << "Unexpected count";
         return ZX_ERR_OUT_OF_RANGE;
       }
       for (size_t i = 0; i < count; i++) {
@@ -137,7 +136,7 @@
     operations.push_back(storage::BufferedOperation{
         kVmoid, storage::Operation{storage::OperationType::kWrite, i * 2, i * 2, 1}});
   }
-  EXPECT_OK(FlushRequests(&handler, operations));
+  EXPECT_EQ(FlushRequests(&handler, operations), ZX_OK);
 }
 
 TEST(FlushRequestsTest, BadFlush) {
@@ -157,20 +156,19 @@
   class TestTransactionHandler : public MockTransactionHandler {
     zx_status_t Transaction(block_fifo_request_t* requests, size_t count) final {
       if (count != 1) {
-        ADD_FAILURE("Unexpected count");
+        ADD_FAILURE() << "Unexpected count";
         return ZX_ERR_OUT_OF_RANGE;
       }
-      EXPECT_EQ(BLOCKIO_TRIM, requests[0].opcode);
+      EXPECT_EQ(unsigned{BLOCKIO_TRIM}, requests[0].opcode);
       EXPECT_EQ(2 * kDiskBlockRatio, requests[0].dev_offset);
       EXPECT_EQ(3 * kDiskBlockRatio, requests[0].length);
       return ZX_OK;
     }
   } handler;
   fbl::Vector<storage::BufferedOperation> operations;
-  operations.push_back(
-        storage::BufferedOperation{kVmoid,
-                                   storage::Operation{storage::OperationType::kTrim, 1, 2, 3}});
-  EXPECT_OK(FlushRequests(&handler, operations));
+  operations.push_back(storage::BufferedOperation{
+      kVmoid, storage::Operation{storage::OperationType::kTrim, 1, 2, 3}});
+  EXPECT_EQ(FlushRequests(&handler, operations), ZX_OK);
 }
 
 }  // namespace