Skip to content

Commit

Permalink
Merge pull request #21 from carterpage/test-gets
Browse files Browse the repository at this point in the history
Test gets
  • Loading branch information
AngusDavis committed Jun 9, 2014
2 parents 1bce24e + 655eafd commit 06a024f
Show file tree
Hide file tree
Showing 11 changed files with 805 additions and 226 deletions.
3 changes: 1 addition & 2 deletions src/main/java/com/google/cloud/anviltop/hbase/AnvilTop.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
package com.google.cloud.anviltop.hbase;

/*
* Copyright (c) 2013 Google Inc.
*
Expand All @@ -13,6 +11,7 @@
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.cloud.anviltop.hbase;

import com.google.protobuf.Descriptors;
import com.google.protobuf.Message;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,17 @@
/*
* Copyright (c) 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/

// Because MasterKeepAliveConnection is default scope, we have to use this package. :-/
package org.apache.hadoop.hbase.client;

Expand Down Expand Up @@ -31,19 +45,6 @@
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/*
* Copyright (c) 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
public class AnvilTopConnection implements HConnection, Closeable {
private static final Log LOG = LogFactory.getLog(AnvilTopConnection.class);

Expand Down
73 changes: 56 additions & 17 deletions src/test/java/com/google/cloud/anviltop/hbase/AbstractTest.java
Original file line number Diff line number Diff line change
@@ -1,34 +1,32 @@
/*
* Copyright (c) 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.cloud.anviltop.hbase;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.HBaseTestingUtility;
import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.client.AnvilTopConnection;
import org.apache.hadoop.hbase.client.HConnection;
import org.apache.hadoop.hbase.client.HConnectionManager;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;

import javax.validation.constraints.NotNull;
import java.io.IOException;

/*
* Copyright (c) 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
public abstract class AbstractTest {
protected static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
protected HConnection connection;
Expand Down Expand Up @@ -66,4 +64,45 @@ public HConnection createNewConnection() throws IOException {
HConnection newConnection = HConnectionManager.createConnection(conf);
return newConnection;
}

protected byte[] randomData(String prefix) {
return Bytes.toBytes(prefix + RandomStringUtils.randomAlphanumeric(8));
}

protected byte[][] randomData(String prefix, int count) {
byte[][] result = new byte[count][];
for (int i = 0; i < count; ++i) {
result[i] = Bytes.toBytes(prefix + RandomStringUtils.randomAlphanumeric(8));
}
return result;
}

protected long[] sequentialTimestamps(int count) {
return sequentialTimestamps(count, System.currentTimeMillis());
}

protected long[] sequentialTimestamps(int count, long firstValue) {
assert count > 0;
long[] timestamps = new long[count];
timestamps[0] = firstValue;
for (int i = 1; i < timestamps.length; ++i) {
timestamps[i] = timestamps[0] + i;
}
return timestamps;
}

protected static class QualifierValue implements Comparable<QualifierValue> {
protected final byte[] qualifier;
protected final byte[] value;

public QualifierValue(@NotNull byte[] qualifier, @NotNull byte[] value) {
this.qualifier = qualifier;
this.value = value;
}

@Override
public int compareTo(QualifierValue qualifierValue) {
return Bytes.compareTo(this.qualifier, qualifierValue.qualifier);
}
}
}
34 changes: 20 additions & 14 deletions src/test/java/com/google/cloud/anviltop/hbase/TestAutoFlush.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
/*
* Copyright (c) 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.cloud.anviltop.hbase;

import org.apache.commons.lang.RandomStringUtils;
Expand All @@ -11,18 +24,11 @@

import java.io.IOException;

/*
* Copyright (c) 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
/**
* Requirement 1.1 - Writes are buffered in the client by default (can be disabled). Buffer size
* can be defined programmatically or configuring the hbase.client.write.buffer property.
*
* 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.
* TODO - Test buffer size definitions
*/
public class TestAutoFlush extends AbstractTest {
@Test
Expand Down Expand Up @@ -59,9 +65,9 @@ public void testAutoFlushOn() throws Exception {

private Get quickPutThenGet(HTableInterface tableForWrite) throws IOException {
// Set up the tiny write and read
byte[] rowKey = Bytes.toBytes("testrow-" + RandomStringUtils.randomAlphanumeric(8));
byte[] qualifier = Bytes.toBytes("testQualifier-" + RandomStringUtils.randomAlphanumeric(8));
byte[] value = Bytes.toBytes("testValue-" + RandomStringUtils.randomAlphanumeric(8));
byte[] rowKey = randomData("testrow-");
byte[] qualifier = randomData("testQualifier-");
byte[] value = randomData("testValue-");
Put put = new Put(rowKey);
put.add(COLUMN_FAMILY, qualifier, value);
Get get = new Get(rowKey);
Expand Down
120 changes: 92 additions & 28 deletions src/test/java/com/google/cloud/anviltop/hbase/TestBasicOps.java
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
/*
* Copyright (c) 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.cloud.anviltop.hbase;

import org.apache.commons.lang.RandomStringUtils;
Expand All @@ -17,29 +30,22 @@
import java.util.List;
import java.util.Random;

/*
* Copyright (c) 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
* in compliance with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License
* is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
public class TestBasicOps extends AbstractTest {
/**
* Happy path for a single value.
*/
@Test
public void testPutGetDelete() throws IOException {
// Initialize
byte[] rowKey = Bytes.toBytes("testrow-" + RandomStringUtils.randomAlphanumeric(8));
byte[] testQualifier = Bytes.toBytes("testQualifier-" + RandomStringUtils.randomAlphanumeric(8));
byte[] testValue = Bytes.toBytes("testValue-" + RandomStringUtils.randomAlphanumeric(8));
byte[] rowKey = randomData("testrow-");
byte[] testQualifier = randomData("testQualifier-");
byte[] testValue = randomData("testValue-");
putGetDeleteExists(rowKey, testQualifier, testValue);
}

/**
* Requirement 1.2 - Rowkey, family, qualifer, and value are byte[]
*/
@Test
public void testBinaryPutGetDelete() throws IOException {
// Initialize
Expand All @@ -50,39 +56,97 @@ public void testBinaryPutGetDelete() throws IOException {
random.nextBytes(testQualifier);
byte[] testValue = new byte[100];
random.nextBytes(testValue);
// TODO(carterpage) - need to test that column-family can work as raw binary
// TODO(carterpage) - test that column-family can work as raw binary

// Put
putGetDeleteExists(rowKey, testQualifier, testValue);
}

/**
* Requirement 1.9 - Referring to a column without the qualifier implicity sets a special "empty"
* qualifier.
*/
@Test
public void testNullQualifier() throws IOException {
byte[] rowKey = Bytes.toBytes("testrow-" + RandomStringUtils.randomAlphanumeric(8));
byte[] testQualifier = null;
byte[] testValue = Bytes.toBytes("testValue-" + RandomStringUtils.randomAlphanumeric(8));
putGetDeleteExists(rowKey, testQualifier, testValue);
// Initialize values
HTableInterface table = connection.getTable(TABLE_NAME);
byte[] rowKey = randomData("testrow-");
byte[] testValue = randomData("testValue-");

// Insert value with null qualifier
Put put = new Put(rowKey);
put.add(COLUMN_FAMILY, null, testValue);
table.put(put);

// This is treated the same as an empty String (which is just an empty byte array).
Get get = new Get(rowKey);
get.addColumn(COLUMN_FAMILY, Bytes.toBytes(""));
Result result = table.get(get);
Assert.assertEquals(1, result.size());
Assert.assertTrue(result.containsColumn(COLUMN_FAMILY, null));
Assert.assertArrayEquals(testValue,
CellUtil.cloneValue(result.getColumnLatestCell(COLUMN_FAMILY, null)));

// Get as a null. This should work.
get = new Get(rowKey);
get.addColumn(COLUMN_FAMILY, null);
result = table.get(get);
Assert.assertEquals(1, result.size());
Assert.assertTrue(result.containsColumn(COLUMN_FAMILY, null));
Assert.assertArrayEquals(testValue,
CellUtil.cloneValue(result.getColumnLatestCell(COLUMN_FAMILY, null)));

// This should return when selecting the whole family too.
get = new Get(rowKey);
get.addFamily(COLUMN_FAMILY);
result = table.get(get);
Assert.assertEquals(1, result.size());
Assert.assertTrue(result.containsColumn(COLUMN_FAMILY, null));
Assert.assertArrayEquals(testValue,
CellUtil.cloneValue(result.getColumnLatestCell(COLUMN_FAMILY, null)));

// Delete
Delete delete = new Delete(rowKey);
delete.deleteColumn(COLUMN_FAMILY, null);
table.delete(delete);

// Confirm deleted
Assert.assertFalse(table.exists(get));
table.close();
}

/**
* Requirement 2.4 - Maximum cell size is 10MB by default. Can be overriden using
* hbase.client.keyvalue.maxsize property.
*
* Cell size includes value and key info, so the value needs to a bit less than the max to work.
*/
@Test
public void testPutBigValue() throws IOException {
// Initialize variables
HTableInterface table = connection.getTable(TABLE_NAME);
byte[] testRowKey = Bytes.toBytes("testrow-" + RandomStringUtils.randomAlphanumeric(8));
byte[] testQualifier = Bytes.toBytes("testQualifier-" + RandomStringUtils.randomAlphanumeric(8));
byte[] testValue = new byte[10 * 2 ^ 20]; // 10 MB
byte[] testRowKey = randomData("testrow-");
byte[] testQualifier = randomData("testQualifier-");
byte[] testValue = new byte[(10 << 20) - 1024]; // 10 MB - 1kB
new Random().nextBytes(testValue);
putGetDeleteExists(testRowKey, testQualifier, testValue);
}

@Test
/**
* Requirement 2.4 - Maximum cell size is 10MB by default. Can be overriden using
* hbase.client.keyvalue.maxsize property.
*
* Ensure the failure case.
*/
@Test(expected = IllegalArgumentException.class)
public void testPutTooBigValue() throws IOException {
// Initialize variables
HTableInterface table = connection.getTable(TABLE_NAME);
byte[] testRowKey = Bytes.toBytes("testrow-" + RandomStringUtils.randomAlphanumeric(8));
byte[] testQualifier = Bytes.toBytes("testQualifier-" + RandomStringUtils.randomAlphanumeric(8));
byte[] testValue = new byte[10 * 2 ^ 20 + 1]; // 10 MB
byte[] testRowKey = randomData("testrow-");
byte[] testQualifier = randomData("testQualifier-");
byte[] testValue = new byte[10 << 20]; // 10 MB
new Random().nextBytes(testValue);
System.out.println(testValue.length);
putGetDeleteExists(testRowKey, testQualifier, testValue);
}

Expand Down
21 changes: 12 additions & 9 deletions src/test/java/com/google/cloud/anviltop/hbase/TestCreateTable.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,3 @@
package com.google.cloud.anviltop.hbase;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.Assert;
import org.junit.Test;

import java.io.IOException;

/*
* Copyright (c) 2013 Google Inc.
*
Expand All @@ -20,7 +11,19 @@
* or implied. See the License for the specific language governing permissions and limitations under
* the License.
*/
package com.google.cloud.anviltop.hbase;

import org.apache.commons.lang.RandomStringUtils;
import org.apache.hadoop.hbase.util.Bytes;
import org.junit.Assert;
import org.junit.Test;

import java.io.IOException;

public class TestCreateTable extends AbstractTest {
/**
* Requirement 1.8 - Table names must match [\w_][\w_\-\.]*
*/
@Test
public void testTableNames() throws IOException {
String[] goodnames = {
Expand Down
Loading

0 comments on commit 06a024f

Please sign in to comment.