/** * 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.lens.server.util; import static org.testng.Assert.assertEquals; import static org.testng.Assert.assertFalse; import java.io.File; import java.io.IOException; import java.io.PrintWriter; import java.util.*; import org.apache.commons.io.FileUtils; import org.testng.annotations.Test; import com.google.common.base.Joiner; import lombok.extern.slf4j.Slf4j; @Slf4j @Test(groups = "unit-test") public class TestScannedPaths { public void testScannedPaths() throws Exception { String filenameA, filenameB, fileRegex; String tempPath = "target/tempfiles/"; ScannedPaths sc; try { filenameA = "tempdata_a"; filenameB = "tempdata_b"; fileRegex = tempPath + "tempdata_*"; createNewPath(tempPath + filenameA); createNewPath(tempPath + filenameB); sc = new ScannedPaths(fileRegex, "file"); assertUnOrdered(sc, filenameA, filenameB); /** * Testing negative Scenario **/ fileRegex = tempPath + "tempdata_unknown_*"; sc = new ScannedPaths(fileRegex, "file"); assertFalse(sc.iterator().hasNext(), "Iterator should be empty for unmatched path patterns."); } finally { FileUtils.deleteQuietly(new File(tempPath)); } } public void testScannedPathsJarGlobOrder() throws Exception { File jarFile, globFile; String filenameA, filenameB, filenameC, fileRegex; String tempPath = "target/tempfiles/"; ScannedPaths sc; PrintWriter writer; try { filenameA = "tempdata_a.jar"; filenameB = "tempdata_b.jar"; filenameC = "tempdata_c.data"; fileRegex = tempPath; createNewPath(tempPath + filenameA); createNewPath(tempPath + filenameB); createNewPath(tempPath + filenameC); /** Test jar_order **/ jarFile = createNewPath(tempPath + "jar_order"); writer = new PrintWriter(jarFile, "UTF-8"); writer.println(filenameB); writer.println(filenameA); writer.close(); sc = new ScannedPaths(fileRegex, "jar"); assertOrdered(sc, filenameB, filenameA); /** Test glob_order **/ if (jarFile != null) { jarFile.delete(); } globFile = createNewPath(tempPath + "glob_order"); writer = new PrintWriter(globFile, "UTF-8"); writer.println(filenameB); writer.println(filenameA); writer.println(filenameC); writer.close(); sc = new ScannedPaths(fileRegex, "file"); assertOrdered(sc, filenameB, filenameA, filenameC); } finally { FileUtils.deleteQuietly(new File(tempPath)); } } /** * Private method used by testScannedPathsMultipleJarGlobOrder. * Creates temp dir structure with files. * * Dir structure created: * sourceDirPath/tempfiles/tempdata_a.jar * sourceDirPath/tempfiles/tempdata_c.jar * sourceDirPath/tempfiles/dir1/tempdata_a.jar * sourceDirPath/tempfiles + "-duplicate"/dir1/tempdata_b.jar * sourceDirPath/tempfiles/dir1/tempdata_c.data * sourceDirPath/tempfiles/dir2/tempdata_a.data * sourceDirPath/tempfiles/dir2/tempdata_b.data * sourceDirPath/tempfiles/dir2/tempdata_c.jar * sourceDirPath/tempfiles/dir3/tempdata_a.jar * sourceDirPath/tempfiles/dir3/tempdata_b.data * sourceDirPath/tempfiles/dir3/tempdata_c-duplicate.jar * sourceDirPath/tempfiles/dir3/tempdata_c.jar * * // Additional regex checks for regex in jar_order/glob_order * sourceDirPath/tempfiles/dir3/innerDirA/inceptionLevel2/tempdata_c.jar * sourceDirPath/tempfiles/dir3/innerDirA/inceptionLevel2/tempdata_c-duplicate.jar * sourceDirPath/tempfiles/dir3/innerDirB/inceptionLevel2/tempdata_c-duplicate-2.jar * @param sourceDirPath */ private void createTempDirStructure1(String sourceDirPath) throws IOException { File jarFile, globFile; String filenameA, filenameB, filenameC; String tempPath = sourceDirPath + "/tempfiles/"; FileUtils.deleteQuietly(new File(tempPath)); String jarExtension = ".jar"; String dataExtension = ".data"; String dir1 = "dir1/", dir2 = "dir2/", dir3 = "dir3/"; filenameA = "tempdata_a"; filenameB = "tempdata_b"; filenameC = "tempdata_c"; PrintWriter writer; createNewPath(tempPath, filenameC, jarExtension); createNewPath(tempPath, filenameA, jarExtension); createNewPath(tempPath, dir1, filenameA, jarExtension); createNewPath(tempPath, dir1, filenameB, jarExtension); createNewPath(tempPath, dir1, filenameC, dataExtension); createNewPath(tempPath, dir2, filenameA, dataExtension); createNewPath(tempPath, dir2, filenameB, dataExtension); createNewPath(tempPath, dir2, filenameC, jarExtension); createNewPath(tempPath, dir3, filenameA, jarExtension); createNewPath(tempPath, dir3, filenameB, dataExtension); createNewPath(tempPath, dir3, filenameC, jarExtension); createNewPath(tempPath, dir3, filenameC, "-duplicate", jarExtension); /** Additional paths for inner dirs **/ createNewPath(tempPath, dir3, "innerDirA/inceptionLevel2/", filenameC, jarExtension); createNewPath(tempPath, dir3, "innerDirA/inceptionLevel2/", filenameC, "-duplicate", jarExtension); createNewPath(tempPath, dir3, "innerDirB/inceptionLevel2/", filenameC, "-duplicate-2", jarExtension); /** Create jar_order **/ jarFile = createNewPath(tempPath, dir1, "jar_order"); writer = new PrintWriter(jarFile, "UTF-8"); writer.println(filenameB + jarExtension); writer.println(filenameA + jarExtension); writer.close(); jarFile = createNewPath(tempPath, dir2, "jar_order"); writer = new PrintWriter(jarFile, "UTF-8"); writer.println(filenameC + jarExtension); writer.close(); jarFile = createNewPath(tempPath, dir3, "jar_order"); writer = new PrintWriter(jarFile, "UTF-8"); writer.println(filenameC + "-duplicate" + jarExtension); writer.println(filenameA + jarExtension); writer.close(); /** Create glob_order **/ globFile = createNewPath(tempPath, dir1, "glob_order"); writer = new PrintWriter(globFile, "UTF-8"); writer.println(filenameC + dataExtension); writer.println(filenameB + jarExtension); writer.println(filenameA + jarExtension); writer.close(); globFile = createNewPath(tempPath, dir3, "glob_order"); writer = new PrintWriter(globFile, "UTF-8"); writer.println(filenameC + jarExtension); writer.println(filenameC + "-duplicate" + jarExtension); /** Check regex compatibility in order files **/ writer.println("inner*/*Level*/" + filenameC + "-duplicate*" + jarExtension); writer.close(); } /** * Private method used by testScannedPathsRecursive. * Creates temp dir structure with files. * * Dir structure created: * sourceDirPath/tempfiles/a_dir/jar_1 * sourceDirPath/tempfiles/a_dir/jar_2 * sourceDirPath/tempfiles/a_dir/jar_order (*1\n*2) * * sourceDirPath/tempfiles/b_dir/jar_3 * sourceDirPath/tempfiles/b_dir/jar_4 * sourceDirPath/tempfiles/b_dir/glob_order (*4\n*3) * * sourceDirPath/tempfiles/c_dir/jar_5 * sourceDirPath/tempfiles/c_dir/jar_6 * * sourceDirPath/tempfiles/jar_order (a*\nb*\nc*) * * @param sourceDirPath */ private void createTempDirStructure2(String sourceDirPath) throws IOException { File orderFile; String tempPath = sourceDirPath + "/parent_dir/"; FileUtils.deleteQuietly(new File(tempPath)); PrintWriter writer; createNewPath(tempPath, "a_dir/jar_1"); createNewPath(tempPath, "a_dir/jar_2"); createNewPath(tempPath, "b_dir/jar_3"); createNewPath(tempPath, "b_dir/jar_4"); createNewPath(tempPath, "c_dir/jar_5"); createNewPath(tempPath, "c_dir/jar_6"); /** Create jar_order **/ orderFile = createNewPath(tempPath, "a_dir/jar_order"); writer = new PrintWriter(orderFile, "UTF-8"); writer.println("*1"); writer.println("*2"); writer.close(); orderFile = createNewPath(tempPath, "b_dir/glob_order"); writer = new PrintWriter(orderFile, "UTF-8"); writer.println("*4"); writer.println("*3"); writer.close(); orderFile = createNewPath(tempPath, "jar_order"); writer = new PrintWriter(orderFile, "UTF-8"); writer.println("a*"); writer.println("b*"); writer.println("c*"); writer.close(); } public void testScannedPathsMultipleJarGlobOrder() throws Exception { ScannedPaths sc; String tempPath = "target/test/"; String filenameAJar = "tempdata_a.jar"; String filenameBJar = "tempdata_b.jar"; String filenameCJar = "tempdata_c.jar"; String filenameCDupJar = "tempdata_c-duplicate.jar"; String filenameCDupJar2 = "tempdata_c-duplicate-2.jar"; String filenameAData = "tempdata_a.data"; String filenameBData = "tempdata_b.data"; String filenameCData = "tempdata_c.data"; String fileRegex1 = tempPath + "*"; String fileRegex2 = tempPath + "*/*"; try { createTempDirStructure1(tempPath); sc = new ScannedPaths(fileRegex1, "jar"); assertUnOrdered(sc, filenameCJar, filenameAJar, filenameBJar, filenameCDupJar); sc = new ScannedPaths(fileRegex2, "jar"); assertUnOrdered(sc, filenameBJar, filenameAJar, filenameCJar, // Direct matched tempdata_c.jar filenameCJar, filenameCDupJar, filenameAJar, filenameAJar // Direct matched tempdata_a.jar ); /** Remove jar_order files from temp dir **/ FileUtils.deleteQuietly(new File(tempPath + "tempfiles/dir1/jar_order")); FileUtils.deleteQuietly(new File(tempPath + "tempfiles/dir2/jar_order")); FileUtils.deleteQuietly(new File(tempPath + "tempfiles/dir3/jar_order")); sc = new ScannedPaths(fileRegex1, "file"); assertUnOrdered(sc, filenameCJar, filenameAJar, filenameAData, filenameBJar, filenameBData, filenameCData, filenameCDupJar, filenameCDupJar2); sc = new ScannedPaths(fileRegex2, "file"); assertUnOrdered(sc, filenameCData, // dir1 filenameBJar, // dir1 filenameAJar, // dir1 filenameCJar, // Direct matched tempdata_c.jar filenameCJar, // dir2 filenameBData, // dir2 filenameAData, // dir2 filenameCJar, // dir3 filenameCDupJar, //dir3 filenameCDupJar2, // dir3/inner filenameCDupJar, // dir3/inner filenameAJar // Direct matched tempdata_a.jar ); } finally { FileUtils.deleteQuietly(new File(tempPath)); } } public void testScannedPathsRecursive() throws Exception { ScannedPaths sc; String tempPath = "target/test/"; String fileRegex = tempPath + "parent_*"; try { createTempDirStructure2(tempPath); sc = new ScannedPaths(fileRegex, "file"); assertUnOrdered(sc, "jar_1", "jar_2", "jar_4", "jar_3", "jar_6", "jar_5"); /** Now also enforce order for c_dir **/ File orderFile = createNewPath(tempPath, "parent_dir/c_dir/glob_order"); PrintWriter writer = new PrintWriter(orderFile, "UTF-8"); writer.println("*5"); writer.println("*6"); writer.close(); sc = new ScannedPaths(fileRegex, "file"); assertUnOrdered(sc, "jar_1", "jar_2", "jar_4", "jar_3", "jar_5", "jar_6"); } finally { FileUtils.deleteQuietly(new File(tempPath)); } } public void testScannedPathsNonExistent() throws Exception { ScannedPaths sc; Iterator<String> iter = null; String tempPath = "target/test/"; String fileRegex = tempPath + "paradox/nopath"; try { sc = new ScannedPaths(fileRegex, "file"); assertFalse(sc.iterator().hasNext(), "Iterator should be empty for unmatched path patterns."); sc = new ScannedPaths(fileRegex, "jar"); assertFalse(sc.iterator().hasNext(), "Iterator should be empty for unmatched path patterns."); } finally { FileUtils.deleteQuietly(new File(tempPath)); } } private File createNewPath(String... params) throws IOException { String fileName = Joiner.on("").join(params); File f = new File(fileName); if (!f.getParentFile().exists()) { f.getParentFile().mkdirs(); } if (!f.exists()) { f.createNewFile(); } return f; } private void assertOrdered(ScannedPaths sc, String... expectedPaths) { ScannedPaths sc2 = new ScannedPaths(new File(sc.getPath().toString()).getAbsolutePath(), sc.getType()); ScannedPaths sc3 = new ScannedPaths("file:" + new File(sc.getPath().toString()).getAbsolutePath(), sc.getType()); assertSameScannedPaths(sc2, sc3); List<String> actual = new ArrayList<>(); for (String path : sc) { actual.add(path.substring(path.lastIndexOf("/") + 1, path.length())); } List<String> expected = new ArrayList<>(); Collections.addAll(expected, expectedPaths); assertEquals(actual, expected); } private void assertUnOrdered(ScannedPaths sc, String... expectedPaths) { ScannedPaths sc2 = new ScannedPaths(new File(sc.getPath().toString()).getAbsolutePath(), sc.getType()); ScannedPaths sc3 = new ScannedPaths("file:" + new File(sc.getPath().toString()).getAbsolutePath(), sc.getType()); assertSameScannedPaths(sc2, sc3); assertEquals(sc2.getFinalPaths(), sc3.getFinalPaths()); Set<String> actual = new HashSet<>(); for (String path : sc) { actual.add(path.substring(path.lastIndexOf("/") + 1, path.length())); } Set<String> expected = new HashSet<>(); Collections.addAll(expected, expectedPaths); assertEquals(actual, expected); } private void assertSameScannedPaths(ScannedPaths sc2, ScannedPaths sc3) { assertEquals(sc2.getFinalPaths().size(), sc3.getFinalPaths().size()); for (int i = 0; i < sc2.getFinalPaths().size(); i++) { assertEquals( sc2.getFinalPaths().get(i).replaceAll("^file:", ""), sc3.getFinalPaths().get(i).replaceAll("^file:", "") ); } } }