Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

application-test.yaml not taken into account when using -Dquarkus.test.native-image-profile=test #27266

Closed
vsevel opened this issue Aug 12, 2022 · 20 comments · Fixed by #31369
Closed
Assignees
Labels
area/config kind/enhancement New feature or request
Milestone

Comments

@vsevel
Copy link
Contributor

vsevel commented Aug 12, 2022

Describe the bug

I am following the BUILDING A NATIVE EXECUTABLE - Profiles documentation.
We have tried moving all %test properties into a separate file application-test.yaml, but this flavor does not seem supported: the application does not those properties when they are moved.

Expected behavior

We should be able to expression properties for the native tests with a custom profile with both flavors %test or application-test.yaml.

Actual behavior

Properties coming from application-test.yaml are ignored in spite of using -Dquarkus.test.native-image-profile=test.

How to Reproduce?

Follow the example in https://quarkus.io/guides/building-native-image#profiles, and transfer %test in a separate file application-test.yaml, launch the app and verify that properties coming from the separate file are not taken into account.

Output of uname -a or ver

No response

Output of java -version

No response

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.8.2.Final

Build tool (ie. output of mvnw --version or gradlew --version)

No response

Additional information

we tried forcing the application-test.yaml to be in the target executable with:

quarkus:
  native:
    resources:
      includes: application-test.yaml

But that did not help.

@vsevel vsevel added the kind/bug Something isn't working label Aug 12, 2022
@vsevel
Copy link
Contributor Author

vsevel commented Oct 6, 2022

hello any news on this?

@radcortez
Copy link
Member

I suppose that the build profile is still prod, correct?

Do you get the message: The profile [X] used to build the native image is different from the runtime profile [Y]. This may lead to unexpected results.

If this is the case, the profile-aware file will not work, because it is not recorded with the native image. The profile-aware properties work because they are listed in getPropertyNames and are recorded regardless of the profile.

I guess that recording the profile from quarkus.test.native-image-profile would fix the issue, but I'm unsure if we want to include testing resources in the final native build.

Ideally, you should build the native image with the profile you want to use, so setting quarkus.profile=Xduring build, plus quarkus.test.native-image-profile. This works as expected.

Registering the resource for native-image, also works, but you need to register both files: quarkus.native.resources.includes=application.yaml,application-x.yaml. This is because we do not include the main file in the native image, and the loading config rules require the main file to be also present to load the profile-aware file.

@radcortez radcortez self-assigned this Oct 10, 2022
@vsevel
Copy link
Contributor Author

vsevel commented Oct 28, 2022

I suppose that the build profile is still prod, correct?

yes. and that seems the correct thing to do. right? I would not want to build with some test profile and send that build to prod. and I would not want to build once with a test profile for testing only, and once with the prod profile when I ship to production, because that would mean to production an untested build (at least during CI)

because of the current behavior, I ended up building with prod and testing with a profile called nativeit in properties in src/main/resources::

quarkus:
  test:
    native-image-profile: nativeit
...
"%nativeit":
  myprop: somevalue

Do you get the message: The profile [X] used to build the native image is different from the runtime profile [Y]. This may lead to unexpected results.

yes: 2022.10.27 12:25:31 2022-10-27 12:25:31,180 WARN [io.qua.run.con.ConfigRecorder] (main) The profile 'prod' used to build the native image is different from the runtime profile 'nativeit'. This may lead to unexpected results.

I guess that recording the profile from quarkus.test.native-image-profile would fix the issue,

you mean it is supposed to also capture an application-nativeit.yaml config file? my impression is that it is not the case.

but I'm unsure if we want to include testing resources in the final native build.

ideally, no I would not want to include test resources in an app I am sending to prod.
I actually do not particularly like "%nativeit".myprop.somevalue in my app either. to me this is just as bad as including a application-nativeit.yaml in the produced binary.

Ideally, you should build the native image with the profile you want to use, so setting quarkus.profile=X during build, plus quarkus.test.native-image-profile. This works as expected.

I have to build using the prod profile. this is what I am shipping. but I have to test with test properties.
really what I need is to point the native exec to a test config during the IT phase, just like in production I would point him toward a runtime provided config directory. and get rid of my nativeit properties from src/main/resources.

one option would be to create a config/application.yaml in the working directory of the native process during tests, or use -Dquarkus.config.locations=application-nativeit.yaml on the launched native process when testing (I do not want to build with that property, only use it when I launch the native process for testing). would that work?

@radcortez
Copy link
Member

you mean it is supposed to also capture an application-nativeit.yaml config file? my impression is that it is not the case.

Not at the moment, because we are not recording the profile set in quarkus.test.native-image-profile, but that is something that we can do. The downside, is that it will record testing properties in the native image (but that already happened if you use property names aware profiles).

ideally, no I would not want to include test resources in an app I am sending to prod. I actually do not particularly like "%nativeit".myprop.somevalue in my app either. to me this is just as bad as including a application-nativeit.yaml in the produced binary.

Yes, I agree.

one option would be to create a config/application.yaml in the working directory of the native process during tests, or use -Dquarkus.config.locations=application-nativeit.yaml on the launched native process when testing (I do not want to build with that property, only use it when I launch the native process for testing). would that work?

Yes, that should work. If it doesn't, I'll say it is a bug and we need to fix it.

@vsevel
Copy link
Contributor Author

vsevel commented Oct 28, 2022

but -Dquarkus.config.locations=application-nativeit.yaml would have to be set on the mvn command, which would be part of the prod build? ideally I would want to build without this property, and start the native exec for ITs with this property. but I believe this is not possible as everything is hidden behind the maven command. or is this something I can control on the failsafe plugin, or elsewhere?

@radcortez
Copy link
Member

You can set specific properties in the surefire / failsafe plugin.

@vsevel
Copy link
Contributor Author

vsevel commented Nov 24, 2022

this is working fine.
I specified:

		<profile>
			<id>native</id>
			<properties>
				<quarkus.package.type>native</quarkus.package.type>
				<quarkus.native.container-build>true</quarkus.native.container-build>
				<quarkus.native.native-image-xmx>7g</quarkus.native.native-image-xmx>
				<quarkus.native.additional-build-args></quarkus.native.additional-build-args>
				<quarkus.config.locations>src/test/application-nativeit.yaml</quarkus.config.locations>
			</properties>
			<build>
				<plugins>
					<plugin>
						<artifactId>maven-failsafe-plugin</artifactId>
						<configuration>
							<systemPropertyVariables>
								<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
							</systemPropertyVariables>
						</configuration>
					</plugin>
				</plugins>
			</build>
		</profile>

I added file src/test/application-nativeit.yaml with content:

myprop: somevalue-native

and in src/main/resources/application.yaml:

myprop: somevalue-default

"%test":
  myprop: somevalue-test

during the build I see:

2022.11.24 12:20:54  2022-11-24 12:20:54,703 INFO  [com.lod.art.ban.qua.MyStartup] (main) running bank-quarkus with java.version: 17.0.3 - java.vm.version: 17.0.3+7 myprop=somevalue-test
2022.11.24 12:20:54  2022-11-24 12:20:54,726 INFO  [com.lod.art.ban.qua.MyStartup] (main) quarkus.config.locations=Optional.empty
2022.11.24 12:20:54  2022-11-24 12:20:54,831 INFO  [io.quarkus] (main) bank-quarkus 1.0.0-SNAPSHOT on JVM (powered by Quarkus 2.14.0.Final) started in 10.655s. Listening on: http://localhost:8081/
2022.11.24 12:20:54  2022-11-24 12:20:54,832 INFO  [io.quarkus] (main) Profile test activated. 
...
2022.11.24 12:24:41  2022-11-24 12:24:41,921 INFO  [com.lod.art.ban.qua.MyStartup] (main) running bank-quarkus with java.version: 17.0.5 - java.vm.version: GraalVM 22.3.0.1-Final Java 17 Mandrel Distribution myprop=somevalue-native
2022.11.24 12:24:41  2022-11-24 12:24:41,921 INFO  [com.lod.art.ban.qua.MyStartup] (main) quarkus.config.locations=Optional[src/test/application-nativeit.yaml]
2022.11.24 12:24:41  2022-11-24 12:24:41,938 INFO  [io.quarkus] (main) bank-quarkus 1.0.0-SNAPSHOT native (powered by Quarkus 2.14.0.Final) started in 0.122s. Listening on: http://0.0.0.0:8081/
2022.11.24 12:24:41  2022-11-24 12:24:41,938 INFO  [io.quarkus] (main) Profile prod activated.

and when I run the app in production, I see:

2022-11-24 11:27:09,582 INFO  [com.lod.art.ban.qua.MyStartup] (main) running bank-quarkus with java.version: 17.0.5 - java.vm.version: GraalVM 22.3.0.1-Final Java 17 Mandrel Distribution myprop=somevalue-default
2022-11-24 11:27:09,582 INFO  [com.lod.art.ban.qua.MyStartup] (main) quarkus.config.locations=Optional[/app/base-application.properties]
2022-11-24 11:27:09,621 INFO  [io.quarkus] (main) bank-quarkus 1.0.0-SNAPSHOT native (powered by Quarkus 2.14.0.Final) started in 0.324s. Listening on: http://0.0.0.0:8080 and https://0.0.0.0:8443
2022-11-24 11:27:09,621 INFO  [io.quarkus] (main) Profile prod activated. 

and there is no more The profile [X] used to build the native image is different from the runtime profile [Y]. This may lead to unexpected results.
so everything seems to working out as expected.

I was just surprised that the <quarkus.config.locations>src/test/application-nativeit.yaml</quarkus.config.locations> would not go in the maven-failsafe-plugin systemPropertyVariables, as in:

					<plugin>
						<artifactId>maven-failsafe-plugin</artifactId>
						<configuration>
							<systemPropertyVariables>
								<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
								<quarkus.config.locations>src/test/application-nativeit.yaml</quarkus.config.locations>
							</systemPropertyVariables>
						</configuration>
					</plugin>

final question: should we add this pattern in the quarkus doc?

@radcortez
Copy link
Member

I was just surprised that the <quarkus.config.locations>src/test/application-nativeit.yaml</quarkus.config.locations> would not go in the maven-failsafe-plugin systemPropertyVariables, as in:

Do you mean that adding the property in systemPropertyVariables, won't work? If that is the case you need to investigate.

About the rest, are you ok sending a PR to the docs with this info? Thank you!

@vsevel
Copy link
Contributor Author

vsevel commented Dec 3, 2022

If that is the case you need to investigate.

ok I will

are you ok sending a PR to the docs with this info?

yes that was the idea

@radcortez
Copy link
Member

Sorry, I meant to say that we need to investigate, but we appreciate your help. Thank you!

@vsevel
Copy link
Contributor Author

vsevel commented Jan 13, 2023

hello. I did some more tests.
I confirm that with <quarkus.config.locations>src/test/application-nativeit.yaml</quarkus.config.locations> in systemPropertyVariables it does not work, and it does if I add it in the profile properties section.
as it stands there is a valid solution for the original requirement
how do you want to go further?

  • close as is
  • open a follow up documentation
  • investigate the reason why systemPropertyVariables? in this issue? in another?

@vsevel
Copy link
Contributor Author

vsevel commented Jan 13, 2023

hmm actually, no it is not working:

	<profiles>
		<profile>
			<id>native</id>
			<properties>
				<quarkus.package.type>native</quarkus.package.type>
				<quarkus.native.container-build>true</quarkus.native.container-build>
				<quarkus.native.native-image-xmx>7g</quarkus.native.native-image-xmx>
				<quarkus.native.additional-build-args></quarkus.native.additional-build-args>
				<quarkus.config.locations>./src/test/application-nativeit.yaml,./config/base-application.properties</quarkus.config.locations>
			</properties>
...

and when I start the app, with no properties and startup code:

    @ConfigProperty(name = "quarkus.config.locations")
    Optional<String> locations;

    void onStart(@Observes StartupEvent ev) {
        log.info("running " + appname
                + " with java.version=" + System.getProperty("java.version")
                + ", java.vm.version=" + System.getProperty("java.vm.version")
                + ", myprop=" + myprop
                + ", workingdir=" + new File(".").getAbsolutePath()
                + ", quarkus.config.locations=" + locations);
    }

then it shows:

2023-01-13 16:42:56,649 INFO  [com.lod.art.ban.qua.MyStartup] (main) running bank-quarkus with java.version=17.0.5, java.vm.version=GraalVM 22.3.0.1-Final Java 17 Mandrel Distribution, myprop=somevalue-default, workingdir=/work/., quarkus.config.locations=Optional[./src/test/application-nativeit.yaml]

so the config locations comes was included in my binary, and not used only in the context of the failsafe plugin.
this is clearly not something we want.

we have to find a way to pass quarkus.config.locations=Optional[./src/test/application-nativeit.yaml only to the failsafe execution.

@vsevel
Copy link
Contributor Author

vsevel commented Jan 13, 2023

I have tried:

				<plugins>
					<plugin>
						<artifactId>maven-failsafe-plugin</artifactId>
						<executions>
							<execution>
								<configuration>
									<quarkus.config.locations>./src/test/application-nativeit.yaml</quarkus.config.locations>
									<systemPropertyVariables>
										<native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
									</systemPropertyVariables>
								</configuration>
							</execution>
						</executions>
					</plugin>

but that does not work (I did not have too much hope).
not sure how to pass maven properties to a plugin.
the systemPropertyVariables seemed to be, on paper, the right way to go.
any idea?

@radcortez
Copy link
Member

Both of these works:

<environmentVariables>
  <QUARKUS_CONFIG_LOCATIONS>./src/main/resources/application-test.properties</QUARKUS_CONFIG_LOCATIONS>
</environmentVariables>
<systemProperties>
  <quarkus.test.arg-line>-Dquarkus.config.locations=./src/main/resources/application-test.properties</quarkus.test.arg-line>
</systemProperties>

We are not propagating the system properties from the failsafe plugin to the integration test launcher. I can't remember a reason not to do it, considering that environmentVariables works.

@geoand any thoughts?

@metacosm
Copy link
Contributor

Probably because env variables are read-only in Java. A work around would be to expose the env variables via system properties using ArtifactLauncher.includeAsSysProps but that wouldn't be strictly testing the exact thing you want to test (at least, not in the case I'm interested in).

@geoand
Copy link
Contributor

geoand commented Jan 20, 2023

@radcortez it's probably just an oversight

@radcortez
Copy link
Member

Ok, I'll see if I can implement something that propagates the properties.

@vsevel
Copy link
Contributor Author

vsevel commented Jan 23, 2023

Both of these works:

<environmentVariables>
  <QUARKUS_CONFIG_LOCATIONS>./src/main/resources/application-test.properties</QUARKUS_CONFIG_LOCATIONS>
</environmentVariables>

@radcortez yes, successfully validated on my side. this is an acceptable solution. it would be more consistent if system property variables worked as well, but I would be happy even if it stayed that way. as discussed previously, I am willing to document once we establish all valid options.

@radcortez
Copy link
Member

We want to implement the propagation of system properties. I'll do it when I find some time for it :)

In the meanwhile, feel free to propose a doc update. Thanks :)

@bitsofinfo
Copy link

#37962

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area/config kind/enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants