http://git-wip-us.apache.org/repos/asf/ant/blob/1ae68097/src/tests/junit/org/apache/tools/ant/types/selectors/ModifiedSelectorTest.java ---------------------------------------------------------------------- diff --git a/src/tests/junit/org/apache/tools/ant/types/selectors/ModifiedSelectorTest.java b/src/tests/junit/org/apache/tools/ant/types/selectors/ModifiedSelectorTest.java index 80dd6df..e83c5b7 100644 --- a/src/tests/junit/org/apache/tools/ant/types/selectors/ModifiedSelectorTest.java +++ b/src/tests/junit/org/apache/tools/ant/types/selectors/ModifiedSelectorTest.java @@ -1,1062 +1,1062 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.tools.ant.types.selectors; - - -// Java -import java.io.File; -import java.text.RuleBasedCollator; -import java.util.Comparator; -import java.util.Iterator; - -import org.apache.tools.ant.AntAssert; -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.BuildFileRule; -import org.apache.tools.ant.Project; -import org.apache.tools.ant.Target; -import org.apache.tools.ant.Task; -import org.apache.tools.ant.types.Parameter; -import org.apache.tools.ant.types.Path; -import org.apache.tools.ant.types.selectors.modifiedselector.Algorithm; -import org.apache.tools.ant.types.selectors.modifiedselector.Cache; -import org.apache.tools.ant.types.selectors.modifiedselector.ChecksumAlgorithm; -import org.apache.tools.ant.types.selectors.modifiedselector.DigestAlgorithm; -import org.apache.tools.ant.types.selectors.modifiedselector.EqualComparator; -import org.apache.tools.ant.types.selectors.modifiedselector.HashvalueAlgorithm; -import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector; -import org.apache.tools.ant.types.selectors.modifiedselector.PropertiesfileCache; -import org.apache.tools.ant.util.FileUtils; -import org.junit.Assume; -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Rule; -import org.junit.Test; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - - -/** - * Unit tests for ModifiedSelector. - * - * @since Ant 1.6 - */ -public class ModifiedSelectorTest { - - @Rule - public final BaseSelectorRule selectorRule = new BaseSelectorRule(); - - /** Utilities used for file operations */ - private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); - - // ===================== attributes ===================== - - - /** Path where the testclasses are. */ - private Path testclasses = null; - - - - - // ===================== JUnit stuff ===================== - - - @Before - public void setUp() { - // init the testclasses path object - Project prj = selectorRule.getProject(); - testclasses = new Path(prj, prj.getProperty("build.tests.value")); - } - - - // ======= testcases for the attributes and nested elements of the selector ===== - - - /** Test right use of cache names. */ - @Test - public void testValidateWrongCache() { - String name = "this-is-not-a-valid-cache-name"; - try { - ModifiedSelector.CacheName cacheName = new ModifiedSelector.CacheName(); - cacheName.setValue(name); - fail("CacheSelector.CacheName accepted invalid value."); - } catch (BuildException be) { - assertEquals(name + " is not a legal value for this attribute", - be.getMessage()); - } - } - - - /** Test right use of cache names. */ - @Test - public void testValidateWrongAlgorithm() { - String name = "this-is-not-a-valid-algorithm-name"; - try { - ModifiedSelector.AlgorithmName algoName - = new ModifiedSelector.AlgorithmName(); - algoName.setValue(name); - fail("CacheSelector.AlgorithmName accepted invalid value."); - } catch (BuildException be) { - assertEquals(name + " is not a legal value for this attribute", - be.getMessage()); - } - } - - - /** Test right use of comparator names. */ - @Test - public void testValidateWrongComparator() { - String name = "this-is-not-a-valid-comparator-name"; - try { - ModifiedSelector.ComparatorName compName - = new ModifiedSelector.ComparatorName(); - compName.setValue(name); - fail("ModifiedSelector.ComparatorName accepted invalid value."); - } catch (BuildException be) { - assertEquals(name + " is not a legal value for this attribute", - be.getMessage()); - } - } - - - @Test - public void testIllegalCustomAlgorithm() { - try { - getAlgoName("java.lang.Object"); - fail("Illegal classname used."); - } catch (BuildException e) { - assertEquals("Wrong exception message.", - "Specified class (java.lang.Object) is not an Algorithm.", - e.getMessage()); - - } - } - - - @Test - public void testNonExistentCustomAlgorithm() { - try { - getAlgoName("non.existent.custom.Algorithm"); - fail("does 'non.existent.custom.Algorithm' really exist?"); - } catch (BuildException e) { - assertEquals("Wrong exception message.", - "Specified class (non.existent.custom.Algorithm) not found.", - e.getMessage()); - - } - } - - @Test - public void testCustomAlgorithm() { - String algo = getAlgoName("org.apache.tools.ant.types.selectors.modifiedselector.HashvalueAlgorithm"); - assertTrue("Wrong algorithm used: "+algo, algo.startsWith("HashvalueAlgorithm")); - } - - @Test - public void testCustomAlgorithm2() { - String algo = getAlgoName("org.apache.tools.ant.types.selectors.MockAlgorithm"); - assertTrue("Wrong algorithm used: "+algo, algo.startsWith("MockAlgorithm")); - } - - - @Test - public void testCustomClasses() { - Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") ); - BFT bft = new BFT(); - bft.setUp(); - try { - // do the actions - bft.doTarget("modifiedselectortest-customClasses"); - // do the checks - the buildfile stores the fileset as property - String fsFullValue = bft.getProperty("fs.full.value"); - String fsModValue = bft.getProperty("fs.mod.value"); - - assertNotNull("'fs.full.value' must be set.", fsFullValue); - assertTrue("'fs.full.value' must not be null.", !"".equals(fsFullValue)); - assertTrue("'fs.full.value' must contain ant.bat.", fsFullValue.indexOf("ant.bat")>-1); - - assertNotNull("'fs.mod.value' must be set.", fsModValue); - // must be empty according to the Mock* implementations - assertTrue("'fs.mod.value' must be empty.", "".equals(fsModValue)); - // don't catch the JUnit exceptions - } finally { - bft.doTarget("modifiedselectortest-scenario-clean"); - bft.deletePropertiesfile(); - bft.tearDown(); - } - } - - - @Test - public void testDelayUpdateTaskFinished() { - doDelayUpdateTest(1); - } - - - @Test - public void testDelayUpdateTargetFinished() { - doDelayUpdateTest(2); - } - - - @Test - public void testDelayUpdateBuildFinished() { - doDelayUpdateTest(3); - } - - - public void doDelayUpdateTest(int kind) { - // no check for 1<=kind<=3 - only internal use therefore check it - // while development - - // readable form of parameter kind - String[] kinds = {"task", "target", "build"}; - - // setup the "Ant project" - MockProject project = new MockProject(); - File base = new File("base"); - File file1 = new File("file1"); - File file2 = new File("file2"); - - // setup the selector - ModifiedSelector sel = new ModifiedSelector(); - sel.setProject(project); - sel.setUpdate(true); - sel.setDelayUpdate(true); - // sorry - otherwise we will get a ClassCastException because the MockCache - // is loaded by two different classloader ... - sel.setClassLoader(this.getClass().getClassLoader()); - sel.addClasspath(testclasses); - - sel.setAlgorithmClass("org.apache.tools.ant.types.selectors.MockAlgorithm"); - sel.setCacheClass("org.apache.tools.ant.types.selectors.MockCache"); - sel.configure(); - - // get the cache, so we can check our things - MockCache cache = (MockCache)sel.getCache(); - - // the test - assertFalse("Cache must not be saved before 1st selection.", cache.saved); - sel.isSelected(base, "file1", file1); - assertFalse("Cache must not be saved after 1st selection.", cache.saved); - sel.isSelected(base, "file2", file2); - assertFalse("Cache must not be saved after 2nd selection.", cache.saved); - switch (kind) { - case 1 : project.fireTaskFinished(); break; - case 2 : project.fireTargetFinished(); break; - case 3 : project.fireBuildFinished(); break; - } - assertTrue("Cache must be saved after " + kinds[kind-1] + "Finished-Event.", cache.saved); - - // MockCache doesnt create a file - therefore no cleanup needed - } - - - /** - * Extracts the real used algorithm name from the ModifiedSelector using - * its toString() method. - * @param classname the classname from the algorithm to use - * @return the algorithm part from the toString() (without brackets) - */ - private String getAlgoName(String classname) { - ModifiedSelector sel = new ModifiedSelector(); - sel.setProject(selectorRule.getProject()); - // add the test classes to its classpath - sel.addClasspath(testclasses); - sel.setAlgorithmClass(classname); - // let the selector do its checks - sel.validate(); - // extract the algorithm name (and config) from the selectors output - String s1 = sel.toString(); - int posStart = s1.indexOf("algorithm=") + 10; - int posEnd = s1.indexOf(" comparator="); - String algo = s1.substring(posStart, posEnd); - // '<' and '>' are only used if the algorithm has properties - if (algo.startsWith("<")) algo = algo.substring(1); - if (algo.endsWith(">")) algo = algo.substring(0, algo.length()-1); - // return the clean value - return algo; - } - - - // ================ testcases for the cache implementations ================ - - - /** - * Propertycache must have a set 'cachefile' attribute. - * The default in ModifiedSelector "cache.properties" is set by the selector. - */ - @Test - public void testPropcacheInvalid() { - Cache cache = new PropertiesfileCache(); - if (cache.isValid()) - fail("PropertyfilesCache does not check its configuration."); - } - - - @Test - public void testPropertyfileCache() { - PropertiesfileCache cache = new PropertiesfileCache(); - File cachefile = new File("cache.properties"); - cache.setCachefile(cachefile); - doTest(cache); - assertFalse("Cache file not deleted.", cachefile.exists()); - } - - - /** Checks whether a cache file is created. */ - @Test - public void testCreatePropertiesCacheDirect() { - File cachefile = new File(selectorRule.getProject().getBaseDir(), "cachefile.properties"); - - PropertiesfileCache cache = new PropertiesfileCache(); - cache.setCachefile(cachefile); - - cache.put("key", "value"); - cache.save(); - - assertTrue("Cachefile not created.", cachefile.exists()); - - cache.delete(); - assertFalse("Cachefile not deleted.", cachefile.exists()); - } - - - /** Checks whether a cache file is created. */ - @Test - public void testCreatePropertiesCacheViaModifiedSelector() { - File cachefile = new File(selectorRule.getProject().getBaseDir(), "cachefile.properties"); - - // Configure the selector - ModifiedSelector s = new ModifiedSelector(); - s.setDelayUpdate(false); - s.addParam("cache.cachefile", cachefile); - - ModifiedSelector.CacheName cacheName = new ModifiedSelector.CacheName(); - cacheName.setValue("propertyfile"); - s.setCache(cacheName); - - s.setUpdate(true); - - selectorRule.selectionString(s); - - // evaluate correctness - assertTrue("Cache file is not created.", cachefile.exists()); - cachefile.delete(); - - } - - - /** - * In earlier implementations there were problems with the <i>order</i> - * of the <param>s. The scenario was <pre> - * <custom class="ModifiedSelector"> - * <param name="cache.cachefile" value="mycache.properties" /> - * <param name="cache" value="propertyfiles" /> - * </custom> - * </pre> It was important first to set the cache and then to set - * the cache's configuration parameters. That results in the reorganized - * configure() method of ModifiedSelector. This testcase tests that. - */ - @Test - public void testCreatePropertiesCacheViaCustomSelector() { - File cachefile = FILE_UTILS.createTempFile("tmp-cache-", ".properties", null, false, false); - - // Configure the selector - - ExtendSelector s = new ExtendSelector(); - s.setClassname("org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector"); - s.addParam(createParam("update", "true")); - s.addParam(createParam("cache.cachefile", cachefile.getAbsolutePath())); - s.addParam(createParam("cache", "propertyfile")); - - selectorRule.selectionString(s); - - // evaluate correctness - assertTrue("Cache file is not created.", cachefile.exists()); - cachefile.delete(); - - } - - - @Test - @Ignore("same logic as on algorithm, no testcases created") - public void testCustomCache() { - // same logic as on algorithm, no testcases created - } - - - /** - * Test the interface semantic of Caches. - * This method does some common test for cache implementations. - * A cache must return a stored value and a valid iterator. - * After calling the delete() the cache must be empty. - * - * @param cache configured test object - */ - protected void doTest(Cache cache) { - assertTrue("Cache not proper configured.", cache.isValid()); - - String key1 = "key1"; - String value1 = "value1"; - String key2 = "key2"; - String value2 = "value2"; - - // given cache must be empty - Iterator it1 = cache.iterator(); - assertFalse("Cache is not empty", it1.hasNext()); - - // cache must return a stored value - cache.put(key1, value1); - cache.put(key2, value2); - assertEquals("cache returned wrong value", value1, cache.get(key1)); - assertEquals("cache returned wrong value", value2, cache.get(key2)); - - // test the iterator - Iterator it2 = cache.iterator(); - Object returned = it2.next(); - boolean ok = (key1.equals(returned) || key2.equals(returned)); - String msg = "Iterator returned unexpected value." - + " key1.equals(returned)="+key1.equals(returned) - + " key2.equals(returned)="+key2.equals(returned) - + " returned="+returned - + " ok="+ok; - assertTrue(msg, ok); - - // clear the cache - cache.delete(); - Iterator it3 = cache.iterator(); - assertFalse("Cache is not empty", it3.hasNext()); - } - - - // ============== testcases for the algorithm implementations ============== - - - @Test - public void testHashvalueAlgorithm() { - HashvalueAlgorithm algo = new HashvalueAlgorithm(); - doTest(algo); - } - - - @Test - public void testDigestAlgorithmMD5() { - DigestAlgorithm algo = new DigestAlgorithm(); - algo.setAlgorithm("MD5"); - doTest(algo); - } - - - @Test - public void testDigestAlgorithmSHA() { - DigestAlgorithm algo = new DigestAlgorithm(); - algo.setAlgorithm("SHA"); - doTest(algo); - } - - - @Test - public void testChecksumAlgorithm() { - ChecksumAlgorithm algo = new ChecksumAlgorithm(); - doTest(algo); - } - - - @Test - public void testChecksumAlgorithmCRC() { - ChecksumAlgorithm algo = new ChecksumAlgorithm(); - algo.setAlgorithm("CRC"); - doTest(algo); - } - - - @Test - public void testChecksumAlgorithmAdler() { - ChecksumAlgorithm algo = new ChecksumAlgorithm(); - algo.setAlgorithm("Adler"); - doTest(algo); - } - - - /** - * Test the interface semantic of Algorithms. - * This method does some common test for algorithm implementations. - * An algorithm must return always the same value for the same file and - * it must not return <i>null</i>. - * - * @param algo configured test object - */ - protected void doTest(Algorithm algo) { - assertTrue("Algorithm not proper configured.", algo.isValid()); - for (int i=0; i<selectorRule.getFiles().length; i++) { - File file = selectorRule.getFiles()[i]; // must not be a directory - if (file.isFile()) { - // get the Hashvalues - String hash1 = algo.getValue(file); - String hash2 = algo.getValue(file); - String hash3 = algo.getValue(file); - String hash4 = algo.getValue(file); - String hash5 = algo.getValue(new File(file.getAbsolutePath())); - - // Assert !=null and equality - assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash1); - assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash2); - assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash3); - assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash4); - assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash5); - assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash2); - assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash3); - assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash4); - assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash5); - }//if-isFile - }//for - - } - - - - // ============== testcases for the comparator implementations ============== - - - @Test - public void testEqualComparator() { - EqualComparator comp = new EqualComparator(); - doTest(comp); - } - - - @Test - public void testRuleComparator() { - RuleBasedCollator comp = (RuleBasedCollator)RuleBasedCollator.getInstance(); - doTest(comp); - } - - - @Test - public void testEqualComparatorViaSelector() { - ModifiedSelector s = new ModifiedSelector(); - ModifiedSelector.ComparatorName compName = new ModifiedSelector.ComparatorName(); - compName.setValue("equal"); - s.setComparator(compName); - try { - performTests(s, "TTTTTTTTTTTT"); - } finally { - s.getCache().delete(); - } - } - - - @Test - @Ignore("not yet supported see note in selector") - public void testRuleComparatorViaSelector() { - ModifiedSelector s = new ModifiedSelector(); - ModifiedSelector.ComparatorName compName = new ModifiedSelector.ComparatorName(); - compName.setValue("rule"); - s.setComparator(compName); - try { - performTests(s, "TTTTTTTTTTTT"); - } finally { - s.getCache().delete(); - } - } - - - @Test - @Ignore("same logic as on algorithm, no testcases created") - public void testCustomComparator() { - // same logic as on algorithm, no testcases created - } - - - @Test - public void testResourceSelectorSimple() { - BFT bft = new BFT(); - bft.doTarget("modifiedselectortest-ResourceSimple"); - bft.deleteCachefile(); - //new File("src/etc/testcases/types/resources/selectors/cache.properties").delete(); - } - - @Test - public void testResourceSelectorSelresTrue() { - BFT bft = new BFT(); - bft.doTarget("modifiedselectortest-ResourceSelresTrue"); - AntAssert.assertContains("does not provide an InputStream", bft.getLog()); - bft.deleteCachefile(); - } - - @Test - public void testResourceSelectorSelresFalse() { - BFT bft = new BFT(); - bft.doTarget("modifiedselectortest-ResourceSelresFalse"); - bft.deleteCachefile(); - } - - @Test - public void testResourceSelectorScenarioSimple() { - - Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home")); - BFT bft = new BFT(); - bft.doTarget("modifiedselectortest-scenario-resourceSimple"); - bft.doTarget("modifiedselectortest-scenario-clean"); - bft.deleteCachefile(); - } - - /** - * Test the interface semantic of Comparators. - * This method does some common test for comparator implementations. - * - * @param comp configured test object - */ - protected void doTest(Comparator comp) { - Object o1 = new String("string1"); - Object o2 = new String("string2"); - Object o3 = new String("string2"); // really "2" - - assertTrue("Comparator gave wrong value.", comp.compare(o1, o2) != 0); - assertTrue("Comparator gave wrong value.", comp.compare(o1, o3) != 0); - assertTrue("Comparator gave wrong value.", comp.compare(o2, o3) == 0); - } - - - // ===================== scenario tests ===================== - - - /** - * Tests whether the seldirs attribute is used. - */ - @Test - public void testSeldirs() { - ModifiedSelector s = new ModifiedSelector(); - StringBuffer sbTrue = new StringBuffer(); - StringBuffer sbFalse = new StringBuffer(); - for (int i=0; i<selectorRule.getFiles().length; i++) { - if (selectorRule.getFiles()[i].isDirectory()) { - sbTrue.append("T"); - sbFalse.append("F"); - } else { - sbTrue.append("T"); - sbFalse.append("T"); - } - } - - s.setSeldirs(true); - performTests(s, sbTrue.toString()); - s.getCache().delete(); - - s.setSeldirs(false); - performTests(s, sbFalse.toString()); - s.getCache().delete(); - - s.getCache().delete(); - } - - - /** - * Complex test scenario using default values (DigestAlgorithm with MD5, - * PropertiesfileCache with file=cache.properties, EqualComparator - * and update=true). <ol> - * <li> try fist time --> should select all </li> - * <li> try second time --> should select no files (only directories) </li> - * <li> modify timestamp of one file and content of a nother one </li> - * <li> try third time --> should select only the file with modified - * content </li> - */ - @Test - public void testScenario1() { - BFT bft = null; - ModifiedSelector s = null; - try { - - String results; - - // Configure the selector - only defaults are used - s = new ModifiedSelector(); - - // - // ***** First Run ***** - // the first call should get all files, because nothing is in - // the cache - // - performTests(s, "TTTTTTTTTTTT"); - - // - // ***** Second Run ***** - // the second call should get no files, because no content - // has changed - // - performTests(s, "TFFFFFFFFFFT"); - - // - // ***** make some files dirty ***** - // - - // these files are made dirty --> 3+4 with different content - String f2name = "tar/bz2/asf-logo-huge.tar.bz2"; - String f3name = "asf-logo.gif.md5"; - String f4name = "copy.filterset.filtered"; - - // AccessObject to the test-Ant-environment - bft = new BFT(); - // give some values (via property file) to that environment - bft.writeProperties("f2name="+f2name); - bft.writeProperties("f3name="+f3name); - bft.writeProperties("f4name="+f4name); - // call the target for making the files dirty - bft.doTarget("modifiedselectortest-makeDirty"); - - // - // ***** Third Run ***** - // third call should get only those files, which CONTENT changed - // (no timestamp changes required!) - results = selectorRule.selectionString(s); - - // - // ***** Check the result ***** - // - - // Mark all files which should be selected as (T)rue and all others - // as (F)alse. Directories are always selected so they always are - // (T)rue. - StringBuffer expected = new StringBuffer(); - for (int i=0; i<selectorRule.getFiles().length; i++) { - String ch = "F"; - if (selectorRule.getFiles()[i].isDirectory()) ch = "T"; - // f2name shouldn't be selected: only timestamp has changed! - if (selectorRule.getFilenames()[i].equalsIgnoreCase(f3name)) ch = "T"; - if (selectorRule.getFilenames()[i].equalsIgnoreCase(f4name)) ch = "T"; - expected.append(ch); - } - - assertEquals( - "Wrong files selected. Differing files: " // info text - + resolve(diff(expected.toString(), results)), // list of files - expected.toString(), // expected result - results // result - ); - - } finally { - // cleanup the environment - if (s!=null) s.getCache().delete(); - if (bft!=null) bft.deletePropertiesfile(); - } - } - - - /** - * This scenario is based on scenario 1, but does not use any - * default value and its based on <custom> selector. Used values are:<ul> - * <li><b>Cache: </b> Propertyfile, - * cachefile={java.io.tmpdir}/mycache.txt </li> - * <li><b>Algorithm: </b> Digest - * algorithm=SHA, Provider=null </li> - * <li><b>Comparator: </b> java.text.RuleBasedCollator - * <li><b>Update: </b> true </li> - */ - @Test - @Ignore("RuleBasedCollator not yet supported - see Selector:375 note") - public void testScenario2() { - ExtendSelector s = new ExtendSelector(); - BFT bft = new BFT(); - String cachefile = System.getProperty("java.io.tmpdir")+"/mycache.txt"; - try { - - s.setClassname("org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector"); - - s.addParam(createParam("cache.cachefile", cachefile)); - //s.addParam(createParam("algorithm.provider","---")); // i don't know any valid - s.addParam(createParam("cache","propertyfile")); - s.addParam(createParam("update","true")); - s.addParam(createParam("comparator","rule")); - s.addParam(createParam("algorithm.name","sha")); - s.addParam(createParam("algorithm","digest")); - - // first and second run - performTests(s, "TTTTTTTTTTTT"); - performTests(s, "TFFFFFFFFFFT"); - // make dirty - String f2name = "tar/bz2/asf-logo-huge.tar.bz2"; - String f3name = "asf-logo.gif.md5"; - String f4name = "copy.filterset.filtered"; - bft.writeProperties("f2name="+f2name); - bft.writeProperties("f3name="+f3name); - bft.writeProperties("f4name="+f4name); - bft.doTarget("modifiedselectortest-makeDirty"); - // third run - String results = selectorRule.selectionString(s); - StringBuffer expected = new StringBuffer(); - for (int i=0; i<selectorRule.getFilenames().length; i++) { - String ch = "F"; - if (selectorRule.getFiles()[i].isDirectory()) ch = "T"; - if (selectorRule.getFilenames()[i].equalsIgnoreCase(f3name)) ch = "T"; - if (selectorRule.getFilenames()[i].equalsIgnoreCase(f4name)) ch = "T"; - expected.append(ch); - } - assertEquals( - "Wrong files selected. Differing files: " // info text - + resolve(diff(expected.toString(), results)), // list of files - expected.toString(), // expected result - results // result - ); - } finally { - // cleanup the environment - (new java.io.File(cachefile)).delete(); - bft.deletePropertiesfile(); - } - } - - - @Test - public void testScenarioCoreSelectorDefaults() { - Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") ); - doScenarioTest("modifiedselectortest-scenario-coreselector-defaults", "cache.properties"); - } - - - @Test - public void testScenarioCoreSelectorSettings() { - Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") ); - doScenarioTest("modifiedselectortest-scenario-coreselector-settings", "core.cache.properties"); - } - - - @Test - public void testScenarioCustomSelectorSettings() { - Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") ); - doScenarioTest("modifiedselectortest-scenario-customselector-settings", "core.cache.properties"); - } - - - public void doScenarioTest(String target, String cachefilename) { - BFT bft = new BFT(); - bft.setUp(); - File cachefile = new File(selectorRule.getProject().getBaseDir(), cachefilename); - try { - // do the actions - bft.doTarget("modifiedselectortest-scenario-clean"); - bft.doTarget(target); - - // the directories to check - File to1 = new File(selectorRule.getOutputDir(), "selectortest/to-1"); - File to2 = new File(selectorRule.getOutputDir(), "selectortest/to-2"); - File to3 = new File(selectorRule.getOutputDir(), "selectortest/to-3"); - - // do the checks - assertTrue("Cache file not created.", cachefile.exists()); - assertTrue("Not enough files copied on first time.", to1.list().length>5); - assertTrue("Too much files copied on second time.", to2.list().length==0); - assertTrue("Too much files copied on third time.", to3.list().length==2); - // don't catch the JUnit exceptions - } finally { - bft.doTarget("modifiedselectortest-scenario-clean"); - bft.deletePropertiesfile(); - bft.tearDown(); - cachefile.delete(); - } - } - - - // ===================== helper methods and classes ==================== - - - /** - * Creates a configured parameter object. - * @param name name of the parameter - * @param value value of the parameter - * @return the parameter object - */ - private Parameter createParam(String name, String value) { - Parameter p = new Parameter(); - p.setName(name); - p.setValue(value); - return p; - } - - - /** - * The BFT class wrapps the selector test-builfile inside an - * ant project. It supports target execution - * and property transfer to that project. - */ - private class BFT extends BuildFileRule { - String buildfile = "src/etc/testcases/types/selectors.xml"; - - String propfile = "ModifiedSelectorTest.properties"; - - boolean isConfigured = false; - - - public void setUp() { - super.configureProject(buildfile); - isConfigured = true; - } - - - /** - * This stub teardown is here because the outer class needs to call the - * tearDown method, and in the superclass it is protected. - */ - public void tearDown() { - super.after(); - - } - - public void doTarget(String target) { - if (!isConfigured) setUp(); - executeTarget(target); - } - - public String getProperty(String property) { - return super.getProject().getProperty(property); - } - - public void writeProperties(String line) { - if (!isConfigured) setUp(); - File dir = getProject().getBaseDir(); - File file = new File(dir, propfile); - try { - java.io.FileWriter out = - new java.io.FileWriter(file.getAbsolutePath(), true); - out.write(line); - out.write(System.getProperty("line.separator")); - out.flush(); - out.close(); - } catch (Exception e) { - e.printStackTrace(); - } - } - - public void deletePropertiesfile() { - if (!isConfigured) setUp(); - new File(getProject().getBaseDir(), propfile).delete(); - } - - public void deleteCachefile() { - File basedir = new File(buildfile).getParentFile(); - File cacheFile = new File(basedir, "cache.properties"); - cacheFile.delete(); - } - - }//class-BFT - - - /** - * MockProject wrappes a very small ant project (one target, one task) - * but provides public methods to fire the build events. - */ - private class MockProject extends Project { - private Task task; - private Target target; - - public MockProject() { - task = new Task(){ - public void execute() { - } - }; - task.setTaskName("testTask"); - target = new Target(); - target.setName("testTarget"); - target.setProject(this); - target.addTask(task); - task.setOwningTarget(target); - } - - public void fireBuildFinished() { - super.fireBuildFinished(null); - } - public void fireSubBuildFinished() { - super.fireSubBuildFinished(null); - } - public void fireTargetStarted() { - super.fireTargetStarted(target); - } - public void fireTargetFinished() { - super.fireTargetFinished(target, null); - } - public void fireTaskStarted() { - super.fireTaskStarted(task); - } - public void fireTaskFinished() { - super.fireTaskFinished(task, null); - } - }//class-MockProject - - - /** - * Does the selection test for a given selector and prints the - * filenames of the differing files (selected but shouldn't, - * not selected but should). - * @param selector The selector to test - * @param expected The expected result - */ - private void performTests(FileSelector selector, String expected) { - String result = selectorRule.selectionString(selector); - String diff = diff(expected, result); - String resolved = resolve(diff); - assertEquals("Differing files: " + resolved, result, expected); - } - /** - * Checks which files are selected and shouldn't be or which - * are not selected but should. - * @param expected String containing 'F's and 'T's - * @param result String containing 'F's and 'T's - * @return Difference as String containing '-' (equal) and - * 'X' (difference). - */ - private String diff(String expected, String result) { - int length1 = expected.length(); - int length2 = result.length(); - int min = (length1 > length2) ? length2 : length1; - StringBuffer sb = new StringBuffer(); - for (int i=0; i<min; i++) { - sb.append( - (expected.charAt(i) == result.charAt(i)) - ? "-" - : "X" - ); - } - return sb.toString(); - } - - /** - * Resolves a diff-String (@see diff()) against the (inherited) filenames- - * and files arrays. - * @param filelist Diff-String - * @return String containing the filenames for all differing files, - * separated with semicolons ';' - */ - private String resolve(String filelist) { - StringBuffer sb = new StringBuffer(); - int min = (selectorRule.getFilenames().length > filelist.length()) - ? filelist.length() - : selectorRule.getFilenames().length; - for (int i=0; i<min; i++) { - if ('X'==filelist.charAt(i)) { - sb.append(selectorRule.getFilenames()[i]); - sb.append(";"); - } - } - return sb.toString(); - } - - -}//class-ModifiedSelectorTest +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.tools.ant.types.selectors; + + +// Java +import java.io.File; +import java.text.RuleBasedCollator; +import java.util.Comparator; +import java.util.Iterator; + +import org.apache.tools.ant.AntAssert; +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.BuildFileRule; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.Target; +import org.apache.tools.ant.Task; +import org.apache.tools.ant.types.Parameter; +import org.apache.tools.ant.types.Path; +import org.apache.tools.ant.types.selectors.modifiedselector.Algorithm; +import org.apache.tools.ant.types.selectors.modifiedselector.Cache; +import org.apache.tools.ant.types.selectors.modifiedselector.ChecksumAlgorithm; +import org.apache.tools.ant.types.selectors.modifiedselector.DigestAlgorithm; +import org.apache.tools.ant.types.selectors.modifiedselector.EqualComparator; +import org.apache.tools.ant.types.selectors.modifiedselector.HashvalueAlgorithm; +import org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector; +import org.apache.tools.ant.types.selectors.modifiedselector.PropertiesfileCache; +import org.apache.tools.ant.util.FileUtils; +import org.junit.Assume; +import org.junit.Before; +import org.junit.Ignore; +import org.junit.Rule; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + + +/** + * Unit tests for ModifiedSelector. + * + * @since Ant 1.6 + */ +public class ModifiedSelectorTest { + + @Rule + public final BaseSelectorRule selectorRule = new BaseSelectorRule(); + + /** Utilities used for file operations */ + private static final FileUtils FILE_UTILS = FileUtils.getFileUtils(); + + // ===================== attributes ===================== + + + /** Path where the testclasses are. */ + private Path testclasses = null; + + + + + // ===================== JUnit stuff ===================== + + + @Before + public void setUp() { + // init the testclasses path object + Project prj = selectorRule.getProject(); + testclasses = new Path(prj, prj.getProperty("build.tests.value")); + } + + + // ======= testcases for the attributes and nested elements of the selector ===== + + + /** Test right use of cache names. */ + @Test + public void testValidateWrongCache() { + String name = "this-is-not-a-valid-cache-name"; + try { + ModifiedSelector.CacheName cacheName = new ModifiedSelector.CacheName(); + cacheName.setValue(name); + fail("CacheSelector.CacheName accepted invalid value."); + } catch (BuildException be) { + assertEquals(name + " is not a legal value for this attribute", + be.getMessage()); + } + } + + + /** Test right use of cache names. */ + @Test + public void testValidateWrongAlgorithm() { + String name = "this-is-not-a-valid-algorithm-name"; + try { + ModifiedSelector.AlgorithmName algoName + = new ModifiedSelector.AlgorithmName(); + algoName.setValue(name); + fail("CacheSelector.AlgorithmName accepted invalid value."); + } catch (BuildException be) { + assertEquals(name + " is not a legal value for this attribute", + be.getMessage()); + } + } + + + /** Test right use of comparator names. */ + @Test + public void testValidateWrongComparator() { + String name = "this-is-not-a-valid-comparator-name"; + try { + ModifiedSelector.ComparatorName compName + = new ModifiedSelector.ComparatorName(); + compName.setValue(name); + fail("ModifiedSelector.ComparatorName accepted invalid value."); + } catch (BuildException be) { + assertEquals(name + " is not a legal value for this attribute", + be.getMessage()); + } + } + + + @Test + public void testIllegalCustomAlgorithm() { + try { + getAlgoName("java.lang.Object"); + fail("Illegal classname used."); + } catch (BuildException e) { + assertEquals("Wrong exception message.", + "Specified class (java.lang.Object) is not an Algorithm.", + e.getMessage()); + + } + } + + + @Test + public void testNonExistentCustomAlgorithm() { + try { + getAlgoName("non.existent.custom.Algorithm"); + fail("does 'non.existent.custom.Algorithm' really exist?"); + } catch (BuildException e) { + assertEquals("Wrong exception message.", + "Specified class (non.existent.custom.Algorithm) not found.", + e.getMessage()); + + } + } + + @Test + public void testCustomAlgorithm() { + String algo = getAlgoName("org.apache.tools.ant.types.selectors.modifiedselector.HashvalueAlgorithm"); + assertTrue("Wrong algorithm used: "+algo, algo.startsWith("HashvalueAlgorithm")); + } + + @Test + public void testCustomAlgorithm2() { + String algo = getAlgoName("org.apache.tools.ant.types.selectors.MockAlgorithm"); + assertTrue("Wrong algorithm used: "+algo, algo.startsWith("MockAlgorithm")); + } + + + @Test + public void testCustomClasses() { + Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") ); + BFT bft = new BFT(); + bft.setUp(); + try { + // do the actions + bft.doTarget("modifiedselectortest-customClasses"); + // do the checks - the buildfile stores the fileset as property + String fsFullValue = bft.getProperty("fs.full.value"); + String fsModValue = bft.getProperty("fs.mod.value"); + + assertNotNull("'fs.full.value' must be set.", fsFullValue); + assertTrue("'fs.full.value' must not be null.", !"".equals(fsFullValue)); + assertTrue("'fs.full.value' must contain ant.bat.", fsFullValue.indexOf("ant.bat")>-1); + + assertNotNull("'fs.mod.value' must be set.", fsModValue); + // must be empty according to the Mock* implementations + assertTrue("'fs.mod.value' must be empty.", "".equals(fsModValue)); + // don't catch the JUnit exceptions + } finally { + bft.doTarget("modifiedselectortest-scenario-clean"); + bft.deletePropertiesfile(); + bft.tearDown(); + } + } + + + @Test + public void testDelayUpdateTaskFinished() { + doDelayUpdateTest(1); + } + + + @Test + public void testDelayUpdateTargetFinished() { + doDelayUpdateTest(2); + } + + + @Test + public void testDelayUpdateBuildFinished() { + doDelayUpdateTest(3); + } + + + public void doDelayUpdateTest(int kind) { + // no check for 1<=kind<=3 - only internal use therefore check it + // while development + + // readable form of parameter kind + String[] kinds = {"task", "target", "build"}; + + // setup the "Ant project" + MockProject project = new MockProject(); + File base = new File("base"); + File file1 = new File("file1"); + File file2 = new File("file2"); + + // setup the selector + ModifiedSelector sel = new ModifiedSelector(); + sel.setProject(project); + sel.setUpdate(true); + sel.setDelayUpdate(true); + // sorry - otherwise we will get a ClassCastException because the MockCache + // is loaded by two different classloader ... + sel.setClassLoader(this.getClass().getClassLoader()); + sel.addClasspath(testclasses); + + sel.setAlgorithmClass("org.apache.tools.ant.types.selectors.MockAlgorithm"); + sel.setCacheClass("org.apache.tools.ant.types.selectors.MockCache"); + sel.configure(); + + // get the cache, so we can check our things + MockCache cache = (MockCache)sel.getCache(); + + // the test + assertFalse("Cache must not be saved before 1st selection.", cache.saved); + sel.isSelected(base, "file1", file1); + assertFalse("Cache must not be saved after 1st selection.", cache.saved); + sel.isSelected(base, "file2", file2); + assertFalse("Cache must not be saved after 2nd selection.", cache.saved); + switch (kind) { + case 1 : project.fireTaskFinished(); break; + case 2 : project.fireTargetFinished(); break; + case 3 : project.fireBuildFinished(); break; + } + assertTrue("Cache must be saved after " + kinds[kind-1] + "Finished-Event.", cache.saved); + + // MockCache doesnt create a file - therefore no cleanup needed + } + + + /** + * Extracts the real used algorithm name from the ModifiedSelector using + * its toString() method. + * @param classname the classname from the algorithm to use + * @return the algorithm part from the toString() (without brackets) + */ + private String getAlgoName(String classname) { + ModifiedSelector sel = new ModifiedSelector(); + sel.setProject(selectorRule.getProject()); + // add the test classes to its classpath + sel.addClasspath(testclasses); + sel.setAlgorithmClass(classname); + // let the selector do its checks + sel.validate(); + // extract the algorithm name (and config) from the selectors output + String s1 = sel.toString(); + int posStart = s1.indexOf("algorithm=") + 10; + int posEnd = s1.indexOf(" comparator="); + String algo = s1.substring(posStart, posEnd); + // '<' and '>' are only used if the algorithm has properties + if (algo.startsWith("<")) algo = algo.substring(1); + if (algo.endsWith(">")) algo = algo.substring(0, algo.length()-1); + // return the clean value + return algo; + } + + + // ================ testcases for the cache implementations ================ + + + /** + * Propertycache must have a set 'cachefile' attribute. + * The default in ModifiedSelector "cache.properties" is set by the selector. + */ + @Test + public void testPropcacheInvalid() { + Cache cache = new PropertiesfileCache(); + if (cache.isValid()) + fail("PropertyfilesCache does not check its configuration."); + } + + + @Test + public void testPropertyfileCache() { + PropertiesfileCache cache = new PropertiesfileCache(); + File cachefile = new File("cache.properties"); + cache.setCachefile(cachefile); + doTest(cache); + assertFalse("Cache file not deleted.", cachefile.exists()); + } + + + /** Checks whether a cache file is created. */ + @Test + public void testCreatePropertiesCacheDirect() { + File cachefile = new File(selectorRule.getProject().getBaseDir(), "cachefile.properties"); + + PropertiesfileCache cache = new PropertiesfileCache(); + cache.setCachefile(cachefile); + + cache.put("key", "value"); + cache.save(); + + assertTrue("Cachefile not created.", cachefile.exists()); + + cache.delete(); + assertFalse("Cachefile not deleted.", cachefile.exists()); + } + + + /** Checks whether a cache file is created. */ + @Test + public void testCreatePropertiesCacheViaModifiedSelector() { + File cachefile = new File(selectorRule.getProject().getBaseDir(), "cachefile.properties"); + + // Configure the selector + ModifiedSelector s = new ModifiedSelector(); + s.setDelayUpdate(false); + s.addParam("cache.cachefile", cachefile); + + ModifiedSelector.CacheName cacheName = new ModifiedSelector.CacheName(); + cacheName.setValue("propertyfile"); + s.setCache(cacheName); + + s.setUpdate(true); + + selectorRule.selectionString(s); + + // evaluate correctness + assertTrue("Cache file is not created.", cachefile.exists()); + cachefile.delete(); + + } + + + /** + * In earlier implementations there were problems with the <i>order</i> + * of the <param>s. The scenario was <pre> + * <custom class="ModifiedSelector"> + * <param name="cache.cachefile" value="mycache.properties" /> + * <param name="cache" value="propertyfiles" /> + * </custom> + * </pre> It was important first to set the cache and then to set + * the cache's configuration parameters. That results in the reorganized + * configure() method of ModifiedSelector. This testcase tests that. + */ + @Test + public void testCreatePropertiesCacheViaCustomSelector() { + File cachefile = FILE_UTILS.createTempFile("tmp-cache-", ".properties", null, false, false); + + // Configure the selector + + ExtendSelector s = new ExtendSelector(); + s.setClassname("org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector"); + s.addParam(createParam("update", "true")); + s.addParam(createParam("cache.cachefile", cachefile.getAbsolutePath())); + s.addParam(createParam("cache", "propertyfile")); + + selectorRule.selectionString(s); + + // evaluate correctness + assertTrue("Cache file is not created.", cachefile.exists()); + cachefile.delete(); + + } + + + @Test + @Ignore("same logic as on algorithm, no testcases created") + public void testCustomCache() { + // same logic as on algorithm, no testcases created + } + + + /** + * Test the interface semantic of Caches. + * This method does some common test for cache implementations. + * A cache must return a stored value and a valid iterator. + * After calling the delete() the cache must be empty. + * + * @param cache configured test object + */ + protected void doTest(Cache cache) { + assertTrue("Cache not proper configured.", cache.isValid()); + + String key1 = "key1"; + String value1 = "value1"; + String key2 = "key2"; + String value2 = "value2"; + + // given cache must be empty + Iterator it1 = cache.iterator(); + assertFalse("Cache is not empty", it1.hasNext()); + + // cache must return a stored value + cache.put(key1, value1); + cache.put(key2, value2); + assertEquals("cache returned wrong value", value1, cache.get(key1)); + assertEquals("cache returned wrong value", value2, cache.get(key2)); + + // test the iterator + Iterator it2 = cache.iterator(); + Object returned = it2.next(); + boolean ok = (key1.equals(returned) || key2.equals(returned)); + String msg = "Iterator returned unexpected value." + + " key1.equals(returned)="+key1.equals(returned) + + " key2.equals(returned)="+key2.equals(returned) + + " returned="+returned + + " ok="+ok; + assertTrue(msg, ok); + + // clear the cache + cache.delete(); + Iterator it3 = cache.iterator(); + assertFalse("Cache is not empty", it3.hasNext()); + } + + + // ============== testcases for the algorithm implementations ============== + + + @Test + public void testHashvalueAlgorithm() { + HashvalueAlgorithm algo = new HashvalueAlgorithm(); + doTest(algo); + } + + + @Test + public void testDigestAlgorithmMD5() { + DigestAlgorithm algo = new DigestAlgorithm(); + algo.setAlgorithm("MD5"); + doTest(algo); + } + + + @Test + public void testDigestAlgorithmSHA() { + DigestAlgorithm algo = new DigestAlgorithm(); + algo.setAlgorithm("SHA"); + doTest(algo); + } + + + @Test + public void testChecksumAlgorithm() { + ChecksumAlgorithm algo = new ChecksumAlgorithm(); + doTest(algo); + } + + + @Test + public void testChecksumAlgorithmCRC() { + ChecksumAlgorithm algo = new ChecksumAlgorithm(); + algo.setAlgorithm("CRC"); + doTest(algo); + } + + + @Test + public void testChecksumAlgorithmAdler() { + ChecksumAlgorithm algo = new ChecksumAlgorithm(); + algo.setAlgorithm("Adler"); + doTest(algo); + } + + + /** + * Test the interface semantic of Algorithms. + * This method does some common test for algorithm implementations. + * An algorithm must return always the same value for the same file and + * it must not return <i>null</i>. + * + * @param algo configured test object + */ + protected void doTest(Algorithm algo) { + assertTrue("Algorithm not proper configured.", algo.isValid()); + for (int i=0; i<selectorRule.getFiles().length; i++) { + File file = selectorRule.getFiles()[i]; // must not be a directory + if (file.isFile()) { + // get the Hashvalues + String hash1 = algo.getValue(file); + String hash2 = algo.getValue(file); + String hash3 = algo.getValue(file); + String hash4 = algo.getValue(file); + String hash5 = algo.getValue(new File(file.getAbsolutePath())); + + // Assert !=null and equality + assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash1); + assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash2); + assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash3); + assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash4); + assertNotNull("Hashvalue was null for "+file.getAbsolutePath(), hash5); + assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash2); + assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash3); + assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash4); + assertEquals("getHashvalue() returned different value for "+file.getAbsolutePath(), hash1, hash5); + }//if-isFile + }//for + + } + + + + // ============== testcases for the comparator implementations ============== + + + @Test + public void testEqualComparator() { + EqualComparator comp = new EqualComparator(); + doTest(comp); + } + + + @Test + public void testRuleComparator() { + RuleBasedCollator comp = (RuleBasedCollator)RuleBasedCollator.getInstance(); + doTest(comp); + } + + + @Test + public void testEqualComparatorViaSelector() { + ModifiedSelector s = new ModifiedSelector(); + ModifiedSelector.ComparatorName compName = new ModifiedSelector.ComparatorName(); + compName.setValue("equal"); + s.setComparator(compName); + try { + performTests(s, "TTTTTTTTTTTT"); + } finally { + s.getCache().delete(); + } + } + + + @Test + @Ignore("not yet supported see note in selector") + public void testRuleComparatorViaSelector() { + ModifiedSelector s = new ModifiedSelector(); + ModifiedSelector.ComparatorName compName = new ModifiedSelector.ComparatorName(); + compName.setValue("rule"); + s.setComparator(compName); + try { + performTests(s, "TTTTTTTTTTTT"); + } finally { + s.getCache().delete(); + } + } + + + @Test + @Ignore("same logic as on algorithm, no testcases created") + public void testCustomComparator() { + // same logic as on algorithm, no testcases created + } + + + @Test + public void testResourceSelectorSimple() { + BFT bft = new BFT(); + bft.doTarget("modifiedselectortest-ResourceSimple"); + bft.deleteCachefile(); + //new File("src/etc/testcases/types/resources/selectors/cache.properties").delete(); + } + + @Test + public void testResourceSelectorSelresTrue() { + BFT bft = new BFT(); + bft.doTarget("modifiedselectortest-ResourceSelresTrue"); + AntAssert.assertContains("does not provide an InputStream", bft.getLog()); + bft.deleteCachefile(); + } + + @Test + public void testResourceSelectorSelresFalse() { + BFT bft = new BFT(); + bft.doTarget("modifiedselectortest-ResourceSelresFalse"); + bft.deleteCachefile(); + } + + @Test + public void testResourceSelectorScenarioSimple() { + + Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home")); + BFT bft = new BFT(); + bft.doTarget("modifiedselectortest-scenario-resourceSimple"); + bft.doTarget("modifiedselectortest-scenario-clean"); + bft.deleteCachefile(); + } + + /** + * Test the interface semantic of Comparators. + * This method does some common test for comparator implementations. + * + * @param comp configured test object + */ + protected void doTest(Comparator comp) { + Object o1 = new String("string1"); + Object o2 = new String("string2"); + Object o3 = new String("string2"); // really "2" + + assertTrue("Comparator gave wrong value.", comp.compare(o1, o2) != 0); + assertTrue("Comparator gave wrong value.", comp.compare(o1, o3) != 0); + assertTrue("Comparator gave wrong value.", comp.compare(o2, o3) == 0); + } + + + // ===================== scenario tests ===================== + + + /** + * Tests whether the seldirs attribute is used. + */ + @Test + public void testSeldirs() { + ModifiedSelector s = new ModifiedSelector(); + StringBuffer sbTrue = new StringBuffer(); + StringBuffer sbFalse = new StringBuffer(); + for (int i=0; i<selectorRule.getFiles().length; i++) { + if (selectorRule.getFiles()[i].isDirectory()) { + sbTrue.append("T"); + sbFalse.append("F"); + } else { + sbTrue.append("T"); + sbFalse.append("T"); + } + } + + s.setSeldirs(true); + performTests(s, sbTrue.toString()); + s.getCache().delete(); + + s.setSeldirs(false); + performTests(s, sbFalse.toString()); + s.getCache().delete(); + + s.getCache().delete(); + } + + + /** + * Complex test scenario using default values (DigestAlgorithm with MD5, + * PropertiesfileCache with file=cache.properties, EqualComparator + * and update=true). <ol> + * <li> try fist time --> should select all </li> + * <li> try second time --> should select no files (only directories) </li> + * <li> modify timestamp of one file and content of a nother one </li> + * <li> try third time --> should select only the file with modified + * content </li> + */ + @Test + public void testScenario1() { + BFT bft = null; + ModifiedSelector s = null; + try { + + String results; + + // Configure the selector - only defaults are used + s = new ModifiedSelector(); + + // + // ***** First Run ***** + // the first call should get all files, because nothing is in + // the cache + // + performTests(s, "TTTTTTTTTTTT"); + + // + // ***** Second Run ***** + // the second call should get no files, because no content + // has changed + // + performTests(s, "TFFFFFFFFFFT"); + + // + // ***** make some files dirty ***** + // + + // these files are made dirty --> 3+4 with different content + String f2name = "tar/bz2/asf-logo-huge.tar.bz2"; + String f3name = "asf-logo.gif.md5"; + String f4name = "copy.filterset.filtered"; + + // AccessObject to the test-Ant-environment + bft = new BFT(); + // give some values (via property file) to that environment + bft.writeProperties("f2name="+f2name); + bft.writeProperties("f3name="+f3name); + bft.writeProperties("f4name="+f4name); + // call the target for making the files dirty + bft.doTarget("modifiedselectortest-makeDirty"); + + // + // ***** Third Run ***** + // third call should get only those files, which CONTENT changed + // (no timestamp changes required!) + results = selectorRule.selectionString(s); + + // + // ***** Check the result ***** + // + + // Mark all files which should be selected as (T)rue and all others + // as (F)alse. Directories are always selected so they always are + // (T)rue. + StringBuffer expected = new StringBuffer(); + for (int i=0; i<selectorRule.getFiles().length; i++) { + String ch = "F"; + if (selectorRule.getFiles()[i].isDirectory()) ch = "T"; + // f2name shouldn't be selected: only timestamp has changed! + if (selectorRule.getFilenames()[i].equalsIgnoreCase(f3name)) ch = "T"; + if (selectorRule.getFilenames()[i].equalsIgnoreCase(f4name)) ch = "T"; + expected.append(ch); + } + + assertEquals( + "Wrong files selected. Differing files: " // info text + + resolve(diff(expected.toString(), results)), // list of files + expected.toString(), // expected result + results // result + ); + + } finally { + // cleanup the environment + if (s!=null) s.getCache().delete(); + if (bft!=null) bft.deletePropertiesfile(); + } + } + + + /** + * This scenario is based on scenario 1, but does not use any + * default value and its based on <custom> selector. Used values are:<ul> + * <li><b>Cache: </b> Propertyfile, + * cachefile={java.io.tmpdir}/mycache.txt </li> + * <li><b>Algorithm: </b> Digest + * algorithm=SHA, Provider=null </li> + * <li><b>Comparator: </b> java.text.RuleBasedCollator + * <li><b>Update: </b> true </li> + */ + @Test + @Ignore("RuleBasedCollator not yet supported - see Selector:375 note") + public void testScenario2() { + ExtendSelector s = new ExtendSelector(); + BFT bft = new BFT(); + String cachefile = System.getProperty("java.io.tmpdir")+"/mycache.txt"; + try { + + s.setClassname("org.apache.tools.ant.types.selectors.modifiedselector.ModifiedSelector"); + + s.addParam(createParam("cache.cachefile", cachefile)); + //s.addParam(createParam("algorithm.provider","---")); // i don't know any valid + s.addParam(createParam("cache","propertyfile")); + s.addParam(createParam("update","true")); + s.addParam(createParam("comparator","rule")); + s.addParam(createParam("algorithm.name","sha")); + s.addParam(createParam("algorithm","digest")); + + // first and second run + performTests(s, "TTTTTTTTTTTT"); + performTests(s, "TFFFFFFFFFFT"); + // make dirty + String f2name = "tar/bz2/asf-logo-huge.tar.bz2"; + String f3name = "asf-logo.gif.md5"; + String f4name = "copy.filterset.filtered"; + bft.writeProperties("f2name="+f2name); + bft.writeProperties("f3name="+f3name); + bft.writeProperties("f4name="+f4name); + bft.doTarget("modifiedselectortest-makeDirty"); + // third run + String results = selectorRule.selectionString(s); + StringBuffer expected = new StringBuffer(); + for (int i=0; i<selectorRule.getFilenames().length; i++) { + String ch = "F"; + if (selectorRule.getFiles()[i].isDirectory()) ch = "T"; + if (selectorRule.getFilenames()[i].equalsIgnoreCase(f3name)) ch = "T"; + if (selectorRule.getFilenames()[i].equalsIgnoreCase(f4name)) ch = "T"; + expected.append(ch); + } + assertEquals( + "Wrong files selected. Differing files: " // info text + + resolve(diff(expected.toString(), results)), // list of files + expected.toString(), // expected result + results // result + ); + } finally { + // cleanup the environment + (new java.io.File(cachefile)).delete(); + bft.deletePropertiesfile(); + } + } + + + @Test + public void testScenarioCoreSelectorDefaults() { + Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") ); + doScenarioTest("modifiedselectortest-scenario-coreselector-defaults", "cache.properties"); + } + + + @Test + public void testScenarioCoreSelectorSettings() { + Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") ); + doScenarioTest("modifiedselectortest-scenario-coreselector-settings", "core.cache.properties"); + } + + + @Test + public void testScenarioCustomSelectorSettings() { + Assume.assumeNotNull("Ant home not set", selectorRule.getProject().getProperty("ant.home") ); + doScenarioTest("modifiedselectortest-scenario-customselector-settings", "core.cache.properties"); + } + + + public void doScenarioTest(String target, String cachefilename) { + BFT bft = new BFT(); + bft.setUp(); + File cachefile = new File(selectorRule.getProject().getBaseDir(), cachefilename); + try { + // do the actions + bft.doTarget("modifiedselectortest-scenario-clean"); + bft.doTarget(target); + + // the directories to check + File to1 = new File(selectorRule.getOutputDir(), "selectortest/to-1"); + File to2 = new File(selectorRule.getOutputDir(), "selectortest/to-2"); + File to3 = new File(selectorRule.getOutputDir(), "selectortest/to-3"); + + // do the checks + assertTrue("Cache file not created.", cachefile.exists()); + assertTrue("Not enough files copied on first time.", to1.list().length>5); + assertTrue("Too much files copied on second time.", to2.list().length==0); + assertTrue("Too much files copied on third time.", to3.list().length==2); + // don't catch the JUnit exceptions + } finally { + bft.doTarget("modifiedselectortest-scenario-clean"); + bft.deletePropertiesfile(); + bft.tearDown(); + cachefile.delete(); + } + } + + + // ===================== helper methods and classes ==================== + + + /** + * Creates a configured parameter object. + * @param name name of the parameter + * @param value value of the parameter + * @return the parameter object + */ + private Parameter createParam(String name, String value) { + Parameter p = new Parameter(); + p.setName(name); + p.setValue(value); + return p; + } + + + /** + * The BFT class wrapps the selector test-builfile inside an + * ant project. It supports target execution + * and property transfer to that project. + */ + private class BFT extends BuildFileRule { + String buildfile = "src/etc/testcases/types/selectors.xml"; + + String propfile = "ModifiedSelectorTest.properties"; + + boolean isConfigured = false; + + + public void setUp() { + super.configureProject(buildfile); + isConfigured = true; + } + + + /** + * This stub teardown is here because the outer class needs to call the + * tearDown method, and in the superclass it is protected. + */ + public void tearDown() { + super.after(); + + } + + public void doTarget(String target) { + if (!isConfigured) setUp(); + executeTarget(target); + } + + public String getProperty(String property) { + return super.getProject().getProperty(property); + } + + public void writeProperties(String line) { + if (!isConfigured) setUp(); + File dir = getProject().getBaseDir(); + File file = new File(dir, propfile); + try { + java.io.FileWriter out = + new java.io.FileWriter(file.getAbsolutePath(), true); + out.write(line); + out.write(System.getProperty("line.separator")); + out.flush(); + out.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void deletePropertiesfile() { + if (!isConfigured) setUp(); + new File(getProject().getBaseDir(), propfile).delete(); + } + + public void deleteCachefile() { + File basedir = new File(buildfile).getParentFile(); + File cacheFile = new File(basedir, "cache.properties"); + cacheFile.delete(); + } + + }//class-BFT + + + /** + * MockProject wrappes a very small ant project (one target, one task) + * but provides public methods to fire the build events. + */ + private class MockProject extends Project { + private Task task; + private Target target; + + public MockProject() { + task = new Task(){ + public void execute() { + } + }; + task.setTaskName("testTask"); + target = new Target(); + target.setName("testTarget"); + target.setProject(this); + target.addTask(task); + task.setOwningTarget(target); + } + + public void fireBuildFinished() { + super.fireBuildFinished(null); + } + public void fireSubBuildFinished() { + super.fireSubBuildFinished(null); + } + public void fireTargetStarted() { + super.fireTargetStarted(target); + } + public void fireTargetFinished() { + super.fireTargetFinished(target, null); + } + public void fireTaskStarted() { + super.fireTaskStarted(task); + } + public void fireTaskFinished() { + super.fireTaskFinished(task, null); + } + }//class-MockProject + + + /** + * Does the selection test for a given selector and prints the + * filenames of the differing files (selected but shouldn't, + * not selected but should). + * @param selector The selector to test + * @param expected The expected result + */ + private void performTests(FileSelector selector, String expected) { + String result = selectorRule.selectionString(selector); + String diff = diff(expected, result); + String resolved = resolve(diff); + assertEquals("Differing files: " + resolved, result, expected); + } + /** + * Checks which files are selected and shouldn't be or which + * are not selected but should. + * @param expected String containing 'F's and 'T's + * @param result String containing 'F's and 'T's + * @return Difference as String containing '-' (equal) and + * 'X' (difference). + */ + private String diff(String expected, String result) { + int length1 = expected.length(); + int length2 = result.length(); + int min = (length1 > length2) ? length2 : length1; + StringBuffer sb = new StringBuffer(); + for (int i=0; i<min; i++) { + sb.append( + (expected.charAt(i) == result.charAt(i)) + ? "-" + : "X" + ); + } + return sb.toString(); + } + + /** + * Resolves a diff-String (@see diff()) against the (inherited) filenames- + * and files arrays. + * @param filelist Diff-String + * @return String containing the filenames for all differing files, + * separated with semicolons ';' + */ + private String resolve(String filelist) { + StringBuffer sb = new StringBuffer(); + int min = (selectorRule.getFilenames().length > filelist.length()) + ? filelist.length() + : selectorRule.getFilenames().length; + for (int i=0; i<min; i++) { + if ('X'==filelist.charAt(i)) { + sb.append(selectorRule.getFilenames()[i]); + sb.append(";"); + } + } + return sb.toString(); + } + + +}//class-ModifiedSelectorTest
http://git-wip-us.apache.org/repos/asf/ant/blob/1ae68097/src/tests/junit/org/apache/tools/ant/types/selectors/PresentSelectorTest.java ---------------------------------------------------------------------- diff --git a/src/tests/junit/org/apache/tools/ant/types/selectors/PresentSelectorTest.java b/src/tests/junit/org/apache/tools/ant/types/selectors/PresentSelectorTest.java index e96a675..f93e101 100644 --- a/src/tests/junit/org/apache/tools/ant/types/selectors/PresentSelectorTest.java +++ b/src/tests/junit/org/apache/tools/ant/types/selectors/PresentSelectorTest.java @@ -1,137 +1,137 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You 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 org.apache.tools.ant.types.selectors; - -import org.apache.tools.ant.BuildException; -import org.apache.tools.ant.types.Mapper; -import org.junit.Rule; -import org.junit.Test; - -import java.io.File; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.fail; - - -/** - * Tests Present Selectors - * - */ -public class PresentSelectorTest { - - - @Rule - public final BaseSelectorRule selectorRule = new BaseSelectorRule(); - - /** - * Test the code that validates the selector. - */ - @Test - public void testValidate() { - PresentSelector s = new PresentSelector(); - try { - s.createMapper(); - s.createMapper(); - fail("PresentSelector allowed more than one nested mapper."); - } catch (BuildException be1) { - assertEquals("Cannot define more than one mapper", - be1.getMessage()); - } - - s = new PresentSelector(); - try { - s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]); - fail("PresentSelector did not check for required fields"); - } catch (BuildException be2) { - assertEquals("The targetdir attribute is required.", - be2.getMessage()); - } - - } - - /** - * Tests to make sure that the selector is selecting files correctly. - */ - @Test - public void testSelectionBehaviour() { - PresentSelector s; - String results; - Mapper m; - Mapper.MapperType identity = new Mapper.MapperType(); - identity.setValue("identity"); - Mapper.MapperType glob = new Mapper.MapperType(); - glob.setValue("glob"); - Mapper.MapperType merge = new Mapper.MapperType(); - merge.setValue("merge"); - Mapper.MapperType flatten = new Mapper.MapperType(); - flatten.setValue("flatten"); - - File beddir = selectorRule.getBeddir(); - - s = new PresentSelector(); - s.setTargetdir(beddir); - results = selectorRule.selectionString(s); - assertEquals("TTTTTTTTTTTT", results); - - s = new PresentSelector(); - s.setTargetdir(beddir); - m = s.createMapper(); - m.setType(identity); - results = selectorRule.selectionString(s); - assertEquals("TTTTTTTTTTTT", results); - - s = new PresentSelector(); - File subdir = new File(System.getProperty("root"), "src/etc/testcases/taskdefs/expected"); - s.setTargetdir(subdir); - m = s.createMapper(); - m.setType(flatten); - results = selectorRule.selectionString(s); - assertEquals("TTTTTTTTTTTF", results); - - s = new PresentSelector(); - s.setTargetdir(beddir); - m = s.createMapper(); - m.setType(merge); - m.setTo("asf-logo.gif.gz"); - results = selectorRule.selectionString(s); - assertEquals("TTTTTTTTTTTT", results); - - s = new PresentSelector(); - subdir = new File(beddir, "tar/bz2"); - s.setTargetdir(subdir); - m = s.createMapper(); - m.setType(glob); - m.setFrom("*.bz2"); - m.setTo("*.tar.bz2"); - results = selectorRule.selectionString(s); - assertEquals("FFTFFFFFFFFF", results); - - - s = new PresentSelector(); - subdir = new File(selectorRule.getOutputDir(), "selectortest2"); - s.setTargetdir(subdir); - results = selectorRule.selectionString(s); - assertEquals("TTTFFTTTTTTT", results); - results = selectorRule.selectionString(s); - assertEquals("TTTFFTTTTTTT", results); - - - } - -} +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.tools.ant.types.selectors; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.types.Mapper; +import org.junit.Rule; +import org.junit.Test; + +import java.io.File; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; + + +/** + * Tests Present Selectors + * + */ +public class PresentSelectorTest { + + + @Rule + public final BaseSelectorRule selectorRule = new BaseSelectorRule(); + + /** + * Test the code that validates the selector. + */ + @Test + public void testValidate() { + PresentSelector s = new PresentSelector(); + try { + s.createMapper(); + s.createMapper(); + fail("PresentSelector allowed more than one nested mapper."); + } catch (BuildException be1) { + assertEquals("Cannot define more than one mapper", + be1.getMessage()); + } + + s = new PresentSelector(); + try { + s.isSelected(selectorRule.getProject().getBaseDir(),selectorRule.getFilenames()[0],selectorRule.getFiles()[0]); + fail("PresentSelector did not check for required fields"); + } catch (BuildException be2) { + assertEquals("The targetdir attribute is required.", + be2.getMessage()); + } + + } + + /** + * Tests to make sure that the selector is selecting files correctly. + */ + @Test + public void testSelectionBehaviour() { + PresentSelector s; + String results; + Mapper m; + Mapper.MapperType identity = new Mapper.MapperType(); + identity.setValue("identity"); + Mapper.MapperType glob = new Mapper.MapperType(); + glob.setValue("glob"); + Mapper.MapperType merge = new Mapper.MapperType(); + merge.setValue("merge"); + Mapper.MapperType flatten = new Mapper.MapperType(); + flatten.setValue("flatten"); + + File beddir = selectorRule.getBeddir(); + + s = new PresentSelector(); + s.setTargetdir(beddir); + results = selectorRule.selectionString(s); + assertEquals("TTTTTTTTTTTT", results); + + s = new PresentSelector(); + s.setTargetdir(beddir); + m = s.createMapper(); + m.setType(identity); + results = selectorRule.selectionString(s); + assertEquals("TTTTTTTTTTTT", results); + + s = new PresentSelector(); + File subdir = new File(System.getProperty("root"), "src/etc/testcases/taskdefs/expected"); + s.setTargetdir(subdir); + m = s.createMapper(); + m.setType(flatten); + results = selectorRule.selectionString(s); + assertEquals("TTTTTTTTTTTF", results); + + s = new PresentSelector(); + s.setTargetdir(beddir); + m = s.createMapper(); + m.setType(merge); + m.setTo("asf-logo.gif.gz"); + results = selectorRule.selectionString(s); + assertEquals("TTTTTTTTTTTT", results); + + s = new PresentSelector(); + subdir = new File(beddir, "tar/bz2"); + s.setTargetdir(subdir); + m = s.createMapper(); + m.setType(glob); + m.setFrom("*.bz2"); + m.setTo("*.tar.bz2"); + results = selectorRule.selectionString(s); + assertEquals("FFTFFFFFFFFF", results); + + + s = new PresentSelector(); + subdir = new File(selectorRule.getOutputDir(), "selectortest2"); + s.setTargetdir(subdir); + results = selectorRule.selectionString(s); + assertEquals("TTTFFTTTTTTT", results); + results = selectorRule.selectionString(s); + assertEquals("TTTFFTTTTTTT", results); + + + } + +}
