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

Reply via email to