-
Notifications
You must be signed in to change notification settings - Fork 25k
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
CLI: Close subcommands in MultiCommand #28954
Changes from 11 commits
39770da
be11085
bf6a3eb
33d78c4
63c3656
52a71d9
ee04957
103d175
050a9f1
b2ece8a
99dd6ce
4b42afd
6eb66e7
91d785e
862090e
f098095
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -22,22 +22,46 @@ | |
import joptsimple.OptionSet; | ||
import org.junit.Before; | ||
|
||
import java.io.IOException; | ||
import java.util.concurrent.atomic.AtomicBoolean; | ||
|
||
public class MultiCommandTests extends CommandTestCase { | ||
|
||
static class DummyMultiCommand extends MultiCommand { | ||
|
||
AtomicBoolean closed = new AtomicBoolean(); | ||
DummyMultiCommand() { | ||
super("A dummy multi command", () -> {}); | ||
} | ||
@Override | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a personal preference but given that we're adding to this class, I find it hard to read without empty lines between methods/constructor/member fields. Can you please add them? |
||
public void close() throws IOException { | ||
super.close(); | ||
this.closed.compareAndSet(false, true); | ||
} | ||
} | ||
|
||
static class DummySubCommand extends Command { | ||
AtomicBoolean throwsExceptionOnClose = new AtomicBoolean(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why does this need to be an AtomicBoolean? I think it can just be a |
||
AtomicBoolean closed = new AtomicBoolean(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. make this |
||
DummySubCommand() { | ||
super("A dummy subcommand", () -> {}); | ||
} | ||
DummySubCommand(boolean throwsExceptionOnClose) { | ||
super("A dummy subcommand", () -> {}); | ||
this.throwsExceptionOnClose.compareAndSet(false, throwsExceptionOnClose); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when you use |
||
} | ||
@Override | ||
protected void execute(Terminal terminal, OptionSet options) throws Exception { | ||
terminal.println("Arguments: " + options.nonOptionArguments().toString()); | ||
} | ||
@Override | ||
public void close() throws IOException { | ||
if (throwsExceptionOnClose.get()) { | ||
throw new IOException(); | ||
} else { | ||
closed.compareAndSet(false, true); | ||
} | ||
} | ||
} | ||
|
||
DummyMultiCommand multiCommand; | ||
|
@@ -102,4 +126,27 @@ public void testSubcommandArguments() throws Exception { | |
assertFalse(output, output.contains("command1")); | ||
assertTrue(output, output.contains("Arguments: [foo, bar]")); | ||
} | ||
|
||
public void testClose() throws Exception { | ||
DummySubCommand subCommand1 = new DummySubCommand(); | ||
DummySubCommand subCommand2 = new DummySubCommand(); | ||
multiCommand.subcommands.put("command1", subCommand1); | ||
multiCommand.subcommands.put("command2", subCommand2); | ||
multiCommand.close(); | ||
assertTrue("MultiCommand must have been closed when close method is invoked", multiCommand.closed.get()); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. for me |
||
assertTrue("SubCommand1 must have been closed when close method is invoked", subCommand1.closed.get()); | ||
assertTrue("SubCommand2 must have been closed when close method is invoked", subCommand2.closed.get()); | ||
} | ||
|
||
public void testCloseWhenSubCommandCloseThrowsException() { | ||
boolean throwExceptionWhenClosed = true; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be nice to test the other scenarios or add some randomization to this test in terms of which subcommand(s) throws an exception: final boolean command1Throws = randomBoolean();
final boolean command2Throws = randomBoolean();
...
assertTrue(command1Throws ^ subCommand1.closed.get());
assertTrue(command2Throws ^ subCommand2.closed.get()); |
||
DummySubCommand subCommand1 = new DummySubCommand(throwExceptionWhenClosed); | ||
DummySubCommand subCommand2 = new DummySubCommand(); | ||
multiCommand.subcommands.put("command1", subCommand1); | ||
multiCommand.subcommands.put("command2", subCommand2); | ||
// verify exception is thrown, as well as other non failed sub-commands closed | ||
// properly. | ||
expectThrows(IOException.class, () -> multiCommand.close()); | ||
assertTrue("SubCommand2 must have been closed when close method is invoked", subCommand2.closed.get()); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make this field
final
and add a line after for readability