-
Notifications
You must be signed in to change notification settings - Fork 358
vcpkg ci: Parse ci.baseline.txt to determine regressions #345
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
Merged
BillyONeal
merged 30 commits into
microsoft:main
from
autoantwort:parse-ci.baseline.txt
Mar 24, 2022
Merged
Changes from 6 commits
Commits
Show all changes
30 commits
Select commit
Hold shift + click to select a range
c17e406
vcpkg ci: Parse ci.baseline.txt to determine regressions
autoantwort a555645
Fix bug and implement PASSING, REMOVE FROM FAIL LIST and --passing-is…
autoantwort fc2cbb5
Apply Nicole's CR
autoantwort 4671c2f
Merge branch 'main' into parse-ci.baseline.txt
autoantwort 7549a57
Fix build
autoantwort a3797dc
Fix Formatting
autoantwort 8fe0d2c
WIP
BillyONeal d9da60b
Merge remote-tracking branch 'origin/main' into parse-ci.baseline.txt
BillyONeal d5f0498
Extend SortedVector to allow merging different SortedVectors together.
BillyONeal 6aa5eaa
Merge remote-tracking branch 'origin/main' into parse-ci.baseline.txt
BillyONeal 81c0ccb
Move some parsing stuff into the cpp, add ParseMessages::exit_if_erro…
BillyONeal f573df3
Finish implementing parser in terms of ParserBase.
BillyONeal 13010c2
Tests and bugfixes!
BillyONeal 2bc6f62
Fix MacOS and Linux build failures.
BillyONeal f3dea2a
Remove std::cerr.
BillyONeal 1f41c11
Generate messages map
BillyONeal c207828
Try to fix macos and linux again.
BillyONeal b089a02
Ensure all named triplets are in the exclusions map.
BillyONeal 8eca723
Merge remote-tracking branch 'origin/main' into parse-ci.baseline.txt
BillyONeal 7f7b54e
Merge remote-tracking branch 'origin/main' into parse-ci.baseline.txt
BillyONeal bfbbe6e
Fix bad merge.
BillyONeal b99de1d
Require the caller to pass the predicate in sorted vector rather than…
BillyONeal e97eac1
Revert the match_until change.
BillyONeal 686d7cd
Merge remote-tracking branch 'origin/main' into parse-ci.baseline.txt
BillyONeal ffa2c8b
Revert "Require the caller to pass the predicate in sorted vector rat…
BillyONeal a3e92af
Localize --allow-unexpected-passing can only be used if a baseline is…
BillyONeal 463db01
Revert ref qualification of extract_Xxx functions.
BillyONeal 19ae76d
Simplify try_match_keyword.
BillyONeal c2a64a0
Merge remote-tracking branch 'origin/main' into parse-ci.baseline.txt
BillyONeal 319ab06
Add more tests requested by Robert.
BillyONeal File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ | |
| #include <vcpkg/base/system.h> | ||
| #include <vcpkg/base/system.print.h> | ||
| #include <vcpkg/base/util.h> | ||
| #include <vcpkg/base/view.h> | ||
|
|
||
| #include <vcpkg/binarycaching.h> | ||
| #include <vcpkg/build.h> | ||
|
|
@@ -25,6 +26,8 @@ | |
| #include <vcpkg/vcpkglib.h> | ||
| #include <vcpkg/vcpkgpaths.h> | ||
|
|
||
| #include <iostream> | ||
|
|
||
| using namespace vcpkg; | ||
|
|
||
| namespace | ||
|
|
@@ -74,6 +77,53 @@ namespace | |
| private: | ||
| Path base_path; | ||
| }; | ||
|
|
||
| enum class CiBaselineState | ||
| { | ||
| Skip, | ||
| Fail, | ||
| }; | ||
|
|
||
| struct CiBaselineLine | ||
| { | ||
| std::string port_name; | ||
| std::string triplet_name; | ||
| CiBaselineState state; | ||
| }; | ||
|
|
||
| std::vector<CiBaselineLine> parse_ci_baseline(View<std::string> lines) | ||
| { | ||
| std::vector<CiBaselineLine> result; | ||
| for (auto& line : lines) | ||
| { | ||
| if (line.empty() || line[0] == '#') continue; | ||
| CiBaselineLine parsed_line; | ||
|
|
||
| auto colon_loc = line.find(':'); | ||
| Checks::check_exit(VCPKG_LINE_INFO, colon_loc != std::string::npos, "Line '%s' must contain a ':'", line); | ||
| parsed_line.port_name = Strings::trim(StringView{line.data(), line.data() + colon_loc}).to_string(); | ||
|
|
||
| auto equal_loc = line.find('=', colon_loc + 1); | ||
| Checks::check_exit(VCPKG_LINE_INFO, equal_loc != std::string::npos, "Line '%s' must contain a '='", line); | ||
| parsed_line.triplet_name = | ||
| Strings::trim(StringView{line.data() + colon_loc + 1, line.data() + equal_loc}).to_string(); | ||
|
|
||
| auto baseline_value = Strings::trim(StringView{line.data() + equal_loc + 1, line.data() + line.size()}); | ||
| if (baseline_value == "fail") | ||
| { | ||
| parsed_line.state = CiBaselineState::Fail; | ||
| } | ||
| else if (baseline_value == "skip") | ||
| { | ||
| parsed_line.state = CiBaselineState::Skip; | ||
| } | ||
| else | ||
| { | ||
| Checks::exit_with_message(VCPKG_LINE_INFO, "Unknown value '%s'", baseline_value); | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
| } | ||
|
|
||
| namespace vcpkg::Commands::CI | ||
|
|
@@ -93,25 +143,30 @@ namespace vcpkg::Commands::CI | |
| static constexpr StringLiteral OPTION_HOST_EXCLUDE = "host-exclude"; | ||
| static constexpr StringLiteral OPTION_FAILURE_LOGS = "failure-logs"; | ||
| static constexpr StringLiteral OPTION_XUNIT = "x-xunit"; | ||
| static constexpr StringLiteral OPTION_CI_BASELINE = "ci-baseline"; | ||
| static constexpr StringLiteral OPTION_ALLOW_UNEXPECTED_PASSING = "allow-unexpected-passing"; | ||
| static constexpr StringLiteral OPTION_RANDOMIZE = "x-randomize"; | ||
| static constexpr StringLiteral OPTION_OUTPUT_HASHES = "output-hashes"; | ||
| static constexpr StringLiteral OPTION_PARENT_HASHES = "parent-hashes"; | ||
| static constexpr StringLiteral OPTION_SKIPPED_CASCADE_COUNT = "x-skipped-cascade-count"; | ||
|
|
||
| static constexpr std::array<CommandSetting, 7> CI_SETTINGS = { | ||
| static constexpr std::array<CommandSetting, 8> CI_SETTINGS = { | ||
| {{OPTION_EXCLUDE, "Comma separated list of ports to skip"}, | ||
| {OPTION_HOST_EXCLUDE, "Comma separated list of ports to skip for the host triplet"}, | ||
| {OPTION_XUNIT, "File to output results in XUnit format (internal)"}, | ||
| {OPTION_CI_BASELINE, "Path to the ci.baseline.txt file. Used to skip ports and detect regressions."}, | ||
| {OPTION_FAILURE_LOGS, "Directory to which failure logs will be copied"}, | ||
| {OPTION_OUTPUT_HASHES, "File to output all determined package hashes"}, | ||
| {OPTION_PARENT_HASHES, | ||
| "File to read package hashes for a parent CI state, to reduce the set of changed packages"}, | ||
| {OPTION_SKIPPED_CASCADE_COUNT, | ||
| "Asserts that the number of --exclude and supports skips exactly equal this number"}}}; | ||
|
|
||
| static constexpr std::array<CommandSwitch, 2> CI_SWITCHES = {{ | ||
| static constexpr std::array<CommandSwitch, 3> CI_SWITCHES = {{ | ||
| {OPTION_DRY_RUN, "Print out plan without execution"}, | ||
| {OPTION_RANDOMIZE, "Randomize the install order"}, | ||
| {OPTION_ALLOW_UNEXPECTED_PASSING, | ||
| "Indicates that 'Passing, remove from fail list' results should not be emitted."}, | ||
| }}; | ||
|
|
||
| const CommandStructure COMMAND_STRUCTURE = { | ||
|
|
@@ -484,10 +539,57 @@ namespace vcpkg::Commands::CI | |
| const auto& settings = options.settings; | ||
|
|
||
| BinaryCache binary_cache{args, paths}; | ||
| Triplet target_triplet = Triplet::from_canonical_name(std::string(args.command_arguments[0])); | ||
| Triplet target_triplet = Triplet::from_canonical_name(args.command_arguments[0]); | ||
|
|
||
| auto exclusions = parse_exclusions(settings, OPTION_EXCLUDE); | ||
| auto host_exclusions = parse_exclusions(settings, OPTION_HOST_EXCLUDE); | ||
| auto baseline_iter = settings.find(OPTION_CI_BASELINE); | ||
| const bool allow_unexpected_passing = Util::Sets::contains(options.switches, OPTION_ALLOW_UNEXPECTED_PASSING); | ||
| std::set<PackageSpec> expected_failures; | ||
| if (baseline_iter != settings.end()) | ||
| { | ||
| auto baseline = | ||
| parse_ci_baseline(paths.get_filesystem().read_lines(baseline_iter->second, VCPKG_LINE_INFO)); | ||
| auto target_triplet_string = args.command_arguments[0]; | ||
| auto host_triplet_string = host_triplet.canonical_name(); | ||
| for (auto& line : baseline) | ||
| { | ||
| if (line.triplet_name == target_triplet_string) | ||
| { | ||
| if (line.state == CiBaselineState::Skip) | ||
| { | ||
| exclusions.insert(line.port_name); | ||
| } | ||
| else if (line.state == CiBaselineState::Fail) | ||
| { | ||
| expected_failures.emplace(line.port_name, target_triplet); | ||
| } | ||
| } | ||
| else if (line.triplet_name == host_triplet_string) | ||
| { | ||
| if (line.state == CiBaselineState::Skip) | ||
| { | ||
| host_exclusions.insert(line.port_name); | ||
| } | ||
| else if (line.state == CiBaselineState::Fail) | ||
| { | ||
| expected_failures.emplace(line.port_name, host_triplet); | ||
| } | ||
| } | ||
| } | ||
| } | ||
| else | ||
| { | ||
| Checks::check_exit(VCPKG_LINE_INFO, | ||
|
BillyONeal marked this conversation as resolved.
Outdated
|
||
| !allow_unexpected_passing, | ||
| Strings::concat("--", | ||
| OPTION_ALLOW_UNEXPECTED_PASSING, | ||
| " can only be used if a ci baseline is provided via --", | ||
| OPTION_CI_BASELINE)); | ||
| } | ||
| ExclusionPredicate is_excluded{ | ||
| parse_exclusions(settings, OPTION_EXCLUDE), | ||
| parse_exclusions(settings, OPTION_HOST_EXCLUDE), | ||
| exclusions, | ||
| host_exclusions, | ||
| target_triplet, | ||
| host_triplet, | ||
| }; | ||
|
|
@@ -678,6 +780,38 @@ namespace vcpkg::Commands::CI | |
| print2("\nTriplet: ", result.triplet, "\n"); | ||
| print2("Total elapsed time: ", GlobalState::timer.to_string(), "\n"); | ||
| result.summary.print(); | ||
|
|
||
| if (baseline_iter != settings.end()) | ||
| { | ||
| print2("\nREGRESSIONS:\n"); | ||
| for (auto&& port_result : result.summary.results) | ||
| { | ||
| switch (port_result.build_result.code) | ||
| { | ||
| case Build::BuildResult::BUILD_FAILED: | ||
| case Build::BuildResult::POST_BUILD_CHECKS_FAILED: | ||
| case Build::BuildResult::FILE_CONFLICTS: | ||
| if (expected_failures.find(port_result.spec) == expected_failures.end()) | ||
| { | ||
| std::cerr | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this should also use print2, and we certainly should avoiding new use of iostreams if at all possible. |
||
| << " REGRESSION: " << port_result.spec.to_string() << " failed with " | ||
| << Build::to_string_locale_invariant(port_result.build_result.code).to_string() | ||
| << ". If expected, add " << port_result.spec.to_string() << "=fail to " | ||
| << baseline_iter->second << std::endl; | ||
| } | ||
| break; | ||
| case Build::BuildResult::SUCCEEDED: | ||
| if (!allow_unexpected_passing && | ||
| expected_failures.find(port_result.spec) != expected_failures.end()) | ||
| { | ||
| std::cerr << " PASSING, REMOVE FROM FAIL LIST: " << port_result.spec.to_string() | ||
| << " (" << baseline_iter->second << ")" << std::endl; | ||
| } | ||
| break; | ||
| default: break; | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| auto it_xunit = settings.find(OPTION_XUNIT); | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FYI I'm changing this behavior because it fails, for example, with