dimanche 28 avril 2019

Flaky test using an embedded Mysql DB

I've written an integration test that uses a Mysql embedded database. When I execute the test class on my IDE, the tests executes successfully along with the other integration tests that appear in the same class. The issue comes in when I run all the tests together using a Gradle via command line.

The error I'm getting when running via command line looks something like this:

EmployeeRepositoryFindByEmployeeIdTest > shouldReturnDeparmentForEmployeeId() FAILED
    java.lang.AssertionError:
    Expecting:
      <[Employee(ud=118 age=23,department=null),
        Employee(id=219, age=24, department=Deparment(id=5, name=IT))]>
    to contain exactly (and in same order):
      <[Employee(ud=118 age=23,department=Deparment(id=4, name=IT)),
        Employee(id=219, age=24, department=Deparment(id=5, name=IT))]>
    but some elements were not found:
      <[Employee(ud=118 age=23,department=Deparment(id=4, name=IT))]>
    and others were not expected:
      <[Employee(ud=118 age=23,department=null)]>
        EmployeeRepositoryFindByEmployeeIdTest.shouldReturnDeparmentForEmployeeId(EmployeeRepositoryFindByEmployeeIdTest.java:188)

The test calls the following method:

@Repository
public class EmployeeRepository {    
  private final DSLContext dsl;

  public EmployeeRepository(DSLContext dsl, Clock clock) {
    this.dsl = dsl;
  }

  // ...

  public List<Employee> getEmployeeByDepartmentId(int departmentId) {
    return dsl.select(
        EMPLOYEE.ID,
        EMPLOYEE.AGE,
        EMPLOYEE.DEPARMENT_ID,
        DEPARTMENT.ID,
        DEPARTMENT.NAME
    ).from(EMPLOYEE)
        .leftJoin(DEPARMENT).on(DEPARMENT.ID.eq(EMPLOYEE.DEPARMENT_ID))
        .where(DEPARMENT.ID.eq(departmentId))
        .orderBy(EMPLOYEE.ID)
        .fetch()
        .map(this::getEmployee);
  }
}

What is expected after calling the test method is to receive two employees and the department associated for each but what I'm getting is always null for department_id=4. It feels to me that the join is not executed correctly for some of the rows in the table.

What I've tried to fix this is to increase wait_timeout and max_connections in the MySQL config to something very high but I still see the same issue. Also, I upgraded to latest db version -Version.v5_7_latest- but still the same. I'm not sure where else to look at in order to fix this. Any ideas of how to move forward?

If this helps, here is the MySQL config in the test setup:

  @Bean
  public EmbeddedMysql embeddedMySql() {
    if (embeddedMysql != null) {
      embeddedMysql.reloadSchema("deparment", Collections.emptyList());
      return embeddedMysql;
    } else {
      MysqldConfig config = aMysqldConfig(Version.v5_6_36)
          .withCharset(Charset.UTF8)
          .withPort(3322)
          .withUser("department", "*******")
          .withServerVariable("wait_timeout", "60")
          .withServerVariable("max_connections", "500")
          .build();
      embeddedMysql = anEmbeddedMysql(config)
          .addSchema("department")
          .start();
      return embeddedMysql;
    }
  }

Thanks in advance for the help!

Aucun commentaire:

Enregistrer un commentaire