Skip to content

Commit

Permalink
improves VisibilityFilterTest (#4778)
Browse files Browse the repository at this point in the history
The unit test for VisibilityFilter was not testing caching
or default visibility.  Updated to test these features and
improved the coverage of the test to almost all of the code.
  • Loading branch information
keith-turner authored Aug 6, 2024
1 parent 621ad51 commit ea1558e
Showing 1 changed file with 94 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,16 @@
*/
package org.apache.accumulo.core.iterators.system;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeMap;
import java.util.TreeSet;

import org.apache.accumulo.core.data.Key;
import org.apache.accumulo.core.data.Range;
Expand Down Expand Up @@ -57,16 +60,97 @@ public void testEmptyAuths() throws IOException {
tm.put(new Key("r1", "cf1", "cq1", ""), new Value());
tm.put(new Key("r1", "cf1", "cq2", "C"), new Value());
tm.put(new Key("r1", "cf1", "cq3", ""), new Value());
tm.put(new Key("r2", "cf1", "cq2", "C"), new Value());
SortedKeyValueIterator<Key,Value> filter =
VisibilityFilter.wrap(new SortedMapIterator(tm), Authorizations.EMPTY, "".getBytes());
VisibilityFilter.wrap(new SortedMapIterator(tm), Authorizations.EMPTY, "".getBytes(UTF_8));

filter.seek(new Range(), new HashSet<>(), false);
assertTrue(filter.hasTop());
assertEquals(new Key("r1", "cf1", "cq1", ""), filter.getTopKey());
filter.next();
assertTrue(filter.hasTop());
assertEquals(new Key("r1", "cf1", "cq3", ""), filter.getTopKey());
filter.next();
assertFalse(filter.hasTop());
TreeSet<Key> expected = new TreeSet<>();
expected.add(new Key("r1", "cf1", "cq1", ""));
expected.add(new Key("r1", "cf1", "cq3", ""));

verify(expected, filter);
}

@Test
public void testAuths() throws IOException {
TreeMap<Key,Value> tm = new TreeMap<>();

// want to have repeated col vis in order to exercise cache in test
tm.put(new Key("r1", "cf1", "cq1", "A&B"), new Value());
tm.put(new Key("r1", "cf1", "cq2", "A|C"), new Value());
tm.put(new Key("r1", "cf1", "cq3", "A&B"), new Value());
tm.put(new Key("r2", "cf1", "cq2", "A|C"), new Value());
tm.put(new Key("r2", "cf1", "cq3", ""), new Value());
tm.put(new Key("r2", "cf1", "cq2", "C|D"), new Value());
tm.put(new Key("r3", "cf1", "cq2", "C|(A&D)"), new Value());
tm.put(new Key("r4", "cf1", "cq2", "C|D"), new Value());
tm.put(new Key("r5", "cf1", "cq2", "A&B"), new Value());
tm.put(new Key("r5", "cf1", "cq3", ""), new Value());
tm.put(new Key("r6", "cf1", "cq2", "C|(A&D)"), new Value());

SortedKeyValueIterator<Key,Value> filter = VisibilityFilter.wrap(new SortedMapIterator(tm),
new Authorizations("A", "B"), "".getBytes(UTF_8));

TreeSet<Key> expected = new TreeSet<>();
expected.add(new Key("r1", "cf1", "cq1", "A&B"));
expected.add(new Key("r1", "cf1", "cq2", "A|C"));
expected.add(new Key("r1", "cf1", "cq3", "A&B"));
expected.add(new Key("r2", "cf1", "cq2", "A|C"));
expected.add(new Key("r5", "cf1", "cq2", "A&B"));
expected.add(new Key("r2", "cf1", "cq3", ""));
expected.add(new Key("r5", "cf1", "cq3", ""));

verify(expected, filter);
}

private static void verify(TreeSet<Key> expected, SortedKeyValueIterator<Key,Value> iter)
throws IOException {
for (var filter : List.of(iter, iter.deepCopy(null))) {
filter.seek(new Range(), Set.of(), false);
var eiter = expected.iterator();
while (eiter.hasNext() && filter.hasTop()) {
Key ekey = eiter.next();
assertEquals(ekey, filter.getTopKey());
filter.next();
}

assertFalse(filter.hasTop());
assertFalse(eiter.hasNext());
}
}

@Test
public void testDefaultVisibility() throws IOException {
// Test non empty default visibility
var defaultVis = "A&B&C".getBytes(UTF_8);

TreeMap<Key,Value> tm = new TreeMap<>();

tm.put(new Key("r1", "cf1", "cq1", "A&B"), new Value());
tm.put(new Key("r1", "cf1", "cq2", ""), new Value());
tm.put(new Key("r1", "cf1", "cq3", "A&B"), new Value());
tm.put(new Key("r1", "cf1", "cq4", ""), new Value());
// add something that has the same col vis as the defaultVis
tm.put(new Key("r1", "cf1", "cq5", "A&B&C"), new Value());
tm.put(new Key("r1", "cf1", "cq6", ""), new Value());
tm.put(new Key("r1", "cf1", "cq7", "A&B&C"), new Value());

// with the set of auths [A,B] the default visibility is not visible
SortedKeyValueIterator<Key,Value> filter =
VisibilityFilter.wrap(new SortedMapIterator(tm), new Authorizations("A", "B"), defaultVis);

TreeSet<Key> expected = new TreeSet<>();
expected.add(new Key("r1", "cf1", "cq1", "A&B"));
expected.add(new Key("r1", "cf1", "cq3", "A&B"));

verify(expected, filter);

// with the set of auths [A.B.C] should be able to see all data
filter = VisibilityFilter.wrap(new SortedMapIterator(tm), new Authorizations("A", "B", "C"),
defaultVis);
filter.seek(new Range(), Set.of(), false);

verify(new TreeSet<>(tm.keySet()), filter);
}

}

0 comments on commit ea1558e

Please sign in to comment.