Hello everyone, Recently I have been researching https://issues.apache.org/jira/browse/FINERACT-722 <https://issues.apache.org/jira/browse/FINERACT-722> about integration test(s) failing on the first of the month due to an incorrect value of the loan interest due.
The most interesting thing I found was that when I ran the entire integration test suite on the first day of the month, LoanReschedulingWithinCenterTest would always fail. But when I ran LoanReschedulingWithinCenterTest alone it would always succeed. This made me think that somehow state was being “dirtied” between integration tests. After lots of debugging I found the root cause was because some values used to calculate the interest due were read from the global configuration table (c_configuration). I found that GloalConfigurationTest (and a couple other tests) modified this table - significantly, the configuration about loan repayments on the first of the month was modified. My first implementation to fix this was simply hardcoding REST API requests in the integration test to reset these configurations. It worked, but I worried about how well this would work as a long term solution. - What if these default values change? - A future programmer would have to make sure these were all the current default values. - This only reset the c_configuration table - What if other tests modify the DB such that it affects the outcome of other tests? - We would also have to reset those values manually and keep them in sync with their defaults manually. I then found that the DB’s initial instance defaults are the same as at fineract-provider/src/main/resources/sql/migrations/sample_data/barebones_db.sql And I realized that the Grade Flyway migration task initializes these values to the same defaults. I tried to run Fineract's existing Gradle tasks (from within integration test @Before functions) using Runtime.getRuntime.exec(“./gradlew migrateTaskName”) so that table instance data would be reset. I found this approach better than hardcoding the values because they would be read from the migrations directory and so they’d always be up to date. However, I found problems with the reliability of this implementation (also running gradlew tasks from within Java still felt hacky to me). Finally, I learned of a newer Flyway feature that could resolve this very cleanly and simply. This feature is an annotation: @FlywayTest which can be placed on a test class to clean (drop) and migrate the DB to a fresh state. The @FlywayTest annotation can also be placed on a function so that this clean/migration is done before each test function rather than once before the entire class. See https://github.com/flyway/flyway-test-extensions <https://github.com/flyway/flyway-test-extensions> In Fineract, the current Flyway dependency is com.googlecode.flyway:flyway-core version 2.1.1 (last updated March 2013). See https://mvnrepository.com/artifact/com.googlecode.flyway/flyway-core <https://mvnrepository.com/artifact/com.googlecode.flyway/flyway-core> com.googlecode.flyway had it’s last update December 2013, and says it’s now moved to org.flywaydb:flyway-core version 5.x and 6.x (6.x is beta but has updates in 2019) See https://mvnrepository.com/artifact/org.flywaydb/flyway-core <https://mvnrepository.com/artifact/org.flywaydb/flyway-core> This new Flyway feature (@FlywayTest) is only available from the org.flywaydb repo (not the current Fineract dependency com.googlecode.flyway). So my final question: Would it be worthwhile to update / refactor Flyway so I could use this feature, or do you think it would be unnecessary work? If it would be unnecessary / too time consuming to update this Flyway dependency, I could try to find a way to achieve this using Fineract's current version of the Flyway API. Please let me know your thoughts / concerns. Thanks in advance for your time and advice — Dylan Robson
