Java tutorial
/* * IzPack - Copyright 2001-2012 Julien Ponge, All Rights Reserved. * * http://izpack.org/ * http://izpack.codehaus.org/ * * Copyright 2012 Tim Anderson * * 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.izforge.izpack.core.data; import com.izforge.izpack.api.data.*; import com.izforge.izpack.api.exception.InstallerException; import com.izforge.izpack.api.rules.Condition; import com.izforge.izpack.core.container.DefaultContainer; import com.izforge.izpack.core.rules.ConditionContainer; import com.izforge.izpack.core.rules.RulesEngineImpl; import com.izforge.izpack.core.rules.process.ExistsCondition; import com.izforge.izpack.core.rules.process.VariableCondition; import com.izforge.izpack.core.variable.ConfigFileValue; import com.izforge.izpack.core.variable.PlainConfigFileValue; import com.izforge.izpack.core.variable.PlainValue; import com.izforge.izpack.util.Platforms; import org.apache.commons.io.FileUtils; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TemporaryFolder; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import static org.junit.Assert.*; /** * Tests the {@link DefaultVariables} class. * * @author Tim Anderson */ public class DefaultVariablesTest { @Rule public TemporaryFolder rootFolder = new TemporaryFolder(); /** * The variables. */ private final DefaultVariables variables = new DefaultVariables(); /** * Tests the {@link Variables#set(String, String)}, {@link Variables#get(String)} and * {@link Variables#get(String, String)} methods. */ @Test public void testStringVariables() { // test basic set/get variables.set("var1", "value1"); assertEquals(variables.get("var1"), "value1"); // test nulls variables.set("null", null); assertNull(variables.get("null")); assertEquals("default", variables.get("null", "default")); // test where no variable set assertNull(variables.get("nonExistingVariable")); assertEquals("default", variables.get("nonExistingVariable", "default")); } /** * Tests the {@link Variables#getBoolean(String)} and {@link Variables#getBoolean(String, boolean)} methods. */ @Test public void testBooleanVariables() { // test basic set/get variables.set("var1", "true"); variables.set("var2", "false"); assertEquals(true, variables.getBoolean("var1")); assertEquals(false, variables.getBoolean("var2")); // test null variables.set("null", null); assertEquals(false, variables.getBoolean("null")); assertEquals(true, variables.getBoolean("null", true)); // test where no variable set assertEquals(false, variables.getBoolean("nonExistingVariable")); assertEquals(true, variables.getBoolean("nonExistingVariable", true)); // test when the value is not a boolean value variables.set("notABoolean", "yes"); assertEquals(false, variables.getBoolean("notABoolean")); assertEquals(true, variables.getBoolean("notABoolean", true)); } /** * Tests the {@link Variables#getInt(String)} and {@link Variables#getInt(String, int)} methods. */ @Test public void testIntVariables() { // check basic set, get variables.set("var1", "0"); variables.set("var2", Integer.toString(Integer.MIN_VALUE)); variables.set("var3", Integer.toString(Integer.MAX_VALUE)); assertEquals(0, variables.getInt("var1")); assertEquals(Integer.MIN_VALUE, variables.getInt("var2")); assertEquals(Integer.MAX_VALUE, variables.getInt("var3")); // check when the variable is null variables.set("null", null); assertEquals(-1, variables.getInt("null")); assertEquals(9999, variables.getInt("null", 9999)); // check when the variable doesn't exist assertEquals(-1, variables.getInt("nonExistingVariable")); assertEquals(9999, variables.getInt("nonExistingVariable", 9999)); // check when the variable is not an integer value variables.set("notAnInt", "abcdef"); assertEquals(-1, variables.getInt("notAnInt")); assertEquals(9999, variables.getInt("notAnInt", 9999)); // check behaviour when value < Integer.MIN_VALUE or > Integer.MAX_VALUE variables.set("exceed1", Long.toString(Long.MIN_VALUE)); variables.set("exceed2", Long.toString(Long.MAX_VALUE)); assertEquals(-1, variables.getInt("exceed1")); assertEquals(9999, variables.getInt("exceed1", 9999)); assertEquals(-1, variables.getInt("exceed2")); assertEquals(9999, variables.getInt("exceed2", 9999)); } /** * Tests the {@link Variables#getLong(String)} and {@link Variables#getLong(String, long)} methods. */ @Test public void testLongVariables() { // check basic set, get variables.set("var1", "0"); assertEquals(0, variables.getLong("var1")); // check when the variable is null variables.set("null", null); assertEquals(-1, variables.getLong("null")); assertEquals(9999, variables.getLong("null", 9999)); // check when the variable doesn't exist assertEquals(-1, variables.getLong("nonExistingVariable")); assertEquals(9999, variables.getLong("nonExistingVariable", 9999)); // check when the variable is not an integer value variables.set("notALong", "abcdef"); assertEquals(-1, variables.getLong("notALong")); assertEquals(9999, variables.getLong("notALong", 9999)); } /** * Tests the {@link Variables#replace(String)} method. */ @Test public void testReplace() { variables.set("var1", "Hello"); variables.set("var2", "world"); assertEquals("Hello world", variables.replace("$var1 $var2")); assertEquals("Hello world", variables.replace("${var1} ${var2}")); // check non-existent variable assertEquals("Hello $var3", variables.replace("$var1 $var3")); assertEquals("Hello ${var3}", variables.replace("${var1} ${var3}")); // check malformed variable assertEquals("Hello ${var3", variables.replace("$var1 ${var3")); // check null assertNull(variables.replace(null)); } /** * Tests simple dynamic variables. */ @Test public void testDynamicVariables() { variables.add(createDynamic("var1", "$INSTALL_PATH")); variables.set("INSTALL_PATH", "a"); assertNull(variables.get("var1")); // not created till variables refreshed variables.refresh(); assertEquals("a", variables.get("var1")); } /** * Tests conditional dynamic variables. */ @Test public void testConditionalDynamicVariables() { // set up conditions Map<String, Condition> conditions = new HashMap<String, Condition>(); conditions.put("cond1", new VariableCondition("os", "windows")); // true when os = windows conditions.put("cond2", new VariableCondition("os", "unix")); // true when os = unix // set up the rules AutomatedInstallData installData = new AutomatedInstallData(variables, Platforms.FREEBSD); RulesEngineImpl rules = new RulesEngineImpl(installData, new ConditionContainer(new DefaultContainer()), installData.getPlatform()); rules.readConditionMap(conditions); ((DefaultVariables) variables).setRules(rules); // add dynamic variables variables.add(createDynamic("INSTALL_PATH", "c:\\Program Files", "cond1")); // evaluated when os = windows variables.add(createDynamic("INSTALL_PATH", "/usr/local/bin", "cond2")); // evaluated when os = unix // check when cond1 is true variables.set("os", "windows"); variables.refresh(); assertEquals("c:\\Program Files", variables.get("INSTALL_PATH")); // check when cond2 is true variables.set("os", "unix"); variables.refresh(); assertEquals("/usr/local/bin", variables.get("INSTALL_PATH")); } /** * Tests for IZPACK-1260 */ @Test public void testDynamicVariablesIZPACK1260() { // set up conditions Map<String, Condition> conditions = new HashMap<String, Condition>(); conditions.put("haveInstallPath", new ExistsCondition(ExistsCondition.ContentType.VARIABLE, "INSTALL_PATH")); conditions.put("previous.wrapper.conf.exists", new ExistsCondition(ExistsCondition.ContentType.FILE, "${previous.wrapper.conf}")); // set up the rules AutomatedInstallData installData = new AutomatedInstallData(variables, Platforms.LINUX); RulesEngineImpl rules = new RulesEngineImpl(installData, new ConditionContainer(new DefaultContainer()), installData.getPlatform()); rules.readConditionMap(conditions); ((DefaultVariables) variables).setRules(rules); variables.add(createDynamicCheckonce("previous.wrapper.conf", "${INSTALL_PATH}/conf/wrapper.conf".replace("/", File.separator), "haveInstallPath")); variables.add(createDynamicCheckonce("previous.wrapper.conf", "${INSTALL_PATH}/wrapper.conf".replace("/", File.separator), "haveInstallPath+!previous.wrapper.conf.exists")); File installPath = null; File confFile = null; try { installPath = rootFolder.newFolder("myapp"); File confPath = new File(installPath, "conf"); confPath.mkdirs(); confFile = new File(confPath, "wrapper.conf"); FileUtils.touch(confFile); } catch (IOException e) { fail("File operation failed."); } variables.set("INSTALL_PATH", installPath.getAbsolutePath()); variables.refresh(); assertEquals(confFile.getAbsolutePath(), variables.get("previous.wrapper.conf")); } /** * Tests simple dynamic variables. */ @Test public void testDynamicVariablesWithUserInput() { // set up conditions Map<String, Condition> conditions = new HashMap<String, Condition>(); conditions.put("cond1", new VariableCondition("condvar1", "x")); conditions.put("cond2", new VariableCondition("condvar2", "y")); // set up the rules AutomatedInstallData installData = new AutomatedInstallData(variables, Platforms.LINUX); RulesEngineImpl rules = new RulesEngineImpl(installData, new ConditionContainer(new DefaultContainer()), installData.getPlatform()); rules.readConditionMap(conditions); ((DefaultVariables) variables).setRules(rules); variables.add(createDynamicCheckonce("var", "a", "cond1+cond2")); variables.add(createDynamicCheckonce("var", "b", "cond1+!cond2")); // !cond1+!cond2 variables.refresh(); assertNull(variables.get("var")); variables.set("condvar1", "x"); // cond1+!cond2 variables.refresh(); assertEquals("b", variables.get("var")); variables.refresh(); // Double check whether it is a stable state (for instance on panel change) assertEquals("b", variables.get("var")); Set<String> blocked = new HashSet<String>(); // we now do overwrite the variable on a UserInputPanel blocked.add("var"); variables.set("var", "anothervalue"); variables.registerBlockedVariableNames(blocked, this); variables.refresh(); // user input is stronger than other definitions assertEquals("anothervalue", variables.get("var")); variables.set("condvar2", "y"); // a conditions changes and wants to overwrite the variable variables.refresh(); // but user input still must survive assertEquals("anothervalue", variables.get("var")); // now the user goes back to the previous panel variables.unregisterBlockedVariableNames(blocked, this); variables.refresh(); // value must be changed as defined for cond1+cond2 assertEquals("a", variables.get("var")); variables.refresh(); // Double check whether it is a stable state (for instance on panel change) assertEquals("a", variables.get("var")); } /** * Tests dynamic variables with a deeper dependency * Before IZPACK-1406 the recursion was done by iterations of variables.refresh(). * Since IZPACK-1406 the variables are preordered by PackagerBase.buildVariableList(). * Therefore we have to provide the variables here in the correct order. * @see com.izforge.izpack.compiler.DynVariableOrderTest for ordering tests */ @SuppressWarnings("JavadocReference") @Test public void testDependentDynamicVariables() { variables.set("depVar1", "depValue"); variables.add(createDynamic("depVar2", "${depVar1}")); variables.add(createDynamic("depVar3", "${depVar2}")); assertNull(variables.get("depVar3")); // not created till variables refreshed variables.refresh(); assertEquals("check dependent variable", "depValue", variables.get("depVar3")); } /** * Tests dynamic variables with a deeper dependency */ @Test public void testDependentDynamicVariables2() { variables.add(createDynamic("name1", "someValue")); variables.add(createDynamic("name2", "${name1}")); variables.add(createDynamic("name3", "${name2}")); assertNull(variables.get("name3")); // not created till variables refreshed variables.refresh(); assertEquals("check dependent variable", "someValue", variables.get("name3")); } /** * Tests dynamic variables with a deeper dependency and checkonce==true */ @Test public void testDependentDynamicVariablesWithCheckOnce() { variables.set("depVar1", "depValue"); variables.add(createDynamic("depVar2", "${depVar1}")); variables.add(createDynamic("depVar3", "${depVar2}")); variables.add(createDynamicCheckonce("checkonceVar", "${depVar3}")); variables.refresh(); assertEquals("check dependent variable", "depValue", variables.get("depVar3")); assertEquals("check variable with checkonce=true", "depValue", variables.get("checkonceVar")); variables.set("depVar1", "newValue"); variables.refresh(); assertEquals("recheck dependent variable", "newValue", variables.get("depVar3")); // should be changed assertEquals("recheck variable with checkonce=true", "depValue", variables.get("checkonceVar")); // should not change any more } /** * Tests dynamic variables with and without conditions * <p> * This test is for the definition * <dynamicvariables> * <variable name="thechoice" value="fallback value" /> * <variable name="thechoice" value="choice1" condition="cond1" /> * <variable name="thechoice" value="choice2" condition="cond2" /> * </dynamicvariables> */ @Test public void testMixedDynamicVariables() { final String observedVar = "thechoice"; // set up conditions Map<String, Condition> conditions = new HashMap<String, Condition>(); conditions.put("cond1", new VariableCondition("condvar1", "1")); conditions.put("cond2", new VariableCondition("condvar2", "1")); // set up the rules AutomatedInstallData installData = new AutomatedInstallData(variables, Platforms.LINUX); RulesEngineImpl rules = new RulesEngineImpl(installData, new ConditionContainer(new DefaultContainer()), installData.getPlatform()); rules.readConditionMap(conditions); ((DefaultVariables) variables).setRules(rules); variables.add(createDynamic(observedVar, "fallback value", null)); variables.add(createDynamic(observedVar, "choice1", "cond1")); variables.add(createDynamic(observedVar, "choice2", "cond2")); assertNull(variables.get(observedVar)); // !cond1+!cond2 variables.refresh(); assertEquals("fallback value", variables.get(observedVar)); // cond1+!cond2 variables.set("condvar1", "1"); variables.refresh(); assertEquals("choice1", variables.get(observedVar)); variables.refresh(); // Double check whether it is a stable state (for instance on panel change) assertEquals("choice1", variables.get(observedVar)); // cond1+cond2 variables.set("condvar2", "1"); variables.refresh(); assertEquals("choice2", variables.get(observedVar)); variables.refresh(); // Double check whether it is a stable state (for instance on panel change) assertEquals("choice2", variables.get(observedVar)); // !cond1+cond2 variables.set("condvar1", "0"); variables.refresh(); assertEquals("choice2", variables.get(observedVar)); variables.refresh(); // Double check whether it is a stable state (for instance on panel change) assertEquals("choice2", variables.get(observedVar)); // !cond1+!cond2 variables.set("condvar2", "0"); variables.refresh(); assertEquals("fallback value", variables.get(observedVar)); variables.refresh(); // Double check whether it is a stable state (for instance on panel change) assertEquals("fallback value", variables.get(observedVar)); // !cond1+cond2 variables.set("condvar2", "1"); variables.refresh(); assertEquals("choice2", variables.get(observedVar)); variables.refresh(); // Double check whether it is a stable state (for instance on panel change) assertEquals("choice2", variables.get(observedVar)); // cond1+cond2 variables.set("condvar1", "1"); variables.refresh(); // cond2 takes precedence because of ordering assertEquals("choice2", variables.get(observedVar)); variables.refresh(); // Double check whether it is a stable state (for instance on panel change) assertEquals("choice2", variables.get(observedVar)); } /** * Tests dynamic variables with cyclic reference * <dynamicvariables> * <variable name="a" value="${b}" /> * <variable name="b" value="${a}" /> * </dynamicvariables> * <p> * This example is not useful, but should not create a loop. * Resolving is done in the best way it can be done. No error is thrown, but variable "a" is simply not resolved. */ @Test public void testCyclicReference() { variables.add(createDynamic("a", "${b}")); variables.add(createDynamic("b", "${a}")); variables.refresh(); assertEquals("${b}", variables.get("a")); assertEquals("${b}", variables.get("b")); } /** * Test loop detection with no dynamic variables at all * Ensure, that no exception is thrown */ @Test public void testNoDynamicVariables() { boolean catched = false; try { variables.refresh(); } catch (InstallerException e) { catched = true; } assertFalse("empty <dynamicVariables> must not throw an exception", catched); } /** * Tests a variable defined both static (<variables>) and dynamic (<dynamicvariables>) */ @Test public void testMixedVariables() { variables.set("var1", "value1"); variables.add(createDynamic("var1", "dynValue")); assertEquals("static value", "value1", variables.get("var1")); // dynamic variable not resolved till variables refreshed variables.refresh(); assertEquals("dynamic overwrite", "dynValue", variables.get("var1")); // static variable is overwritten by dynamic variable variables.add(createDynamic("var1", "${var2}")); // var2 is not defined yet variables.refresh(); assertEquals("expect unresolved reference", "${var2}", variables.get("var1")); variables.set("var2", "value2"); // define var2 variables.refresh(); assertEquals("expect reference resolved", "value2", variables.get("var1")); } /** * Tests a variable defined both static (<variables>) and dynamic (<dynamicvariables>) with reference to ini file */ @Test public void testMixedVariablesFromIniFileUnsetTrue() { testMixedVariablesFromIniFileUnset(true); // variable "var6" is static defined, but dynamic reference is not found in ini file. // with unset="true" (Default) the static variable is overwritten with null assertNull("undefined reference gives <null>", variables.get("var6")); } /** * Tests a variable defined both static (<variables>) and dynamic (<dynamicvariables>) with reference to ini file */ @Test public void testMixedVariablesFromIniFileUnsetFalse() { testMixedVariablesFromIniFileUnset(false); // variable "var6" is static defined, but dynamic reference is not found in ini file. // with unset="false" the static variable is conserved and can be used as default assertEquals("undefined reference gives static value", "static", variables.get("var6")); } private void testMixedVariablesFromIniFileUnset(boolean unset) { // setup for testMixedVariablesFromIniFileUnsetTrue and testMixedVariablesFromIniFileUnsetFalse variables.set("var1", "static"); variables.set("var2", "static"); variables.set("var3", "static"); variables.set("var4", "static"); variables.set("var5", "static"); variables.set("var6", "static"); variables.add(createDynamicFromIni("found", unset)); variables.add(createDynamicFromIni("var1", unset)); variables.add(createDynamicFromIni("var2", unset)); variables.add(createDynamicFromIni("var3", unset)); variables.add(createDynamicFromIni("var4", unset)); variables.add(createDynamicFromIni("var5", unset)); variables.add(createDynamicFromIni("var6", unset)); // common tests for testMixedVariablesFromIniFileUnsetTrue and testMixedVariablesFromIniFileUnsetFalse assertEquals("static value", "static", variables.get("var1")); // dynamic variable not resolved till variables refreshed variables.refresh(); assertEquals("ini not found", "true", variables.get("found")); // check, whether ini was found at all // static variable replaced by dynamic value from ini assertEquals("value from ini", "ini1", variables.get("var1")); assertEquals("value from ini with spaces", "ini2", variables.get("var2")); assertEquals("value from ini with spaces in value", "ini with spaces", variables.get("var3")); assertEquals("empty value from ini", "", variables.get("var4")); assertEquals("empty value with spaces in ini", "", variables.get("var5")); } /** * Test for blocking of dynamic variables */ @Test public void testBlockedDynamicVariables() { // set up conditions Map<String, Condition> conditions = new HashMap<String, Condition>(); conditions.put("cond1", new VariableCondition("condvar1", "1")); variables.set("condvar1", "0"); // set up the rules AutomatedInstallData installData = new AutomatedInstallData(variables, Platforms.LINUX); RulesEngineImpl rules = new RulesEngineImpl(installData, new ConditionContainer(new DefaultContainer()), installData.getPlatform()); rules.readConditionMap(conditions); ((DefaultVariables) variables).setRules(rules); String blockedVar = "a"; variables.add(createDynamic(blockedVar, "oldValue")); variables.add(createDynamic(blockedVar, "newValue", "cond1")); variables.refresh(); assertEquals("oldValue", variables.get(blockedVar)); // block variable Set<String> blockedVars = new HashSet<String>(); blockedVars.add(blockedVar); Panel blocker = new Panel(); variables.registerBlockedVariableNames(blockedVars, blocker); variables.refresh(); assertEquals("oldValue", variables.get(blockedVar)); // condition becomes true, but variable is still blocked variables.set("condvar1", "1"); variables.refresh(); assertEquals("oldValue", variables.get(blockedVar)); // unblock variable, so value should change variables.unregisterBlockedVariableNames(blockedVars, blocker); variables.refresh(); assertEquals("newValue", variables.get(blockedVar)); } /** * Creates a dynamic variable with Checkonce set. * * @param name the variable name * @param value the variable value * @return a new variable */ private DynamicVariable createDynamicCheckonce(String name, String value) { return createDynamicCheckonce(name, value, null); } /** * Creates a dynamic variable with a condition and Checkonce set. * * @param name the variable name * @param value the variable value * @param conditionId the condition identifier. May be {@code null} * @return a new variable */ private DynamicVariable createDynamicCheckonce(String name, String value, String conditionId) { DynamicVariable var = createDynamic(name, value, conditionId); var.setCheckonce(true); return var; } /** * Creates a dynamic variable. * * @param name the variable name * @param value the variable value * @return a new variable */ private DynamicVariable createDynamic(String name, String value) { return createDynamic(name, value, null); } /** * Creates a dynamic variable with a condition. * * @param name the variable name * @param value the variable value * @param conditionId the condition identifier. May be {@code null} * @return a new variable */ private DynamicVariable createDynamic(String name, String value, String conditionId) { DynamicVariableImpl result = new DynamicVariableImpl(); result.setName(name); result.setValue(new PlainValue(value)); result.setConditionid(conditionId); return result; } /** * Creates a dynamic variable from the ini file "src/test/resources/com/izforge/izpack/core/variable/test.ini". * * @param name the variable name * @param autounset whether to unset, when undefined * @return a new variable */ private DynamicVariable createDynamicFromIni(String name, boolean autounset) { return createDynamicFromIni(name, "src/test/resources/com/izforge/izpack/core/variable/test.ini", "test", name, autounset); } /** * Creates a dynamic variable from a ini file. * * @param name the variable name * @param file the test ini file * @param filesection the section in the ini file * @param filekey the key in the ini file * @param autounset whether to unset, when undefined * @return a new variable */ private DynamicVariable createDynamicFromIni(String name, String file, String filesection, String filekey, boolean autounset) { DynamicVariableImpl result = new DynamicVariableImpl(); result.setName(name); boolean escape = true; result.setValue( new PlainConfigFileValue(file, ConfigFileValue.CONFIGFILE_TYPE_INI, filesection, filekey, escape)); result.setAutoUnset(autounset); return result; } /** * Tests variable overrides to be passed to the installer */ @Test public void testOverrides() { File file = new File("src/test/resources/com/izforge/izpack/core/data/test.defaults"); assertTrue("File " + file + " not found", file.exists()); Overrides overrides = null; try { overrides = new DefaultOverrides(file); overrides.load(); } catch (IOException e) { fail(e.getMessage()); } variables.add(createDynamic("var1", "dynamic_definition")); variables.setOverrides(overrides); variables.refresh(); assertEquals("Wrong override after refresh without explicitly setting the variable", "OVERRIDE1", variables.get("var1")); variables.set("var1", "explicit_value"); assertEquals( "Explicitly set variable value not present not present after refresh" + "- user input will not override the defaults contents", "explicit_value", variables.get("var1")); } }