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.junit.ClassRule; 035import org.junit.Test; 036import org.junit.experimental.categories.Category; 037 038/** 039 * Test that I can Iterate Client Actions that hold Cells (Get does not have Cells). 040 */ 041@Category({SmallTests.class, ClientTests.class}) 042public class TestPutDeleteEtcCellIteration { 043 044 @ClassRule 045 public static final HBaseClassTestRule CLASS_RULE = 046 HBaseClassTestRule.forClass(TestPutDeleteEtcCellIteration.class); 047 048 private static final byte [] ROW = new byte [] {'r'}; 049 private static final long TIMESTAMP = System.currentTimeMillis(); 050 private static final int COUNT = 10; 051 052 @Test 053 public void testPutIteration() throws IOException { 054 Put p = new Put(ROW); 055 for (int i = 0; i < COUNT; i++) { 056 byte [] bytes = Bytes.toBytes(i); 057 p.addColumn(bytes, bytes, TIMESTAMP, bytes); 058 } 059 int index = 0; 060 for (CellScanner cellScanner = p.cellScanner(); cellScanner.advance();) { 061 Cell cell = cellScanner.current(); 062 byte [] bytes = Bytes.toBytes(index++); 063 cell.equals(new KeyValue(ROW, bytes, bytes, TIMESTAMP, bytes)); 064 } 065 assertEquals(COUNT, index); 066 } 067 068 @Test (expected = ConcurrentModificationException.class) 069 public void testPutConcurrentModificationOnIteration() throws IOException { 070 Put p = new Put(ROW); 071 for (int i = 0; i < COUNT; i++) { 072 byte [] bytes = Bytes.toBytes(i); 073 p.addColumn(bytes, bytes, TIMESTAMP, bytes); 074 } 075 int index = 0; 076 int trigger = 3; 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 if (trigger == 3) p.addColumn(bytes, bytes, TIMESTAMP, bytes); 082 cell.equals(new KeyValue(ROW, bytes, bytes, TIMESTAMP, bytes)); 083 } 084 assertEquals(COUNT, index); 085 } 086 087 @Test 088 public void testDeleteIteration() throws IOException { 089 Delete d = new Delete(ROW); 090 for (int i = 0; i < COUNT; i++) { 091 byte [] bytes = Bytes.toBytes(i); 092 d.addColumn(bytes, bytes, TIMESTAMP); 093 } 094 int index = 0; 095 for (CellScanner cellScanner = d.cellScanner(); cellScanner.advance();) { 096 Cell cell = cellScanner.current(); 097 byte [] bytes = Bytes.toBytes(index++); 098 cell.equals(new KeyValue(ROW, bytes, bytes, TIMESTAMP, KeyValue.Type.DeleteColumn)); 099 } 100 assertEquals(COUNT, index); 101 } 102 103 @Test 104 public void testAppendIteration() throws IOException { 105 Append a = new Append(ROW); 106 for (int i = 0; i < COUNT; i++) { 107 byte [] bytes = Bytes.toBytes(i); 108 a.addColumn(bytes, bytes, bytes); 109 } 110 int index = 0; 111 for (CellScanner cellScanner = a.cellScanner(); cellScanner.advance();) { 112 Cell cell = cellScanner.current(); 113 byte [] bytes = Bytes.toBytes(index++); 114 KeyValue kv = (KeyValue)cell; 115 assertTrue(Bytes.equals(CellUtil.cloneFamily(kv), bytes)); 116 assertTrue(Bytes.equals(CellUtil.cloneValue(kv), bytes)); 117 } 118 assertEquals(COUNT, index); 119 } 120 121 @Test 122 public void testIncrementIteration() throws IOException { 123 Increment increment = new Increment(ROW); 124 for (int i = 0; i < COUNT; i++) { 125 byte [] bytes = Bytes.toBytes(i); 126 increment.addColumn(bytes, bytes, i); 127 } 128 int index = 0; 129 for (CellScanner cellScanner = increment.cellScanner(); cellScanner.advance();) { 130 Cell cell = cellScanner.current(); 131 int value = index; 132 byte [] bytes = Bytes.toBytes(index++); 133 KeyValue kv = (KeyValue)cell; 134 assertTrue(Bytes.equals(CellUtil.cloneFamily(kv), bytes)); 135 long a = Bytes.toLong(CellUtil.cloneValue(kv)); 136 assertEquals(value, a); 137 } 138 assertEquals(COUNT, index); 139 } 140 141 @Test 142 public void testResultIteration() throws IOException { 143 Cell [] cells = new Cell[COUNT]; 144 for(int i = 0; i < COUNT; i++) { 145 byte [] bytes = Bytes.toBytes(i); 146 cells[i] = new KeyValue(ROW, bytes, bytes, TIMESTAMP, bytes); 147 } 148 Result r = Result.create(Arrays.asList(cells)); 149 int index = 0; 150 for (CellScanner cellScanner = r.cellScanner(); cellScanner.advance();) { 151 Cell cell = cellScanner.current(); 152 byte [] bytes = Bytes.toBytes(index++); 153 cell.equals(new KeyValue(ROW, bytes, bytes, TIMESTAMP, bytes)); 154 } 155 assertEquals(COUNT, index); 156 } 157}