Use PrintStream in ConfirmingCommand (#2140)

* Use PrintStream in ConfirmingCommand

* Add errorPrintStream

* remove unneccesary line
This commit is contained in:
sarahcaseybot 2023-09-19 12:11:18 -04:00 committed by GitHub
parent e182692a5f
commit fc1857717d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 79 additions and 38 deletions

View file

@ -15,9 +15,12 @@
package google.registry.tools; package google.registry.tools;
import static google.registry.tools.CommandUtilities.promptForYes; import static google.registry.tools.CommandUtilities.promptForYes;
import static java.nio.charset.StandardCharsets.UTF_8;
import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameter;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import java.io.PrintStream;
import java.io.UnsupportedEncodingException;
/** A {@link Command} that implements a confirmation step before executing. */ /** A {@link Command} that implements a confirmation step before executing. */
public abstract class ConfirmingCommand implements Command { public abstract class ConfirmingCommand implements Command {
@ -27,23 +30,37 @@ public abstract class ConfirmingCommand implements Command {
description = "Do not prompt before executing") description = "Do not prompt before executing")
boolean force; boolean force;
public PrintStream printStream;
public PrintStream errorPrintStream;
protected ConfirmingCommand() {
try {
printStream = new PrintStream(System.out, false, UTF_8.name());
errorPrintStream = new PrintStream(System.err, false, UTF_8.name());
} catch (UnsupportedEncodingException e) {
throw new RuntimeException(e);
}
}
@Override @Override
public final void run() throws Exception { public final void run() throws Exception {
if (checkExecutionState()) { if (checkExecutionState()) {
init(); init();
printLineIfNotEmpty(prompt()); printLineIfNotEmpty(prompt(), printStream);
if (dontRunCommand()) { if (dontRunCommand()) {
// This typically happens when all of the work is accomplished inside of prompt(), so do // This typically happens when all of the work is accomplished inside of prompt(), so do
// nothing further. // nothing further.
return; return;
} else if (force || promptForYes("Perform this command?")) { } else if (force || promptForYes("Perform this command?")) {
System.out.println("Running ... "); printStream.println("Running ... ");
System.out.println(execute()); printStream.println(execute());
printLineIfNotEmpty(postExecute()); printLineIfNotEmpty(postExecute(), printStream);
} else { } else {
System.out.println("Command aborted."); printStream.println("Command aborted.");
} }
} }
printStream.close();
errorPrintStream.close();
} }
/** Run any pre-execute command checks and return true if they all pass. */ /** Run any pre-execute command checks and return true if they all pass. */
@ -76,9 +93,9 @@ public abstract class ConfirmingCommand implements Command {
} }
/** Prints the provided text with a trailing newline, if text is not null or empty. */ /** Prints the provided text with a trailing newline, if text is not null or empty. */
private static void printLineIfNotEmpty(String text) { private static void printLineIfNotEmpty(String text, PrintStream printStream) {
if (!Strings.isNullOrEmpty(text)) { if (!Strings.isNullOrEmpty(text)) {
System.out.println(text); printStream.println(text);
} }
} }
} }

View file

@ -78,7 +78,7 @@ final class CreateDomainCommand extends CreateOrUpdateDomainCommand {
Money createCost = prices.getCreateCost(); Money createCost = prices.getCreateCost();
currency = createCost.getCurrencyUnit().getCode(); currency = createCost.getCurrencyUnit().getCode();
cost = createCost.multipliedBy(period).getAmount().toString(); cost = createCost.multipliedBy(period).getAmount().toString();
System.out.printf( printStream.printf(
"NOTE: %s is premium at %s per year; sending total cost for %d year(s) of %s %s.\n", "NOTE: %s is premium at %s per year; sending total cost for %d year(s) of %s %s.\n",
domain, createCost, period, currency, cost); domain, createCost, period, currency, cost);
} }

View file

@ -39,6 +39,7 @@ import google.registry.tools.params.OptionalStringParameter;
import google.registry.tools.params.StringListParameter; import google.registry.tools.params.StringListParameter;
import google.registry.tools.params.TransitionListParameter.BillingCostTransitions; import google.registry.tools.params.TransitionListParameter.BillingCostTransitions;
import google.registry.tools.params.TransitionListParameter.TldStateTransitions; import google.registry.tools.params.TransitionListParameter.TldStateTransitions;
import java.io.UnsupportedEncodingException;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -233,12 +234,11 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
@Nullable @Nullable
@Parameter( @Parameter(
names = {"--num_dns_publish_locks"}, names = {"--num_dns_publish_locks"},
description = description =
"The number of publish locks we allow in parallel for DNS updates under this tld " "The number of publish locks we allow in parallel for DNS updates under this tld "
+ "(1 for TLD-wide locks)", + "(1 for TLD-wide locks)",
arity = 1 arity = 1)
)
Integer numDnsPublishShards; Integer numDnsPublishShards;
@Nullable @Nullable
@ -301,7 +301,7 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
protected abstract void initTldCommand(); protected abstract void initTldCommand();
@Override @Override
protected final void init() { protected final void init() throws UnsupportedEncodingException {
assertAllowedEnvironment(); assertAllowedEnvironment();
initTldCommand(); initTldCommand();
String duplicates = Joiner.on(", ").join(findDuplicates(mainParameters)); String duplicates = Joiner.on(", ").join(findDuplicates(mainParameters));
@ -360,7 +360,7 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
if (!renewBillingCostTransitions.isEmpty()) { if (!renewBillingCostTransitions.isEmpty()) {
// TODO(b/20764952): need invoicing support for multiple renew billing costs. // TODO(b/20764952): need invoicing support for multiple renew billing costs.
if (renewBillingCostTransitions.size() > 1) { if (renewBillingCostTransitions.size() > 1) {
System.err.println( errorPrintStream.println(
"----------------------\n" "----------------------\n"
+ "WARNING: Do not set multiple renew cost transitions " + "WARNING: Do not set multiple renew cost transitions "
+ "until b/20764952 is fixed.\n" + "until b/20764952 is fixed.\n"
@ -463,7 +463,8 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
} }
} }
private void checkReservedListValidityForTld(String tld, Set<String> reservedListNames) { private void checkReservedListValidityForTld(String tld, Set<String> reservedListNames)
throws UnsupportedEncodingException {
ImmutableList.Builder<String> builder = new ImmutableList.Builder<>(); ImmutableList.Builder<String> builder = new ImmutableList.Builder<>();
for (String reservedListName : reservedListNames) { for (String reservedListName : reservedListNames) {
if (!reservedListName.startsWith("common_") && !reservedListName.startsWith(tld + "_")) { if (!reservedListName.startsWith("common_") && !reservedListName.startsWith(tld + "_")) {
@ -476,7 +477,7 @@ abstract class CreateOrUpdateTldCommand extends MutatingCommand {
Joiner.on(", ").join(invalidNames), Joiner.on(", ").join(invalidNames),
tld); tld);
if (overrideReservedListRules) { if (overrideReservedListRules) {
System.err.println("Error overridden: " + errMsg); errorPrintStream.println("Error overridden: " + errMsg);
} else { } else {
throw new IllegalArgumentException(errMsg); throw new IllegalArgumentException(errMsg);
} }

View file

@ -85,7 +85,7 @@ final class DeleteAllocationTokensCommand extends UpdateOrDeleteAllocationTokens
if (!dryRun) { if (!dryRun) {
tm().delete(tokensToDelete); tm().delete(tokensToDelete);
} }
System.out.printf( printStream.printf(
"%s tokens: %s\n", "%s tokens: %s\n",
dryRun ? "Would delete" : "Deleted", dryRun ? "Would delete" : "Deleted",
JOINER.join(tokensToDelete.stream().map(VKey::getKey).sorted().collect(toImmutableList()))); JOINER.join(tokensToDelete.stream().map(VKey::getKey).sorted().collect(toImmutableList())));

View file

@ -14,6 +14,7 @@
package google.registry.tools; package google.registry.tools;
import com.beust.jcommander.Parameter; import com.beust.jcommander.Parameter;
import com.beust.jcommander.Parameters; import com.beust.jcommander.Parameters;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
@ -86,17 +87,17 @@ class LoadTestCommand extends ConfirmingCommand implements CommandWithConnection
@Override @Override
protected boolean checkExecutionState() { protected boolean checkExecutionState() {
if (RegistryToolEnvironment.get() == RegistryToolEnvironment.PRODUCTION) { if (RegistryToolEnvironment.get() == RegistryToolEnvironment.PRODUCTION) {
System.err.println("You may not run a load test against production."); errorPrintStream.println("You may not run a load test against production.");
return false; return false;
} }
// Check validity of TLD and Client Id. // Check validity of TLD and Client Id.
if (!Tlds.getTlds().contains(tld)) { if (!Tlds.getTlds().contains(tld)) {
System.err.printf("No such TLD: %s\n", tld); errorPrintStream.printf("No such TLD: %s\n", tld);
return false; return false;
} }
if (!Registrar.loadByRegistrarId(clientId).isPresent()) { if (!Registrar.loadByRegistrarId(clientId).isPresent()) {
System.err.printf("No such client: %s\n", clientId); errorPrintStream.printf("No such client: %s\n", clientId);
return false; return false;
} }
@ -112,7 +113,7 @@ class LoadTestCommand extends ConfirmingCommand implements CommandWithConnection
@Override @Override
protected String execute() throws Exception { protected String execute() throws Exception {
System.err.println("Initiating load test..."); errorPrintStream.println("Initiating load test...");
ImmutableMap<String, Object> params = new ImmutableMap.Builder<String, Object>() ImmutableMap<String, Object> params = new ImmutableMap.Builder<String, Object>()
.put("tld", tld) .put("tld", tld)

View file

@ -71,7 +71,7 @@ public abstract class LockOrUnlockDomainCommand extends ConfirmingCommand {
} }
String duplicates = Joiner.on(", ").join(findDuplicates(mainParameters)); String duplicates = Joiner.on(", ").join(findDuplicates(mainParameters));
checkArgument(duplicates.isEmpty(), "Duplicate domain arguments found: '%s'", duplicates); checkArgument(duplicates.isEmpty(), "Duplicate domain arguments found: '%s'", duplicates);
System.out.println( printStream.println(
"== ENSURE THAT YOU HAVE AUTHENTICATED THE REGISTRAR BEFORE RUNNING THIS COMMAND =="); "== ENSURE THAT YOU HAVE AUTHENTICATED THE REGISTRAR BEFORE RUNNING THIS COMMAND ==");
} }

View file

@ -42,6 +42,7 @@ import google.registry.model.poll.PollMessage;
import google.registry.model.reporting.HistoryEntry.Type; import google.registry.model.reporting.HistoryEntry.Type;
import google.registry.util.Clock; import google.registry.util.Clock;
import google.registry.util.NonFinalForTesting; import google.registry.util.NonFinalForTesting;
import java.io.UnsupportedEncodingException;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import javax.inject.Inject; import javax.inject.Inject;
@ -76,7 +77,7 @@ class UnrenewDomainCommand extends ConfirmingCommand {
StatusValue.SERVER_UPDATE_PROHIBITED); StatusValue.SERVER_UPDATE_PROHIBITED);
@Override @Override
protected void init() { protected void init() throws UnsupportedEncodingException {
checkArgument(period >= 1 && period <= 9, "Period must be in the range 1-9"); checkArgument(period >= 1 && period <= 9, "Period must be in the range 1-9");
DateTime now = clock.nowUtc(); DateTime now = clock.nowUtc();
ImmutableSet.Builder<String> domainsNonexistentBuilder = new ImmutableSet.Builder<>(); ImmutableSet.Builder<String> domainsNonexistentBuilder = new ImmutableSet.Builder<>();
@ -116,20 +117,24 @@ class UnrenewDomainCommand extends ConfirmingCommand {
&& domainsDeleting.isEmpty() && domainsDeleting.isEmpty()
&& domainsWithDisallowedStatuses.isEmpty() && domainsWithDisallowedStatuses.isEmpty()
&& domainsExpiringTooSoon.isEmpty()); && domainsExpiringTooSoon.isEmpty());
if (foundInvalidDomains) { if (foundInvalidDomains) {
System.err.print("Found domains that cannot be unrenewed for the following reasons:\n\n"); errorPrintStream.print(
"Found domains that cannot be unrenewed for the following reasons:\n\n");
} }
if (!domainsNonexistent.isEmpty()) { if (!domainsNonexistent.isEmpty()) {
System.err.printf("Domains that don't exist: %s\n\n", domainsNonexistent); errorPrintStream.printf("Domains that don't exist: %s\n\n", domainsNonexistent);
} }
if (!domainsDeleting.isEmpty()) { if (!domainsDeleting.isEmpty()) {
System.err.printf("Domains that are deleted or pending delete: %s\n\n", domainsDeleting); errorPrintStream.printf(
"Domains that are deleted or pending delete: %s\n\n", domainsDeleting);
} }
if (!domainsWithDisallowedStatuses.isEmpty()) { if (!domainsWithDisallowedStatuses.isEmpty()) {
System.err.printf("Domains with disallowed statuses: %s\n\n", domainsWithDisallowedStatuses); errorPrintStream.printf(
"Domains with disallowed statuses: %s\n\n", domainsWithDisallowedStatuses);
} }
if (!domainsExpiringTooSoon.isEmpty()) { if (!domainsExpiringTooSoon.isEmpty()) {
System.err.printf("Domains expiring too soon: %s\n\n", domainsExpiringTooSoon); errorPrintStream.printf("Domains expiring too soon: %s\n\n", domainsExpiringTooSoon);
} }
checkArgument(!foundInvalidDomains, "Aborting because some domains cannot be unrenewed"); checkArgument(!foundInvalidDomains, "Aborting because some domains cannot be unrenewed");
} }
@ -154,7 +159,7 @@ class UnrenewDomainCommand extends ConfirmingCommand {
protected String execute() { protected String execute() {
for (String domainName : mainParameters) { for (String domainName : mainParameters) {
tm().transact(() -> unrenewDomain(domainName)); tm().transact(() -> unrenewDomain(domainName));
System.out.printf("Unrenewed %s\n", domainName); printStream.printf("Unrenewed %s\n", domainName);
} }
return "Successfully unrenewed all domains."; return "Successfully unrenewed all domains.";
} }

View file

@ -208,7 +208,7 @@ final class UpdateAllocationTokensCommand extends UpdateOrDeleteAllocationTokens
if (!dryRun) { if (!dryRun) {
tm().putAll(batch); tm().putAll(batch);
} }
System.out.printf( printStream.printf(
"%s tokens: %s\n", "%s tokens: %s\n",
dryRun ? "Would update" : "Updated", dryRun ? "Would update" : "Updated",
JOINER.join( JOINER.join(

View file

@ -70,14 +70,14 @@ public class CreateCancellationsForBillingEventsCommand extends ConfirmingComman
} }
}); });
billingEventsToCancel = billingEventsBuilder.build(); billingEventsToCancel = billingEventsBuilder.build();
System.out.printf("Found %d BillingEvent(s) to cancel\n", billingEventsToCancel.size()); printStream.printf("Found %d BillingEvent(s) to cancel\n", billingEventsToCancel.size());
ImmutableSet<Long> missingIds = missingIdsBuilder.build(); ImmutableSet<Long> missingIds = missingIdsBuilder.build();
if (!missingIds.isEmpty()) { if (!missingIds.isEmpty()) {
System.out.printf("Missing BillingEvent(s) for IDs %s\n", missingIds); printStream.printf("Missing BillingEvent(s) for IDs %s\n", missingIds);
} }
ImmutableSet<Long> alreadyCancelledIds = alreadyCancelledIdsBuilder.build(); ImmutableSet<Long> alreadyCancelledIds = alreadyCancelledIdsBuilder.build();
if (!alreadyCancelledIds.isEmpty()) { if (!alreadyCancelledIds.isEmpty()) {
System.out.printf( printStream.printf(
"The following BillingEvent IDs were already cancelled: %s\n", alreadyCancelledIds); "The following BillingEvent IDs were already cancelled: %s\n", alreadyCancelledIds);
} }
} }
@ -96,7 +96,7 @@ public class CreateCancellationsForBillingEventsCommand extends ConfirmingComman
tm().transact( tm().transact(
() -> { () -> {
if (alreadyCancelled(billingEvent)) { if (alreadyCancelled(billingEvent)) {
System.out.printf( printStream.printf(
"BillingEvent %d already cancelled, this is unexpected.\n", "BillingEvent %d already cancelled, this is unexpected.\n",
billingEvent.getId()); billingEvent.getId());
return 0; return 0;
@ -111,7 +111,7 @@ public class CreateCancellationsForBillingEventsCommand extends ConfirmingComman
.setReason(BillingBase.Reason.ERROR) .setReason(BillingBase.Reason.ERROR)
.setTargetId(billingEvent.getTargetId()) .setTargetId(billingEvent.getTargetId())
.build()); .build());
System.out.printf( printStream.printf(
"Added BillingCancellation for BillingEvent with ID %d\n", "Added BillingCancellation for BillingEvent with ID %d\n",
billingEvent.getId()); billingEvent.getId());
return 1; return 1;

View file

@ -198,7 +198,7 @@ public abstract class CommandTestCase<C extends Command> {
} }
void assertInStderr(String... expected) { void assertInStderr(String... expected) {
String stderror = new String(stderr.toByteArray(), UTF_8); String stderror = getStderrAsString();
for (String line : expected) { for (String line : expected) {
assertThat(stderror).contains(line); assertThat(stderror).contains(line);
} }

View file

@ -38,6 +38,7 @@ class CreateDomainCommandTest extends EppToolCommandTestCase<CreateDomainCommand
@BeforeEach @BeforeEach
void beforeEach() { void beforeEach() {
command.passwordGenerator = new DeterministicStringGenerator("abcdefghijklmnopqrstuvwxyz"); command.passwordGenerator = new DeterministicStringGenerator("abcdefghijklmnopqrstuvwxyz");
command.printStream = System.out;
} }
@Test @Test

View file

@ -68,6 +68,7 @@ class CreateRegistrarCommandTest extends CommandTestCase<CreateRegistrarCommand>
2048, 2048,
ImmutableSet.of("secp256r1", "secp384r1"), ImmutableSet.of("secp256r1", "secp384r1"),
fakeClock); fakeClock);
command.printStream = System.out;
} }
@Test @Test

View file

@ -37,6 +37,7 @@ class CreateRegistrarGroupsCommandTest extends CommandTestCase<CreateRegistrarGr
@Test @Test
void test_createGroupsForTwoRegistrars() throws Exception { void test_createGroupsForTwoRegistrars() throws Exception {
command.printStream = System.out;
runCommandForced("NewRegistrar", "TheRegistrar"); runCommandForced("NewRegistrar", "TheRegistrar");
verify(connection) verify(connection)
.sendPostRequest( .sendPostRequest(

View file

@ -521,6 +521,7 @@ class CreateTldCommandTest extends CommandTestCase<CreateTldCommand> {
@Test @Test
void testSuccess_setCommonAndReservedListFromOtherTld_withOverride() throws Exception { void testSuccess_setCommonAndReservedListFromOtherTld_withOverride() throws Exception {
command.errorPrintStream = System.err;
runReservedListsTestOverride("common_abuse,tld_banned"); runReservedListsTestOverride("common_abuse,tld_banned");
String errMsg = String errMsg =
"Error overridden: The reserved list(s) tld_banned " "Error overridden: The reserved list(s) tld_banned "

View file

@ -53,6 +53,7 @@ class DeleteAllocationTokensCommandTest extends CommandTestCase<DeleteAllocation
preNot2 = persistToken("prefix8ZZZhs8", null, false); preNot2 = persistToken("prefix8ZZZhs8", null, false);
othrRed = persistToken("h97987sasdfhh", null, true); othrRed = persistToken("h97987sasdfhh", null, true);
othrNot = persistToken("asdgfho7HASDS", null, false); othrNot = persistToken("asdgfho7HASDS", null, false);
command.printStream = System.out;
} }
@Test @Test

View file

@ -37,6 +37,8 @@ class LoadTestCommandTest extends CommandTestCase<LoadTestCommand> {
command.setConnection(connection); command.setConnection(connection);
createTld("example"); createTld("example");
persistNewRegistrar("acme", "ACME", Registrar.Type.REAL, 99L); persistNewRegistrar("acme", "ACME", Registrar.Type.REAL, 99L);
command.printStream = System.out;
command.errorPrintStream = System.err;
} }
@Test @Test

View file

@ -50,6 +50,7 @@ class LockDomainCommandTest extends CommandTestCase<LockDomainCommand> {
new DeterministicStringGenerator(Alphabets.BASE_58), new DeterministicStringGenerator(Alphabets.BASE_58),
"adminreg", "adminreg",
new CloudTasksHelper(fakeClock).getTestCloudTasksUtils()); new CloudTasksHelper(fakeClock).getTestCloudTasksUtils());
command.printStream = System.out;
} }
@Test @Test

View file

@ -61,6 +61,7 @@ class UniformRapidSuspensionCommandTest
ImmutableSet.of( ImmutableSet.of(
DomainDsData.create(1, 2, 3, new HexBinaryAdapter().unmarshal("dead")), DomainDsData.create(1, 2, 3, new HexBinaryAdapter().unmarshal("dead")),
DomainDsData.create(4, 5, 6, new HexBinaryAdapter().unmarshal("beef"))); DomainDsData.create(4, 5, 6, new HexBinaryAdapter().unmarshal("beef")));
command.printStream = System.out;
} }
private void persistDomainWithHosts( private void persistDomainWithHosts(

View file

@ -53,6 +53,7 @@ class UnlockDomainCommandTest extends CommandTestCase<UnlockDomainCommand> {
new DeterministicStringGenerator(Alphabets.BASE_58), new DeterministicStringGenerator(Alphabets.BASE_58),
"adminreg", "adminreg",
new CloudTasksHelper(fakeClock).getTestCloudTasksUtils()); new CloudTasksHelper(fakeClock).getTestCloudTasksUtils());
command.printStream = System.out;
} }
private Domain persistLockedDomain(String domainName, String registrarId) { private Domain persistLockedDomain(String domainName, String registrarId) {

View file

@ -55,6 +55,7 @@ public class UnrenewDomainCommandTest extends CommandTestCase<UnrenewDomainComma
createTld("tld"); createTld("tld");
fakeClock.setTo(DateTime.parse("2016-12-06T13:55:01Z")); fakeClock.setTo(DateTime.parse("2016-12-06T13:55:01Z"));
command.clock = fakeClock; command.clock = fakeClock;
command.printStream = System.out;
} }
@Test @Test
@ -178,6 +179,7 @@ public class UnrenewDomainCommandTest extends CommandTestCase<UnrenewDomainComma
@Test @Test
void test_varietyOfInvalidDomains_displaysErrors() { void test_varietyOfInvalidDomains_displaysErrors() {
command.errorPrintStream = System.err;
DateTime now = fakeClock.nowUtc(); DateTime now = fakeClock.nowUtc();
persistResource( persistResource(
DatabaseHelper.newDomain("deleting.tld") DatabaseHelper.newDomain("deleting.tld")

View file

@ -1048,6 +1048,7 @@ class UpdateTldCommandTest extends CommandTestCase<UpdateTldCommand> {
@Test @Test
void testSuccess_setCommonAndReservedListFromOtherTld_withOverride() throws Exception { void testSuccess_setCommonAndReservedListFromOtherTld_withOverride() throws Exception {
command.errorPrintStream = System.err;
runReservedListsTestOverride("common_abuse,tld_banned"); runReservedListsTestOverride("common_abuse,tld_banned");
String errMsg = String errMsg =
"Error overridden: The reserved list(s) tld_banned " "Error overridden: The reserved list(s) tld_banned "

View file

@ -34,6 +34,7 @@ import google.registry.model.reporting.HistoryEntryDao;
import google.registry.persistence.VKey; import google.registry.persistence.VKey;
import google.registry.testing.DatabaseHelper; import google.registry.testing.DatabaseHelper;
import google.registry.tools.CommandTestCase; import google.registry.tools.CommandTestCase;
import java.io.PrintStream;
import org.joda.money.CurrencyUnit; import org.joda.money.CurrencyUnit;
import org.joda.money.Money; import org.joda.money.Money;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
@ -59,6 +60,7 @@ public class CreateCancellationsForBillingEventsCommandTest
fakeClock.nowUtc(), fakeClock.nowUtc(),
fakeClock.nowUtc().plusYears(2)); fakeClock.nowUtc().plusYears(2));
billingEventToCancel = createBillingEvent(); billingEventToCancel = createBillingEvent();
command.printStream = System.out;
} }
@Test @Test
@ -97,8 +99,10 @@ public class CreateCancellationsForBillingEventsCommandTest
@Test @Test
void testAlreadyCancelled() throws Exception { void testAlreadyCancelled() throws Exception {
// multiple runs / cancellations should be a no-op // multiple runs / cancellations should be a no-op
command.printStream = new PrintStream(tmpDir.resolve("test.txt").toFile());
runCommandForced(String.valueOf(billingEventToCancel.getId())); runCommandForced(String.valueOf(billingEventToCancel.getId()));
assertBillingEventCancelled(); assertBillingEventCancelled();
command.printStream = System.out;
runCommandForced(String.valueOf(billingEventToCancel.getId())); runCommandForced(String.valueOf(billingEventToCancel.getId()));
assertBillingEventCancelled(); assertBillingEventCancelled();
assertThat(DatabaseHelper.loadAllOf(BillingCancellation.class)).hasSize(1); assertThat(DatabaseHelper.loadAllOf(BillingCancellation.class)).hasSize(1);