Skip to content

Commit

Permalink
Improved the CLI tests. Moved generated content to a folder in target.
Browse files Browse the repository at this point in the history
  • Loading branch information
david-waltermire committed May 28, 2024
1 parent 92bb9bc commit 4bf19ac
Show file tree
Hide file tree
Showing 17 changed files with 137 additions and 75 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,7 @@

import com.google.auto.service.AutoService;

import gov.nist.secauto.metaschema.cli.commands.GenerateSchemaCommand;
import gov.nist.secauto.metaschema.cli.commands.ValidateContentUsingModuleCommand;
import gov.nist.secauto.metaschema.cli.commands.ValidateModuleCommand;
import gov.nist.secauto.metaschema.cli.commands.MetaschemaCommands;
import gov.nist.secauto.metaschema.cli.processor.command.AbstractParentCommand;
import gov.nist.secauto.metaschema.cli.processor.command.ICommand;

Expand All @@ -41,9 +39,7 @@ public class MetaschemaCommand

public MetaschemaCommand() {
super(true);
addCommandHandler(new GenerateSchemaCommand());
addCommandHandler(new ValidateModuleCommand());
addCommandHandler(new ValidateContentUsingModuleCommand());
MetaschemaCommands.COMMANDS.forEach(this::addCommandHandler);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,49 +274,58 @@ protected ExitStatus executeCommand(
return ExitCode.IO_ERROR.exit().withThrowable(ex);
}
Object object = document.getValue();
if (object == null) {
return ExitCode.INVALID_ARGUMENTS.exitMessage("The target profile contained no data");
}

if (object instanceof Catalog) {
// this is a catalog
return ExitCode.INVALID_ARGUMENTS.exitMessage("The target file is already a catalog");
} else if (object instanceof Profile) {
// this is a profile
URI sourceUri = ObjectUtils.notNull(source.toUri());
return ExitCode.INVALID_ARGUMENTS.exitMessage("The target is already a catalog");
}

DynamicContext dynamicContext = new DynamicContext(
StaticContext.builder()
.baseUri(sourceUri)
.defaultModelNamespace(document.getNamespace())
.build());
dynamicContext.setDocumentLoader(loader);
ProfileResolver resolver = new ProfileResolver();
resolver.setDynamicContext(dynamicContext);
if (!(object instanceof Profile)) {
// this is something else
return ExitCode.INVALID_ARGUMENTS.exitMessage("The target is not a profile");
}

IDocumentNodeItem resolvedProfile;
try {
resolvedProfile = resolver.resolve(document);
} catch (IOException | ProfileResolutionException ex) {
return ExitCode.PROCESSING_ERROR
.exitMessage(
String.format("Unable to resolve profile '%s'. %s", document.getDocumentUri(), ex.getMessage()))
.withThrowable(ex);
}
// this is a profile
URI sourceUri = ObjectUtils.notNull(source.toUri());

// DefaultConstraintValidator validator = new
// DefaultConstraintValidator(dynamicContext);
// ((IBoundXdmNodeItem)resolvedProfile).validate(validator);
// validator.finalizeValidation();
DynamicContext dynamicContext = new DynamicContext(
StaticContext.builder()
.baseUri(sourceUri)
.defaultModelNamespace(document.getNamespace())
.build());
dynamicContext.setDocumentLoader(loader);
ProfileResolver resolver = new ProfileResolver();
resolver.setDynamicContext(dynamicContext);

ISerializer<Catalog> serializer
= OscalBindingContext.instance().newSerializer(toFormat, Catalog.class);
try {
if (destination == null) {
@SuppressWarnings({ "resource", "PMD.CloseResource" }) PrintStream stdOut = ObjectUtils.notNull(System.out);
serializer.serialize((Catalog) INodeItem.toValue(resolvedProfile), stdOut);
} else {
serializer.serialize((Catalog) INodeItem.toValue(resolvedProfile), destination);
}
} catch (IOException ex) {
return ExitCode.PROCESSING_ERROR.exit().withThrowable(ex);
IDocumentNodeItem resolvedProfile;
try {
resolvedProfile = resolver.resolve(document);
} catch (IOException | ProfileResolutionException ex) {
return ExitCode.PROCESSING_ERROR
.exitMessage(
String.format("Unable to resolve profile '%s'. %s", document.getDocumentUri(), ex.getMessage()))
.withThrowable(ex);
}

// DefaultConstraintValidator validator = new
// DefaultConstraintValidator(dynamicContext);
// ((IBoundXdmNodeItem)resolvedProfile).validate(validator);
// validator.finalizeValidation();

ISerializer<Catalog> serializer
= OscalBindingContext.instance().newSerializer(toFormat, Catalog.class);
try {
if (destination == null) {
@SuppressWarnings({ "resource", "PMD.CloseResource" }) PrintStream stdOut = ObjectUtils.notNull(System.out);
serializer.serialize((Catalog) INodeItem.toValue(resolvedProfile), stdOut);
} else {
serializer.serialize((Catalog) INodeItem.toValue(resolvedProfile), destination);
}
} catch (IOException ex) {
return ExitCode.PROCESSING_ERROR.exit().withThrowable(ex);
}
return ExitCode.OK.exit();
}
Expand Down
123 changes: 90 additions & 33 deletions src/test/java/gov/nist/secauto/oscal/tools/cli/core/CLITest.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,18 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;

import gov.nist.secauto.metaschema.binding.io.Format;
import gov.nist.secauto.metaschema.cli.processor.ExitCode;
import gov.nist.secauto.metaschema.cli.processor.ExitStatus;
import gov.nist.secauto.metaschema.core.util.ObjectUtils;
import gov.nist.secauto.metaschema.databind.io.Format;
import gov.nist.secauto.oscal.lib.profile.resolver.ProfileResolutionException;

import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
Expand All @@ -61,13 +64,26 @@ void evaluateResult(@NonNull ExitStatus status, @NonNull ExitCode expectedCode,
@NonNull Class<? extends Throwable> thrownClass) {
status.generateMessage(true);
Throwable thrown = status.getThrowable();
assert thrown != null;
assertAll(
() -> assertEquals(expectedCode, status.getExitCode(), "exit code mismatch"),
() -> assertEquals(thrownClass, thrown.getClass(), "expected Throwable mismatch"));
() -> assertEquals(
thrownClass,
thrown == null ? null : thrown.getClass(),
"Throwable mismatch"));
}

private static Stream<Arguments> providesValues() {
private static String generateOutputPath(@NonNull Path source, @NonNull Format targetFormat) throws IOException {
String filename = ObjectUtils.notNull(source.getFileName()).toString();

int pos = filename.lastIndexOf('.');
filename = filename.substring(0, pos) + "_converted" + targetFormat.getDefaultExtension();

Path dir = Files.createDirectories(Path.of("target/oscal-cli-convert"));

return dir.resolve(filename).toString();
}

private static Stream<Arguments> providesValues() throws IOException {
final String[] commands = { "ap", "ar", "catalog", "component-definition", "profile", "poam", "ssp" };
final Map<Format, List<Format>> formatEntries = Map.of(
Format.XML, Arrays.asList(Format.JSON, Format.YAML),
Expand All @@ -76,42 +92,83 @@ private static Stream<Arguments> providesValues() {
List<Arguments> values = new ArrayList<>();

values.add(Arguments.of(new String[] { "--version" }, ExitCode.OK, null));
// TODO: Test all data formats once usnistgov/oscal-cli#216 fix merged.
Path path = Paths.get("src/test/resources/cli/example_profile_invalid" + Format.XML.getDefaultExtension());
values.add(
Arguments.of(new String[] { "profile", "resolve", "--to=" + Format.XML.name().toLowerCase(), path.toString() },
ExitCode.PROCESSING_ERROR, ProfileResolutionException.class));

for (String cmd : commands) {
// test helps
values.add(Arguments.of(new String[] { cmd, "validate", "-h" }, ExitCode.OK, null));
// TODO: Update when usnistgov/oscal-cli#210 fix merged.
values.add(Arguments.of(new String[] { cmd, "convert", "-h" }, ExitCode.INVALID_COMMAND, null));
values.add(Arguments.of(new String[] { cmd, "convert", "-h" }, ExitCode.OK, null));

for (Format format : Format.values()) {
path = Paths.get("src/test/resources/cli/example_" + cmd + "_invalid" + format.getDefaultExtension());
values.add(Arguments.of(new String[] { cmd, "validate", path.toString() }, ExitCode.FAIL, null));
path = Paths.get("src/test/resources/cli/example_" + cmd + "_valid" + format.getDefaultExtension());
values.add(Arguments.of(new String[] { cmd, "validate", path.toString() }, ExitCode.OK, null));
path = Paths.get("src/test/resources/cli/example_profile_valid" + format.getDefaultExtension());
List<Format> targetFormats = formatEntries.get(format);
for (Format targetFormat : targetFormats) {
path = Paths.get("src/test/resources/cli/example_" + cmd + "_valid" + format.getDefaultExtension());
String outputPath = path.toString().replace(format.getDefaultExtension(),
"_converted" + targetFormat.getDefaultExtension());
values.add(Arguments.of(new String[] { cmd, "convert", "--to=" + targetFormat.name().toLowerCase(),
path.toString(), outputPath, "--overwrite" }, ExitCode.OK, null));
String sourceExtension = format.getDefaultExtension();
values.add(
Arguments.of(
new String[] {
cmd,
"validate",
Paths.get("src/test/resources/cli/example_" + cmd + "_invalid" + sourceExtension).toString()
},
ExitCode.FAIL,
null));
values.add(
Arguments.of(
new String[] {
cmd,
"validate",
Paths.get("src/test/resources/cli/example_" + cmd + "_valid" + sourceExtension).toString()
},
ExitCode.OK,
null));

for (Format targetFormat : formatEntries.get(format)) {
Path path = Paths.get("src/test/resources/cli/example_" + cmd + "_valid" + sourceExtension);
values.add(
Arguments.of(
new String[] {
cmd,
"convert",
"--to=" + targetFormat.name().toLowerCase(),
path.toString(),
generateOutputPath(path, targetFormat),
"--overwrite"
},
ExitCode.OK,
null));

// TODO: Update when usnistgov/oscal#217 fix merged.
path = Paths.get("src/test/resources/cli/example_" + cmd + "_invalid" + format.getDefaultExtension());
outputPath = path.toString().replace(format.getDefaultExtension(),
"_converted" + targetFormat.getDefaultExtension());
values.add(Arguments.of(new String[] { cmd, "convert", "--to=" + targetFormat.name().toLowerCase(),
path.toString(), outputPath, "--overwrite" }, ExitCode.OK, null));
path = Paths.get("src/test/resources/cli/example_" + cmd + "_invalid" + sourceExtension);
values.add(
Arguments.of(
new String[] {
cmd,
"convert",
"--to=" + targetFormat.name().toLowerCase(),
path.toString(),
generateOutputPath(path, targetFormat),
"--overwrite"
},
ExitCode.OK,
null));
}
if (cmd == "profile") {
path = Paths.get("src/test/resources/cli/example_profile_valid" + format.getDefaultExtension());
values
.add(Arguments.of(new String[] { cmd, "resolve", "--to=" + format.name().toLowerCase(), path.toString() },
ExitCode.OK, null));
values.add(
Arguments.of(
new String[] {
cmd,
"resolve",
"--to=" + format.name().toLowerCase(),
Paths.get("src/test/resources/cli/example_profile_valid" + sourceExtension).toString()
},
ExitCode.OK,
null));
values.add(
Arguments.of(
new String[] {
"profile",
"resolve",
"--to=" + format.name().toLowerCase(),
Paths.get("src/test/resources/cli/example_profile_invalid" + sourceExtension).toString()
},
ExitCode.PROCESSING_ERROR,
ProfileResolutionException.class));
}
}
}
Expand Down
File renamed without changes.
File renamed without changes.

0 comments on commit 4bf19ac

Please sign in to comment.