Add support for unit tests

Change-Id: I7129d8a9ae5d76589530a3c9da6c9dfbe9d3a366
Reviewed-on: https://fuchsia-review.googlesource.com/c/drivers/wlan/intel/iwlwifi/+/647122
Fuchsia-Auto-Submit: Renato Mangini Dias <mangini@google.com>
Reviewed-by: Sakthi Vignesh Radhakrishnan <rsakthi@google.com>
Commit-Queue: Auto-Submit <auto-submit@fuchsia-infra.iam.gserviceaccount.com>
diff --git a/README.md b/README.md
index f727063..abeb371 100644
--- a/README.md
+++ b/README.md
@@ -57,7 +57,7 @@
 Let the emulator know where are the system packages for on-demand loading:
 
 ```
-tools/ffx repository add-from-pm sdk/amber-files
+tools/ffx repository add-from-pm bazel-iwlwifi/external/fuchsia_sdk/amber-files
 tools/ffx target repository register --alias fuchsia.com --repository devhost
 ```
 
@@ -71,7 +71,7 @@
 1. Build the driver:
 
   ```
-  tools/bazel build --config=fuchsia_x64 third_party/iwlwifi/platform:fuchsia_device
+  scripts/build.sh third_party/iwlwifi/platform:fuchsia_device
   ```
 
   This command will build the driver and make it available as a package on a local Fuchsia repository.
@@ -79,7 +79,7 @@
 2. Register the package repository
 
   ```
-  tools/ffx repository add-from-pm -r iwlwifi_driver_repo bazel-out/x86_64-fastbuild/bin/third_party/iwlwifi/iwlwifi_driver_repo
+  tools/ffx repository add-from-pm -r iwlwifi_driver_repo bazel-bin/third_party/iwlwifi/iwlwifi_driver_repo
   tools/ffx target repository register -r iwlwifi_driver_repo
   ```
 
@@ -102,3 +102,32 @@
   ```
   tools/ffx driver register fuchsia-pkg://iwlwifi_driver_repo/iwlwifi#lib/libcore.so
   ```
+
+## Run tests
+
+1. Build the tests:
+
+  ```
+  scripts/build.sh third_party/iwlwifi:driver_repository
+  ```
+
+  This command will build the driver and make it available as a package on a local Fuchsia repository.
+
+2. Register the package repository
+
+  ```
+  tools/ffx repository add-from-pm -r fuchsiadrivers.com bazel-bin/third_party/iwlwifi/fuchsiadrivers.com.repo
+  tools/ffx target repository register -r fuchsiadrivers.com
+  ```
+
+  TODO(fxbug.dev/92052): ffx does not play nice with the repository created by
+  Bazel, probably because Bazel removes the write permission so that external
+  players don't break the hermeciticy of the build. As a consequence, ffx
+  requires 'add-from-pm' and 'target repository register' every time a new
+  package is published.
+
+3. Execute the tests
+
+  ```
+  tools/ffx test run fuchsia-pkg://fuchsiadrivers.com/test_hello_pkg#meta/hello_test.cm
+  ```
diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel
index caabebe..51fd9a2 100644
--- a/WORKSPACE.bazel
+++ b/WORKSPACE.bazel
@@ -13,7 +13,10 @@
 
     # TODO: use a release tag or a specific commit hash to ensure
     # hermeciticy and reproductability.
-    branch = "main",
+    # branch = "main",
+
+    # TODO: remove once fxrev.dev/647121 is merged
+    commit = "2887fd57876a4a2c271c8a13fdad51ed88d96a7f",
 
     # use patch_cmds instead of strip_prefix because of https://github.com/bazelbuild/bazel/issues/10062
     # we need to remove /tools before moving because there is a bazel_rules_fuchsia/tools directory
@@ -65,3 +68,15 @@
 load("@com_grail_bazel_compdb//:deps.bzl", "bazel_compdb_deps")
 
 bazel_compdb_deps()
+
+load(
+    "@bazel_tools//tools/build_defs/repo:http.bzl",
+    "http_archive"
+)
+http_archive(
+  name = "com_google_googletest",
+  urls = ["https://github.com/google/googletest/archive/609281088cfefc76f9d0ce82e1ff6c30cc3591e5.zip"],
+  strip_prefix = "googletest-609281088cfefc76f9d0ce82e1ff6c30cc3591e5",
+  sha256 = "5cf189eb6847b4f8fc603a3ffff3b0771c08eec7dd4bd961bfd45477dd13eb73",
+  patches = ["fuchsia_bazel.patch", "fuchsia_gtest.patch", ],
+)
diff --git a/external/fuchsia_bazel.patch b/external/fuchsia_bazel.patch
new file mode 100644
index 0000000..1e1d7a6
--- /dev/null
+++ b/external/fuchsia_bazel.patch
@@ -0,0 +1,11 @@
+--- BUILD.bazel	2021-10-11 16:03:43.000000000 -0700
++++ BUILD.bazel	2022-02-07 15:56:37.000000000 -0800
+@@ -99,7 +99,7 @@
+         ":windows": [],
+         "//conditions:default": ["-pthread"],
+     }),
+-    deps = select({
++    deps = ["@fuchsia_sdk//pkg/fdio", "@fuchsia_sdk//pkg/zx",] + select({
+         ":has_absl": [
+             "@com_google_absl//absl/debugging:failure_signal_handler",
+             "@com_google_absl//absl/debugging:stacktrace",
diff --git a/external/fuchsia_gtest.patch b/external/fuchsia_gtest.patch
new file mode 100644
index 0000000..97082c7
--- /dev/null
+++ b/external/fuchsia_gtest.patch
@@ -0,0 +1,11 @@
+--- googletest/src/gtest-death-test.cc	2022-02-08 00:56:05.825834938 +0000
++++ googletest/src/gtest-death-test.cc	2022-02-08 00:56:18.291537025 +0000
+@@ -958,7 +958,7 @@
+       ZX_INFO_PROCESS, &buffer, sizeof(buffer), nullptr, nullptr);
+   GTEST_DEATH_TEST_CHECK_(status_zx == ZX_OK);
+ 
+-  GTEST_DEATH_TEST_CHECK_(buffer.exited);
++  // GTEST_DEATH_TEST_CHECK_(buffer.exited);
+   set_status(buffer.return_code);
+   return status();
+ }
diff --git a/scripts/bootstrap.sh b/scripts/bootstrap.sh
index 94fe178..1dfbb08 100755
--- a/scripts/bootstrap.sh
+++ b/scripts/bootstrap.sh
@@ -8,11 +8,11 @@
 
 # This script is used to fetch the prebuilt that is needed by driver build.
 
-readonly REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/..
+readonly REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." >/dev/null 2>&1 && pwd)"
 readonly BAZELISK_TOOL="${REPO_ROOT}/tools/bazel"
 readonly OVERRIDE_SDK="${REPO_ROOT}/fuchsia_sdk.tar.gz"
 readonly WORKSPACE_NAME="$(basename "$REPO_ROOT")"
-readonly SDK_WORKSPACE_DIR="${REPO_ROOT}/bazel-${WORKSPACE_NAME}/external/fuchsia_sdk_dynamic"
+readonly SDK_WORKSPACE_DIR="${REPO_ROOT}/bazel-${WORKSPACE_NAME}/external/fuchsia_sdk"
 
 function get_os {
   uname -s | tr '[:upper:]' '[:lower:]'
diff --git a/scripts/build.sh b/scripts/build.sh
index d4a8ea8..d880cec 100755
--- a/scripts/build.sh
+++ b/scripts/build.sh
@@ -9,11 +9,23 @@
 # This script is used by infra to validate that the driver can be built and
 # tests pass.
 
-readonly REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd)"/..
+readonly REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." >/dev/null 2>&1 && pwd)"
 readonly BAZELISK_TOOL="${REPO_ROOT}/tools/bazel"
 readonly OVERRIDE_SDK="${REPO_ROOT}/fuchsia_sdk.tar.gz"
+readonly DEFAULT_TARGET="third_party/iwlwifi/platform:fuchsia_device"
 
 main() {
+  target="$DEFAULT_TARGET"
+  args=()
+  while [[ "$#" -gt 0 ]]; do
+    if ! [[ "$1" =~ ^-- ]]; then
+      target="$1"
+    else
+      args+=( "$1" )
+    fi
+    shift
+  done
+
   if [[ -f "$OVERRIDE_SDK" && -z "$BAZEL_FUCHSIA_SDK_ARCHIVE" ]]; then
     export BAZEL_FUCHSIA_SDK_ARCHIVE="$OVERRIDE_SDK"
   fi
@@ -23,7 +35,7 @@
       exit 1
     fi
     echo -e >&2 "\033[1;33mINFO:\033[0m Using a local SDK: ${BAZEL_FUCHSIA_SDK_ARCHIVE##$REPO_ROOT/}"
-    "$BAZELISK_TOOL" build --config=fuchsia_x64 third_party/iwlwifi/platform:fuchsia_device "$@"
+    "$BAZELISK_TOOL" build --config=fuchsia_x64 "$target" "${args[@]}"
     echo "Everything build and all tests passed."
   else
     # TODO(mangini): handle this appropriately when the DDK is published by
diff --git a/third_party/iwlwifi/BUILD.bazel b/third_party/iwlwifi/BUILD.bazel
index 94b2781..520e1ed 100644
--- a/third_party/iwlwifi/BUILD.bazel
+++ b/third_party/iwlwifi/BUILD.bazel
@@ -2,6 +2,11 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+load(
+    "@rules_fuchsia//fuchsia:defs.bzl",
+    "fuchsia_package_repository",
+)
+
 package(default_visibility = ["//visibility:public"])
 
 cc_library(
@@ -42,3 +47,12 @@
         "//third_party/iwlwifi/platform:platform",
     ],
 )
+
+fuchsia_package_repository(
+    name = "driver_repository",
+    testonly = True,
+    repo_name = "fuchsiadrivers.com",
+    deps = [
+        "//third_party/iwlwifi/test:test_hello_pkg",
+    ],
+)
\ No newline at end of file
diff --git a/third_party/iwlwifi/test/BUILD.bazel b/third_party/iwlwifi/test/BUILD.bazel
index 6e4925a..37275a1 100644
--- a/third_party/iwlwifi/test/BUILD.bazel
+++ b/third_party/iwlwifi/test/BUILD.bazel
@@ -2,54 +2,98 @@
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
+load(
+    "@rules_fuchsia//fuchsia:defs.bzl",
+    "fuchsia_package",
+    "fuchsia_unittest_component",
+)
+
 package(default_visibility = ["//visibility:public"])
 
-cc_library(
-  name = "sim_library",
-  srcs = [
-    "fake-ucode-capa-test.cc",
-#    "inspect-host-cmd.cc",
-#    "inspect-host-cmd.h",
-#    "sim-mvm.cc",
-#    "sim-nvm-data.inc",
-#    "sim-nvm.cc",
-#    "sim-trans.cc",
-#    "single-ap-test.cc",
-#    "tlv-fw-builder.cc",
-#    "tlv-fw-builder.h",
-#    "wlan-pkt-builder.cc",
-  ],
-  hdrs = [
-    "fake-ucode-capa-test.h",
- #   "mock-trans.h",
- #  "sim-mvm.h",
- #  "sim-nvm.h",
- #  "sim-trans.h",
- #  "sim.h",
- #  "single-ap-test.h",
- #   "wlan-pkt-builder.h",
-   ],
-  deps = [
-  #  "//sdk/banjo/fuchsia.hardware.wlan.mac:fuchsia.hardware.wlan.mac_banjo_cpp",
-  #  "//sdk/banjo/fuchsia.hardware.wlanphyimpl:fuchsia.hardware.wlanphyimpl_banjo_cpp",
-  #  "//sdk/fidl/fuchsia.wlan.common:fuchsia.wlan.common_banjo_cpp",
-  #  "//third_party/iwlwifi:core",
-  #  "//third_party/iwlwifi/fw:api",
-  #  "//third_party/iwlwifi/mvm",
-  #  "//third_party/iwlwifi/platform:fuchsia_device",
-  # "//third_party/devices/testing/fake-bti",
-  # "//zircon/system/ulib/async-loop:async-loop-cpp",
-  # "//zircon/system/ulib/async-loop:async-loop-default",
-  # "//zircon/system/ulib/fbl",
+cc_test(
+    name = "hello_test",
+    size = "small",
+    srcs = ["hello_test.cc"],
+    deps = [
+        "@com_google_googletest//:gtest_main",
+    ],
+)
 
-  #  "//third_party/connectivity/wlan/drivers/testing/lib/sim-device",
-  #  "//third_party/connectivity/wlan/drivers/testing/lib/sim-env",
-  #  "//third_party/connectivity/wlan/drivers/testing/lib/sim-fake-ap",
-  # "//third_party/iwlwifi:core",
-  # "//third_party/iwlwifi/platform",
-  # "//third_party/devices/pci/testing:pci-protocol-fake",
-  # "//third_party/devices/testing/mock-ddk",
-  # "//zircon/system/public",
-   "//zircon/system/ulib/zxtest",
-  ],
+filegroup(
+    name = "common_libs",
+    srcs = [
+        "@fuchsia_sdk//:arch/x64/sysroot/dist/lib/ld.so.1",
+    ],
+    visibility = ["//visibility:public"],
+)
+
+fuchsia_unittest_component(
+    name = "test_hello_component",
+    test_name = "hello_test",
+    deps = [
+        ":common_libs",
+        ":hello_test",
+        "@fuchsia_clang//:dist",
+        "@fuchsia_sdk//pkg/fdio",
+    ],
+)
+
+fuchsia_package(
+    name = "test_hello_pkg",
+    package_name = "test_hello_pkg",
+    testonly = True,
+    visibility = ["//visibility:public"],
+    deps = [
+        ":test_hello_component",
+    ],
+)
+
+cc_library(
+    name = "sim_library",
+    srcs = [
+        "fake-ucode-capa-test.cc",
+        #    "inspect-host-cmd.cc",
+        #    "inspect-host-cmd.h",
+        #    "sim-mvm.cc",
+        #    "sim-nvm-data.inc",
+        #    "sim-nvm.cc",
+        #    "sim-trans.cc",
+        #    "single-ap-test.cc",
+        #    "tlv-fw-builder.cc",
+        #    "tlv-fw-builder.h",
+        #    "wlan-pkt-builder.cc",
+    ],
+    hdrs = [
+        "fake-ucode-capa-test.h",
+        #   "mock-trans.h",
+        #  "sim-mvm.h",
+        #  "sim-nvm.h",
+        #  "sim-trans.h",
+        #  "sim.h",
+        #  "single-ap-test.h",
+        #   "wlan-pkt-builder.h",
+    ],
+    deps = [
+        #  "//sdk/banjo/fuchsia.hardware.wlan.mac:fuchsia.hardware.wlan.mac_banjo_cpp",
+        #  "//sdk/banjo/fuchsia.hardware.wlanphyimpl:fuchsia.hardware.wlanphyimpl_banjo_cpp",
+        #  "//sdk/fidl/fuchsia.wlan.common:fuchsia.wlan.common_banjo_cpp",
+        #  "//third_party/iwlwifi:core",
+        #  "//third_party/iwlwifi/fw:api",
+        #  "//third_party/iwlwifi/mvm",
+        #  "//third_party/iwlwifi/platform:fuchsia_device",
+        # "//third_party/devices/testing/fake-bti",
+        # "//zircon/system/ulib/async-loop:async-loop-cpp",
+        # "//zircon/system/ulib/async-loop:async-loop-default",
+        # "//zircon/system/ulib/fbl",
+
+        #  "//third_party/connectivity/wlan/drivers/testing/lib/sim-device",
+        #  "//third_party/connectivity/wlan/drivers/testing/lib/sim-env",
+        #  "//third_party/connectivity/wlan/drivers/testing/lib/sim-fake-ap",
+        # "//third_party/iwlwifi:core",
+        # "//third_party/iwlwifi/platform",
+        # "//third_party/devices/pci/testing:pci-protocol-fake",
+        # "//third_party/devices/testing/mock-ddk",
+        # "//zircon/system/public",
+        "//zircon/system/ulib/zxtest",
+    ],
 )
diff --git a/third_party/iwlwifi/test/hello_test.cc b/third_party/iwlwifi/test/hello_test.cc
new file mode 100644
index 0000000..5a57e13
--- /dev/null
+++ b/third_party/iwlwifi/test/hello_test.cc
@@ -0,0 +1,9 @@
+#include <gtest/gtest.h>
+
+// Demonstrate some basic assertions.
+TEST(HelloTest, BasicAssertions) {
+  // Expect two strings not to be equal.
+  EXPECT_STRNE("hello", "world");
+  // Expect equality.
+  EXPECT_EQ(7 * 6, 42);
+}
diff --git a/third_party/iwlwifi/test/meta/test_manifest.cml b/third_party/iwlwifi/test/meta/test_manifest.cml
new file mode 100644
index 0000000..eb407ef
--- /dev/null
+++ b/third_party/iwlwifi/test/meta/test_manifest.cml
@@ -0,0 +1,15 @@
+{
+    program: {
+        runner: 'elf_test_runner',
+        binary: 'bin/hello_test',
+    },
+    capabilities: [
+        { protocol: "fuchsia.test.Suite" },
+    ],
+    expose: [
+        {
+            protocol: "fuchsia.test.Suite",
+            from: "self",
+        },
+    ],
+}
\ No newline at end of file