[samples] Migrate unit tests to CFv2 components

Update the sample unit tests for hello_world and rot13 to run as
Fuchsia test packages on a target device using CFv2 test runners.

Bug: 87492
Test: scripts/setup-and-test.sh
Change-Id: Ic1a9076e32e62effcb4f022d07b9e6588221e8d5
Reviewed-on: https://fuchsia-review.googlesource.com/c/samples/+/647250
Reviewed-by: Wayne Piekarski <waynepie@google.com>
Commit-Queue: Dave Smith <smithdave@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index e7bb152..f41c941 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -22,21 +22,30 @@
     ]
     outputs = [ "${root_out_dir}/{{source_file_part}}" ]
   }
+
+  copy("tests") {
+    testonly = true
+    deps = [
+      "//src/calculator:tests",
+      "//src/hello_world:tests",
+      "//src/rot13:tests",
+    ]
+    sources = [
+      "${target_gen_dir}/src/hello_world/hello_world_test/hello_world_test.far",
+      "${target_gen_dir}/src/calculator/engine/engine_unittest/engine_unittest.far",
+      "${target_gen_dir}/src/rot13/server/rot13_unittests/rot13_unittests.far",
+    ]
+    outputs = [ "${root_out_dir}/{{source_file_part}}" ]
+  }
 } else {
   group("default") {
     deps = [ "//src/hello_world" ]
   }
-}
 
-group("tests") {
-  testonly = true
-  deps = [ "//src/hello_world:tests" ]
-  if (is_fuchsia) {
-    deps += [
-      "//src/calculator:tests",
-      "//src/rot13:tests",
-    ]
-  }
+  group("tests") {
+    testonly = true
+    deps = [ "//src/hello_world:tests" ]
+  } 
 }
 
 # build all the targets exposed by the Fuchsia sdk.
diff --git a/src/calculator/BUILD.gn b/src/calculator/BUILD.gn
index f64716a..6b2bcdb 100644
--- a/src/calculator/BUILD.gn
+++ b/src/calculator/BUILD.gn
@@ -15,7 +15,7 @@
 
 group("tests") {
   testonly = true
-  deps = [
+  public_deps = [
     "//src/calculator/engine:tests",
   ]
 }
diff --git a/src/calculator/README.md b/src/calculator/README.md
index 697e437..a180a75 100644
--- a/src/calculator/README.md
+++ b/src/calculator/README.md
@@ -64,3 +64,43 @@
     [calculator_realm/client] INFO: Request: 2 + 2
     [calculator_realm/client] INFO: Result: 4
     ```
+
+## Run the unit tests
+
+1.  Execute the unit test suite using `ffx test run`. This resolves the
+    component from the package repository and executes the tests:
+
+    ```
+    $ ffx test run fuchsia-pkg://fuchsia.com/engine_unittest#meta/engine_unittest.cm
+    ```
+
+1.  Verify that the test cases pass:
+
+    ```
+    Running test 'fuchsia-pkg://fuchsia.com/engine_unittest#meta/engine_unittest.cm'
+    [RUNNING]	main
+    [stdout - main]
+    Running main() from ../../third_party/googletest/src/googletest/src/gtest_main.cc
+    [==========] Running 5 tests from 1 test suite.
+    [----------] Global test environment set-up.
+    [----------] 5 tests from EngineUnitTest
+    [ RUN      ] EngineUnitTest.Negate
+    [       OK ] EngineUnitTest.Negate (11 ms)
+    [ RUN      ] EngineUnitTest.Add
+    [       OK ] EngineUnitTest.Add (12 ms)
+    [ RUN      ] EngineUnitTest.Subtract
+    [       OK ] EngineUnitTest.Subtract (12 ms)
+    [ RUN      ] EngineUnitTest.Multiply
+    [       OK ] EngineUnitTest.Multiply (11 ms)
+    [ RUN      ] EngineUnitTest.Divide
+    [       OK ] EngineUnitTest.Divide (11 ms)
+    [----------] 5 tests from EngineUnitTest (60 ms total)
+
+    [----------] Global test environment tear-down
+    [==========] 5 tests from 1 test suite ran. (66 ms total)
+    [  PASSED  ] 5 tests.
+    [PASSED]	main
+
+    1 out of 1 tests passed...
+    fuchsia-pkg://fuchsia.com/engine_unittest#meta/engine_unittest.cm completed with result: PASSED
+    ```
diff --git a/src/calculator/engine/BUILD.gn b/src/calculator/engine/BUILD.gn
index 0602c36..00c7058 100644
--- a/src/calculator/engine/BUILD.gn
+++ b/src/calculator/engine/BUILD.gn
@@ -4,13 +4,15 @@
 
 import("//third_party/fuchsia-sdk/build/component.gni")
 import("//third_party/fuchsia-sdk/build/package.gni")
+import("//third_party/fuchsia-sdk/build/test.gni")
 
-# All tests.
+
 group("tests") {
   testonly = true
 
-  deps = [
-    "//src/calculator/engine/test",
+  public_deps = [
+    ":engine_unittest",
+    ":engine_unittest_package",
   ]
 }
 
@@ -73,3 +75,14 @@
     ":component",
   ]
 }
+
+# Fuchsia test component containing the Calculator engine unit tests.
+fuchsia_test("engine_unittest") {
+  manifest = "meta/engine_unittest.cml"
+
+  sources = [ "test/engine_unittest.cc" ]
+  deps = [
+    "//src/calculator/engine:lib",
+    "//third_party/googletest:gtest_main",
+  ]
+}
diff --git a/src/calculator/engine/meta/engine_unittest.cml b/src/calculator/engine/meta/engine_unittest.cml
new file mode 100644
index 0000000..6efb251
--- /dev/null
+++ b/src/calculator/engine/meta/engine_unittest.cml
@@ -0,0 +1,9 @@
+{
+    include: [
+        "syslog/client.shard.cml",
+        "sys/testing/elf_test_runner.shard.cml",
+    ],
+    program: {
+        binary: "engine_unittest__exec",
+    },
+}
diff --git a/src/calculator/engine/test/BUILD.gn b/src/calculator/engine/test/BUILD.gn
deleted file mode 100644
index a5d8467..0000000
--- a/src/calculator/engine/test/BUILD.gn
+++ /dev/null
@@ -1,26 +0,0 @@
-# Copyright 2019 The Fuchsia Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-import("//build/testing.gni")
-
-# All tests.
-group("test") {
-  testonly = true
-
-  deps = [
-    ":engine_host_unit_test",
-  ]
-}
-
-# An executable containing unit tests that can be run on the development host.
-test("engine_host_unit_test") {
-  sources = [
-    "engine_host_unit_test.cc",
-  ]
-
-  deps = [
-    "//src/calculator/engine:lib",
-    "//third_party/googletest:gtest_main",
-  ]
-}
diff --git a/src/calculator/engine/test/engine_host_unit_test.cc b/src/calculator/engine/test/engine_unittest.cc
similarity index 68%
rename from src/calculator/engine/test/engine_host_unit_test.cc
rename to src/calculator/engine/test/engine_unittest.cc
index 2febdfa..691e53f 100644
--- a/src/calculator/engine/test/engine_host_unit_test.cc
+++ b/src/calculator/engine/test/engine_unittest.cc
@@ -2,7 +2,7 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-/// Test cases for the math engine that run on the development host.
+/// Unit test cases for the math engine.
 
 #include <gtest/gtest.h>
 
@@ -11,32 +11,32 @@
 namespace calculator_engine {
 
 /// The fixture for testing class the calculator engine.
-class EngineHostUnitTest : public ::testing::Test {
+class EngineUnitTest : public ::testing::Test {
  protected:
-  EngineHostUnitTest() = default;
+  EngineUnitTest() = default;
 };
 
-TEST_F(EngineHostUnitTest, Negate) {
+TEST_F(EngineUnitTest, Negate) {
   double result = negate(3.5);
   EXPECT_DOUBLE_EQ(-3.5, result);
 }
 
-TEST_F(EngineHostUnitTest, Add) {
+TEST_F(EngineUnitTest, Add) {
   double result = add(3.5, 2.5);
   EXPECT_DOUBLE_EQ(6., result);
 }
 
-TEST_F(EngineHostUnitTest, Subtract) {
+TEST_F(EngineUnitTest, Subtract) {
   double result = subtract(3.5, 2.5);
   EXPECT_DOUBLE_EQ(1., result);
 }
 
-TEST_F(EngineHostUnitTest, Multiply) {
+TEST_F(EngineUnitTest, Multiply) {
   double result = multiply(3.5, 2.5);
   EXPECT_DOUBLE_EQ(8.75, result);
 }
 
-TEST_F(EngineHostUnitTest, Divide) {
+TEST_F(EngineUnitTest, Divide) {
   double result = divide(3.5, 2.5);
   EXPECT_DOUBLE_EQ(1.4, result);
 }
diff --git a/src/hello_world/BUILD.gn b/src/hello_world/BUILD.gn
index fbbb58f..d46ceee 100644
--- a/src/hello_world/BUILD.gn
+++ b/src/hello_world/BUILD.gn
@@ -2,9 +2,6 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-# testing is for host base unit tests using googletest
-import("//build/testing.gni")
-
 # default group
 group("hello_world") {
   deps = [ ":hello_bin" ]
@@ -15,10 +12,15 @@
   }
 }
 
-# Tests group
+# tests group
 group("tests") {
   testonly = true
-  deps = [ ":hello_world_test" ]
+  if (is_fuchsia) {
+    public_deps = [
+      ":hello_world_test",
+      ":hello_world_test_package",
+    ]
+  }
 }
 
 # Executable using both a static and shared lib.
@@ -46,19 +48,10 @@
   ]
 }
 
-# Host unit test
-test("hello_world_test") {
-  sources = [ "test/hello_test.cc" ]
-  deps = [
-    ":hello_static",
-    "//third_party/googletest:gtest",
-    "//third_party/googletest:gtest_main",
-  ]
-}
-
 if (is_fuchsia) {
   import("//third_party/fuchsia-sdk/build/component.gni")
   import("//third_party/fuchsia-sdk/build/package.gni")
+  import("//third_party/fuchsia-sdk/build/test.gni")
 
   fuchsia_component("component") {
     manifest_output_name = "hello_world"
@@ -70,4 +63,14 @@
     package_name = "hello_world"
     deps = [ ":component" ]
   }
+
+  fuchsia_test("hello_world_test") {
+    manifest = "meta/hello_world_test.cml"
+
+    sources = [ "test/hello_test.cc" ]
+    deps = [
+      "//third_party/googletest:gtest",
+      "//third_party/googletest:gtest_main",
+    ]
+  }
 }
diff --git a/src/hello_world/README.md b/src/hello_world/README.md
index 4fdb86f..0959310 100644
--- a/src/hello_world/README.md
+++ b/src/hello_world/README.md
@@ -57,3 +57,25 @@
     [hello_world][I] Hello, world
     [hello_world][I] cppthreads: hello
     ```
+
+## Run the unit tests
+
+1.  Execute the unit test suite using `ffx test run`. This resolves the
+    component from the package repository and executes the tests:
+
+    ```
+    $ ffx test run fuchsia-pkg://fuchsia.com/hello_world_test#meta/hello_world_test.cm
+    ```
+
+1.  Verify that the test cases pass:
+
+    ```
+    Running test 'fuchsia-pkg://fuchsia.com/hello_world_test#meta/hello_world_test.cm'
+    [RUNNING]	HelloWorldTest.True
+    [stdout - HelloWorldTest.True]
+    Running main() from ../../third_party/googletest/src/googletest/src/gtest_main.cc
+    [PASSED]	HelloWorldTest.True
+
+    1 out of 1 tests passed...
+    fuchsia-pkg://fuchsia.com/hello_world_test#meta/hello_world_test.cm completed with result: PASSED
+    ```
diff --git a/src/hello_world/meta/hello_world_test.cml b/src/hello_world/meta/hello_world_test.cml
new file mode 100644
index 0000000..9eefb8d
--- /dev/null
+++ b/src/hello_world/meta/hello_world_test.cml
@@ -0,0 +1,9 @@
+{
+    include: [
+        "syslog/client.shard.cml",
+        "sys/testing/elf_test_runner.shard.cml",
+    ],
+    program: {
+        binary: "hello_world_test__exec",
+    },
+}
diff --git a/src/hello_world/test/hello_test.cc b/src/hello_world/test/hello_test.cc
index 6321173..513ad83 100644
--- a/src/hello_world/test/hello_test.cc
+++ b/src/hello_world/test/hello_test.cc
@@ -2,8 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <memory>
-
-#include "third_party/googletest/src/googletest/include/gtest/gtest.h"
+#include <gtest/gtest.h>
 
 TEST(HelloWorldTest, True) { EXPECT_TRUE(true); }
diff --git a/src/rot13/BUILD.gn b/src/rot13/BUILD.gn
index 51f43ac..21d6c51 100644
--- a/src/rot13/BUILD.gn
+++ b/src/rot13/BUILD.gn
@@ -15,8 +15,8 @@
 
 group("tests") {
   testonly = true
-  deps = [
-    "//src/rot13/server:host_tests",
+  public_deps = [
+    "//src/rot13/server:tests",
   ]
 }
 
diff --git a/src/rot13/README.md b/src/rot13/README.md
index 293b600..4e79819 100644
--- a/src/rot13/README.md
+++ b/src/rot13/README.md
@@ -84,3 +84,45 @@
       // ...
     }
     ```
+
+## Run the unit tests
+
+1.  Execute the unit test suite using `ffx test run`. This resolves the
+    component from the package repository and executes the tests:
+
+    ```
+    $ ffx test run fuchsia-pkg://fuchsia.com/rot13_unittests#meta/rot13_unittests.cm
+    ```
+
+1.  Verify that the test cases pass:
+
+    ```
+    Running test 'fuchsia-pkg://fuchsia.com/rot13_unittests#meta/rot13_unittests.cm'
+    [RUNNING]	Rot13Test.TrueTest
+    [stdout - Rot13Test.TrueTest]
+    Running main() from ../../third_party/googletest/src/googletest/src/gtest_main.cc
+    [PASSED]	Rot13Test.TrueTest
+    [RUNNING]	Rot13Test.Encrypt_EdgeCases
+    [stdout - Rot13Test.Encrypt_EdgeCases]
+    Running main() from ../../third_party/googletest/src/googletest/src/gtest_main.cc
+    [PASSED]	Rot13Test.Encrypt_EdgeCases
+    [RUNNING]	Rot13Test.Encrypt_HelloWorld
+    [stdout - Rot13Test.Encrypt_HelloWorld]
+    Running main() from ../../third_party/googletest/src/googletest/src/gtest_main.cc
+    [PASSED]	Rot13Test.Encrypt_HelloWorld
+    [RUNNING]	Rot13Test.Encrypt_Empty
+    [stdout - Rot13Test.Encrypt_Empty]
+    Running main() from ../../third_party/googletest/src/googletest/src/gtest_main.cc
+    [PASSED]	Rot13Test.Encrypt_Empty
+    [RUNNING]	Rot13Test.Checksum_Empty
+    [stdout - Rot13Test.Checksum_Empty]
+    Running main() from ../../third_party/googletest/src/googletest/src/gtest_main.cc
+    [PASSED]	Rot13Test.Checksum_Empty
+    [RUNNING]	Rot13Test.Checksum_HelloWorld
+    [stdout - Rot13Test.Checksum_HelloWorld]
+    Running main() from ../../third_party/googletest/src/googletest/src/gtest_main.cc
+    [PASSED]	Rot13Test.Checksum_HelloWorld
+
+    6 out of 6 tests passed...
+    fuchsia-pkg://fuchsia.com/rot13_unittests#meta/rot13_unittests.cm completed with result: PASSED
+    ```
diff --git a/src/rot13/server/BUILD.gn b/src/rot13/server/BUILD.gn
index 62ec009..6180991 100644
--- a/src/rot13/server/BUILD.gn
+++ b/src/rot13/server/BUILD.gn
@@ -2,16 +2,15 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-import("//build/testing.gni")
-import("//third_party/fuchsia-sdk/build/component.gni")
-import("//third_party/fuchsia-sdk/build/package.gni")
-
-group("host_tests") {
-  # Tests run on the host. These are unit tests that are platform independent.
+#tests group
+group("tests") {
   testonly = true
-  deps = [
-    ":rot13_unittests",
-  ]
+  if (is_fuchsia) {
+    public_deps = [
+      ":rot13_unittests",
+      ":rot13_unittests_package",
+    ]
+  }
 }
 
 # Keep the app in a lib component so it can be reused by tests
@@ -37,19 +36,6 @@
   ]
 }
 
-# Testing rules
-test("rot13_unittests") {
-  sources = [
-    "rot13_unittests.cc",
-  ]
-  deps = [
-    ":impl_lib",
-    "//third_party/googletest:gtest",
-    "//third_party/googletest:gtest_main",
-  ]
-}
-
-# Server targets
 executable("rot13_server_bin") {
   sources = [
     "rot13_server.cc",
@@ -62,15 +48,33 @@
   ]
 }
 
-fuchsia_component("server_component") {
-  manifest = "meta/rot13_server.cml"
-  data_deps = [
-    ":rot13_server_bin",
-  ]
-}
+if (is_fuchsia) {
+  import("//third_party/fuchsia-sdk/build/component.gni")
+  import("//third_party/fuchsia-sdk/build/package.gni")
+  import("//third_party/fuchsia-sdk/build/test.gni")
 
-fuchsia_package("rot13_server") {
-  deps = [
-    ":server_component",
-  ]
+  fuchsia_component("server_component") {
+    manifest = "meta/rot13_server.cml"
+    data_deps = [
+      ":rot13_server_bin",
+    ]
+  }
+
+  fuchsia_package("rot13_server") {
+    deps = [
+      ":server_component",
+    ]
+  }
+
+  fuchsia_test("rot13_unittests") {
+    manifest = "meta/rot13_unittests.cml"
+    sources = [
+      "rot13_unittests.cc",
+    ]
+    deps = [
+      ":impl_lib",
+      "//third_party/googletest:gtest",
+      "//third_party/googletest:gtest_main",
+    ]
+  }
 }
diff --git a/src/rot13/server/meta/rot13_unittests.cml b/src/rot13/server/meta/rot13_unittests.cml
new file mode 100644
index 0000000..2f85560
--- /dev/null
+++ b/src/rot13/server/meta/rot13_unittests.cml
@@ -0,0 +1,9 @@
+{
+    include: [
+        "syslog/client.shard.cml",
+        "sys/testing/elf_test_runner.shard.cml",
+    ],
+    program: {
+        binary: "rot13_unittests__exec",
+    },
+}