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.assertNotEquals; 021import static org.junit.Assert.assertTrue; 022 023import java.io.IOException; 024import java.util.List; 025import org.apache.hadoop.hbase.Cell; 026import org.apache.hadoop.hbase.CellBuilderFactory; 027import org.apache.hadoop.hbase.CellBuilderType; 028import org.apache.hadoop.hbase.CellUtil; 029import org.apache.hadoop.hbase.ExtendedCell; 030import org.apache.hadoop.hbase.HBaseClassTestRule; 031import org.apache.hadoop.hbase.PrivateCellUtil; 032import org.apache.hadoop.hbase.io.TimeRange; 033import org.apache.hadoop.hbase.testclassification.ClientTests; 034import org.apache.hadoop.hbase.testclassification.SmallTests; 035import org.apache.hadoop.hbase.util.Bytes; 036import org.junit.Assert; 037import org.junit.ClassRule; 038import org.junit.Test; 039import org.junit.experimental.categories.Category; 040 041@Category({ SmallTests.class, ClientTests.class }) 042public class TestMutation { 043 044 @ClassRule 045 public static final HBaseClassTestRule CLASS_RULE = 046 HBaseClassTestRule.forClass(TestMutation.class); 047 048 @Test 049 public void testAppendCopyConstructor() throws IOException { 050 Append origin = new Append(Bytes.toBytes("ROW-01")); 051 origin.setPriority(100); 052 byte[] family = Bytes.toBytes("CF-01"); 053 054 origin.add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(origin.getRow()) 055 .setFamily(family).setQualifier(Bytes.toBytes("q")).setType(Cell.Type.Put) 056 .setValue(Bytes.toBytes(100)).build()); 057 origin.addColumn(family, Bytes.toBytes("q0"), Bytes.toBytes("value")); 058 origin.setTimeRange(100, 1000); 059 Append clone = new Append(origin); 060 assertEquals(origin, clone); 061 origin.addColumn(family, Bytes.toBytes("q1"), Bytes.toBytes("value")); 062 063 // They should have different cell lists 064 assertNotEquals(origin.getCellList(family), clone.getCellList(family)); 065 } 066 067 @Test 068 public void testIncrementCopyConstructor() throws IOException { 069 Increment origin = new Increment(Bytes.toBytes("ROW-01")); 070 origin.setPriority(100); 071 byte[] family = Bytes.toBytes("CF-01"); 072 073 origin.add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(origin.getRow()) 074 .setFamily(family).setQualifier(Bytes.toBytes("q")).setType(Cell.Type.Put) 075 .setValue(Bytes.toBytes(100)).build()); 076 origin.addColumn(family, Bytes.toBytes("q0"), 4); 077 origin.setTimeRange(100, 1000); 078 Increment clone = new Increment(origin); 079 assertEquals(origin, clone); 080 origin.addColumn(family, Bytes.toBytes("q1"), 3); 081 082 // They should have different cell lists 083 assertNotEquals(origin.getCellList(family), clone.getCellList(family)); 084 } 085 086 @Test 087 public void testDeleteCopyConstructor() throws IOException { 088 Delete origin = new Delete(Bytes.toBytes("ROW-01")); 089 origin.setPriority(100); 090 byte[] family = Bytes.toBytes("CF-01"); 091 092 origin.add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(origin.getRow()) 093 .setFamily(family).setQualifier(Bytes.toBytes("q")).setType(Cell.Type.Delete).build()); 094 origin.addColumn(family, Bytes.toBytes("q0")); 095 origin.addColumns(family, Bytes.toBytes("q1")); 096 origin.addFamily(family); 097 origin.addColumns(family, Bytes.toBytes("q2"), 100); 098 origin.addFamilyVersion(family, 1000); 099 Delete clone = new Delete(origin); 100 assertEquals(origin, clone); 101 origin.addColumn(family, Bytes.toBytes("q3")); 102 103 // They should have different cell lists 104 assertNotEquals(origin.getCellList(family), clone.getCellList(family)); 105 } 106 107 @Test 108 public void testPutCopyConstructor() throws IOException { 109 Put origin = new Put(Bytes.toBytes("ROW-01")); 110 origin.setPriority(100); 111 byte[] family = Bytes.toBytes("CF-01"); 112 113 origin.add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(origin.getRow()) 114 .setFamily(family).setQualifier(Bytes.toBytes("q")).setType(Cell.Type.Put) 115 .setValue(Bytes.toBytes("value")).build()); 116 origin.addColumn(family, Bytes.toBytes("q0"), Bytes.toBytes("V-01")); 117 origin.addColumn(family, Bytes.toBytes("q1"), 100, Bytes.toBytes("V-01")); 118 Put clone = new Put(origin); 119 assertEquals(origin, clone); 120 origin.addColumn(family, Bytes.toBytes("q2"), Bytes.toBytes("V-02")); 121 122 // They should have different cell lists 123 assertNotEquals(origin.getCellList(family), clone.getCellList(family)); 124 } 125 126 private void assertEquals(Mutation origin, Mutation clone) { 127 Assert.assertEquals(origin.getFamilyCellMap().size(), clone.getFamilyCellMap().size()); 128 for (byte[] family : origin.getFamilyCellMap().keySet()) { 129 List<ExtendedCell> originCells = origin.getCellList(family); 130 List<ExtendedCell> cloneCells = clone.getCellList(family); 131 Assert.assertEquals(originCells.size(), cloneCells.size()); 132 for (int i = 0; i != cloneCells.size(); ++i) { 133 ExtendedCell originCell = originCells.get(i); 134 ExtendedCell cloneCell = cloneCells.get(i); 135 assertTrue(PrivateCellUtil.equals(originCell, cloneCell)); 136 assertTrue(CellUtil.matchingValue(originCell, cloneCell)); 137 } 138 } 139 Assert.assertEquals(origin.getAttributesMap().size(), clone.getAttributesMap().size()); 140 for (String name : origin.getAttributesMap().keySet()) { 141 byte[] originValue = origin.getAttributesMap().get(name); 142 byte[] cloneValue = clone.getAttributesMap().get(name); 143 assertTrue(Bytes.equals(originValue, cloneValue)); 144 } 145 Assert.assertEquals(origin.getTimestamp(), clone.getTimestamp()); 146 Assert.assertEquals(origin.getPriority(), clone.getPriority()); 147 if (origin instanceof Append) { 148 assertEquals(((Append) origin).getTimeRange(), ((Append) clone).getTimeRange()); 149 } 150 if (origin instanceof Increment) { 151 assertEquals(((Increment) origin).getTimeRange(), ((Increment) clone).getTimeRange()); 152 } 153 } 154 155 private static void assertEquals(TimeRange origin, TimeRange clone) { 156 Assert.assertEquals(origin.getMin(), clone.getMin()); 157 Assert.assertEquals(origin.getMax(), clone.getMax()); 158 } 159 160 // HBASE-14881 161 @Test 162 public void testRowIsImmutableOrNot() { 163 byte[] rowKey = Bytes.toBytes("immutable"); 164 165 // Test when row key is immutable 166 Put putRowIsImmutable = new Put(rowKey, true); 167 assertTrue(rowKey == putRowIsImmutable.getRow()); // No local copy is made 168 169 // Test when row key is not immutable 170 Put putRowIsNotImmutable = new Put(rowKey, 1000L, false); 171 assertTrue(rowKey != putRowIsNotImmutable.getRow()); // A local copy is made 172 } 173 174 // HBASE-14882 175 @Test 176 public void testAddImmutableToPut() throws IOException { 177 byte[] row = Bytes.toBytes("immutable-row"); 178 byte[] family = Bytes.toBytes("immutable-family"); 179 180 byte[] qualifier0 = Bytes.toBytes("immutable-qualifier-0"); 181 byte[] value0 = Bytes.toBytes("immutable-value-0"); 182 183 byte[] qualifier1 = Bytes.toBytes("immutable-qualifier-1"); 184 byte[] value1 = Bytes.toBytes("immutable-value-1"); 185 long ts1 = 5000L; 186 187 // "true" indicates that the input row is immutable 188 Put put = new Put(row, true); 189 put 190 .add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(row).setFamily(family) 191 .setQualifier(qualifier0).setTimestamp(put.getTimestamp()).setType(Cell.Type.Put) 192 .setValue(value0).build()) 193 .add(CellBuilderFactory.create(CellBuilderType.SHALLOW_COPY).setRow(row).setFamily(family) 194 .setQualifier(qualifier1).setTimestamp(ts1).setType(Cell.Type.Put).setValue(value1) 195 .build()); 196 197 // Verify the cell of family:qualifier0 198 Cell cell0 = put.get(family, qualifier0).get(0); 199 200 // Verify no local copy is made for family, qualifier or value 201 assertTrue(cell0.getFamilyArray() == family); 202 assertTrue(cell0.getQualifierArray() == qualifier0); 203 assertTrue(cell0.getValueArray() == value0); 204 205 // Verify timestamp 206 assertTrue(cell0.getTimestamp() == put.getTimestamp()); 207 208 // Verify the cell of family:qualifier1 209 Cell cell1 = put.get(family, qualifier1).get(0); 210 211 // Verify no local copy is made for family, qualifier or value 212 assertTrue(cell1.getFamilyArray() == family); 213 assertTrue(cell1.getQualifierArray() == qualifier1); 214 assertTrue(cell1.getValueArray() == value1); 215 216 // Verify timestamp 217 assertTrue(cell1.getTimestamp() == ts1); 218 } 219}