Create a new app to hold GenerateSqlSchemaCommand (#409)

* Create a new app to hold GenerateSqlSchemaCommand

GenerateSqlSchemaCommand starts postgresql using testcontainer.
This makes junit etc a runtime dependency, allowing them to get
into release artifacts.

By moving this command to a separate tool, we can remove junit
etc as compile/runtime dependency.
This commit is contained in:
Weimin Yu 2019-12-13 16:05:35 -05:00 committed by GitHub
parent 1143b25391
commit 6aaf081489
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
60 changed files with 1163 additions and 154 deletions

View file

@ -60,7 +60,6 @@ public final class RegistryTool {
.put("generate_dns_report", GenerateDnsReportCommand.class)
.put("generate_escrow_deposit", GenerateEscrowDepositCommand.class)
.put("generate_lordn", GenerateLordnCommand.class)
.put("generate_sql_schema", GenerateSqlSchemaCommand.class)
.put("generate_zone_files", GenerateZoneFilesCommand.class)
.put("get_allocation_token", GetAllocationTokenCommand.class)
.put("get_claims_list", GetClaimsListCommand.class)

View file

@ -0,0 +1,37 @@
// Copyright 2019 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package google.registry.tools;
import com.google.common.collect.ImmutableMap;
/** Entry point of Nomulus development commands. */
public class DevTool {
/**
* Available commands.
*
* <p><b>Note:</b> If changing the command-line name of any commands below, remember to resolve
* any invocations in scripts (e.g. PDT, ICANN reporting).
*/
public static final ImmutableMap<String, Class<? extends Command>> COMMAND_MAP =
ImmutableMap.of("generate_sql_schema", GenerateSqlSchemaCommand.class);
public static void main(String[] args) throws Exception {
RegistryToolEnvironment.parseFromArgs(args).setup();
try (RegistryCli cli = new RegistryCli("devtool", COMMAND_MAP)) {
cli.run(args);
}
}
}

View file

@ -31,7 +31,7 @@ import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
import org.testcontainers.containers.PostgreSQLContainer;
/** Unit tests for {@link google.registry.tools.GenerateSqlSchemaCommand}. */
/** Unit tests for {@link GenerateSqlSchemaCommand}. */
@RunWith(JUnit4.class)
public class GenerateSqlSchemaCommandTest extends CommandTestCase<GenerateSqlSchemaCommand> {

View file

@ -21,24 +21,29 @@ import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import com.beust.jcommander.Parameters;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.common.collect.Sets.SetView;
import com.google.common.reflect.ClassPath;
import com.google.common.reflect.ClassPath.ClassInfo;
import com.google.common.truth.Expect;
import google.registry.testing.SystemPropertyRule;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.Map;
import junitparams.JUnitParamsRunner;
import junitparams.naming.TestCaseName;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
/** Unit tests for {@link RegistryTool}. */
@RunWith(JUnit4.class)
public class RegistryToolTest {
/** Unit tests for {@link RegistryTool} and {@link DevTool}. */
@RunWith(JUnitParamsRunner.class)
public class ToolsTest {
@Rule
public final Expect expect = Expect.create();
@ -50,28 +55,39 @@ public class RegistryToolTest {
RegistryToolEnvironment.UNITTEST.setup(systemPropertyRule);
}
@Test
public void test_commandMap_namesAreInAlphabeticalOrder() {
assertThat(RegistryTool.COMMAND_MAP.keySet()).isInStrictOrder();
}
@Test
public void test_commandMap_includesAllCommands() throws Exception {
ImmutableSet<?> commandMapClasses = ImmutableSet.copyOf(RegistryTool.COMMAND_MAP.values());
ImmutableSet<?> registryToolCommands = ImmutableSet.copyOf(RegistryTool.COMMAND_MAP.values());
ImmutableSet<?> devToolCommands = ImmutableSet.copyOf(DevTool.COMMAND_MAP.values());
assertWithMessage("RegistryTool and DevTool have overlapping commands")
.that(Sets.intersection(registryToolCommands, devToolCommands))
.isEmpty();
SetView<?> allCommandsInTools = Sets.union(registryToolCommands, devToolCommands);
ImmutableSet<?> classLoaderClasses = getAllCommandClasses();
// Not using plain old containsExactlyElementsIn() since it produces a huge unreadable blob.
assertWithMessage("command classes in RegistryTool.COMMAND_MAP but not found by class loader")
.that(Sets.difference(commandMapClasses, classLoaderClasses))
assertWithMessage("command classes in COMMAND_MAP but not found by class loader")
.that(Sets.difference(allCommandsInTools, classLoaderClasses))
.isEmpty();
assertWithMessage("command classes found by class loader but not in RegistryTool.COMMAND_MAP")
.that(Sets.difference(classLoaderClasses, commandMapClasses))
assertWithMessage("command classes found by class loader but not in COMMAND_MAP")
.that(Sets.difference(classLoaderClasses, allCommandsInTools))
.isEmpty();
}
@Test
public void test_commandMap_namesAreDerivedFromClassNames() {
@junitparams.Parameters(method = "getToolCommandMap")
@TestCaseName("{method}_{0}")
public void test_commandMap_namesAreInAlphabeticalOrder(
String toolName, ImmutableMap<String, Class<? extends Command>> commandMap) {
assertThat(commandMap.keySet()).isInStrictOrder();
}
@Test
@junitparams.Parameters(method = "getToolCommandMap")
@TestCaseName("{method}_{0}")
public void test_commandMap_namesAreDerivedFromClassNames(
String toolName, ImmutableMap<String, Class<? extends Command>> commandMap) {
for (Map.Entry<String, ? extends Class<? extends Command>> commandEntry :
RegistryTool.COMMAND_MAP.entrySet()) {
commandMap.entrySet()) {
String className = commandEntry.getValue().getSimpleName();
expect.that(commandEntry.getKey())
// JCommander names should match the class name, up to "Command" and case formatting.
@ -80,15 +96,25 @@ public class RegistryToolTest {
}
@Test
public void test_commandMap_allCommandsHaveDescriptions() {
@junitparams.Parameters(method = "getToolCommandMap")
@TestCaseName("{method}_{0}")
public void test_commandMap_allCommandsHaveDescriptions(
String toolName, ImmutableMap<String, Class<? extends Command>> commandMap) {
for (Map.Entry<String, ? extends Class<? extends Command>> commandEntry :
RegistryTool.COMMAND_MAP.entrySet()) {
commandMap.entrySet()) {
Parameters parameters = commandEntry.getValue().getAnnotation(Parameters.class);
assertThat(parameters).isNotNull();
assertThat(parameters.commandDescription()).isNotEmpty();
}
}
@SuppressWarnings("unused")
private List<List<Object>> getToolCommandMap() {
return ImmutableList.of(
ImmutableList.of("RegistryTool", RegistryTool.COMMAND_MAP),
ImmutableList.of("DevTool", DevTool.COMMAND_MAP));
}
/**
* Gets the set of all non-abstract classes implementing the {@link Command} interface (abstract
* class and interface subtypes of Command aren't expected to have cli commands). Note that this