Skip to content

Add Aggregation fuzzer framework - #12667

Merged
alamb merged 41 commits into
apache:mainfrom
Rachelint:aggr-fuzzer
Oct 9, 2024
Merged

Add Aggregation fuzzer framework#12667
alamb merged 41 commits into
apache:mainfrom
Rachelint:aggr-fuzzer

Conversation

@Rachelint

@RachelintRachelint commented Sep 28, 2024

Copy link
Copy Markdown
Contributor

Which issue does this PR close?

Part of #12114

Rationale for this change

The aggregation fuzz tests maybe not enough, becasue there are so many optimizations in aggregation in datafusion.
For improving the testing, the first thing to do may be building a framework to make creating testcase easier.

This pr aimed to introduce such a framework.

What changes are included in this PR?

Design an AggregationFuzzer to make creating testcases for aggregation easier.
Two key components in AggregationFuzzer are DatasetGenerator and SessionContextGenerator.

In AggregationFuzzer(with a deinfed query represented by sql currently):

  • Multiple datasets will be generated by DatasetGenerator firstly.

  • And then for a specific dataset, multiple SessionContext with the random params about aggreagtion, and a baseline SessionContext will be generated.

  • Still for the specific dataset, each randomly generated SessionContext + basline result(generated from dataset + basline SessionContext) will be used to build AggregationFuzzTestTask.

  • In AggregationFuzzTestTask, we will run the query with dataset + related SessionContext, then we compare the result with basline result. If inconsistency found, report it and panic.

  • Finally, all AggregationFuzzTestTasks will be run in parallel in AggregationFuzzer

Are these changes tested?

Test by uts.

Are there any user-facing changes?

No,

@github-actionsgithub-actionsBot added the core Core DataFusion crate label Sep 28, 2024
@alamb

Copy link
Copy Markdown
Contributor

😍 😍 😍 😍

@Rachelint
Rachelintforce-pushed the aggr-fuzzer branch 2 times, most recently from d1f5aea to 6ad27f5CompareOctober 3, 2024 14:59
@Rachelint

Rachelint commented Oct 3, 2024

Copy link
Copy Markdown
ContributorAuthor

Rest works:

  • Rewrite more cases through fuzzer
  • Refine the error handling
    • Error of fuzzer self, just simple expect/unwrap
    • Inconsistent results, println the task information, then panic

@Rachelint
Rachelintforce-pushed the aggr-fuzzer branch 3 times, most recently from b059373 to cf82eb7CompareOctober 4, 2024 10:37
@RachelintRachelint changed the title [WIP] Aggregation fuzzerAggregation fuzzerOct 4, 2024
@Rachelint

Rachelint commented Oct 4, 2024

Copy link
Copy Markdown
ContributorAuthor

@alamb I found the new fuzz cases(based on aggregation fuzzer) failed after I rebase main.
I try to revert #12623 , and tests passed again, but I am still not sure what is wrong...

The failed new case: test_group_by_mixed_string_int64

I am more sure now, it may be due to the process of null, when I switch the field to non-nullabe, the test passed.


Updated
have found the reason, see detail in #12758
This pr may be ready now.

@Rachelint
Rachelint marked this pull request as ready for review October 4, 2024 13:26
@Rachelint

Copy link
Copy Markdown
ContributorAuthor

I found the reason and have submitted a pr to fix it #12758

@alamb

alamb commented Oct 4, 2024

Copy link
Copy Markdown
Contributor

I found the reason and have submitted a pr to fix it #12758

Testing for the win!

@Rachelint

Rachelint commented Oct 8, 2024

Copy link
Copy Markdown
ContributorAuthor

The tests' run time after modifying data_gen_rounds and ctx_gen_rounds to both 16.

 Nextest run ID ef162b0e-5d2e-42dd-bf83-b6ccd08ff386 with nextest profile: default
Starting 40 tests across 1 binary
PASS [ 1.080s] datafusion::fuzz fuzz_cases::aggregate_fuzz::test_basic_string_aggr_no_group
PASS [ 1.570s] datafusion::fuzz fuzz_cases::aggregate_fuzz::test_basic_prim_aggr_no_group
PASS [ 1.512s] datafusion::fuzz fuzz_cases::aggregation_fuzzer::context_generator::test::test_generated_context
PASS [ 1.968s] datafusion::fuzz fuzz_cases::aggregation_fuzzer::data_generator::test::test_generated_datasets
PASS [ 3.496s] datafusion::fuzz fuzz_cases::distinct_count_string_fuzz::distinct_count_string_test
PASS [ 6.636s] datafusion::fuzz fuzz_cases::aggregate_fuzz::test_basic_string_aggr_group_by_single_int64
PASS [ 11.075s] datafusion::fuzz fuzz_cases::aggregate_fuzz::test_basic_prim_aggr_group_by_single_string
PASS [ 11.309s] datafusion::fuzz fuzz_cases::aggregate_fuzz::group_by_strings
PASS [ 11.404s] datafusion::fuzz fuzz_cases::aggregate_fuzz::test_basic_string_aggr_group_by_single_string
PASS [ 11.426s] datafusion::fuzz fuzz_cases::aggregate_fuzz::test_basic_prim_aggr_group_by_single_int64
PASS [ 9.577s] datafusion::fuzz fuzz_cases::join_fuzz::test_anti_join_1k
PASS [ 8.794s] datafusion::fuzz fuzz_cases::join_fuzz::test_anti_join_1k_filtered
PASS [ 16.672s] datafusion::fuzz fuzz_cases::aggregate_fuzz::streaming_aggregate_test
PASS [ 5.653s] datafusion::fuzz fuzz_cases::join_fuzz::test_inner_join_1k
PASS [ 11.194s] datafusion::fuzz fuzz_cases::join_fuzz::test_full_join_1k
PASS [ 18.353s] datafusion::fuzz fuzz_cases::aggregate_fuzz::test_basic_prim_aggr_group_by_mixed_string_int64
PASS [ 7.364s] datafusion::fuzz fuzz_cases::join_fuzz::test_inner_join_1k_filtered
PASS [ 7.730s] datafusion::fuzz fuzz_cases::join_fuzz::test_left_join_1k
PASS [ 19.300s] datafusion::fuzz fuzz_cases::aggregate_fuzz::test_basic_string_aggr_group_by_mixed_string_int64
PASS [ 8.605s] datafusion::fuzz fuzz_cases::join_fuzz::test_full_join_1k_filtered
PASS [ 0.043s] datafusion::fuzz fuzz_cases::merge_fuzz::test_merge_2
PASS [ 0.069s] datafusion::fuzz fuzz_cases::merge_fuzz::test_merge_2_no_overlap
PASS [ 0.049s] datafusion::fuzz fuzz_cases::merge_fuzz::test_merge_3
PASS [ 0.037s] datafusion::fuzz fuzz_cases::merge_fuzz::test_merge_3_gaps
PASS [ 7.009s] datafusion::fuzz fuzz_cases::join_fuzz::test_left_join_1k_filtered
PASS [ 5.310s] datafusion::fuzz fuzz_cases::join_fuzz::test_right_join_1k
PASS [ 2.085s] datafusion::fuzz fuzz_cases::limit_fuzz::test_sort_topk_f64
PASS [ 1.723s] datafusion::fuzz fuzz_cases::limit_fuzz::test_sort_topk_i32
PASS [ 3.581s] datafusion::fuzz fuzz_cases::join_fuzz::test_semi_join_1k
PASS [ 0.164s] datafusion::fuzz fuzz_cases::sort_preserving_repartition_fuzz::sp_repartition_fuzz_tests::stream_merge_multi_order_preserve
PASS [ 3.120s] datafusion::fuzz fuzz_cases::join_fuzz::test_semi_join_1k_filtered
PASS [ 0.761s] datafusion::fuzz fuzz_cases::window_fuzz::bounded_window_causal_non_causal
PASS [ 5.374s] datafusion::fuzz fuzz_cases::join_fuzz::test_right_join_1k_filtered
PASS [ 3.533s] datafusion::fuzz fuzz_cases::limit_fuzz::test_sort_topk_str
PASS [ 3.914s] datafusion::fuzz fuzz_cases::limit_fuzz::test_sort_topk_i64str
PASS [ 6.426s] datafusion::fuzz fuzz_cases::sort_fuzz::test_sort_100k_mem
PASS [ 6.416s] datafusion::fuzz fuzz_cases::sort_preserving_repartition_fuzz::sp_repartition_fuzz_tests::sort_preserving_repartition_test
PASS [ 7.181s] datafusion::fuzz fuzz_cases::sort_fuzz::test_sort_unlimited_mem
PASS [ 7.971s] datafusion::fuzz fuzz_cases::sort_fuzz::test_sort_1k_mem
PASS [ 12.769s] datafusion::fuzz fuzz_cases::window_fuzz::window_bounded_window_random_comparison

@Rachelint

Rachelint commented Oct 8, 2024

Copy link
Copy Markdown
ContributorAuthor

@alamb I have added tests to cover more aggregations:

  • basic prim aggr(sum/sum distinct/max/min/count/avg)
  • basic string aggr(count/count distinct/min/max)

I make it through the simple implementation about randomly select sql memtioned in #12667 (comment)

  • it will randomly select a sql for each dataset
  • then run CTX_GEN_ROUNDS(now 16) randomly SessionConfig on specific dataset + selected query

Now the testcase may be like:

// Build fuzzerlet fuzzer = builder
.data_gen_config(data_gen_config).data_gen_rounds(16).add_sql("SELECT sum(a) FROM fuzz_table").add_sql("SELECT sum(distinct a) FROM fuzz_table").add_sql("SELECT max(a) FROM fuzz_table").add_sql("SELECT min(a) FROM fuzz_table").add_sql("SELECT count(a) FROM fuzz_table").add_sql("SELECT count(distinct a) FROM fuzz_table").add_sql("SELECT avg(a) FROM fuzz_table").table_name("fuzz_table").build();

And unforunately, seems a bug about min/max for string found... Maybe we should check and try to fix it in other pr.

@alamb

alamb commented Oct 8, 2024

Copy link
Copy Markdown
Contributor

And unforunately, seems a bug about min/max for string found... Maybe we should check and try to fix it in other pr.

Yes, let's handle that as a separate PR / issue.

@alambalamb left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thank you again @Rachelint -- I think this is great and I'll plan to merge it tomorrow unless anyone else would like time to review

Then we can work on follow on items in other PRs

Comment threaddatafusion/core/tests/fuzz_cases/aggregate_fuzz.rs
}

/// Fuzz test for group by `sting + int64`
#[tokio::test(flavor = "multi_thread")]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I meant like

#[tokio::test]
async fn test_basic_string_aggr_group_by_mixed_string_int64_1() {
...
}
#[tokio::test]
async fn test_basic_string_aggr_group_by_mixed_string_int64_2() {
...
}

Rather than a single test that was multi-threaded

@alamb
alamb merged commit 3353c06 into apache:mainOct 9, 2024
@alamb

alamb commented Oct 9, 2024

Copy link
Copy Markdown
Contributor

Thanks again @Rachelint -- this is so great

@alamb

alamb commented Oct 9, 2024

Copy link
Copy Markdown
Contributor

I am working on filing the error that this found for min/max

@alamb

alamb commented Oct 9, 2024

Copy link
Copy Markdown
Contributor

I also have some ideas on how to improve the error reporting here

@Rachelint
Rachelint deleted the aggr-fuzzer branch October 9, 2024 14:26
@Rachelint

Copy link
Copy Markdown
ContributorAuthor

I also have some ideas on how to improve the error reporting here

Nice, the error reporting is indeed not so readable currently

@Rachelint

Copy link
Copy Markdown
ContributorAuthor

I also have some ideas on how to improve the error reporting here

Maybe #5131 will help? The error seems similar.

@alamb

alamb commented Oct 9, 2024

Copy link
Copy Markdown
Contributor

#12832 has a proposal for improved error reporting

let fuzzer = builder
.data_gen_config(data_gen_config)
.data_gen_rounds(8)
// FIXME: Encounter error in min/max

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Proposed fix in #12834

@alamb

Copy link
Copy Markdown
Contributor

BTW this found another bug in #12792

See https://github.com/apache/datafusion/actions/runs/11272685143/job/31348663515?pr=12792

❤️

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

coreCore DataFusion crate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@Rachelint@alamb@jayzhan211