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