'Micronaut @Requires annotation not respected in pipeline

I have built a Micronaut application which so far has not had any CI pipeline. All builds work flawlessly on all developer computers, but I can't for the life of me get it to run in a pipeline.

The issue is that I have a service annotated with @Context, meaning I want it to start at application startup:

@Context
@Requires(property = "broker.subscribe.exchanges", env = { "k8s", "local" })
@ExecuteOn(TaskExecutors.MESSAGE_CONSUMER)
public class SubscriberService {

    private final BrokerSubscriber subscriber;

    public SubscriberService(final BrokerSubscriber subscriber) {
        this.subscriber = subscriber;
    }
}

This just starts subscribing to a number of exchanges. I've added env to the annotation to ensure these do not start when running tests. If I remove the env property from the annotation, I get one failing test.

The code running in the pipeline has the env property set on the annotation, but it is not respected. When I run ./gradlew clean test in the pipeline, the exact same test that fail without the env property set locally fail.

The test in question tests a configuration object, and is not annotated with @MicronautTest, however it does start an ApplicationContext:

class BrokerConfigurationTest {

    private ApplicationContext ctx;

    @BeforeEach
    void setUp() {
        final Map<String, Object> items = new HashMap<>();
        items.put(getKey("server.host"), HOST);
        items.put(getKey("server.port"), PORT);
        items.put(getKey("server.password"), PASSWORD);
        items.put(getKey("server.user"), USER);
        items.put(getKey("subscribe.exchanges"), Set.of(EXCHANGE));

        // Explicitly not loading anything else.
        ctx = ApplicationContext.builder().packages(BrokerConfigurationTest.class.getPackageName()).properties(items).start();
        // Same result:
        // ctx = ApplicationContext.builder().environments("asdf").properties(items).start();
        // Same result:
        // ctx = ApplicationContext.run(items);
    }
}

What actually does work is removing the following line:

items.put(getKey("subscribe.exchanges"), Set.of(EXCHANGE));

Meaning that the @Requires annotation is not fulfilled in regards to its property:

@Requires(property = "broker.subscribe.exchanges", env = { "k8s", "local" })

With this setup, I can even remove the env property in the annotation and it works. But I need to test the behavior of this property, so this is not solution.

What I've tried that does not work:

  1. Disable environment deduction with ./gradlew -Dmicronaut.env.deduction=false clean test
  2. Adding env variable MICRONAUT_ENVIRONMENTS set to ci in the pipeline build, and adding notEnv = { "ci" } in the Requires-annotation.
  3. Both of the above at the same time
  4. Explicitly telling the failing tests not to scan for anything outside of their own packages
  5. Explicitly setting the environment to something other than k8s or local in the setup of the test.

Super smooth experience with the framework so far, but this has me scratching my head. Any input on what might be off here would be greatly appreciated.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source