Skip to content

[Flaky Test] druid-core org.apache.druid.math.expr.ParserTest#testApplyFunctions #13470

@Kerr0220

Description

@Kerr0220

Problem Description

org.apache.druid.math.expr.ParserTest#testApplyFunctions in core is a flaky test. It can pass the maven-test while showing non-deterministic behavior under NonDex and thus failed.

Error Message

[ERROR] org.apache.druid.math.expr.ParserTest.testApplyFunctions  Time elapsed: 0 s  <<< FAILURE!
java.lang.AssertionError: x + map((x) -> x + 1, y) expected:<[x, y]> but was:<[y, x]>
        at org.junit.Assert.fail(Assert.java:89)
        at org.junit.Assert.failNotEquals(Assert.java:835)
        at org.junit.Assert.assertEquals(Assert.java:120)
        at org.apache.druid.math.expr.ParserTest.validateParser(ParserTest.java:836)
        at org.apache.druid.math.expr.ParserTest.testApplyFunctions(ParserTest.java:541)
        ......

Steps to reproduce the failure:

  1. (optional) check NonDex
  2. run the following command in druid:
MODULE=core
TEST=org.apache.druid.math.expr.ParserTest#testApplyFunctions  
mvn install -pl $MODULE -am -DskipTests 
mvn -pl $MODULE edu.illinois:nondex-maven-plugin:1.1.2:nondex -Dtest=$TEST
  1. the result will be saved under the package folder in .nondex

Configurations

Apache Maven 3.6.0;
openjdk version "1.8.0_342";
OpenJDK Runtime Environment (build 1.8.0_342-8u342-b07-0ubuntu1~20.04-b07);
OpenJDK 64-Bit Server VM (build 25.342-b07, mixed mode);

Potential Cause

The problem might be caused by the non-deterministic feature of HashSet. Here's the description of HashSet in JavaSE-8 specification:

It makes no guarantees as to the iteration order of the set; in particular, it does not guarantee that the order will remain constant over time.

This feature leads to the non-deterministic order of the return given by Expr.getRequiredBindingsList() since it simply converts a HashSet object got from Expr.map() to an ArrayList.

  public List<String> getRequiredBindingsList() {
    return new ArrayList<>(getRequiredBindings());
  }


  public Set<String> getRequiredBindings() {
    return map(freeVariables, IdentifierExpr::getBindingIfIdentifier);
  }


  private static Set<String> map(
      Set<IdentifierExpr> variables,
      java.util.function.Function<IdentifierExpr, String> mapper
  ) {
    Set<String> results = Sets.newHashSetWithExpectedSize(variables.size());
    for (IdentifierExpr variable : variables) {
      results.add(mapper.apply(variable));
    }
    return results;
  }

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions