/* * RHQ Management Platform * Copyright (C) 2011 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.rhq.core.pc.drift; import static java.util.Arrays.asList; import static java.util.Collections.emptyList; import static org.apache.commons.io.FileUtils.deleteDirectory; import static org.apache.commons.io.FileUtils.toFile; import static org.rhq.core.util.file.FileUtil.forEachFile; import static org.rhq.test.AssertUtils.assertCollectionEqualsNoOrder; import static org.testng.Assert.assertTrue; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.commons.io.FileUtils; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import org.rhq.core.domain.drift.Filter; import org.rhq.core.util.file.FileVisitor; public class FilterFileVisitorTest { private File basedir; @BeforeMethod public void setUp() throws Exception { File root = toFile(getClass().getResource(".")); basedir = new File(root, "basedir"); deleteDirectory(basedir); basedir.mkdirs(); } @Test public void visitAllFilesWhenNoFiltersSpecified() throws Exception { File libDir = mkdir(basedir, "lib"); File server1Jar = touch(libDir, "server-1.jar"); File server2Jar = touch(libDir, "server-2.jar"); File nativeLibDir = mkdir(libDir, "native"); File nativeServer1Lib = touch(nativeLibDir, "server-1.so"); File nativeServer2Lib = touch(nativeLibDir, "server-2.so"); List<Filter> includes = emptyList(); List<Filter> excludes = emptyList(); TestVisitor visitor = new TestVisitor(); forEachFile(basedir, new FilterFileVisitor(basedir, includes, excludes, visitor)); assertCollectionEqualsNoOrder(asList(server1Jar, server2Jar, nativeServer1Lib, nativeServer2Lib), visitor.visitedFiles, "Visitor should be called for every file when no filters specified"); } // This could be a DriftDetectorTest but fits well here. @Test public void visitBaseDirFilesThatMatchFilters() throws Exception { File fooJar = touch(basedir, "foo.jar"); File gooJar = touch(basedir, "goo.jar"); File myapp = touch(basedir, "myapp.war"); touch(basedir, "bar.jar"); // These filter paths should all normalize to the same directory List<Filter> includes = asList(new Filter(".", "foo*"), new Filter("./", "*.war"), new Filter("/", "goo*")); List<Filter> excludes = emptyList(); TestVisitor visitor = new TestVisitor(); forEachFile(basedir, new FilterFileVisitor(basedir, includes, excludes, visitor)); assertCollectionEqualsNoOrder(asList(fooJar, gooJar, myapp), visitor.visitedFiles, "Filtering failed with multiple includes and no excludes"); } @Test public void visitFilesThatMatchIncludes() throws Exception { File libDir = mkdir(basedir, "lib"); File fooJar = touch(libDir, "foo.jar"); File fooWar = touch(libDir, "foo-1.jar"); File myapp = touch(libDir, "myapp.war"); touch(libDir, "bar.jar"); List<Filter> includes = asList(new Filter(libDir.getAbsolutePath(), "foo*"), new Filter(libDir.getAbsolutePath(), "*.war")); List<Filter> excludes = emptyList(); TestVisitor visitor = new TestVisitor(); forEachFile(basedir, new FilterFileVisitor(basedir, includes, excludes, visitor)); assertCollectionEqualsNoOrder(asList(fooJar, fooWar, myapp), visitor.visitedFiles, "Filtering failed with multiple includes and no excludes"); } @Test public void visitFilesThatMatchIncludesInWinParenDirs() throws Exception { // win test only if ('/' == File.separatorChar) { return; } File root = toFile(getClass().getResource(".")); File winbasedir = new File(root, "base (dir)"); deleteDirectory(winbasedir); winbasedir.mkdirs(); File parenDir = mkdir(winbasedir, "sys (x86)"); File fooJar = touch(parenDir, "foo.jar"); File fooWar = touch(parenDir, "foo-1.jar"); File myapp = touch(parenDir, "myapp.war"); touch(parenDir, "bar.jar"); List<Filter> includes = asList(new Filter(parenDir.getAbsolutePath(), "foo*"), new Filter(parenDir.getAbsolutePath(), "*.war")); List<Filter> excludes = emptyList(); TestVisitor visitor = new TestVisitor(); forEachFile(winbasedir, new FilterFileVisitor(winbasedir, includes, excludes, visitor)); assertCollectionEqualsNoOrder(asList(fooJar, fooWar, myapp), visitor.visitedFiles, "Filtering failed with mulitple includes and no excludes"); deleteDirectory(winbasedir); } @Test public void doNotVisitFileThatDoesNotMatchInclude() throws Exception { touch(basedir, "server.txt"); List<Filter> includes = asList(new Filter(basedir.getAbsolutePath(), "*.html")); List<Filter> excludes = emptyList(); TestVisitor visitor = new TestVisitor(); forEachFile(basedir, new FilterFileVisitor(basedir, includes, excludes, visitor)); assertTrue(visitor.visitedFiles.isEmpty(), "Do not visit files that do not match an includes filter"); } @Test public void visitFileThatDoesNotMatchExcludes() throws Exception { File server1Txt = touch(basedir, "server-1.txt"); File server1Html = touch(basedir, "server-1.html"); List<Filter> includes = emptyList(); List<Filter> excludes = asList(new Filter(basedir.getAbsolutePath(), "*.txt")); TestVisitor visitor = new TestVisitor(); forEachFile(basedir, new FilterFileVisitor(basedir, includes, excludes, visitor)); assertCollectionEqualsNoOrder(asList(server1Html), visitor.visitedFiles, "Visit files that do not match " + "excludes filter and no includes are specified"); } @Test public void doNotVisitFileThatMatchesExclude() throws Exception { File libDir = mkdir(basedir, "lib"); File server1Jar = touch(libDir, "server-1.jar"); File server2Jar = touch(libDir, "server-2.jar"); List<Filter> includes = emptyList(); List<Filter> excludes = asList(new Filter(libDir.getAbsolutePath(), "server-1.jar")); TestVisitor visitor = new TestVisitor(); forEachFile(basedir, new FilterFileVisitor(basedir, includes, excludes, visitor)); assertCollectionEqualsNoOrder(asList(server2Jar), visitor.visitedFiles, "Filtering failed when no includes and an exclude were specified."); } @Test public void visitFileThatMatchesIncludeAndDoesNotMatchesExclude() throws Exception { // This test also verifies that files that match an include and also match // an exclude are not visited. File libDir = mkdir(basedir, "lib"); File server1Jar = touch(libDir, "server-1.jar"); File server2Jar = touch(libDir, "server-2.jar"); File confDir = mkdir(basedir, "conf"); File server1Conf = touch(confDir, "server-1.conf"); File server2Conf = touch(confDir, "server-2.conf"); List<Filter> includes = asList(new Filter(basedir.getAbsolutePath(), "**/*.*")); List<Filter> excludes = asList(new Filter(confDir.getAbsolutePath(), "server-2.conf")); TestVisitor visitor = new TestVisitor(); forEachFile(basedir, new FilterFileVisitor(basedir, includes, excludes, visitor)); assertCollectionEqualsNoOrder(asList(server1Jar, server2Jar, server1Conf), visitor.visitedFiles, "Do not visit files that match an excludes even when the file matches an include"); } @Test public void expandRelativePaths() throws Exception { File server1Html = touch(basedir, "server-1.html"); File server2Html = touch(basedir, "server-2.html"); File server1Txt = touch(basedir, "server-1.txt"); File server2Txt = touch(basedir, "server-2.txt"); File libDir = mkdir(basedir, "lib"); File server1Jar = touch(libDir, "server-1.jar"); File server2Jar = touch(libDir, "server-2.jar"); List<Filter> includes = asList(new Filter(".", "server-1.*"), new Filter("./lib", "server-1.*")); List<Filter> excludes = emptyList(); TestVisitor visitor = new TestVisitor(); forEachFile(basedir, new FilterFileVisitor(basedir, includes, excludes, visitor)); assertCollectionEqualsNoOrder(asList(server1Html, server1Txt, server1Jar), visitor.visitedFiles, "Relative paths should be expanded out to full paths"); } @Test public void includeEverythingWhenPathIsADirectoryAndNoPatternSpecified() throws Exception { File deployDir = mkdir(basedir, "deploy"); File serverEar = touch(deployDir, "server.ear"); File myapp = mkdir(deployDir, "myapp.war"); File indexHtml = touch(myapp, "index.html"); File confDir = mkdir(basedir, "conf"); File serverConf = touch(confDir, "server.conf"); List<Filter> includes = asList(new Filter(deployDir.getAbsolutePath(), null)); List<Filter> excludes = emptyList(); TestVisitor visitor = new TestVisitor(); forEachFile(basedir, new FilterFileVisitor(basedir, includes, excludes, visitor)); assertCollectionEqualsNoOrder(asList(serverEar, indexHtml), visitor.visitedFiles, "When a filter path specifies a directory and no pattern is specified, all files under that directory, " + "including subdirectories should be considered a match."); } private File mkdir(File parent, String dirName) throws IOException { File dir = new File(parent, dirName); dir.mkdirs(); return dir; } private File touch(File dir, String fileName) throws IOException { File file = new File(dir, fileName); FileUtils.touch(file); return file; } static class TestVisitor implements FileVisitor { public List<File> visitedFiles = new ArrayList<File>(); @Override public void visit(File file) { visitedFiles.add(file); } } }