Updated Branches: refs/heads/master de185a23b -> ba9bfa938
ACCUMULO-2206 add a test for a theory about recovering a tablet that has no mutations Project: http://git-wip-us.apache.org/repos/asf/accumulo/repo Commit: http://git-wip-us.apache.org/repos/asf/accumulo/commit/8ead5c64 Tree: http://git-wip-us.apache.org/repos/asf/accumulo/tree/8ead5c64 Diff: http://git-wip-us.apache.org/repos/asf/accumulo/diff/8ead5c64 Branch: refs/heads/master Commit: 8ead5c64d21e03d1a674c151ce624807791c3d13 Parents: b53b8cf Author: Eric Newton <eric.new...@gmail.com> Authored: Fri Jan 17 13:02:30 2014 -0500 Committer: Eric Newton <eric.new...@gmail.com> Committed: Fri Jan 17 13:02:49 2014 -0500 ---------------------------------------------------------------------- .../accumulo/test/NoMutationRecoveryIT.java | 118 +++++++++++++++++++ 1 file changed, 118 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/accumulo/blob/8ead5c64/test/src/test/java/org/apache/accumulo/test/NoMutationRecoveryIT.java ---------------------------------------------------------------------- diff --git a/test/src/test/java/org/apache/accumulo/test/NoMutationRecoveryIT.java b/test/src/test/java/org/apache/accumulo/test/NoMutationRecoveryIT.java new file mode 100644 index 0000000..4656d30 --- /dev/null +++ b/test/src/test/java/org/apache/accumulo/test/NoMutationRecoveryIT.java @@ -0,0 +1,118 @@ +/* + * 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.test; + +import static org.junit.Assert.*; + +import java.util.Map.Entry; + +import org.apache.accumulo.core.client.BatchWriter; +import org.apache.accumulo.core.client.BatchWriterConfig; +import org.apache.accumulo.core.client.Connector; +import org.apache.accumulo.core.client.Scanner; +import org.apache.accumulo.core.data.Key; +import org.apache.accumulo.core.data.Mutation; +import org.apache.accumulo.core.data.PartialKey; +import org.apache.accumulo.core.data.Value; +import org.apache.accumulo.core.metadata.MetadataTable; +import org.apache.accumulo.core.metadata.RootTable; +import org.apache.accumulo.core.metadata.schema.MetadataSchema; +import org.apache.accumulo.core.security.Authorizations; +import org.apache.accumulo.core.security.TablePermission; +import org.apache.accumulo.minicluster.ServerType; +import org.apache.accumulo.minicluster.impl.MiniAccumuloConfigImpl; +import org.apache.accumulo.minicluster.impl.ProcessReference; +import org.apache.accumulo.test.functional.ConfigurableMacIT; +import org.apache.hadoop.io.Text; +import org.junit.Test; + +// Verify that a recovery of a log without any mutations removes the log reference +public class NoMutationRecoveryIT extends ConfigurableMacIT { + + static final String TABLE = "table"; + + @Override + public void configure(MiniAccumuloConfigImpl cfg) { + cfg.useMiniDFS(true); + cfg.setNumTservers(1); + } + + public boolean equals(Entry<Key, Value> a, Entry<Key, Value> b) { + // comparison, without timestamp + Key akey = a.getKey(); + Key bkey = b.getKey(); + return akey.compareTo(bkey, PartialKey.ROW_COLFAM_COLQUAL_COLVIS) == 0 && a.getValue().equals(b.getValue()); + } + + @Test(timeout = 2 * 60 * 1000) + public void test() throws Exception { + Connector conn = getConnector(); + conn.tableOperations().create(TABLE); + update(conn, TABLE, new Text("row"), new Text("cf"), new Text("cq"), new Value("value".getBytes())); + Entry<Key, Value> logRef = getLogRef(conn, MetadataTable.NAME); + conn.tableOperations().flush(TABLE, null, null, true); + for (@SuppressWarnings("unused") Entry<Key, Value> refs : getLogRefs(conn, MetadataTable.NAME)) { + fail("should not have any refs"); + } + conn.securityOperations().grantTablePermission(conn.whoami(), MetadataTable.NAME, TablePermission.WRITE); + update(conn, MetadataTable.NAME, logRef); + assertTrue(equals(logRef, getLogRef(conn, MetadataTable.NAME))); + conn.tableOperations().flush(MetadataTable.NAME, null, null, true); + conn.tableOperations().flush(RootTable.NAME, null, null, true); + for (ProcessReference proc : cluster.getProcesses().get(ServerType.TABLET_SERVER)) { + cluster.killProcess(ServerType.TABLET_SERVER, proc); + } + cluster.start(); + Scanner s = conn.createScanner(TABLE, Authorizations.EMPTY); + int count = 0; + for (Entry<Key,Value> e : s) { + assertEquals(e.getKey().getRow().toString(), "row"); + assertEquals(e.getKey().getColumnFamily().toString(), "cf"); + assertEquals(e.getKey().getColumnQualifier().toString(), "cq"); + assertEquals(e.getValue().toString(), "value"); + count++; + } + assertEquals(1, count); + for (Entry<Key, Value> ref : getLogRefs(conn, MetadataTable.NAME)) { + assertFalse(equals(ref, logRef)); + } + } + + private void update(Connector conn, String name, Entry<Key,Value> logRef) throws Exception { + Key k = logRef.getKey(); + update(conn, name, k.getRow(), k.getColumnFamily(), k.getColumnQualifier(), logRef.getValue()); + } + + private Iterable<Entry<Key, Value>> getLogRefs(Connector conn, String table) throws Exception { + Scanner s = conn.createScanner(table, Authorizations.EMPTY); + s.fetchColumnFamily(MetadataSchema.TabletsSection.LogColumnFamily.NAME); + return s; + } + + private Entry<Key,Value> getLogRef(Connector conn, String table) throws Exception { + return getLogRefs(conn, table).iterator().next(); + } + + private void update(Connector conn, String table, Text row, Text cf, Text cq, Value value) throws Exception { + BatchWriter bw = conn.createBatchWriter(table, new BatchWriterConfig()); + Mutation m = new Mutation(row); + m.put(cf, cq, value); + bw.addMutation(m); + bw.close(); + } + +}