| /* |
| * Copyright 2014 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
| * in compliance with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software distributed under the License |
| * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
| * or implied. See the License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package com.google.gwt.dev.resource.impl; |
| |
| import com.google.gwt.thirdparty.guava.common.collect.Lists; |
| import com.google.gwt.thirdparty.guava.common.collect.Sets; |
| import com.google.gwt.thirdparty.guava.common.io.Files; |
| |
| import junit.framework.TestCase; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.nio.file.FileSystemException; |
| import java.util.Collections; |
| import java.util.Comparator; |
| import java.util.List; |
| import java.util.Set; |
| |
| /** |
| * Tests for ResourceAccumulator. |
| */ |
| public class ResourceAccumulatorTest extends TestCase { |
| |
| public void testAddFile() throws Exception { |
| File rootDirectory = Files.createTempDir(); |
| File subDirectory = createDirectoryIn("subdir", rootDirectory); |
| |
| ResourceAccumulator resourceAccumulator = |
| new ResourceAccumulator(rootDirectory.toPath(), createInclusivePathPrefixSet()); |
| |
| assertTrue(getResources(resourceAccumulator).isEmpty()); |
| |
| createFileIn("New.java", subDirectory); |
| waitForFileEvents(); |
| |
| List<AbstractResource> resources = getResources(resourceAccumulator); |
| assertEquals(1, resources.size()); |
| assertTrue(resources.get(0).getPath().endsWith("New.java")); |
| |
| resourceAccumulator.shutdown(); |
| } |
| |
| public void testDeleteFile() throws Exception { |
| File rootDirectory = Files.createTempDir(); |
| File subDirectory = createDirectoryIn("subdir", rootDirectory); |
| File originalFile = createFileIn("SomeFile.java", subDirectory); |
| |
| ResourceAccumulator resourceAccumulator = |
| new ResourceAccumulator(rootDirectory.toPath(), createInclusivePathPrefixSet()); |
| |
| List<AbstractResource> resources = getResources(resourceAccumulator); |
| assertEquals(1, resources.size()); |
| assertTrue(resources.get(0).getPath().endsWith("SomeFile.java")); |
| |
| originalFile.delete(); |
| waitForFileEvents(); |
| |
| assertTrue(getResources(resourceAccumulator).isEmpty()); |
| |
| resourceAccumulator.shutdown(); |
| } |
| |
| public void testListensInNewDirectories() throws Exception { |
| File rootDirectory = Files.createTempDir(); |
| |
| ResourceAccumulator resourceAccumulator = |
| new ResourceAccumulator(rootDirectory.toPath(), createInclusivePathPrefixSet()); |
| |
| assertTrue(getResources(resourceAccumulator).isEmpty()); |
| |
| // Create a new directory and contained file AFTER the root directory has started being listened |
| // to. |
| File subDirectory = createDirectoryIn("subdir", rootDirectory); |
| createFileIn("New.java", subDirectory); |
| waitForFileEvents(); |
| |
| List<AbstractResource> resources = getResources(resourceAccumulator); |
| assertEquals(1, resources.size()); |
| assertTrue(resources.get(0).getPath().endsWith("New.java")); |
| |
| resourceAccumulator.shutdown(); |
| } |
| |
| public void testMultipleListeners() throws Exception { |
| File rootDirectory = Files.createTempDir(); |
| File subDirectory = createDirectoryIn("subdir", rootDirectory); |
| |
| ResourceAccumulator resourceAccumulator1 = |
| new ResourceAccumulator(rootDirectory.toPath(), createInclusivePathPrefixSet()); |
| ResourceAccumulator resourceAccumulator2 = |
| new ResourceAccumulator(rootDirectory.toPath(), createInclusivePathPrefixSet()); |
| |
| assertTrue(getResources(resourceAccumulator1).isEmpty()); |
| assertTrue(getResources(resourceAccumulator2).isEmpty()); |
| |
| createFileIn("New.java", subDirectory); |
| waitForFileEvents(); |
| |
| List<AbstractResource> resources1 = getResources(resourceAccumulator1); |
| assertEquals(1, resources1.size()); |
| assertTrue(resources1.get(0).getPath().endsWith("New.java")); |
| |
| List<AbstractResource> resources2 = getResources(resourceAccumulator2); |
| assertEquals(1, resources2.size()); |
| assertTrue(resources2.get(0).getPath().endsWith("New.java")); |
| |
| resourceAccumulator1.shutdown(); |
| resourceAccumulator2.shutdown(); |
| } |
| |
| public void testRenameFile() throws Exception { |
| File rootDirectory = Files.createTempDir(); |
| File subDirectory = createDirectoryIn("subdir", rootDirectory); |
| File originalFile = createFileIn("OriginalName.java", subDirectory); |
| File renamedFile = new File(subDirectory, "Renamed.java"); |
| |
| ResourceAccumulator resourceAccumulator = |
| new ResourceAccumulator(rootDirectory.toPath(), createInclusivePathPrefixSet()); |
| |
| List<AbstractResource> resources = getResources(resourceAccumulator); |
| assertEquals(1, resources.size()); |
| assertTrue(resources.get(0).getPath().endsWith("OriginalName.java")); |
| |
| originalFile.renameTo(renamedFile); |
| waitForFileEvents(); |
| |
| resources = getResources(resourceAccumulator); |
| assertEquals(1, resources.size()); |
| assertTrue(resources.get(0).getPath().endsWith("Renamed.java")); |
| |
| resourceAccumulator.shutdown(); |
| } |
| |
| public void testRenameDirectory() throws Exception { |
| File rootDirectory = Files.createTempDir(); |
| File subDirectory = createDirectoryIn("original_dir", rootDirectory); |
| createFileIn("Name1.java", subDirectory); |
| createFileIn("Name2.java", subDirectory); |
| File renamedSubDirectory = new File(rootDirectory, "new_dir"); |
| |
| ResourceAccumulator resourceAccumulator = |
| new ResourceAccumulator(rootDirectory.toPath(), createInclusivePathPrefixSet()); |
| |
| List<AbstractResource> resources = getResources(resourceAccumulator); |
| assertEquals(2, resources.size()); |
| assertTrue(resources.get(0).getPath().endsWith("original_dir/Name1.java")); |
| assertTrue(resources.get(1).getPath().endsWith("original_dir/Name2.java")); |
| |
| subDirectory.renameTo(renamedSubDirectory); |
| waitForFileEvents(); |
| |
| resources = getResources(resourceAccumulator); |
| assertEquals(2, resources.size()); |
| assertTrue(resources.get(0).getPath().endsWith("new_dir/Name1.java")); |
| assertTrue(resources.get(1).getPath().endsWith("new_dir/Name2.java")); |
| |
| resourceAccumulator.shutdown(); |
| } |
| |
| public void testRenameParentDirectory() throws Exception { |
| File rootDirectory = Files.createTempDir(); |
| File parentDirectory = createDirectoryIn("original_dir", rootDirectory); |
| File subDirectory = createDirectoryIn("subdir", parentDirectory); |
| createFileIn("Name1.java", subDirectory); |
| createFileIn("Name2.java", subDirectory); |
| File renamedParentDirectory = new File(rootDirectory, "new_dir"); |
| |
| ResourceAccumulator resourceAccumulator = |
| new ResourceAccumulator(rootDirectory.toPath(), createInclusivePathPrefixSet()); |
| |
| List<AbstractResource> resources = getResources(resourceAccumulator); |
| assertEquals(2, resources.size()); |
| assertTrue(resources.get(0).getPath().endsWith("original_dir/subdir/Name1.java")); |
| assertTrue(resources.get(1).getPath().endsWith("original_dir/subdir/Name2.java")); |
| |
| parentDirectory.renameTo(renamedParentDirectory); |
| waitForFileEvents(); |
| |
| resources = getResources(resourceAccumulator); |
| assertEquals(2, resources.size()); |
| assertTrue(resources.get(0).getPath().endsWith("new_dir/subdir/Name1.java")); |
| assertTrue(resources.get(1).getPath().endsWith("new_dir/subdir/Name2.java")); |
| |
| resourceAccumulator.shutdown(); |
| } |
| |
| public void testSymlinkInfiniteLoop() throws Exception { |
| File rootDirectory = Files.createTempDir(); |
| File subDirectory = Files.createTempDir(); |
| |
| ResourceAccumulator resourceAccumulator = |
| new ResourceAccumulator(rootDirectory.toPath(), createInclusivePathPrefixSet()); |
| |
| assertTrue(getResources(resourceAccumulator).isEmpty()); |
| |
| // Symlink in a loop |
| java.nio.file.Files.createSymbolicLink(new File(rootDirectory, "sublink").toPath(), |
| subDirectory.toPath()).toFile(); |
| java.nio.file.Files.createSymbolicLink(new File(subDirectory, "sublink").toPath(), |
| rootDirectory.toPath()).toFile(); |
| createFileIn("New.java", subDirectory); |
| waitForFileEvents(); |
| |
| try { |
| // Should throw an error if resourceAccumulator got stuck in an infinite directory scan loop. |
| getResources(resourceAccumulator); |
| fail(); |
| } catch (FileSystemException expected) { |
| // Expected |
| } |
| |
| resourceAccumulator.shutdown(); |
| } |
| |
| public void testSymlinks() throws Exception { |
| File scratchDirectory = Files.createTempDir(); |
| File newFile = createFileIn("New.java", scratchDirectory); |
| File rootDirectory = Files.createTempDir(); |
| File subDirectory = Files.createTempDir(); |
| |
| ResourceAccumulator resourceAccumulator = |
| new ResourceAccumulator(rootDirectory.toPath(), createInclusivePathPrefixSet()); |
| |
| assertTrue(getResources(resourceAccumulator).isEmpty()); |
| |
| // Symlink in a subdirectory and then symlink in a contained file. |
| java.nio.file.Files.createSymbolicLink(new File(rootDirectory, "sublink").toPath(), |
| subDirectory.toPath()).toFile(); |
| java.nio.file.Files.createSymbolicLink(new File(subDirectory, "New.java").toPath(), |
| newFile.toPath()).toFile(); |
| waitForFileEvents(); |
| |
| List<AbstractResource> resources = getResources(resourceAccumulator); |
| assertEquals(1, resources.size()); |
| assertTrue(resources.get(0).getPath().endsWith("sublink/New.java")); |
| |
| resourceAccumulator.shutdown(); |
| } |
| |
| private static File createDirectoryIn(String fileName, File inDirectory) { |
| File newDirectory = new File(inDirectory, fileName); |
| newDirectory.mkdir(); |
| return newDirectory; |
| } |
| |
| private static File createFileIn(String fileName, File inDirectory) throws IOException { |
| File newFile = new File(inDirectory, fileName); |
| newFile.createNewFile(); |
| return newFile; |
| } |
| |
| private List<AbstractResource> getResources(ResourceAccumulator resourceAccumulator) |
| throws IOException { |
| resourceAccumulator.refreshResources(); |
| List<AbstractResource> list = Lists.newArrayList(resourceAccumulator.getResources().keySet()); |
| Collections.sort(list, new Comparator<AbstractResource>() { |
| @Override |
| public int compare(AbstractResource a, AbstractResource b) { |
| return a.getLocation().compareTo(b.getLocation()); |
| } |
| }); |
| return list; |
| } |
| |
| private Set<PathPrefixSet> pathPrefixes = Sets.newHashSet(); |
| |
| @Override |
| public void tearDown() { |
| pathPrefixes.clear(); |
| } |
| |
| private PathPrefixSet createInclusivePathPrefixSet() { |
| PathPrefixSet pathPrefixSet = new PathPrefixSet(); |
| pathPrefixSet.add(new PathPrefix("", null)); |
| |
| // Keep the the reference until the end of the test to create a strong reference, otherwise |
| // will get GCed as ResourceAccumulator refers to it weakly. |
| pathPrefixes.add(pathPrefixSet); |
| return pathPrefixSet; |
| } |
| |
| private void waitForFileEvents() throws InterruptedException { |
| Thread.sleep(100); |
| } |
| } |