package liquibase.integration.commandline; import liquibase.exception.CommandLineParsingException; import liquibase.integration.commandline.Main; import liquibase.util.StringUtils; import static org.junit.Assert.*; import org.junit.Test; import java.io.*; import java.net.URL; import java.net.URLClassLoader; import java.util.Arrays; import java.util.Properties; /** * Tests for {@link Main} */ public class MainTest { @Test public void migrateWithAllParameters() throws Exception { String[] args = new String[]{ "--driver=DRIVER", "--username=USERNAME", "--password=PASSWORD", "--url=URL", "--changeLogFile=FILE", "--classpath=CLASSPATH;CLASSPATH2", "--contexts=CONTEXT1,CONTEXT2", "--promptForNonLocalDatabase=true", "update", }; Main cli = new Main(); cli.parseOptions(args); assertEquals("DRIVER", cli.driver); assertEquals("USERNAME", cli.username); assertEquals("PASSWORD", cli.password); assertEquals("URL", cli.url); assertEquals("FILE", cli.changeLogFile); assertEquals("CLASSPATH;CLASSPATH2", cli.classpath); assertEquals("CONTEXT1,CONTEXT2", cli.contexts); assertEquals(Boolean.TRUE, cli.promptForNonLocalDatabase); assertEquals("update", cli.command); } @Test public void falseBooleanParameters() throws Exception { String[] args = new String[]{ "--promptForNonLocalDatabase=false", "update", }; Main cli = new Main(); cli.parseOptions(args); assertEquals(Boolean.FALSE, cli.promptForNonLocalDatabase); assertEquals("update", cli.command); } @Test public void convertMigrateToUpdate() throws Exception { String[] args = new String[]{ "--promptForNonLocalDatabase=false", "migrate", }; Main cli = new Main(); cli.parseOptions(args); assertEquals("update", cli.command); } @Test public void trueBooleanParameters() throws Exception { String[] args = new String[]{ "--promptForNonLocalDatabase=true", "update", }; Main cli = new Main(); cli.parseOptions(args); assertEquals(Boolean.TRUE, cli.promptForNonLocalDatabase); assertEquals("update", cli.command); } @Test(expected = CommandLineParsingException.class) public void parameterWithoutDash() throws Exception { String[] args = new String[]{ "promptForNonLocalDatabase=true", "update", }; Main cli = new Main(); cli.parseOptions(args); } @Test(expected = CommandLineParsingException.class) public void unknownParameter() throws Exception { String[] args = new String[]{ "--promptForNonLocalDatabase=true", "--badParam=here", "migrate", }; Main cli = new Main(); cli.parseOptions(args); } @Test(expected = CommandLineParsingException.class) public void configureNonExistantClassloaderLocation() throws Exception { Main cli = new Main(); cli.classpath = "badClasspathLocation"; cli.configureClassLoader(); } @Test public void windowsConfigureClassLoaderLocation() throws Exception { Main cli = new Main(); if (cli.isWindows()) { System.setProperty("os.name", "Windows XP"); cli.classpath = "c:\\;c:\\windows\\"; cli.applyDefaults(); cli.configureClassLoader(); URL[] classloaderURLs = ((URLClassLoader) cli.classLoader).getURLs(); assertEquals(2, classloaderURLs.length); assertEquals("file:/c:/", classloaderURLs[0].toExternalForm()); assertEquals("file:/c:/windows/", classloaderURLs[1].toExternalForm()); } } @Test public void unixConfigureClassLoaderLocation() throws Exception { Main cli = new Main(); if (!cli.isWindows()) { System.setProperty("os.name", "Linux"); cli.classpath = "/tmp:/"; cli.applyDefaults(); cli.configureClassLoader(); URL[] classloaderURLs = ((URLClassLoader) cli.classLoader).getURLs(); assertEquals(2, classloaderURLs.length); assertEquals("file:/tmp/", classloaderURLs[0].toExternalForm()); assertEquals("file:/", classloaderURLs[1].toExternalForm()); } } @Test public void propertiesFileWithNoOtherArgs() throws Exception { Main cli = new Main(); Properties props = new Properties(); props.setProperty("driver", "DRIVER"); props.setProperty("username", "USERNAME"); props.setProperty("password", "PASSWD"); props.setProperty("url", "URL"); props.setProperty("changeLogFile", "FILE"); props.setProperty("classpath", "CLASSPAHT"); props.setProperty("contexts", "CONTEXTS"); props.setProperty("promptForNonLocalDatabase", "TRUE"); ByteArrayOutputStream propFile = new ByteArrayOutputStream(); props.store(propFile, ""); cli.parsePropertiesFile(new ByteArrayInputStream(propFile.toByteArray())); assertEquals("DRIVER", cli.driver); assertEquals("USERNAME", cli.username); assertEquals("PASSWD", cli.password); assertEquals("URL", cli.url); assertEquals("FILE", cli.changeLogFile); assertEquals("CLASSPAHT", cli.classpath); assertEquals("CONTEXTS", cli.contexts); assertEquals(Boolean.TRUE, cli.promptForNonLocalDatabase); } @Test public void propertiesFileWithOtherArgs() throws Exception { Main cli = new Main(); cli.username = "PASSED USERNAME"; cli.password = "PASSED PASSWD"; Properties props = new Properties(); props.setProperty("driver", "DRIVER"); props.setProperty("username", "USERNAME"); props.setProperty("password", "PASSWD"); props.setProperty("url", "URL"); props.setProperty("changeLogFile", "FILE"); props.setProperty("classpath", "CLASSPAHT"); props.setProperty("contexts", "CONTEXTS"); props.setProperty("promptForNonLocalDatabase", "TRUE"); ByteArrayOutputStream propFile = new ByteArrayOutputStream(); props.store(propFile, ""); cli.parsePropertiesFile(new ByteArrayInputStream(propFile.toByteArray())); assertEquals("DRIVER", cli.driver); assertEquals("PASSED USERNAME", cli.username); assertEquals("PASSED PASSWD", cli.password); assertEquals("URL", cli.url); assertEquals("FILE", cli.changeLogFile); assertEquals("CLASSPAHT", cli.classpath); assertEquals("CONTEXTS", cli.contexts); assertEquals(Boolean.TRUE, cli.promptForNonLocalDatabase); } @Test public void applyDefaults() { Main cli = new Main(); cli.promptForNonLocalDatabase = Boolean.TRUE; cli.applyDefaults(); assertEquals(Boolean.TRUE, cli.promptForNonLocalDatabase); cli.promptForNonLocalDatabase = Boolean.FALSE; cli.applyDefaults(); assertEquals(Boolean.FALSE, cli.promptForNonLocalDatabase); cli.promptForNonLocalDatabase = null; cli.applyDefaults(); assertEquals(Boolean.FALSE, cli.promptForNonLocalDatabase); } @Test(expected = CommandLineParsingException.class) public void propertiesFileWithBadArgs() throws Exception { Main cli = new Main(); Properties props = new Properties(); props.setProperty("driver", "DRIVER"); props.setProperty("username", "USERNAME"); props.setProperty("badArg", "ARG"); ByteArrayOutputStream propFile = new ByteArrayOutputStream(); props.store(propFile, ""); cli.parsePropertiesFile(new ByteArrayInputStream(propFile.toByteArray())); } @Test public void checkSetup() { Main cli = new Main(); assertTrue(cli.checkSetup().size() > 0); cli.driver = "driver"; cli.username = "username"; cli.password = "pwd"; cli.url = "url"; cli.changeLogFile = "file"; cli.classpath = "classpath"; assertTrue(cli.checkSetup().size() > 0); cli.command = "BadCommand"; assertTrue(cli.checkSetup().size() > 0); cli.command = "migrate"; assertEquals(0, cli.checkSetup().size()); } @Test public void printHelp() throws Exception { ByteArrayOutputStream stream = new ByteArrayOutputStream(); Main cli = new Main(); cli.printHelp(new PrintStream(stream)); BufferedReader reader = new BufferedReader(new StringReader(new String(stream.toByteArray()))); String line; while ((line = reader.readLine()) != null) { //noinspection MagicNumber if (line.length() > 80) { fail("'" + line + "' is longer than 80 chars"); } } } @Test public void tag() throws Exception { String[] args = new String[]{ "--driver=DRIVER", "--username=USERNAME", "--password=PASSWORD", "--url=URL", "--changeLogFile=FILE", "--classpath=CLASSPATH;CLASSPATH2", "--contexts=CONTEXT1,CONTEXT2", "tag", "TagHere" }; Main cli = new Main(); cli.parseOptions(args); assertEquals("DRIVER", cli.driver); assertEquals("USERNAME", cli.username); assertEquals("PASSWORD", cli.password); assertEquals("URL", cli.url); assertEquals("FILE", cli.changeLogFile); assertEquals("CLASSPATH;CLASSPATH2", cli.classpath); assertEquals("CONTEXT1,CONTEXT2", cli.contexts); assertEquals("tag", cli.command); assertEquals("TagHere", cli.commandParams.iterator().next()); } @Test public void migrateWithEqualsInParams() throws Exception { String url = "dbc:sqlserver://127.0.0.1;DatabaseName=dev_nn;user=ffdatabase;password=p!88worD"; String[] args = new String[]{ "--url=" + url, "migrate", }; Main cli = new Main(); cli.parseOptions(args); assertEquals(url, cli.url); } @Test public void fixArgs() { Main liquibase = new Main(); String[] fixedArgs = liquibase.fixupArgs(new String[] {"--defaultsFile","liquibase.properties", "migrate"}); assertEquals("--defaultsFile=liquibase.properties migrate", StringUtils.join(Arrays.asList(fixedArgs), " ")); fixedArgs = liquibase.fixupArgs(new String[] {"--defaultsFile=liquibase.properties", "migrate"}); assertEquals("--defaultsFile=liquibase.properties migrate", StringUtils.join(Arrays.asList(fixedArgs), " ")); fixedArgs = liquibase.fixupArgs(new String[] {"--driver=DRIVER", "--username=USERNAME", "--password=PASSWORD", "--url=URL", "--changeLogFile=FILE", "--classpath=CLASSPATH;CLASSPATH2", "--contexts=CONTEXT1,CONTEXT2", "--promptForNonLocalDatabase=true", "migrate" }); assertEquals("--driver=DRIVER --username=USERNAME --password=PASSWORD --url=URL --changeLogFile=FILE --classpath=CLASSPATH;CLASSPATH2 --contexts=CONTEXT1,CONTEXT2 --promptForNonLocalDatabase=true migrate", StringUtils.join(Arrays.asList(fixedArgs), " ")); } @Test public void testVersionArg() throws IOException, CommandLineParsingException { Main.main(new String[] {"--version"}); } @Test public void testSplitArgWithValueEndingByEqualSing() throws CommandLineParsingException { final String argName = "password"; final String argValue = "s3-cr3t="; Main tested = new Main(); tested.parseOptions(new String[] { "--" + argName + "=" + argValue }); assertEquals(argValue, tested.password); } }