Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ public static void setTriviallyAllowingTestCode(boolean newValue) {
policyManager.setTriviallyAllowingTestCode(newValue);
}

public static void addEntitledTestPackages(String[] entitledTestPackages) {
policyManager.addEntitledTestPackages(entitledTestPackages);
public static void setEntitledTestPackages(String[] entitledTestPackages) {
policyManager.setEntitledTestPackages(entitledTestPackages);
}

public static void reset() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,11 @@ public void setTriviallyAllowingTestCode(boolean newValue) {
this.isTriviallyAllowingTestCode = newValue;
}

public void addEntitledTestPackages(String[] entitledTestPackages) {
public void setEntitledTestPackages(String... entitledTestPackages) {
assertNoRedundantPrefixes(TEST_FRAMEWORK_PACKAGE_PREFIXES, entitledTestPackages, false);
if (entitledTestPackages.length > 1) {
assertNoRedundantPrefixes(entitledTestPackages, entitledTestPackages, true);
}
String[] packages = ArrayUtils.concat(this.entitledTestPackages, entitledTestPackages);
Arrays.sort(packages);
this.entitledTestPackages = packages;
Expand Down Expand Up @@ -120,13 +124,44 @@ private boolean isEntitlementClass(Class<?> requestingClass) {
}

private boolean isTestFrameworkClass(Class<?> requestingClass) {
String packageName = requestingClass.getPackageName();
int idx = Arrays.binarySearch(entitledTestPackages, packageName);
return isTestFrameworkClass(entitledTestPackages, requestingClass.getPackageName());
}

// no redundant entries allowed, see assertNoRedundantPrefixes
static boolean isTestFrameworkClass(String[] sortedPrefixes, String packageName) {
int idx = Arrays.binarySearch(sortedPrefixes, packageName);
if (idx >= 0) {
return true;
}
idx = -idx - 2; // candidate package (insertion point - 1)
return idx >= 0 && idx < entitledTestPackages.length && packageName.startsWith(entitledTestPackages[idx]);
idx = -idx - 2; // candidate package index (insertion point - 1)
if (idx >= 0 && idx < sortedPrefixes.length) {
String candidate = sortedPrefixes[idx];
if (packageName.startsWith(candidate)
&& (packageName.length() == candidate.length() || packageName.charAt(candidate.length()) == '.')) {
return true;
}
}
return false;
}

private static boolean isNotPrefixMatch(String name, String prefix, boolean discardExactMatch) {
assert prefix.endsWith(".") == false : "Invalid package prefix ending with '.' [" + prefix + "]";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some ideas:

Another approach might be to make the period at the end mandatory. Then a simple prefix match would work.

A third approach would be to add the period automatically to all prefixes. Again the simple prefix match would work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about it. In either case, it shouldn't be lenient. So I either have to check the final dot is not there OR always require it to be there. Not much of a difference imho.

if (name == prefix || name.startsWith(prefix)) {
if (name.length() == prefix.length()) {
return discardExactMatch;
}
return false == (name.length() > prefix.length() && name.charAt(prefix.length()) == '.');
}
return true;
}

static void assertNoRedundantPrefixes(String[] setA, String[] setB, boolean discardExactMatch) {
for (String a : setA) {
for (String b : setB) {
assert isNotPrefixMatch(a, b, discardExactMatch) && isNotPrefixMatch(b, a, discardExactMatch)
: "Redundant prefix entries: [" + a + ", " + b + "]";
}
}
}

private boolean isTestCode(Class<?> requestingClass) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -536,7 +536,7 @@ public static void setupEntitlementsForClass() {
if (entitledPackages != null) {
assert withEntitlementsOnTestCode == false : "Cannot use @WithEntitlementsOnTestCode together with @EntitledTestPackages";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

these contradict each other

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. Why is that? I can imagine a case where we want entitlements enforced on test code, but also want to grant certain test packages.

assert entitledPackages.value().length > 0 : "No test packages specified in @EntitledTestPackages";
TestEntitlementBootstrap.addEntitledTestPackages(entitledPackages.value());
TestEntitlementBootstrap.setEntitledTestPackages(entitledPackages.value());
}
} else if (withEntitlementsOnTestCode) {
throw new AssertionError(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,15 @@
import org.elasticsearch.test.ESTestCase;
import org.junit.Before;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import static org.elasticsearch.entitlement.runtime.policy.PolicyManager.ComponentKind.PLUGIN;
import static org.hamcrest.Matchers.both;
import static org.hamcrest.Matchers.containsString;
import static org.hamcrest.Matchers.equalTo;

public class TestPolicyManagerTests extends ESTestCase {
TestPolicyManager policyManager;
Expand Down Expand Up @@ -60,4 +64,43 @@ public void testIsTriviallyAllowed() {
policyManager.setTriviallyAllowingTestCode(false);
assertFalse(policyManager.isTriviallyAllowed(getClass()));
}

public void testDefaultEntitledTestPackages() {
String[] testPackages = policyManager.entitledTestPackages.clone();
TestPolicyManager.assertNoRedundantPrefixes(testPackages, testPackages, true);

Arrays.sort(testPackages);
assertThat("Entitled test framework packages are not sorted", policyManager.entitledTestPackages, equalTo(testPackages));
}

public void testRejectSetRedundantEntitledTestPackages() {
var throwable = expectThrows(AssertionError.class, () -> policyManager.setEntitledTestPackages("org.apache.lucene.tests"));
var baseMatcher = both(containsString("Redundant prefix entries"));
assertThat(throwable.getMessage(), baseMatcher.and(containsString("org.apache.lucene.tests, org.apache.lucene.tests")));

throwable = expectThrows(AssertionError.class, () -> policyManager.setEntitledTestPackages("org.apache.lucene"));
assertThat(throwable.getMessage(), baseMatcher.and(containsString("org.apache.lucene.tests, org.apache.lucene")));

throwable = expectThrows(AssertionError.class, () -> policyManager.setEntitledTestPackages("org.apache.lucene.tests.whatever"));
assertThat(throwable.getMessage(), baseMatcher.and(containsString("org.apache.lucene.tests, org.apache.lucene.tests.whatever")));

throwable = expectThrows(AssertionError.class, () -> policyManager.setEntitledTestPackages("my.package", "my.package.sub"));
assertThat(throwable.getMessage(), baseMatcher.and(containsString("my.package, my.package.sub")));

throwable = expectThrows(AssertionError.class, () -> policyManager.setEntitledTestPackages("trailing.dot."));
assertThat(throwable.getMessage(), containsString("Invalid package prefix ending with '.' [trailing.dot.]"));
}

public void testIsTestFrameworkClass() {
String[] sortedPrefixes = { "a.b", "a.bc", "a.c" };

assertTrue(TestPolicyManager.isTestFrameworkClass(sortedPrefixes, "a.b"));
assertTrue(TestPolicyManager.isTestFrameworkClass(sortedPrefixes, "a.b.c"));
assertTrue(TestPolicyManager.isTestFrameworkClass(sortedPrefixes, "a.bc"));
assertTrue(TestPolicyManager.isTestFrameworkClass(sortedPrefixes, "a.bc.a"));

assertFalse(TestPolicyManager.isTestFrameworkClass(sortedPrefixes, "a"));
assertFalse(TestPolicyManager.isTestFrameworkClass(sortedPrefixes, "a.ba"));
assertFalse(TestPolicyManager.isTestFrameworkClass(sortedPrefixes, "a.bcc"));
}
}