View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.security.visibility;
19  
20  import static org.apache.hadoop.hbase.security.visibility.VisibilityConstants.LABELS_TABLE_NAME;
21  import static org.junit.Assert.assertEquals;
22  import static org.junit.Assert.assertTrue;
23  
24  import java.io.IOException;
25  import java.io.InterruptedIOException;
26  import java.security.PrivilegedExceptionAction;
27  import java.util.ArrayList;
28  import java.util.Arrays;
29  import java.util.List;
30  
31  import org.apache.hadoop.conf.Configuration;
32  import org.apache.hadoop.hbase.Cell;
33  import org.apache.hadoop.hbase.CellScanner;
34  import org.apache.hadoop.hbase.HBaseTestingUtility;
35  import org.apache.hadoop.hbase.HColumnDescriptor;
36  import org.apache.hadoop.hbase.HConstants;
37  import org.apache.hadoop.hbase.HTableDescriptor;
38  import org.apache.hadoop.hbase.testclassification.MediumTests;
39  import org.apache.hadoop.hbase.TableName;
40  import org.apache.hadoop.hbase.client.Admin;
41  import org.apache.hadoop.hbase.client.Connection;
42  import org.apache.hadoop.hbase.client.ConnectionFactory;
43  import org.apache.hadoop.hbase.client.Delete;
44  import org.apache.hadoop.hbase.client.Get;
45  import org.apache.hadoop.hbase.client.HTable;
46  import org.apache.hadoop.hbase.client.Put;
47  import org.apache.hadoop.hbase.client.Result;
48  import org.apache.hadoop.hbase.client.ResultScanner;
49  import org.apache.hadoop.hbase.client.RetriesExhaustedWithDetailsException;
50  import org.apache.hadoop.hbase.client.Scan;
51  import org.apache.hadoop.hbase.client.Table;
52  import org.apache.hadoop.hbase.protobuf.generated.VisibilityLabelsProtos.VisibilityLabelsResponse;
53  import org.apache.hadoop.hbase.security.User;
54  import org.apache.hadoop.hbase.util.Bytes;
55  import org.junit.After;
56  import org.junit.AfterClass;
57  import org.junit.BeforeClass;
58  import org.junit.Rule;
59  import org.junit.Test;
60  import org.junit.experimental.categories.Category;
61  import org.junit.rules.TestName;
62  
63  /**
64   * Tests visibility labels with deletes
65   */
66  @Category(MediumTests.class)
67  public class TestVisibilityLabelsWithDeletes {
68    private static final String TOPSECRET = "TOPSECRET";
69    private static final String PUBLIC = "PUBLIC";
70    private static final String PRIVATE = "PRIVATE";
71    private static final String CONFIDENTIAL = "CONFIDENTIAL";
72    private static final String SECRET = "SECRET";
73    public static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
74    private static final byte[] row1 = Bytes.toBytes("row1");
75    private static final byte[] row2 = Bytes.toBytes("row2");
76    private final static byte[] fam = Bytes.toBytes("info");
77    private final static byte[] qual = Bytes.toBytes("qual");
78    private final static byte[] qual1 = Bytes.toBytes("qual1");
79    private final static byte[] qual2 = Bytes.toBytes("qual2");
80    private final static byte[] value = Bytes.toBytes("value");
81    private final static byte[] value1 = Bytes.toBytes("value1");
82    public static Configuration conf;
83  
84    @Rule
85    public final TestName TEST_NAME = new TestName();
86    public static User SUPERUSER;
87  
88    @BeforeClass
89    public static void setupBeforeClass() throws Exception {
90      // setup configuration
91      conf = TEST_UTIL.getConfiguration();
92      conf.setBoolean(HConstants.DISTRIBUTED_LOG_REPLAY_KEY, false);
93      VisibilityTestUtil.enableVisiblityLabels(conf);
94      conf.setClass(VisibilityUtils.VISIBILITY_LABEL_GENERATOR_CLASS, SimpleScanLabelGenerator.class,
95          ScanLabelGenerator.class);
96      conf.set("hbase.superuser", "admin");
97      TEST_UTIL.startMiniCluster(2);
98      SUPERUSER = User.createUserForTesting(conf, "admin", new String[] { "supergroup" });
99  
100     // Wait for the labels table to become available
101     TEST_UTIL.waitTableEnabled(LABELS_TABLE_NAME.getName(), 50000);
102     addLabels();
103   }
104 
105   @AfterClass
106   public static void tearDownAfterClass() throws Exception {
107     TEST_UTIL.shutdownMiniCluster();
108   }
109 
110   @After
111   public void tearDown() throws Exception {
112   }
113 
114   @Test
115   public void testVisibilityLabelsWithDeleteColumns() throws Throwable {
116     setAuths();
117     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
118 
119     try (Table table = createTableAndWriteDataWithLabels(tableName,
120         SECRET + "&" + TOPSECRET, SECRET)) {
121       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
122         @Override
123         public Void run() throws Exception {
124           try (Connection connection = ConnectionFactory.createConnection(conf);
125                Table table = connection.getTable(tableName)) {
126             Delete d = new Delete(row1);
127             d.setCellVisibility(new CellVisibility(TOPSECRET + "&" + SECRET));
128             d.addColumns(fam, qual);
129             table.delete(d);
130           } catch (Throwable t) {
131             throw new IOException(t);
132           }
133           return null;
134         }
135       };
136       SUPERUSER.runAs(actiona);
137 
138       TEST_UTIL.getHBaseAdmin().flush(tableName);
139       Scan s = new Scan();
140       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL));
141       ResultScanner scanner = table.getScanner(s);
142       Result[] next = scanner.next(3);
143       assertTrue(next.length == 1);
144       CellScanner cellScanner = next[0].cellScanner();
145       cellScanner.advance();
146       Cell current = cellScanner.current();
147       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
148           current.getRowLength(), row2, 0, row2.length));
149 
150     }
151   }
152 
153   @Test
154   public void testVisibilityLabelsWithDeleteFamily() throws Exception {
155     setAuths();
156     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
157     try (Table table = createTableAndWriteDataWithLabels(tableName, SECRET,
158         CONFIDENTIAL + "|" + TOPSECRET);) {
159       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
160         @Override
161         public Void run() throws Exception {
162           try (Connection connection = ConnectionFactory.createConnection(conf);
163                Table table = connection.getTable(tableName)) {
164             Delete d = new Delete(row2);
165             d.setCellVisibility(new CellVisibility(TOPSECRET + "|" + CONFIDENTIAL));
166             d.addFamily(fam);
167             table.delete(d);
168           } catch (Throwable t) {
169             throw new IOException(t);
170           }
171           return null;
172         }
173       };
174       SUPERUSER.runAs(actiona);
175 
176       TEST_UTIL.getHBaseAdmin().flush(tableName);
177       Scan s = new Scan();
178       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL));
179       ResultScanner scanner = table.getScanner(s);
180       Result[] next = scanner.next(3);
181       assertTrue(next.length == 1);
182       CellScanner cellScanner = next[0].cellScanner();
183       cellScanner.advance();
184       Cell current = cellScanner.current();
185       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
186           current.getRowLength(), row1, 0, row1.length));
187     }
188   }
189 
190   @Test
191   public void testVisibilityLabelsWithDeleteFamilyVersion() throws Exception {
192     setAuths();
193     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
194     long[] ts = new long[] { 123l, 125l };
195     try (Table table = createTableAndWriteDataWithLabels(tableName, ts,
196         CONFIDENTIAL + "|" + TOPSECRET, SECRET)) {
197       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
198         @Override
199         public Void run() throws Exception {
200           try (Connection connection = ConnectionFactory.createConnection(conf);
201                Table table = connection.getTable(tableName)) {
202             Delete d = new Delete(row1);
203             d.setCellVisibility(new CellVisibility(TOPSECRET + "|" + CONFIDENTIAL));
204             d.deleteFamilyVersion(fam, 123l);
205             table.delete(d);
206           } catch (Throwable t) {
207             throw new IOException(t);
208           }
209           return null;
210         }
211       };
212       SUPERUSER.runAs(actiona);
213 
214       TEST_UTIL.getHBaseAdmin().flush(tableName);
215       Scan s = new Scan();
216       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL));
217       ResultScanner scanner = table.getScanner(s);
218       Result[] next = scanner.next(3);
219       assertTrue(next.length == 1);
220       CellScanner cellScanner = next[0].cellScanner();
221       cellScanner.advance();
222       Cell current = cellScanner.current();
223       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
224           current.getRowLength(), row2, 0, row2.length));
225     }
226   }
227 
228   @Test
229   public void testVisibilityLabelsWithDeleteColumnExactVersion() throws Exception {
230     setAuths();
231     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
232     long[] ts = new long[] { 123l, 125l };
233     try (Table table = createTableAndWriteDataWithLabels(tableName, ts,
234         CONFIDENTIAL + "|" + TOPSECRET, SECRET);) {
235       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
236         @Override
237         public Void run() throws Exception {
238           try (Connection connection = ConnectionFactory.createConnection(conf);
239                Table table = connection.getTable(tableName)) {
240             Delete d = new Delete(row1);
241             d.setCellVisibility(new CellVisibility(TOPSECRET + "|" + CONFIDENTIAL));
242             d.addColumn(fam, qual, 123l);
243             table.delete(d);
244           } catch (Throwable t) {
245             throw new IOException(t);
246           }
247           return null;
248         }
249       };
250       SUPERUSER.runAs(actiona);
251 
252       TEST_UTIL.getHBaseAdmin().flush(tableName);
253       Scan s = new Scan();
254       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL));
255       ResultScanner scanner = table.getScanner(s);
256       Result[] next = scanner.next(3);
257       assertTrue(next.length == 1);
258       CellScanner cellScanner = next[0].cellScanner();
259       cellScanner.advance();
260       Cell current = cellScanner.current();
261       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
262           current.getRowLength(), row2, 0, row2.length));
263     }
264   }
265 
266   @Test
267   public void testVisibilityLabelsWithDeleteColumnsWithMultipleVersions() throws Exception {
268     setAuths();
269     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
270     try (Table table = doPuts(tableName)) {
271       TEST_UTIL.getHBaseAdmin().flush(tableName);
272       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
273         @Override
274         public Void run() throws Exception {
275           try (Connection connection = ConnectionFactory.createConnection(conf);
276                Table table = connection.getTable(tableName)) {
277             Delete d = new Delete(row1);
278             d.setCellVisibility(new CellVisibility("(" + PRIVATE + "&" + CONFIDENTIAL + ")|(" +
279                 SECRET + "&" + TOPSECRET+")"));
280             d.addColumns(fam, qual, 125l);
281             table.delete(d);
282           } catch (Throwable t) {
283             throw new IOException(t);
284           }
285           return null;
286         }
287       };
288       SUPERUSER.runAs(actiona);
289 
290       TEST_UTIL.getHBaseAdmin().flush(tableName);
291       Scan s = new Scan();
292       s.setMaxVersions(5);
293       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
294       ResultScanner scanner = table.getScanner(s);
295       Result[] next = scanner.next(3);
296       assertTrue(next.length == 2);
297       CellScanner cellScanner = next[0].cellScanner();
298       cellScanner.advance();
299       Cell current = cellScanner.current();
300       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
301           current.getRowLength(), row1, 0, row1.length));
302       assertEquals(current.getTimestamp(), 127l);
303       cellScanner.advance();
304       current = cellScanner.current();
305       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
306           current.getRowLength(), row1, 0, row1.length));
307       assertEquals(current.getTimestamp(), 126l);
308       cellScanner.advance();
309       current = cellScanner.current();
310       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
311           current.getRowLength(), row1, 0, row1.length));
312       assertEquals(current.getTimestamp(), 125l);
313       cellScanner = next[1].cellScanner();
314       cellScanner.advance();
315       current = cellScanner.current();
316       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
317           current.getRowLength(), row2, 0, row2.length));
318     }
319   }
320 
321   @Test
322   public void testVisibilityLabelsWithDeleteColumnsWithMultipleVersionsNoTimestamp()
323       throws Exception {
324     setAuths();
325     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
326     try (Table table = doPuts(tableName)) {
327       TEST_UTIL.getHBaseAdmin().flush(tableName);
328       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
329         @Override
330         public Void run() throws Exception {
331           try (Connection connection = ConnectionFactory.createConnection(conf);
332                Table table = connection.getTable(tableName)) {
333             Delete d1 = new Delete(row1);
334             d1.setCellVisibility(new CellVisibility(CONFIDENTIAL));
335             d1.addColumns(fam, qual);
336 
337             table.delete(d1);
338 
339             Delete d2 = new Delete(row1);
340             d2.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
341             d2.addColumns(fam, qual);
342             table.delete(d2);
343 
344             Delete d3 = new Delete(row1);
345             d3.setCellVisibility(new CellVisibility("(" + PRIVATE + "&" + CONFIDENTIAL + ")|("
346                 + SECRET + "&" + TOPSECRET + ")"));
347             d3.addColumns(fam, qual);
348             table.delete(d3);
349           } catch (Throwable t) {
350             throw new IOException(t);
351           }
352           return null;
353         }
354       };
355       SUPERUSER.runAs(actiona);
356       Scan s = new Scan();
357       s.setMaxVersions(5);
358       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
359       ResultScanner scanner = table.getScanner(s);
360       Result[] next = scanner.next(3);
361       assertEquals(1, next.length);
362       CellScanner cellScanner = next[0].cellScanner();
363       cellScanner.advance();
364       Cell current = cellScanner.current();
365       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
366           current.getRowLength(), row2, 0, row2.length));
367     }
368   }
369 
370   @Test
371   public void
372     testVisibilityLabelsWithDeleteColumnsWithNoMatchVisExpWithMultipleVersionsNoTimestamp()
373       throws Exception {
374     setAuths();
375     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
376     try (Table table = doPuts(tableName)) {
377       TEST_UTIL.getHBaseAdmin().flush(tableName);
378       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
379         @Override
380         public Void run() throws Exception {
381           try (Connection connection = ConnectionFactory.createConnection(conf);
382                Table table = connection.getTable(tableName)) {
383             Delete d = new Delete(row1);
384             d.setCellVisibility(new CellVisibility(CONFIDENTIAL));
385             d.addColumns(fam, qual);
386             table.delete(d);
387 
388             d = new Delete(row1);
389             d.setCellVisibility(new CellVisibility(SECRET));
390             d.addColumns(fam, qual);
391             table.delete(d);
392 
393             d = new Delete(row1);
394             d.setCellVisibility(new CellVisibility("(" + PRIVATE + "&" + CONFIDENTIAL + ")|("
395                 + SECRET + "&" + TOPSECRET + ")"));
396             d.addColumns(fam, qual);
397             table.delete(d);
398           } catch (Throwable t) {
399             throw new IOException(t);
400           }
401           return null;
402         }
403       };
404       SUPERUSER.runAs(actiona);
405       Scan s = new Scan();
406       s.setMaxVersions(5);
407       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
408       ResultScanner scanner = table.getScanner(s);
409       Result[] next = scanner.next(3);
410       assertTrue(next.length == 2);
411       CellScanner cellScanner = next[0].cellScanner();
412       cellScanner.advance();
413       Cell current = cellScanner.current();
414       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
415           current.getRowLength(), row1, 0, row1.length));
416       cellScanner = next[1].cellScanner();
417       cellScanner.advance();
418       current = cellScanner.current();
419       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
420           current.getRowLength(), row2, 0, row2.length));
421     }
422   }
423 
424   @Test
425   public void testVisibilityLabelsWithDeleteFamilyWithMultipleVersionsNoTimestamp()
426       throws Exception {
427     setAuths();
428     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
429     try (Table table = doPuts(tableName)) {
430       TEST_UTIL.getHBaseAdmin().flush(tableName);
431       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
432         @Override
433         public Void run() throws Exception {
434           try (Connection connection = ConnectionFactory.createConnection(conf);
435                Table table = connection.getTable(tableName)) {
436             Delete d1 = new Delete(row1);
437             d1.setCellVisibility(new CellVisibility(CONFIDENTIAL));
438             d1.addFamily(fam);
439             table.delete(d1);
440 
441             Delete d2 = new Delete(row1);
442             d2.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
443             d2.addFamily(fam);
444             table.delete(d2);
445 
446             Delete d3 = new Delete(row1);
447             d3.setCellVisibility(new CellVisibility("(" + PRIVATE + "&" + CONFIDENTIAL + ")|("
448                 + SECRET + "&" + TOPSECRET + ")"));
449             d3.addFamily(fam);
450             table.delete(d3);
451           } catch (Throwable t) {
452             throw new IOException(t);
453           }
454           return null;
455         }
456       };
457       SUPERUSER.runAs(actiona);
458       Scan s = new Scan();
459       s.setMaxVersions(5);
460       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
461       ResultScanner scanner = table.getScanner(s);
462       Result[] next = scanner.next(3);
463       assertEquals(1, next.length);
464       CellScanner cellScanner = next[0].cellScanner();
465       cellScanner.advance();
466       Cell current = cellScanner.current();
467       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
468           current.getRowLength(), row2, 0, row2.length));
469     }
470   }
471 
472   @Test
473   public void testDeleteColumnsWithoutAndWithVisibilityLabels() throws Exception {
474     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
475     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
476     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
477     HTableDescriptor desc = new HTableDescriptor(tableName);
478     desc.addFamily(colDesc);
479     hBaseAdmin.createTable(desc);
480     try (Table table = TEST_UTIL.getConnection().getTable(tableName)) {
481       Put put = new Put(row1);
482       put.addColumn(fam, qual, value);
483       put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
484       table.put(put);
485       Delete d = new Delete(row1);
486       // without visibility
487       d.addColumns(fam, qual, HConstants.LATEST_TIMESTAMP);
488       table.delete(d);
489       PrivilegedExceptionAction<Void> scanAction = new PrivilegedExceptionAction<Void>() {
490         @Override
491         public Void run() throws Exception {
492           try (Connection connection = ConnectionFactory.createConnection(conf);
493               Table table = connection.getTable(tableName)) {
494             Scan s = new Scan();
495             ResultScanner scanner = table.getScanner(s);
496             Result[] next = scanner.next(3);
497             assertEquals(next.length, 1);
498           } catch (Throwable t) {
499             throw new IOException(t);
500           }
501           return null;
502         }
503       };
504       SUPERUSER.runAs(scanAction);
505       d = new Delete(row1);
506       // with visibility
507       d.setCellVisibility(new CellVisibility(CONFIDENTIAL));
508       d.addColumns(fam, qual, HConstants.LATEST_TIMESTAMP);
509       table.delete(d);
510       scanAction = new PrivilegedExceptionAction<Void>() {
511         @Override
512         public Void run() throws Exception {
513           try (Connection connection = ConnectionFactory.createConnection(conf);
514               Table table = connection.getTable(tableName)) {
515             Scan s = new Scan();
516             ResultScanner scanner = table.getScanner(s);
517             Result[] next = scanner.next(3);
518             assertEquals(next.length, 0);
519           } catch (Throwable t) {
520             throw new IOException(t);
521           }
522           return null;
523         }
524       };
525       SUPERUSER.runAs(scanAction);
526     }
527   }
528 
529   @Test
530   public void testDeleteColumnsWithAndWithoutVisibilityLabels() throws Exception {
531     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
532     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
533     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
534     HTableDescriptor desc = new HTableDescriptor(tableName);
535     desc.addFamily(colDesc);
536     hBaseAdmin.createTable(desc);
537     try (Table table = TEST_UTIL.getConnection().getTable(tableName)) {
538       Put put = new Put(row1);
539       put.addColumn(fam, qual, value);
540       put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
541       table.put(put);
542       Delete d = new Delete(row1);
543       // with visibility
544       d.setCellVisibility(new CellVisibility(CONFIDENTIAL));
545       d.addColumns(fam, qual, HConstants.LATEST_TIMESTAMP);
546       table.delete(d);
547       PrivilegedExceptionAction<Void> scanAction = new PrivilegedExceptionAction<Void>() {
548         @Override
549         public Void run() throws Exception {
550           try (Connection connection = ConnectionFactory.createConnection(conf);
551               Table table = connection.getTable(tableName)) {
552             Scan s = new Scan();
553             ResultScanner scanner = table.getScanner(s);
554             Result[] next = scanner.next(3);
555             assertEquals(next.length, 0);
556           } catch (Throwable t) {
557             throw new IOException(t);
558           }
559           return null;
560         }
561       };
562       SUPERUSER.runAs(scanAction);
563       d = new Delete(row1);
564       // without visibility
565       d.addColumns(fam, qual, HConstants.LATEST_TIMESTAMP);
566       table.delete(d);
567       scanAction = new PrivilegedExceptionAction<Void>() {
568         @Override
569         public Void run() throws Exception {
570           try (Connection connection = ConnectionFactory.createConnection(conf);
571               Table table = connection.getTable(tableName)) {
572             Scan s = new Scan();
573             ResultScanner scanner = table.getScanner(s);
574             Result[] next = scanner.next(3);
575             assertEquals(next.length, 0);
576           } catch (Throwable t) {
577             throw new IOException(t);
578           }
579           return null;
580         }
581       };
582       SUPERUSER.runAs(scanAction);
583     }
584   }
585 
586   @Test
587   public void testDeleteFamiliesWithoutAndWithVisibilityLabels() throws Exception {
588     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
589     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
590     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
591     HTableDescriptor desc = new HTableDescriptor(tableName);
592     desc.addFamily(colDesc);
593     hBaseAdmin.createTable(desc);
594     try (Table table = TEST_UTIL.getConnection().getTable(tableName)) {
595       Put put = new Put(row1);
596       put.addColumn(fam, qual, value);
597       put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
598       table.put(put);
599       Delete d = new Delete(row1);
600       // without visibility
601       d.addFamily(fam);
602       table.delete(d);
603       PrivilegedExceptionAction<Void> scanAction = new PrivilegedExceptionAction<Void>() {
604         @Override
605         public Void run() throws Exception {
606           try (Connection connection = ConnectionFactory.createConnection(conf);
607               Table table = connection.getTable(tableName)) {
608             Scan s = new Scan();
609             ResultScanner scanner = table.getScanner(s);
610             Result[] next = scanner.next(3);
611             assertEquals(next.length, 1);
612           } catch (Throwable t) {
613             throw new IOException(t);
614           }
615           return null;
616         }
617       };
618       SUPERUSER.runAs(scanAction);
619       d = new Delete(row1);
620       // with visibility
621       d.setCellVisibility(new CellVisibility(CONFIDENTIAL));
622       d.addFamily(fam);
623       table.delete(d);
624       scanAction = new PrivilegedExceptionAction<Void>() {
625         @Override
626         public Void run() throws Exception {
627           try (Connection connection = ConnectionFactory.createConnection(conf);
628               Table table = connection.getTable(tableName)) {
629             Scan s = new Scan();
630             ResultScanner scanner = table.getScanner(s);
631             Result[] next = scanner.next(3);
632             assertEquals(next.length, 0);
633           } catch (Throwable t) {
634             throw new IOException(t);
635           }
636           return null;
637         }
638       };
639       SUPERUSER.runAs(scanAction);
640     }
641   }
642 
643   @Test
644   public void testDeleteFamiliesWithAndWithoutVisibilityLabels() throws Exception {
645     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
646     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
647     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
648     HTableDescriptor desc = new HTableDescriptor(tableName);
649     desc.addFamily(colDesc);
650     hBaseAdmin.createTable(desc);
651     try (Table table = TEST_UTIL.getConnection().getTable(tableName)) {
652       Put put = new Put(row1);
653       put.addColumn(fam, qual, value);
654       put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
655       table.put(put);
656       Delete d = new Delete(row1);
657       d.setCellVisibility(new CellVisibility(CONFIDENTIAL));
658       // with visibility
659       d.addFamily(fam);
660       table.delete(d);
661       PrivilegedExceptionAction<Void> scanAction = new PrivilegedExceptionAction<Void>() {
662         @Override
663         public Void run() throws Exception {
664           try (Connection connection = ConnectionFactory.createConnection(conf);
665               Table table = connection.getTable(tableName)) {
666             Scan s = new Scan();
667             ResultScanner scanner = table.getScanner(s);
668             Result[] next = scanner.next(3);
669             assertEquals(next.length, 0);
670           } catch (Throwable t) {
671             throw new IOException(t);
672           }
673           return null;
674         }
675       };
676       SUPERUSER.runAs(scanAction);
677       d = new Delete(row1);
678       // without visibility
679       d.addFamily(fam);
680       table.delete(d);
681       scanAction = new PrivilegedExceptionAction<Void>() {
682         @Override
683         public Void run() throws Exception {
684           try (Connection connection = ConnectionFactory.createConnection(conf);
685               Table table = connection.getTable(tableName)) {
686             Scan s = new Scan();
687             ResultScanner scanner = table.getScanner(s);
688             Result[] next = scanner.next(3);
689             assertEquals(next.length, 0);
690           } catch (Throwable t) {
691             throw new IOException(t);
692           }
693           return null;
694         }
695       };
696       SUPERUSER.runAs(scanAction);
697     }
698   }
699 
700   @Test
701   public void testDeletesWithoutAndWithVisibilityLabels() throws Exception {
702     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
703     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
704     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
705     HTableDescriptor desc = new HTableDescriptor(tableName);
706     desc.addFamily(colDesc);
707     hBaseAdmin.createTable(desc);
708     try (Table table = TEST_UTIL.getConnection().getTable(tableName)) {
709       Put put = new Put(row1);
710       put.addColumn(fam, qual, value);
711       put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
712       table.put(put);
713       Delete d = new Delete(row1);
714       // without visibility
715       d.addColumn(fam, qual);
716       table.delete(d);
717       PrivilegedExceptionAction<Void> scanAction = new PrivilegedExceptionAction<Void>() {
718         @Override
719         public Void run() throws Exception {
720           try (Connection connection = ConnectionFactory.createConnection(conf);
721               Table table = connection.getTable(tableName)) {
722             Scan s = new Scan();
723             ResultScanner scanner = table.getScanner(s);
724             // The delete would not be able to apply it because of visibility mismatch
725             Result[] next = scanner.next(3);
726             assertEquals(next.length, 1);
727           } catch (Throwable t) {
728             throw new IOException(t);
729           }
730           return null;
731         }
732       };
733       SUPERUSER.runAs(scanAction);
734       d = new Delete(row1);
735       // with visibility
736       d.setCellVisibility(new CellVisibility(CONFIDENTIAL));
737       d.addColumn(fam, qual);
738       table.delete(d);
739       scanAction = new PrivilegedExceptionAction<Void>() {
740         @Override
741         public Void run() throws Exception {
742           try (Connection connection = ConnectionFactory.createConnection(conf);
743               Table table = connection.getTable(tableName)) {
744             Scan s = new Scan();
745             ResultScanner scanner = table.getScanner(s);
746             Result[] next = scanner.next(3);
747             // this will alone match
748             assertEquals(next.length, 0);
749           } catch (Throwable t) {
750             throw new IOException(t);
751           }
752           return null;
753         }
754       };
755       SUPERUSER.runAs(scanAction);
756     }
757   }
758 
759   @Test
760   public void testVisibilityLabelsWithDeleteFamilyWithPutsReAppearing() throws Exception {
761     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
762     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
763     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
764     colDesc.setMaxVersions(5);
765     HTableDescriptor desc = new HTableDescriptor(tableName);
766     desc.addFamily(colDesc);
767     hBaseAdmin.createTable(desc);
768     try (Table table = new HTable(conf, tableName)) {
769       Put put = new Put(Bytes.toBytes("row1"));
770       put.add(fam, qual, value);
771       put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
772       table.put(put);
773       put = new Put(Bytes.toBytes("row1"));
774       put.add(fam, qual, value);
775       put.setCellVisibility(new CellVisibility(SECRET));
776       table.put(put);
777       TEST_UTIL.getHBaseAdmin().flush(tableName);
778       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
779         @Override
780         public Void run() throws Exception {
781           try (Connection connection = ConnectionFactory.createConnection(conf);
782                Table table = connection.getTable(tableName)) {
783             Delete d = new Delete(row1);
784             d.setCellVisibility(new CellVisibility(CONFIDENTIAL));
785             d.addFamily(fam);
786             table.delete(d);
787           } catch (Throwable t) {
788             throw new IOException(t);
789           }
790           return null;
791         }
792       };
793       SUPERUSER.runAs(actiona);
794       Scan s = new Scan();
795       s.setMaxVersions(5);
796       s.setAuthorizations(new Authorizations(SECRET));
797       ResultScanner scanner = table.getScanner(s);
798       Result[] next = scanner.next(3);
799       assertEquals(next.length, 1);
800       put = new Put(Bytes.toBytes("row1"));
801       put.add(fam, qual, value1);
802       put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
803       table.put(put);
804       actiona = new PrivilegedExceptionAction<Void>() {
805         @Override
806         public Void run() throws Exception {
807           try (Connection connection = ConnectionFactory.createConnection(conf);
808                Table table = connection.getTable(tableName)) {
809             Delete d = new Delete(row1);
810             d.setCellVisibility(new CellVisibility(SECRET));
811             d.addFamily(fam);
812             table.delete(d);
813           } catch (Throwable t) {
814             throw new IOException(t);
815           }
816           return null;
817         }
818       };
819       SUPERUSER.runAs(actiona);
820       s = new Scan();
821       s.setMaxVersions(5);
822       s.setAuthorizations(new Authorizations(CONFIDENTIAL));
823       scanner = table.getScanner(s);
824       next = scanner.next(3);
825       assertEquals(next.length, 1);
826       s = new Scan();
827       s.setMaxVersions(5);
828       s.setAuthorizations(new Authorizations(SECRET));
829       scanner = table.getScanner(s);
830       Result[] next1 = scanner.next(3);
831       assertEquals(next1.length, 0);
832     }
833   }
834 
835   @Test
836   public void testVisibilityLabelsWithDeleteColumnsWithPutsReAppearing() throws Exception {
837     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
838     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
839     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
840     colDesc.setMaxVersions(5);
841     HTableDescriptor desc = new HTableDescriptor(tableName);
842     desc.addFamily(colDesc);
843     hBaseAdmin.createTable(desc);
844     try (Table table = new HTable(conf, tableName)) {
845       Put put = new Put(Bytes.toBytes("row1"));
846       put.add(fam, qual, value);
847       put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
848       table.put(put);
849       put = new Put(Bytes.toBytes("row1"));
850       put.add(fam, qual, value);
851       put.setCellVisibility(new CellVisibility(SECRET));
852       table.put(put);
853       TEST_UTIL.getHBaseAdmin().flush(tableName);
854       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
855         @Override
856         public Void run() throws Exception {
857           try (Connection connection = ConnectionFactory.createConnection(conf);
858                Table table = connection.getTable(tableName)) {
859             Delete d = new Delete(row1);
860             d.setCellVisibility(new CellVisibility(CONFIDENTIAL));
861             d.addColumns(fam, qual);
862             table.delete(d);
863           } catch (Throwable t) {
864             throw new IOException(t);
865           }
866           return null;
867         }
868       };
869       SUPERUSER.runAs(actiona);
870       Scan s = new Scan();
871       s.setMaxVersions(5);
872       s.setAuthorizations(new Authorizations(SECRET));
873       ResultScanner scanner = table.getScanner(s);
874       Result[] next = scanner.next(3);
875       assertEquals(next.length, 1);
876       put = new Put(Bytes.toBytes("row1"));
877       put.add(fam, qual, value1);
878       put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
879       table.put(put);
880       actiona = new PrivilegedExceptionAction<Void>() {
881         @Override
882         public Void run() throws Exception {
883           try (Connection connection = ConnectionFactory.createConnection(conf);
884                Table table = connection.getTable(tableName)) {
885             Delete d = new Delete(row1);
886             d.setCellVisibility(new CellVisibility(SECRET));
887             d.addColumns(fam, qual);
888             table.delete(d);
889           } catch (Throwable t) {
890             throw new IOException(t);
891           }
892           return null;
893         }
894       };
895       SUPERUSER.runAs(actiona);
896       s = new Scan();
897       s.setMaxVersions(5);
898       s.setAuthorizations(new Authorizations(CONFIDENTIAL));
899       scanner = table.getScanner(s);
900       next = scanner.next(3);
901       assertEquals(next.length, 1);
902       s = new Scan();
903       s.setMaxVersions(5);
904       s.setAuthorizations(new Authorizations(SECRET));
905       scanner = table.getScanner(s);
906       Result[] next1 = scanner.next(3);
907       assertEquals(next1.length, 0);
908     }
909   }
910 
911   @Test
912   public void testVisibilityCombinations() throws Exception {
913     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
914     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
915     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
916     colDesc.setMaxVersions(5);
917     HTableDescriptor desc = new HTableDescriptor(tableName);
918     desc.addFamily(colDesc);
919     hBaseAdmin.createTable(desc);
920     try (Table table = new HTable(conf, tableName)) {
921       Put put = new Put(Bytes.toBytes("row1"));
922       put.add(fam, qual, 123l, value);
923       put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
924       table.put(put);
925       put = new Put(Bytes.toBytes("row1"));
926       put.add(fam, qual, 124l, value1);
927       put.setCellVisibility(new CellVisibility(SECRET));
928       table.put(put);
929       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
930         @Override
931         public Void run() throws Exception {
932           try (Connection connection = ConnectionFactory.createConnection(conf);
933                Table table = connection.getTable(tableName)) {
934             Delete d = new Delete(row1);
935             d.setCellVisibility(new CellVisibility(SECRET));
936             d.addColumns(fam, qual, 126l);
937             table.delete(d);
938           } catch (Throwable t) {
939             throw new IOException(t);
940           }
941 
942           try (Connection connection = ConnectionFactory.createConnection(conf);
943                Table table = connection.getTable(tableName)) {
944             Delete d = new Delete(row1);
945             d.setCellVisibility(new CellVisibility(CONFIDENTIAL));
946             d.addColumn(fam, qual, 123l);
947             table.delete(d);
948           } catch (Throwable t) {
949             throw new IOException(t);
950           }
951           return null;
952         }
953       };
954       SUPERUSER.runAs(actiona);
955       Scan s = new Scan();
956       s.setMaxVersions(5);
957       s.setAuthorizations(new Authorizations(CONFIDENTIAL, SECRET));
958       ResultScanner scanner = table.getScanner(s);
959       Result[] next = scanner.next(3);
960       assertEquals(next.length, 0);
961     }
962   }
963   @Test
964   public void testVisibilityLabelsWithDeleteColumnWithSpecificVersionWithPutsReAppearing()
965       throws Exception {
966     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
967     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
968     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
969     colDesc.setMaxVersions(5);
970     HTableDescriptor desc = new HTableDescriptor(tableName);
971     desc.addFamily(colDesc);
972     hBaseAdmin.createTable(desc);
973 
974     try (Table table = new HTable(conf, tableName)) {
975       Put put1 = new Put(Bytes.toBytes("row1"));
976       put1.add(fam, qual, 123l, value);
977       put1.setCellVisibility(new CellVisibility(CONFIDENTIAL));
978 
979       Put put2 = new Put(Bytes.toBytes("row1"));
980       put2.add(fam, qual, 123l, value1);
981       put2.setCellVisibility(new CellVisibility(SECRET));
982       table.put(createList(put1, put2));
983 
984       Scan s = new Scan();
985       s.setMaxVersions(5);
986       s.setAuthorizations(new Authorizations(CONFIDENTIAL, SECRET));
987 
988       ResultScanner scanner = table.getScanner(s);
989       assertEquals(scanner.next(3).length, 1);
990       scanner.close();
991 
992       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
993         @Override
994         public Void run() throws Exception {
995           try (Connection connection = ConnectionFactory.createConnection(conf);
996                Table table = connection.getTable(tableName)) {
997             Delete d = new Delete(row1);
998             d.setCellVisibility(new CellVisibility(CONFIDENTIAL));
999             d.addColumn(fam, qual, 123l);
1000             table.delete(d);
1001           }
1002 
1003           try (Connection connection = ConnectionFactory.createConnection(conf);
1004                Table table = connection.getTable(tableName)) {
1005             Delete d = new Delete(row1);
1006             d.setCellVisibility(new CellVisibility(SECRET));
1007             d.addColumn(fam, qual, 123l);
1008             table.delete(d);
1009           } catch (Throwable t) {
1010             throw new IOException(t);
1011           }
1012           return null;
1013         }
1014       };
1015       SUPERUSER.runAs(actiona);
1016       s = new Scan();
1017       s.setMaxVersions(5);
1018       s.setAuthorizations(new Authorizations(CONFIDENTIAL));
1019       scanner = table.getScanner(s);
1020       assertEquals(scanner.next(3).length, 0);
1021       scanner.close();
1022     }
1023   }
1024 
1025   @Test
1026   public void
1027     testVisibilityLabelsWithDeleteFamilyWithNoMatchingVisExpWithMultipleVersionsNoTimestamp()
1028       throws Exception {
1029     setAuths();
1030     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
1031     try (Table table = doPuts(tableName)) {
1032       TEST_UTIL.getHBaseAdmin().flush(tableName);
1033       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
1034         @Override
1035         public Void run() throws Exception {
1036           Delete d1 = new Delete(row1);
1037           d1.setCellVisibility(new CellVisibility(CONFIDENTIAL));
1038           d1.addFamily(fam);
1039 
1040           Delete d2 = new Delete(row1);
1041           d2.setCellVisibility(new CellVisibility(SECRET));
1042           d2.addFamily(fam);
1043 
1044           Delete d3 = new Delete(row1);
1045           d3.setCellVisibility(new CellVisibility("(" + PRIVATE + "&" + CONFIDENTIAL + ")|("
1046               + SECRET + "&" + TOPSECRET + ")"));
1047           d3.addFamily(fam);
1048 
1049           try (Connection connection = ConnectionFactory.createConnection(conf);
1050                Table table = connection.getTable(tableName)) {
1051             table.delete(createList(d1, d2, d3));
1052           } catch (Throwable t) {
1053             throw new IOException(t);
1054           }
1055           return null;
1056         }
1057       };
1058       SUPERUSER.runAs(actiona);
1059       Scan s = new Scan();
1060       s.setMaxVersions(5);
1061       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
1062       ResultScanner scanner = table.getScanner(s);
1063       Result[] next = scanner.next(3);
1064       assertTrue(next.length == 2);
1065       CellScanner cellScanner = next[0].cellScanner();
1066       cellScanner.advance();
1067       Cell current = cellScanner.current();
1068       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1069           current.getRowLength(), row1, 0, row1.length));
1070       cellScanner = next[1].cellScanner();
1071       cellScanner.advance();
1072       current = cellScanner.current();
1073       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1074           current.getRowLength(), row2, 0, row2.length));
1075       scanner.close();
1076     }
1077   }
1078 
1079   @Test
1080   public void testDeleteFamilyAndDeleteColumnsWithAndWithoutVisibilityExp() throws Exception {
1081     setAuths();
1082     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
1083     try (Table table = doPuts(tableName)) {
1084       TEST_UTIL.getHBaseAdmin().flush(tableName);
1085       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
1086         @Override
1087         public Void run() throws Exception {
1088           Delete d1 = new Delete(row1);
1089           d1.addFamily(fam);
1090 
1091           Delete d2 = new Delete(row1);
1092           d2.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
1093           d2.addColumns(fam, qual);
1094           try (Connection connection = ConnectionFactory.createConnection(conf);
1095                Table table = connection.getTable(tableName)) {
1096             table.delete(createList(d1, d2));
1097           } catch (Throwable t) {
1098             throw new IOException(t);
1099           }
1100           return null;
1101         }
1102       };
1103       SUPERUSER.runAs(actiona);
1104       Scan s = new Scan();
1105       s.setMaxVersions(5);
1106       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
1107       ResultScanner scanner = table.getScanner(s);
1108       Result[] next = scanner.next(3);
1109       assertTrue(next.length == 2);
1110       CellScanner cellScanner = next[0].cellScanner();
1111       cellScanner.advance();
1112       Cell current = cellScanner.current();
1113       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1114           current.getRowLength(), row1, 0, row1.length));
1115       assertEquals(current.getTimestamp(), 127l);
1116       cellScanner.advance();
1117       current = cellScanner.current();
1118       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1119           current.getRowLength(), row1, 0, row1.length));
1120       assertEquals(current.getTimestamp(), 126l);
1121       cellScanner.advance();
1122       current = cellScanner.current();
1123       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1124           current.getRowLength(), row1, 0, row1.length));
1125       assertEquals(current.getTimestamp(), 124l);
1126       cellScanner.advance();
1127       current = cellScanner.current();
1128       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1129           current.getRowLength(), row1, 0, row1.length));
1130       assertEquals(current.getTimestamp(), 123l);
1131       cellScanner = next[1].cellScanner();
1132       cellScanner.advance();
1133       current = cellScanner.current();
1134       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1135           current.getRowLength(), row2, 0, row2.length));
1136       scanner.close();
1137     }
1138   }
1139 
1140   private Table doPuts(TableName tableName) throws IOException, InterruptedIOException,
1141       RetriesExhaustedWithDetailsException, InterruptedException {
1142     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
1143     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
1144     colDesc.setMaxVersions(5);
1145     HTableDescriptor desc = new HTableDescriptor(tableName);
1146     desc.addFamily(colDesc);
1147     hBaseAdmin.createTable(desc);
1148 
1149     List<Put> puts = new ArrayList<Put>();
1150     Put put = new Put(Bytes.toBytes("row1"));
1151     put.add(fam, qual, 123l, value);
1152     put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
1153     puts.add(put);
1154 
1155     put = new Put(Bytes.toBytes("row1"));
1156     put.add(fam, qual, 124l, value);
1157     put.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")|("
1158     + TOPSECRET + "&" + SECRET+")"));
1159     puts.add(put);
1160 
1161     put = new Put(Bytes.toBytes("row1"));
1162     put.add(fam, qual, 125l, value);
1163     put.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
1164     puts.add(put);
1165 
1166     put = new Put(Bytes.toBytes("row1"));
1167     put.add(fam, qual, 126l, value);
1168     put.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")|("
1169         + TOPSECRET + "&" + SECRET+")"));
1170     puts.add(put);
1171 
1172     put = new Put(Bytes.toBytes("row1"));
1173     put.add(fam, qual, 127l, value);
1174     put.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")|("
1175         + TOPSECRET + "&" + SECRET+")"));
1176     puts.add(put);
1177 
1178     TEST_UTIL.getHBaseAdmin().flush(tableName);
1179     put = new Put(Bytes.toBytes("row2"));
1180     put.add(fam, qual, 127l, value);
1181     put.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")|(" + TOPSECRET
1182         + "&" + SECRET + ")"));
1183     puts.add(put);
1184 
1185     Table table = new HTable(conf, tableName);
1186     table.put(puts);
1187     return table;
1188   }
1189 
1190   private Table doPutsWithDiffCols(TableName tableName) throws IOException,
1191       InterruptedIOException, RetriesExhaustedWithDetailsException, InterruptedException {
1192     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
1193     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
1194     colDesc.setMaxVersions(5);
1195     HTableDescriptor desc = new HTableDescriptor(tableName);
1196     desc.addFamily(colDesc);
1197     hBaseAdmin.createTable(desc);
1198 
1199     List<Put> puts = new ArrayList<>();
1200     Put put = new Put(Bytes.toBytes("row1"));
1201     put.add(fam, qual, 123l, value);
1202     put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
1203     puts.add(put);
1204 
1205     put = new Put(Bytes.toBytes("row1"));
1206     put.add(fam, qual, 124l, value);
1207     put.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")|("
1208     + TOPSECRET + "&" + SECRET+")"));
1209     puts.add(put);
1210 
1211     put = new Put(Bytes.toBytes("row1"));
1212     put.add(fam, qual, 125l, value);
1213     put.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
1214     puts.add(put);
1215 
1216     put = new Put(Bytes.toBytes("row1"));
1217     put.add(fam, qual1, 126l, value);
1218     put.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
1219     puts.add(put);
1220 
1221     put = new Put(Bytes.toBytes("row1"));
1222     put.add(fam, qual2, 127l, value);
1223     put.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")|("
1224         + TOPSECRET + "&" + SECRET+")"));
1225     puts.add(put);
1226 
1227     Table table = new HTable(conf, tableName);
1228     table.put(puts);
1229     return table;
1230   }
1231 
1232   private Table doPutsWithoutVisibility(TableName tableName) throws IOException,
1233       InterruptedIOException, RetriesExhaustedWithDetailsException, InterruptedException {
1234     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
1235     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
1236     colDesc.setMaxVersions(5);
1237     HTableDescriptor desc = new HTableDescriptor(tableName);
1238     desc.addFamily(colDesc);
1239     hBaseAdmin.createTable(desc);
1240     List<Put> puts = new ArrayList<>();
1241     Put put = new Put(Bytes.toBytes("row1"));
1242     put.add(fam, qual, 123l, value);
1243     puts.add(put);
1244 
1245     put = new Put(Bytes.toBytes("row1"));
1246     put.add(fam, qual, 124l, value);
1247     puts.add(put);
1248 
1249     put = new Put(Bytes.toBytes("row1"));
1250     put.add(fam, qual, 125l, value);
1251     puts.add(put);
1252 
1253     put = new Put(Bytes.toBytes("row1"));
1254     put.add(fam, qual, 126l, value);
1255     puts.add(put);
1256 
1257     put = new Put(Bytes.toBytes("row1"));
1258     put.add(fam, qual, 127l, value);
1259     puts.add(put);
1260 
1261     Table table = new HTable(conf, tableName);
1262     table.put(puts);
1263 
1264     TEST_UTIL.getHBaseAdmin().flush(tableName);
1265 
1266     put = new Put(Bytes.toBytes("row2"));
1267     put.add(fam, qual, 127l, value);
1268     table.put(put);
1269 
1270     return table;
1271   }
1272 
1273 
1274   @Test
1275   public void testDeleteColumnWithSpecificTimeStampUsingMultipleVersionsUnMatchingVisExpression()
1276       throws Exception {
1277     setAuths();
1278     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
1279     try (Table table = doPuts(tableName)) {
1280       TEST_UTIL.getHBaseAdmin().flush(tableName);
1281       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
1282         @Override
1283         public Void run() throws Exception {
1284           try (Connection connection = ConnectionFactory.createConnection(conf);
1285                Table table = connection.getTable(tableName)) {
1286             Delete d = new Delete(row1);
1287             d.setCellVisibility(new CellVisibility("(" + PRIVATE + "&" + CONFIDENTIAL + ")|(" +
1288                 SECRET + "&" + TOPSECRET+")"));
1289             d.addColumn(fam, qual, 125l);
1290             table.delete(d);
1291           } catch (Throwable t) {
1292             throw new IOException(t);
1293           }
1294           return null;
1295         }
1296       };
1297       SUPERUSER.runAs(actiona);
1298 
1299       TEST_UTIL.getHBaseAdmin().flush(tableName);
1300       Scan s = new Scan();
1301       s.setMaxVersions(5);
1302       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
1303       ResultScanner scanner = table.getScanner(s);
1304       Result[] next = scanner.next(3);
1305       assertTrue(next.length == 2);
1306       CellScanner cellScanner = next[0].cellScanner();
1307       cellScanner.advance();
1308       Cell current = cellScanner.current();
1309       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1310           current.getRowLength(), row1, 0, row1.length));
1311       assertEquals(current.getTimestamp(), 127l);
1312       cellScanner.advance();
1313       current = cellScanner.current();
1314       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1315           current.getRowLength(), row1, 0, row1.length));
1316       assertEquals(current.getTimestamp(), 126l);
1317       cellScanner.advance();
1318       current = cellScanner.current();
1319       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1320           current.getRowLength(), row1, 0, row1.length));
1321       assertEquals(current.getTimestamp(), 125l);
1322       cellScanner.advance();
1323       current = cellScanner.current();
1324       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1325           current.getRowLength(), row1, 0, row1.length));
1326       assertEquals(current.getTimestamp(), 124l);
1327       cellScanner.advance();
1328       current = cellScanner.current();
1329       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1330           current.getRowLength(), row1, 0, row1.length));
1331       assertEquals(current.getTimestamp(), 123l);
1332       cellScanner = next[1].cellScanner();
1333       cellScanner.advance();
1334       current = cellScanner.current();
1335       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1336           current.getRowLength(), row2, 0, row2.length));
1337     }
1338   }
1339 
1340   @Test
1341   public void testDeleteColumnWithLatestTimeStampUsingMultipleVersions() throws Exception {
1342     setAuths();
1343     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
1344     try (Table table = doPuts(tableName)) {
1345       TEST_UTIL.getHBaseAdmin().flush(tableName);
1346       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
1347         @Override
1348         public Void run() throws Exception {
1349           try (Connection connection = ConnectionFactory.createConnection(conf);
1350                Table table = connection.getTable(tableName)) {
1351             Delete d = new Delete(row1);
1352             d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
1353             d.addColumn(fam, qual);
1354             table.delete(d);
1355           } catch (Throwable t) {
1356             throw new IOException(t);
1357           }
1358           return null;
1359         }
1360       };
1361       SUPERUSER.runAs(actiona);
1362 
1363       TEST_UTIL.getHBaseAdmin().flush(tableName);
1364       Scan s = new Scan();
1365       s.setMaxVersions(5);
1366       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
1367       ResultScanner scanner = table.getScanner(s);
1368       Result[] next = scanner.next(3);
1369       assertTrue(next.length == 2);
1370       CellScanner cellScanner = next[0].cellScanner();
1371       cellScanner.advance();
1372       Cell current = cellScanner.current();
1373       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1374           current.getRowLength(), row1, 0, row1.length));
1375       assertEquals(current.getTimestamp(), 127l);
1376       cellScanner.advance();
1377       current = cellScanner.current();
1378       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1379           current.getRowLength(), row1, 0, row1.length));
1380       assertEquals(current.getTimestamp(), 126l);
1381       cellScanner.advance();
1382       current = cellScanner.current();
1383       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1384           current.getRowLength(), row1, 0, row1.length));
1385       assertEquals(current.getTimestamp(), 124l);
1386       cellScanner.advance();
1387       current = cellScanner.current();
1388       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1389           current.getRowLength(), row1, 0, row1.length));
1390       assertEquals(current.getTimestamp(), 123l);
1391       cellScanner = next[1].cellScanner();
1392       cellScanner.advance();
1393       current = cellScanner.current();
1394       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1395           current.getRowLength(), row2, 0, row2.length));
1396     }
1397   }
1398 
1399   @Test (timeout=180000)
1400   public void testDeleteColumnWithLatestTimeStampWhenNoVersionMatches() throws Exception {
1401     setAuths();
1402     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
1403     try (Table table = doPuts(tableName)) {
1404       TEST_UTIL.getHBaseAdmin().flush(tableName);
1405       Put put = new Put(Bytes.toBytes("row1"));
1406       put.add(fam, qual, 128l, value);
1407       put.setCellVisibility(new CellVisibility(TOPSECRET));
1408       table.put(put);
1409       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
1410         @Override
1411         public Void run() throws Exception {
1412           try (Connection connection = ConnectionFactory.createConnection(conf);
1413                Table table = connection.getTable(tableName)) {
1414             Delete d = new Delete(row1);
1415             d.setCellVisibility(new CellVisibility(SECRET ));
1416             d.addColumn(fam, qual);
1417             table.delete(d);
1418           } catch (Throwable t) {
1419             throw new IOException(t);
1420           }
1421           return null;
1422         }
1423       };
1424       SUPERUSER.runAs(actiona);
1425 
1426       TEST_UTIL.getHBaseAdmin().flush(tableName);
1427       Scan s = new Scan();
1428       s.setMaxVersions(5);
1429       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
1430       ResultScanner scanner = table.getScanner(s);
1431       Result[] next = scanner.next(3);
1432       assertTrue(next.length == 2);
1433       CellScanner cellScanner = next[0].cellScanner();
1434       cellScanner.advance();
1435       Cell current = cellScanner.current();
1436       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1437           current.getRowLength(), row1, 0, row1.length));
1438       assertEquals(current.getTimestamp(), 128l);
1439       cellScanner.advance();
1440       current = cellScanner.current();
1441       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1442           current.getRowLength(), row1, 0, row1.length));
1443       assertEquals(current.getTimestamp(), 127l);
1444       cellScanner.advance();
1445       current = cellScanner.current();
1446       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1447           current.getRowLength(), row1, 0, row1.length));
1448       assertEquals(current.getTimestamp(), 126l);
1449       cellScanner.advance();
1450       current = cellScanner.current();
1451       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1452           current.getRowLength(), row1, 0, row1.length));
1453       assertEquals(current.getTimestamp(), 125l);
1454       cellScanner.advance();
1455       current = cellScanner.current();
1456       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1457           current.getRowLength(), row1, 0, row1.length));
1458       assertEquals(current.getTimestamp(), 124l);
1459       cellScanner = next[1].cellScanner();
1460       cellScanner.advance();
1461       current = cellScanner.current();
1462       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1463           current.getRowLength(), row2, 0, row2.length));
1464 
1465       put = new Put(Bytes.toBytes("row1"));
1466       put.add(fam, qual, 129l, value);
1467       put.setCellVisibility(new CellVisibility(SECRET));
1468       table.put(put);
1469 
1470       TEST_UTIL.getHBaseAdmin().flush(tableName);
1471       s = new Scan();
1472       s.setMaxVersions(5);
1473       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
1474       scanner = table.getScanner(s);
1475       next = scanner.next(3);
1476       assertTrue(next.length == 2);
1477       cellScanner = next[0].cellScanner();
1478       cellScanner.advance();
1479       current = cellScanner.current();
1480       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1481           current.getRowLength(), row1, 0, row1.length));
1482       assertEquals(current.getTimestamp(), 129l);
1483     }
1484   }
1485   @Test
1486   public void testDeleteColumnWithLatestTimeStampUsingMultipleVersionsAfterCompaction()
1487       throws Exception {
1488     setAuths();
1489     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
1490     try (Table table = doPuts(tableName)) {
1491       TEST_UTIL.getHBaseAdmin().flush(tableName);
1492       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
1493         @Override
1494         public Void run() throws Exception {
1495           try (Connection connection = ConnectionFactory.createConnection(conf);
1496                Table table = connection.getTable(tableName)) {
1497             Delete d = new Delete(row1);
1498             d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
1499             d.addColumn(fam, qual);
1500             table.delete(d);
1501           } catch (Throwable t) {
1502             throw new IOException(t);
1503           }
1504           return null;
1505         }
1506       };
1507       SUPERUSER.runAs(actiona);
1508       TEST_UTIL.getHBaseAdmin().flush(tableName);
1509       Put put = new Put(Bytes.toBytes("row3"));
1510       put.add(fam, qual, 127l, value);
1511       put.setCellVisibility(new CellVisibility(CONFIDENTIAL + "&" + PRIVATE));
1512       table.put(put);
1513       TEST_UTIL.getHBaseAdmin().flush(tableName);
1514       TEST_UTIL.getHBaseAdmin().majorCompact(tableName);
1515       // Sleep to ensure compaction happens. Need to do it in a better way
1516       Thread.sleep(5000);
1517       Scan s = new Scan();
1518       s.setMaxVersions(5);
1519       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
1520       ResultScanner scanner = table.getScanner(s);
1521       Result[] next = scanner.next(3);
1522       assertTrue(next.length == 3);
1523       CellScanner cellScanner = next[0].cellScanner();
1524       cellScanner.advance();
1525       Cell current = cellScanner.current();
1526       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1527           current.getRowLength(), row1, 0, row1.length));
1528       assertEquals(current.getTimestamp(), 127l);
1529       cellScanner.advance();
1530       current = cellScanner.current();
1531       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1532           current.getRowLength(), row1, 0, row1.length));
1533       assertEquals(current.getTimestamp(), 126l);
1534       cellScanner.advance();
1535       current = cellScanner.current();
1536       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1537           current.getRowLength(), row1, 0, row1.length));
1538       assertEquals(current.getTimestamp(), 124l);
1539       cellScanner.advance();
1540       current = cellScanner.current();
1541       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1542           current.getRowLength(), row1, 0, row1.length));
1543       assertEquals(current.getTimestamp(), 123l);
1544       cellScanner = next[1].cellScanner();
1545       cellScanner.advance();
1546       current = cellScanner.current();
1547       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1548           current.getRowLength(), row2, 0, row2.length));
1549     }
1550   }
1551 
1552   @Test
1553   public void testDeleteFamilyLatestTimeStampWithMulipleVersions() throws Exception {
1554     setAuths();
1555     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
1556     try (Table table = doPuts(tableName)) {
1557       TEST_UTIL.getHBaseAdmin().flush(tableName);
1558       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
1559         @Override
1560         public Void run() throws Exception {
1561           try (Connection connection = ConnectionFactory.createConnection(conf);
1562                Table table = connection.getTable(tableName)) {
1563             Delete d = new Delete(row1);
1564             d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
1565             d.addFamily(fam);
1566             table.delete(d);
1567           } catch (Throwable t) {
1568             throw new IOException(t);
1569           }
1570           return null;
1571         }
1572       };
1573       SUPERUSER.runAs(actiona);
1574 
1575       TEST_UTIL.getHBaseAdmin().flush(tableName);
1576       Scan s = new Scan();
1577       s.setMaxVersions(5);
1578       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
1579       ResultScanner scanner = table.getScanner(s);
1580       Result[] next = scanner.next(3);
1581       assertTrue(next.length == 2);
1582       CellScanner cellScanner = next[0].cellScanner();
1583       cellScanner.advance();
1584       Cell current = cellScanner.current();
1585       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1586           current.getRowLength(), row1, 0, row1.length));
1587       assertEquals(current.getTimestamp(), 127l);
1588       cellScanner.advance();
1589       current = cellScanner.current();
1590       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1591           current.getRowLength(), row1, 0, row1.length));
1592       assertEquals(current.getTimestamp(), 126l);
1593       cellScanner = next[1].cellScanner();
1594       cellScanner.advance();
1595       current = cellScanner.current();
1596       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1597           current.getRowLength(), row2, 0, row2.length));
1598     }
1599   }
1600 
1601   @Test
1602   public void testDeleteColumnswithMultipleColumnsWithMultipleVersions() throws Exception {
1603     setAuths();
1604     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
1605     try (Table table = doPutsWithDiffCols(tableName)) {
1606       TEST_UTIL.getHBaseAdmin().flush(tableName);
1607       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
1608         @Override
1609         public Void run() throws Exception {
1610           Delete d = new Delete(row1);
1611           d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
1612           d.addColumns(fam, qual, 125l);
1613           try (Connection connection = ConnectionFactory.createConnection(conf);
1614                Table table = connection.getTable(tableName)) {
1615             table.delete(d);
1616           } catch (Throwable t) {
1617             throw new IOException(t);
1618           }
1619           return null;
1620         }
1621       };
1622       SUPERUSER.runAs(actiona);
1623 
1624       TEST_UTIL.getHBaseAdmin().flush(tableName);
1625       Scan s = new Scan();
1626       s.setMaxVersions(5);
1627       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
1628       ResultScanner scanner = table.getScanner(s);
1629       Result[] next = scanner.next(3);
1630       assertTrue(next.length == 1);
1631       CellScanner cellScanner = next[0].cellScanner();
1632       cellScanner.advance();
1633       Cell current = cellScanner.current();
1634       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1635           current.getRowLength(), row1, 0, row1.length));
1636       assertEquals(current.getTimestamp(), 124l);
1637       cellScanner.advance();
1638       current = cellScanner.current();
1639       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1640           current.getRowLength(), row1, 0, row1.length));
1641       assertEquals(current.getTimestamp(), 123l);
1642       cellScanner.advance();
1643       current = cellScanner.current();
1644       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1645           current.getRowLength(), row1, 0, row1.length));
1646       assertTrue(Bytes.equals(current.getQualifierArray(), current.getQualifierOffset(),
1647           current.getQualifierLength(), qual1, 0, qual1.length));
1648       assertEquals(current.getTimestamp(), 126l);
1649       cellScanner.advance();
1650       current = cellScanner.current();
1651       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1652           current.getRowLength(), row1, 0, row1.length));
1653       assertEquals(current.getTimestamp(), 127l);
1654       assertTrue(Bytes.equals(current.getQualifierArray(), current.getQualifierOffset(),
1655           current.getQualifierLength(), qual2, 0, qual2.length));
1656     }
1657   }
1658 
1659   @Test
1660   public void testDeleteColumnsWithDiffColsAndTags() throws Exception {
1661     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
1662     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
1663     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
1664     colDesc.setMaxVersions(5);
1665     HTableDescriptor desc = new HTableDescriptor(tableName);
1666     desc.addFamily(colDesc);
1667     hBaseAdmin.createTable(desc);
1668     try (Table table = new HTable(conf, tableName)) {
1669       Put put = new Put(Bytes.toBytes("row1"));
1670       put.add(fam, qual1, 125l, value);
1671       put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
1672       table.put(put);
1673       put = new Put(Bytes.toBytes("row1"));
1674       put.add(fam, qual1, 126l, value);
1675       put.setCellVisibility(new CellVisibility(SECRET));
1676       table.put(put);
1677       TEST_UTIL.getHBaseAdmin().flush(tableName);
1678       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
1679         @Override
1680         public Void run() throws Exception {
1681           Delete d1 = new Delete(row1);
1682           d1.setCellVisibility(new CellVisibility(SECRET));
1683           d1.addColumns(fam, qual, 126l);
1684 
1685           Delete d2 = new Delete(row1);
1686           d2.setCellVisibility(new CellVisibility(CONFIDENTIAL));
1687           d2.addColumns(fam, qual1, 125l);
1688 
1689           try (Connection connection = ConnectionFactory.createConnection(conf);
1690                Table table = connection.getTable(tableName)) {
1691             table.delete(createList(d1, d2));
1692           } catch (Throwable t) {
1693             throw new IOException(t);
1694           }
1695           return null;
1696         }
1697       };
1698       SUPERUSER.runAs(actiona);
1699       Scan s = new Scan();
1700       s.setMaxVersions(5);
1701       s.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL));
1702       ResultScanner scanner = table.getScanner(s);
1703       Result[] next = scanner.next(3);
1704       assertEquals(next.length, 1);
1705     }
1706   }
1707   @Test
1708   public void testDeleteColumnsWithDiffColsAndTags1() throws Exception {
1709     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
1710     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
1711     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
1712     colDesc.setMaxVersions(5);
1713     HTableDescriptor desc = new HTableDescriptor(tableName);
1714     desc.addFamily(colDesc);
1715     hBaseAdmin.createTable(desc);
1716     try (Table table = new HTable(conf, tableName)) {
1717       Put put = new Put(Bytes.toBytes("row1"));
1718       put.add(fam, qual1, 125l, value);
1719       put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
1720       table.put(put);
1721       put = new Put(Bytes.toBytes("row1"));
1722       put.add(fam, qual1, 126l, value);
1723       put.setCellVisibility(new CellVisibility(SECRET));
1724       table.put(put);
1725       TEST_UTIL.getHBaseAdmin().flush(tableName);
1726       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
1727         @Override
1728         public Void run() throws Exception {
1729           Delete d1 = new Delete(row1);
1730           d1.setCellVisibility(new CellVisibility(SECRET));
1731           d1.addColumns(fam, qual, 126l);
1732 
1733           Delete d2 = new Delete(row1);
1734           d2.setCellVisibility(new CellVisibility(CONFIDENTIAL));
1735           d2.addColumns(fam, qual1, 126l);
1736 
1737           try (Connection connection = ConnectionFactory.createConnection(conf);
1738                Table table = connection.getTable(tableName)) {
1739             table.delete(createList(d1, d2));
1740           } catch (Throwable t) {
1741             throw new IOException(t);
1742           }
1743           return null;
1744         }
1745       };
1746       SUPERUSER.runAs(actiona);
1747       Scan s = new Scan();
1748       s.setMaxVersions(5);
1749       s.setAuthorizations(new Authorizations(SECRET, CONFIDENTIAL));
1750       ResultScanner scanner = table.getScanner(s);
1751       Result[] next = scanner.next(3);
1752       assertEquals(next.length, 1);
1753     }
1754   }
1755   @Test
1756   public void testDeleteFamilyWithoutCellVisibilityWithMulipleVersions() throws Exception {
1757     setAuths();
1758     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
1759     try (Table table = doPutsWithoutVisibility(tableName)) {
1760       TEST_UTIL.getHBaseAdmin().flush(tableName);
1761       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
1762         @Override
1763         public Void run() throws Exception {
1764           try (Connection connection = ConnectionFactory.createConnection(conf);
1765                Table table = connection.getTable(tableName)) {
1766             Delete d = new Delete(row1);
1767             d.addFamily(fam);
1768             table.delete(d);
1769           } catch (Throwable t) {
1770             throw new IOException(t);
1771           }
1772           return null;
1773         }
1774       };
1775       SUPERUSER.runAs(actiona);
1776 
1777       TEST_UTIL.getHBaseAdmin().flush(tableName);
1778       Scan s = new Scan();
1779       s.setMaxVersions(5);
1780       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
1781       ResultScanner scanner = table.getScanner(s);
1782       Result[] next = scanner.next(3);
1783       assertTrue(next.length == 1);
1784       // All cells wrt row1 should be deleted as we are not passing the Cell Visibility
1785       CellScanner cellScanner = next[0].cellScanner();
1786       cellScanner.advance();
1787       Cell current = cellScanner.current();
1788       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1789           current.getRowLength(), row2, 0, row2.length));
1790     }
1791   }
1792 
1793   @Test
1794   public void testDeleteFamilyLatestTimeStampWithMulipleVersionsWithoutCellVisibilityInPuts()
1795       throws Exception {
1796     setAuths();
1797     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
1798     try (Table table = doPutsWithoutVisibility(tableName)) {
1799       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
1800         @Override
1801         public Void run() throws Exception {
1802           try (Connection connection = ConnectionFactory.createConnection(conf);
1803                Table table = connection.getTable(tableName)) {
1804             Delete d = new Delete(row1);
1805             d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
1806             d.addFamily(fam);
1807             table.delete(d);
1808           } catch (Throwable t) {
1809             throw new IOException(t);
1810           }
1811           return null;
1812         }
1813       };
1814       SUPERUSER.runAs(actiona);
1815       TEST_UTIL.getHBaseAdmin().flush(tableName);
1816       Scan s = new Scan();
1817       s.setMaxVersions(5);
1818       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
1819       ResultScanner scanner = table.getScanner(s);
1820       Result[] next = scanner.next(3);
1821       assertTrue(next.length == 2);
1822       CellScanner cellScanner = next[0].cellScanner();
1823       cellScanner.advance();
1824       Cell current = cellScanner.current();
1825       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1826           current.getRowLength(), row1, 0, row1.length));
1827       assertEquals(current.getTimestamp(), 127l);
1828       cellScanner.advance();
1829       current = cellScanner.current();
1830       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1831           current.getRowLength(), row1, 0, row1.length));
1832       assertEquals(current.getTimestamp(), 126l);
1833       cellScanner.advance();
1834       current = cellScanner.current();
1835       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1836           current.getRowLength(), row1, 0, row1.length));
1837       assertEquals(current.getTimestamp(), 125l);
1838       cellScanner.advance();
1839       current = cellScanner.current();
1840       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1841           current.getRowLength(), row1, 0, row1.length));
1842       assertEquals(current.getTimestamp(), 124l);
1843       cellScanner.advance();
1844       current = cellScanner.current();
1845       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1846           current.getRowLength(), row1, 0, row1.length));
1847       assertEquals(current.getTimestamp(), 123l);
1848       cellScanner = next[1].cellScanner();
1849       cellScanner.advance();
1850       current = cellScanner.current();
1851       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1852           current.getRowLength(), row2, 0, row2.length));
1853     }
1854   }
1855 
1856   @Test
1857   public void testDeleteFamilySpecificTimeStampWithMulipleVersions() throws Exception {
1858     setAuths();
1859     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
1860     try (Table table = doPuts(tableName)) {
1861       TEST_UTIL.getHBaseAdmin().flush(tableName);
1862       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
1863         @Override
1864         public Void run() throws Exception {
1865           try (Connection connection = ConnectionFactory.createConnection(conf);
1866                Table table = connection.getTable(tableName)) {
1867             Delete d = new Delete(row1);
1868             d.setCellVisibility(new CellVisibility("(" + PRIVATE + "&" + CONFIDENTIAL + ")|("
1869                 + SECRET + "&" + TOPSECRET + ")"));
1870             d.addFamily(fam, 126l);
1871             table.delete(d);
1872           } catch (Throwable t) {
1873             throw new IOException(t);
1874           }
1875           return null;
1876         }
1877       };
1878       SUPERUSER.runAs(actiona);
1879 
1880       TEST_UTIL.getHBaseAdmin().flush(tableName);
1881       Scan s = new Scan();
1882       s.setMaxVersions(5);
1883       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
1884       ResultScanner scanner = table.getScanner(s);
1885       Result[] next = scanner.next(6);
1886       assertTrue(next.length == 2);
1887       CellScanner cellScanner = next[0].cellScanner();
1888       cellScanner.advance();
1889       Cell current = cellScanner.current();
1890       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1891           current.getRowLength(), row1, 0, row1.length));
1892       assertEquals(current.getTimestamp(), 127l);
1893       cellScanner.advance();
1894       current = cellScanner.current();
1895       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1896           current.getRowLength(), row1, 0, row1.length));
1897       assertEquals(current.getTimestamp(), 125l);
1898       cellScanner.advance();
1899       current = cellScanner.current();
1900       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1901           current.getRowLength(), row1, 0, row1.length));
1902       assertEquals(current.getTimestamp(), 123l);
1903       cellScanner = next[1].cellScanner();
1904       cellScanner.advance();
1905       current = cellScanner.current();
1906       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1907           current.getRowLength(), row2, 0, row2.length));
1908     }
1909   }
1910 
1911   @Test
1912   public void testScanAfterCompaction() throws Exception {
1913     setAuths();
1914     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
1915     try (Table table = doPuts(tableName)) {
1916       TEST_UTIL.getHBaseAdmin().flush(tableName);
1917       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
1918         @Override
1919         public Void run() throws Exception {
1920           try (Connection connection = ConnectionFactory.createConnection(conf);
1921                Table table = connection.getTable(tableName)) {
1922             Delete d = new Delete(row1);
1923             d.setCellVisibility(new CellVisibility("(" + PRIVATE + "&" + CONFIDENTIAL + ")|(" +
1924                 SECRET + "&" + TOPSECRET+")"));
1925             d.addFamily(fam, 126l);
1926             table.delete(d);
1927           } catch (Throwable t) {
1928             throw new IOException(t);
1929           }
1930           return null;
1931         }
1932       };
1933       SUPERUSER.runAs(actiona);
1934 
1935       TEST_UTIL.getHBaseAdmin().flush(tableName);
1936       Put put = new Put(Bytes.toBytes("row3"));
1937       put.add(fam, qual, 127l, value);
1938       put.setCellVisibility(new CellVisibility(CONFIDENTIAL + "&" + PRIVATE));
1939       table.put(put);
1940       TEST_UTIL.getHBaseAdmin().flush(tableName);
1941       TEST_UTIL.getHBaseAdmin().compact(tableName);
1942       Thread.sleep(5000);
1943       // Sleep to ensure compaction happens. Need to do it in a better way
1944       Scan s = new Scan();
1945       s.setMaxVersions(5);
1946       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
1947       ResultScanner scanner = table.getScanner(s);
1948       Result[] next = scanner.next(3);
1949       assertTrue(next.length == 3);
1950       CellScanner cellScanner = next[0].cellScanner();
1951       cellScanner.advance();
1952       Cell current = cellScanner.current();
1953       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1954           current.getRowLength(), row1, 0, row1.length));
1955       assertEquals(current.getTimestamp(), 127l);
1956       cellScanner = next[1].cellScanner();
1957       cellScanner.advance();
1958       current = cellScanner.current();
1959       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1960           current.getRowLength(), row2, 0, row2.length));
1961     }
1962   }
1963 
1964   @Test
1965   public void testDeleteFamilySpecificTimeStampWithMulipleVersionsDoneTwice() throws Exception {
1966     setAuths();
1967     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
1968     // Do not flush here.
1969     try (Table table = doPuts(tableName)) {
1970       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
1971         @Override
1972         public Void run() throws Exception {
1973           try (Connection connection = ConnectionFactory.createConnection(conf);
1974                Table table = connection.getTable(tableName)) {
1975             Delete d = new Delete(row1);
1976             d.setCellVisibility(new CellVisibility("(" + PRIVATE + "&" + CONFIDENTIAL + ")|("
1977                 + TOPSECRET + "&" + SECRET+")"));
1978             d.addFamily(fam, 125l);
1979             table.delete(d);
1980           } catch (Throwable t) {
1981             throw new IOException(t);
1982           }
1983           return null;
1984         }
1985       };
1986       SUPERUSER.runAs(actiona);
1987 
1988       Scan s = new Scan();
1989       s.setMaxVersions(5);
1990       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
1991       ResultScanner scanner = table.getScanner(s);
1992       Result[] next = scanner.next(3);
1993       assertTrue(next.length == 2);
1994       CellScanner cellScanner = next[0].cellScanner();
1995       cellScanner.advance();
1996       Cell current = cellScanner.current();
1997       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
1998           current.getRowLength(), row1, 0, row1.length));
1999       assertEquals(current.getTimestamp(), 127l);
2000       cellScanner.advance();
2001       current = cellScanner.current();
2002       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2003           current.getRowLength(), row1, 0, row1.length));
2004       assertEquals(current.getTimestamp(), 126l);
2005       cellScanner.advance();
2006       current = cellScanner.current();
2007       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2008           current.getRowLength(), row1, 0, row1.length));
2009       assertEquals(current.getTimestamp(), 125l);
2010       cellScanner.advance();
2011       current = cellScanner.current();
2012       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2013           current.getRowLength(), row1, 0, row1.length));
2014       assertEquals(current.getTimestamp(), 123l);
2015       cellScanner = next[1].cellScanner();
2016       cellScanner.advance();
2017       current = cellScanner.current();
2018       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2019           current.getRowLength(), row2, 0, row2.length));
2020 
2021       // Issue 2nd delete
2022       actiona = new PrivilegedExceptionAction<Void>() {
2023         @Override
2024         public Void run() throws Exception {
2025           try (Connection connection = ConnectionFactory.createConnection(conf);
2026                Table table = connection.getTable(tableName)) {
2027             Delete d = new Delete(row1);
2028             d.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")|("
2029                 + TOPSECRET + "&" + SECRET+")"));
2030             d.addFamily(fam, 127l);
2031             table.delete(d);
2032           } catch (Throwable t) {
2033             throw new IOException(t);
2034           }
2035           return null;
2036         }
2037       };
2038       SUPERUSER.runAs(actiona);
2039       s = new Scan();
2040       s.setMaxVersions(5);
2041       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2042       scanner = table.getScanner(s);
2043       next = scanner.next(3);
2044       assertTrue(next.length == 2);
2045       cellScanner = next[0].cellScanner();
2046       cellScanner.advance();
2047       current = cellScanner.current();
2048       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2049           current.getRowLength(), row1, 0, row1.length));
2050       assertEquals(current.getTimestamp(), 125l);
2051       cellScanner.advance();
2052       current = cellScanner.current();
2053       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2054           current.getRowLength(), row1, 0, row1.length));
2055       assertEquals(current.getTimestamp(), 123l);
2056       cellScanner = next[1].cellScanner();
2057       cellScanner.advance();
2058       current = cellScanner.current();
2059       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2060           current.getRowLength(), row2, 0, row2.length));
2061       assertEquals(current.getTimestamp(), 127l);
2062     }
2063   }
2064 
2065   @Test
2066   public void testMultipleDeleteFamilyVersionWithDiffLabels() throws Exception {
2067     PrivilegedExceptionAction<VisibilityLabelsResponse> action =
2068         new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
2069       @Override
2070       public VisibilityLabelsResponse run() throws Exception {
2071         try {
2072           return VisibilityClient.setAuths(conf, new String[] { CONFIDENTIAL, PRIVATE, SECRET },
2073               SUPERUSER.getShortName());
2074         } catch (Throwable e) {
2075         }
2076         return null;
2077       }
2078     };
2079     VisibilityLabelsResponse response = SUPERUSER.runAs(action);
2080     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
2081     try (Table table = doPuts(tableName);) {
2082       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
2083         @Override
2084         public Void run() throws Exception {
2085           try (Connection connection = ConnectionFactory.createConnection(conf);
2086                Table table = connection.getTable(tableName)) {
2087             Delete d = new Delete(row1);
2088             d.setCellVisibility(new CellVisibility(CONFIDENTIAL));
2089             d.deleteFamilyVersion(fam, 123l);
2090             table.delete(d);
2091             d = new Delete(row1);
2092             d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
2093             d.deleteFamilyVersion(fam, 125l);
2094             table.delete(d);
2095           } catch (Throwable t) {
2096             throw new IOException(t);
2097           }
2098           return null;
2099         }
2100       };
2101       SUPERUSER.runAs(actiona);
2102 
2103       TEST_UTIL.getHBaseAdmin().flush(tableName);
2104       Scan s = new Scan();
2105       s.setMaxVersions(5);
2106       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2107       ResultScanner scanner = table.getScanner(s);
2108       Result[] next = scanner.next(5);
2109       assertTrue(next.length == 2);
2110       CellScanner cellScanner = next[0].cellScanner();
2111       cellScanner.advance();
2112       Cell current = cellScanner.current();
2113       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2114           current.getRowLength(), row1, 0, row1.length));
2115       assertEquals(current.getTimestamp(), 127l);
2116       cellScanner.advance();
2117       current = cellScanner.current();
2118       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2119           current.getRowLength(), row1, 0, row1.length));
2120       assertEquals(current.getTimestamp(), 126l);
2121       cellScanner.advance();
2122       current = cellScanner.current();
2123       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2124           current.getRowLength(), row1, 0, row1.length));
2125       assertEquals(current.getTimestamp(), 124l);
2126     }
2127   }
2128 
2129   @Test (timeout=180000)
2130   public void testSpecificDeletesFollowedByDeleteFamily() throws Exception {
2131     setAuths();
2132     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
2133     try (Table table = doPuts(tableName)){
2134       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
2135         @Override
2136         public Void run() throws Exception {
2137           try (Connection connection = ConnectionFactory.createConnection(conf);
2138                Table table = connection.getTable(tableName)) {
2139             Delete d = new Delete(row1);
2140             d.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")|("
2141                 + TOPSECRET + "&" + SECRET + ")"));
2142             d.addColumn(fam, qual, 126l);
2143             table.delete(d);
2144             d = new Delete(row1);
2145             d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
2146             d.deleteFamilyVersion(fam, 125l);
2147             table.delete(d);
2148           } catch (Throwable t) {
2149             throw new IOException(t);
2150           }
2151           return null;
2152         }
2153       };
2154       SUPERUSER.runAs(actiona);
2155 
2156       TEST_UTIL.getHBaseAdmin().flush(tableName);
2157       Scan s = new Scan();
2158       s.setMaxVersions(5);
2159       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2160       ResultScanner scanner = table.getScanner(s);
2161       Result[] next = scanner.next(5);
2162       assertTrue(next.length == 2);
2163       CellScanner cellScanner = next[0].cellScanner();
2164       cellScanner.advance();
2165       Cell current = cellScanner.current();
2166       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2167           current.getRowLength(), row1, 0, row1.length));
2168       assertEquals(current.getTimestamp(), 127l);
2169       cellScanner.advance();
2170       current = cellScanner.current();
2171       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2172           current.getRowLength(), row1, 0, row1.length));
2173       assertEquals(current.getTimestamp(), 124l);
2174       cellScanner.advance();
2175       current = cellScanner.current();
2176       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2177           current.getRowLength(), row1, 0, row1.length));
2178       assertEquals(current.getTimestamp(), 123l);
2179       // Issue 2nd delete
2180       actiona = new PrivilegedExceptionAction<Void>() {
2181         @Override
2182         public Void run() throws Exception {
2183           try (Connection connection = ConnectionFactory.createConnection(conf);
2184                Table table = connection.getTable(tableName)) {
2185             Delete d = new Delete(row1);
2186             d.setCellVisibility(new CellVisibility(CONFIDENTIAL));
2187             d.addFamily(fam);
2188             table.delete(d);
2189           } catch (Throwable t) {
2190             throw new IOException(t);
2191           }
2192           return null;
2193         }
2194       };
2195       SUPERUSER.runAs(actiona);
2196       s = new Scan();
2197       s.setMaxVersions(5);
2198       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2199       scanner = table.getScanner(s);
2200       next = scanner.next(5);
2201       assertTrue(next.length == 2);
2202       cellScanner = next[0].cellScanner();
2203       cellScanner.advance();
2204       current = cellScanner.current();
2205       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2206           current.getRowLength(), row1, 0, row1.length));
2207       assertEquals(current.getTimestamp(), 127l);
2208       cellScanner.advance();
2209       current = cellScanner.current();
2210       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2211           current.getRowLength(), row1, 0, row1.length));
2212       assertEquals(current.getTimestamp(), 124l);
2213     }
2214   }
2215 
2216   @Test(timeout = 180000)
2217   public void testSpecificDeletesFollowedByDeleteFamily1() throws Exception {
2218     PrivilegedExceptionAction<VisibilityLabelsResponse> action =
2219         new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
2220       @Override
2221       public VisibilityLabelsResponse run() throws Exception {
2222         try {
2223           return VisibilityClient.setAuths(conf, new String[] { CONFIDENTIAL, PRIVATE, SECRET },
2224               SUPERUSER.getShortName());
2225         } catch (Throwable e) {
2226         }
2227         return null;
2228       }
2229     };
2230     VisibilityLabelsResponse response = SUPERUSER.runAs(action);
2231     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
2232     try (Table table = doPuts(tableName)){
2233       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
2234         @Override
2235         public Void run() throws Exception {
2236           try (Connection connection = ConnectionFactory.createConnection(conf);
2237                Table table = connection.getTable(tableName)) {
2238             Delete d = new Delete(row1);
2239             d.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")|("
2240                 + TOPSECRET + "&" + SECRET + ")"));
2241             d.addColumn(fam, qual);
2242             table.delete(d);
2243 
2244             d = new Delete(row1);
2245             d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
2246             d.deleteFamilyVersion(fam, 125l);
2247             table.delete(d);
2248           } catch (Throwable t) {
2249             throw new IOException(t);
2250           }
2251           return null;
2252         }
2253       };
2254       SUPERUSER.runAs(actiona);
2255 
2256       TEST_UTIL.getHBaseAdmin().flush(tableName);
2257       Scan s = new Scan();
2258       s.setMaxVersions(5);
2259       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2260       ResultScanner scanner = table.getScanner(s);
2261       Result[] next = scanner.next(5);
2262       assertTrue(next.length == 2);
2263       CellScanner cellScanner = next[0].cellScanner();
2264       cellScanner.advance();
2265       Cell current = cellScanner.current();
2266       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2267           current.getRowLength(), row1, 0, row1.length));
2268       assertEquals(current.getTimestamp(), 126l);
2269       cellScanner.advance();
2270       current = cellScanner.current();
2271       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2272           current.getRowLength(), row1, 0, row1.length));
2273       assertEquals(current.getTimestamp(), 124l);
2274       cellScanner.advance();
2275       current = cellScanner.current();
2276       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2277           current.getRowLength(), row1, 0, row1.length));
2278       assertEquals(current.getTimestamp(), 123l);
2279       // Issue 2nd delete
2280       actiona = new PrivilegedExceptionAction<Void>() {
2281         @Override
2282         public Void run() throws Exception {
2283           try (Connection connection = ConnectionFactory.createConnection(conf);
2284                Table table = connection.getTable(tableName)) {
2285             Delete d = new Delete(row1);
2286             d.setCellVisibility(new CellVisibility(CONFIDENTIAL));
2287             d.addFamily(fam);
2288             table.delete(d);
2289           } catch (Throwable t) {
2290             throw new IOException(t);
2291           }
2292           return null;
2293         }
2294       };
2295       SUPERUSER.runAs(actiona);
2296       s = new Scan();
2297       s.setMaxVersions(5);
2298       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2299       scanner = table.getScanner(s);
2300       next = scanner.next(5);
2301       assertTrue(next.length == 2);
2302       cellScanner = next[0].cellScanner();
2303       cellScanner.advance();
2304       current = cellScanner.current();
2305       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2306           current.getRowLength(), row1, 0, row1.length));
2307       assertEquals(current.getTimestamp(), 126l);
2308       cellScanner.advance();
2309       current = cellScanner.current();
2310       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2311           current.getRowLength(), row1, 0, row1.length));
2312       assertEquals(current.getTimestamp(), 124l);
2313     }
2314   }
2315 
2316   @Test
2317   public void testDeleteColumnSpecificTimeStampWithMulipleVersionsDoneTwice() throws Exception {
2318     setAuths();
2319     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
2320     try (Table table = doPuts(tableName)) {
2321       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
2322         @Override
2323         public Void run() throws Exception {
2324           try (Connection connection = ConnectionFactory.createConnection(conf);
2325                Table table = connection.getTable(tableName)) {
2326             Delete d = new Delete(row1);
2327             d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
2328             d.addColumn(fam, qual, 125l);
2329             table.delete(d);
2330           } catch (Throwable t) {
2331             throw new IOException(t);
2332           }
2333           return null;
2334         }
2335       };
2336       SUPERUSER.runAs(actiona);
2337 
2338       Scan s = new Scan();
2339       s.setMaxVersions(5);
2340       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2341       ResultScanner scanner = table.getScanner(s);
2342       Result[] next = scanner.next(3);
2343       assertTrue(next.length == 2);
2344       CellScanner cellScanner = next[0].cellScanner();
2345       cellScanner.advance();
2346       Cell current = cellScanner.current();
2347       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2348           current.getRowLength(), row1, 0, row1.length));
2349       assertEquals(current.getTimestamp(), 127l);
2350       cellScanner.advance();
2351       current = cellScanner.current();
2352       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2353           current.getRowLength(), row1, 0, row1.length));
2354       assertEquals(current.getTimestamp(), 126l);
2355       cellScanner.advance();
2356       current = cellScanner.current();
2357       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2358           current.getRowLength(), row1, 0, row1.length));
2359       assertEquals(current.getTimestamp(), 124l);
2360       cellScanner.advance();
2361       current = cellScanner.current();
2362       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2363           current.getRowLength(), row1, 0, row1.length));
2364       assertEquals(current.getTimestamp(), 123l);
2365       cellScanner = next[1].cellScanner();
2366       cellScanner.advance();
2367       current = cellScanner.current();
2368       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2369           current.getRowLength(), row2, 0, row2.length));
2370 
2371       // Issue 2nd delete
2372       actiona = new PrivilegedExceptionAction<Void>() {
2373         @Override
2374         public Void run() throws Exception {
2375           try (Connection connection = ConnectionFactory.createConnection(conf);
2376                Table table = connection.getTable(tableName)) {
2377             Delete d = new Delete(row1);
2378             d.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")|("
2379                 + TOPSECRET + "&" + SECRET+")"));
2380             d.addColumn(fam, qual, 127l);
2381             table.delete(d);
2382           } catch (Throwable t) {
2383             throw new IOException(t);
2384           }
2385           return null;
2386         }
2387       };
2388       SUPERUSER.runAs(actiona);
2389       s = new Scan();
2390       s.setMaxVersions(5);
2391       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2392       scanner = table.getScanner(s);
2393       next = scanner.next(3);
2394       assertTrue(next.length == 2);
2395       cellScanner = next[0].cellScanner();
2396       cellScanner.advance();
2397       current = cellScanner.current();
2398       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2399           current.getRowLength(), row1, 0, row1.length));
2400       assertEquals(current.getTimestamp(), 126l);
2401       cellScanner.advance();
2402       current = cellScanner.current();
2403       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2404           current.getRowLength(), row1, 0, row1.length));
2405       assertEquals(current.getTimestamp(), 124l);
2406       cellScanner.advance();
2407       current = cellScanner.current();
2408       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2409           current.getRowLength(), row1, 0, row1.length));
2410       assertEquals(current.getTimestamp(), 123l);
2411       cellScanner = next[1].cellScanner();
2412       cellScanner.advance();
2413       current = cellScanner.current();
2414       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2415           current.getRowLength(), row2, 0, row2.length));
2416       assertEquals(current.getTimestamp(), 127l);
2417     }
2418   }
2419 
2420   @Test
2421   public void testDeleteColumnSpecificTimeStampWithMulipleVersionsDoneTwice1() throws Exception {
2422     setAuths();
2423     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
2424     // Do not flush here.
2425     try (Table table = doPuts(tableName)) {
2426       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
2427         @Override
2428         public Void run() throws Exception {
2429           try (Connection connection = ConnectionFactory.createConnection(conf);
2430                Table table = connection.getTable(tableName)) {
2431             Delete d = new Delete(row1);
2432             d.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")" +
2433                 "|(" + TOPSECRET + "&" + SECRET + ")"));
2434             d.addColumn(fam, qual, 127l);
2435             table.delete(d);
2436           } catch (Throwable t) {
2437             throw new IOException(t);
2438           }
2439           return null;
2440         }
2441       };
2442       SUPERUSER.runAs(actiona);
2443 
2444       Scan s = new Scan();
2445       s.setMaxVersions(5);
2446       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2447       ResultScanner scanner = table.getScanner(s);
2448       Result[] next = scanner.next(3);
2449       assertTrue(next.length == 2);
2450       CellScanner cellScanner = next[0].cellScanner();
2451       cellScanner.advance();
2452       Cell current = cellScanner.current();
2453       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2454           current.getRowLength(), row1, 0, row1.length));
2455       assertEquals(current.getTimestamp(), 126l);
2456       cellScanner.advance();
2457       current = cellScanner.current();
2458       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2459           current.getRowLength(), row1, 0, row1.length));
2460       assertEquals(current.getTimestamp(), 125l);
2461       cellScanner.advance();
2462       current = cellScanner.current();
2463       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2464           current.getRowLength(), row1, 0, row1.length));
2465       assertEquals(current.getTimestamp(), 124l);
2466       cellScanner.advance();
2467       current = cellScanner.current();
2468       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2469           current.getRowLength(), row1, 0, row1.length));
2470       assertEquals(current.getTimestamp(), 123l);
2471       cellScanner = next[1].cellScanner();
2472       cellScanner.advance();
2473       current = cellScanner.current();
2474       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2475           current.getRowLength(), row2, 0, row2.length));
2476 
2477       // Issue 2nd delete
2478       actiona = new PrivilegedExceptionAction<Void>() {
2479         @Override
2480         public Void run() throws Exception {
2481           try (Connection connection = ConnectionFactory.createConnection(conf);
2482                Table table = connection.getTable(tableName)) {
2483             Delete d = new Delete(row1);
2484             d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
2485             d.addColumn(fam, qual, 127l);
2486             table.delete(d);
2487           } catch (Throwable t) {
2488             throw new IOException(t);
2489           }
2490           return null;
2491         }
2492       };
2493       SUPERUSER.runAs(actiona);
2494       s = new Scan();
2495       s.setMaxVersions(5);
2496       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2497       scanner = table.getScanner(s);
2498       next = scanner.next(3);
2499       assertTrue(next.length == 2);
2500       cellScanner = next[0].cellScanner();
2501       cellScanner.advance();
2502       current = cellScanner.current();
2503       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2504           current.getRowLength(), row1, 0, row1.length));
2505       assertEquals(current.getTimestamp(), 126l);
2506       cellScanner.advance();
2507       current = cellScanner.current();
2508       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2509           current.getRowLength(), row1, 0, row1.length));
2510       assertEquals(current.getTimestamp(), 125l);
2511       cellScanner.advance();
2512       current = cellScanner.current();
2513       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2514           current.getRowLength(), row1, 0, row1.length));
2515       assertEquals(current.getTimestamp(), 124l);
2516       cellScanner.advance();
2517       current = cellScanner.current();
2518       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2519           current.getRowLength(), row1, 0, row1.length));
2520       assertEquals(current.getTimestamp(), 123l);
2521       cellScanner = next[1].cellScanner();
2522       cellScanner.advance();
2523       current = cellScanner.current();
2524       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2525           current.getRowLength(), row2, 0, row2.length));
2526       assertEquals(current.getTimestamp(), 127l);
2527     }
2528   }
2529   @Test
2530   public void testDeleteColumnSpecificTimeStampWithMulipleVersionsDoneTwice2() throws Exception {
2531     setAuths();
2532     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
2533 
2534     // Do not flush here.
2535     try (Table table = doPuts(tableName)) {
2536       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
2537         @Override
2538         public Void run() throws Exception {
2539           try (Connection connection = ConnectionFactory.createConnection(conf);
2540                Table table = connection.getTable(tableName)) {
2541             Delete d = new Delete(row1);
2542             d.setCellVisibility(new CellVisibility("(" + PRIVATE + "&" + CONFIDENTIAL + ")|("
2543                 + TOPSECRET + "&" + SECRET+")"));
2544             d.addColumn(fam, qual, 125l);
2545             table.delete(d);
2546           } catch (Throwable t) {
2547             throw new IOException(t);
2548           }
2549           return null;
2550         }
2551       };
2552       SUPERUSER.runAs(actiona);
2553 
2554       Scan s = new Scan();
2555       s.setMaxVersions(5);
2556       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2557       ResultScanner scanner = table.getScanner(s);
2558       Result[] next = scanner.next(3);
2559       assertTrue(next.length == 2);
2560       CellScanner cellScanner = next[0].cellScanner();
2561       cellScanner.advance();
2562       Cell current = cellScanner.current();
2563       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2564           current.getRowLength(), row1, 0, row1.length));
2565       assertEquals(current.getTimestamp(), 127l);
2566       cellScanner.advance();
2567       current = cellScanner.current();
2568       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2569           current.getRowLength(), row1, 0, row1.length));
2570       assertEquals(current.getTimestamp(), 126l);
2571       cellScanner.advance();
2572       current = cellScanner.current();
2573       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2574           current.getRowLength(), row1, 0, row1.length));
2575       assertEquals(current.getTimestamp(), 125l);
2576       cellScanner.advance();
2577       current = cellScanner.current();
2578       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2579           current.getRowLength(), row1, 0, row1.length));
2580       assertEquals(current.getTimestamp(), 124l);
2581       cellScanner.advance();
2582       current = cellScanner.current();
2583       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2584           current.getRowLength(), row1, 0, row1.length));
2585       assertEquals(current.getTimestamp(), 123l);
2586       cellScanner = next[1].cellScanner();
2587       cellScanner.advance();
2588       current = cellScanner.current();
2589       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2590           current.getRowLength(), row2, 0, row2.length));
2591 
2592       // Issue 2nd delete
2593       actiona = new PrivilegedExceptionAction<Void>() {
2594         @Override
2595         public Void run() throws Exception {
2596           try (Connection connection = ConnectionFactory.createConnection(conf);
2597                Table table = connection.getTable(tableName)) {
2598             Delete d = new Delete(row1);
2599             d.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")|("
2600                 + TOPSECRET + "&" + SECRET+")"));
2601             d.addColumn(fam, qual, 127l);
2602             table.delete(d);
2603           } catch (Throwable t) {
2604             throw new IOException(t);
2605           }
2606           return null;
2607         }
2608       };
2609       SUPERUSER.runAs(actiona);
2610       s = new Scan();
2611       s.setMaxVersions(5);
2612       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2613       scanner = table.getScanner(s);
2614       next = scanner.next(3);
2615       assertTrue(next.length == 2);
2616       cellScanner = next[0].cellScanner();
2617       cellScanner.advance();
2618       current = cellScanner.current();
2619       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2620           current.getRowLength(), row1, 0, row1.length));
2621       assertEquals(current.getTimestamp(), 126l);
2622       cellScanner.advance();
2623       current = cellScanner.current();
2624       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2625           current.getRowLength(), row1, 0, row1.length));
2626       assertEquals(current.getTimestamp(), 125l);
2627       cellScanner.advance();
2628       current = cellScanner.current();
2629       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2630           current.getRowLength(), row1, 0, row1.length));
2631       assertEquals(current.getTimestamp(), 124l);
2632       cellScanner.advance();
2633       current = cellScanner.current();
2634       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2635           current.getRowLength(), row1, 0, row1.length));
2636       assertEquals(current.getTimestamp(), 123l);
2637       cellScanner = next[1].cellScanner();
2638       cellScanner.advance();
2639       current = cellScanner.current();
2640       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2641           current.getRowLength(), row2, 0, row2.length));
2642       assertEquals(current.getTimestamp(), 127l);
2643     }
2644   }
2645   @Test
2646   public void testDeleteColumnAndDeleteFamilylSpecificTimeStampWithMulipleVersion()
2647       throws Exception {
2648     setAuths();
2649     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
2650     // Do not flush here.
2651     try (Table table = doPuts(tableName)) {
2652       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
2653         @Override
2654         public Void run() throws Exception {
2655           try (Connection connection = ConnectionFactory.createConnection(conf);
2656                Table table = connection.getTable(tableName)) {
2657             Delete d = new Delete(row1);
2658             d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
2659             d.addColumn(fam, qual, 125l);
2660             table.delete(d);
2661           } catch (Throwable t) {
2662             throw new IOException(t);
2663           }
2664           return null;
2665         }
2666       };
2667       SUPERUSER.runAs(actiona);
2668 
2669       Scan s = new Scan();
2670       s.setMaxVersions(5);
2671       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2672       ResultScanner scanner = table.getScanner(s);
2673       Result[] next = scanner.next(3);
2674       assertTrue(next.length == 2);
2675       CellScanner cellScanner = next[0].cellScanner();
2676       cellScanner.advance();
2677       Cell current = cellScanner.current();
2678       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2679           current.getRowLength(), row1, 0, row1.length));
2680       assertEquals(current.getTimestamp(), 127l);
2681       cellScanner.advance();
2682       current = cellScanner.current();
2683       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2684           current.getRowLength(), row1, 0, row1.length));
2685       assertEquals(current.getTimestamp(), 126l);
2686       cellScanner.advance();
2687       current = cellScanner.current();
2688       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2689           current.getRowLength(), row1, 0, row1.length));
2690       assertEquals(current.getTimestamp(), 124l);
2691       cellScanner.advance();
2692       current = cellScanner.current();
2693       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2694           current.getRowLength(), row1, 0, row1.length));
2695       assertEquals(current.getTimestamp(), 123l);
2696       cellScanner = next[1].cellScanner();
2697       cellScanner.advance();
2698       current = cellScanner.current();
2699       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2700           current.getRowLength(), row2, 0, row2.length));
2701 
2702       // Issue 2nd delete
2703       actiona = new PrivilegedExceptionAction<Void>() {
2704         @Override
2705         public Void run() throws Exception {
2706           try (Connection connection = ConnectionFactory.createConnection(conf);
2707                Table table = connection.getTable(tableName)) {
2708             Delete d = new Delete(row1);
2709             d.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")|("
2710                 + TOPSECRET + "&" + SECRET+")"));
2711             d.addFamily(fam, 124l);
2712             table.delete(d);
2713           } catch (Throwable t) {
2714             throw new IOException(t);
2715           }
2716           return null;
2717         }
2718       };
2719       SUPERUSER.runAs(actiona);
2720       s = new Scan();
2721       s.setMaxVersions(5);
2722       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2723       scanner = table.getScanner(s);
2724       next = scanner.next(3);
2725       assertTrue(next.length == 2);
2726       cellScanner = next[0].cellScanner();
2727       cellScanner.advance();
2728       current = cellScanner.current();
2729       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2730           current.getRowLength(), row1, 0, row1.length));
2731       assertEquals(current.getTimestamp(), 127l);
2732       cellScanner.advance();
2733       current = cellScanner.current();
2734       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2735           current.getRowLength(), row1, 0, row1.length));
2736       assertEquals(current.getTimestamp(), 126l);
2737       cellScanner = next[1].cellScanner();
2738       cellScanner.advance();
2739       current = cellScanner.current();
2740       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2741           current.getRowLength(), row2, 0, row2.length));
2742       assertEquals(current.getTimestamp(), 127l);
2743     }
2744   }
2745 
2746   private void setAuths() throws IOException, InterruptedException {
2747     PrivilegedExceptionAction<VisibilityLabelsResponse> action =
2748         new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
2749       @Override
2750       public VisibilityLabelsResponse run() throws Exception {
2751         try {
2752           return VisibilityClient.setAuths(conf, new String[] { CONFIDENTIAL, PRIVATE, SECRET,
2753               TOPSECRET }, SUPERUSER.getShortName());
2754         } catch (Throwable e) {
2755         }
2756         return null;
2757       }
2758     };
2759     SUPERUSER.runAs(action);
2760   }
2761 
2762   @Test
2763   public void testDiffDeleteTypesForTheSameCellUsingMultipleVersions() throws Exception {
2764     setAuths();
2765     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
2766     try (Table table = doPuts(tableName)){
2767       // Do not flush here.
2768       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
2769         @Override
2770         public Void run() throws Exception {
2771           try (Connection connection = ConnectionFactory.createConnection(conf);
2772                Table table = connection.getTable(tableName)) {
2773             Delete d = new Delete(row1);
2774             d.setCellVisibility(new CellVisibility("(" + PRIVATE + "&" + CONFIDENTIAL + ")|("
2775                 + TOPSECRET + "&" + SECRET+")"));
2776             d.addColumns(fam, qual, 125l);
2777             table.delete(d);
2778           } catch (Throwable t) {
2779             throw new IOException(t);
2780           }
2781           return null;
2782         }
2783       };
2784       SUPERUSER.runAs(actiona);
2785 
2786       Scan s = new Scan();
2787       s.setMaxVersions(5);
2788       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2789       ResultScanner scanner = table.getScanner(s);
2790       Result[] next = scanner.next(3);
2791       assertTrue(next.length == 2);
2792       CellScanner cellScanner = next[0].cellScanner();
2793       cellScanner.advance();
2794       Cell current = cellScanner.current();
2795       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2796           current.getRowLength(), row1, 0, row1.length));
2797       assertEquals(current.getTimestamp(), 127l);
2798       cellScanner.advance();
2799       current = cellScanner.current();
2800       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2801           current.getRowLength(), row1, 0, row1.length));
2802       assertEquals(current.getTimestamp(), 126l);
2803       cellScanner.advance();
2804       current = cellScanner.current();
2805       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2806           current.getRowLength(), row1, 0, row1.length));
2807       assertEquals(current.getTimestamp(), 125l);
2808       cellScanner.advance();
2809       current = cellScanner.current();
2810       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2811           current.getRowLength(), row1, 0, row1.length));
2812       assertEquals(current.getTimestamp(), 123l);
2813       cellScanner = next[1].cellScanner();
2814       cellScanner.advance();
2815       current = cellScanner.current();
2816       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2817           current.getRowLength(), row2, 0, row2.length));
2818 
2819       // Issue 2nd delete
2820       actiona = new PrivilegedExceptionAction<Void>() {
2821         @Override
2822         public Void run() throws Exception {
2823           try (Connection connection = ConnectionFactory.createConnection(conf);
2824                Table table = connection.getTable(tableName)) {
2825             Delete d = new Delete(row1);
2826             d.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")|("
2827                 + TOPSECRET + "&" + SECRET+")"));
2828             d.addColumn(fam, qual, 127l);
2829             table.delete(d);
2830           } catch (Throwable t) {
2831             throw new IOException(t);
2832           }
2833           return null;
2834         }
2835       };
2836       SUPERUSER.runAs(actiona);
2837       s = new Scan();
2838       s.setMaxVersions(5);
2839       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2840       scanner = table.getScanner(s);
2841       next = scanner.next(3);
2842       assertTrue(next.length == 2);
2843       cellScanner = next[0].cellScanner();
2844       cellScanner.advance();
2845       current = cellScanner.current();
2846       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2847           current.getRowLength(), row1, 0, row1.length));
2848       assertEquals(current.getTimestamp(), 126l);
2849       cellScanner.advance();
2850       current = cellScanner.current();
2851       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2852           current.getRowLength(), row1, 0, row1.length));
2853       assertEquals(current.getTimestamp(), 125l);
2854       cellScanner.advance();
2855       current = cellScanner.current();
2856       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2857           current.getRowLength(), row1, 0, row1.length));
2858       assertEquals(current.getTimestamp(), 123l);
2859       cellScanner = next[1].cellScanner();
2860       cellScanner.advance();
2861       current = cellScanner.current();
2862       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2863           current.getRowLength(), row2, 0, row2.length));
2864     }
2865   }
2866 
2867   @Test
2868   public void testDeleteColumnLatestWithNoCellVisibility() throws Exception {
2869     setAuths();
2870     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
2871     try (Table table = doPuts(tableName)){
2872       TEST_UTIL.getHBaseAdmin().flush(tableName);
2873       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
2874         @Override
2875         public Void run() throws Exception {
2876           try (Connection connection = ConnectionFactory.createConnection(conf);
2877                Table table = connection.getTable(tableName)) {
2878             Delete d = new Delete(row1);
2879             d.addColumn(fam, qual, 125l);
2880             table.delete(d);
2881           } catch (Throwable t) {
2882             throw new IOException(t);
2883           }
2884           return null;
2885         }
2886       };
2887       SUPERUSER.runAs(actiona);
2888 
2889       TEST_UTIL.getHBaseAdmin().flush(tableName);
2890       Scan s = new Scan();
2891       s.setMaxVersions(5);
2892       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2893       ResultScanner scanner = table.getScanner(s);
2894       Result[] next = scanner.next(3);
2895       assertTrue(next.length == 2);
2896       scanAll(next);
2897       actiona = new PrivilegedExceptionAction<Void>() {
2898         @Override
2899         public Void run() throws Exception {
2900           try (Connection connection = ConnectionFactory.createConnection(conf);
2901                Table table = connection.getTable(tableName)) {
2902             Delete d = new Delete(row1);
2903             d.addColumns(fam, qual, 125l);
2904             table.delete(d);
2905           } catch (Throwable t) {
2906             throw new IOException(t);
2907           }
2908           return null;
2909         }
2910       };
2911       SUPERUSER.runAs(actiona);
2912 
2913       TEST_UTIL.getHBaseAdmin().flush(tableName);
2914       s = new Scan();
2915       s.setMaxVersions(5);
2916       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2917       scanner = table.getScanner(s);
2918       next = scanner.next(3);
2919       assertTrue(next.length == 2);
2920       scanAll(next);
2921 
2922       actiona = new PrivilegedExceptionAction<Void>() {
2923         @Override
2924         public Void run() throws Exception {
2925           try (Connection connection = ConnectionFactory.createConnection(conf);
2926                Table table = connection.getTable(tableName)) {
2927             Delete d = new Delete(row1);
2928             d.addFamily(fam, 125l);
2929             table.delete(d);
2930           } catch (Throwable t) {
2931             throw new IOException(t);
2932           }
2933           return null;
2934         }
2935       };
2936       SUPERUSER.runAs(actiona);
2937 
2938       TEST_UTIL.getHBaseAdmin().flush(tableName);
2939       s = new Scan();
2940       s.setMaxVersions(5);
2941       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2942       scanner = table.getScanner(s);
2943       next = scanner.next(3);
2944       assertTrue(next.length == 2);
2945       scanAll(next);
2946 
2947       actiona = new PrivilegedExceptionAction<Void>() {
2948         @Override
2949         public Void run() throws Exception {
2950           try (Connection connection = ConnectionFactory.createConnection(conf);
2951                Table table = connection.getTable(tableName)) {
2952             Delete d = new Delete(row1);
2953             d.addFamily(fam);
2954             table.delete(d);
2955           } catch (Throwable t) {
2956             throw new IOException(t);
2957           }
2958           return null;
2959         }
2960       };
2961       SUPERUSER.runAs(actiona);
2962 
2963       TEST_UTIL.getHBaseAdmin().flush(tableName);
2964       s = new Scan();
2965       s.setMaxVersions(5);
2966       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2967       scanner = table.getScanner(s);
2968       next = scanner.next(3);
2969       assertTrue(next.length == 2);
2970       scanAll(next);
2971 
2972       actiona = new PrivilegedExceptionAction<Void>() {
2973         @Override
2974         public Void run() throws Exception {
2975           try (Connection connection = ConnectionFactory.createConnection(conf);
2976                Table table = connection.getTable(tableName)) {
2977             Delete d = new Delete(row1);
2978             d.addColumns(fam, qual);
2979             table.delete(d);
2980           } catch (Throwable t) {
2981             throw new IOException(t);
2982           }
2983           return null;
2984         }
2985       };
2986       SUPERUSER.runAs(actiona);
2987 
2988       TEST_UTIL.getHBaseAdmin().flush(tableName);
2989       s = new Scan();
2990       s.setMaxVersions(5);
2991       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2992       scanner = table.getScanner(s);
2993       next = scanner.next(3);
2994       assertTrue(next.length == 2);
2995       scanAll(next);
2996 
2997       actiona = new PrivilegedExceptionAction<Void>() {
2998         @Override
2999         public Void run() throws Exception {
3000           try (Connection connection = ConnectionFactory.createConnection(conf);
3001                Table table = connection.getTable(tableName)) {
3002             Delete d = new Delete(row1);
3003             d.deleteFamilyVersion(fam, 126l);
3004             table.delete(d);
3005           } catch (Throwable t) {
3006             throw new IOException(t);
3007           }
3008           return null;
3009         }
3010       };
3011       SUPERUSER.runAs(actiona);
3012 
3013       TEST_UTIL.getHBaseAdmin().flush(tableName);
3014       s = new Scan();
3015       s.setMaxVersions(5);
3016       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
3017       scanner = table.getScanner(s);
3018       next = scanner.next(3);
3019       assertTrue(next.length == 2);
3020       scanAll(next);
3021     }
3022   }
3023 
3024   @Test
3025   public void testDeleteWithNoVisibilitiesForPutsAndDeletes() throws Exception {
3026     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
3027     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
3028     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
3029     colDesc.setMaxVersions(5);
3030     HTableDescriptor desc = new HTableDescriptor(tableName);
3031     desc.addFamily(colDesc);
3032     hBaseAdmin.createTable(desc);
3033     Put p = new Put (Bytes.toBytes("row1"));
3034     p.addColumn(fam, qual, value);
3035     Table table = TEST_UTIL.getConnection().getTable(tableName);
3036     table.put(p);
3037     p = new Put (Bytes.toBytes("row1"));
3038     p.addColumn(fam, qual1, value);
3039     table.put(p);
3040     p = new Put (Bytes.toBytes("row2"));
3041     p.addColumn(fam, qual, value);
3042     table.put(p);
3043     p = new Put (Bytes.toBytes("row2"));
3044     p.addColumn(fam, qual1, value);
3045     table.put(p);
3046     Delete d = new Delete(Bytes.toBytes("row1"));
3047     table.delete(d);
3048     Get g = new Get(Bytes.toBytes("row1"));
3049     g.setMaxVersions();
3050     g.setAuthorizations(new Authorizations(SECRET, PRIVATE));
3051     Result result = table.get(g);
3052     assertEquals(0, result.rawCells().length);
3053 
3054     p = new Put (Bytes.toBytes("row1"));
3055     p.addColumn(fam, qual, value);
3056     table.put(p);
3057     result = table.get(g);
3058     assertEquals(1, result.rawCells().length);
3059   }
3060 
3061   @Test
3062   public void testDeleteWithFamilyDeletesOfSameTsButDifferentVisibilities() throws Exception {
3063     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
3064     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
3065     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
3066     colDesc.setMaxVersions(5);
3067     HTableDescriptor desc = new HTableDescriptor(tableName);
3068     desc.addFamily(colDesc);
3069     hBaseAdmin.createTable(desc);
3070     Table table = TEST_UTIL.getConnection().getTable(tableName);
3071     long t1 = 1234L;
3072     CellVisibility cellVisibility1 = new CellVisibility(SECRET);
3073     CellVisibility cellVisibility2 = new CellVisibility(PRIVATE);
3074     // Cell row1:info:qual:1234 with visibility SECRET
3075     Put p = new Put(row1);
3076     p.addColumn(fam, qual, t1, value);
3077     p.setCellVisibility(cellVisibility1);
3078     table.put(p);
3079 
3080     // Cell row1:info:qual1:1234 with visibility PRIVATE
3081     p = new Put(row1);
3082     p.addColumn(fam, qual1, t1, value);
3083     p.setCellVisibility(cellVisibility2);
3084     table.put(p);
3085 
3086     Delete d = new Delete(row1);
3087     d.addFamily(fam, t1);
3088     d.setCellVisibility(cellVisibility2);
3089     table.delete(d);
3090     d = new Delete(row1);
3091     d.addFamily(fam, t1);
3092     d.setCellVisibility(cellVisibility1);
3093     table.delete(d);
3094 
3095     Get g = new Get(row1);
3096     g.setMaxVersions();
3097     g.setAuthorizations(new Authorizations(SECRET, PRIVATE));
3098     Result result = table.get(g);
3099     assertEquals(0, result.rawCells().length);
3100 
3101     // Cell row2:info:qual:1234 with visibility SECRET
3102     p = new Put(row2);
3103     p.addColumn(fam, qual, t1, value);
3104     p.setCellVisibility(cellVisibility1);
3105     table.put(p);
3106 
3107     // Cell row2:info:qual1:1234 with visibility PRIVATE
3108     p = new Put(row2);
3109     p.addColumn(fam, qual1, t1, value);
3110     p.setCellVisibility(cellVisibility2);
3111     table.put(p);
3112 
3113     d = new Delete(row2);
3114     d.addFamilyVersion(fam, t1);
3115     d.setCellVisibility(cellVisibility2);
3116     table.delete(d);
3117     d = new Delete(row2);
3118     d.addFamilyVersion(fam, t1);
3119     d.setCellVisibility(cellVisibility1);
3120     table.delete(d);
3121 
3122     g = new Get(row2);
3123     g.setMaxVersions();
3124     g.setAuthorizations(new Authorizations(SECRET, PRIVATE));
3125     result = table.get(g);
3126     assertEquals(0, result.rawCells().length);
3127   }
3128 
3129   private void scanAll(Result[] next) throws IOException {
3130     CellScanner cellScanner = next[0].cellScanner();
3131     cellScanner.advance();
3132     Cell current = cellScanner.current();
3133     assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(),
3134         row1, 0, row1.length));
3135     assertEquals(current.getTimestamp(), 127l);
3136     cellScanner.advance();
3137     current = cellScanner.current();
3138     assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(),
3139         row1, 0, row1.length));
3140     assertEquals(current.getTimestamp(), 126l);
3141     cellScanner.advance();
3142     current = cellScanner.current();
3143     assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(),
3144         row1, 0, row1.length));
3145     assertEquals(current.getTimestamp(), 125l);
3146     cellScanner.advance();
3147     current = cellScanner.current();
3148     assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(),
3149         row1, 0, row1.length));
3150     assertEquals(current.getTimestamp(), 124l);
3151     cellScanner.advance();
3152     current = cellScanner.current();
3153     assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(),
3154         row1, 0, row1.length));
3155     assertEquals(current.getTimestamp(), 123l);
3156     cellScanner = next[1].cellScanner();
3157     cellScanner.advance();
3158     current = cellScanner.current();
3159     assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(),
3160         row2, 0, row2.length));
3161   }
3162 
3163   @Test
3164   public void testVisibilityExpressionWithNotEqualORCondition() throws Exception {
3165     setAuths();
3166     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
3167     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
3168     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
3169     colDesc.setMaxVersions(5);
3170     HTableDescriptor desc = new HTableDescriptor(tableName);
3171     desc.addFamily(colDesc);
3172     hBaseAdmin.createTable(desc);
3173     try (Table table = new HTable(conf, tableName)) {
3174       Put put = new Put(Bytes.toBytes("row1"));
3175       put.add(fam, qual, 123l, value);
3176       put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
3177       table.put(put);
3178       put = new Put(Bytes.toBytes("row1"));
3179       put.add(fam, qual, 124l, value);
3180       put.setCellVisibility(new CellVisibility(CONFIDENTIAL + "|" + PRIVATE));
3181       table.put(put);
3182       TEST_UTIL.getHBaseAdmin().flush(tableName);
3183       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
3184         @Override
3185         public Void run() throws Exception {
3186           try (Connection connection = ConnectionFactory.createConnection(conf);
3187                Table table = connection.getTable(tableName)) {
3188             Delete d = new Delete(row1);
3189             d.addColumn(fam, qual, 124l);
3190             d.setCellVisibility(new CellVisibility(PRIVATE ));
3191             table.delete(d);
3192           } catch (Throwable t) {
3193             throw new IOException(t);
3194           }
3195           return null;
3196         }
3197       };
3198       SUPERUSER.runAs(actiona);
3199 
3200       TEST_UTIL.getHBaseAdmin().flush(tableName);
3201       Scan s = new Scan();
3202       s.setMaxVersions(5);
3203       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
3204       ResultScanner scanner = table.getScanner(s);
3205       Result[] next = scanner.next(3);
3206       assertTrue(next.length == 1);
3207       CellScanner cellScanner = next[0].cellScanner();
3208       cellScanner.advance();
3209       Cell current = cellScanner.current();
3210       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
3211           current.getRowLength(), row1, 0, row1.length));
3212       assertEquals(current.getTimestamp(), 124l);
3213       cellScanner.advance();
3214       current = cellScanner.current();
3215       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
3216           current.getRowLength(), row1, 0, row1.length));
3217       assertEquals(current.getTimestamp(), 123l);
3218     }
3219   }
3220 
3221   public static Table createTableAndWriteDataWithLabels(TableName tableName, String... labelExps)
3222       throws Exception {
3223     Table table = null;
3224     table = TEST_UTIL.createTable(tableName, fam);
3225     int i = 1;
3226     List<Put> puts = new ArrayList<Put>();
3227     for (String labelExp : labelExps) {
3228       Put put = new Put(Bytes.toBytes("row" + i));
3229       put.add(fam, qual, HConstants.LATEST_TIMESTAMP, value);
3230       put.setCellVisibility(new CellVisibility(labelExp));
3231       puts.add(put);
3232       table.put(put);
3233       i++;
3234     }
3235     // table.put(puts);
3236     return table;
3237   }
3238 
3239   public static Table createTableAndWriteDataWithLabels(TableName tableName, long[] timestamp,
3240       String... labelExps) throws Exception {
3241     Table table = null;
3242     table = TEST_UTIL.createTable(tableName, fam);
3243     int i = 1;
3244     List<Put> puts = new ArrayList<Put>();
3245     for (String labelExp : labelExps) {
3246       Put put = new Put(Bytes.toBytes("row" + i));
3247       put.add(fam, qual, timestamp[i - 1], value);
3248       put.setCellVisibility(new CellVisibility(labelExp));
3249       puts.add(put);
3250       table.put(put);
3251       TEST_UTIL.getHBaseAdmin().flush(tableName);
3252       i++;
3253     }
3254     return table;
3255   }
3256 
3257   public static void addLabels() throws Exception {
3258     PrivilegedExceptionAction<VisibilityLabelsResponse> action =
3259         new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
3260       @Override
3261       public VisibilityLabelsResponse run() throws Exception {
3262         String[] labels = { SECRET, TOPSECRET, CONFIDENTIAL, PUBLIC, PRIVATE };
3263         try {
3264           VisibilityClient.addLabels(conf, labels);
3265         } catch (Throwable t) {
3266           throw new IOException(t);
3267         }
3268         return null;
3269       }
3270     };
3271     SUPERUSER.runAs(action);
3272   }
3273   
3274   @SafeVarargs
3275   public static <T> List<T> createList(T... ts) {
3276     return new ArrayList<>(Arrays.asList(ts));
3277   }
3278 }