Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

unit tests: Add mz_ore::test to initialize logging implicitly #19603

Merged
merged 9 commits into from
Jun 2, 2023

Conversation

def-
Copy link
Contributor

@def- def- commented May 31, 2023

It seems easy to forget to initialize logging. Unfortunately there is no easy way of doing this in Rust currently. See for example a recent Slack discussion: https://materializeinc.slack.com/archives/C0246GEHL8N/p1683754885066559

I'll rebase this once the reviews are through since it has huge conflict potential.

Motivation

  • This PR refactors existing code.

Tips for reviewer

Review individual commits.

Checklist

  • This PR has adequate test coverage / QA involvement has been duly considered.
  • This PR has an associated up-to-date design doc, is a design doc (template), or is sufficiently small to not require a design.
  • If this PR evolves an existing $T ⇔ Proto$T mapping (possibly in a backwards-incompatible way), then it is tagged with a T-proto label.
  • If this PR will require changes to cloud orchestration, there is a companion cloud PR to account for those changes that is tagged with the release-blocker label (example).
  • This PR includes the following user-facing behavior changes:

@def- def- force-pushed the pr-mz-test branch 3 times, most recently from 1464c3d to d102f73 Compare May 31, 2023 14:28
Copy link
Member

@benesch benesch left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a fantastic idea! Let's have @guswynn or @petrosagg or some other Rust expert review the proc macro itself, but +100 on the idea from me.

Can we do a blanket find/replace on #[test] in the codebase, too? It seems that you've limited the swap for just those tests that mz_ore::test::init_logging() was called in, but really any test function that doesn't call that is a recipe for trouble. Then we should also update STYLE.md to say that use of this macro is mandatory.

@def- def- changed the title unit tests: Add mz_test::test to initialize logging implicitly unit tests: Add mz_ore::test to initialize logging implicitly Jun 1, 2023
@@ -84,6 +84,7 @@
/src/stash-debug @MaterializeInc/surfaces
/src/storage @MaterializeInc/storage
/src/storage-client @MaterializeInc/storage
/src/test-macro @MaterializeInc/qa
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@philip-stoev I hope this is ok, otherwise can also assign it to myself directly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is ok, thanks.

/// Copyright (C) 2019-2022 Daniel Mueller <[email protected]>
/// SPDX-License-Identifier: (Apache-2.0 OR MIT)

#[proc_macro_attribute]
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the actually interesting part of this PR, the rest is just to actually use it.

#body
}

#logging_init
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we later have other things we want to run in each unit test, during setup or at the end, we can add them here in the future.

@def- def- marked this pull request as ready for review June 1, 2023 18:09
@def- def- requested review from a team June 1, 2023 18:09
@def- def- requested review from a team, aalexandrov and umanwizard as code owners June 1, 2023 18:09
@def- def- requested a review from benesch June 1, 2023 18:09
Comment on lines +106 to +111
let inner_test = match args.as_slice() {
[] => parse_quote! { ::core::prelude::v1::test },
[NestedMeta::Meta(Meta::Path(path))] => quote! { #path },
[NestedMeta::Meta(Meta::List(list))] => quote! { #list },
_ => panic!("unsupported attributes supplied: {:?}", args),
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't support flavor = "multi_thread" (https://docs.rs/tokio/latest/tokio/attr.test.html#multi-threaded-runtime) in tokio::test does it? What if we expanded to tokio::test over the normal test attribute automatically if the function is async? Then we can also support flavor as an arg

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does, I used the flavor = "multi_threads" in some tests and haven't seen a problem. Example from the project I took this from: https://github.com/d-e-s-o/test-log/blob/f500323f947a4bfdcb015edbc814555ddb04a0fc/tests/mod.rs#L71

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh then this looks good!

Copy link
Contributor

@philip-stoev philip-stoev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. Can we get one of the linters to start rejecting incorrect direct use of the test macro? I believe @teskje was the last person that was trying to use a linter to prohibit certain constructs altogether.

@def-
Copy link
Contributor Author

def- commented Jun 2, 2023

I don't know how to create Rust-parser based warnings myself. I can easily do a regex though if that is sufficient.

Edit: I found clippy.toml which looks good for this.

@teskje
Copy link
Contributor

teskje commented Jun 2, 2023

Clippy's disallowed-macros config seems like it should work for this, but I tried for a bit and couldn't get it to flag #[test] or #[tokio::test].

Copy link
Contributor

@teskje teskje left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, though I'll also leave the proc macro review to more knowledgable folks.

I agree that it would be nice to have something in CI flagging use of non-mz test macros.

@def-
Copy link
Contributor Author

def- commented Jun 2, 2023

clippy is unfortunately insufficient here, since it will complain about the location where the mz_ore::test macro is used, so we'd have to silence the warning everywhere, which defeats the purpose. I tried with:

diff --git a/clippy.toml b/clippy.toml
index 83b1777a60..c92db4b1ee 100644
--- a/clippy.toml
+++ b/clippy.toml
@@ -49,6 +49,9 @@ disallowed-methods = [
 disallowed-macros = [
     { path = "proptest::prop_oneof", reason = "use `proptest::strategy::Union::new` instead" },
     { path = "log::log", reason = "use the macros provided by `tracing` instead (#9992)" },
+    { path = "core::prelude::v1::test", reason = "use the `mz_ore::test` macro instead" },
+    # How to warn about tokio::test but not mz_ore::test(tokio::test)?
+    #{ path = "tokio::test", reason = "use the `mz_ore::test(tokio::test)` macro instead" },
 ]

 disallowed-types = [
diff --git a/src/test-macro/src/lib.rs b/src/test-macro/src/lib.rs
index 4748331929..3cd0ec08b7 100644
--- a/src/test-macro/src/lib.rs
+++ b/src/test-macro/src/lib.rs
@@ -104,6 +104,7 @@ pub fn test(attr: TokenStream, item: TokenStream) -> TokenStream {
     let input = parse_macro_input!(item as ItemFn);

     let inner_test = match args.as_slice() {
+        #[allow(clippy::disallowed_macros)]
         [] => parse_quote! { ::core::prelude::v1::test },
         [NestedMeta::Meta(Meta::Path(path))] => quote! { #path },
         [NestedMeta::Meta(Meta::List(list))] => quote! { #list },

@philip-stoev
Copy link
Contributor

Ok then so the new boilerplate code will desseminate using copy+paste then.

@@ -0,0 +1,50 @@
#!/usr/bin/env bash
Copy link
Contributor Author

@def- def- Jun 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As requested, added a lint. Sample output:

lint: error: test-attribute: src/ore/tests/future.rs: use of disallowed `#[tokio::test] attribute. Use the `#[mz_ore::test(tokio::test)]` attribute instead or add a `// allow(test-attribute)` comment

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool! 🎉

@def-
Copy link
Contributor Author

def- commented Jun 2, 2023

I'll set this to auto-merge unless someone complains and/or wants to review the macro. After it's merged I'll check the open PRs to see if they would break linting and notify people.

@def- def- enabled auto-merge June 2, 2023 18:03
@def- def- merged commit 9dcb55c into MaterializeInc:main Jun 2, 2023
@def- def- deleted the pr-mz-test branch June 2, 2023 19:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants