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

Improved use of java.io.tmpdir #838

Merged
merged 4 commits into from
Sep 19, 2024
Merged

Conversation

jglick
Copy link
Member

@jglick jglick commented Sep 18, 2024

Ensure that temporary files are written to target/tmp/ (where mvn clean can delete them) rather than the system temporary directory, including in RealJenkinsRule forked JVMs; note that in the test JVM it seems to be necessary to look up this system property explicitly, I think since Surefire sets the system property after startup rather than using -D, and something reads and caches the value soon after startup. Ensure that all temporary directories are deleted when the test exits. Use temporary directories instead of $JENKINS_HOME for anything added by the test harness rather than Jenkins itself. (Extracted from #827.)

@@ -63,7 +63,7 @@
public class UnitTestSupportingPluginManager extends PluginManager {

public UnitTestSupportingPluginManager(File rootDir) {
super((ServletContext) null, new File(rootDir, "plugins"));
super((ServletContext) null, rootDir);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

was deleting plugins but not the parent dir jenkinsXXX created by

@@ -90,7 +90,7 @@ public void setup(JenkinsRule jenkinsRule, WithPluginManager recipe) throws Exce
public void decorateHome(JenkinsRule jenkinsRule, File home) throws Exception {
Class<? extends PluginManager> c = recipe.value();
Constructor<? extends PluginManager> ctr = c.getDeclaredConstructor(File.class);
jenkinsRule.setPluginManager(ctr.newInstance(home));
jenkinsRule.setPluginManager(ctr.newInstance(new File(home, "plugins")));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To restore behavior for those tests requesting UnitTestSupportingPluginManager.

@@ -90,7 +101,6 @@ private String getMimeType(String path) {
*/
public static synchronized JavaNetReverseProxy2 getInstance() throws Exception {
if (INSTANCE == null) {
// TODO: think of a better location --- ideally inside the target/ dir so that clean would wipe them out
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

}
if (home.get() != null) {
try {
jenkinsOptions("--webroot=" + createTempDirectory("webroot"), "--pluginroot=" + createTempDirectory("pluginroot"));
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Various controller packagings set these options to temp dirs, so I think it is realistic to set them here automatically. Otherwise the fallback is inside $JENKINS_HOME which is undesirable.

try {
deprovision();
tmp.dispose();
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be confusing depending on whether or not you have whitespace displayed: now just deleting all temp dirs when the test completes, regardless of #610 mode. (The other code in deprovision did not seem important since a rule instance is only expected to be used once.)

* and will honor {@code java.io.tmpdir} set by Surefire
* after {@code StaticProperty.JAVA_IO_TMPDIR} has been initialized.
*/
public Path createTempDirectory(String prefix) throws IOException {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exposing this utility since it can be useful from certain tests, and it is otherwise tedious to arrange for dirs to be deleted at test exit.

@jglick jglick marked this pull request as draft September 19, 2024 12:22
@jglick jglick marked this pull request as ready for review September 19, 2024 13:17
@jglick jglick merged commit 9e8bb87 into jenkinsci:master Sep 19, 2024
14 checks passed
@jglick jglick deleted the java.io.tmpdir branch September 19, 2024 13:45
@basil
Copy link
Member

basil commented Sep 19, 2024

java.lang.AssertionError
	at org.junit.Assert.fail(Assert.java:87)
	at org.junit.Assert.assertTrue(Assert.java:42)
	at org.junit.Assert.assertTrue(Assert.java:53)
	at hudson.PluginManagerTest.uberClassLoaderIsAvailableDuringStart(PluginManagerTest.java:213)
org.jvnet.hudson.test.RealJenkinsRule$StepException: 
Remote step threw an exception: java.lang.AssertionError: 
Expected: is "/home/jenkins/agent/workspace/Core_jenkins_PR-9756/test/target/j h7251048736527506496/agent.jar"
     but: was "/home/jenkins/agent/workspace/Core_jenkins_PR-9756/test/target/agent.jar"
	at org.jvnet.hudson.test.RealJenkinsRule.runRemotely(RealJenkinsRule.java:998)
	at org.jvnet.hudson.test.RealJenkinsRule.runRemotely(RealJenkinsRule.java:983)
	at hudson.slaves.JNLPLauncherRealTest.then(JNLPLauncherRealTest.java:81)
	at hudson.slaves.JNLPLauncherRealTest.webSocket(JNLPLauncherRealTest.java:70)
	at java.base/java.lang.reflect.Method.invoke(Method.java:569)
	at org.jvnet.hudson.test.RealJenkinsRule$1.evaluate(RealJenkinsRule.java:527)
Caused by: java.lang.AssertionError: 
Expected: is "/home/jenkins/agent/workspace/Core_jenkins_PR-9756/test/target/j h7251048736527506496/agent.jar"
     but: was "/home/jenkins/agent/workspace/Core_jenkins_PR-9756/test/target/agent.jar"
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
	at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:6)
	at hudson.slaves.JNLPLauncherRealTest$RunJobStep.run(JNLPLauncherRealTest.java:107)
	at org.jvnet.hudson.test.RealJenkinsRule$StepsToStep2.run(RealJenkinsRule.java:1419)
	at org.jvnet.hudson.test.RealJenkinsRule$Endpoint.lambda$doStep$0(RealJenkinsRule.java:1332)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
	at java.base/java.lang.Thread.run(Thread.java:840)

@@ -465,7 +481,7 @@ private static AgentArguments getAgentArguments(JenkinsRule r, String name) thro
if (!launcher.getWorkDirSettings().isDisabled()) {
commandLineArgs = launcher.getWorkDirSettings().toCommandLineArgs(c);
}
File agentJar = new File(r.jenkins.getRootDir(), "agent.jar");
File agentJar = new File(System.getProperty("java.io.tmpdir"), "agent.jar");
Copy link
Member

@jtnord jtnord Sep 20, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this appears to completely break some things:

e.g. -DforkCount=<number_greater_than_one> as the file may not exist for 2 forks at the time of checking (which use the same surefire temp directory) , is completely written by one and the other and then used whilst the other is overwriting it.
Or in Windows locking exceptions for the second attempt to write the file.

  1. the ability to quickly switch between version using -DJenkins.version=x (you now need to mvn clean as opposed to just using the incremental compilation which is faster)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah a temp file would be better for this case. I can prepare a patch for it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants