Skip to content

Conversation

@maflcko
Copy link
Member

@maflcko maflcko commented Dec 19, 2024

All other benchmarks and tests have their data embedded, except for the univalue json tests.

This is not only confusing, but also problematic, when the test binary is moved to a different system for testing, because one has to put the test files in the source dir that was used at compile-time.

Fix all issues by embedding them. Also, re-enable a disabled test. Also, fix an issue in the GenerateHeaderFromJson.cmake.

Requested in https://github.com/bitcoin/bitcoin/pull/31434/files#r1876000910

@DrahtBot
Copy link
Contributor

DrahtBot commented Dec 19, 2024

The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

Code Coverage & Benchmarks

For details see: https://corecheck.dev/bitcoin/bitcoin/pulls/31542.

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK l0rinc, fjahr, TheCharlatan, hebasto, achow101

If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #31176 (ci: Test cross-built Windows executables on Windows natively by hebasto)

If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

@DrahtBot DrahtBot changed the title test: Embed univalue json tests in binary test: Embed univalue json tests in binary Dec 19, 2024
@DrahtBot DrahtBot added the Tests label Dec 19, 2024
@sedited
Copy link
Contributor

sedited commented Dec 19, 2024

Nice, Concept ACK

@hebasto
Copy link
Member

hebasto commented Dec 19, 2024

Concept ACK. Thank you for picking this up!

Copy link
Contributor

@sedited sedited left a comment

Choose a reason for hiding this comment

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

ACK fabda022536c7a000a575bbb05059d27d29b5cca

Copy link
Member

@hebasto hebasto left a comment

Choose a reason for hiding this comment

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

Approach ACK fabda022536c7a000a575bbb05059d27d29b5cca.

Related: #30901 improves handling of data files in build scripts.

@maflcko maflcko force-pushed the 2412-univalue-json-tests branch from fabda02 to faf23a8 Compare December 20, 2024 09:48
Copy link
Member

@hebasto hebasto left a comment

Choose a reason for hiding this comment

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

ACK faf23a8d0328f288d64dd697de4efedbc6970531.

@DrahtBot DrahtBot requested a review from sedited December 20, 2024 09:57
@maflcko maflcko force-pushed the 2412-univalue-json-tests branch from faf23a8 to faedcc5 Compare December 20, 2024 10:10
@maflcko
Copy link
Member Author

maflcko commented Dec 20, 2024

Thx, fixed typo (good catch)! Also, pushed again for inline constexpr 😅

Copy link
Contributor

@sedited sedited left a comment

Choose a reason for hiding this comment

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

Nice improvements, Re-ACK faedcc5fdabc508aaade9b461e44ea3a6670f36b

@DrahtBot DrahtBot requested a review from hebasto December 20, 2024 11:14
Copy link
Contributor

@l0rinc l0rinc left a comment

Choose a reason for hiding this comment

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

Thanks for the cleanup, please consider a few simplification and unification recommendations

Comment on lines +19 to +20
Copy link
Contributor

Choose a reason for hiding this comment

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

does this sorting (here and in unitester.cpp) serve some purpose of could we use natural ordering?
We can't see this way that e.g. fail43 is missing and adding new lines would get confusing this way (maybe even adding a 0 prefix for <10):

Details
if(BUILD_TESTS)
  include(GenerateHeaders)
  generate_header_from_json(test/fail1.json)
  generate_header_from_json(test/fail2.json)
  generate_header_from_json(test/fail3.json)
  generate_header_from_json(test/fail4.json)
  generate_header_from_json(test/fail5.json)
  generate_header_from_json(test/fail6.json)
  generate_header_from_json(test/fail7.json)
  generate_header_from_json(test/fail8.json)
  generate_header_from_json(test/fail9.json)
  generate_header_from_json(test/fail10.json)
  generate_header_from_json(test/fail11.json)
  generate_header_from_json(test/fail12.json)
  generate_header_from_json(test/fail13.json)
  generate_header_from_json(test/fail14.json)
  generate_header_from_json(test/fail15.json)
  generate_header_from_json(test/fail16.json)
  generate_header_from_json(test/fail17.json)
  generate_header_from_json(test/fail18.json)
  generate_header_from_json(test/fail19.json)
  generate_header_from_json(test/fail20.json)
  generate_header_from_json(test/fail21.json)
  generate_header_from_json(test/fail22.json)
  generate_header_from_json(test/fail23.json)
  generate_header_from_json(test/fail24.json)
  generate_header_from_json(test/fail25.json)
  generate_header_from_json(test/fail26.json)
  generate_header_from_json(test/fail27.json)
  generate_header_from_json(test/fail28.json)
  generate_header_from_json(test/fail29.json)
  generate_header_from_json(test/fail30.json)
  generate_header_from_json(test/fail31.json)
  generate_header_from_json(test/fail32.json)
  generate_header_from_json(test/fail33.json)
  generate_header_from_json(test/fail34.json)
  generate_header_from_json(test/fail35.json)
  generate_header_from_json(test/fail36.json)
  generate_header_from_json(test/fail37.json)
  generate_header_from_json(test/fail38.json)
  generate_header_from_json(test/fail39.json)
  generate_header_from_json(test/fail40.json)
  generate_header_from_json(test/fail41.json)
  generate_header_from_json(test/fail42.json)
  generate_header_from_json(test/fail44.json)
  generate_header_from_json(test/fail45.json)
  generate_header_from_json(test/pass1.json)
  generate_header_from_json(test/pass2.json)
  generate_header_from_json(test/pass3.json)
  generate_header_from_json(test/pass4.json)
  generate_header_from_json(test/round1.json)
  generate_header_from_json(test/round2.json)
  generate_header_from_json(test/round3.json)
  generate_header_from_json(test/round4.json)
  generate_header_from_json(test/round5.json)
  generate_header_from_json(test/round6.json)
  generate_header_from_json(test/round7.json)
  add_executable(unitester
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail1.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail2.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail3.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail4.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail5.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail6.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail7.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail8.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail9.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail10.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail11.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail12.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail13.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail14.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail15.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail16.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail17.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail18.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail19.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail20.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail21.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail22.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail23.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail24.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail25.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail26.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail27.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail28.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail29.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail30.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail31.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail32.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail33.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail34.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail35.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail36.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail37.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail38.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail39.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail40.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail41.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail42.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail44.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/fail45.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/pass1.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/pass2.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/pass3.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/pass4.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/round1.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/round2.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/round3.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/round4.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/round5.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/round6.json.h
    ${CMAKE_CURRENT_BINARY_DIR}/test/round7.json.h
    test/unitester.cpp
  )

Copy link
Member Author

Choose a reason for hiding this comment

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

does this sorting (here and in unitester.cpp) serve some purpose of could we use natural ordering?

Yes, the purpose is to follow the clang-format sorting. If it was changed, clang-format will undo the change the next time.

maybe even adding a 0 prefix for <10

Happy to review a follow-up doing this, but I'll leave this as-is for now.

Copy link
Contributor

Choose a reason for hiding this comment

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

I understand why a macro is the smallest change to make runtest happy, but I think we can avoid that weird string parsing and introduce enums instead:

enum class TestType { Fail, Pass, RoundTrip };

and define the test as:

inline constexpr std::map<std::string_view, TestType> tests{
    {json_tests::fail1, TestType::Fail},
    {json_tests::fail2, TestType::Fail},
    {json_tests::fail3, TestType::Fail},
...

which could simplify runtest to:

static void runtest(std::string_view data, TestType type) {
    UniValue val;
    bool testResult = val.read(std::string{data});

    if (type == TestType::Fail) {
        assert(!testResult);
        return;
    }
    ...

Copy link
Member Author

@maflcko maflcko Dec 20, 2024

Choose a reason for hiding this comment

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

I want to keep the changes minimal. Also, I am not sure if an enum class is the right choice, so I'll leave this as-is for now.

Copy link
Member

@hebasto hebasto left a comment

Choose a reason for hiding this comment

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

re-ACK faedcc5fdabc508aaade9b461e44ea3a6670f36b.

@maflcko maflcko added this to the 29.0 milestone Dec 20, 2024
@maflcko
Copy link
Member Author

maflcko commented Dec 20, 2024

(assigned milestone, because this is a blocker to run the tests on native windows, which would be nice to finally get running)

Use character literals instead of integer hex values (i.e. `'\x5b','\x0a', ...` instead of `0x5b, 0x0a, ...`) for generated headers.
This avoids C++11 narrowing warnings in a more concise way than using explicit char casts.

Extra whitespace is also removed between elements for brevity.
@l0rinc
Copy link
Contributor

l0rinc commented Dec 20, 2024

ACK faedcc5fdabc508aaade9b461e44ea3a6670f36b

Avoiding file reads during test setup is a step forward in portability 👍
We can continue the refactors in follow-up PRs.

MarcoFalke added 3 commits December 20, 2024 15:01
Also, extend the pass2.json test to the maximum depth possible. The two
tests are now similar to fail45.json and pass4.json, except for the
string element in the inner-most array.

Also, sort.
@maflcko maflcko force-pushed the 2412-univalue-json-tests branch from faedcc5 to faf7eac Compare December 20, 2024 14:02
@l0rinc
Copy link
Contributor

l0rinc commented Dec 20, 2024

ACK faf7eac

The changes since last ACK: simplify char casting and reformat the affected sources.

@DrahtBot DrahtBot requested review from hebasto and sedited December 20, 2024 14:17
@fjahr
Copy link
Contributor

fjahr commented Dec 31, 2024

tACK faf7eac

Reviewed code and verified that tests are still running as intended.

Copy link
Contributor

@sedited sedited left a comment

Choose a reason for hiding this comment

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

Re-ACK faf7eac

Copy link
Member

@hebasto hebasto left a comment

Choose a reason for hiding this comment

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

Re-ACK faf7eac. The commit, which modifies CMake scripts, has been replaced with the one from #31547, and a formatting commit has been added since my recent review.

@achow101
Copy link
Member

achow101 commented Jan 3, 2025

ACK faf7eac

@achow101 achow101 merged commit 4036ee3 into bitcoin:master Jan 3, 2025
18 checks passed
@maflcko maflcko deleted the 2412-univalue-json-tests branch January 6, 2025 08:42
sedited added a commit to sedited/rust-bitcoinkernel that referenced this pull request Jan 17, 2025