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

Move process output handling to separate class & add tests #101

Merged
merged 1 commit into from
Mar 3, 2024
Merged

Move process output handling to separate class & add tests #101

merged 1 commit into from
Mar 3, 2024

Conversation

Marcono1234
Copy link
Contributor

Context

This allows testing process handling in general without having to run certain Git commands, hoping that they behave in a certain way (exit code and console output), which requires complicated test setups and which could break for future Git versions. See also git-commit-id/git-commit-id-maven-plugin#483 (this hopefully allows removing BigDiffTest).

I have added additional GitHub review comments below to highlight certain aspects of these changes.

Contributor Checklist

  • Added relevant integration or unit tests to verify the changes
  • Update the Readme or any other documentation (including relevant Javadoc)
  • Ensured that tests pass locally: mvn clean package
  • Ensured that the code meets the current checkstyle coding style definition: mvn clean verify -Pcheckstyle -Dmaven.test.skip=true -B

This allows testing process handling in general without having to run
certain Git commands, hoping that they behave in a certain way (exit code
and console output), which requires complicated test setups and which
could break for future Git versions.
Comment on lines -496 to -497
// return false to indicate we don't need to read more content
return false;
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed this logic to stop reading from the output. It is always necessary to read from the output, even if the lines are then discarded, otherwise the output buffer can get full and the process gets stuck writing to stdout.

final Future<Optional<RuntimeException>> stderrFuture = executorService.submit(
new CallableBufferedStreamReader(proc.getErrorStream(),
line -> {
errMsg.append(line);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This might have been missing a \n after every line.

Comment on lines +102 to +109
} catch (ExecutionException e) {
throw new ExecutionException("Failed waiting for stdout", e.getCause());
}
try {
stderrOutput = stderrFuture.get();
} catch (ExecutionException e) {
throw new ExecutionException("Failed waiting for stderr", e.getCause());
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not completely sure about this unwrapping with e.getCause() and then rewrapping as ExecutionException. Could also directly propagate e, but then you would have to inspect the stack trace to understand whether the exception occurred for the stdout or stderr thread.

private static void runJavaProcess(int exitCode, int outRepeatCount, long sleepMillis, TestAction testAction) {
// Creates a small Java program and starts it directly from the source file (JEP 330)
// This is done instead of using shell scripts to be more independent of the OS running the test
String javaBinaryPath = System.getProperty("java.home") + File.separator + "bin" + File.separator + "java";
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Constructing the javaBinaryPath this way might be a bit brittle, but it is probably the most reliable approach.

I also thought about obtaining the java path using java.lang.ProcessHandle.current() assuming that the current test process is a Java process, but that might be too speculative. For example when running the test in Eclipse this was actually javaw, which is probably fine as well, but shows that making assumptions about the current running process is not reliable enough.

Any suggestions for alternative ways for obtaining the java path are welcome.

(Though I would really like to avoid using shell scripting instead of a Java source file, because that would require OS-specific shell scripts and might be quite error-prone.)

Copy link
Contributor

Choose a reason for hiding this comment

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

Thanks for your contribution! I like the overall change and it looks good to me. However this tests feels a bit off in my view. I clearly would agree that adding tests always bring a benefit (e.g. to see if something is broken that worked before), but I'm not sure if we somehow want to rely on executing java.
I'll need to think about that...I can't think of a real alternative that would work os independant. Certainly hacking some shell scripts is IMHO even worse...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@TheSnoozer, have you made a decision yet? No hurry in case you haven't yet.

Would it be an option to include these changes, and if this test causes problems in the future or becomes difficult to maintain, add @Ignore to it (or in the worst case even remove it again)?

I think the main problem (if any) with this is obtaining the java path and making sure it is the correct one. The other parts of this test should be quite reliable.

One way in which this test can be improved though could be to add a proper DummyProgram.java file or similar under src/test/resources/process-handler/1 instead of the current approach of creating temp files for the Java source code. Should I change that?

Footnotes

  1. The reason why I would move it under src/test/resources instead of src/test/java is that there is no need to create a .class file for it, it might look weird if there is this seemingly unused Java source file under src/test/java and one might be tempted to use some of the test dependencies in it, even though this would not work at runtime.
    That would however require moving the current Git submodule at src/test/resources one level down, e.g. to src/test/resources/git-repos.

Copy link
Contributor

Choose a reason for hiding this comment

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

Indeed the main problem is obtaining the java executable....

I guess you are right, in case this becomes a hassle in the future I still can remove the tests, or add @ignore...

Thanks again for your contribution I'm going ahead and merge now!

@TheSnoozer TheSnoozer added this to the 6.0.0 milestone Mar 3, 2024
@TheSnoozer TheSnoozer merged commit a5f1676 into git-commit-id:master Mar 3, 2024
12 checks passed
@TheSnoozer TheSnoozer modified the milestones: 6.0.0, 6.0.0-rc.7 Mar 3, 2024
@Marcono1234 Marcono1234 deleted the process-handling branch March 23, 2024 12:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants