Add class to fork and exec kati, based on the commandline option given.
Test: m product-config-test && java -jar out/host/linux-x86/testcases/product-config-test/product-config-test.jar Change-Id: I4706e32ff7ac4424b6835b94fef40a2c838f8492
This commit is contained in:
@@ -30,7 +30,7 @@ import java.util.Map;
|
|||||||
* <b>Naming Convention:</b>
|
* <b>Naming Convention:</b>
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li>ERROR_ for Categories with isLevelSettable false and Level.ERROR
|
* <li>ERROR_ for Categories with isLevelSettable false and Level.ERROR
|
||||||
* <li>WARNING_ for Categories with isLevelSettable false and default WARNING or HIDDEN
|
* <li>WARNING_ for Categories with isLevelSettable true and default WARNING or HIDDEN
|
||||||
* <li>Don't have isLevelSettable true and not ERROR. (The constructor asserts this).
|
* <li>Don't have isLevelSettable true and not ERROR. (The constructor asserts this).
|
||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
@@ -42,4 +42,7 @@ public class Errors extends ErrorReporter {
|
|||||||
public final Category WARNING_UNKNOWN_COMMAND_LINE_ERROR = new Category(2, true, Level.HIDDEN,
|
public final Category WARNING_UNKNOWN_COMMAND_LINE_ERROR = new Category(2, true, Level.HIDDEN,
|
||||||
"Passing unknown errors on the command line. Hidden by default for\n"
|
"Passing unknown errors on the command line. Hidden by default for\n"
|
||||||
+ "forward compatibility.");
|
+ "forward compatibility.");
|
||||||
|
|
||||||
|
public final Category ERROR_KATI = new Category(3, false, Level.ERROR,
|
||||||
|
"Error executing or reading from Kati.");
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,43 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* 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 com.android.build.config;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public interface KatiCommand {
|
||||||
|
public static class KatiException extends Exception {
|
||||||
|
private String mStderr;
|
||||||
|
|
||||||
|
public KatiException(List<String> cmd, String stderr) {
|
||||||
|
super("Error running kati: " + Arrays.toString(cmd.toArray()));
|
||||||
|
mStderr = stderr;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getStderr() {
|
||||||
|
return mStderr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run kati directly. Returns stdout data.
|
||||||
|
*
|
||||||
|
* @throws KatiException if there is an error. KatiException will contain
|
||||||
|
* the stderr from the kati invocation.
|
||||||
|
*/
|
||||||
|
public String run(String[] args) throws KatiException;
|
||||||
|
}
|
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2020 The Android Open Source Project
|
||||||
|
*
|
||||||
|
* 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 com.android.build.config;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class KatiCommandImpl implements KatiCommand {
|
||||||
|
final Errors mErrors;
|
||||||
|
final Options mOptions;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runnable that consumes all of an InputStream until EOF, writes the contents
|
||||||
|
* into a StringBuilder, and then closes the stream.
|
||||||
|
*/
|
||||||
|
class OutputReader implements Runnable {
|
||||||
|
private final InputStream mStream;
|
||||||
|
private final StringBuilder mOutput;
|
||||||
|
|
||||||
|
OutputReader(InputStream stream, StringBuilder output) {
|
||||||
|
mStream = stream;
|
||||||
|
mOutput = output;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
final char[] buf = new char[16*1024];
|
||||||
|
final InputStreamReader reader = new InputStreamReader(mStream, StandardCharsets.UTF_8);
|
||||||
|
try {
|
||||||
|
int amt;
|
||||||
|
while ((amt = reader.read(buf, 0, buf.length)) >= 0) {
|
||||||
|
mOutput.append(buf, 0, amt);
|
||||||
|
}
|
||||||
|
} catch (IOException ex) {
|
||||||
|
mErrors.ERROR_KATI.add("Error reading from kati: " + ex.getMessage());
|
||||||
|
} finally {
|
||||||
|
try {
|
||||||
|
reader.close();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
// Close doesn't throw
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public KatiCommandImpl(Errors errors, Options options) {
|
||||||
|
mErrors = errors;
|
||||||
|
mOptions = options;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run kati directly. Returns stdout data.
|
||||||
|
*
|
||||||
|
* @throws KatiException if there is an error. KatiException will contain
|
||||||
|
* the stderr from the kati invocation.
|
||||||
|
*/
|
||||||
|
public String run(String[] args) throws KatiException {
|
||||||
|
final ArrayList<String> cmd = new ArrayList();
|
||||||
|
cmd.add(mOptions.getCKatiBin());
|
||||||
|
for (String arg: args) {
|
||||||
|
cmd.add(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
final ProcessBuilder builder = new ProcessBuilder(cmd);
|
||||||
|
builder.redirectOutput(ProcessBuilder.Redirect.PIPE);
|
||||||
|
builder.redirectError(ProcessBuilder.Redirect.PIPE);
|
||||||
|
|
||||||
|
Process process = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
process = builder.start();
|
||||||
|
} catch (IOException ex) {
|
||||||
|
throw new KatiException(cmd, "IOException running process: " + ex.getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
|
final StringBuilder stdout = new StringBuilder();
|
||||||
|
final Thread stdoutThread = new Thread(new OutputReader(process.getInputStream(), stdout),
|
||||||
|
"kati_stdout_reader");
|
||||||
|
stdoutThread.start();
|
||||||
|
|
||||||
|
final StringBuilder stderr = new StringBuilder();
|
||||||
|
final Thread stderrThread = new Thread(new OutputReader(process.getErrorStream(), stderr),
|
||||||
|
"kati_stderr_reader");
|
||||||
|
stderrThread.start();
|
||||||
|
|
||||||
|
int returnCode = waitForProcess(process);
|
||||||
|
joinThread(stdoutThread);
|
||||||
|
joinThread(stderrThread);
|
||||||
|
|
||||||
|
if (returnCode != 0) {
|
||||||
|
throw new KatiException(cmd, stderr.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return stdout.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap Process.waitFor() because it throws InterruptedException.
|
||||||
|
*/
|
||||||
|
private static int waitForProcess(Process proc) {
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
return proc.waitFor();
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap Thread.join() because it throws InterruptedException.
|
||||||
|
*/
|
||||||
|
private static void joinThread(Thread thread) {
|
||||||
|
while (true) {
|
||||||
|
try {
|
||||||
|
thread.join();
|
||||||
|
return;
|
||||||
|
} catch (InterruptedException ex) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@@ -47,7 +47,7 @@ public class Main {
|
|||||||
int exitCode = 0;
|
int exitCode = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Options options = Options.parse(errors, args);
|
Options options = Options.parse(errors, args, System.getenv());
|
||||||
if (errors.hadError()) {
|
if (errors.hadError()) {
|
||||||
Options.printHelp(System.err);
|
Options.printHelp(System.err);
|
||||||
System.err.println();
|
System.err.println();
|
||||||
@@ -62,7 +62,7 @@ public class Main {
|
|||||||
Options.printHelp(System.out);
|
Options.printHelp(System.out);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} catch (CommandException ex) {
|
} catch (CommandException | Errors.FatalException ex) {
|
||||||
// These are user errors, so don't show a stack trace
|
// These are user errors, so don't show a stack trace
|
||||||
exitCode = 1;
|
exitCode = 1;
|
||||||
} catch (Throwable ex) {
|
} catch (Throwable ex) {
|
||||||
|
@@ -17,6 +17,7 @@
|
|||||||
package com.android.build.config;
|
package com.android.build.config;
|
||||||
|
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.TreeMap;
|
import java.util.TreeMap;
|
||||||
|
|
||||||
public class Options {
|
public class Options {
|
||||||
@@ -27,19 +28,50 @@ public class Options {
|
|||||||
|
|
||||||
private Action mAction = Action.DEFAULT;
|
private Action mAction = Action.DEFAULT;
|
||||||
|
|
||||||
|
private String mProduct;
|
||||||
|
private String mVariant;
|
||||||
|
private String mOutDir;
|
||||||
|
private String mCKatiBin;
|
||||||
|
|
||||||
public Action getAction() {
|
public Action getAction() {
|
||||||
return mAction;
|
return mAction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getProduct() {
|
||||||
|
return mProduct;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getVariant() {
|
||||||
|
return mVariant;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getOutDir() {
|
||||||
|
return mOutDir != null ? mOutDir : "out";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getCKatiBin() {
|
||||||
|
return mCKatiBin;
|
||||||
|
}
|
||||||
|
|
||||||
public static void printHelp(PrintStream out) {
|
public static void printHelp(PrintStream out) {
|
||||||
out.println("usage: product_config");
|
out.println("usage: product_config");
|
||||||
out.println();
|
out.println();
|
||||||
out.println("OPTIONS");
|
out.println("REQUIRED FLAGS");
|
||||||
|
out.println(" --ckati_bin CKATI Kati binary to use.");
|
||||||
|
out.println();
|
||||||
|
out.println("OPTIONAL FLAGS");
|
||||||
out.println(" --hide ERROR_ID Suppress this error.");
|
out.println(" --hide ERROR_ID Suppress this error.");
|
||||||
out.println(" --error ERROR_ID Make this ERROR_ID a fatal error.");
|
out.println(" --error ERROR_ID Make this ERROR_ID a fatal error.");
|
||||||
out.println(" --help -h This message.");
|
out.println(" --help -h This message.");
|
||||||
out.println(" --warning ERROR_ID Make this ERROR_ID a warning.");
|
out.println(" --warning ERROR_ID Make this ERROR_ID a warning.");
|
||||||
out.println();
|
out.println();
|
||||||
|
out.println("REQUIRED ENVIRONMENT");
|
||||||
|
out.println(" TARGET_PRODUCT Product to build from lunch command.");
|
||||||
|
out.println(" TARGET_BUILD_VARIANT Build variant from lunch command.");
|
||||||
|
out.println();
|
||||||
|
out.println("OPTIONAL ENVIRONMENT");
|
||||||
|
out.println(" OUT_DIR Build output directory. Defaults to \"out\".");
|
||||||
|
out.println();
|
||||||
out.println("ERRORS");
|
out.println("ERRORS");
|
||||||
out.println(" The following are the errors that can be controlled on the");
|
out.println(" The following are the errors that can be controlled on the");
|
||||||
out.println(" commandline with the --hide --warning --error flags.");
|
out.println(" commandline with the --hide --warning --error flags.");
|
||||||
@@ -63,20 +95,26 @@ public class Options {
|
|||||||
|
|
||||||
private Errors mErrors;
|
private Errors mErrors;
|
||||||
private String[] mArgs;
|
private String[] mArgs;
|
||||||
|
private Map<String,String> mEnv;
|
||||||
private Options mResult = new Options();
|
private Options mResult = new Options();
|
||||||
private int mIndex;
|
private int mIndex;
|
||||||
|
private boolean mSkipRequiredArgValidation;
|
||||||
|
|
||||||
public Parser(Errors errors, String[] args) {
|
public Parser(Errors errors, String[] args, Map<String,String> env) {
|
||||||
mErrors = errors;
|
mErrors = errors;
|
||||||
mArgs = args;
|
mArgs = args;
|
||||||
|
mEnv = env;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Options parse() {
|
public Options parse() {
|
||||||
|
// Args
|
||||||
try {
|
try {
|
||||||
while (mIndex < mArgs.length) {
|
while (mIndex < mArgs.length) {
|
||||||
final String arg = mArgs[mIndex];
|
final String arg = mArgs[mIndex];
|
||||||
|
|
||||||
if ("--hide".equals(arg)) {
|
if ("--ckati_bin".equals(arg)) {
|
||||||
|
mResult.mCKatiBin = requireNextStringArg(arg);
|
||||||
|
} else if ("--hide".equals(arg)) {
|
||||||
handleErrorCode(arg, Errors.Level.HIDDEN);
|
handleErrorCode(arg, Errors.Level.HIDDEN);
|
||||||
} else if ("--error".equals(arg)) {
|
} else if ("--error".equals(arg)) {
|
||||||
handleErrorCode(arg, Errors.Level.ERROR);
|
handleErrorCode(arg, Errors.Level.ERROR);
|
||||||
@@ -99,11 +137,45 @@ public class Options {
|
|||||||
mErrors.ERROR_COMMAND_LINE.add(ex.getMessage());
|
mErrors.ERROR_COMMAND_LINE.add(ex.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Environment
|
||||||
|
mResult.mProduct = mEnv.get("TARGET_PRODUCT");
|
||||||
|
mResult.mVariant = mEnv.get("TARGET_BUILD_VARIANT");
|
||||||
|
mResult.mOutDir = mEnv.get("OUT_DIR");
|
||||||
|
|
||||||
|
validateArgs();
|
||||||
|
|
||||||
return mResult;
|
return mResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addWarning(Errors.Category category, String message) {
|
/**
|
||||||
category.add(message);
|
* For testing; don't generate errors about missing arguments
|
||||||
|
*/
|
||||||
|
public void setSkipRequiredArgValidation() {
|
||||||
|
mSkipRequiredArgValidation = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void validateArgs() {
|
||||||
|
if (!mSkipRequiredArgValidation) {
|
||||||
|
if (mResult.mCKatiBin == null || "".equals(mResult.mCKatiBin)) {
|
||||||
|
addMissingArgError("--ckati_bin");
|
||||||
|
}
|
||||||
|
if (mResult.mProduct == null) {
|
||||||
|
addMissingEnvError("TARGET_PRODUCT");
|
||||||
|
}
|
||||||
|
if (mResult.mVariant == null) {
|
||||||
|
addMissingEnvError("TARGET_BUILD_VARIANT");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addMissingArgError(String argName) {
|
||||||
|
mErrors.ERROR_COMMAND_LINE.add("Required command line argument missing: "
|
||||||
|
+ argName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addMissingEnvError(String envName) {
|
||||||
|
mErrors.ERROR_COMMAND_LINE.add("Required environment variable missing: "
|
||||||
|
+ envName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getNextNonFlagArg() {
|
private String getNextNonFlagArg() {
|
||||||
@@ -117,6 +189,14 @@ public class Options {
|
|||||||
return mArgs[mIndex];
|
return mArgs[mIndex];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String requireNextStringArg(String arg) throws ParseException {
|
||||||
|
final String val = getNextNonFlagArg();
|
||||||
|
if (val == null) {
|
||||||
|
throw new ParseException(arg + " requires a string argument.");
|
||||||
|
}
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
private int requireNextNumberArg(String arg) throws ParseException {
|
private int requireNextNumberArg(String arg) throws ParseException {
|
||||||
final String val = getNextNonFlagArg();
|
final String val = getNextNonFlagArg();
|
||||||
if (val == null) {
|
if (val == null) {
|
||||||
@@ -151,7 +231,7 @@ public class Options {
|
|||||||
* <p>
|
* <p>
|
||||||
* Adds errors encountered to Errors object.
|
* Adds errors encountered to Errors object.
|
||||||
*/
|
*/
|
||||||
public static Options parse(Errors errors, String[] args) {
|
public static Options parse(Errors errors, String[] args, Map<String, String> env) {
|
||||||
return (new Parser(errors, args)).parse();
|
return (new Parser(errors, args, env)).parse();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -19,12 +19,24 @@ package com.android.build.config;
|
|||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
public class OptionsTest {
|
public class OptionsTest {
|
||||||
|
|
||||||
|
private Options parse(Errors errors, String[] args) {
|
||||||
|
final HashMap<String, String> env = new HashMap();
|
||||||
|
env.put("TARGET_PRODUCT", "test_product");
|
||||||
|
env.put("TARGET_BUILD_VARIANT", "user");
|
||||||
|
final Options.Parser parser = new Options.Parser(errors, args, env);
|
||||||
|
parser.setSkipRequiredArgValidation();
|
||||||
|
return parser.parse();
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testErrorMissingLast() {
|
public void testErrorMissingLast() {
|
||||||
final Errors errors = new Errors();
|
final Errors errors = new Errors();
|
||||||
|
|
||||||
final Options options = Options.parse(errors, new String[] {
|
final Options options = parse(errors, new String[] {
|
||||||
"--error"
|
"--error"
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -37,7 +49,7 @@ public class OptionsTest {
|
|||||||
public void testErrorMissingNotLast() {
|
public void testErrorMissingNotLast() {
|
||||||
final Errors errors = new Errors();
|
final Errors errors = new Errors();
|
||||||
|
|
||||||
final Options options = Options.parse(errors, new String[] {
|
final Options options = parse(errors, new String[] {
|
||||||
"--error", "--warning", "2"
|
"--error", "--warning", "2"
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -50,7 +62,7 @@ public class OptionsTest {
|
|||||||
public void testErrorNotNumeric() {
|
public void testErrorNotNumeric() {
|
||||||
final Errors errors = new Errors();
|
final Errors errors = new Errors();
|
||||||
|
|
||||||
final Options options = Options.parse(errors, new String[] {
|
final Options options = parse(errors, new String[] {
|
||||||
"--error", "notgood"
|
"--error", "notgood"
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -63,7 +75,7 @@ public class OptionsTest {
|
|||||||
public void testErrorInvalidError() {
|
public void testErrorInvalidError() {
|
||||||
final Errors errors = new Errors();
|
final Errors errors = new Errors();
|
||||||
|
|
||||||
final Options options = Options.parse(errors, new String[] {
|
final Options options = parse(errors, new String[] {
|
||||||
"--error", "50000"
|
"--error", "50000"
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -76,7 +88,7 @@ public class OptionsTest {
|
|||||||
public void testErrorOne() {
|
public void testErrorOne() {
|
||||||
final Errors errors = new Errors();
|
final Errors errors = new Errors();
|
||||||
|
|
||||||
final Options options = Options.parse(errors, new String[] {
|
final Options options = parse(errors, new String[] {
|
||||||
"--error", "2"
|
"--error", "2"
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -89,7 +101,7 @@ public class OptionsTest {
|
|||||||
public void testWarningOne() {
|
public void testWarningOne() {
|
||||||
final Errors errors = new Errors();
|
final Errors errors = new Errors();
|
||||||
|
|
||||||
final Options options = Options.parse(errors, new String[] {
|
final Options options = parse(errors, new String[] {
|
||||||
"--warning", "2"
|
"--warning", "2"
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -102,7 +114,7 @@ public class OptionsTest {
|
|||||||
public void testHideOne() {
|
public void testHideOne() {
|
||||||
final Errors errors = new Errors();
|
final Errors errors = new Errors();
|
||||||
|
|
||||||
final Options options = Options.parse(errors, new String[] {
|
final Options options = parse(errors, new String[] {
|
||||||
"--hide", "2"
|
"--hide", "2"
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -110,5 +122,16 @@ public class OptionsTest {
|
|||||||
Assert.assertEquals(Options.Action.DEFAULT, options.getAction());
|
Assert.assertEquals(Options.Action.DEFAULT, options.getAction());
|
||||||
Assert.assertFalse(errors.hadWarningOrError());
|
Assert.assertFalse(errors.hadWarningOrError());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEnv() {
|
||||||
|
final Errors errors = new Errors();
|
||||||
|
|
||||||
|
final Options options = parse(errors, new String[0]);
|
||||||
|
|
||||||
|
Assert.assertEquals("test_product", options.getProduct());
|
||||||
|
Assert.assertEquals("user", options.getVariant());
|
||||||
|
Assert.assertFalse(errors.hadWarningOrError());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user