http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/server/base/src/test/java/org/apache/accumulo/server/rpc/TCredentialsUpdatingInvocationHandlerTest.java
----------------------------------------------------------------------
diff --git 
a/server/base/src/test/java/org/apache/accumulo/server/rpc/TCredentialsUpdatingInvocationHandlerTest.java
 
b/server/base/src/test/java/org/apache/accumulo/server/rpc/TCredentialsUpdatingInvocationHandlerTest.java
index 1b87a9e..4f7cbba 100644
--- 
a/server/base/src/test/java/org/apache/accumulo/server/rpc/TCredentialsUpdatingInvocationHandlerTest.java
+++ 
b/server/base/src/test/java/org/apache/accumulo/server/rpc/TCredentialsUpdatingInvocationHandlerTest.java
@@ -116,6 +116,18 @@ public class TCredentialsUpdatingInvocationHandlerTest {
     proxy.updateArgs(new Object[] {new Object(), tcreds});
   }
 
+  @SuppressWarnings("deprecation")
+  @Test
+  public void testAllowedAnyImpersonationForAnyUser() throws Exception {
+    final String proxyServer = "proxy";
+    cc.set(Property.INSTANCE_RPC_SASL_PROXYUSERS.getKey() + proxyServer + 
".users", "*");
+    cc.set(Property.INSTANCE_RPC_SASL_PROXYUSERS.getKey() + proxyServer + 
".hosts", "*");
+    proxy = new TCredentialsUpdatingInvocationHandler<>(new Object(), conf);
+    TCredentials tcreds = new TCredentials("client", 
KerberosToken.class.getName(), ByteBuffer.allocate(0), 
UUID.randomUUID().toString());
+    UGIAssumingProcessor.rpcPrincipal.set(proxyServer);
+    proxy.updateArgs(new Object[] {new Object(), tcreds});
+  }
+
   @Test
   public void testAllowedAnyImpersonationForAnyUserNewConfig() throws 
Exception {
     final String proxyServer = "proxy";
@@ -127,6 +139,20 @@ public class TCredentialsUpdatingInvocationHandlerTest {
     proxy.updateArgs(new Object[] {new Object(), tcreds});
   }
 
+  @SuppressWarnings("deprecation")
+  @Test
+  public void testAllowedImpersonationForSpecificUsers() throws Exception {
+    final String proxyServer = "proxy";
+    cc.set(Property.INSTANCE_RPC_SASL_PROXYUSERS.getKey() + proxyServer + 
".users", "client1,client2");
+    cc.set(Property.INSTANCE_RPC_SASL_PROXYUSERS.getKey() + proxyServer + 
".hosts", "*");
+    proxy = new TCredentialsUpdatingInvocationHandler<>(new Object(), conf);
+    TCredentials tcreds = new TCredentials("client1", 
KerberosToken.class.getName(), ByteBuffer.allocate(0), 
UUID.randomUUID().toString());
+    UGIAssumingProcessor.rpcPrincipal.set(proxyServer);
+    proxy.updateArgs(new Object[] {new Object(), tcreds});
+    tcreds = new TCredentials("client2", KerberosToken.class.getName(), 
ByteBuffer.allocate(0), UUID.randomUUID().toString());
+    proxy.updateArgs(new Object[] {new Object(), tcreds});
+  }
+
   @Test
   public void testAllowedImpersonationForSpecificUsersNewConfig() throws 
Exception {
     final String proxyServer = "proxy";
@@ -140,6 +166,19 @@ public class TCredentialsUpdatingInvocationHandlerTest {
     proxy.updateArgs(new Object[] {new Object(), tcreds});
   }
 
+  @SuppressWarnings("deprecation")
+  @Test(expected = ThriftSecurityException.class)
+  public void testDisallowedImpersonationForUser() throws Exception {
+    final String proxyServer = "proxy";
+    // let "otherproxy" impersonate, but not "proxy"
+    cc.set(Property.INSTANCE_RPC_SASL_PROXYUSERS.getKey() + "otherproxy" + 
".users", "*");
+    cc.set(Property.INSTANCE_RPC_SASL_PROXYUSERS.getKey() + "otherproxy" + 
".hosts", "*");
+    proxy = new TCredentialsUpdatingInvocationHandler<>(new Object(), conf);
+    TCredentials tcreds = new TCredentials("client", 
KerberosToken.class.getName(), ByteBuffer.allocate(0), 
UUID.randomUUID().toString());
+    UGIAssumingProcessor.rpcPrincipal.set(proxyServer);
+    proxy.updateArgs(new Object[] {new Object(), tcreds});
+  }
+
   @Test(expected = ThriftSecurityException.class)
   public void testDisallowedImpersonationForUserNewConfig() throws Exception {
     final String proxyServer = "proxy";
@@ -152,6 +191,21 @@ public class TCredentialsUpdatingInvocationHandlerTest {
     proxy.updateArgs(new Object[] {new Object(), tcreds});
   }
 
+  @SuppressWarnings("deprecation")
+  @Test(expected = ThriftSecurityException.class)
+  public void testDisallowedImpersonationForMultipleUsers() throws Exception {
+    final String proxyServer = "proxy";
+    // let "otherproxy" impersonate, but not "proxy"
+    cc.set(Property.INSTANCE_RPC_SASL_PROXYUSERS.getKey() + "otherproxy1" + 
".users", "*");
+    cc.set(Property.INSTANCE_RPC_SASL_PROXYUSERS.getKey() + "otherproxy1" + 
".hosts", "*");
+    cc.set(Property.INSTANCE_RPC_SASL_PROXYUSERS.getKey() + "otherproxy2" + 
".users", "client1,client2");
+    cc.set(Property.INSTANCE_RPC_SASL_PROXYUSERS.getKey() + "otherproxy2" + 
".hosts", "*");
+    proxy = new TCredentialsUpdatingInvocationHandler<>(new Object(), conf);
+    TCredentials tcreds = new TCredentials("client1", 
KerberosToken.class.getName(), ByteBuffer.allocate(0), 
UUID.randomUUID().toString());
+    UGIAssumingProcessor.rpcPrincipal.set(proxyServer);
+    proxy.updateArgs(new Object[] {new Object(), tcreds});
+  }
+
   @Test(expected = ThriftSecurityException.class)
   public void testDisallowedImpersonationForMultipleUsersNewConfig() throws 
Exception {
     final String proxyServer = "proxy";
@@ -164,6 +218,19 @@ public class TCredentialsUpdatingInvocationHandlerTest {
     proxy.updateArgs(new Object[] {new Object(), tcreds});
   }
 
+  @SuppressWarnings("deprecation")
+  @Test
+  public void testAllowedImpersonationFromSpecificHost() throws Exception {
+    final String proxyServer = "proxy", client = "client", host = 
"host.domain.com";
+    cc.set(Property.INSTANCE_RPC_SASL_PROXYUSERS.getKey() + proxyServer + 
".users", client);
+    cc.set(Property.INSTANCE_RPC_SASL_PROXYUSERS.getKey() + proxyServer + 
".hosts", host);
+    proxy = new TCredentialsUpdatingInvocationHandler<>(new Object(), conf);
+    TCredentials tcreds = new TCredentials("client", 
KerberosToken.class.getName(), ByteBuffer.allocate(0), 
UUID.randomUUID().toString());
+    UGIAssumingProcessor.rpcPrincipal.set(proxyServer);
+    TServerUtils.clientAddress.set(host);
+    proxy.updateArgs(new Object[] {new Object(), tcreds});
+  }
+
   @Test
   public void testAllowedImpersonationFromSpecificHostNewConfig() throws 
Exception {
     final String proxyServer = "proxy", client = "client", host = 
"host.domain.com";
@@ -176,6 +243,20 @@ public class TCredentialsUpdatingInvocationHandlerTest {
     proxy.updateArgs(new Object[] {new Object(), tcreds});
   }
 
+  @SuppressWarnings("deprecation")
+  @Test(expected = ThriftSecurityException.class)
+  public void testDisallowedImpersonationFromSpecificHost() throws Exception {
+    final String proxyServer = "proxy", client = "client", host = 
"host.domain.com";
+    cc.set(Property.INSTANCE_RPC_SASL_PROXYUSERS.getKey() + proxyServer + 
".users", client);
+    cc.set(Property.INSTANCE_RPC_SASL_PROXYUSERS.getKey() + proxyServer + 
".hosts", host);
+    proxy = new TCredentialsUpdatingInvocationHandler<>(new Object(), conf);
+    TCredentials tcreds = new TCredentials("client", 
KerberosToken.class.getName(), ByteBuffer.allocate(0), 
UUID.randomUUID().toString());
+    UGIAssumingProcessor.rpcPrincipal.set(proxyServer);
+    // The RPC came from a different host than is allowed
+    TServerUtils.clientAddress.set("otherhost.domain.com");
+    proxy.updateArgs(new Object[] {new Object(), tcreds});
+  }
+
   @Test(expected = ThriftSecurityException.class)
   public void testDisallowedImpersonationFromSpecificHostNewConfig() throws 
Exception {
     final String proxyServer = "proxy", client = "client", host = 
"host.domain.com";

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/server/base/src/test/java/org/apache/accumulo/server/security/UserImpersonationTest.java
----------------------------------------------------------------------
diff --git 
a/server/base/src/test/java/org/apache/accumulo/server/security/UserImpersonationTest.java
 
b/server/base/src/test/java/org/apache/accumulo/server/security/UserImpersonationTest.java
index 714a1c1..5b4e1b0 100644
--- 
a/server/base/src/test/java/org/apache/accumulo/server/security/UserImpersonationTest.java
+++ 
b/server/base/src/test/java/org/apache/accumulo/server/security/UserImpersonationTest.java
@@ -67,6 +67,19 @@ public class UserImpersonationTest {
     };
   }
 
+  void setValidHosts(String user, String hosts) {
+    setUsersOrHosts(user, ".hosts", hosts);
+  }
+
+  void setValidUsers(String user, String users) {
+    setUsersOrHosts(user, ".users", users);
+  }
+
+  @SuppressWarnings("deprecation")
+  void setUsersOrHosts(String user, String suffix, String value) {
+    cc.set(Property.INSTANCE_RPC_SASL_PROXYUSERS.getKey() + user + suffix, 
value);
+  }
+
   void setValidHostsNewConfig(String user, String... hosts) {
     cc.set(Property.INSTANCE_RPC_SASL_ALLOWED_HOST_IMPERSONATION.getKey(), 
Joiner.on(';').join(hosts));
   }
@@ -83,6 +96,23 @@ public class UserImpersonationTest {
   }
 
   @Test
+  public void testAnyUserAndHosts() {
+    String server = "server";
+    setValidHosts(server, "*");
+    setValidUsers(server, "*");
+    UserImpersonation impersonation = new UserImpersonation(conf);
+
+    UsersWithHosts uwh = impersonation.get(server);
+    assertNotNull(uwh);
+
+    assertTrue(uwh.acceptsAllHosts());
+    assertTrue(uwh.acceptsAllUsers());
+
+    assertEquals(AlwaysTrueSet.class, uwh.getHosts().getClass());
+    assertEquals(AlwaysTrueSet.class, uwh.getUsers().getClass());
+  }
+
+  @Test
   public void testAnyUserAndHostsNewConfig() {
     String server = "server";
     setValidHostsNewConfig(server, "*");
@@ -100,6 +130,22 @@ public class UserImpersonationTest {
   }
 
   @Test
+  public void testNoHostByDefault() {
+    String server = "server";
+    setValidUsers(server, "*");
+    UserImpersonation impersonation = new UserImpersonation(conf);
+
+    UsersWithHosts uwh = impersonation.get(server);
+    assertNotNull(uwh);
+
+    assertFalse(uwh.acceptsAllHosts());
+    assertTrue(uwh.acceptsAllUsers());
+
+    assertNotEquals(AlwaysTrueSet.class, uwh.getHosts().getClass());
+    assertEquals(AlwaysTrueSet.class, uwh.getUsers().getClass());
+  }
+
+  @Test
   public void testNoHostByDefaultNewConfig() {
     String server = "server";
     setValidUsersNewConfig(ImmutableMap.of(server, "*"));
@@ -116,6 +162,22 @@ public class UserImpersonationTest {
   }
 
   @Test
+  public void testNoUsersByDefault() {
+    String server = "server";
+    setValidHosts(server, "*");
+    UserImpersonation impersonation = new UserImpersonation(conf);
+
+    UsersWithHosts uwh = impersonation.get(server);
+    assertNotNull(uwh);
+
+    assertTrue(uwh.acceptsAllHosts());
+    assertFalse(uwh.acceptsAllUsers());
+
+    assertEquals(AlwaysTrueSet.class, uwh.getHosts().getClass());
+    assertNotEquals(AlwaysTrueSet.class, uwh.getUsers().getClass());
+  }
+
+  @Test
   public void testNoUsersByDefaultNewConfig() {
     String server = "server";
     setValidHostsNewConfig(server, "*");
@@ -126,6 +188,29 @@ public class UserImpersonationTest {
   }
 
   @Test
+  public void testSingleUserAndHost() {
+    String server = "server", host = "single_host.domain.com", client = 
"single_client";
+    setValidHosts(server, host);
+    setValidUsers(server, client);
+    UserImpersonation impersonation = new UserImpersonation(conf);
+
+    UsersWithHosts uwh = impersonation.get(server);
+    assertNotNull(uwh);
+
+    assertFalse(uwh.acceptsAllHosts());
+    assertFalse(uwh.acceptsAllUsers());
+
+    assertNotEquals(AlwaysTrueSet.class, uwh.getHosts().getClass());
+    assertNotEquals(AlwaysTrueSet.class, uwh.getUsers().getClass());
+
+    assertTrue(uwh.getUsers().contains(client));
+    assertTrue(uwh.getHosts().contains(host));
+
+    assertFalse(uwh.getUsers().contains("some_other_user"));
+    assertFalse(uwh.getHosts().contains("other_host.domain.com"));
+  }
+
+  @Test
   public void testSingleUserAndHostNewConfig() {
     String server = "server", host = "single_host.domain.com", client = 
"single_client";
     setValidHostsNewConfig(server, host);
@@ -149,6 +234,28 @@ public class UserImpersonationTest {
   }
 
   @Test
+  public void testMultipleExplicitUsers() {
+    String server = "server", client1 = "client1", client2 = "client2", 
client3 = "client3";
+    setValidHosts(server, "*");
+    setValidUsers(server, Joiner.on(',').join(client1, client2, client3));
+    UserImpersonation impersonation = new UserImpersonation(conf);
+
+    UsersWithHosts uwh = impersonation.get(server);
+    assertNotNull(uwh);
+
+    assertTrue(uwh.acceptsAllHosts());
+    assertFalse(uwh.acceptsAllUsers());
+
+    assertEquals(AlwaysTrueSet.class, uwh.getHosts().getClass());
+    assertNotEquals(AlwaysTrueSet.class, uwh.getUsers().getClass());
+
+    assertTrue(uwh.getUsers().contains(client1));
+    assertTrue(uwh.getUsers().contains(client2));
+    assertTrue(uwh.getUsers().contains(client3));
+    assertFalse(uwh.getUsers().contains("other_client"));
+  }
+
+  @Test
   public void testMultipleExplicitUsersNewConfig() {
     String server = "server", client1 = "client1", client2 = "client2", 
client3 = "client3";
     setValidHostsNewConfig(server, "*");
@@ -171,6 +278,28 @@ public class UserImpersonationTest {
   }
 
   @Test
+  public void testMultipleExplicitHosts() {
+    String server = "server", host1 = "host1", host2 = "host2", host3 = 
"host3";
+    setValidHosts(server, Joiner.on(',').join(host1, host2, host3));
+    setValidUsers(server, "*");
+    UserImpersonation impersonation = new UserImpersonation(conf);
+
+    UsersWithHosts uwh = impersonation.get(server);
+    assertNotNull(uwh);
+
+    assertFalse(uwh.acceptsAllHosts());
+    assertTrue(uwh.acceptsAllUsers());
+
+    assertNotEquals(AlwaysTrueSet.class, uwh.getHosts().getClass());
+    assertEquals(AlwaysTrueSet.class, uwh.getUsers().getClass());
+
+    assertTrue(uwh.getHosts().contains(host1));
+    assertTrue(uwh.getHosts().contains(host2));
+    assertTrue(uwh.getHosts().contains(host3));
+    assertFalse(uwh.getHosts().contains("other_host"));
+  }
+
+  @Test
   public void testMultipleExplicitHostsNewConfig() {
     String server = "server", host1 = "host1", host2 = "host2", host3 = 
"host3";
     setValidHostsNewConfig(server, Joiner.on(',').join(host1, host2, host3));
@@ -193,6 +322,33 @@ public class UserImpersonationTest {
   }
 
   @Test
+  public void testMultipleExplicitUsersHosts() {
+    String server = "server", host1 = "host1", host2 = "host2", host3 = 
"host3", client1 = "client1", client2 = "client2", client3 = "client3";
+    setValidHosts(server, Joiner.on(',').join(host1, host2, host3));
+    setValidUsers(server, Joiner.on(',').join(client1, client2, client3));
+    UserImpersonation impersonation = new UserImpersonation(conf);
+
+    UsersWithHosts uwh = impersonation.get(server);
+    assertNotNull(uwh);
+
+    assertFalse(uwh.acceptsAllHosts());
+    assertFalse(uwh.acceptsAllUsers());
+
+    assertNotEquals(AlwaysTrueSet.class, uwh.getHosts().getClass());
+    assertNotEquals(AlwaysTrueSet.class, uwh.getUsers().getClass());
+
+    assertTrue(uwh.getUsers().contains(client1));
+    assertTrue(uwh.getUsers().contains(client2));
+    assertTrue(uwh.getUsers().contains(client3));
+    assertFalse(uwh.getUsers().contains("other_client"));
+
+    assertTrue(uwh.getHosts().contains(host1));
+    assertTrue(uwh.getHosts().contains(host2));
+    assertTrue(uwh.getHosts().contains(host3));
+    assertFalse(uwh.getHosts().contains("other_host"));
+  }
+
+  @Test
   public void testMultipleExplicitUsersHostsNewConfig() {
     String server = "server", host1 = "host1", host2 = "host2", host3 = 
"host3", client1 = "client1", client2 = "client2", client3 = "client3";
     setValidHostsNewConfig(server, Joiner.on(',').join(host1, host2, host3));
@@ -220,6 +376,59 @@ public class UserImpersonationTest {
   }
 
   @Test
+  public void testMultipleAllowedImpersonators() {
+    String server1 = "server1", server2 = "server2", host1 = "host1", host2 = 
"host2", host3 = "host3", client1 = "client1", client2 = "client2", client3 = 
"client3";
+    // server1 can impersonate client1 and client2 from host1 or host2
+    setValidHosts(server1, Joiner.on(',').join(host1, host2));
+    setValidUsers(server1, Joiner.on(',').join(client1, client2));
+    // server2 can impersonate only client3 from host3
+    setValidHosts(server2, host3);
+    setValidUsers(server2, client3);
+    UserImpersonation impersonation = new UserImpersonation(conf);
+
+    UsersWithHosts uwh = impersonation.get(server1);
+    assertNotNull(uwh);
+
+    assertFalse(uwh.acceptsAllHosts());
+    assertFalse(uwh.acceptsAllUsers());
+
+    assertNotEquals(AlwaysTrueSet.class, uwh.getHosts().getClass());
+    assertNotEquals(AlwaysTrueSet.class, uwh.getUsers().getClass());
+
+    assertTrue(uwh.getUsers().contains(client1));
+    assertTrue(uwh.getUsers().contains(client2));
+    assertFalse(uwh.getUsers().contains(client3));
+    assertFalse(uwh.getUsers().contains("other_client"));
+
+    assertTrue(uwh.getHosts().contains(host1));
+    assertTrue(uwh.getHosts().contains(host2));
+    assertFalse(uwh.getHosts().contains(host3));
+    assertFalse(uwh.getHosts().contains("other_host"));
+
+    uwh = impersonation.get(server2);
+    assertNotNull(uwh);
+
+    assertFalse(uwh.acceptsAllHosts());
+    assertFalse(uwh.acceptsAllUsers());
+
+    assertNotEquals(AlwaysTrueSet.class, uwh.getHosts().getClass());
+    assertNotEquals(AlwaysTrueSet.class, uwh.getUsers().getClass());
+
+    assertFalse(uwh.getUsers().contains(client1));
+    assertFalse(uwh.getUsers().contains(client2));
+    assertTrue(uwh.getUsers().contains(client3));
+    assertFalse(uwh.getUsers().contains("other_client"));
+
+    assertFalse(uwh.getHosts().contains(host1));
+    assertFalse(uwh.getHosts().contains(host2));
+    assertTrue(uwh.getHosts().contains(host3));
+    assertFalse(uwh.getHosts().contains("other_host"));
+
+    // client3 is not allowed to impersonate anyone
+    assertNull(impersonation.get(client3));
+  }
+
+  @Test
   public void testMultipleAllowedImpersonatorsNewConfig() {
     String server1 = "server1", server2 = "server2", host1 = "host1", host2 = 
"host2", host3 = "host3", client1 = "client1", client2 = "client2", client3 = 
"client3";
     // server1 can impersonate client1 and client2 from host1 or host2
@@ -270,6 +479,24 @@ public class UserImpersonationTest {
     assertNull(impersonation.get(client3));
   }
 
+  @SuppressWarnings("deprecation")
+  @Test
+  public void testSingleUser() throws Exception {
+    final String server = "server/hostn...@example.com", client = 
"cli...@example.com";
+    cc.set(Property.INSTANCE_RPC_SASL_PROXYUSERS.getKey() + server + ".users", 
client);
+    cc.set(Property.INSTANCE_RPC_SASL_PROXYUSERS.getKey() + server + ".hosts", 
"*");
+    UserImpersonation impersonation = new UserImpersonation(conf);
+
+    UsersWithHosts uwh = impersonation.get(server);
+
+    assertNotNull(uwh);
+
+    assertTrue(uwh.acceptsAllHosts());
+    assertFalse(uwh.acceptsAllUsers());
+
+    assertTrue(uwh.getUsers().contains(client));
+  }
+
   @Test
   public void testSingleUserNewConfig() throws Exception {
     final String server = "server/hostn...@example.com", client = 
"cli...@example.com";

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/server/base/src/test/java/org/apache/accumulo/server/util/TServerUtilsTest.java
----------------------------------------------------------------------
diff --git 
a/server/base/src/test/java/org/apache/accumulo/server/util/TServerUtilsTest.java
 
b/server/base/src/test/java/org/apache/accumulo/server/util/TServerUtilsTest.java
index fde9e6d..37d127a 100644
--- 
a/server/base/src/test/java/org/apache/accumulo/server/util/TServerUtilsTest.java
+++ 
b/server/base/src/test/java/org/apache/accumulo/server/util/TServerUtilsTest.java
@@ -29,6 +29,7 @@ import java.io.IOException;
 import java.net.InetAddress;
 import java.net.ServerSocket;
 import java.net.UnknownHostException;
+import java.nio.ByteBuffer;
 import java.util.List;
 import java.util.concurrent.ExecutorService;
 
@@ -87,6 +88,34 @@ public class TServerUtilsTest {
       return 30;
     }
 
+    @Deprecated
+    @Override
+    public Connector getConnector(String user, byte[] pass) throws 
AccumuloException, AccumuloSecurityException {
+      throw new UnsupportedOperationException();
+    }
+
+    @Deprecated
+    @Override
+    public Connector getConnector(String user, ByteBuffer pass) throws 
AccumuloException, AccumuloSecurityException {
+      throw new UnsupportedOperationException();
+    }
+
+    @Deprecated
+    @Override
+    public Connector getConnector(String user, CharSequence pass) throws 
AccumuloException, AccumuloSecurityException {
+      throw new UnsupportedOperationException();
+    }
+
+    @Deprecated
+    @Override
+    public AccumuloConfiguration getConfiguration() {
+      throw new UnsupportedOperationException();
+    }
+
+    @Deprecated
+    @Override
+    public void setConfiguration(AccumuloConfiguration conf) {}
+
     @Override
     public Connector getConnector(String principal, AuthenticationToken token) 
throws AccumuloException, AccumuloSecurityException {
       throw new UnsupportedOperationException();

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/server/master/src/main/java/org/apache/accumulo/master/Master.java
----------------------------------------------------------------------
diff --git a/server/master/src/main/java/org/apache/accumulo/master/Master.java 
b/server/master/src/main/java/org/apache/accumulo/master/Master.java
index 8233673..dbf0f87 100644
--- a/server/master/src/main/java/org/apache/accumulo/master/Master.java
+++ b/server/master/src/main/java/org/apache/accumulo/master/Master.java
@@ -343,7 +343,8 @@ public class Master extends AccumuloServerContext 
implements LiveTServerSet.List
           zoo.putPersistentData(zooRoot + Constants.ZTABLES + "/" + id + 
Constants.ZTABLE_COMPACT_CANCEL_ID, zero, NodeExistsPolicy.SKIP);
         }
 
-        String zpath = zooRoot + Constants.ZCONFIG + 
"/tserver.wal.sync.method";
+        @SuppressWarnings("deprecation")
+        String zpath = zooRoot + Constants.ZCONFIG + "/" + 
Property.TSERV_WAL_SYNC_METHOD.getKey();
         // is the entire instance set to use flushing vs sync?
         boolean flushDefault = false;
         try {
@@ -357,7 +358,8 @@ public class Master extends AccumuloServerContext 
implements LiveTServerSet.List
         for (String id : zoo.getChildren(zooRoot + Constants.ZTABLES)) {
           log.debug("Converting table " + id + " WALog setting to Durability");
           try {
-            String path = zooRoot + Constants.ZTABLES + "/" + id + 
Constants.ZTABLE_CONF + "/table.walog.enabled";
+            @SuppressWarnings("deprecation")
+            String path = zooRoot + Constants.ZTABLES + "/" + id + 
Constants.ZTABLE_CONF + "/" + Property.TABLE_WALOG_ENABLED.getKey();
             byte[] data = zoo.getData(path, null);
             boolean useWAL = Boolean.parseBoolean(new String(data, UTF_8));
             zoo.recursiveDelete(path, NodeMissingPolicy.FAIL);

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/server/master/src/main/java/org/apache/accumulo/master/util/FateAdmin.java
----------------------------------------------------------------------
diff --git 
a/server/master/src/main/java/org/apache/accumulo/master/util/FateAdmin.java 
b/server/master/src/main/java/org/apache/accumulo/master/util/FateAdmin.java
new file mode 100644
index 0000000..a1dd303
--- /dev/null
+++ b/server/master/src/main/java/org/apache/accumulo/master/util/FateAdmin.java
@@ -0,0 +1,104 @@
+/*
+ * 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.accumulo.master.util;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.Constants;
+import org.apache.accumulo.core.cli.Help;
+import org.apache.accumulo.core.client.Instance;
+import org.apache.accumulo.core.zookeeper.ZooUtil;
+import org.apache.accumulo.fate.AdminUtil;
+import org.apache.accumulo.fate.ReadOnlyStore;
+import org.apache.accumulo.fate.ZooStore;
+import org.apache.accumulo.fate.zookeeper.IZooReaderWriter;
+import org.apache.accumulo.master.Master;
+import org.apache.accumulo.server.client.HdfsZooInstance;
+import org.apache.accumulo.server.zookeeper.ZooReaderWriter;
+
+import com.beust.jcommander.JCommander;
+import com.beust.jcommander.Parameter;
+import com.beust.jcommander.Parameters;
+
+/**
+ * A utility to administer FATE operations
+ */
+public class FateAdmin {
+
+  static class TxOpts {
+    @Parameter(description = "<txid>...", required = true)
+    List<String> txids = new ArrayList<>();
+  }
+
+  @Parameters(commandDescription = "Stop an existing FATE by transaction id")
+  static class FailOpts extends TxOpts {}
+
+  @Parameters(commandDescription = "Delete an existing FATE by transaction id")
+  static class DeleteOpts extends TxOpts {}
+
+  @Parameters(commandDescription = "List the existing FATE transactions")
+  static class PrintOpts {}
+
+  public static void main(String[] args) throws Exception {
+    Help opts = new Help();
+    JCommander jc = new JCommander(opts);
+    jc.setProgramName(FateAdmin.class.getName());
+    LinkedHashMap<String,TxOpts> txOpts = new LinkedHashMap<>(2);
+    txOpts.put("fail", new FailOpts());
+    txOpts.put("delete", new DeleteOpts());
+    for (Entry<String,TxOpts> entry : txOpts.entrySet()) {
+      jc.addCommand(entry.getKey(), entry.getValue());
+    }
+    jc.addCommand("print", new PrintOpts());
+    jc.parse(args);
+    if (opts.help || jc.getParsedCommand() == null) {
+      jc.usage();
+      System.exit(1);
+    }
+
+    System.err
+        .printf("This tool has been deprecated%nFATE administration now 
available within 'accumulo shell'%n$ fate fail <txid>... | delete <txid>... | 
print [<txid>...]%n%n");
+
+    AdminUtil<Master> admin = new AdminUtil<>();
+
+    Instance instance = HdfsZooInstance.getInstance();
+    String path = ZooUtil.getRoot(instance) + Constants.ZFATE;
+    String masterPath = ZooUtil.getRoot(instance) + Constants.ZMASTER_LOCK;
+    IZooReaderWriter zk = ZooReaderWriter.getInstance();
+    ZooStore<Master> zs = new ZooStore<>(path, zk);
+
+    if (jc.getParsedCommand().equals("fail")) {
+      for (String txid : txOpts.get(jc.getParsedCommand()).txids) {
+        if (!admin.prepFail(zs, zk, masterPath, txid)) {
+          System.exit(1);
+        }
+      }
+    } else if (jc.getParsedCommand().equals("delete")) {
+      for (String txid : txOpts.get(jc.getParsedCommand()).txids) {
+        if (!admin.prepDelete(zs, zk, masterPath, txid)) {
+          System.exit(1);
+        }
+        admin.deleteLocks(zs, zk, ZooUtil.getRoot(instance) + 
Constants.ZTABLE_LOCKS, txid);
+      }
+    } else if (jc.getParsedCommand().equals("print")) {
+      admin.print(new ReadOnlyStore<>(zs), zk, ZooUtil.getRoot(instance) + 
Constants.ZTABLE_LOCKS);
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java
----------------------------------------------------------------------
diff --git 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java
 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java
index 0aa9d72..31bea15 100644
--- 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java
+++ 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/ShellServlet.java
@@ -81,6 +81,7 @@ public class ShellServlet extends BasicServlet {
       // user attribute is null, check to see if username and password are 
passed as parameters
       user = req.getParameter("user");
       String pass = req.getParameter("pass");
+      String mock = req.getParameter("mock");
       if (user == null || pass == null) {
         // username or password are null, re-authenticate
         sb.append(authenticationForm(req.getRequestURI(), CSRF_TOKEN));
@@ -88,7 +89,7 @@ public class ShellServlet extends BasicServlet {
       }
       try {
         // get a new shell for this user
-        ShellExecutionThread shellThread = new ShellExecutionThread(user, 
pass);
+        ShellExecutionThread shellThread = new ShellExecutionThread(user, 
pass, mock);
         service().submit(shellThread);
         userShells().put(session.getId(), shellThread);
       } catch (IOException e) {
@@ -223,7 +224,8 @@ public class ShellServlet extends BasicServlet {
 
   private String authenticationForm(String requestURI, String csrfToken) {
     return "<div id='login'><form method=POST action='" + requestURI + "'>"
-        + "<table><tr><td>Username:&nbsp;</td><td><input type='text' 
name='user'></td></tr>"
+        + "<table><tr><td>Mock:&nbsp</td><td><input type='checkbox' 
name='mock' value='mock'></td></tr>"
+        + "<tr><td>Username:&nbsp;</td><td><input type='text' 
name='user'></td></tr>"
         + "<tr><td>Password:&nbsp;</td><td><input type='password' 
name='pass'></td><td>" + "<input type='hidden' name='" + CSRF_KEY + "' value='" 
+ csrfToken
         + "'/><input type='submit' 
value='Enter'></td></tr></table></form></div>";
   }
@@ -253,7 +255,7 @@ public class ShellServlet extends BasicServlet {
     private boolean done;
     private boolean readWait;
 
-    private ShellExecutionThread(String username, String password) throws 
IOException {
+    private ShellExecutionThread(String username, String password, String 
mock) throws IOException {
       this.done = false;
       this.cmd = null;
       this.cmdIndex = 0;
@@ -262,7 +264,10 @@ public class ShellServlet extends BasicServlet {
       ConsoleReader reader = new ConsoleReader(this, output);
       this.shell = new Shell(reader);
       shell.setLogErrorsToConsole();
-      if (shell.config("-u", username, "-p", password)) {
+      if (mock != null) {
+        if (shell.config("--fake", "-u", username, "-p", password))
+          throw new IOException("mock shell config error");
+      } else if (shell.config("-u", username, "-p", password)) {
         throw new IOException("shell config error");
       }
     }

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/trace/NullScanner.java
----------------------------------------------------------------------
diff --git 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/trace/NullScanner.java
 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/trace/NullScanner.java
index d96d23f..b91d454 100644
--- 
a/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/trace/NullScanner.java
+++ 
b/server/monitor/src/main/java/org/apache/accumulo/monitor/servlets/trace/NullScanner.java
@@ -53,6 +53,16 @@ public class NullScanner implements Scanner {
   @Override
   public void clearScanIterators() {}
 
+  @Deprecated
+  @Override
+  public void setTimeOut(int timeOut) {}
+
+  @Deprecated
+  @Override
+  public int getTimeOut() {
+    return 0;
+  }
+
   @Override
   public void setRange(Range range) {}
 

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/server/tracer/src/test/java/org/apache/accumulo/tracer/TracerTest.java
----------------------------------------------------------------------
diff --git 
a/server/tracer/src/test/java/org/apache/accumulo/tracer/TracerTest.java 
b/server/tracer/src/test/java/org/apache/accumulo/tracer/TracerTest.java
index 19891a4..6dcf7a4 100644
--- a/server/tracer/src/test/java/org/apache/accumulo/tracer/TracerTest.java
+++ b/server/tracer/src/test/java/org/apache/accumulo/tracer/TracerTest.java
@@ -99,6 +99,7 @@ public class TracerTest {
     public void close() throws IOException {}
   }
 
+  @SuppressWarnings("deprecation")
   @Test
   public void testTrace() throws Exception {
     TestReceiver tracer = new TestReceiver();
@@ -114,7 +115,7 @@ public class TracerTest {
     assertFalse(Trace.isTracing());
 
     Span start = Trace.on("testing");
-    assertEquals(org.apache.htrace.Trace.currentSpan(), 
start.getScope().getSpan());
+    assertEquals(Trace.currentTrace().getSpan(), start.getScope().getSpan());
     assertTrue(Trace.isTracing());
 
     Span span = Trace.start("shortest trace ever");

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/server/tserver/src/main/java/org/apache/accumulo/tserver/TservConstraintEnv.java
----------------------------------------------------------------------
diff --git 
a/server/tserver/src/main/java/org/apache/accumulo/tserver/TservConstraintEnv.java
 
b/server/tserver/src/main/java/org/apache/accumulo/tserver/TservConstraintEnv.java
index 5a50e8f..fc371c9 100644
--- 
a/server/tserver/src/main/java/org/apache/accumulo/tserver/TservConstraintEnv.java
+++ 
b/server/tserver/src/main/java/org/apache/accumulo/tserver/TservConstraintEnv.java
@@ -24,6 +24,7 @@ import 
org.apache.accumulo.core.constraints.Constraint.Environment;
 import org.apache.accumulo.core.data.ByteSequence;
 import org.apache.accumulo.core.data.impl.KeyExtent;
 import org.apache.accumulo.core.security.AuthorizationContainer;
+import org.apache.accumulo.core.security.Authorizations;
 import org.apache.accumulo.core.security.thrift.TCredentials;
 import org.apache.accumulo.server.security.SecurityOperation;
 
@@ -31,6 +32,7 @@ public class TservConstraintEnv implements Environment {
 
   private final TCredentials credentials;
   private final SecurityOperation security;
+  private Authorizations auths;
   private KeyExtent ke;
 
   TservConstraintEnv(SecurityOperation secOp, TCredentials credentials) {
@@ -53,6 +55,18 @@ public class TservConstraintEnv implements Environment {
   }
 
   @Override
+  @Deprecated
+  public Authorizations getAuthorizations() {
+    if (auths == null)
+      try {
+        this.auths = security.getUserAuthorizations(credentials);
+      } catch (ThriftSecurityException e) {
+        throw new RuntimeException(e);
+      }
+    return auths;
+  }
+
+  @Override
   public AuthorizationContainer getAuthorizationsContainer() {
     return new AuthorizationContainer() {
       @Override

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/server/tserver/src/main/java/org/apache/accumulo/tserver/log/LocalWALRecovery.java
----------------------------------------------------------------------
diff --git 
a/server/tserver/src/main/java/org/apache/accumulo/tserver/log/LocalWALRecovery.java
 
b/server/tserver/src/main/java/org/apache/accumulo/tserver/log/LocalWALRecovery.java
index a3d8782..2667b53 100644
--- 
a/server/tserver/src/main/java/org/apache/accumulo/tserver/log/LocalWALRecovery.java
+++ 
b/server/tserver/src/main/java/org/apache/accumulo/tserver/log/LocalWALRecovery.java
@@ -48,6 +48,7 @@ import com.google.common.annotations.VisibleForTesting;
 /**
  * This class will attempt to rewrite any local WALs to HDFS.
  */
+@SuppressWarnings("deprecation")
 public class LocalWALRecovery implements Runnable {
   private static final Logger log = 
LoggerFactory.getLogger(LocalWALRecovery.class);
 
@@ -153,8 +154,8 @@ public class LocalWALRecovery implements Runnable {
           Path localWal = new Path(file.toURI());
           FileSystem localFs = FileSystem.getLocal(fs.getConf());
 
-          Reader reader = new SequenceFile.Reader(localFs.getConf(), 
SequenceFile.Reader.file(localWal.makeQualified(localWal.toUri(),
-              localFs.getWorkingDirectory())));
+          Reader reader = new SequenceFile.Reader(localFs, localWal, 
localFs.getConf());
+          // Reader reader = new SequenceFile.Reader(localFs.getConf(), 
SequenceFile.Reader.file(localWal));
           Path tmp = new Path(options.destination + "/" + name + ".copy");
           FSDataOutputStream writer = fs.create(tmp);
           while (reader.next(key, value)) {

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/server/tserver/src/test/java/org/apache/accumulo/tserver/log/SortedLogRecoveryTest.java
----------------------------------------------------------------------
diff --git 
a/server/tserver/src/test/java/org/apache/accumulo/tserver/log/SortedLogRecoveryTest.java
 
b/server/tserver/src/test/java/org/apache/accumulo/tserver/log/SortedLogRecoveryTest.java
index d9a4e0e..b65d5ce 100644
--- 
a/server/tserver/src/test/java/org/apache/accumulo/tserver/log/SortedLogRecoveryTest.java
+++ 
b/server/tserver/src/test/java/org/apache/accumulo/tserver/log/SortedLogRecoveryTest.java
@@ -138,7 +138,8 @@ public class SortedLogRecoveryTest {
       for (Entry<String,KeyValue[]> entry : logs.entrySet()) {
         String path = workdir + "/" + entry.getKey();
         FileSystem ns = fs.getVolumeByPath(new Path(path)).getFileSystem();
-        Writer map = new MapFile.Writer(ns.getConf(), new Path(path + 
"/log1"), Writer.keyClass(LogFileKey.class), 
Writer.valueClass(LogFileValue.class));
+        @SuppressWarnings("deprecation")
+        Writer map = new MapFile.Writer(ns.getConf(), ns, path + "/log1", 
LogFileKey.class, LogFileValue.class);
         for (KeyValue lfe : entry.getValue()) {
           map.append(lfe.key, lfe.value);
         }

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/server/tserver/src/test/java/org/apache/accumulo/tserver/tablet/RootFilesTest.java
----------------------------------------------------------------------
diff --git 
a/server/tserver/src/test/java/org/apache/accumulo/tserver/tablet/RootFilesTest.java
 
b/server/tserver/src/test/java/org/apache/accumulo/tserver/tablet/RootFilesTest.java
index 7a1a785..d9c6862 100644
--- 
a/server/tserver/src/test/java/org/apache/accumulo/tserver/tablet/RootFilesTest.java
+++ 
b/server/tserver/src/test/java/org/apache/accumulo/tserver/tablet/RootFilesTest.java
@@ -41,10 +41,6 @@ import org.junit.rules.TemporaryFolder;
  *
  */
 public class RootFilesTest {
-  @SuppressWarnings("deprecation")
-  private static final Property INSTANCE_DFS_DIR = Property.INSTANCE_DFS_DIR;
-  @SuppressWarnings("deprecation")
-  private static final Property INSTANCE_DFS_URI = Property.INSTANCE_DFS_URI;
 
   @Rule
   public TemporaryFolder tempFolder = new TemporaryFolder(new 
File(System.getProperty("user.dir") + "/target"));
@@ -120,12 +116,13 @@ public class RootFilesTest {
     }
   }
 
+  @SuppressWarnings("deprecation")
   @Test
   public void testFileReplacement() throws IOException {
 
     ConfigurationCopy conf = new ConfigurationCopy();
-    conf.set(INSTANCE_DFS_URI, "file:///");
-    conf.set(INSTANCE_DFS_DIR, "/");
+    conf.set(Property.INSTANCE_DFS_URI, "file:///");
+    conf.set(Property.INSTANCE_DFS_DIR, "/");
 
     VolumeManager vm = VolumeManagerImpl.get(conf);
 

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/shell/src/main/java/org/apache/accumulo/shell/Shell.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/Shell.java 
b/shell/src/main/java/org/apache/accumulo/shell/Shell.java
index 1819f43..7678ead 100644
--- a/shell/src/main/java/org/apache/accumulo/shell/Shell.java
+++ b/shell/src/main/java/org/apache/accumulo/shell/Shell.java
@@ -66,6 +66,7 @@ import 
org.apache.accumulo.core.data.thrift.TConstraintViolationSummary;
 import 
org.apache.accumulo.core.tabletserver.thrift.ConstraintViolationException;
 import org.apache.accumulo.core.trace.DistributedTrace;
 import org.apache.accumulo.core.util.BadArgumentException;
+import org.apache.accumulo.core.util.DeprecationUtil;
 import org.apache.accumulo.core.util.format.DefaultFormatter;
 import org.apache.accumulo.core.util.format.Formatter;
 import org.apache.accumulo.core.util.format.FormatterConfig;
@@ -95,6 +96,7 @@ import org.apache.accumulo.shell.commands.DeleteIterCommand;
 import org.apache.accumulo.shell.commands.DeleteManyCommand;
 import org.apache.accumulo.shell.commands.DeleteNamespaceCommand;
 import org.apache.accumulo.shell.commands.DeleteRowsCommand;
+import org.apache.accumulo.shell.commands.DeleteScanIterCommand;
 import org.apache.accumulo.shell.commands.DeleteShellIterCommand;
 import org.apache.accumulo.shell.commands.DeleteTableCommand;
 import org.apache.accumulo.shell.commands.DeleteUserCommand;
@@ -147,6 +149,7 @@ import org.apache.accumulo.shell.commands.ScriptCommand;
 import org.apache.accumulo.shell.commands.SetAuthsCommand;
 import org.apache.accumulo.shell.commands.SetGroupsCommand;
 import org.apache.accumulo.shell.commands.SetIterCommand;
+import org.apache.accumulo.shell.commands.SetScanIterCommand;
 import org.apache.accumulo.shell.commands.SetShellIterCommand;
 import org.apache.accumulo.shell.commands.SleepCommand;
 import org.apache.accumulo.shell.commands.SystemPermissionsCommand;
@@ -368,7 +371,9 @@ public class Shell extends ShellOptions implements 
KeywordExecutable {
         }
       }
 
-      DistributedTrace.enable(InetAddress.getLocalHost().getHostName(), 
"shell", clientConf);
+      if (!options.isFake()) {
+        DistributedTrace.enable(InetAddress.getLocalHost().getHostName(), 
"shell", clientConf);
+      }
 
       this.setTableName("");
       connector = instance.getConnector(user, token);
@@ -401,8 +406,8 @@ public class Shell extends ShellOptions implements 
KeywordExecutable {
     Command[] execCommands = {new ExecfileCommand(), new HistoryCommand(), new 
ExtensionCommand(), new ScriptCommand()};
     Command[] exitCommands = {new ByeCommand(), new ExitCommand(), new 
QuitCommand()};
     Command[] helpCommands = {new AboutCommand(), new HelpCommand(), new 
InfoCommand(), new QuestionCommand()};
-    Command[] iteratorCommands = {new DeleteIterCommand(), new 
ListIterCommand(), new SetIterCommand(), new SetShellIterCommand(), new 
ListShellIterCommand(),
-        new DeleteShellIterCommand()};
+    Command[] iteratorCommands = {new DeleteIterCommand(), new 
DeleteScanIterCommand(), new ListIterCommand(), new SetIterCommand(), new 
SetScanIterCommand(),
+        new SetShellIterCommand(), new ListShellIterCommand(), new 
DeleteShellIterCommand()};
     Command[] otherCommands = {new HiddenCommand()};
     Command[] permissionsCommands = {new GrantCommand(), new RevokeCommand(), 
new SystemPermissionsCommand(), new TablePermissionsCommand(),
         new UserPermissionsCommand(), new NamespacePermissionsCommand()};
@@ -446,24 +451,28 @@ public class Shell extends ShellOptions implements 
KeywordExecutable {
   protected void setInstance(ShellOptionsJC options) {
     // should only be one set of instance options set
     instance = null;
-    String instanceName, hosts;
-    if (options.isHdfsZooInstance()) {
-      instanceName = hosts = null;
-    } else if (options.getZooKeeperInstance().size() > 0) {
-      List<String> zkOpts = options.getZooKeeperInstance();
-      instanceName = zkOpts.get(0);
-      hosts = zkOpts.get(1);
+    if (options.isFake()) {
+      instance = DeprecationUtil.makeMockInstance("fake");
     } else {
-      instanceName = options.getZooKeeperInstanceName();
-      hosts = options.getZooKeeperHosts();
-    }
-    final ClientConfiguration clientConf;
-    try {
-      clientConf = options.getClientConfiguration();
-    } catch (ConfigurationException | FileNotFoundException e) {
-      throw new IllegalArgumentException("Unable to load client config from " 
+ options.getClientConfigFile(), e);
+      String instanceName, hosts;
+      if (options.isHdfsZooInstance()) {
+        instanceName = hosts = null;
+      } else if (options.getZooKeeperInstance().size() > 0) {
+        List<String> zkOpts = options.getZooKeeperInstance();
+        instanceName = zkOpts.get(0);
+        hosts = zkOpts.get(1);
+      } else {
+        instanceName = options.getZooKeeperInstanceName();
+        hosts = options.getZooKeeperHosts();
+      }
+      final ClientConfiguration clientConf;
+      try {
+        clientConf = options.getClientConfiguration();
+      } catch (ConfigurationException | FileNotFoundException e) {
+        throw new IllegalArgumentException("Unable to load client config from 
" + options.getClientConfigFile(), e);
+      }
+      instance = getZooInstance(instanceName, hosts, clientConf);
     }
-    instance = getZooInstance(instanceName, hosts, clientConf);
   }
 
   /**

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/shell/src/main/java/org/apache/accumulo/shell/ShellOptionsJC.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/ShellOptionsJC.java 
b/shell/src/main/java/org/apache/accumulo/shell/ShellOptionsJC.java
index 7f476c1..1e5156f 100644
--- a/shell/src/main/java/org/apache/accumulo/shell/ShellOptionsJC.java
+++ b/shell/src/main/java/org/apache/accumulo/shell/ShellOptionsJC.java
@@ -241,6 +241,10 @@ public class ShellOptionsJC {
     return debugEnabled;
   }
 
+  public boolean isFake() {
+    return fake;
+  }
+
   public boolean isHelpEnabled() {
     return helpEnabled;
   }

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteScanIterCommand.java
----------------------------------------------------------------------
diff --git 
a/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteScanIterCommand.java
 
b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteScanIterCommand.java
new file mode 100644
index 0000000..7c8cf22
--- /dev/null
+++ 
b/shell/src/main/java/org/apache/accumulo/shell/commands/DeleteScanIterCommand.java
@@ -0,0 +1,103 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.Shell.Command;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class DeleteScanIterCommand extends Command {
+  private Option nameOpt, allOpt;
+
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final 
Shell shellState) throws Exception {
+    Shell.log.warn("Deprecated, use " + new 
DeleteShellIterCommand().getName());
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+
+    if (cl.hasOption(allOpt.getOpt())) {
+      final List<IteratorSetting> tableScanIterators = 
shellState.scanIteratorOptions.remove(tableName);
+      if (tableScanIterators == null) {
+        Shell.log.info("No scan iterators set on table " + tableName);
+      } else {
+        Shell.log.info("Removed the following scan iterators from table " + 
tableName + ":" + tableScanIterators);
+      }
+    } else if (cl.hasOption(nameOpt.getOpt())) {
+      final String name = cl.getOptionValue(nameOpt.getOpt());
+      final List<IteratorSetting> tableScanIterators = 
shellState.scanIteratorOptions.get(tableName);
+      if (tableScanIterators != null) {
+        boolean found = false;
+        for (Iterator<IteratorSetting> iter = tableScanIterators.iterator(); 
iter.hasNext();) {
+          if (iter.next().getName().equals(name)) {
+            iter.remove();
+            found = true;
+            break;
+          }
+        }
+        if (!found) {
+          Shell.log.info("No iterator named " + name + " found for table " + 
tableName);
+        } else {
+          Shell.log.info("Removed scan iterator " + name + " from table " + 
tableName + " (" + shellState.scanIteratorOptions.get(tableName).size() + " 
left)");
+          if (shellState.scanIteratorOptions.get(tableName).size() == 0) {
+            shellState.scanIteratorOptions.remove(tableName);
+          }
+        }
+      } else {
+        Shell.log.info("No iterator named " + name + " found for table " + 
tableName);
+      }
+    }
+
+    return 0;
+  }
+
+  @Override
+  public String description() {
+    return "deletes a table-specific scan iterator so it is no longer used 
during this shell session";
+  }
+
+  @Override
+  public Options getOptions() {
+    final Options o = new Options();
+
+    OptionGroup nameGroup = new OptionGroup();
+
+    nameOpt = new Option("n", "name", true, "iterator to delete");
+    nameOpt.setArgName("itername");
+
+    allOpt = new Option("a", "all", false, "delete all scan iterators");
+    allOpt.setArgName("all");
+
+    nameGroup.addOption(nameOpt);
+    nameGroup.addOption(allOpt);
+    nameGroup.setRequired(true);
+    o.addOptionGroup(nameGroup);
+    o.addOption(OptUtil.tableOpt("table to delete scan iterators from"));
+
+    return o;
+  }
+
+  @Override
+  public int numArgs() {
+    return 0;
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/shell/src/main/java/org/apache/accumulo/shell/commands/SetIterCommand.java
----------------------------------------------------------------------
diff --git 
a/shell/src/main/java/org/apache/accumulo/shell/commands/SetIterCommand.java 
b/shell/src/main/java/org/apache/accumulo/shell/commands/SetIterCommand.java
index 6e89298..fffdf21 100644
--- a/shell/src/main/java/org/apache/accumulo/shell/commands/SetIterCommand.java
+++ b/shell/src/main/java/org/apache/accumulo/shell/commands/SetIterCommand.java
@@ -53,7 +53,7 @@ import jline.console.ConsoleReader;
 public class SetIterCommand extends Command {
 
   private Option allScopeOpt, mincScopeOpt, majcScopeOpt, scanScopeOpt, 
nameOpt, priorityOpt;
-  private Option ageoffTypeOpt, regexTypeOpt, versionTypeOpt, reqvisTypeOpt, 
classnameTypeOpt;
+  private Option aggTypeOpt, ageoffTypeOpt, regexTypeOpt, versionTypeOpt, 
reqvisTypeOpt, classnameTypeOpt;
 
   @Override
   public int execute(final String fullCommand, final CommandLine cl, final 
Shell shellState) throws AccumuloException, AccumuloSecurityException,
@@ -66,7 +66,12 @@ public class SetIterCommand extends Command {
 
     final Map<String,String> options = new HashMap<>();
     String classname = cl.getOptionValue(classnameTypeOpt.getOpt());
-    if (cl.hasOption(regexTypeOpt.getOpt())) {
+    if (cl.hasOption(aggTypeOpt.getOpt())) {
+      Shell.log.warn("aggregators are deprecated");
+      @SuppressWarnings("deprecation")
+      String deprecatedClassName = 
org.apache.accumulo.core.iterators.AggregatingIterator.class.getName();
+      classname = deprecatedClassName;
+    } else if (cl.hasOption(regexTypeOpt.getOpt())) {
       classname = RegExFilter.class.getName();
     } else if (cl.hasOption(ageoffTypeOpt.getOpt())) {
       classname = AgeOffFilter.class.getName();
@@ -114,6 +119,14 @@ public class SetIterCommand extends Command {
 
     ScanCommand.ensureTserversCanLoadIterator(shellState, tableName, 
classname);
 
+    final String aggregatorClass = options.get("aggregatorClass");
+    @SuppressWarnings("deprecation")
+    String deprecatedAggregatorClassName = 
org.apache.accumulo.core.iterators.aggregation.Aggregator.class.getName();
+    if (aggregatorClass != null && 
!shellState.getConnector().tableOperations().testClassLoad(tableName, 
aggregatorClass, deprecatedAggregatorClassName)) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, 
"Servers are unable to load " + aggregatorClass + " as type "
+          + deprecatedAggregatorClassName);
+    }
+
     for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); 
i.hasNext();) {
       final Entry<String,String> entry = i.next();
       if (entry.getValue() == null || entry.getValue().isEmpty()) {
@@ -148,6 +161,14 @@ public class SetIterCommand extends Command {
           + SortedKeyValueIterator.class.getName());
     }
 
+    final String aggregatorClass = options.get("aggregatorClass");
+    @SuppressWarnings("deprecation")
+    String deprecatedAggregatorClassName = 
org.apache.accumulo.core.iterators.aggregation.Aggregator.class.getName();
+    if (aggregatorClass != null && 
!shellState.getConnector().namespaceOperations().testClassLoad(namespace, 
aggregatorClass, deprecatedAggregatorClassName)) {
+      throw new ShellCommandException(ErrorCode.INITIALIZATION_FAILURE, 
"Servers are unable to load " + aggregatorClass + " as type "
+          + deprecatedAggregatorClassName);
+    }
+
     for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); 
i.hasNext();) {
       final Entry<String,String> entry = i.next();
       if (entry.getValue() == null || entry.getValue().isEmpty()) {
@@ -336,12 +357,14 @@ public class SetIterCommand extends Command {
     final OptionGroup typeGroup = new OptionGroup();
     classnameTypeOpt = new Option("class", "class-name", true, "a java class 
that implements SortedKeyValueIterator");
     classnameTypeOpt.setArgName("name");
+    aggTypeOpt = new Option("agg", "aggregator", false, "an aggregating type");
     regexTypeOpt = new Option("regex", "regular-expression", false, "a regex 
matching iterator");
     versionTypeOpt = new Option("vers", "version", false, "a versioning 
iterator");
     reqvisTypeOpt = new Option("reqvis", "require-visibility", false, "an 
iterator that omits entries with empty visibilities");
     ageoffTypeOpt = new Option("ageoff", "ageoff", false, "an aging off 
iterator");
 
     typeGroup.addOption(classnameTypeOpt);
+    typeGroup.addOption(aggTypeOpt);
     typeGroup.addOption(regexTypeOpt);
     typeGroup.addOption(versionTypeOpt);
     typeGroup.addOption(reqvisTypeOpt);

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/shell/src/main/java/org/apache/accumulo/shell/commands/SetScanIterCommand.java
----------------------------------------------------------------------
diff --git 
a/shell/src/main/java/org/apache/accumulo/shell/commands/SetScanIterCommand.java
 
b/shell/src/main/java/org/apache/accumulo/shell/commands/SetScanIterCommand.java
new file mode 100644
index 0000000..2399d0e
--- /dev/null
+++ 
b/shell/src/main/java/org/apache/accumulo/shell/commands/SetScanIterCommand.java
@@ -0,0 +1,113 @@
+/*
+ * 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.accumulo.shell.commands;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.IteratorSetting;
+import org.apache.accumulo.core.client.Scanner;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.core.iterators.IteratorUtil.IteratorScope;
+import org.apache.accumulo.core.security.Authorizations;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellCommandException;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.OptionGroup;
+import org.apache.commons.cli.Options;
+
+public class SetScanIterCommand extends SetIterCommand {
+  @Override
+  public int execute(final String fullCommand, final CommandLine cl, final 
Shell shellState) throws AccumuloException, AccumuloSecurityException,
+      TableNotFoundException, IOException, ShellCommandException {
+    Shell.log.warn("Deprecated, use " + new SetShellIterCommand().getName());
+    return super.execute(fullCommand, cl, shellState);
+  }
+
+  @Override
+  protected void setTableProperties(final CommandLine cl, final Shell 
shellState, final int priority, final Map<String,String> options, final String 
classname,
+      final String name) throws AccumuloException, AccumuloSecurityException, 
ShellCommandException, TableNotFoundException {
+
+    final String tableName = OptUtil.getTableOpt(cl, shellState);
+
+    ScanCommand.ensureTserversCanLoadIterator(shellState, tableName, 
classname);
+
+    for (Iterator<Entry<String,String>> i = options.entrySet().iterator(); 
i.hasNext();) {
+      final Entry<String,String> entry = i.next();
+      if (entry.getValue() == null || entry.getValue().isEmpty()) {
+        i.remove();
+      }
+    }
+
+    List<IteratorSetting> tableScanIterators = 
shellState.scanIteratorOptions.get(tableName);
+    if (tableScanIterators == null) {
+      tableScanIterators = new ArrayList<>();
+      shellState.scanIteratorOptions.put(tableName, tableScanIterators);
+    }
+    final IteratorSetting setting = new IteratorSetting(priority, name, 
classname);
+    setting.addOptions(options);
+
+    // initialize a scanner to ensure the new setting does not conflict with 
existing settings
+    final String user = shellState.getConnector().whoami();
+    final Authorizations auths = 
shellState.getConnector().securityOperations().getUserAuthorizations(user);
+    final Scanner scanner = shellState.getConnector().createScanner(tableName, 
auths);
+    for (IteratorSetting s : tableScanIterators) {
+      scanner.addScanIterator(s);
+    }
+    scanner.addScanIterator(setting);
+
+    // if no exception has been thrown, it's safe to add it to the list
+    tableScanIterators.add(setting);
+    Shell.log.debug("Scan iterators :" + 
shellState.scanIteratorOptions.get(tableName));
+  }
+
+  @Override
+  public String description() {
+    return "sets a table-specific scan iterator for this shell session";
+  }
+
+  @Override
+  public Options getOptions() {
+    // Remove the options that specify which type of iterator this is, since
+    // they are all scan iterators with this command.
+    final HashSet<OptionGroup> groups = new HashSet<>();
+    final Options parentOptions = super.getOptions();
+    final Options modifiedOptions = new Options();
+    for (Iterator<?> it = parentOptions.getOptions().iterator(); 
it.hasNext();) {
+      Option o = (Option) it.next();
+      if (!IteratorScope.majc.name().equals(o.getOpt()) && 
!IteratorScope.minc.name().equals(o.getOpt()) && 
!IteratorScope.scan.name().equals(o.getOpt())) {
+        modifiedOptions.addOption(o);
+        OptionGroup group = parentOptions.getOptionGroup(o);
+        if (group != null)
+          groups.add(group);
+      }
+    }
+    for (OptionGroup group : groups) {
+      modifiedOptions.addOptionGroup(group);
+    }
+    return modifiedOptions;
+  }
+
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/shell/src/main/java/org/apache/accumulo/shell/mock/MockShell.java
----------------------------------------------------------------------
diff --git a/shell/src/main/java/org/apache/accumulo/shell/mock/MockShell.java 
b/shell/src/main/java/org/apache/accumulo/shell/mock/MockShell.java
new file mode 100644
index 0000000..ebc92f7
--- /dev/null
+++ b/shell/src/main/java/org/apache/accumulo/shell/mock/MockShell.java
@@ -0,0 +1,159 @@
+/*
+ * 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.accumulo.shell.mock;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import jline.console.ConsoleReader;
+
+import org.apache.accumulo.core.client.AccumuloException;
+import org.apache.accumulo.core.client.AccumuloSecurityException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.accumulo.shell.Shell;
+import org.apache.accumulo.shell.ShellOptionsJC;
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.vfs2.FileSystemException;
+
+/**
+ * An Accumulo Shell implementation that allows a developer to attach an 
InputStream and Writer to the Shell for testing purposes.
+ *
+ * @deprecated since 1.8.0; use MiniAccumuloCluster or a standard mock 
framework instead.
+ */
+@Deprecated
+public class MockShell extends Shell {
+  private static final String NEWLINE = "\n";
+
+  protected InputStream in;
+  protected OutputStream out;
+
+  public MockShell(InputStream in, OutputStream out) throws IOException {
+    super();
+    this.in = in;
+    this.out = out;
+  }
+
+  @Override
+  public boolean config(String... args) throws IOException {
+    // If configuring the shell failed, fail quickly
+    if (!super.config(args)) {
+      return false;
+    }
+
+    // Update the ConsoleReader with the input and output "redirected"
+    try {
+      this.reader = new ConsoleReader(in, out);
+    } catch (Exception e) {
+      printException(e);
+      return false;
+    }
+
+    // Don't need this for testing purposes
+    this.reader.setHistoryEnabled(false);
+    this.reader.setPaginationEnabled(false);
+
+    // Make the parsing from the client easier;
+    this.verbose = false;
+    return true;
+  }
+
+  @Override
+  protected void setInstance(ShellOptionsJC options) {
+    // We always want a MockInstance for this test
+    instance = new org.apache.accumulo.core.client.mock.MockInstance();
+  }
+
+  @Override
+  public int start() throws IOException {
+    String input;
+    if (isVerbose())
+      printInfo();
+
+    if (execFile != null) {
+      java.util.Scanner scanner = new java.util.Scanner(execFile, 
UTF_8.name());
+      try {
+        while (scanner.hasNextLine() && !hasExited()) {
+          execCommand(scanner.nextLine(), true, isVerbose());
+        }
+      } finally {
+        scanner.close();
+      }
+    } else if (execCommand != null) {
+      for (String command : execCommand.split("\n")) {
+        execCommand(command, true, isVerbose());
+      }
+      return exitCode;
+    }
+
+    while (true) {
+      if (hasExited())
+        return exitCode;
+
+      reader.setPrompt(getDefaultPrompt());
+      input = reader.readLine();
+      if (input == null) {
+        reader.println();
+        return exitCode;
+      } // user canceled
+
+      execCommand(input, false, false);
+    }
+  }
+
+  /**
+   * @param in
+   *          the in to set
+   */
+  public void setConsoleInputStream(InputStream in) {
+    this.in = in;
+  }
+
+  /**
+   * @param out
+   *          the output stream to set
+   */
+  public void setConsoleWriter(OutputStream out) {
+    this.out = out;
+  }
+
+  @Override
+  public ClassLoader getClassLoader(final CommandLine cl, final Shell 
shellState) throws AccumuloException, TableNotFoundException, 
AccumuloSecurityException,
+      IOException, FileSystemException {
+    return MockShell.class.getClassLoader();
+  }
+
+  /**
+   * Convenience method to create the byte-array to hand to the console
+   *
+   * @param commands
+   *          An array of commands to run
+   * @return A byte[] input stream which can be handed to the console.
+   */
+  public static ByteArrayInputStream makeCommands(String... commands) {
+    StringBuilder sb = new StringBuilder(commands.length * 8);
+
+    for (String command : commands) {
+      sb.append(command).append(NEWLINE);
+    }
+
+    return new ByteArrayInputStream(sb.toString().getBytes(UTF_8));
+  }
+}

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/shell/src/test/java/org/apache/accumulo/shell/ShellConfigTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/ShellConfigTest.java 
b/shell/src/test/java/org/apache/accumulo/shell/ShellConfigTest.java
index 5e8736c..8bef14d 100644
--- a/shell/src/test/java/org/apache/accumulo/shell/ShellConfigTest.java
+++ b/shell/src/test/java/org/apache/accumulo/shell/ShellConfigTest.java
@@ -24,48 +24,29 @@ import java.io.File;
 import java.io.FileDescriptor;
 import java.io.FileInputStream;
 import java.io.IOException;
-import java.io.OutputStream;
 import java.io.PrintStream;
 import java.nio.file.Files;
 import java.util.HashMap;
 import java.util.Map;
 
+import jline.console.ConsoleReader;
+
 import org.apache.accumulo.core.client.ClientConfiguration;
 import org.apache.accumulo.core.client.security.tokens.PasswordToken;
 import org.apache.accumulo.core.conf.AccumuloConfiguration;
 import org.apache.accumulo.core.conf.ConfigurationCopy;
 import org.apache.accumulo.core.conf.Property;
+import org.apache.accumulo.shell.ShellTest.TestOutputStream;
 import org.apache.log4j.Level;
 import org.junit.After;
 import org.junit.Before;
-import org.junit.Ignore;
 import org.junit.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.beust.jcommander.ParameterException;
 
-import jline.console.ConsoleReader;
-
 public class ShellConfigTest {
-
-  public static class TestOutputStream extends OutputStream {
-    StringBuilder sb = new StringBuilder();
-
-    @Override
-    public void write(int b) throws IOException {
-      sb.append((char) (0xff & b));
-    }
-
-    public String get() {
-      return sb.toString();
-    }
-
-    public void clear() {
-      sb.setLength(0);
-    }
-  }
-
   TestOutputStream output;
   Shell shell;
   PrintStream out;
@@ -121,20 +102,17 @@ public class ShellConfigTest {
     assertTrue("Did not print usage", output.get().startsWith("Usage"));
   }
 
-  @Ignore
   @Test
   public void testTokenWithoutOptions() throws IOException {
     assertFalse(shell.config(args("--fake", "-tc", 
PasswordToken.class.getName())));
     assertFalse(output.get().contains(ParameterException.class.getName()));
   }
 
-  @Ignore
   @Test
   public void testTokenAndOption() throws IOException {
     assertTrue(shell.config(args("--fake", "-tc", 
PasswordToken.class.getName(), "-u", "foo", "-l", "password=foo")));
   }
 
-  @Ignore
   @Test
   public void testTokenAndOptionAndPassword() throws IOException {
     assertFalse(shell.config(args("--fake", "-tc", 
PasswordToken.class.getName(), "-l", "password=foo", "-p", "bar")));

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/shell/src/test/java/org/apache/accumulo/shell/ShellSetInstanceTest.java
----------------------------------------------------------------------
diff --git 
a/shell/src/test/java/org/apache/accumulo/shell/ShellSetInstanceTest.java 
b/shell/src/test/java/org/apache/accumulo/shell/ShellSetInstanceTest.java
index 6dae0b4..428481a 100644
--- a/shell/src/test/java/org/apache/accumulo/shell/ShellSetInstanceTest.java
+++ b/shell/src/test/java/org/apache/accumulo/shell/ShellSetInstanceTest.java
@@ -34,6 +34,8 @@ import java.util.Collections;
 import java.util.List;
 import java.util.UUID;
 
+import jline.console.ConsoleReader;
+
 import org.apache.accumulo.core.client.ClientConfiguration;
 import org.apache.accumulo.core.client.ClientConfiguration.ClientProperty;
 import org.apache.accumulo.core.client.ZooKeeperInstance;
@@ -47,6 +49,7 @@ import org.apache.log4j.Level;
 import org.easymock.EasyMock;
 import org.junit.After;
 import org.junit.AfterClass;
+import org.junit.Assert;
 import org.junit.Assume;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -56,17 +59,10 @@ import 
org.powermock.core.classloader.annotations.PowerMockIgnore;
 import org.powermock.core.classloader.annotations.PrepareForTest;
 import org.powermock.modules.junit4.PowerMockRunner;
 
-import jline.console.ConsoleReader;
-
 @RunWith(PowerMockRunner.class)
 @PowerMockIgnore("javax.security.*")
 @PrepareForTest({Shell.class, ZooUtil.class, ConfigSanityCheck.class})
 public class ShellSetInstanceTest {
-  @SuppressWarnings("deprecation")
-  private static Property INSTANCE_DFS_DIR = Property.INSTANCE_DFS_DIR;
-  @SuppressWarnings("deprecation")
-  private static Property INSTANCE_DFS_URI = Property.INSTANCE_DFS_URI;
-
   public static class TestOutputStream extends OutputStream {
     StringBuilder sb = new StringBuilder();
 
@@ -125,6 +121,17 @@ public class ShellSetInstanceTest {
     SiteConfiguration.clearInstance();
   }
 
+  @Deprecated
+  @Test
+  public void testSetInstance_Fake() throws Exception {
+    ShellOptionsJC opts = createMock(ShellOptionsJC.class);
+    expect(opts.isFake()).andReturn(true);
+    replay(opts);
+
+    shell.setInstance(opts);
+    Assert.assertTrue(shell.getInstance() instanceof 
org.apache.accumulo.core.client.mock.MockInstance);
+  }
+
   @Test
   public void testSetInstance_HdfsZooInstance_Explicit() throws Exception {
     testSetInstance_HdfsZooInstance(true, false, false);
@@ -148,6 +155,7 @@ public class ShellSetInstanceTest {
   private void testSetInstance_HdfsZooInstance(boolean explicitHdfs, boolean 
onlyInstance, boolean onlyHosts) throws Exception {
     ClientConfiguration clientConf = createMock(ClientConfiguration.class);
     ShellOptionsJC opts = createMock(ShellOptionsJC.class);
+    expect(opts.isFake()).andReturn(false);
     expect(opts.getClientConfiguration()).andReturn(clientConf);
     expect(opts.isHdfsZooInstance()).andReturn(explicitHdfs);
     if (!explicitHdfs) {
@@ -183,10 +191,14 @@ public class ShellSetInstanceTest {
     }
     if (!onlyInstance) {
       
expect(clientConf.containsKey(Property.INSTANCE_VOLUMES.getKey())).andReturn(false).atLeastOnce();
-      
expect(clientConf.containsKey(INSTANCE_DFS_DIR.getKey())).andReturn(true).atLeastOnce();
-      
expect(clientConf.containsKey(INSTANCE_DFS_URI.getKey())).andReturn(true).atLeastOnce();
-      
expect(clientConf.getString(INSTANCE_DFS_URI.getKey())).andReturn("hdfs://nn1").atLeastOnce();
-      
expect(clientConf.getString(INSTANCE_DFS_DIR.getKey())).andReturn("/dfs").atLeastOnce();
+      @SuppressWarnings("deprecation")
+      String INSTANCE_DFS_DIR_KEY = Property.INSTANCE_DFS_DIR.getKey();
+      @SuppressWarnings("deprecation")
+      String INSTANCE_DFS_URI_KEY = Property.INSTANCE_DFS_URI.getKey();
+      
expect(clientConf.containsKey(INSTANCE_DFS_DIR_KEY)).andReturn(true).atLeastOnce();
+      
expect(clientConf.containsKey(INSTANCE_DFS_URI_KEY)).andReturn(true).atLeastOnce();
+      
expect(clientConf.getString(INSTANCE_DFS_URI_KEY)).andReturn("hdfs://nn1").atLeastOnce();
+      
expect(clientConf.getString(INSTANCE_DFS_DIR_KEY)).andReturn("/dfs").atLeastOnce();
     }
 
     UUID randomUUID = null;
@@ -221,6 +233,7 @@ public class ShellSetInstanceTest {
   private void testSetInstance_ZKInstance(boolean dashZ) throws Exception {
     ClientConfiguration clientConf = createMock(ClientConfiguration.class);
     ShellOptionsJC opts = createMock(ShellOptionsJC.class);
+    expect(opts.isFake()).andReturn(false);
     expect(opts.getClientConfiguration()).andReturn(clientConf);
     expect(opts.isHdfsZooInstance()).andReturn(false);
     
expect(clientConf.getKeys()).andReturn(Arrays.asList(ClientProperty.INSTANCE_NAME.getKey(),
 ClientProperty.INSTANCE_ZK_HOST.getKey()).iterator());

http://git-wip-us.apache.org/repos/asf/accumulo/blob/4f2e6472/shell/src/test/java/org/apache/accumulo/shell/ShellTest.java
----------------------------------------------------------------------
diff --git a/shell/src/test/java/org/apache/accumulo/shell/ShellTest.java 
b/shell/src/test/java/org/apache/accumulo/shell/ShellTest.java
new file mode 100644
index 0000000..dc902ce
--- /dev/null
+++ b/shell/src/test/java/org/apache/accumulo/shell/ShellTest.java
@@ -0,0 +1,394 @@
+/*
+ * 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.accumulo.shell;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.nio.file.Files;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.TimeZone;
+
+import org.apache.log4j.Level;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import jline.console.ConsoleReader;
+
+public class ShellTest {
+  private static final Logger log = LoggerFactory.getLogger(ShellTest.class);
+
+  public static class TestOutputStream extends OutputStream {
+    StringBuilder sb = new StringBuilder();
+
+    @Override
+    public void write(int b) throws IOException {
+      sb.append((char) (0xff & b));
+    }
+
+    public String get() {
+      return sb.toString();
+    }
+
+    public void clear() {
+      sb.setLength(0);
+    }
+  }
+
+  public static class StringInputStream extends InputStream {
+    private String source = "";
+    private int offset = 0;
+
+    @Override
+    public int read() throws IOException {
+      if (offset == source.length())
+        return '\n';
+      else
+        return source.charAt(offset++);
+    }
+
+    public void set(String other) {
+      source = other;
+      offset = 0;
+    }
+  }
+
+  private StringInputStream input;
+  private TestOutputStream output;
+  private Shell shell;
+  private File config;
+
+  void execExpectList(String cmd, boolean expecteGoodExit, List<String> 
expectedStrings) throws IOException {
+    exec(cmd);
+    if (expecteGoodExit) {
+      assertGoodExit("", true);
+    } else {
+      assertBadExit("", true);
+    }
+
+    for (String expectedString : expectedStrings) {
+      assertTrue(expectedString + " was not present in " + output.get(), 
output.get().contains(expectedString));
+    }
+  }
+
+  void exec(String cmd) throws IOException {
+    output.clear();
+    shell.execCommand(cmd, true, true);
+  }
+
+  void exec(String cmd, boolean expectGoodExit) throws IOException {
+    exec(cmd);
+    if (expectGoodExit)
+      assertGoodExit("", true);
+    else
+      assertBadExit("", true);
+  }
+
+  void exec(String cmd, boolean expectGoodExit, String expectString) throws 
IOException {
+    exec(cmd, expectGoodExit, expectString, true);
+  }
+
+  void exec(String cmd, boolean expectGoodExit, String expectString, boolean 
stringPresent) throws IOException {
+    exec(cmd);
+    if (expectGoodExit)
+      assertGoodExit(expectString, stringPresent);
+    else
+      assertBadExit(expectString, stringPresent);
+  }
+
+  @Before
+  public void setup() throws IOException {
+    TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
+    Shell.log.setLevel(Level.OFF);
+    output = new TestOutputStream();
+    input = new StringInputStream();
+    config = Files.createTempFile(null, null).toFile();
+    shell = new Shell(new ConsoleReader(input, output));
+    shell.setLogErrorsToConsole();
+    shell.config("--config-file", config.toString(), "--fake", "-u", "test", 
"-p", "secret");
+  }
+
+  @After
+  public void teardown() {
+    if (config.exists()) {
+      if (!config.delete()) {
+        log.error("Unable to delete {}", config);
+      }
+    }
+    shell.shutdown();
+  }
+
+  void assertGoodExit(String s, boolean stringPresent) {
+    Shell.log.debug(output.get());
+    assertEquals(shell.getExitCode(), 0);
+    if (s.length() > 0)
+      assertEquals(s + " present in " + output.get() + " was not " + 
stringPresent, stringPresent, output.get().contains(s));
+  }
+
+  void assertBadExit(String s, boolean stringPresent) {
+    Shell.log.debug(output.get());
+    assertTrue(shell.getExitCode() > 0);
+    if (s.length() > 0)
+      assertEquals(s + " present in " + output.get() + " was not " + 
stringPresent, stringPresent, output.get().contains(s));
+    shell.resetExitCode();
+  }
+
+  @Test
+  public void aboutTest() throws IOException {
+    Shell.log.debug("Starting about test -----------------------------------");
+    exec("about", true, "Shell - Apache Accumulo Interactive Shell");
+    exec("about -v", true, "Current user:");
+    exec("about arg", false, "java.lang.IllegalArgumentException: Expected 0 
arguments");
+  }
+
+  @Test
+  public void addGetSplitsTest() throws IOException {
+    Shell.log.debug("Starting addGetSplits test ----------------------------");
+    exec("addsplits arg", false, "java.lang.IllegalStateException: Not in a 
table context");
+    exec("createtable test", true);
+    exec("addsplits 1 \\x80", true);
+    exec("getsplits", true, "1\n\\x80");
+    exec("getsplits -m 1", true, "1");
+    exec("getsplits -b64", true, "MQ==\ngA==");
+    exec("deletetable test -f", true, "Table: [test] has been deleted");
+  }
+
+  @Test
+  public void insertDeleteScanTest() throws IOException {
+    Shell.log.debug("Starting insertDeleteScan test ------------------------");
+    exec("insert r f q v", false, "java.lang.IllegalStateException: Not in a 
table context");
+    exec("delete r f q", false, "java.lang.IllegalStateException: Not in a 
table context");
+    exec("createtable test", true);
+    exec("insert r f q v", true);
+    exec("scan", true, "r f:q []    v");
+    exec("delete r f q", true);
+    exec("scan", true, "r f:q []    v", false);
+    exec("insert \\x90 \\xa0 \\xb0 \\xc0\\xd0\\xe0\\xf0", true);
+    exec("scan", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0");
+    exec("scan -f 2", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0");
+    exec("scan -f 2", true, "\\x90 \\xA0:\\xB0 []    \\xC0\\xD0\\xE0", false);
+    exec("scan -b \\x90 -e \\x90 -c \\xA0", true, "\\x90 \\xA0:\\xB0 []    
\\xC0");
+    exec("scan -b \\x90 -e \\x90 -c \\xA0:\\xB0", true, "\\x90 \\xA0:\\xB0 []  
  \\xC0");
+    exec("scan -b \\x90 -be", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("scan -e \\x90 -ee", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("scan -b \\x90\\x00", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("scan -e \\x8f", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("delete \\x90 \\xa0 \\xb0", true);
+    exec("scan", true, "\\x90 \\xA0:\\xB0 []    \\xC0", false);
+    exec("deletetable test -f", true, "Table: [test] has been deleted");
+  }
+
+  @Test
+  public void deleteManyTest() throws IOException {
+    exec("deletemany", false, "java.lang.IllegalStateException: Not in a table 
context");
+    exec("createtable test", true);
+    exec("deletemany", true, "\n");
+
+    exec("insert 0 0 0 0 -ts 0");
+    exec("insert 0 0 0 0 -l 0 -ts 0");
+    exec("insert 1 1 1 1 -ts 1");
+    exec("insert 2 2 2 2 -ts 2");
+
+    // prompts for delete, and rejects by default
+    exec("deletemany", true, "[SKIPPED] 0 0:0 []");
+    exec("deletemany -r 0", true, "[SKIPPED] 0 0:0 []");
+    exec("deletemany -r 0 -f", true, "[DELETED] 0 0:0 []");
+
+    // with auths, can delete the other record
+    exec("setauths -s 0");
+    exec("deletemany -r 0 -f", true, "[DELETED] 0 0:0 [0]");
+
+    // delete will show the timestamp
+    exec("deletemany -r 1 -f -st", true, "[DELETED] 1 1:1 [] 1");
+
+    // DeleteManyCommand has its own Formatter (DeleterFormatter), so it does 
not honor the -fm flag
+    exec("deletemany -r 2 -f -st -fm 
org.apache.accumulo.core.util.format.DateStringFormatter", true, "[DELETED] 2 
2:2 [] 2");
+
+    exec("setauths -c ", true);
+    exec("deletetable test -f", true, "Table: [test] has been deleted");
+  }
+
+  @Test
+  public void authsTest() throws Exception {
+    Shell.log.debug("Starting auths test --------------------------");
+    exec("setauths x,y,z", false, "Missing required option");
+    exec("setauths -s x,y,z -u notauser", false, "user does not exist");
+    exec("setauths -s y,z,x", true);
+    exec("getauths -u notauser", false, "user does not exist");
+    execExpectList("getauths", true, Arrays.asList("x", "y", "z"));
+    exec("addauths -u notauser", false, "Missing required option");
+    exec("addauths -u notauser -s foo", false, "user does not exist");
+    exec("addauths -s a", true);
+    execExpectList("getauths", true, Arrays.asList("x", "y", "z", "a"));
+    exec("setauths -c", true);
+  }
+
+  @Test
+  public void userTest() throws Exception {
+    Shell.log.debug("Starting user test --------------------------");
+    // Test cannot be done via junit because createuser only prompts for 
password
+    // exec("createuser root", false, "user exists");
+  }
+
+  @Test
+  public void duContextTest() throws Exception {
+    Shell.log.debug("Starting du context test --------------------------");
+    exec("createtable t", true);
+    exec("du", true, "0 [t]");
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+  }
+
+  @Test
+  public void duTest() throws IOException {
+    Shell.log.debug("Starting DU test --------------------------");
+    exec("createtable t", true);
+    exec("du t", true, "0 [t]");
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+  }
+
+  @Test
+  public void duPatternTest() throws IOException {
+    Shell.log.debug("Starting DU with pattern test 
--------------------------");
+    exec("createtable t", true);
+    exec("createtable tt", true);
+    exec("du -p t.*", true, "0 [t, tt]");
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+    exec("deletetable tt -f", true, "Table: [tt] has been deleted");
+  }
+
+  @Test
+  public void scanTimestampTest() throws IOException {
+    Shell.log.debug("Starting scanTimestamp test ------------------------");
+    exec("createtable test", true);
+    exec("insert r f q v -ts 0", true);
+    exec("scan -st", true, "r f:q [] 0    v");
+    exec("scan -st -f 0", true, " : [] 0   ");
+    exec("deletemany -f", true);
+    exec("deletetable test -f", true, "Table: [test] has been deleted");
+  }
+
+  @Test
+  public void scanFewTest() throws IOException {
+    Shell.log.debug("Starting scanFew test ------------------------");
+    exec("createtable test", true);
+    // historically, showing few did not pertain to ColVis or Timestamp
+    exec("insert 1 123 123456 -l '12345678' -ts 123456789 1234567890", true);
+    exec("setauths -s 12345678", true);
+    String expected = "1 123:123456 [12345678] 123456789    1234567890";
+    String expectedFew = "1 123:12345 [12345678] 123456789    12345";
+    exec("scan -st", true, expected);
+    exec("scan -st -f 5", true, expectedFew);
+    // also prove that BinaryFormatter behaves same as the default
+    exec("scan -st -fm org.apache.accumulo.core.util.format.BinaryFormatter", 
true, expected);
+    exec("scan -st -f 5 -fm 
org.apache.accumulo.core.util.format.BinaryFormatter", true, expectedFew);
+    exec("setauths -c", true);
+    exec("deletetable test -f", true, "Table: [test] has been deleted");
+  }
+
+  @Test
+  public void scanDateStringFormatterTest() throws IOException {
+    Shell.log.debug("Starting scan dateStringFormatter test 
--------------------------");
+    exec("createtable t", true);
+    exec("insert r f q v -ts 0", true);
+    @SuppressWarnings("deprecation")
+    DateFormat dateFormat = new 
SimpleDateFormat(org.apache.accumulo.core.util.format.DateStringFormatter.DATE_FORMAT);
+    String expected = String.format("r f:q [] %s    v", dateFormat.format(new 
Date(0)));
+    // historically, showing few did not pertain to ColVis or Timestamp
+    String expectedFew = expected;
+    String expectedNoTimestamp = String.format("r f:q []    v");
+    exec("scan -fm org.apache.accumulo.core.util.format.DateStringFormatter 
-st", true, expected);
+    exec("scan -fm org.apache.accumulo.core.util.format.DateStringFormatter 
-st -f 1000", true, expected);
+    exec("scan -fm org.apache.accumulo.core.util.format.DateStringFormatter 
-st -f 5", true, expectedFew);
+    exec("scan -fm org.apache.accumulo.core.util.format.DateStringFormatter", 
true, expectedNoTimestamp);
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+  }
+
+  @Test
+  public void grepTest() throws IOException {
+    Shell.log.debug("Starting grep test --------------------------");
+    exec("grep", false, "java.lang.IllegalStateException: Not in a table 
context");
+    exec("createtable t", true);
+    exec("setauths -s vis", true);
+    exec("insert r f q v -ts 0 -l vis", true);
+
+    String expected = "r f:q [vis]    v";
+    String expectedTimestamp = "r f:q [vis] 0    v";
+    exec("grep", false, "No terms specified");
+    exec("grep non_matching_string", true, "");
+    // historically, showing few did not pertain to ColVis or Timestamp
+    exec("grep r", true, expected);
+    exec("grep r -f 1", true, expected);
+    exec("grep r -st", true, expectedTimestamp);
+    exec("grep r -st -f 1", true, expectedTimestamp);
+    exec("setauths -c", true);
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+  }
+
+  @Test
+  public void commentTest() throws IOException {
+    Shell.log.debug("Starting comment test --------------------------");
+    exec("#", true, "Unknown command", false);
+    exec("# foo", true, "Unknown command", false);
+    exec("- foo", true, "Unknown command", true);
+  }
+
+  @Test
+  public void execFileTest() throws IOException {
+    Shell.log.debug("Starting exec file test --------------------------");
+    shell.config("--config-file", config.toString(), "--fake", "-u", "test", 
"-p", "secret", "-f", "src/test/resources/shelltest.txt");
+    assertEquals(0, shell.start());
+    assertGoodExit("Unknown command", false);
+  }
+
+  @Test
+  public void setIterTest() throws IOException {
+    Shell.log.debug("Starting setiter test --------------------------");
+    exec("createtable t", true);
+
+    String cmdJustClass = "setiter -class VersioningIterator -p 1";
+    exec(cmdJustClass, false, "java.lang.IllegalArgumentException", false);
+    exec(cmdJustClass, false, "fully qualified package name", true);
+
+    String cmdFullPackage = "setiter -class o.a.a.foo -p 1";
+    exec(cmdFullPackage, false, "java.lang.IllegalArgumentException", false);
+    exec(cmdFullPackage, false, "class not found", true);
+
+    String cmdNoOption = "setiter -class java.lang.String -p 1";
+    exec(cmdNoOption, false, "loaded successfully but does not implement 
SortedKeyValueIterator", true);
+
+    input.set("\n\n");
+    exec("setiter -scan -class 
org.apache.accumulo.core.iterators.ColumnFamilyCounter -p 30 -name foo", true);
+
+    input.set("bar\nname value\n");
+    exec("setiter -scan -class 
org.apache.accumulo.core.iterators.ColumnFamilyCounter -p 31", true);
+
+    // TODO can't verify this as config -t fails, functionality verified in 
ShellServerIT
+
+    exec("deletetable t -f", true, "Table: [t] has been deleted");
+  }
+}

Reply via email to