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.assertNotNull; 022 023import java.io.IOException; 024import java.lang.reflect.Type; 025import java.nio.ByteBuffer; 026import java.util.Arrays; 027import java.util.List; 028import java.util.Map; 029import org.apache.hadoop.hbase.Cell; 030import org.apache.hadoop.hbase.CellComparatorImpl; 031import org.apache.hadoop.hbase.CellUtil; 032import org.apache.hadoop.hbase.HBaseClassTestRule; 033import org.apache.hadoop.hbase.HConstants; 034import org.apache.hadoop.hbase.KeyValue; 035import org.apache.hadoop.hbase.filter.BinaryComparator; 036import org.apache.hadoop.hbase.filter.ColumnCountGetFilter; 037import org.apache.hadoop.hbase.filter.ColumnPaginationFilter; 038import org.apache.hadoop.hbase.filter.ColumnPrefixFilter; 039import org.apache.hadoop.hbase.filter.ColumnRangeFilter; 040import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp; 041import org.apache.hadoop.hbase.filter.DependentColumnFilter; 042import org.apache.hadoop.hbase.filter.FamilyFilter; 043import org.apache.hadoop.hbase.filter.Filter; 044import org.apache.hadoop.hbase.filter.FilterList; 045import org.apache.hadoop.hbase.filter.FilterList.Operator; 046import org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter; 047import org.apache.hadoop.hbase.filter.InclusiveStopFilter; 048import org.apache.hadoop.hbase.filter.KeyOnlyFilter; 049import org.apache.hadoop.hbase.filter.MultipleColumnPrefixFilter; 050import org.apache.hadoop.hbase.filter.PageFilter; 051import org.apache.hadoop.hbase.filter.PrefixFilter; 052import org.apache.hadoop.hbase.filter.QualifierFilter; 053import org.apache.hadoop.hbase.filter.RowFilter; 054import org.apache.hadoop.hbase.filter.SingleColumnValueExcludeFilter; 055import org.apache.hadoop.hbase.filter.SingleColumnValueFilter; 056import org.apache.hadoop.hbase.filter.SkipFilter; 057import org.apache.hadoop.hbase.filter.TimestampsFilter; 058import org.apache.hadoop.hbase.filter.ValueFilter; 059import org.apache.hadoop.hbase.filter.WhileMatchFilter; 060import org.apache.hadoop.hbase.testclassification.ClientTests; 061import org.apache.hadoop.hbase.testclassification.SmallTests; 062import org.apache.hadoop.hbase.util.BuilderStyleTest; 063import org.apache.hadoop.hbase.util.Bytes; 064import org.apache.hadoop.hbase.util.GsonUtil; 065import org.junit.Assert; 066import org.junit.ClassRule; 067import org.junit.Test; 068import org.junit.experimental.categories.Category; 069 070import org.apache.hbase.thirdparty.com.google.common.reflect.TypeToken; 071import org.apache.hbase.thirdparty.com.google.gson.Gson; 072 073/** 074 * Run tests that use the functionality of the Operation superclass for 075 * Puts, Gets, Deletes, Scans, and MultiPuts. 076 */ 077@Category({ClientTests.class, SmallTests.class}) 078public class TestOperation { 079 @ClassRule 080 public static final HBaseClassTestRule CLASS_RULE = 081 HBaseClassTestRule.forClass(TestOperation.class); 082 083 private static byte [] ROW = Bytes.toBytes("testRow"); 084 private static byte [] FAMILY = Bytes.toBytes("testFamily"); 085 private static byte [] QUALIFIER = Bytes.toBytes("testQualifier"); 086 private static byte [] VALUE = Bytes.toBytes("testValue"); 087 088 private static Gson GSON = GsonUtil.createGson().create(); 089 090 private static List<Long> TS_LIST = Arrays.asList(2L, 3L, 5L); 091 private static TimestampsFilter TS_FILTER = new TimestampsFilter(TS_LIST); 092 private static String STR_TS_FILTER = TS_FILTER.getClass().getSimpleName() + " (3/3): [2, 3, 5]"; 093 094 private static List<Long> L_TS_LIST = Arrays.asList(0L, 1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L); 095 private static TimestampsFilter L_TS_FILTER = new TimestampsFilter(L_TS_LIST); 096 private static String STR_L_TS_FILTER = 097 L_TS_FILTER.getClass().getSimpleName() + " (5/11): [0, 1, 2, 3, 4]"; 098 099 private static String COL_NAME_1 = "col1"; 100 private static ColumnPrefixFilter COL_PRE_FILTER = 101 new ColumnPrefixFilter(Bytes.toBytes(COL_NAME_1)); 102 private static String STR_COL_PRE_FILTER = 103 COL_PRE_FILTER.getClass().getSimpleName() + " " + COL_NAME_1; 104 105 private static String COL_NAME_2 = "col2"; 106 private static ColumnRangeFilter CR_FILTER = 107 new ColumnRangeFilter(Bytes.toBytes(COL_NAME_1), true, Bytes.toBytes(COL_NAME_2), false); 108 private static String STR_CR_FILTER = CR_FILTER.getClass().getSimpleName() 109 + " [" + COL_NAME_1 + ", " + COL_NAME_2 + ")"; 110 111 private static int COL_COUNT = 9; 112 private static ColumnCountGetFilter CCG_FILTER = new ColumnCountGetFilter(COL_COUNT); 113 private static String STR_CCG_FILTER = CCG_FILTER.getClass().getSimpleName() + " " + COL_COUNT; 114 115 private static int LIMIT = 3; 116 private static int OFFSET = 4; 117 private static ColumnPaginationFilter CP_FILTER = new ColumnPaginationFilter(LIMIT, OFFSET); 118 private static String STR_CP_FILTER = CP_FILTER.getClass().getSimpleName() 119 + " (" + LIMIT + ", " + OFFSET + ")"; 120 121 private static String STOP_ROW_KEY = "stop"; 122 private static InclusiveStopFilter IS_FILTER = 123 new InclusiveStopFilter(Bytes.toBytes(STOP_ROW_KEY)); 124 private static String STR_IS_FILTER = 125 IS_FILTER.getClass().getSimpleName() + " " + STOP_ROW_KEY; 126 127 private static String PREFIX = "prefix"; 128 private static PrefixFilter PREFIX_FILTER = new PrefixFilter(Bytes.toBytes(PREFIX)); 129 private static String STR_PREFIX_FILTER = "PrefixFilter " + PREFIX; 130 131 private static byte[][] PREFIXES = { Bytes.toBytes("0"), Bytes.toBytes("1"), Bytes.toBytes("2") }; 132 private static MultipleColumnPrefixFilter MCP_FILTER = new MultipleColumnPrefixFilter(PREFIXES); 133 private static String STR_MCP_FILTER = 134 MCP_FILTER.getClass().getSimpleName() + " (3/3): [0, 1, 2]"; 135 136 private static byte[][] L_PREFIXES = { 137 Bytes.toBytes("0"), Bytes.toBytes("1"), Bytes.toBytes("2"), Bytes.toBytes("3"), 138 Bytes.toBytes("4"), Bytes.toBytes("5"), Bytes.toBytes("6"), Bytes.toBytes("7") }; 139 private static MultipleColumnPrefixFilter L_MCP_FILTER = 140 new MultipleColumnPrefixFilter(L_PREFIXES); 141 private static String STR_L_MCP_FILTER = 142 L_MCP_FILTER.getClass().getSimpleName() + " (5/8): [0, 1, 2, 3, 4]"; 143 144 private static int PAGE_SIZE = 9; 145 private static PageFilter PAGE_FILTER = new PageFilter(PAGE_SIZE); 146 private static String STR_PAGE_FILTER = PAGE_FILTER.getClass().getSimpleName() + " " + PAGE_SIZE; 147 148 private static SkipFilter SKIP_FILTER = new SkipFilter(L_TS_FILTER); 149 private static String STR_SKIP_FILTER = 150 SKIP_FILTER.getClass().getSimpleName() + " " + STR_L_TS_FILTER; 151 152 private static WhileMatchFilter WHILE_FILTER = new WhileMatchFilter(L_TS_FILTER); 153 private static String STR_WHILE_FILTER = 154 WHILE_FILTER.getClass().getSimpleName() + " " + STR_L_TS_FILTER; 155 156 private static KeyOnlyFilter KEY_ONLY_FILTER = new KeyOnlyFilter(); 157 private static String STR_KEY_ONLY_FILTER = KEY_ONLY_FILTER.getClass().getSimpleName(); 158 159 private static FirstKeyOnlyFilter FIRST_KEY_ONLY_FILTER = new FirstKeyOnlyFilter(); 160 private static String STR_FIRST_KEY_ONLY_FILTER = 161 FIRST_KEY_ONLY_FILTER.getClass().getSimpleName(); 162 163 private static CompareOp CMP_OP = CompareOp.EQUAL; 164 private static byte[] CMP_VALUE = Bytes.toBytes("value"); 165 private static BinaryComparator BC = new BinaryComparator(CMP_VALUE); 166 private static DependentColumnFilter DC_FILTER = 167 new DependentColumnFilter(FAMILY, QUALIFIER, true, CMP_OP, BC); 168 private static String STR_DC_FILTER = String.format( 169 "%s (%s, %s, %s, %s, %s)", DC_FILTER.getClass().getSimpleName(), 170 Bytes.toStringBinary(FAMILY), Bytes.toStringBinary(QUALIFIER), true, 171 CMP_OP.name(), Bytes.toStringBinary(BC.getValue())); 172 173 private static FamilyFilter FAMILY_FILTER = new FamilyFilter(CMP_OP, BC); 174 private static String STR_FAMILY_FILTER = 175 FAMILY_FILTER.getClass().getSimpleName() + " (EQUAL, value)"; 176 177 private static QualifierFilter QUALIFIER_FILTER = new QualifierFilter(CMP_OP, BC); 178 private static String STR_QUALIFIER_FILTER = 179 QUALIFIER_FILTER.getClass().getSimpleName() + " (EQUAL, value)"; 180 181 private static RowFilter ROW_FILTER = new RowFilter(CMP_OP, BC); 182 private static String STR_ROW_FILTER = ROW_FILTER.getClass().getSimpleName() + " (EQUAL, value)"; 183 184 private static ValueFilter VALUE_FILTER = new ValueFilter(CMP_OP, BC); 185 private static String STR_VALUE_FILTER = 186 VALUE_FILTER.getClass().getSimpleName() + " (EQUAL, value)"; 187 188 private static SingleColumnValueFilter SCV_FILTER = 189 new SingleColumnValueFilter(FAMILY, QUALIFIER, CMP_OP, CMP_VALUE); 190 private static String STR_SCV_FILTER = String.format("%s (%s, %s, %s, %s)", 191 SCV_FILTER.getClass().getSimpleName(), Bytes.toStringBinary(FAMILY), 192 Bytes.toStringBinary(QUALIFIER), CMP_OP.name(), 193 Bytes.toStringBinary(CMP_VALUE)); 194 195 private static SingleColumnValueExcludeFilter SCVE_FILTER = 196 new SingleColumnValueExcludeFilter(FAMILY, QUALIFIER, CMP_OP, CMP_VALUE); 197 private static String STR_SCVE_FILTER = String.format("%s (%s, %s, %s, %s)", 198 SCVE_FILTER.getClass().getSimpleName(), Bytes.toStringBinary(FAMILY), 199 Bytes.toStringBinary(QUALIFIER), CMP_OP.name(), Bytes.toStringBinary(CMP_VALUE)); 200 201 private static FilterList AND_FILTER_LIST = new FilterList( 202 Operator.MUST_PASS_ALL, Arrays.asList((Filter) TS_FILTER, L_TS_FILTER, CR_FILTER)); 203 private static String STR_AND_FILTER_LIST = String.format( 204 "%s AND (3/3): [%s, %s, %s]", AND_FILTER_LIST.getClass().getSimpleName(), 205 STR_TS_FILTER, STR_L_TS_FILTER, STR_CR_FILTER); 206 207 private static FilterList OR_FILTER_LIST = new FilterList( 208 Operator.MUST_PASS_ONE, Arrays.asList((Filter) TS_FILTER, L_TS_FILTER, CR_FILTER)); 209 private static String STR_OR_FILTER_LIST = String.format( 210 "%s OR (3/3): [%s, %s, %s]", AND_FILTER_LIST.getClass().getSimpleName(), 211 STR_TS_FILTER, STR_L_TS_FILTER, STR_CR_FILTER); 212 213 private static FilterList L_FILTER_LIST = new FilterList( 214 Arrays.asList((Filter) TS_FILTER, L_TS_FILTER, CR_FILTER, COL_PRE_FILTER, 215 CCG_FILTER, CP_FILTER, PREFIX_FILTER, PAGE_FILTER)); 216 private static String STR_L_FILTER_LIST = String.format( 217 "%s AND (5/8): [%s, %s, %s, %s, %s, %s]", 218 L_FILTER_LIST.getClass().getSimpleName(), STR_TS_FILTER, STR_L_TS_FILTER, 219 STR_CR_FILTER, STR_COL_PRE_FILTER, STR_CCG_FILTER, STR_CP_FILTER); 220 221 private static Filter[] FILTERS = { 222 TS_FILTER, // TimestampsFilter 223 L_TS_FILTER, // TimestampsFilter 224 COL_PRE_FILTER, // ColumnPrefixFilter 225 CP_FILTER, // ColumnPaginationFilter 226 CR_FILTER, // ColumnRangeFilter 227 CCG_FILTER, // ColumnCountGetFilter 228 IS_FILTER, // InclusiveStopFilter 229 PREFIX_FILTER, // PrefixFilter 230 PAGE_FILTER, // PageFilter 231 SKIP_FILTER, // SkipFilter 232 WHILE_FILTER, // WhileMatchFilter 233 KEY_ONLY_FILTER, // KeyOnlyFilter 234 FIRST_KEY_ONLY_FILTER, // FirstKeyOnlyFilter 235 MCP_FILTER, // MultipleColumnPrefixFilter 236 L_MCP_FILTER, // MultipleColumnPrefixFilter 237 DC_FILTER, // DependentColumnFilter 238 FAMILY_FILTER, // FamilyFilter 239 QUALIFIER_FILTER, // QualifierFilter 240 ROW_FILTER, // RowFilter 241 VALUE_FILTER, // ValueFilter 242 SCV_FILTER, // SingleColumnValueFilter 243 SCVE_FILTER, // SingleColumnValueExcludeFilter 244 AND_FILTER_LIST, // FilterList 245 OR_FILTER_LIST, // FilterList 246 L_FILTER_LIST, // FilterList 247 }; 248 249 private static String[] FILTERS_INFO = { 250 STR_TS_FILTER, // TimestampsFilter 251 STR_L_TS_FILTER, // TimestampsFilter 252 STR_COL_PRE_FILTER, // ColumnPrefixFilter 253 STR_CP_FILTER, // ColumnPaginationFilter 254 STR_CR_FILTER, // ColumnRangeFilter 255 STR_CCG_FILTER, // ColumnCountGetFilter 256 STR_IS_FILTER, // InclusiveStopFilter 257 STR_PREFIX_FILTER, // PrefixFilter 258 STR_PAGE_FILTER, // PageFilter 259 STR_SKIP_FILTER, // SkipFilter 260 STR_WHILE_FILTER, // WhileMatchFilter 261 STR_KEY_ONLY_FILTER, // KeyOnlyFilter 262 STR_FIRST_KEY_ONLY_FILTER, // FirstKeyOnlyFilter 263 STR_MCP_FILTER, // MultipleColumnPrefixFilter 264 STR_L_MCP_FILTER, // MultipleColumnPrefixFilter 265 STR_DC_FILTER, // DependentColumnFilter 266 STR_FAMILY_FILTER, // FamilyFilter 267 STR_QUALIFIER_FILTER, // QualifierFilter 268 STR_ROW_FILTER, // RowFilter 269 STR_VALUE_FILTER, // ValueFilter 270 STR_SCV_FILTER, // SingleColumnValueFilter 271 STR_SCVE_FILTER, // SingleColumnValueExcludeFilter 272 STR_AND_FILTER_LIST, // FilterList 273 STR_OR_FILTER_LIST, // FilterList 274 STR_L_FILTER_LIST, // FilterList 275 }; 276 277 static { 278 assertEquals("The sizes of static arrays do not match: " 279 + "[FILTERS: %d <=> FILTERS_INFO: %d]", 280 FILTERS.length, FILTERS_INFO.length); 281 } 282 283 /** 284 * Test the client Operations' JSON encoding to ensure that produced JSON is 285 * parseable and that the details are present and not corrupted. 286 * 287 * @throws IOException if the JSON conversion fails 288 */ 289 @Test 290 public void testOperationJSON() throws IOException { 291 // produce a Scan Operation 292 Scan scan = new Scan(ROW); 293 scan.addColumn(FAMILY, QUALIFIER); 294 // get its JSON representation, and parse it 295 String json = scan.toJSON(); 296 Type typeOfHashMap = new TypeToken<Map<String, Object>>() { 297 }.getType(); 298 Map<String, Object> parsedJSON = GSON.fromJson(json, typeOfHashMap); 299 // check for the row 300 assertEquals("startRow incorrect in Scan.toJSON()", 301 Bytes.toStringBinary(ROW), parsedJSON.get("startRow")); 302 // check for the family and the qualifier. 303 List familyInfo = (List) ((Map) parsedJSON.get("families")).get( 304 Bytes.toStringBinary(FAMILY)); 305 assertNotNull("Family absent in Scan.toJSON()", familyInfo); 306 assertEquals("Qualifier absent in Scan.toJSON()", 1, familyInfo.size()); 307 assertEquals("Qualifier incorrect in Scan.toJSON()", 308 Bytes.toStringBinary(QUALIFIER), 309 familyInfo.get(0)); 310 311 // produce a Get Operation 312 Get get = new Get(ROW); 313 get.addColumn(FAMILY, QUALIFIER); 314 // get its JSON representation, and parse it 315 json = get.toJSON(); 316 parsedJSON = GSON.fromJson(json, typeOfHashMap); 317 // check for the row 318 assertEquals("row incorrect in Get.toJSON()", 319 Bytes.toStringBinary(ROW), parsedJSON.get("row")); 320 // check for the family and the qualifier. 321 familyInfo = (List) ((Map) parsedJSON.get("families")).get( 322 Bytes.toStringBinary(FAMILY)); 323 assertNotNull("Family absent in Get.toJSON()", familyInfo); 324 assertEquals("Qualifier absent in Get.toJSON()", 1, familyInfo.size()); 325 assertEquals("Qualifier incorrect in Get.toJSON()", 326 Bytes.toStringBinary(QUALIFIER), 327 familyInfo.get(0)); 328 329 // produce a Put operation 330 Put put = new Put(ROW); 331 put.addColumn(FAMILY, QUALIFIER, VALUE); 332 // get its JSON representation, and parse it 333 json = put.toJSON(); 334 parsedJSON = GSON.fromJson(json, typeOfHashMap); 335 // check for the row 336 assertEquals("row absent in Put.toJSON()", 337 Bytes.toStringBinary(ROW), parsedJSON.get("row")); 338 // check for the family and the qualifier. 339 familyInfo = (List) ((Map) parsedJSON.get("families")).get( 340 Bytes.toStringBinary(FAMILY)); 341 assertNotNull("Family absent in Put.toJSON()", familyInfo); 342 assertEquals("KeyValue absent in Put.toJSON()", 1, familyInfo.size()); 343 Map kvMap = (Map) familyInfo.get(0); 344 assertEquals("Qualifier incorrect in Put.toJSON()", 345 Bytes.toStringBinary(QUALIFIER), 346 kvMap.get("qualifier")); 347 assertEquals("Value length incorrect in Put.toJSON()", VALUE.length, 348 ((Number) kvMap.get("vlen")).intValue()); 349 350 // produce a Delete operation 351 Delete delete = new Delete(ROW); 352 delete.addColumn(FAMILY, QUALIFIER); 353 // get its JSON representation, and parse it 354 json = delete.toJSON(); 355 parsedJSON = GSON.fromJson(json, typeOfHashMap); 356 // check for the row 357 assertEquals("row absent in Delete.toJSON()", 358 Bytes.toStringBinary(ROW), parsedJSON.get("row")); 359 // check for the family and the qualifier. 360 familyInfo = (List) ((Map) parsedJSON.get("families")).get( 361 Bytes.toStringBinary(FAMILY)); 362 assertNotNull("Family absent in Delete.toJSON()", familyInfo); 363 assertEquals("KeyValue absent in Delete.toJSON()", 1, familyInfo.size()); 364 kvMap = (Map) familyInfo.get(0); 365 assertEquals("Qualifier incorrect in Delete.toJSON()", 366 Bytes.toStringBinary(QUALIFIER), kvMap.get("qualifier")); 367 } 368 369 @Test 370 public void testPutCreationWithByteBuffer() { 371 Put p = new Put(ROW); 372 List<Cell> c = p.get(FAMILY, QUALIFIER); 373 Assert.assertEquals(0, c.size()); 374 Assert.assertEquals(HConstants.LATEST_TIMESTAMP, p.getTimestamp()); 375 376 p.addColumn(FAMILY, ByteBuffer.wrap(QUALIFIER), 1984L, ByteBuffer.wrap(VALUE)); 377 c = p.get(FAMILY, QUALIFIER); 378 Assert.assertEquals(1, c.size()); 379 Assert.assertEquals(1984L, c.get(0).getTimestamp()); 380 Assert.assertArrayEquals(VALUE, CellUtil.cloneValue(c.get(0))); 381 Assert.assertEquals(HConstants.LATEST_TIMESTAMP, p.getTimestamp()); 382 Assert.assertEquals(0, CellComparatorImpl.COMPARATOR.compare(c.get(0), new KeyValue(c.get(0)))); 383 384 p = new Put(ROW); 385 p.addColumn(FAMILY, ByteBuffer.wrap(QUALIFIER), 2013L, null); 386 c = p.get(FAMILY, QUALIFIER); 387 Assert.assertEquals(1, c.size()); 388 Assert.assertEquals(2013L, c.get(0).getTimestamp()); 389 Assert.assertArrayEquals(new byte[]{}, CellUtil.cloneValue(c.get(0))); 390 Assert.assertEquals(HConstants.LATEST_TIMESTAMP, p.getTimestamp()); 391 Assert.assertEquals(0, CellComparatorImpl.COMPARATOR.compare(c.get(0), new KeyValue(c.get(0)))); 392 393 p = new Put(ByteBuffer.wrap(ROW)); 394 p.addColumn(FAMILY, ByteBuffer.wrap(QUALIFIER), 2001L, null); 395 c = p.get(FAMILY, QUALIFIER); 396 Assert.assertEquals(1, c.size()); 397 Assert.assertEquals(2001L, c.get(0).getTimestamp()); 398 Assert.assertArrayEquals(new byte[]{}, CellUtil.cloneValue(c.get(0))); 399 Assert.assertArrayEquals(ROW, CellUtil.cloneRow(c.get(0))); 400 Assert.assertEquals(HConstants.LATEST_TIMESTAMP, p.getTimestamp()); 401 Assert.assertEquals(0, CellComparatorImpl.COMPARATOR.compare(c.get(0), new KeyValue(c.get(0)))); 402 403 p = new Put(ByteBuffer.wrap(ROW), 1970L); 404 p.addColumn(FAMILY, ByteBuffer.wrap(QUALIFIER), 2001L, null); 405 c = p.get(FAMILY, QUALIFIER); 406 Assert.assertEquals(1, c.size()); 407 Assert.assertEquals(2001L, c.get(0).getTimestamp()); 408 Assert.assertArrayEquals(new byte[]{}, CellUtil.cloneValue(c.get(0))); 409 Assert.assertArrayEquals(ROW, CellUtil.cloneRow(c.get(0))); 410 Assert.assertEquals(1970L, p.getTimestamp()); 411 Assert.assertEquals(0, CellComparatorImpl.COMPARATOR.compare(c.get(0), new KeyValue(c.get(0)))); 412 } 413 414 @Test 415 @SuppressWarnings("rawtypes") 416 public void testOperationSubClassMethodsAreBuilderStyle() { 417 /* All Operation subclasses should have a builder style setup where setXXX/addXXX methods 418 * can be chainable together: 419 * . For example: 420 * Scan scan = new Scan() 421 * .setFoo(foo) 422 * .setBar(bar) 423 * .setBuz(buz) 424 * 425 * This test ensures that all methods starting with "set" returns the declaring object 426 */ 427 428 // TODO: We should ensure all subclasses of Operation is checked. 429 Class[] classes = new Class[] { 430 Operation.class, 431 OperationWithAttributes.class, 432 Mutation.class, 433 Query.class, 434 Delete.class, 435 Increment.class, 436 Append.class, 437 Put.class, 438 Get.class, 439 Scan.class}; 440 441 BuilderStyleTest.assertClassesAreBuilderStyle(classes); 442 } 443}