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 (Connection conn = ConnectionFactory.createConnection(conf)) {
2072           return VisibilityClient.setAuths(conn, 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 (Connection conn = ConnectionFactory.createConnection(conf)) {
2223           return VisibilityClient.setAuths(conn, new String[] { CONFIDENTIAL,
2224             PRIVATE, SECRET },
2225               SUPERUSER.getShortName());
2226         } catch (Throwable e) {
2227         }
2228         return null;
2229       }
2230     };
2231     VisibilityLabelsResponse response = SUPERUSER.runAs(action);
2232     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
2233     try (Table table = doPuts(tableName)){
2234       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
2235         @Override
2236         public Void run() throws Exception {
2237           try (Connection connection = ConnectionFactory.createConnection(conf);
2238                Table table = connection.getTable(tableName)) {
2239             Delete d = new Delete(row1);
2240             d.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")|("
2241                 + TOPSECRET + "&" + SECRET + ")"));
2242             d.addColumn(fam, qual);
2243             table.delete(d);
2244 
2245             d = new Delete(row1);
2246             d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
2247             d.deleteFamilyVersion(fam, 125l);
2248             table.delete(d);
2249           } catch (Throwable t) {
2250             throw new IOException(t);
2251           }
2252           return null;
2253         }
2254       };
2255       SUPERUSER.runAs(actiona);
2256 
2257       TEST_UTIL.getHBaseAdmin().flush(tableName);
2258       Scan s = new Scan();
2259       s.setMaxVersions(5);
2260       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2261       ResultScanner scanner = table.getScanner(s);
2262       Result[] next = scanner.next(5);
2263       assertTrue(next.length == 2);
2264       CellScanner cellScanner = next[0].cellScanner();
2265       cellScanner.advance();
2266       Cell current = cellScanner.current();
2267       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2268           current.getRowLength(), row1, 0, row1.length));
2269       assertEquals(current.getTimestamp(), 126l);
2270       cellScanner.advance();
2271       current = cellScanner.current();
2272       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2273           current.getRowLength(), row1, 0, row1.length));
2274       assertEquals(current.getTimestamp(), 124l);
2275       cellScanner.advance();
2276       current = cellScanner.current();
2277       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2278           current.getRowLength(), row1, 0, row1.length));
2279       assertEquals(current.getTimestamp(), 123l);
2280       // Issue 2nd delete
2281       actiona = new PrivilegedExceptionAction<Void>() {
2282         @Override
2283         public Void run() throws Exception {
2284           try (Connection connection = ConnectionFactory.createConnection(conf);
2285                Table table = connection.getTable(tableName)) {
2286             Delete d = new Delete(row1);
2287             d.setCellVisibility(new CellVisibility(CONFIDENTIAL));
2288             d.addFamily(fam);
2289             table.delete(d);
2290           } catch (Throwable t) {
2291             throw new IOException(t);
2292           }
2293           return null;
2294         }
2295       };
2296       SUPERUSER.runAs(actiona);
2297       s = new Scan();
2298       s.setMaxVersions(5);
2299       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2300       scanner = table.getScanner(s);
2301       next = scanner.next(5);
2302       assertTrue(next.length == 2);
2303       cellScanner = next[0].cellScanner();
2304       cellScanner.advance();
2305       current = cellScanner.current();
2306       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2307           current.getRowLength(), row1, 0, row1.length));
2308       assertEquals(current.getTimestamp(), 126l);
2309       cellScanner.advance();
2310       current = cellScanner.current();
2311       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2312           current.getRowLength(), row1, 0, row1.length));
2313       assertEquals(current.getTimestamp(), 124l);
2314     }
2315   }
2316 
2317   @Test
2318   public void testDeleteColumnSpecificTimeStampWithMulipleVersionsDoneTwice() throws Exception {
2319     setAuths();
2320     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
2321     try (Table table = doPuts(tableName)) {
2322       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
2323         @Override
2324         public Void run() throws Exception {
2325           try (Connection connection = ConnectionFactory.createConnection(conf);
2326                Table table = connection.getTable(tableName)) {
2327             Delete d = new Delete(row1);
2328             d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
2329             d.addColumn(fam, qual, 125l);
2330             table.delete(d);
2331           } catch (Throwable t) {
2332             throw new IOException(t);
2333           }
2334           return null;
2335         }
2336       };
2337       SUPERUSER.runAs(actiona);
2338 
2339       Scan s = new Scan();
2340       s.setMaxVersions(5);
2341       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2342       ResultScanner scanner = table.getScanner(s);
2343       Result[] next = scanner.next(3);
2344       assertTrue(next.length == 2);
2345       CellScanner cellScanner = next[0].cellScanner();
2346       cellScanner.advance();
2347       Cell current = cellScanner.current();
2348       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2349           current.getRowLength(), row1, 0, row1.length));
2350       assertEquals(current.getTimestamp(), 127l);
2351       cellScanner.advance();
2352       current = cellScanner.current();
2353       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2354           current.getRowLength(), row1, 0, row1.length));
2355       assertEquals(current.getTimestamp(), 126l);
2356       cellScanner.advance();
2357       current = cellScanner.current();
2358       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2359           current.getRowLength(), row1, 0, row1.length));
2360       assertEquals(current.getTimestamp(), 124l);
2361       cellScanner.advance();
2362       current = cellScanner.current();
2363       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2364           current.getRowLength(), row1, 0, row1.length));
2365       assertEquals(current.getTimestamp(), 123l);
2366       cellScanner = next[1].cellScanner();
2367       cellScanner.advance();
2368       current = cellScanner.current();
2369       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2370           current.getRowLength(), row2, 0, row2.length));
2371 
2372       // Issue 2nd delete
2373       actiona = new PrivilegedExceptionAction<Void>() {
2374         @Override
2375         public Void run() throws Exception {
2376           try (Connection connection = ConnectionFactory.createConnection(conf);
2377                Table table = connection.getTable(tableName)) {
2378             Delete d = new Delete(row1);
2379             d.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")|("
2380                 + TOPSECRET + "&" + SECRET+")"));
2381             d.addColumn(fam, qual, 127l);
2382             table.delete(d);
2383           } catch (Throwable t) {
2384             throw new IOException(t);
2385           }
2386           return null;
2387         }
2388       };
2389       SUPERUSER.runAs(actiona);
2390       s = new Scan();
2391       s.setMaxVersions(5);
2392       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2393       scanner = table.getScanner(s);
2394       next = scanner.next(3);
2395       assertTrue(next.length == 2);
2396       cellScanner = next[0].cellScanner();
2397       cellScanner.advance();
2398       current = cellScanner.current();
2399       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2400           current.getRowLength(), row1, 0, row1.length));
2401       assertEquals(current.getTimestamp(), 126l);
2402       cellScanner.advance();
2403       current = cellScanner.current();
2404       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2405           current.getRowLength(), row1, 0, row1.length));
2406       assertEquals(current.getTimestamp(), 124l);
2407       cellScanner.advance();
2408       current = cellScanner.current();
2409       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2410           current.getRowLength(), row1, 0, row1.length));
2411       assertEquals(current.getTimestamp(), 123l);
2412       cellScanner = next[1].cellScanner();
2413       cellScanner.advance();
2414       current = cellScanner.current();
2415       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2416           current.getRowLength(), row2, 0, row2.length));
2417       assertEquals(current.getTimestamp(), 127l);
2418     }
2419   }
2420 
2421   @Test
2422   public void testDeleteColumnSpecificTimeStampWithMulipleVersionsDoneTwice1() throws Exception {
2423     setAuths();
2424     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
2425     // Do not flush here.
2426     try (Table table = doPuts(tableName)) {
2427       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
2428         @Override
2429         public Void run() throws Exception {
2430           try (Connection connection = ConnectionFactory.createConnection(conf);
2431                Table table = connection.getTable(tableName)) {
2432             Delete d = new Delete(row1);
2433             d.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")" +
2434                 "|(" + TOPSECRET + "&" + SECRET + ")"));
2435             d.addColumn(fam, qual, 127l);
2436             table.delete(d);
2437           } catch (Throwable t) {
2438             throw new IOException(t);
2439           }
2440           return null;
2441         }
2442       };
2443       SUPERUSER.runAs(actiona);
2444 
2445       Scan s = new Scan();
2446       s.setMaxVersions(5);
2447       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2448       ResultScanner scanner = table.getScanner(s);
2449       Result[] next = scanner.next(3);
2450       assertTrue(next.length == 2);
2451       CellScanner cellScanner = next[0].cellScanner();
2452       cellScanner.advance();
2453       Cell current = cellScanner.current();
2454       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2455           current.getRowLength(), row1, 0, row1.length));
2456       assertEquals(current.getTimestamp(), 126l);
2457       cellScanner.advance();
2458       current = cellScanner.current();
2459       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2460           current.getRowLength(), row1, 0, row1.length));
2461       assertEquals(current.getTimestamp(), 125l);
2462       cellScanner.advance();
2463       current = cellScanner.current();
2464       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2465           current.getRowLength(), row1, 0, row1.length));
2466       assertEquals(current.getTimestamp(), 124l);
2467       cellScanner.advance();
2468       current = cellScanner.current();
2469       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2470           current.getRowLength(), row1, 0, row1.length));
2471       assertEquals(current.getTimestamp(), 123l);
2472       cellScanner = next[1].cellScanner();
2473       cellScanner.advance();
2474       current = cellScanner.current();
2475       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2476           current.getRowLength(), row2, 0, row2.length));
2477 
2478       // Issue 2nd delete
2479       actiona = new PrivilegedExceptionAction<Void>() {
2480         @Override
2481         public Void run() throws Exception {
2482           try (Connection connection = ConnectionFactory.createConnection(conf);
2483                Table table = connection.getTable(tableName)) {
2484             Delete d = new Delete(row1);
2485             d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
2486             d.addColumn(fam, qual, 127l);
2487             table.delete(d);
2488           } catch (Throwable t) {
2489             throw new IOException(t);
2490           }
2491           return null;
2492         }
2493       };
2494       SUPERUSER.runAs(actiona);
2495       s = new Scan();
2496       s.setMaxVersions(5);
2497       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2498       scanner = table.getScanner(s);
2499       next = scanner.next(3);
2500       assertTrue(next.length == 2);
2501       cellScanner = next[0].cellScanner();
2502       cellScanner.advance();
2503       current = cellScanner.current();
2504       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2505           current.getRowLength(), row1, 0, row1.length));
2506       assertEquals(current.getTimestamp(), 126l);
2507       cellScanner.advance();
2508       current = cellScanner.current();
2509       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2510           current.getRowLength(), row1, 0, row1.length));
2511       assertEquals(current.getTimestamp(), 125l);
2512       cellScanner.advance();
2513       current = cellScanner.current();
2514       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2515           current.getRowLength(), row1, 0, row1.length));
2516       assertEquals(current.getTimestamp(), 124l);
2517       cellScanner.advance();
2518       current = cellScanner.current();
2519       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2520           current.getRowLength(), row1, 0, row1.length));
2521       assertEquals(current.getTimestamp(), 123l);
2522       cellScanner = next[1].cellScanner();
2523       cellScanner.advance();
2524       current = cellScanner.current();
2525       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2526           current.getRowLength(), row2, 0, row2.length));
2527       assertEquals(current.getTimestamp(), 127l);
2528     }
2529   }
2530   @Test
2531   public void testDeleteColumnSpecificTimeStampWithMulipleVersionsDoneTwice2() throws Exception {
2532     setAuths();
2533     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
2534 
2535     // Do not flush here.
2536     try (Table table = doPuts(tableName)) {
2537       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
2538         @Override
2539         public Void run() throws Exception {
2540           try (Connection connection = ConnectionFactory.createConnection(conf);
2541                Table table = connection.getTable(tableName)) {
2542             Delete d = new Delete(row1);
2543             d.setCellVisibility(new CellVisibility("(" + PRIVATE + "&" + CONFIDENTIAL + ")|("
2544                 + TOPSECRET + "&" + SECRET+")"));
2545             d.addColumn(fam, qual, 125l);
2546             table.delete(d);
2547           } catch (Throwable t) {
2548             throw new IOException(t);
2549           }
2550           return null;
2551         }
2552       };
2553       SUPERUSER.runAs(actiona);
2554 
2555       Scan s = new Scan();
2556       s.setMaxVersions(5);
2557       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2558       ResultScanner scanner = table.getScanner(s);
2559       Result[] next = scanner.next(3);
2560       assertTrue(next.length == 2);
2561       CellScanner cellScanner = next[0].cellScanner();
2562       cellScanner.advance();
2563       Cell current = cellScanner.current();
2564       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2565           current.getRowLength(), row1, 0, row1.length));
2566       assertEquals(current.getTimestamp(), 127l);
2567       cellScanner.advance();
2568       current = cellScanner.current();
2569       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2570           current.getRowLength(), row1, 0, row1.length));
2571       assertEquals(current.getTimestamp(), 126l);
2572       cellScanner.advance();
2573       current = cellScanner.current();
2574       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2575           current.getRowLength(), row1, 0, row1.length));
2576       assertEquals(current.getTimestamp(), 125l);
2577       cellScanner.advance();
2578       current = cellScanner.current();
2579       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2580           current.getRowLength(), row1, 0, row1.length));
2581       assertEquals(current.getTimestamp(), 124l);
2582       cellScanner.advance();
2583       current = cellScanner.current();
2584       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2585           current.getRowLength(), row1, 0, row1.length));
2586       assertEquals(current.getTimestamp(), 123l);
2587       cellScanner = next[1].cellScanner();
2588       cellScanner.advance();
2589       current = cellScanner.current();
2590       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2591           current.getRowLength(), row2, 0, row2.length));
2592 
2593       // Issue 2nd delete
2594       actiona = new PrivilegedExceptionAction<Void>() {
2595         @Override
2596         public Void run() throws Exception {
2597           try (Connection connection = ConnectionFactory.createConnection(conf);
2598                Table table = connection.getTable(tableName)) {
2599             Delete d = new Delete(row1);
2600             d.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")|("
2601                 + TOPSECRET + "&" + SECRET+")"));
2602             d.addColumn(fam, qual, 127l);
2603             table.delete(d);
2604           } catch (Throwable t) {
2605             throw new IOException(t);
2606           }
2607           return null;
2608         }
2609       };
2610       SUPERUSER.runAs(actiona);
2611       s = new Scan();
2612       s.setMaxVersions(5);
2613       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2614       scanner = table.getScanner(s);
2615       next = scanner.next(3);
2616       assertTrue(next.length == 2);
2617       cellScanner = next[0].cellScanner();
2618       cellScanner.advance();
2619       current = cellScanner.current();
2620       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2621           current.getRowLength(), row1, 0, row1.length));
2622       assertEquals(current.getTimestamp(), 126l);
2623       cellScanner.advance();
2624       current = cellScanner.current();
2625       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2626           current.getRowLength(), row1, 0, row1.length));
2627       assertEquals(current.getTimestamp(), 125l);
2628       cellScanner.advance();
2629       current = cellScanner.current();
2630       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2631           current.getRowLength(), row1, 0, row1.length));
2632       assertEquals(current.getTimestamp(), 124l);
2633       cellScanner.advance();
2634       current = cellScanner.current();
2635       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2636           current.getRowLength(), row1, 0, row1.length));
2637       assertEquals(current.getTimestamp(), 123l);
2638       cellScanner = next[1].cellScanner();
2639       cellScanner.advance();
2640       current = cellScanner.current();
2641       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2642           current.getRowLength(), row2, 0, row2.length));
2643       assertEquals(current.getTimestamp(), 127l);
2644     }
2645   }
2646   @Test
2647   public void testDeleteColumnAndDeleteFamilylSpecificTimeStampWithMulipleVersion()
2648       throws Exception {
2649     setAuths();
2650     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
2651     // Do not flush here.
2652     try (Table table = doPuts(tableName)) {
2653       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
2654         @Override
2655         public Void run() throws Exception {
2656           try (Connection connection = ConnectionFactory.createConnection(conf);
2657                Table table = connection.getTable(tableName)) {
2658             Delete d = new Delete(row1);
2659             d.setCellVisibility(new CellVisibility(SECRET + "&" + TOPSECRET));
2660             d.addColumn(fam, qual, 125l);
2661             table.delete(d);
2662           } catch (Throwable t) {
2663             throw new IOException(t);
2664           }
2665           return null;
2666         }
2667       };
2668       SUPERUSER.runAs(actiona);
2669 
2670       Scan s = new Scan();
2671       s.setMaxVersions(5);
2672       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2673       ResultScanner scanner = table.getScanner(s);
2674       Result[] next = scanner.next(3);
2675       assertTrue(next.length == 2);
2676       CellScanner cellScanner = next[0].cellScanner();
2677       cellScanner.advance();
2678       Cell current = cellScanner.current();
2679       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2680           current.getRowLength(), row1, 0, row1.length));
2681       assertEquals(current.getTimestamp(), 127l);
2682       cellScanner.advance();
2683       current = cellScanner.current();
2684       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2685           current.getRowLength(), row1, 0, row1.length));
2686       assertEquals(current.getTimestamp(), 126l);
2687       cellScanner.advance();
2688       current = cellScanner.current();
2689       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2690           current.getRowLength(), row1, 0, row1.length));
2691       assertEquals(current.getTimestamp(), 124l);
2692       cellScanner.advance();
2693       current = cellScanner.current();
2694       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2695           current.getRowLength(), row1, 0, row1.length));
2696       assertEquals(current.getTimestamp(), 123l);
2697       cellScanner = next[1].cellScanner();
2698       cellScanner.advance();
2699       current = cellScanner.current();
2700       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2701           current.getRowLength(), row2, 0, row2.length));
2702 
2703       // Issue 2nd delete
2704       actiona = new PrivilegedExceptionAction<Void>() {
2705         @Override
2706         public Void run() throws Exception {
2707           try (Connection connection = ConnectionFactory.createConnection(conf);
2708                Table table = connection.getTable(tableName)) {
2709             Delete d = new Delete(row1);
2710             d.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")|("
2711                 + TOPSECRET + "&" + SECRET+")"));
2712             d.addFamily(fam, 124l);
2713             table.delete(d);
2714           } catch (Throwable t) {
2715             throw new IOException(t);
2716           }
2717           return null;
2718         }
2719       };
2720       SUPERUSER.runAs(actiona);
2721       s = new Scan();
2722       s.setMaxVersions(5);
2723       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2724       scanner = table.getScanner(s);
2725       next = scanner.next(3);
2726       assertTrue(next.length == 2);
2727       cellScanner = next[0].cellScanner();
2728       cellScanner.advance();
2729       current = cellScanner.current();
2730       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2731           current.getRowLength(), row1, 0, row1.length));
2732       assertEquals(current.getTimestamp(), 127l);
2733       cellScanner.advance();
2734       current = cellScanner.current();
2735       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2736           current.getRowLength(), row1, 0, row1.length));
2737       assertEquals(current.getTimestamp(), 126l);
2738       cellScanner = next[1].cellScanner();
2739       cellScanner.advance();
2740       current = cellScanner.current();
2741       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2742           current.getRowLength(), row2, 0, row2.length));
2743       assertEquals(current.getTimestamp(), 127l);
2744     }
2745   }
2746 
2747   private void setAuths() throws IOException, InterruptedException {
2748     PrivilegedExceptionAction<VisibilityLabelsResponse> action =
2749         new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
2750       @Override
2751       public VisibilityLabelsResponse run() throws Exception {
2752         try (Connection conn = ConnectionFactory.createConnection(conf)) {
2753           return VisibilityClient.setAuths(conn, new String[] { CONFIDENTIAL,
2754             PRIVATE, SECRET,
2755               TOPSECRET }, SUPERUSER.getShortName());
2756         } catch (Throwable e) {
2757         }
2758         return null;
2759       }
2760     };
2761     SUPERUSER.runAs(action);
2762   }
2763 
2764   @Test
2765   public void testDiffDeleteTypesForTheSameCellUsingMultipleVersions() throws Exception {
2766     setAuths();
2767     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
2768     try (Table table = doPuts(tableName)){
2769       // Do not flush here.
2770       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
2771         @Override
2772         public Void run() throws Exception {
2773           try (Connection connection = ConnectionFactory.createConnection(conf);
2774                Table table = connection.getTable(tableName)) {
2775             Delete d = new Delete(row1);
2776             d.setCellVisibility(new CellVisibility("(" + PRIVATE + "&" + CONFIDENTIAL + ")|("
2777                 + TOPSECRET + "&" + SECRET+")"));
2778             d.addColumns(fam, qual, 125l);
2779             table.delete(d);
2780           } catch (Throwable t) {
2781             throw new IOException(t);
2782           }
2783           return null;
2784         }
2785       };
2786       SUPERUSER.runAs(actiona);
2787 
2788       Scan s = new Scan();
2789       s.setMaxVersions(5);
2790       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2791       ResultScanner scanner = table.getScanner(s);
2792       Result[] next = scanner.next(3);
2793       assertTrue(next.length == 2);
2794       CellScanner cellScanner = next[0].cellScanner();
2795       cellScanner.advance();
2796       Cell current = cellScanner.current();
2797       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2798           current.getRowLength(), row1, 0, row1.length));
2799       assertEquals(current.getTimestamp(), 127l);
2800       cellScanner.advance();
2801       current = cellScanner.current();
2802       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2803           current.getRowLength(), row1, 0, row1.length));
2804       assertEquals(current.getTimestamp(), 126l);
2805       cellScanner.advance();
2806       current = cellScanner.current();
2807       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2808           current.getRowLength(), row1, 0, row1.length));
2809       assertEquals(current.getTimestamp(), 125l);
2810       cellScanner.advance();
2811       current = cellScanner.current();
2812       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2813           current.getRowLength(), row1, 0, row1.length));
2814       assertEquals(current.getTimestamp(), 123l);
2815       cellScanner = next[1].cellScanner();
2816       cellScanner.advance();
2817       current = cellScanner.current();
2818       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2819           current.getRowLength(), row2, 0, row2.length));
2820 
2821       // Issue 2nd delete
2822       actiona = new PrivilegedExceptionAction<Void>() {
2823         @Override
2824         public Void run() throws Exception {
2825           try (Connection connection = ConnectionFactory.createConnection(conf);
2826                Table table = connection.getTable(tableName)) {
2827             Delete d = new Delete(row1);
2828             d.setCellVisibility(new CellVisibility("(" + CONFIDENTIAL + "&" + PRIVATE + ")|("
2829                 + TOPSECRET + "&" + SECRET+")"));
2830             d.addColumn(fam, qual, 127l);
2831             table.delete(d);
2832           } catch (Throwable t) {
2833             throw new IOException(t);
2834           }
2835           return null;
2836         }
2837       };
2838       SUPERUSER.runAs(actiona);
2839       s = new Scan();
2840       s.setMaxVersions(5);
2841       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2842       scanner = table.getScanner(s);
2843       next = scanner.next(3);
2844       assertTrue(next.length == 2);
2845       cellScanner = next[0].cellScanner();
2846       cellScanner.advance();
2847       current = cellScanner.current();
2848       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2849           current.getRowLength(), row1, 0, row1.length));
2850       assertEquals(current.getTimestamp(), 126l);
2851       cellScanner.advance();
2852       current = cellScanner.current();
2853       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2854           current.getRowLength(), row1, 0, row1.length));
2855       assertEquals(current.getTimestamp(), 125l);
2856       cellScanner.advance();
2857       current = cellScanner.current();
2858       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2859           current.getRowLength(), row1, 0, row1.length));
2860       assertEquals(current.getTimestamp(), 123l);
2861       cellScanner = next[1].cellScanner();
2862       cellScanner.advance();
2863       current = cellScanner.current();
2864       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
2865           current.getRowLength(), row2, 0, row2.length));
2866     }
2867   }
2868 
2869   @Test
2870   public void testDeleteColumnLatestWithNoCellVisibility() throws Exception {
2871     setAuths();
2872     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
2873     try (Table table = doPuts(tableName)){
2874       TEST_UTIL.getHBaseAdmin().flush(tableName);
2875       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
2876         @Override
2877         public Void run() throws Exception {
2878           try (Connection connection = ConnectionFactory.createConnection(conf);
2879                Table table = connection.getTable(tableName)) {
2880             Delete d = new Delete(row1);
2881             d.addColumn(fam, qual, 125l);
2882             table.delete(d);
2883           } catch (Throwable t) {
2884             throw new IOException(t);
2885           }
2886           return null;
2887         }
2888       };
2889       SUPERUSER.runAs(actiona);
2890 
2891       TEST_UTIL.getHBaseAdmin().flush(tableName);
2892       Scan s = new Scan();
2893       s.setMaxVersions(5);
2894       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2895       ResultScanner scanner = table.getScanner(s);
2896       Result[] next = scanner.next(3);
2897       assertTrue(next.length == 2);
2898       scanAll(next);
2899       actiona = new PrivilegedExceptionAction<Void>() {
2900         @Override
2901         public Void run() throws Exception {
2902           try (Connection connection = ConnectionFactory.createConnection(conf);
2903                Table table = connection.getTable(tableName)) {
2904             Delete d = new Delete(row1);
2905             d.addColumns(fam, qual, 125l);
2906             table.delete(d);
2907           } catch (Throwable t) {
2908             throw new IOException(t);
2909           }
2910           return null;
2911         }
2912       };
2913       SUPERUSER.runAs(actiona);
2914 
2915       TEST_UTIL.getHBaseAdmin().flush(tableName);
2916       s = new Scan();
2917       s.setMaxVersions(5);
2918       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2919       scanner = table.getScanner(s);
2920       next = scanner.next(3);
2921       assertTrue(next.length == 2);
2922       scanAll(next);
2923 
2924       actiona = new PrivilegedExceptionAction<Void>() {
2925         @Override
2926         public Void run() throws Exception {
2927           try (Connection connection = ConnectionFactory.createConnection(conf);
2928                Table table = connection.getTable(tableName)) {
2929             Delete d = new Delete(row1);
2930             d.addFamily(fam, 125l);
2931             table.delete(d);
2932           } catch (Throwable t) {
2933             throw new IOException(t);
2934           }
2935           return null;
2936         }
2937       };
2938       SUPERUSER.runAs(actiona);
2939 
2940       TEST_UTIL.getHBaseAdmin().flush(tableName);
2941       s = new Scan();
2942       s.setMaxVersions(5);
2943       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2944       scanner = table.getScanner(s);
2945       next = scanner.next(3);
2946       assertTrue(next.length == 2);
2947       scanAll(next);
2948 
2949       actiona = new PrivilegedExceptionAction<Void>() {
2950         @Override
2951         public Void run() throws Exception {
2952           try (Connection connection = ConnectionFactory.createConnection(conf);
2953                Table table = connection.getTable(tableName)) {
2954             Delete d = new Delete(row1);
2955             d.addFamily(fam);
2956             table.delete(d);
2957           } catch (Throwable t) {
2958             throw new IOException(t);
2959           }
2960           return null;
2961         }
2962       };
2963       SUPERUSER.runAs(actiona);
2964 
2965       TEST_UTIL.getHBaseAdmin().flush(tableName);
2966       s = new Scan();
2967       s.setMaxVersions(5);
2968       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2969       scanner = table.getScanner(s);
2970       next = scanner.next(3);
2971       assertTrue(next.length == 2);
2972       scanAll(next);
2973 
2974       actiona = new PrivilegedExceptionAction<Void>() {
2975         @Override
2976         public Void run() throws Exception {
2977           try (Connection connection = ConnectionFactory.createConnection(conf);
2978                Table table = connection.getTable(tableName)) {
2979             Delete d = new Delete(row1);
2980             d.addColumns(fam, qual);
2981             table.delete(d);
2982           } catch (Throwable t) {
2983             throw new IOException(t);
2984           }
2985           return null;
2986         }
2987       };
2988       SUPERUSER.runAs(actiona);
2989 
2990       TEST_UTIL.getHBaseAdmin().flush(tableName);
2991       s = new Scan();
2992       s.setMaxVersions(5);
2993       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
2994       scanner = table.getScanner(s);
2995       next = scanner.next(3);
2996       assertTrue(next.length == 2);
2997       scanAll(next);
2998 
2999       actiona = new PrivilegedExceptionAction<Void>() {
3000         @Override
3001         public Void run() throws Exception {
3002           try (Connection connection = ConnectionFactory.createConnection(conf);
3003                Table table = connection.getTable(tableName)) {
3004             Delete d = new Delete(row1);
3005             d.deleteFamilyVersion(fam, 126l);
3006             table.delete(d);
3007           } catch (Throwable t) {
3008             throw new IOException(t);
3009           }
3010           return null;
3011         }
3012       };
3013       SUPERUSER.runAs(actiona);
3014 
3015       TEST_UTIL.getHBaseAdmin().flush(tableName);
3016       s = new Scan();
3017       s.setMaxVersions(5);
3018       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
3019       scanner = table.getScanner(s);
3020       next = scanner.next(3);
3021       assertTrue(next.length == 2);
3022       scanAll(next);
3023     }
3024   }
3025 
3026   @Test
3027   public void testDeleteWithNoVisibilitiesForPutsAndDeletes() throws Exception {
3028     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
3029     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
3030     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
3031     colDesc.setMaxVersions(5);
3032     HTableDescriptor desc = new HTableDescriptor(tableName);
3033     desc.addFamily(colDesc);
3034     hBaseAdmin.createTable(desc);
3035     Put p = new Put (Bytes.toBytes("row1"));
3036     p.addColumn(fam, qual, value);
3037     Table table = TEST_UTIL.getConnection().getTable(tableName);
3038     table.put(p);
3039     p = new Put (Bytes.toBytes("row1"));
3040     p.addColumn(fam, qual1, value);
3041     table.put(p);
3042     p = new Put (Bytes.toBytes("row2"));
3043     p.addColumn(fam, qual, value);
3044     table.put(p);
3045     p = new Put (Bytes.toBytes("row2"));
3046     p.addColumn(fam, qual1, value);
3047     table.put(p);
3048     Delete d = new Delete(Bytes.toBytes("row1"));
3049     table.delete(d);
3050     Get g = new Get(Bytes.toBytes("row1"));
3051     g.setMaxVersions();
3052     g.setAuthorizations(new Authorizations(SECRET, PRIVATE));
3053     Result result = table.get(g);
3054     assertEquals(0, result.rawCells().length);
3055 
3056     p = new Put (Bytes.toBytes("row1"));
3057     p.addColumn(fam, qual, value);
3058     table.put(p);
3059     result = table.get(g);
3060     assertEquals(1, result.rawCells().length);
3061   }
3062 
3063   @Test
3064   public void testDeleteWithFamilyDeletesOfSameTsButDifferentVisibilities() throws Exception {
3065     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
3066     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
3067     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
3068     colDesc.setMaxVersions(5);
3069     HTableDescriptor desc = new HTableDescriptor(tableName);
3070     desc.addFamily(colDesc);
3071     hBaseAdmin.createTable(desc);
3072     Table table = TEST_UTIL.getConnection().getTable(tableName);
3073     long t1 = 1234L;
3074     CellVisibility cellVisibility1 = new CellVisibility(SECRET);
3075     CellVisibility cellVisibility2 = new CellVisibility(PRIVATE);
3076     // Cell row1:info:qual:1234 with visibility SECRET
3077     Put p = new Put(row1);
3078     p.addColumn(fam, qual, t1, value);
3079     p.setCellVisibility(cellVisibility1);
3080     table.put(p);
3081 
3082     // Cell row1:info:qual1:1234 with visibility PRIVATE
3083     p = new Put(row1);
3084     p.addColumn(fam, qual1, t1, value);
3085     p.setCellVisibility(cellVisibility2);
3086     table.put(p);
3087 
3088     Delete d = new Delete(row1);
3089     d.addFamily(fam, t1);
3090     d.setCellVisibility(cellVisibility2);
3091     table.delete(d);
3092     d = new Delete(row1);
3093     d.addFamily(fam, t1);
3094     d.setCellVisibility(cellVisibility1);
3095     table.delete(d);
3096 
3097     Get g = new Get(row1);
3098     g.setMaxVersions();
3099     g.setAuthorizations(new Authorizations(SECRET, PRIVATE));
3100     Result result = table.get(g);
3101     assertEquals(0, result.rawCells().length);
3102 
3103     // Cell row2:info:qual:1234 with visibility SECRET
3104     p = new Put(row2);
3105     p.addColumn(fam, qual, t1, value);
3106     p.setCellVisibility(cellVisibility1);
3107     table.put(p);
3108 
3109     // Cell row2:info:qual1:1234 with visibility PRIVATE
3110     p = new Put(row2);
3111     p.addColumn(fam, qual1, t1, value);
3112     p.setCellVisibility(cellVisibility2);
3113     table.put(p);
3114 
3115     d = new Delete(row2);
3116     d.addFamilyVersion(fam, t1);
3117     d.setCellVisibility(cellVisibility2);
3118     table.delete(d);
3119     d = new Delete(row2);
3120     d.addFamilyVersion(fam, t1);
3121     d.setCellVisibility(cellVisibility1);
3122     table.delete(d);
3123 
3124     g = new Get(row2);
3125     g.setMaxVersions();
3126     g.setAuthorizations(new Authorizations(SECRET, PRIVATE));
3127     result = table.get(g);
3128     assertEquals(0, result.rawCells().length);
3129   }
3130 
3131   private void scanAll(Result[] next) throws IOException {
3132     CellScanner cellScanner = next[0].cellScanner();
3133     cellScanner.advance();
3134     Cell current = cellScanner.current();
3135     assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(),
3136         row1, 0, row1.length));
3137     assertEquals(current.getTimestamp(), 127l);
3138     cellScanner.advance();
3139     current = cellScanner.current();
3140     assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(),
3141         row1, 0, row1.length));
3142     assertEquals(current.getTimestamp(), 126l);
3143     cellScanner.advance();
3144     current = cellScanner.current();
3145     assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(),
3146         row1, 0, row1.length));
3147     assertEquals(current.getTimestamp(), 125l);
3148     cellScanner.advance();
3149     current = cellScanner.current();
3150     assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(),
3151         row1, 0, row1.length));
3152     assertEquals(current.getTimestamp(), 124l);
3153     cellScanner.advance();
3154     current = cellScanner.current();
3155     assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(),
3156         row1, 0, row1.length));
3157     assertEquals(current.getTimestamp(), 123l);
3158     cellScanner = next[1].cellScanner();
3159     cellScanner.advance();
3160     current = cellScanner.current();
3161     assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(), current.getRowLength(),
3162         row2, 0, row2.length));
3163   }
3164 
3165   @Test
3166   public void testVisibilityExpressionWithNotEqualORCondition() throws Exception {
3167     setAuths();
3168     final TableName tableName = TableName.valueOf(TEST_NAME.getMethodName());
3169     Admin hBaseAdmin = TEST_UTIL.getHBaseAdmin();
3170     HColumnDescriptor colDesc = new HColumnDescriptor(fam);
3171     colDesc.setMaxVersions(5);
3172     HTableDescriptor desc = new HTableDescriptor(tableName);
3173     desc.addFamily(colDesc);
3174     hBaseAdmin.createTable(desc);
3175     try (Table table = new HTable(conf, tableName)) {
3176       Put put = new Put(Bytes.toBytes("row1"));
3177       put.add(fam, qual, 123l, value);
3178       put.setCellVisibility(new CellVisibility(CONFIDENTIAL));
3179       table.put(put);
3180       put = new Put(Bytes.toBytes("row1"));
3181       put.add(fam, qual, 124l, value);
3182       put.setCellVisibility(new CellVisibility(CONFIDENTIAL + "|" + PRIVATE));
3183       table.put(put);
3184       TEST_UTIL.getHBaseAdmin().flush(tableName);
3185       PrivilegedExceptionAction<Void> actiona = new PrivilegedExceptionAction<Void>() {
3186         @Override
3187         public Void run() throws Exception {
3188           try (Connection connection = ConnectionFactory.createConnection(conf);
3189                Table table = connection.getTable(tableName)) {
3190             Delete d = new Delete(row1);
3191             d.addColumn(fam, qual, 124l);
3192             d.setCellVisibility(new CellVisibility(PRIVATE ));
3193             table.delete(d);
3194           } catch (Throwable t) {
3195             throw new IOException(t);
3196           }
3197           return null;
3198         }
3199       };
3200       SUPERUSER.runAs(actiona);
3201 
3202       TEST_UTIL.getHBaseAdmin().flush(tableName);
3203       Scan s = new Scan();
3204       s.setMaxVersions(5);
3205       s.setAuthorizations(new Authorizations(SECRET, PRIVATE, CONFIDENTIAL, TOPSECRET));
3206       ResultScanner scanner = table.getScanner(s);
3207       Result[] next = scanner.next(3);
3208       assertTrue(next.length == 1);
3209       CellScanner cellScanner = next[0].cellScanner();
3210       cellScanner.advance();
3211       Cell current = cellScanner.current();
3212       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
3213           current.getRowLength(), row1, 0, row1.length));
3214       assertEquals(current.getTimestamp(), 124l);
3215       cellScanner.advance();
3216       current = cellScanner.current();
3217       assertTrue(Bytes.equals(current.getRowArray(), current.getRowOffset(),
3218           current.getRowLength(), row1, 0, row1.length));
3219       assertEquals(current.getTimestamp(), 123l);
3220     }
3221   }
3222 
3223   public static Table createTableAndWriteDataWithLabels(TableName tableName, String... labelExps)
3224       throws Exception {
3225     Table table = null;
3226     table = TEST_UTIL.createTable(tableName, fam);
3227     int i = 1;
3228     List<Put> puts = new ArrayList<Put>();
3229     for (String labelExp : labelExps) {
3230       Put put = new Put(Bytes.toBytes("row" + i));
3231       put.add(fam, qual, HConstants.LATEST_TIMESTAMP, value);
3232       put.setCellVisibility(new CellVisibility(labelExp));
3233       puts.add(put);
3234       table.put(put);
3235       i++;
3236     }
3237     // table.put(puts);
3238     return table;
3239   }
3240 
3241   public static Table createTableAndWriteDataWithLabels(TableName tableName, long[] timestamp,
3242       String... labelExps) throws Exception {
3243     Table table = null;
3244     table = TEST_UTIL.createTable(tableName, fam);
3245     int i = 1;
3246     List<Put> puts = new ArrayList<Put>();
3247     for (String labelExp : labelExps) {
3248       Put put = new Put(Bytes.toBytes("row" + i));
3249       put.add(fam, qual, timestamp[i - 1], value);
3250       put.setCellVisibility(new CellVisibility(labelExp));
3251       puts.add(put);
3252       table.put(put);
3253       TEST_UTIL.getHBaseAdmin().flush(tableName);
3254       i++;
3255     }
3256     return table;
3257   }
3258 
3259   public static void addLabels() throws Exception {
3260     PrivilegedExceptionAction<VisibilityLabelsResponse> action =
3261         new PrivilegedExceptionAction<VisibilityLabelsResponse>() {
3262       @Override
3263       public VisibilityLabelsResponse run() throws Exception {
3264         String[] labels = { SECRET, TOPSECRET, CONFIDENTIAL, PUBLIC, PRIVATE };
3265         try (Connection conn = ConnectionFactory.createConnection(conf)) {
3266           VisibilityClient.addLabels(conn, labels);
3267         } catch (Throwable t) {
3268           throw new IOException(t);
3269         }
3270         return null;
3271       }
3272     };
3273     SUPERUSER.runAs(action);
3274   }
3275   
3276   @SafeVarargs
3277   public static <T> List<T> createList(T... ts) {
3278     return new ArrayList<>(Arrays.asList(ts));
3279   }
3280 }