powertools-lambda-java icon indicating copy to clipboard operation
powertools-lambda-java copied to clipboard

Provide alternative way to disable idempotency in tests

Open roamingthings opened this issue 2 years ago • 6 comments

Is your feature request related to a problem? Please describe. During testing it may be necessary to disable the idempotency feature. Currently this can be achieved by setting the POWERTOOLS_IDEMPOTENCY_DISABLED ENV variable to true. The documentation suggests to either use the JUnit-Pioneer library to manipuplate the ENV variable during test or set the variable for all tests in the Maven or Gradle build.

However, when using Java 17+ it's no longer possible to use JUnit-Pioneer to set the ENV variable. The documentation of JUnit-Pioneer states:

The best way to prevent these warnings/errors, is to change the code under test, so this extension is no longer needed.

This only leaves the option to disable idempotency during build when using Maven or Gradle. However, when running test without a build tool (e.g. using IntelliJ) you have to manually configure ENV for each test you run. This also couples the test execution to the environment it's running in (Gradle, IDE etc.). In my opinion the test can no longer be 'self-containt'.

Describe the solution you'd like Independent of the technical solution the documentation should be updated to reflect the fact, that JUnit-Pioneer cannot be used for Java 17+.

To actually disable the idempotency feature there should be another mechanism that does not rely on an ENV variable. I'm not sure what would best fit the best-practices of this library. I could imagine a Java system-property or a method in the software.amazon.lambda.powertools.idempotency.Idempotency class.

Another alternative could be to extend the software.amazon.lambda.powertools.idempotency.Idempotency.Config class to disable idempotency.

I would still keep the option to use an ENV variable for test scenarios outside a unit test.

Describe alternatives you've considered As described above the only alternative I can see is to disable idempotency in the build tool/environment.

Additional context ./.

roamingthings avatar Aug 24 '23 06:08 roamingthings

Hi Alexander, thanks for reporting this.

Maybe we can add a method into the Config, but I'd like to think about a less intrusive solution.

jeromevdl avatar Aug 24 '23 07:08 jeromevdl

I agree. I would also prefer to not have a configuration property for that. So far I didn't have an idea.

Just thinking out loud: Maybe provide some kind of MockPersistencestore?

roamingthings avatar Aug 24 '23 07:08 roamingthings

Hey @roamingthings if you have a good idea for solving this, let us know. We see the issue but realistically won't get to it in the overall priority list for the moment.

scottgerring avatar Aug 31 '23 08:08 scottgerring

I will think more about the MockPersistenceStore way to handle that.

roamingthings avatar Sep 20 '23 12:09 roamingthings

Pioneer maintainer here. Regarding:

Independent of the technical solution the documentation should be updated to reflect the fact, that JUnit-Pioneer cannot be used for Java 17+.

Actually, Pioneer's environment variable extension works with Java 17+. From the docs:

The next best thing is to allow access to that specific package:

--add-opens java.base/java.util=$TARGET_MODULE
--add-opens java.base/java.lang=$TARGET_MODULE

Where $TARGET_MODULE equals ALL-UNNAMED if you place JUnit Pioneer on the class path, or org.junitpioneer if you place JUnit Pioneer on the module path.

We use this in our very own test:

https://github.com/junit-pioneer/junit-pioneer/blob/bdd0fbc0c75b2a697d414a8da80c9f6e294bce68/build.gradle.kts#L227-L233

Feel free to reach out if you are struggling with a specific setup. ✌️

EDIT: We just updated our docs, don't hesitate to comment on the following PR:

https://github.com/junit-pioneer/junit-pioneer/pull/773

beatngu13 avatar Oct 05 '23 19:10 beatngu13

@beatngu13 Thank you for pointing out the options on how to run Pioneer with Java 17+.

However, also Pioneer is a great framework I don't feel comfortable with having to modify the JVM behaviour, even if it's just in tests. Maybe this is the only solution here, but I will do some experiments when I have some time(TM).

Again, thank you for updating the documentation

roamingthings avatar Oct 15 '23 05:10 roamingthings

@roamingthings It would be possible to create your own PersistenceStore and pass this to the IdempotencyConfig e.g. by injecting it to the Lambda handler constructor through your tests.

    Idempotency.config().withPersistenceStore(
            new MyMockPersistenceStoreExtendingBasePersistenceStore();
    ).configure();

This class needs to extend BasePersistenceStore and implement PersistenceStore.

phipag avatar Oct 27 '25 13:10 phipag