001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.client; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertTrue; 022 023import java.io.IOException; 024import java.util.Arrays; 025import java.util.ConcurrentModificationException; 026import org.apache.hadoop.hbase.Cell; 027import org.apache.hadoop.hbase.CellScanner; 028import org.apache.hadoop.hbase.CellUtil; 029import org.apache.hadoop.hbase.HBaseClassTestRule; 030import org.apache.hadoop.hbase.KeyValue; 031import org.apache.hadoop.hbase.testclassification.ClientTests; 032import org.apache.hadoop.hbase.testclassification.SmallTests; 033import org.apache.hadoop.hbase.util.Bytes; 034import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 035import org.junit.ClassRule; 036import org.junit.Test; 037import org.junit.experimental.categories.Category; 038 039/** 040 * Test that I can Iterate Client Actions that hold Cells (Get does not have Cells). 041 */ 042@Category({ SmallTests.class, ClientTests.class }) 043public class TestPutDeleteEtcCellIteration { 044 045 @ClassRule 046 public static final HBaseClassTestRule CLASS_RULE = 047 HBaseClassTestRule.forClass(TestPutDeleteEtcCellIteration.class); 048 049 private static final byte[] ROW = new byte[] { 'r' }; 050 private static final long TIMESTAMP = EnvironmentEdgeManager.currentTime(); 051 private static final int COUNT = 10; 052 053 @Test 054 public void testPutIteration() throws IOException { 055 Put p = new Put(ROW); 056 for (int i = 0; i < COUNT; i++) { 057 byte[] bytes = Bytes.toBytes(i); 058 p.addColumn(bytes, bytes, TIMESTAMP, bytes); 059 } 060 int index = 0; 061 for (CellScanner cellScanner = p.cellScanner(); cellScanner.advance();) { 062 Cell cell = cellScanner.current(); 063 byte[] bytes = Bytes.toBytes(index++); 064 assertEquals(new KeyValue(ROW, bytes, bytes, TIMESTAMP, bytes), cell); 065 } 066 assertEquals(COUNT, index); 067 } 068 069 @Test(expected = ConcurrentModificationException.class) 070 public void testPutConcurrentModificationOnIteration() throws IOException { 071 Put p = new Put(ROW); 072 for (int i = 0; i < COUNT; i++) { 073 byte[] bytes = Bytes.toBytes(i); 074 p.addColumn(bytes, bytes, TIMESTAMP, bytes); 075 } 076 int index = 0; 077 for (CellScanner cellScanner = p.cellScanner(); cellScanner.advance();) { 078 Cell cell = cellScanner.current(); 079 byte[] bytes = Bytes.toBytes(index++); 080 // When we hit the trigger, try inserting a new KV; should trigger exception 081 p.addColumn(bytes, bytes, TIMESTAMP, bytes); 082 assertEquals(new KeyValue(ROW, bytes, bytes, TIMESTAMP, bytes), cell); 083 } 084 } 085 086 @Test 087 public void testDeleteIteration() throws IOException { 088 Delete d = new Delete(ROW); 089 for (int i = 0; i < COUNT; i++) { 090 byte[] bytes = Bytes.toBytes(i); 091 d.addColumn(bytes, bytes, TIMESTAMP); 092 } 093 int index = 0; 094 for (CellScanner cellScanner = d.cellScanner(); cellScanner.advance();) { 095 Cell cell = cellScanner.current(); 096 byte[] bytes = Bytes.toBytes(index++); 097 assertEquals(new KeyValue(ROW, bytes, bytes, TIMESTAMP, KeyValue.Type.Delete), cell); 098 } 099 assertEquals(COUNT, index); 100 } 101 102 @Test 103 public void testAppendIteration() throws IOException { 104 Append a = new Append(ROW); 105 for (int i = 0; i < COUNT; i++) { 106 byte[] bytes = Bytes.toBytes(i); 107 a.addColumn(bytes, bytes, bytes); 108 } 109 int index = 0; 110 for (CellScanner cellScanner = a.cellScanner(); cellScanner.advance();) { 111 Cell cell = cellScanner.current(); 112 byte[] bytes = Bytes.toBytes(index++); 113 KeyValue kv = (KeyValue) cell; 114 assertTrue(Bytes.equals(CellUtil.cloneFamily(kv), bytes)); 115 assertTrue(Bytes.equals(CellUtil.cloneValue(kv), bytes)); 116 } 117 assertEquals(COUNT, index); 118 } 119 120 @Test 121 public void testIncrementIteration() throws IOException { 122 Increment increment = new Increment(ROW); 123 for (int i = 0; i < COUNT; i++) { 124 byte[] bytes = Bytes.toBytes(i); 125 increment.addColumn(bytes, bytes, i); 126 } 127 int index = 0; 128 for (CellScanner cellScanner = increment.cellScanner(); cellScanner.advance();) { 129 Cell cell = cellScanner.current(); 130 int value = index; 131 byte[] bytes = Bytes.toBytes(index++); 132 KeyValue kv = (KeyValue) cell; 133 assertTrue(Bytes.equals(CellUtil.cloneFamily(kv), bytes)); 134 long a = Bytes.toLong(CellUtil.cloneValue(kv)); 135 assertEquals(value, a); 136 } 137 assertEquals(COUNT, index); 138 } 139 140 @Test 141 public void testResultIteration() throws IOException { 142 Cell[] cells = new Cell[COUNT]; 143 for (int i = 0; i < COUNT; i++) { 144 byte[] bytes = Bytes.toBytes(i); 145 cells[i] = new KeyValue(ROW, bytes, bytes, TIMESTAMP, bytes); 146 } 147 Result r = Result.create(Arrays.asList(cells)); 148 int index = 0; 149 for (CellScanner cellScanner = r.cellScanner(); cellScanner.advance();) { 150 Cell cell = cellScanner.current(); 151 byte[] bytes = Bytes.toBytes(index++); 152 assertEquals(new KeyValue(ROW, bytes, bytes, TIMESTAMP, bytes), cell); 153 } 154 assertEquals(COUNT, index); 155 } 156}