Added validate-config subcommand (#2994)

* Remove benchmark from workflow (#2827)

Remove benchmark from workflow

Signed-off-by: Antony Denyer <git@antonydenyer.co.uk>
Co-authored-by: Sally MacFarlane <sally.macfarlane@consensys.net>
Signed-off-by: Min Song <minsong@splunk.com>

* Added subcommand for validate-config

Signed-off-by: Min Song <ms2597@cornell.edu>
Signed-off-by: Min Song <minsong@splunk.com>

* formatting

Signed-off-by: Sally MacFarlane <sally.macfarlane@consensys.net>

* use the main TomlConfigFile provider

* inject commandLine

Signed-off-by: Sally MacFarlane <sally.macfarlane@consensys.net>

Co-authored-by: Antony Denyer <git@antonydenyer.co.uk>
Co-authored-by: Min Song <minsong@splunk.com>
Co-authored-by: Min Song <ms2597@cornell.edu>
pull/3034/head
Sally MacFarlane 3 years ago committed by GitHub
parent 3658ef034e
commit 4f44863694
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 3
      CHANGELOG.md
  2. 4
      besu/src/main/java/org/hyperledger/besu/cli/BesuCommand.java
  3. 70
      besu/src/main/java/org/hyperledger/besu/cli/subcommands/ValidateConfigSubCommand.java
  4. 2
      besu/src/main/java/org/hyperledger/besu/cli/util/TomlConfigFileDefaultProvider.java
  5. 90
      besu/src/test/java/org/hyperledger/besu/cli/ValidateConfigSubCommandTest.java

@ -4,6 +4,7 @@
### Additions and Improvements
- Add discovery options to genesis file [#2944](https://github.com/hyperledger/besu/pull/2944)
- Add validate-config subcommand to perform basic syntax validation of TOML config [#2994](https://github.com/hyperledger/besu/pull/2994)
### Bug Fixes
@ -13,7 +14,7 @@
### Additions and Improvements
- Add CLI autocomplete scripts. [#2854](https://github.com/hyperledger/besu/pull/2854)
- Added support for PKCS11 keystore on PKI Block Creation. [#2865](https://github.com/hyperledger/besu/pull/2865)
- Add support for PKCS11 keystore on PKI Block Creation. [#2865](https://github.com/hyperledger/besu/pull/2865)
- Optimize EVM Memory for MLOAD Operations [#2917](https://github.com/hyperledger/besu/pull/2917)
- Upgrade CircleCI OpenJDK docker image to version 11.0.12. [#2928](https://github.com/hyperledger/besu/pull/2928)
- Update JDK 11 to latest version in Besu Docker images. [#2925](https://github.com/hyperledger/besu/pull/2925)

@ -71,6 +71,7 @@ import org.hyperledger.besu.cli.presynctasks.PrivateDatabaseMigrationPreSyncTask
import org.hyperledger.besu.cli.subcommands.PasswordSubCommand;
import org.hyperledger.besu.cli.subcommands.PublicKeySubCommand;
import org.hyperledger.besu.cli.subcommands.RetestethSubCommand;
import org.hyperledger.besu.cli.subcommands.ValidateConfigSubCommand;
import org.hyperledger.besu.cli.subcommands.blocks.BlocksSubCommand;
import org.hyperledger.besu.cli.subcommands.operator.OperatorSubCommand;
import org.hyperledger.besu.cli.subcommands.rlp.RLPSubCommand;
@ -1256,6 +1257,9 @@ public class BesuCommand implements DefaultCommandValues, Runnable {
RLPSubCommand.COMMAND_NAME, new RLPSubCommand(resultHandler.out(), in));
commandLine.addSubcommand(
OperatorSubCommand.COMMAND_NAME, new OperatorSubCommand(resultHandler.out()));
commandLine.addSubcommand(
ValidateConfigSubCommand.COMMAND_NAME,
new ValidateConfigSubCommand(commandLine, resultHandler.out()));
final String generateCompletionSubcommandName = "generate-completion";
commandLine.addSubcommand(
generateCompletionSubcommandName, AutoComplete.GenerateCompletion.class);

@ -0,0 +1,70 @@
/*
* Copyright contributors to Hyperledger Besu.
*
* 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.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.cli.subcommands;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.hyperledger.besu.cli.subcommands.ValidateConfigSubCommand.COMMAND_NAME;
import org.hyperledger.besu.cli.BesuCommand;
import org.hyperledger.besu.cli.DefaultCommandValues;
import org.hyperledger.besu.cli.util.TomlConfigFileDefaultProvider;
import java.io.PrintStream;
import java.nio.file.Path;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.ParentCommand;
@Command(
name = COMMAND_NAME,
description = "This command provides basic Besu config validation (syntax only).",
mixinStandardHelpOptions = true)
public class ValidateConfigSubCommand implements Runnable {
public static final String COMMAND_NAME = "validate-config";
@Option(
names = "--config-file",
paramLabel = DefaultCommandValues.MANDATORY_PATH_FORMAT_HELP,
description = "Path to Besu config file")
private final Path dataPath = DefaultCommandValues.getDefaultBesuDataPath(this);
@SuppressWarnings("unused")
@ParentCommand
private BesuCommand parentCommand;
final PrintStream out;
final CommandLine commandLine;
public ValidateConfigSubCommand(final CommandLine commandLine, final PrintStream out) {
this.out = out;
this.commandLine = commandLine;
}
@Override
public void run() {
checkNotNull(parentCommand);
try {
new TomlConfigFileDefaultProvider(commandLine, dataPath.toFile()).loadConfigurationFromFile();
} catch (Exception e) {
this.out.print(e);
return;
}
this.out.print(
"TOML config file is valid on basic inspection. Further dependencies between related options are checked when Besu starts.");
}
}

@ -138,7 +138,7 @@ public class TomlConfigFileDefaultProvider implements IDefaultValueProvider {
commandLine, String.format("Unable to read TOML configuration file %s", configFile));
}
private void loadConfigurationFromFile() {
public void loadConfigurationFromFile() {
if (result == null) {
try {

@ -0,0 +1,90 @@
/*
* Copyright contributors to Hyperledger Besu.
*
* 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.
*
* SPDX-License-Identifier: Apache-2.0
*/
package org.hyperledger.besu.cli;
import static org.assertj.core.api.Assertions.assertThat;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import com.google.common.io.Resources;
import org.junit.Test;
import picocli.CommandLine.Model.CommandSpec;
public class ValidateConfigSubCommandTest extends CommandTestAbstract {
private static final String EXPECTED_PUBLIC_KEY_USAGE =
"Usage: besu validate-config [-hV] [--config-file=<PATH>]"
+ System.lineSeparator()
+ "This command provides basic Besu config validation (syntax only)."
+ System.lineSeparator()
+ " --config-file=<PATH> Path to Besu config file"
+ System.lineSeparator()
+ " -h, --help Show this help message and exit."
+ System.lineSeparator()
+ " -V, --version Print version information and exit."
+ System.lineSeparator();
private static final String VALIDATE_CONFIG_SUBCOMMAND_NAME = "validate-config";
@Test
public void validateConfigSubCommandExists() {
CommandSpec spec = parseCommand().getSpec();
assertThat(spec.subcommands()).containsKeys(VALIDATE_CONFIG_SUBCOMMAND_NAME);
assertThat(commandOutput.toString()).isEmpty();
assertThat(commandErrorOutput.toString()).isEmpty();
}
@Test
public void callingValidateConfigSubCommandHelpMustDisplayUsage() {
parseCommand(VALIDATE_CONFIG_SUBCOMMAND_NAME, "--help");
assertThat(commandOutput.toString()).startsWith(EXPECTED_PUBLIC_KEY_USAGE);
assertThat(commandErrorOutput.toString()).isEmpty();
}
@Test
public void callingValidateConfigSubCommandWithNonExistentMustDisplayError() {
parseCommand(VALIDATE_CONFIG_SUBCOMMAND_NAME, "--config-file", "/non/existent/file");
assertThat(commandOutput.toString())
.contains("Unable to read TOML configuration, file not found.");
assertThat(commandErrorOutput.toString()).isEmpty();
}
@Test
public void callingValidateConfigSubCommandWithInvalidFileMustDisplayError() throws IOException {
final Path invalidToml = Files.createTempFile("invalid", "toml");
Files.writeString(invalidToml, "xyz=");
invalidToml.toFile().deleteOnExit();
parseCommand(VALIDATE_CONFIG_SUBCOMMAND_NAME, "--config-file", invalidToml.toString());
assertThat(commandOutput.toString()).contains("Invalid TOML configuration");
assertThat(commandErrorOutput.toString()).isEmpty();
}
@Test
public void callingValidateConfigSubCommandWithValidTomlFileSucceeds() throws IOException {
final URL configFile = this.getClass().getResource("/everything_config.toml");
final Path validToml = Files.createTempFile("valid", "toml");
Files.write(validToml, Resources.toByteArray(configFile));
validToml.toFile().deleteOnExit();
parseCommand(VALIDATE_CONFIG_SUBCOMMAND_NAME, "--config-file", validToml.toString());
assertThat(commandOutput.toString()).startsWith("TOML config file is valid");
assertThat(commandErrorOutput.toString()).isEmpty();
}
}
Loading…
Cancel
Save