Allow a #[gtest] test to specify a C++ class for its TestSuite. [chromium/src : main]

9 views
Skip to first unread message

danakj (Gerrit)

unread,
Mar 30, 2022, 1:57:20 PM3/30/22
to rust...@chromium.org, Łukasz Anforowicz, Adrian Taylor, chromium...@chromium.org

Attention is currently required from: Łukasz Anforowicz.

Patch set 21:Commit-Queue +1

View Change

    To view, visit change 3560902. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I1fe5efa8090435133054b3b7e71f28184b9d4733
    Gerrit-Change-Number: 3560902
    Gerrit-PatchSet: 21
    Gerrit-Owner: danakj <dan...@chromium.org>
    Gerrit-Reviewer: danakj <dan...@chromium.org>
    Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-CC: Adrian Taylor <adet...@chromium.org>
    Gerrit-Attention: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-Comment-Date: Wed, 30 Mar 2022 17:57:11 +0000
    Gerrit-HasComments: No
    Gerrit-Has-Labels: Yes
    Gerrit-MessageType: comment

    danakj (Gerrit)

    unread,
    Mar 30, 2022, 1:57:22 PM3/30/22
    to rust...@chromium.org, Matthew Riley, Łukasz Anforowicz

    Attention is currently required from: Łukasz Anforowicz.

    danakj has uploaded this change for review.

    View Change

    Allow a #[gtest] test to specify a C++ class for its TestSuite.

    By default the testing::Test class is used, which is equivalent to the
    C++ TEST() macro. But just as in C++, with the TEST_F() macro, we need
    a way to specify a different class to be the TestSuite. The only
    requirement is that the test is a subclass of testing::Test.

    We generalize the Gtest TestSuite factory code with a templated
    function, but Rust can not call templated C++ functions yet. So we
    still wrap that function with the pre-existing
    rust_gtest_default_factory() function.

    This would allow easily writing other factory functions in C++ targets
    outside of //testing on top of the template helper, or even generating
    such functions in the future.

    We augment the #[gtest] macro to look for a further #[gtest_suite]
    macro that names a C++ factory for the TestSuite class. The syntax is:

    #[gtest_suite(some_factory_function)]

    Where the factory function is an unsafe extern "C" function pointer that
    receives a function pointer and returns a
    rust_gtest_interop::GtestFactoryPtr, making its signature:

    unsafe extern "C" fn(f: extern "C" fn()) -> GTestFactoryPtr

    In the process, we drop a level of abstraction, so we no longer have a
    factory-factory, and Rust works with a function pointer to the C++
    function directly.

    R=luk...@chromium.org

    Bug: 1305396
    Change-Id: I1fe5efa8090435133054b3b7e71f28184b9d4733
    Cq-Include-Trybots: luci.chromium.try:android-rust-arm-rel,android-rust-arm-dbg,linux-rust-x64-dbg,linux-rust-x64-rel
    ---
    M testing/rust_gtest_interop/BUILD.gn
    M testing/rust_gtest_interop/README.md
    M testing/rust_gtest_interop/gtest_attribute.rs
    M testing/rust_gtest_interop/rust_gtest_interop.cc
    M testing/rust_gtest_interop/rust_gtest_interop.h
    M testing/rust_gtest_interop/rust_gtest_interop.rs
    M testing/rust_gtest_interop/rust_gtest_interop_unittest.rs
    M testing/rust_gtest_interop/rust_gtest_interop_unittest_main.cc
    A testing/rust_gtest_interop/test/test_factory.cc
    A testing/rust_gtest_interop/test/test_factory.h
    10 files changed, 308 insertions(+), 79 deletions(-)


    To view, visit change 3560902. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I1fe5efa8090435133054b3b7e71f28184b9d4733
    Gerrit-Change-Number: 3560902
    Gerrit-PatchSet: 21
    Gerrit-Owner: danakj <dan...@chromium.org>
    Gerrit-Reviewer: danakj <dan...@chromium.org>
    Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-CC: Adrian Taylor <adet...@chromium.org>
    Gerrit-CC: Matthew Riley <mat...@chromium.org>
    Gerrit-Attention: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-MessageType: newchange

    Łukasz Anforowicz (Gerrit)

    unread,
    Mar 30, 2022, 5:58:33 PM3/30/22
    to danakj, rust...@chromium.org, Chromium LUCI CQ, Matthew Riley, Adrian Taylor, chromium...@chromium.org

    Attention is currently required from: danakj.

    View Change

    4 comments:

    • File testing/rust_gtest_interop/gtest_attribute.rs:

      • Patch Set #23, Line 2: TokenStream2

        I think that this Stack Overflow answer (and the question above) are quite interesting to read: https://stackoverflow.com/a/63280281/4692014

        In particular, it suggests to import items from proc-macro2 (so they can be used unqualified), and just used fully qualified names for proc_macro.

      • Patch Set #23, Line 269:

                        fn #rust_gtest_default_factory(
        body: extern "C" fn(),
        ) -> ::rust_gtest_interop::GtestSuitePtr;

        #gtest_factory_fn_signature

        Only one of these is needed at a time, right? Would we be able to simplify the code here a bit, if everything (including the defaults) went through non-optional `gtest_factory_fn` and `gtest_factory_fn_signature`?

    • File testing/rust_gtest_interop/rust_gtest_interop.h:

      • Patch Set #23, Line 19:

        The Subclass must be
        // `testing::Test`, or a subclass thereof

        Can this requirement be enforced via `static_assert` / `std::is_base_of`?

    • File testing/rust_gtest_interop/test/test_factory.h:

      • Patch Set #23, Line 20:

        // A custom Gtest factory that returns a `TestSubclass`.
        extern "C" testing::Test* test_subclass_factory(void (*body)()) {
        return rust_gtest_interop::rust_gtest_factory_for_subclass<TestSubclass>(
        body);
        }

        // Returns how many times the test_subclass_factory() function was called.
        extern "C" size_t num_subclass_created() {
        return TestSubclass::num_created();
        }

        These can be moved into the .cc file, right? I guess having them here is fine, although they aren't *really* part of the public API (they are only used from internals of rust_gtest_interop / are not used by actual test code).

    To view, visit change 3560902. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I1fe5efa8090435133054b3b7e71f28184b9d4733
    Gerrit-Change-Number: 3560902
    Gerrit-PatchSet: 23
    Gerrit-Owner: danakj <dan...@chromium.org>
    Gerrit-Reviewer: danakj <dan...@chromium.org>
    Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-CC: Adrian Taylor <adet...@chromium.org>
    Gerrit-CC: Matthew Riley <mat...@chromium.org>
    Gerrit-Attention: danakj <dan...@chromium.org>
    Gerrit-Comment-Date: Wed, 30 Mar 2022 21:58:24 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Gerrit-MessageType: comment

    danakj (Gerrit)

    unread,
    Mar 31, 2022, 9:39:28 AM3/31/22
    to rust...@chromium.org, Chromium LUCI CQ, Matthew Riley, Łukasz Anforowicz, Adrian Taylor, chromium...@chromium.org

    Attention is currently required from: Łukasz Anforowicz.

    View Change

    5 comments:

      • I think that this Stack Overflow answer (and the question above) are quite interesting to read: http […]

        Oh okay.

      • Patch Set #23, Line 269:

                        fn #rust_gtest_default_factory(
        body: extern "C" fn(),
        ) -> ::rust_gtest_interop::GtestSuitePtr;

        #gtest_factory_fn_signature

      • Only one of these is needed at a time, right? Would we be able to simplify the code here a bit, if […]

        Yeah, the next CL was doing something like this as well. Done.

    • File testing/rust_gtest_interop/rust_gtest_interop.h:

      • Patch Set #23, Line 19:

        The Subclass must be
        // `testing::Test`, or a subclass thereof

        Can this requirement be enforced via `static_assert` / `std::is_base_of`?

      • It is enforced when rust_gtest_factory_for_subclass returns it as a Test*. We could also check is_convertable here, though it would be redundant I think, since that's where RustClass is constructed? I suppose someone could (incorrectly) bypass rust_gtest_factory_for_subclass... Done.

    • File testing/rust_gtest_interop/test/test_factory.h:

      • Patch Set #23, Line 20:

        // A custom Gtest factory that returns a `TestSubclass`.
        extern "C" testing::Test* test_subclass_factory(void (*body)()) {
        return rust_gtest_interop::rust_gtest_factory_for_subclass<TestSubclass>(
        body);
        }

        // Returns how many times the test_subclass_factory() function was called.
        extern "C" size_t num_subclass_created() {
        return TestSubclass::num_created();
        }

      • These can be moved into the . […]

        They are used by rust_gtest_interop_unittests only. They and are not part of rust_gtest_interop.

        They could go in the .cc yes. I was thinking eventually they'll go away when the unit test can use the TestSubclass, and template functions directly instead. And in the meantime they may get consumed by a binding generator in which case they need to be in the header.

    To view, visit change 3560902. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I1fe5efa8090435133054b3b7e71f28184b9d4733
    Gerrit-Change-Number: 3560902
    Gerrit-PatchSet: 23
    Gerrit-Owner: danakj <dan...@chromium.org>
    Gerrit-Reviewer: danakj <dan...@chromium.org>
    Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-CC: Adrian Taylor <adet...@chromium.org>
    Gerrit-CC: Matthew Riley <mat...@chromium.org>
    Gerrit-Attention: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-Comment-Date: Thu, 31 Mar 2022 13:39:10 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: No
    Comment-In-Reply-To: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-MessageType: comment

    Łukasz Anforowicz (Gerrit)

    unread,
    Mar 31, 2022, 8:41:40 PM3/31/22
    to danakj, rust...@chromium.org, Chromium LUCI CQ, Matthew Riley, Adrian Taylor, chromium...@chromium.org

    Attention is currently required from: danakj.

    Patch set 24:Code-Review +1

    View Change

    3 comments:

    • Patchset:

    • File testing/rust_gtest_interop/README.md:

      • Patch Set #24, Line 169: chosen_class_gtest_factory

        Macro expansion will generate a bunch of ~manual FFI declarations. This is okay to get things working. But... I wonder if we should say somewhere here that 1) this is `unsafe` (e.g. if a user provides an incompatible function signature to `gtest_suite` then they get crashes/UB/etc) and 2) that the unsafety can go away after more investment into automated bindings generation (maybe marking this with a TODO(bug) for tracking).

        WDYT?

    • File testing/rust_gtest_interop/gtest_attribute.rs:

      • Oh okay.

        In particular, I hope that this helps with making parts of this unit-testable.

    To view, visit change 3560902. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I1fe5efa8090435133054b3b7e71f28184b9d4733
    Gerrit-Change-Number: 3560902
    Gerrit-PatchSet: 24
    Gerrit-Owner: danakj <dan...@chromium.org>
    Gerrit-Reviewer: danakj <dan...@chromium.org>
    Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-CC: Adrian Taylor <adet...@chromium.org>
    Gerrit-CC: Matthew Riley <mat...@chromium.org>
    Gerrit-Attention: danakj <dan...@chromium.org>
    Gerrit-Comment-Date: Fri, 01 Apr 2022 00:41:24 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes
    Comment-In-Reply-To: danakj <dan...@chromium.org>

    danakj (Gerrit)

    unread,
    Apr 1, 2022, 10:18:33 AM4/1/22
    to rust...@chromium.org, Łukasz Anforowicz, Chromium LUCI CQ, Matthew Riley, Adrian Taylor, chromium...@chromium.org

    Patch set 24:Commit-Queue +2

    View Change

    1 comment:

    • File testing/rust_gtest_interop/README.md:

      • Macro expansion will generate a bunch of ~manual FFI declarations. […]

        Let's see how the dust settles on the next CL. I don't think it's good in the way it is now. But with the macro + specifying types it's a bit better, and very different from this.

    To view, visit change 3560902. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I1fe5efa8090435133054b3b7e71f28184b9d4733
    Gerrit-Change-Number: 3560902
    Gerrit-PatchSet: 24
    Gerrit-Owner: danakj <dan...@chromium.org>
    Gerrit-Reviewer: danakj <dan...@chromium.org>
    Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-CC: Adrian Taylor <adet...@chromium.org>
    Gerrit-CC: Matthew Riley <mat...@chromium.org>
    Gerrit-Comment-Date: Fri, 01 Apr 2022 14:18:19 +0000
    Gerrit-HasComments: Yes
    Gerrit-Has-Labels: Yes

    Chromium LUCI CQ (Gerrit)

    unread,
    Apr 1, 2022, 10:44:09 AM4/1/22
    to danakj, rust...@chromium.org, Łukasz Anforowicz, Matthew Riley, Adrian Taylor, chromium...@chromium.org

    Chromium LUCI CQ submitted this change.

    View Change


    Approvals: Łukasz Anforowicz: Looks good to me danakj: Commit
    Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3560902
    Reviewed-by: Łukasz Anforowicz <luk...@chromium.org>
    Commit-Queue: danakj <dan...@chromium.org>
    Cr-Commit-Position: refs/heads/main@{#987906}

    ---
    M testing/rust_gtest_interop/BUILD.gn
    M testing/rust_gtest_interop/README.md
    M testing/rust_gtest_interop/gtest_attribute.rs
    M testing/rust_gtest_interop/rust_gtest_interop.cc
    M testing/rust_gtest_interop/rust_gtest_interop.h
    M testing/rust_gtest_interop/rust_gtest_interop.rs
    M testing/rust_gtest_interop/rust_gtest_interop_unittest.rs
    M testing/rust_gtest_interop/rust_gtest_interop_unittest_main.cc
    A testing/rust_gtest_interop/test/test_factory.cc
    A testing/rust_gtest_interop/test/test_factory.h
    10 files changed, 316 insertions(+), 84 deletions(-)


    To view, visit change 3560902. To unsubscribe, or for help writing mail filters, visit settings.

    Gerrit-Project: chromium/src
    Gerrit-Branch: main
    Gerrit-Change-Id: I1fe5efa8090435133054b3b7e71f28184b9d4733
    Gerrit-Change-Number: 3560902
    Gerrit-PatchSet: 25
    Gerrit-Owner: danakj <dan...@chromium.org>
    Gerrit-Reviewer: Chromium LUCI CQ <chromiu...@luci-project-accounts.iam.gserviceaccount.com>
    Gerrit-Reviewer: danakj <dan...@chromium.org>
    Gerrit-Reviewer: Łukasz Anforowicz <luk...@chromium.org>
    Gerrit-CC: Adrian Taylor <adet...@chromium.org>
    Gerrit-CC: Matthew Riley <mat...@chromium.org>
    Gerrit-MessageType: merged
    Reply all
    Reply to author
    Forward
    0 new messages