[devmgr][tests] Fix ASAN issues in test utilities

We were exposing unique_ptrs across API boundaries, which results in
ASAN issues around mismatched allocators.  This patch switch to using
move semantics instead of unique_ptrs.

Test: Ran all affected tests under ASAN

ZX-3397 #comment Fixes the framework

Change-Id: I78480ef866c0973de1fe68d981a9236e8ad31f57
diff --git a/garnet/tests/zircon/libdriver-integration-test/integration-test.cc b/garnet/tests/zircon/libdriver-integration-test/integration-test.cc
index 3e6a1661..f70b9f9 100644
--- a/garnet/tests/zircon/libdriver-integration-test/integration-test.cc
+++ b/garnet/tests/zircon/libdriver-integration-test/integration-test.cc
@@ -14,7 +14,7 @@
 
 namespace libdriver_integration_test {
 
-std::unique_ptr<IntegrationTest::IsolatedDevmgr> IntegrationTest::devmgr_;
+IntegrationTest::IsolatedDevmgr IntegrationTest::devmgr_;
 const zx::duration IntegrationTest::kDefaultTimeout = zx::sec(5);
 
 void IntegrationTest::SetUpTestCase() {
@@ -24,13 +24,11 @@
     auto args = IsolatedDevmgr::DefaultArgs();
     args.stdio = fbl::unique_fd(open("/dev/null", O_RDWR));
 
-    fbl::unique_ptr<IsolatedDevmgr> tmp;
-    zx_status_t status = IsolatedDevmgr::Create(std::move(args), &tmp);
+    zx_status_t status = IsolatedDevmgr::Create(std::move(args), &IntegrationTest::devmgr_);
     if (status != ZX_OK) {
         printf("libdriver-integration-tests: failed to create isolated devmgr\n");
         return;
     }
-    IntegrationTest::devmgr_.reset(tmp.release());
 }
 
 void IntegrationTest::TearDownTestCase() {
@@ -39,7 +37,7 @@
 
 IntegrationTest::IntegrationTest()
     : loop_(&kAsyncLoopConfigNoAttachToThread),
-      devmgr_exception_(this, devmgr_->containing_job().get(), 0) {
+      devmgr_exception_(this, devmgr_.containing_job().get(), 0) {
 
     zx_status_t status = devmgr_exception_.Bind(loop_.dispatcher());
     if (status != ZX_OK) {
@@ -48,7 +46,7 @@
         return;
     }
 
-    fdio_t* io = fdio_unsafe_fd_to_io(IntegrationTest::devmgr_->devfs_root().get());
+    fdio_t* io = fdio_unsafe_fd_to_io(IntegrationTest::devmgr_.devfs_root().get());
     status = devfs_.Bind(zx::channel(fdio_service_clone(fdio_unsafe_borrow_channel(io))),
                          loop_.dispatcher());
     fdio_unsafe_release(io);
diff --git a/garnet/tests/zircon/libdriver-integration-test/integration-test.h b/garnet/tests/zircon/libdriver-integration-test/integration-test.h
index aade283..d5eb899 100644
--- a/garnet/tests/zircon/libdriver-integration-test/integration-test.h
+++ b/garnet/tests/zircon/libdriver-integration-test/integration-test.h
@@ -125,7 +125,7 @@
     void RunPromise(Promise<void> promise);
 protected:
     using IsolatedDevmgr = devmgr_integration_test::IsolatedDevmgr;
-    static std::unique_ptr<IsolatedDevmgr> devmgr_;
+    static IsolatedDevmgr devmgr_;
 
     async::Loop loop_;
     fidl::InterfacePtr<fuchsia::io::Directory> devfs_;
diff --git a/garnet/tests/zircon/libdriver-integration-test/root-mock-device.cc b/garnet/tests/zircon/libdriver-integration-test/root-mock-device.cc
index cc3438a..148b743 100644
--- a/garnet/tests/zircon/libdriver-integration-test/root-mock-device.cc
+++ b/garnet/tests/zircon/libdriver-integration-test/root-mock-device.cc
@@ -44,14 +44,14 @@
 // bound to.  This is provided so we can trigger unbinding of the mock device.
 // |*control_out| will be a channel for fulfilling requests from the mock
 // device.
-zx_status_t RootMockDevice::Create(const std::unique_ptr<IsolatedDevmgr>& devmgr,
+zx_status_t RootMockDevice::Create(const IsolatedDevmgr& devmgr,
                                    async_dispatcher_t* dispatcher,
                                    std::unique_ptr<MockDeviceHooks> hooks,
                                    std::unique_ptr<RootMockDevice>* mock_out) {
     // Wait for /dev/test/test to appear
     fbl::unique_fd fd;
     zx_status_t status = devmgr_integration_test::RecursiveWaitForFile(
-            devmgr->devfs_root(), "test/test", zx::deadline_after(zx::sec(5)), &fd);
+            devmgr.devfs_root(), "test/test", zx::deadline_after(zx::sec(5)), &fd);
     if (status != ZX_OK) {
         return status;
     }
@@ -80,7 +80,7 @@
         return ZX_ERR_BAD_STATE;
     }
     std::string relative_devpath(devpath.get(), strlen(kDevPrefix));
-    fd.reset(openat(devmgr->devfs_root().get(), relative_devpath.c_str(), O_RDWR));
+    fd.reset(openat(devmgr.devfs_root().get(), relative_devpath.c_str(), O_RDWR));
     if (!fd.is_valid()) {
         return ZX_ERR_NOT_FOUND;
     }
@@ -112,7 +112,7 @@
     // happen before the bind(), since ioctl_device_bind() will cause us to get
     // blocked in the mock device driver waiting for input on what to do.
     zx::channel test_device_channel;
-    fbl::unique_fd new_connection(openat(devmgr->devfs_root().get(), relative_devpath.c_str(),
+    fbl::unique_fd new_connection(openat(devmgr.devfs_root().get(), relative_devpath.c_str(),
                                          O_RDWR));
     status = fdio_get_service_handle(new_connection.release(),
                                      test_device_channel.reset_and_get_address());
diff --git a/garnet/tests/zircon/libdriver-integration-test/root-mock-device.h b/garnet/tests/zircon/libdriver-integration-test/root-mock-device.h
index 52b6bcf..9822874 100644
--- a/garnet/tests/zircon/libdriver-integration-test/root-mock-device.h
+++ b/garnet/tests/zircon/libdriver-integration-test/root-mock-device.h
@@ -8,6 +8,7 @@
 #include <string>
 #include <utility>
 
+#include <fbl/unique_ptr.h>
 #include <fbl/vector.h>
 #include <fuchsia/device/test/cpp/fidl.h>
 #include <lib/devmgr-integration-test/fixture.h>
@@ -33,7 +34,7 @@
                    async_dispatcher_t* dispatcher, std::string path);
     ~RootMockDevice();
 
-    static zx_status_t Create(const std::unique_ptr<IsolatedDevmgr>& devmgr,
+    static zx_status_t Create(const IsolatedDevmgr& devmgr,
                               async_dispatcher_t* dispatcher,
                               std::unique_ptr<MockDeviceHooks> hooks,
                               std::unique_ptr<RootMockDevice>* mock_out);
diff --git a/zircon/system/ulib/devmgr-integration-test/include/lib/devmgr-integration-test/fixture.h b/zircon/system/ulib/devmgr-integration-test/include/lib/devmgr-integration-test/fixture.h
index b2d9e3e..3678b37 100644
--- a/zircon/system/ulib/devmgr-integration-test/include/lib/devmgr-integration-test/fixture.h
+++ b/zircon/system/ulib/devmgr-integration-test/include/lib/devmgr-integration-test/fixture.h
@@ -14,8 +14,22 @@
 
 class IsolatedDevmgr {
 public:
+    IsolatedDevmgr() = default;
     ~IsolatedDevmgr();
 
+    IsolatedDevmgr(const IsolatedDevmgr&) = delete;
+    IsolatedDevmgr& operator=(const IsolatedDevmgr&) = delete;
+
+    IsolatedDevmgr(IsolatedDevmgr&& other)
+            : job_(std::move(other.job_)), devfs_root_(std::move(other.devfs_root_)) {
+    }
+
+    IsolatedDevmgr& operator=(IsolatedDevmgr&& other) {
+        job_ = std::move(other.job_);
+        devfs_root_ = std::move(other.devfs_root_);
+        return *this;
+    }
+
     // Path to the test sysdev driver
     static const char* kSysdevDriver;
 
@@ -25,8 +39,7 @@
 
     // Launch a new isolated devmgr.  The instance will be destroyed when
     // |*out|'s dtor runs.
-    static zx_status_t Create(devmgr_launcher::Args args,
-                              fbl::unique_ptr<IsolatedDevmgr>* out);
+    static zx_status_t Create(devmgr_launcher::Args args, IsolatedDevmgr* out);
 
     // Get a fd to the root of the isolate devmgr's devfs.  This fd
     // may be used with openat() and fdio_watch_directory().
@@ -35,6 +48,10 @@
     // Borrow the handle to the job containing the isolated devmgr.  This may be
     // used for things like binding to an exception port.
     const zx::job& containing_job() const { return job_; }
+
+    void reset() {
+        *this = IsolatedDevmgr();
+    }
 private:
     // Job that contains the devmgr environment
     zx::job job_;
diff --git a/zircon/system/ulib/devmgr-integration-test/launcher.cpp b/zircon/system/ulib/devmgr-integration-test/launcher.cpp
index c557688..935c267 100644
--- a/zircon/system/ulib/devmgr-integration-test/launcher.cpp
+++ b/zircon/system/ulib/devmgr-integration-test/launcher.cpp
@@ -35,11 +35,11 @@
 }
 
 zx_status_t IsolatedDevmgr::Create(devmgr_launcher::Args args,
-                                   fbl::unique_ptr<IsolatedDevmgr>* out) {
-    auto devmgr = fbl::make_unique<IsolatedDevmgr>();
+                                   IsolatedDevmgr* out) {
+    IsolatedDevmgr devmgr;
 
     zx::channel devfs;
-    zx_status_t status = devmgr_launcher::Launch(std::move(args), &devmgr->job_, &devfs);
+    zx_status_t status = devmgr_launcher::Launch(std::move(args), &devmgr.job_, &devfs);
     if (status != ZX_OK) {
         return status;
     }
@@ -55,7 +55,7 @@
     if (status != ZX_OK) {
         return status;
     }
-    devmgr->devfs_root_.reset(fd);
+    devmgr.devfs_root_.reset(fd);
 
     *out = std::move(devmgr);
     return ZX_OK;
diff --git a/zircon/system/ulib/driver-integration-test/include/lib/driver-integration-test/fixture.h b/zircon/system/ulib/driver-integration-test/include/lib/driver-integration-test/fixture.h
index 4117a6b..0a427a1 100644
--- a/zircon/system/ulib/driver-integration-test/include/lib/driver-integration-test/fixture.h
+++ b/zircon/system/ulib/driver-integration-test/include/lib/driver-integration-test/fixture.h
@@ -28,14 +28,14 @@
 
     // Launch a new isolated devmgr.  The instance will be destroyed when
     // |*out|'s dtor runs.
-    static zx_status_t Create(Args args, fbl::unique_ptr<IsolatedDevmgr>* out);
+    static zx_status_t Create(Args args, IsolatedDevmgr* out);
 
     // Get a fd to the root of the isolate devmgr's devfs.  This fd
     // may be used with openat() and fdio_watch_directory().
-    const fbl::unique_fd& devfs_root() const { return devmgr_->devfs_root(); }
+    const fbl::unique_fd& devfs_root() const { return devmgr_.devfs_root(); }
 
 private:
-    fbl::unique_ptr<devmgr_integration_test::IsolatedDevmgr> devmgr_;
+    devmgr_integration_test::IsolatedDevmgr devmgr_;
 };
 
 } // namespace driver_integration_test
diff --git a/zircon/system/ulib/driver-integration-test/launcher.cpp b/zircon/system/ulib/driver-integration-test/launcher.cpp
index 6d79498..496c00e 100644
--- a/zircon/system/ulib/driver-integration-test/launcher.cpp
+++ b/zircon/system/ulib/driver-integration-test/launcher.cpp
@@ -74,8 +74,8 @@
 } // namespace
 
 zx_status_t IsolatedDevmgr::Create(IsolatedDevmgr::Args args,
-                                   fbl::unique_ptr<IsolatedDevmgr>* out) {
-    auto devmgr = fbl::make_unique<IsolatedDevmgr>();
+                                   IsolatedDevmgr* out) {
+    IsolatedDevmgr devmgr;
 
     devmgr_launcher::Args devmgr_args;
     devmgr_args.sys_device_driver = "/boot/driver/platform-bus.so";
@@ -88,7 +88,7 @@
     }
 
     status = devmgr_integration_test::IsolatedDevmgr::Create(std::move(devmgr_args),
-                                                             &devmgr->devmgr_);
+                                                             &devmgr.devmgr_);
     if (status != ZX_OK) {
         return status;
     }
diff --git a/zircon/system/ulib/driver-integration-test/test/main.cpp b/zircon/system/ulib/driver-integration-test/test/main.cpp
index 8595b10..3021db9 100644
--- a/zircon/system/ulib/driver-integration-test/test/main.cpp
+++ b/zircon/system/ulib/driver-integration-test/test/main.cpp
@@ -41,19 +41,19 @@
     args.driver_search_paths.push_back("/boot/driver");
     args.device_list.push_back(kDeviceEntry);
 
-    fbl::unique_ptr<IsolatedDevmgr> devmgr;
+    IsolatedDevmgr devmgr;
     ASSERT_EQ(IsolatedDevmgr::Create(std::move(args), &devmgr), ZX_OK);
 
     fbl::unique_fd fd;
-    ASSERT_EQ(RecursiveWaitForFile(devmgr->devfs_root(), "sys/platform",
+    ASSERT_EQ(RecursiveWaitForFile(devmgr.devfs_root(), "sys/platform",
                                    zx::deadline_after(zx::sec(5)), &fd),
               ZX_OK);
 
-    EXPECT_EQ(RecursiveWaitForFile(devmgr->devfs_root(), "sys/platform/test-board",
+    EXPECT_EQ(RecursiveWaitForFile(devmgr.devfs_root(), "sys/platform/test-board",
                                    zx::deadline_after(zx::sec(5)), &fd),
               ZX_OK);
 
-    EXPECT_EQ(RecursiveWaitForFile(devmgr->devfs_root(), "sys/platform/00:00:f/fallback-rtc",
+    EXPECT_EQ(RecursiveWaitForFile(devmgr.devfs_root(), "sys/platform/00:00:f/fallback-rtc",
                                    zx::deadline_after(zx::sec(5)), &fd),
               ZX_OK);
 
diff --git a/zircon/system/ulib/ramdevice-client/include/ramdevice-client/ramnand.h b/zircon/system/ulib/ramdevice-client/include/ramdevice-client/ramnand.h
index 542d754..c32338f 100644
--- a/zircon/system/ulib/ramdevice-client/include/ramdevice-client/ramnand.h
+++ b/zircon/system/ulib/ramdevice-client/include/ramdevice-client/ramnand.h
@@ -28,14 +28,14 @@
     ~RamNandCtl() = default;
 
     const fbl::unique_fd& fd() { return ctl_; }
-    const fbl::unique_fd& devfs_root() { return devmgr_->devfs_root(); }
+    const fbl::unique_fd& devfs_root() { return devmgr_.devfs_root(); }
 
 private:
-    RamNandCtl(fbl::unique_ptr<devmgr_integration_test::IsolatedDevmgr> devmgr,
+    RamNandCtl(devmgr_integration_test::IsolatedDevmgr devmgr,
                fbl::unique_fd ctl)
         : devmgr_(std::move(devmgr)), ctl_(std::move(ctl)) {}
 
-    fbl::unique_ptr<devmgr_integration_test::IsolatedDevmgr> devmgr_;
+    devmgr_integration_test::IsolatedDevmgr devmgr_;
     fbl::unique_fd ctl_;
 };
 
diff --git a/zircon/system/ulib/ramdevice-client/ramnand.cpp b/zircon/system/ulib/ramdevice-client/ramnand.cpp
index ae0730d..12f0df5 100644
--- a/zircon/system/ulib/ramdevice-client/ramnand.cpp
+++ b/zircon/system/ulib/ramdevice-client/ramnand.cpp
@@ -34,7 +34,7 @@
     args.load_drivers.push_back(devmgr_integration_test::IsolatedDevmgr::kSysdevDriver);
     args.driver_search_paths.push_back("/boot/driver");
 
-    fbl::unique_ptr<devmgr_integration_test::IsolatedDevmgr> devmgr;
+    devmgr_integration_test::IsolatedDevmgr devmgr;
     zx_status_t st = devmgr_integration_test::IsolatedDevmgr::Create(std::move(args), &devmgr);
     if (st != ZX_OK) {
         fprintf(stderr, "Could not create ram_nand_ctl device, %d\n", st);
@@ -42,7 +42,7 @@
     }
 
     fbl::unique_fd ctl;
-    st = devmgr_integration_test::RecursiveWaitForFile(devmgr->devfs_root(), "misc/nand-ctl",
+    st = devmgr_integration_test::RecursiveWaitForFile(devmgr.devfs_root(), "misc/nand-ctl",
                                                        zx::deadline_after(zx::sec(5)), &ctl);
     if (st != ZX_OK) {
         fprintf(stderr, "ram_nand_ctl device failed enumerated, %d\n", st);
diff --git a/zircon/system/utest/driver-test/main.cpp b/zircon/system/utest/driver-test/main.cpp
index a7a748b..02d5db8 100644
--- a/zircon/system/utest/driver-test/main.cpp
+++ b/zircon/system/utest/driver-test/main.cpp
@@ -31,7 +31,7 @@
 
 namespace {
 
-void do_one_test(const fbl::unique_ptr<IsolatedDevmgr>& devmgr, const zx::channel& test_root,
+void do_one_test(const IsolatedDevmgr& devmgr, const zx::channel& test_root,
                  const char* drv_libname, const zx::socket& output,
                  fuchsia_device_test_TestReport* report) {
     // Initialize the report with a failure state to handle early returns
@@ -71,7 +71,7 @@
     fbl::unique_fd fd;
     int retry = 0;
     do {
-        fd.reset(openat(devmgr->devfs_root().get(), relative_devpath, O_RDWR));
+        fd.reset(openat(devmgr.devfs_root().get(), relative_devpath, O_RDWR));
         if (fd.is_valid()) {
             break;
         }
@@ -158,7 +158,7 @@
 int main(int argc, char** argv) {
     auto args = IsolatedDevmgr::DefaultArgs();
 
-    fbl::unique_ptr<IsolatedDevmgr> devmgr;
+    IsolatedDevmgr devmgr;
     zx_status_t status = IsolatedDevmgr::Create(std::move(args), &devmgr);
     if (status != ZX_OK) {
         printf("driver-tests: failed to create isolated devmgr\n");
@@ -174,7 +174,7 @@
 
     // Wait for /dev/test/test to appear
     fbl::unique_fd fd;
-    status = devmgr_integration_test::RecursiveWaitForFile(devmgr->devfs_root(), "test/test",
+    status = devmgr_integration_test::RecursiveWaitForFile(devmgr.devfs_root(), "test/test",
                                                            zx::deadline_after(zx::sec(5)), &fd);
     if (status != ZX_OK) {
         printf("driver-tests: failed to find /dev/test/test\n");
diff --git a/zircon/system/utest/platform-bus/main.cpp b/zircon/system/utest/platform-bus/main.cpp
index 44b0b2d..f0a30fc 100644
--- a/zircon/system/utest/platform-bus/main.cpp
+++ b/zircon/system/utest/platform-bus/main.cpp
@@ -60,35 +60,35 @@
     args.driver_search_paths.push_back("/boot/driver");
     ASSERT_TRUE(GetBootData(&args.bootdata));
 
-    fbl::unique_ptr<IsolatedDevmgr> devmgr;
+    IsolatedDevmgr devmgr;
     ASSERT_EQ(IsolatedDevmgr::Create(std::move(args), &devmgr), ZX_OK);
 
     fbl::unique_fd fd;
-    ASSERT_EQ(RecursiveWaitForFile(devmgr->devfs_root(), "sys/platform",
+    ASSERT_EQ(RecursiveWaitForFile(devmgr.devfs_root(), "sys/platform",
                                    zx::deadline_after(zx::sec(5)), &fd),
               ZX_OK);
 
-    EXPECT_EQ(RecursiveWaitForFile(devmgr->devfs_root(), "sys/platform/test-board",
+    EXPECT_EQ(RecursiveWaitForFile(devmgr.devfs_root(), "sys/platform/test-board",
                                    zx::deadline_after(zx::sec(5)), &fd),
               ZX_OK);
 
-    EXPECT_EQ(RecursiveWaitForFile(devmgr->devfs_root(), "sys/platform/11:01:1",
+    EXPECT_EQ(RecursiveWaitForFile(devmgr.devfs_root(), "sys/platform/11:01:1",
                                    zx::deadline_after(zx::sec(5)), &fd),
               ZX_OK);
 
-    EXPECT_EQ(RecursiveWaitForFile(devmgr->devfs_root(), "sys/platform/11:01:1/child-1",
+    EXPECT_EQ(RecursiveWaitForFile(devmgr.devfs_root(), "sys/platform/11:01:1/child-1",
                                    zx::deadline_after(zx::sec(5)), &fd),
               ZX_OK);
 
-    EXPECT_EQ(RecursiveWaitForFile(devmgr->devfs_root(), "sys/platform/11:01:1/child-1/child-2",
+    EXPECT_EQ(RecursiveWaitForFile(devmgr.devfs_root(), "sys/platform/11:01:1/child-1/child-2",
                                    zx::deadline_after(zx::sec(5)), &fd),
               ZX_OK);
 
-    EXPECT_EQ(RecursiveWaitForFile(devmgr->devfs_root(), "sys/platform/11:01:1/child-1/child-3",
+    EXPECT_EQ(RecursiveWaitForFile(devmgr.devfs_root(), "sys/platform/11:01:1/child-1/child-3",
                                    zx::deadline_after(zx::sec(5)), &fd),
               ZX_OK);
 
-    const int dirfd = devmgr->devfs_root().get();
+    const int dirfd = devmgr.devfs_root().get();
     struct stat st;
     EXPECT_EQ(fstatat(dirfd, "sys/platform/test-board", &st, 0), 0);
     EXPECT_EQ(fstatat(dirfd, "sys/platform/11:01:1", &st, 0), 0);