From 6b2c0470c203f52604fa43ea18802f4d14921834 Mon Sep 17 00:00:00 2001 From: "A. Cody Schuffelen" Date: Thu, 24 Sep 2026 17:23:15 -0700 Subject: [PATCH] Create a CF_ASSERT macro for tests In tests it is common to write ```c++ auto value = FunctionReturningResult(); ASSERT_THAT(value, IsOk()); DoSomething(*value); ``` It would be nice to have something like `CF_EXPECT` instead, to write a test as ```c++ auto value = CF_ASSERT(FunctionReturningResult()); DoSomething(value); ``` Sample error: ``` cuttlefish/host/commands/cvd/cli/commands/monitor/kernel_test.cc:31: Failure Value of: macro_intermediate_result Expected: an ok result Actual: 56-byte object , which is an error result with trace: | cuttlefish/host/commands/cvd/cli/commands/monitor/kernel.cc:55 v Result cuttlefish::ParseKernelLine(std::string_view) CF_EXPECT(false) ``` Bug: b/565923720 --- .../cvd/cli/commands/monitor/BUILD.bazel | 1 + .../cvd/cli/commands/monitor/kernel_test.cc | 39 +++++++++---------- base/cvd/cuttlefish/result/BUILD.bazel | 11 ++++++ base/cvd/cuttlefish/result/assert.h | 35 +++++++++++++++++ 4 files changed, 66 insertions(+), 20 deletions(-) create mode 100644 base/cvd/cuttlefish/result/assert.h diff --git a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/monitor/BUILD.bazel b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/monitor/BUILD.bazel index d057a357052..b100bc0262e 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/monitor/BUILD.bazel +++ b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/monitor/BUILD.bazel @@ -100,6 +100,7 @@ cf_cc_test( srcs = ["kernel_test.cc"], deps = [ ":kernel", + "//cuttlefish/result:assert", "//cuttlefish/result:result_matchers", ], ) diff --git a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/monitor/kernel_test.cc b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/monitor/kernel_test.cc index 1d1367bae77..8bb29b6702f 100644 --- a/base/cvd/cuttlefish/host/commands/cvd/cli/commands/monitor/kernel_test.cc +++ b/base/cvd/cuttlefish/host/commands/cvd/cli/commands/monitor/kernel_test.cc @@ -16,40 +16,39 @@ #include "cuttlefish/host/commands/cvd/cli/commands/monitor/kernel.h" -#include - #include "gmock/gmock.h" #include "gtest/gtest.h" +#include "cuttlefish/result/assert.h" #include "cuttlefish/result/result_matchers.h" namespace cuttlefish { TEST(KernelTest, ParseKernelLineValid) { - std::string line = "[ 0.123456] init: starting service"; - auto parsed = ParseKernelLine(line); - ASSERT_THAT(parsed, IsOk()); - EXPECT_EQ(parsed->timestamp, "[ 0.123456]"); - EXPECT_EQ(parsed->prefix, " init:"); - EXPECT_EQ(parsed->message, " starting service"); + static constexpr char kLine[] = "[ 0.123456] init: starting service"; + KernelLine parsed = CF_ASSERT(ParseKernelLine(kLine)); + + EXPECT_EQ(parsed.timestamp, "[ 0.123456]"); + EXPECT_EQ(parsed.prefix, " init:"); + EXPECT_EQ(parsed.message, " starting service"); } TEST(KernelTest, ParseKernelLineNoColon) { - std::string line = "[ 0.123456] Linux version 6.1.0"; - auto parsed = ParseKernelLine(line); - ASSERT_THAT(parsed, IsOk()); - EXPECT_EQ(parsed->timestamp, "[ 0.123456]"); - EXPECT_EQ(parsed->prefix, ""); - EXPECT_EQ(parsed->message, " Linux version 6.1.0"); + static constexpr char kLine[] = "[ 0.123456] Linux version 6.1.0"; + KernelLine parsed = CF_ASSERT(ParseKernelLine(kLine)); + + EXPECT_EQ(parsed.timestamp, "[ 0.123456]"); + EXPECT_EQ(parsed.prefix, ""); + EXPECT_EQ(parsed.message, " Linux version 6.1.0"); } TEST(KernelTest, ParseKernelLineParens) { - std::string line = "[ 0.123456] driver(param:val): message"; - auto parsed = ParseKernelLine(line); - ASSERT_THAT(parsed, IsOk()); - EXPECT_EQ(parsed->timestamp, "[ 0.123456]"); - EXPECT_EQ(parsed->prefix, " driver(param:val):"); - EXPECT_EQ(parsed->message, " message"); + static constexpr char kLine[] = "[ 0.123456] driver(param:val): message"; + KernelLine parsed = CF_ASSERT(ParseKernelLine(kLine)); + + EXPECT_EQ(parsed.timestamp, "[ 0.123456]"); + EXPECT_EQ(parsed.prefix, " driver(param:val):"); + EXPECT_EQ(parsed.message, " message"); } TEST(KernelTest, ParseKernelLineInvalid) { diff --git a/base/cvd/cuttlefish/result/BUILD.bazel b/base/cvd/cuttlefish/result/BUILD.bazel index 587d5730af5..922ac5c2c60 100644 --- a/base/cvd/cuttlefish/result/BUILD.bazel +++ b/base/cvd/cuttlefish/result/BUILD.bazel @@ -4,6 +4,17 @@ package( default_visibility = ["//:android_cuttlefish"], ) +cf_cc_library( + name = "assert", + testonly = 1, + hdrs = ["assert.h"], + deps = [ + "//cuttlefish/result:expect", + "//cuttlefish/result:result_matchers", + "@googletest//:gtest", + ], +) + cf_cc_library( name = "error_type", srcs = ["error_type.cc"], diff --git a/base/cvd/cuttlefish/result/assert.h b/base/cvd/cuttlefish/result/assert.h new file mode 100644 index 00000000000..755f0cb7c50 --- /dev/null +++ b/base/cvd/cuttlefish/result/assert.h @@ -0,0 +1,35 @@ +// +// Copyright (C) 2026 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +#pragma once + +#include "gmock/gmock.h" // IWYU pragma: keep: preprocessor + +#include "cuttlefish/result/expect.h" // IWYU pragma: keep: preprocessor +#include "cuttlefish/result/result_matchers.h" // IWYU pragma: keep: preprocessor + +#define CF_ASSERT_OVERLOAD(_1, _2, NAME, ...) NAME + +#define CF_ASSERT2(RESULT, MSG) \ + ({ \ + decltype(RESULT)&& macro_intermediate_result = RESULT; \ + ASSERT_THAT(macro_intermediate_result, IsOk()) << MSG; \ + OutcomeDereference(std::move(macro_intermediate_result)); \ + }) + +#define CF_ASSERT1(RESULT) CF_ASSERT2(RESULT, "") + +#define CF_ASSERT(...) \ + CF_ASSERT_OVERLOAD(__VA_ARGS__, CF_ASSERT2, CF_ASSERT1)(__VA_ARGS__)