Merge branch 'master' of https://code.google.com/p/plexi.fs into OverviewImages
diff --git a/src/com/google/enterprise/adaptor/fs/AclBuilder.java b/src/com/google/enterprise/adaptor/fs/AclBuilder.java
index f2d7952..e8db799 100644
--- a/src/com/google/enterprise/adaptor/fs/AclBuilder.java
+++ b/src/com/google/enterprise/adaptor/fs/AclBuilder.java
@@ -17,8 +17,6 @@
import com.google.common.base.Preconditions;
import com.google.common.base.Predicate;
import com.google.enterprise.adaptor.Acl;
-import com.google.enterprise.adaptor.Acl.InheritanceType;
-import com.google.enterprise.adaptor.DocId;
import com.google.enterprise.adaptor.GroupPrincipal;
import com.google.enterprise.adaptor.Principal;
import com.google.enterprise.adaptor.UserPrincipal;
@@ -64,48 +62,30 @@
this.namespace = namespace;
}
- public Acl getAcl(DocId inheritId, boolean isDirectory,
- String fragmentName) throws IOException {
- Acl.Builder b = getAcl(inheritId, fragmentName, isDirectEntry);
- if (!isDirectory) {
- b.setInheritanceType(InheritanceType.LEAF_NODE);
- }
- return b.build();
+ public Acl.Builder getAcl() throws IOException {
+ return getAcl(isDirectEntry);
}
- public Acl getInheritableByAllDescendentFoldersAcl(DocId inheritId,
- String fragmentName) throws IOException {
- return getAcl(inheritId, fragmentName,
- isInheritableByAllDescendentFoldersEntry).build();
- }
-
- public Acl getInheritableByAllDescendentFilesAcl(DocId inheritId,
- String fragmentName) throws IOException {
- return getAcl(inheritId, fragmentName,
- isInheritableByAllDescendentFilesEntry).build();
- }
-
- public Acl getInheritableByChildFoldersOnlyAcl(DocId inheritId,
- String fragmentName) throws IOException {
- return getAcl(inheritId, fragmentName,
- isInheritableByChildFoldersOnlyEntry).build();
- }
-
- public Acl getInheritableByChildFilesOnlyAcl(DocId inheritId,
- String fragmentName) throws IOException {
- return getAcl(inheritId, fragmentName,
- isInheritableByChildFilesOnlyEntry).build();
- }
-
- public Acl getShareAcl(DocId inheritId)
+ public Acl.Builder getInheritableByAllDescendentFoldersAcl()
throws IOException {
- // Windows NT share Acls are returned as inheritable by child files.
- return getAcl(inheritId, null, isDirectEntry)
- .setInheritanceType(InheritanceType.AND_BOTH_PERMIT).build();
+ return getAcl(isInheritableByAllDescendentFoldersEntry);
}
- private Acl.Builder getAcl(DocId inheritId, String fragmentName,
- Predicate<Set<AclEntryFlag>> predicate) throws IOException {
+ public Acl.Builder getInheritableByAllDescendentFilesAcl()
+ throws IOException {
+ return getAcl(isInheritableByAllDescendentFilesEntry);
+ }
+
+ public Acl.Builder getInheritableByChildFoldersOnlyAcl() throws IOException {
+ return getAcl(isInheritableByChildFoldersOnlyEntry);
+ }
+
+ public Acl.Builder getInheritableByChildFilesOnlyAcl() throws IOException {
+ return getAcl(isInheritableByChildFilesOnlyEntry);
+ }
+
+ private Acl.Builder getAcl(Predicate<Set<AclEntryFlag>> predicate)
+ throws IOException {
Set<Principal> permits = new HashSet<Principal>();
Set<Principal> denies = new HashSet<Principal>();
for (AclEntry entry : aclView.getAcl()) {
@@ -136,8 +116,7 @@
}
return new Acl.Builder().setPermits(permits).setDenies(denies)
- .setInheritFrom(inheritId, fragmentName).setEverythingCaseInsensitive()
- .setInheritanceType(InheritanceType.CHILD_OVERRIDES);
+ .setEverythingCaseInsensitive();
}
/**
diff --git a/src/com/google/enterprise/adaptor/fs/FsAdaptor.java b/src/com/google/enterprise/adaptor/fs/FsAdaptor.java
index 0693d61..c12f3b3 100644
--- a/src/com/google/enterprise/adaptor/fs/FsAdaptor.java
+++ b/src/com/google/enterprise/adaptor/fs/FsAdaptor.java
@@ -20,6 +20,7 @@
import com.google.common.collect.Sets;
import com.google.enterprise.adaptor.AbstractAdaptor;
import com.google.enterprise.adaptor.Acl;
+import com.google.enterprise.adaptor.Acl.InheritanceType;
import com.google.enterprise.adaptor.AdaptorContext;
import com.google.enterprise.adaptor.Config;
import com.google.enterprise.adaptor.DocId;
@@ -256,7 +257,8 @@
AclBuilder builder = new AclBuilder(rootPath,
delegate.getDfsShareAclView(rootPath.getParent()),
supportedWindowsAccounts, builtinPrefix, namespace);
- namedResources.put(DFS_SHARE_ACL_DOCID, builder.getShareAcl(null));
+ namedResources.put(DFS_SHARE_ACL_DOCID, builder.getAcl()
+ .setInheritanceType(InheritanceType.AND_BOTH_PERMIT).build());
// Push the Acl for the active storage UNC path.
Path activeStorage = delegate.getDfsUncActiveStorageUnc(rootPath);
@@ -266,16 +268,18 @@
}
builder = new AclBuilder(activeStorage,
- delegate.getShareAclView(activeStorage), supportedWindowsAccounts,
- builtinPrefix, namespace);
- namedResources.put(SHARE_ACL_DOCID,
- builder.getShareAcl(DFS_SHARE_ACL_DOCID));
+ delegate.getShareAclView(activeStorage),
+ supportedWindowsAccounts, builtinPrefix, namespace);
+ namedResources.put(SHARE_ACL_DOCID, builder.getAcl()
+ .setInheritFrom(DFS_SHARE_ACL_DOCID)
+ .setInheritanceType(InheritanceType.AND_BOTH_PERMIT).build());
} else {
// For a non-DFS UNC we have only have a share Acl to push.
AclBuilder builder = new AclBuilder(rootPath,
- delegate.getShareAclView(rootPath), supportedWindowsAccounts,
- builtinPrefix, namespace);
- namedResources.put(SHARE_ACL_DOCID, builder.getShareAcl(null));
+ delegate.getShareAclView(rootPath),
+ supportedWindowsAccounts, builtinPrefix, namespace);
+ namedResources.put(SHARE_ACL_DOCID, builder.getAcl()
+ .setInheritanceType(InheritanceType.AND_BOTH_PERMIT).build());
}
pusher.pushNamedResources(namedResources);
@@ -343,16 +347,20 @@
if (isRoot || hasNoInheritedAcl) {
builder = new AclBuilder(doc, aclViews.getCombinedAclView(),
supportedWindowsAccounts, builtinPrefix, namespace);
- acl = builder.getAcl(SHARE_ACL_DOCID, docIsDirectory, null);
+ acl = builder.getAcl().setInheritFrom(SHARE_ACL_DOCID)
+ .setInheritanceType(docIsDirectory ? InheritanceType.CHILD_OVERRIDES
+ : InheritanceType.LEAF_NODE).build();
} else {
builder = new AclBuilder(doc, aclViews.getDirectAclView(),
supportedWindowsAccounts, builtinPrefix, namespace);
if (docIsDirectory) {
- acl = builder.getAcl(parentDocId, docIsDirectory,
- CHILD_FOLDER_INHERIT_ACL);
+ acl = builder.getAcl()
+ .setInheritFrom(parentDocId, CHILD_FOLDER_INHERIT_ACL)
+ .setInheritanceType(InheritanceType.CHILD_OVERRIDES).build();
} else {
- acl = builder.getAcl(parentDocId, docIsDirectory,
- CHILD_FILE_INHERIT_ACL);
+ acl = builder.getAcl()
+ .setInheritFrom(parentDocId, CHILD_FILE_INHERIT_ACL)
+ .setInheritanceType(InheritanceType.LEAF_NODE).build();
}
}
log.log(Level.FINEST, "Setting Acl: doc: {0}, acl: {1}",
@@ -362,29 +370,39 @@
// Push the additional Acls for a folder.
if (docIsDirectory) {
if (isRoot || hasNoInheritedAcl) {
- resp.putNamedResource(ALL_FOLDER_INHERIT_ACL,
- builder.getInheritableByAllDescendentFoldersAcl(SHARE_ACL_DOCID,
- null));
+ resp.putNamedResource(ALL_FOLDER_INHERIT_ACL,
+ builder.getInheritableByAllDescendentFoldersAcl()
+ .setInheritFrom(SHARE_ACL_DOCID)
+ .setInheritanceType(InheritanceType.CHILD_OVERRIDES).build());
resp.putNamedResource(ALL_FILE_INHERIT_ACL,
- builder.getInheritableByAllDescendentFilesAcl(SHARE_ACL_DOCID,
- null));
+ builder.getInheritableByAllDescendentFilesAcl()
+ .setInheritFrom(SHARE_ACL_DOCID)
+ .setInheritanceType(InheritanceType.CHILD_OVERRIDES).build());
resp.putNamedResource(CHILD_FOLDER_INHERIT_ACL,
- builder.getInheritableByChildFoldersOnlyAcl(SHARE_ACL_DOCID, null));
+ builder.getInheritableByChildFoldersOnlyAcl()
+ .setInheritFrom(SHARE_ACL_DOCID)
+ .setInheritanceType(InheritanceType.CHILD_OVERRIDES).build());
resp.putNamedResource(CHILD_FILE_INHERIT_ACL,
- builder.getInheritableByChildFilesOnlyAcl(SHARE_ACL_DOCID, null));
+ builder.getInheritableByChildFilesOnlyAcl()
+ .setInheritFrom(SHARE_ACL_DOCID)
+ .setInheritanceType(InheritanceType.CHILD_OVERRIDES).build());
} else {
- resp.putNamedResource(ALL_FOLDER_INHERIT_ACL,
- builder.getInheritableByAllDescendentFoldersAcl(parentDocId,
- ALL_FOLDER_INHERIT_ACL));
+ resp.putNamedResource(ALL_FOLDER_INHERIT_ACL,
+ builder.getInheritableByAllDescendentFoldersAcl()
+ .setInheritFrom(parentDocId, ALL_FOLDER_INHERIT_ACL)
+ .setInheritanceType(InheritanceType.CHILD_OVERRIDES).build());
resp.putNamedResource(ALL_FILE_INHERIT_ACL,
- builder.getInheritableByAllDescendentFilesAcl(parentDocId,
- ALL_FILE_INHERIT_ACL));
+ builder.getInheritableByAllDescendentFilesAcl()
+ .setInheritFrom(parentDocId, ALL_FILE_INHERIT_ACL)
+ .setInheritanceType(InheritanceType.CHILD_OVERRIDES).build());
resp.putNamedResource(CHILD_FOLDER_INHERIT_ACL,
- builder.getInheritableByChildFoldersOnlyAcl(parentDocId,
- ALL_FOLDER_INHERIT_ACL));
+ builder.getInheritableByChildFoldersOnlyAcl()
+ .setInheritFrom(parentDocId, ALL_FOLDER_INHERIT_ACL)
+ .setInheritanceType(InheritanceType.CHILD_OVERRIDES).build());
resp.putNamedResource(CHILD_FILE_INHERIT_ACL,
- builder.getInheritableByChildFilesOnlyAcl(parentDocId,
- ALL_FILE_INHERIT_ACL));
+ builder.getInheritableByChildFilesOnlyAcl()
+ .setInheritFrom(parentDocId, ALL_FILE_INHERIT_ACL)
+ .setInheritanceType(InheritanceType.CHILD_OVERRIDES).build());
}
}
diff --git a/src/com/google/enterprise/adaptor/fs/WindowsFileDelegate.java b/src/com/google/enterprise/adaptor/fs/WindowsFileDelegate.java
index 4b864ad..18b139b 100644
--- a/src/com/google/enterprise/adaptor/fs/WindowsFileDelegate.java
+++ b/src/com/google/enterprise/adaptor/fs/WindowsFileDelegate.java
@@ -51,6 +51,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.CountDownLatch;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -230,10 +231,17 @@
+ ". The path is not a valid directory.");
}
+ CountDownLatch startSignal = new CountDownLatch(1);
synchronized (monitorThreadLock) {
- monitorThread = new MonitorThread(watchPath, queue);
+ monitorThread = new MonitorThread(watchPath, queue, startSignal);
monitorThread.start();
}
+ // Wait for the monitor thread to start watching filesystem.
+ try {
+ startSignal.await();
+ } catch (InterruptedException e) {
+ Thread.currentThread().interrupt();
+ }
}
@Override
@@ -249,13 +257,18 @@
private static class MonitorThread extends Thread {
private final Path watchPath;
private final BlockingQueue<Path> queue;
+ private final CountDownLatch startSignal;
private final HANDLE stopEvent;
- public MonitorThread(Path watchPath, BlockingQueue<Path> queue) {
+ public MonitorThread(Path watchPath, BlockingQueue<Path> queue,
+ CountDownLatch startSignal) {
Preconditions.checkNotNull(watchPath, "the watchPath may not be null");
Preconditions.checkNotNull(queue, "the queue may not be null");
+ Preconditions.checkNotNull(startSignal,
+ "the start signal may not be null");
this.watchPath = watchPath;
this.queue = queue;
+ this.startSignal = startSignal;
stopEvent = Kernel32.INSTANCE.CreateEvent(null, false, false, null);
}
@@ -283,6 +296,9 @@
runMonitorLoop();
} catch (IOException e) {
log.log(Level.WARNING, "Unable to monitor " + watchPath, e);
+ } finally {
+ // Wake up caller, in case monitor fails to start up.
+ startSignal.countDown();
}
log.exiting("WindowsFileDelegate", "MonitorThread.run", watchPath);
}
@@ -360,6 +376,9 @@
+ ". GetLastError: " + klib.GetLastError());
}
+ // Signal any waiting threads that the monitor is now active.
+ startSignal.countDown();
+
log.log(Level.FINER, "Waiting for notifications.");
int waitResult = klib.WaitForSingleObjectEx(stopEvent,
Kernel32.INFINITE, true);
diff --git a/test/com/google/enterprise/adaptor/fs/AclBuilderTest.java b/test/com/google/enterprise/adaptor/fs/AclBuilderTest.java
index 1fb3414..b6ea1e2 100644
--- a/test/com/google/enterprise/adaptor/fs/AclBuilderTest.java
+++ b/test/com/google/enterprise/adaptor/fs/AclBuilderTest.java
@@ -29,8 +29,6 @@
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.enterprise.adaptor.Acl;
-import com.google.enterprise.adaptor.Acl.InheritanceType;
-import com.google.enterprise.adaptor.DocId;
import com.google.enterprise.adaptor.GroupPrincipal;
import com.google.enterprise.adaptor.Principal;
import com.google.enterprise.adaptor.UserPrincipal;
@@ -54,7 +52,6 @@
public ExpectedException thrown = ExpectedException.none();
private final Path doc = Paths.get("foo", "bar");
- private final DocId inheritId = new DocId("foo");
private final Set<String> windowsAccounts = ImmutableSet.of(
"BUILTIN\\Administrators", "Everyone", "BUILTIN\\Users",
"BUILTIN\\Guest", "NT AUTHORITY\\INTERACTIVE",
@@ -73,6 +70,8 @@
.flags(FILE_INHERIT, DIRECTORY_INHERIT),
group("sales").type(DENY).perms(GENERIC_READ)
.flags(FILE_INHERIT, DIRECTORY_INHERIT));
+ // This is the expected ACL for the above aclView.
+ private final Acl expectedAcl = expectedBuilder().build();
@Test
public void testConstructorNullPath() throws Exception {
@@ -105,64 +104,32 @@
}
@Test
- public void testGetAclForDirectory() throws Exception {
- Acl acl = newBuilder(aclView).getAcl(inheritId, true, null);
- Acl expected = expectedBuilder().build();
- assertEquals(expected, acl);
- }
-
- @Test
- public void testGetAclForFile() throws Exception {
- Acl acl = newBuilder(aclView).getAcl(inheritId, false, null);
- Acl expected = expectedBuilder()
- .setInheritanceType(InheritanceType.LEAF_NODE)
- .build();
- assertEquals(expected, acl);
- }
-
- @Test
- public void testGetShareAcl() throws Exception {
- Acl acl = newBuilder(aclView).getShareAcl(inheritId);
- Acl expected = expectedBuilder()
- .setInheritanceType(InheritanceType.AND_BOTH_PERMIT)
- .build();
- assertEquals(expected, acl);
+ public void testGetAcl() throws Exception {
+ assertEquals(expectedAcl, newBuilder(aclView).getAcl().build());
}
@Test
public void testGetInheritableByAllDescendentFoldersAcl() throws Exception {
- String fragment = "allFoldersAcl";
- Acl acl = newBuilder(aclView).getInheritableByAllDescendentFoldersAcl(
- inheritId, fragment);
- Acl expected = expectedBuilder(fragment).build();
- assertEquals(expected, acl);
+ assertEquals(expectedAcl,
+ newBuilder(aclView).getInheritableByAllDescendentFoldersAcl().build());
}
@Test
public void testGetInheritableByAllDescendentFilesAcl() throws Exception {
- String fragment = "allFilesAcl";
- Acl acl = newBuilder(aclView).getInheritableByAllDescendentFilesAcl(
- inheritId, fragment);
- Acl expected = expectedBuilder(fragment).build();
- assertEquals(expected, acl);
+ assertEquals(expectedAcl,
+ newBuilder(aclView).getInheritableByAllDescendentFilesAcl().build());
}
@Test
public void testGetInheritableByChildFoldersOnlyAcl() throws Exception {
- String fragment = "childFoldersAcl";
- Acl acl = newBuilder(aclView).getInheritableByChildFoldersOnlyAcl(
- inheritId, fragment);
- Acl expected = expectedBuilder(fragment).build();
- assertEquals(expected, acl);
+ assertEquals(expectedAcl,
+ newBuilder(aclView).getInheritableByChildFoldersOnlyAcl().build());
}
@Test
public void testGetInheritableByChildFilesOnlyAcl() throws Exception {
- String fragment = "childFilesAcl";
- Acl acl = newBuilder(aclView).getInheritableByChildFilesOnlyAcl(
- inheritId, fragment);
- Acl expected = expectedBuilder(fragment).build();
- assertEquals(expected, acl);
+ assertEquals(expectedAcl,
+ newBuilder(aclView).getInheritableByChildFilesOnlyAcl().build());
}
@Test
@@ -181,31 +148,19 @@
.flags(FILE_INHERIT));
AclBuilder aclBuilder = newBuilder(aclView);
- String fragment = "allFilesAcl";
- Acl acl = aclBuilder.getInheritableByAllDescendentFilesAcl(inheritId,
- fragment);
- Acl expected = expectedBuilder(fragment).build();
- assertEquals(expected, acl);
-
- fragment = "childFilesAcl";
- acl = aclBuilder.getInheritableByChildFilesOnlyAcl(inheritId, fragment);
- expected = expectedBuilder(fragment).build();
- assertEquals(expected, acl);
+ // The file inherit ACLs should have all the users and groups.
+ assertEquals(expectedAcl,
+ aclBuilder.getInheritableByAllDescendentFilesAcl().build());
+ assertEquals(expectedAcl,
+ aclBuilder.getInheritableByChildFilesOnlyAcl().build());
// The folder inherit ACLs should not include "mary" or "sales".
- fragment = "allFoldersAcl";
- acl = aclBuilder.getInheritableByAllDescendentFoldersAcl(inheritId,
- fragment);
- expected = expectedBuilder(fragment)
+ Acl expected = expectedBuilder()
.setPermitUsers(users("joe")).setDenyGroups(emptyGroups).build();
- assertEquals(expected, acl);
-
- fragment = "childFoldersAcl";
- acl = aclBuilder.getInheritableByAllDescendentFoldersAcl(inheritId,
- fragment);
- expected = expectedBuilder(fragment)
- .setPermitUsers(users("joe")).setDenyGroups(emptyGroups).build();
- assertEquals(expected, acl);
+ assertEquals(expected,
+ aclBuilder.getInheritableByAllDescendentFoldersAcl().build());
+ assertEquals(expected,
+ aclBuilder.getInheritableByAllDescendentFoldersAcl().build());
}
@Test
@@ -224,31 +179,19 @@
.flags(DIRECTORY_INHERIT));
AclBuilder aclBuilder = newBuilder(aclView);
- String fragment = "allFoldersAcl";
- Acl acl = aclBuilder.getInheritableByAllDescendentFoldersAcl(inheritId,
- fragment);
- Acl expected = expectedBuilder(fragment).build();
- assertEquals(expected, acl);
-
- fragment = "childFoldersAcl";
- acl = aclBuilder.getInheritableByChildFoldersOnlyAcl(inheritId, fragment);
- expected = expectedBuilder(fragment).build();
- assertEquals(expected, acl);
+ // The folder inherit ACLs should have all the users and groups.
+ assertEquals(expectedAcl,
+ aclBuilder.getInheritableByAllDescendentFoldersAcl().build());
+ assertEquals(expectedAcl,
+ aclBuilder.getInheritableByChildFoldersOnlyAcl().build());
// The file inherit ACLs should not include "mary" or "sales".
- fragment = "allFilesAcl";
- acl = aclBuilder.getInheritableByAllDescendentFilesAcl(inheritId,
- fragment);
- expected = expectedBuilder(fragment)
+ Acl expected = expectedBuilder()
.setPermitUsers(users("joe")).setDenyGroups(emptyGroups).build();
- assertEquals(expected, acl);
-
- fragment = "childFilesAcl";
- acl = aclBuilder.getInheritableByAllDescendentFilesAcl(inheritId,
- fragment);
- expected = expectedBuilder(fragment)
- .setPermitUsers(users("joe")).setDenyGroups(emptyGroups).build();
- assertEquals(expected, acl);
+ assertEquals(expected,
+ aclBuilder.getInheritableByAllDescendentFilesAcl().build());
+ assertEquals(expected,
+ aclBuilder.getInheritableByAllDescendentFilesAcl().build());
}
@Test
@@ -262,13 +205,12 @@
.flags(FILE_INHERIT, DIRECTORY_INHERIT));
AclBuilder aclBuilder = newBuilder(aclView);
- Acl acl =
- aclBuilder.getInheritableByAllDescendentFoldersAcl(inheritId, null);
+ Acl acl = aclBuilder.getInheritableByAllDescendentFoldersAcl().build();
Acl expected = emptyExpectedBuilder()
.setPermitUsers(users("joe", "mary")).build();
assertEquals(expected, acl);
- acl = aclBuilder.getInheritableByChildFoldersOnlyAcl(inheritId, null);
+ acl = aclBuilder.getInheritableByChildFoldersOnlyAcl().build();
expected = emptyExpectedBuilder()
.setPermitUsers(users("joe", "mike", "mary")).build();
assertEquals(expected, acl);
@@ -285,13 +227,12 @@
.flags(FILE_INHERIT, DIRECTORY_INHERIT));
AclBuilder aclBuilder = newBuilder(aclView);
- Acl acl =
- aclBuilder.getInheritableByAllDescendentFilesAcl(inheritId, null);
+ Acl acl = aclBuilder.getInheritableByAllDescendentFilesAcl().build();
Acl expected = emptyExpectedBuilder()
.setPermitUsers(users("joe", "mary")).build();
assertEquals(expected, acl);
- acl = aclBuilder.getInheritableByChildFilesOnlyAcl(inheritId, null);
+ acl = aclBuilder.getInheritableByChildFilesOnlyAcl().build();
expected = emptyExpectedBuilder()
.setPermitUsers(users("joe", "mike", "mary")).build();
assertEquals(expected, acl);
@@ -309,18 +250,17 @@
AclBuilder aclBuilder = newBuilder(aclView);
// This node's ACL should not include mike.
- Acl acl = aclBuilder.getAcl(inheritId, true, null);
Acl expected = emptyExpectedBuilder()
.setPermitUsers(users("joe", "mary")).build();
- assertEquals(expected, acl);
+ assertEquals(expected, aclBuilder.getAcl().build());
// However, all of its children should include mike.
expected = emptyExpectedBuilder()
.setPermitUsers(users("joe", "mike", "mary")).build();
- acl = aclBuilder.getInheritableByAllDescendentFoldersAcl(inheritId, null);
- assertEquals(expected, acl);
- acl = aclBuilder.getInheritableByAllDescendentFilesAcl(inheritId, null);
- assertEquals(expected, acl);
+ assertEquals(expected,
+ aclBuilder.getInheritableByAllDescendentFoldersAcl().build());
+ assertEquals(expected,
+ aclBuilder.getInheritableByAllDescendentFilesAcl().build());
}
@Test
@@ -335,12 +275,11 @@
// This node's ACLs should not include mike.
Acl expected = emptyExpectedBuilder()
.setPermitUsers(users("joe")).build();
- Acl acl = aclBuilder.getAcl(inheritId, true, null);
- assertEquals(expected, acl);
- acl = aclBuilder.getInheritableByAllDescendentFoldersAcl(inheritId, null);
- assertEquals(expected, acl);
- acl = aclBuilder.getInheritableByAllDescendentFilesAcl(inheritId, null);
- assertEquals(expected, acl);
+ assertEquals(expected, aclBuilder.getAcl().build());
+ assertEquals(expected,
+ aclBuilder.getInheritableByAllDescendentFoldersAcl().build());
+ assertEquals(expected,
+ aclBuilder.getInheritableByAllDescendentFilesAcl().build());
}
@Test
@@ -365,8 +304,7 @@
Acl expected = emptyExpectedBuilder()
.setPermitUsers(users(Iterables.toArray(windowsAccounts, String.class)))
.build();
- Acl acl = aclBuilder.getAcl(inheritId, true, null);
- assertEquals(expected, acl);
+ assertEquals(expected, aclBuilder.getAcl().build());
}
/** Returns an AclBuilder for the AclFileAttributeView. */
@@ -381,16 +319,7 @@
* then call build().
*/
private Acl.Builder expectedBuilder() {
- return expectedBuilder(null);
- }
-
- /**
- * Returns an Acl.Builder representing the aclView field.
- * The caller is expected to overwrite any of thes presets,
- * then call build().
- */
- private Acl.Builder expectedBuilder(String fragment) {
- return emptyExpectedBuilder(fragment)
+ return emptyExpectedBuilder()
.setPermitUsers(users("joe", "mary")).setDenyUsers(users("mike"))
.setPermitGroups(groups("EVERYONE")).setDenyGroups(groups("sales"));
}
@@ -399,16 +328,7 @@
* Returns an Acl.Builder with no users or groups.
*/
private Acl.Builder emptyExpectedBuilder() {
- return emptyExpectedBuilder(null);
- }
-
- /**
- * Returns an Acl.Builder with no users or groups.
- */
- private Acl.Builder emptyExpectedBuilder(String fragment) {
- return new Acl.Builder().setInheritFrom(inheritId, fragment)
- .setInheritanceType(InheritanceType.CHILD_OVERRIDES)
- .setEverythingCaseInsensitive();
+ return new Acl.Builder().setEverythingCaseInsensitive();
}
/**
diff --git a/test/com/google/enterprise/adaptor/fs/WindowsFileDelegateTest.java b/test/com/google/enterprise/adaptor/fs/WindowsFileDelegateTest.java
new file mode 100644
index 0000000..f345598
--- /dev/null
+++ b/test/com/google/enterprise/adaptor/fs/WindowsFileDelegateTest.java
@@ -0,0 +1,291 @@
+// Copyright 2014 Google Inc. All Rights Reserved.
+//
+// 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.enterprise.adaptor.fs;
+
+import com.google.common.base.Charsets;
+import com.google.common.base.Preconditions;
+import com.google.common.collect.Sets;
+import com.google.common.io.CharStreams;
+
+import static org.junit.Assert.*;
+import static org.junit.Assume.*;
+
+import org.junit.*;
+import org.junit.rules.ExpectedException;
+import org.junit.rules.TemporaryFolder;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.nio.file.DirectoryStream;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardCopyOption;
+import java.nio.file.attribute.AclFileAttributeView;
+import java.nio.file.attribute.BasicFileAttributes;
+import java.nio.file.attribute.FileTime;
+import java.util.Collections;
+import java.util.Set;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+import java.util.concurrent.TimeUnit;
+
+/** Tests for {@link WindowsFileDelegate} */
+public class WindowsFileDelegateTest {
+
+ @BeforeClass
+ public static void checkIfRunningOnWindows() {
+ TestHelper.assumeOsIsWindows();
+ }
+
+ private FileDelegate delegate = new WindowsFileDelegate();
+ private BlockingQueue<Path> queue = new LinkedBlockingQueue<Path>();
+ private Path tempRoot;
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ @Rule
+ public TemporaryFolder temp = new TemporaryFolder();
+
+ @Before
+ public void setUp() throws Exception {
+ tempRoot = temp.getRoot().getCanonicalFile().toPath();
+ }
+
+ @After
+ public void tearDown() {
+ delegate.destroy();
+ }
+
+ private Path newTempDir(String name) throws IOException {
+ return temp.newFolder(name).toPath();
+ }
+
+ private Path newTempFile(String name) throws IOException {
+ return temp.newFile(name).toPath();
+ }
+
+ private Path newTempFile(Path parent, String name) throws IOException {
+ Preconditions.checkArgument(parent.startsWith(tempRoot));
+ return Files.createFile(parent.resolve(name));
+ }
+
+ @Test
+ public void testNewDocIdLocalFiles() throws Exception {
+ Path dir = newTempDir("testDir");
+ Path file = newTempFile(dir, "test");
+
+ String id = delegate.newDocId(tempRoot).getUniqueId();
+ assertTrue(id.startsWith(tempRoot.toString().replace('\\', '/')));
+ assertTrue(id.endsWith("/"));
+
+ id = delegate.newDocId(dir).getUniqueId();
+ assertTrue(id.startsWith(tempRoot.toString().replace('\\', '/')));
+ assertTrue(id.startsWith(dir.toString().replace('\\', '/')));
+ assertTrue(id.endsWith("/"));
+
+ id = delegate.newDocId(file).getUniqueId();
+ assertTrue(id.startsWith(tempRoot.toString().replace('\\', '/')));
+ assertTrue(id.startsWith(dir.toString().replace('\\', '/')));
+ assertTrue(id.equals(file.toString().replace('\\', '/')));
+ assertFalse(id.endsWith("/"));
+ }
+
+ @Test
+ public void testNewDocIdVirtualUncPaths() throws Exception {
+ assertEquals("\\\\host/share",
+ delegate.newDocId(Paths.get("\\\\host\\share")).getUniqueId());
+ assertEquals("\\\\host/share",
+ delegate.newDocId(Paths.get("\\\\host\\share\\")).getUniqueId());
+ assertEquals("\\\\host/share/foo/bar",
+ delegate.newDocId(Paths.get("\\\\host\\share\\foo\\bar"))
+ .getUniqueId());
+ }
+
+ @Test
+ public void testNewDocIdLocalUncPaths() throws Exception {
+ String uncTempRoot = getTempRootAsUncPath();
+ assumeNotNull(uncTempRoot);
+ Path tempRoot = Paths.get(uncTempRoot);
+ String expectedTempRootId = "\\\\" + uncTempRoot.substring(2)
+ .replace('\\', '/') + "/";
+
+ assertEquals(expectedTempRootId,
+ delegate.newDocId(tempRoot).getUniqueId());
+
+ newTempDir("testDir");
+ assertEquals(expectedTempRootId + "testDir/",
+ delegate.newDocId(tempRoot.resolve("testDir")).getUniqueId());
+
+ newTempFile("test");
+ assertEquals(expectedTempRootId + "test",
+ delegate.newDocId(tempRoot.resolve("test")).getUniqueId());
+ }
+
+ private String getTempRootAsUncPath() throws IOException {
+ String tempPath = temp.getRoot().getCanonicalPath();
+ if (tempPath.length() > 2 && tempPath.charAt(1) == ':') {
+ String uncPath = "\\\\localhost\\" + tempPath.substring(0, 1) + "$"
+ + tempPath.substring(2);
+ try {
+ // Now verify we have access to the local administrative share.
+ if (new File(uncPath).list() != null) {
+ return uncPath;
+ }
+ } catch (SecurityException e) {
+ // Cannot access local administrative share.
+ }
+ }
+ return null;
+ }
+
+ @Test
+ public void testStartMonitorBadPath() throws Exception {
+ Path file = newTempFile("test.txt");
+ thrown.expect(IOException.class);
+ delegate.startMonitorPath(file, queue);
+ }
+
+ @Test
+ public void testStartStopMonitor() throws Exception {
+ delegate.startMonitorPath(tempRoot, queue);
+ delegate.stopMonitorPath();
+ }
+
+ @Test
+ public void testMonitorAddFile() throws Exception {
+ // These shouldn't show up as new or modified.
+ newTempDir("existingDir");
+ newTempFile("existingFile");
+ delegate.startMonitorPath(tempRoot, queue);
+ Path file = newTempFile("test.txt");
+ // Adding a file shows up as a change to its parent.
+ checkForChanges(Collections.singleton(tempRoot));
+ }
+
+ @Test
+ public void testMonitorDeleteFile() throws Exception {
+ Path file = newTempFile("test.txt");
+ delegate.startMonitorPath(tempRoot, queue);
+ Files.delete(file);
+ // Deleting a file shows up as a change to itself and its parent.
+ checkForChanges(Sets.newHashSet(tempRoot, file));
+ }
+
+ @Test
+ public void testMonitorRenameFile() throws Exception {
+ Path file = newTempFile("test.txt");
+ Path newFile = file.resolveSibling("newName.txt");
+ delegate.startMonitorPath(tempRoot, queue);
+ Files.move(file, newFile, StandardCopyOption.ATOMIC_MOVE);
+ // Renaming a file shows up as a change to its old name, its new name,
+ // and its parent.
+ checkForChanges(Sets.newHashSet(tempRoot, file, newFile));
+ }
+
+ @Test
+ public void testMonitorMoveAccrossDirs() throws Exception {
+ Path dir1 = newTempDir("dir1");
+ Path dir2 = newTempDir("dir2");
+ Path file1 = newTempFile(dir1, "test.txt");
+ Path file2 = dir2.resolve(file1.getFileName());
+ delegate.startMonitorPath(tempRoot, queue);
+ Files.move(file1, file2);
+ // Moving a file shows up as a change to its old name, its new name,
+ // its old parent, and its new parent.
+ checkForChanges(Sets.newHashSet(file1, file2, dir1, dir2));
+ }
+
+ @Test
+ public void testMonitorModifyFile() throws Exception {
+ Path file = newTempFile("test.txt");
+ delegate.startMonitorPath(tempRoot, queue);
+ Files.write(file, "Hello World".getBytes("UTF-8"));
+ // Modifying a file shows up as a change to that file.
+ checkForChanges(Collections.singleton(file));
+ }
+
+ @Test
+ public void testMonitorModifyFileAttributes() throws Exception {
+ Path file = newTempFile("test.txt");
+ FileTime lastModified = Files.getLastModifiedTime(file);
+ delegate.startMonitorPath(tempRoot, queue);
+ Files.setLastModifiedTime(file,
+ FileTime.fromMillis(lastModified.toMillis() + 10000L));
+ // Modifying a file shows up as a change to that file.
+ checkForChanges(Collections.singleton(file));
+ }
+
+ @Test
+ public void testMonitorRenameDir() throws Exception {
+ Path dir = newTempDir("dir1");
+ Path newDir = dir.resolveSibling("newName.dir");
+ delegate.startMonitorPath(tempRoot, queue);
+ Files.move(dir, newDir, StandardCopyOption.ATOMIC_MOVE);
+ // Renaming a directory shows up as a change to its old name, its new name,
+ // and its parent.
+ checkForChanges(Sets.newHashSet(tempRoot, dir));
+ }
+
+ @Test
+ public void testMonitorMoveDir() throws Exception {
+ Path dir1 = newTempDir("dir1");
+ Path dir2 = newTempDir("dir2");
+ Path dir1dir2 = dir1.resolve(dir2.getFileName());
+ delegate.startMonitorPath(tempRoot, queue);
+ Files.move(dir2, dir1dir2);
+ // Moving a file shows up as a change to its old name, its new name,
+ // its old parent, and its new parent.
+ checkForChanges(Sets.newHashSet(tempRoot, dir1, dir2));
+ }
+
+ @Test
+ public void testMonitorChangesInSubDirs() throws Exception {
+ Path dir = newTempDir("testDir");
+ Path file = newTempFile(dir, "test.txt");
+ delegate.startMonitorPath(tempRoot, queue);
+ Files.write(file, "Hello World".getBytes("UTF-8"));
+ // Modifying a file shows up as a change to that file.
+ checkForChanges(Collections.singleton(file));
+ }
+
+ private void checkForChanges(Set<Path> expected) throws Exception {
+ // Collect up the changes. Adapted from BlockingQueueBatcher.take(),
+ // but without infinite initial wait.
+ Set<Path> changes = Sets.newHashSet();
+ int maxBatchSize = expected.size();
+ long maxLatencyMillis = 10000;
+ long currentTime = System.currentTimeMillis();
+ long stopBatchTime = currentTime + maxLatencyMillis;
+
+ while (currentTime < stopBatchTime && changes.size() < maxBatchSize) {
+ // Block until an item is in the queue or the batch timeout expires.
+ Path path =
+ queue.poll(stopBatchTime - currentTime, TimeUnit.MILLISECONDS);
+ if (path == null) {
+ // Timeout occurred.
+ break;
+ }
+ changes.add(path);
+ queue.drainTo(changes);
+ currentTime = System.currentTimeMillis();
+ }
+
+ // Now verify that the changes we got were the ones that were expected.
+ assertEquals(expected, changes);
+ }
+}