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