Skip to content

Commit 5b9fcaa

Browse files
authored
Clean up PolicyManager and ScopeResolver tests (#127115) (#127238)
* Simplify PolicyManagerTests * Clean and simplify ScopeResolverTests
1 parent 65c6ea6 commit 5b9fcaa

File tree

3 files changed

+90
-282
lines changed

3 files changed

+90
-282
lines changed

libs/entitlement/src/test/java/org/elasticsearch/entitlement/runtime/policy/PolicyManagerTests.java

Lines changed: 53 additions & 236 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.elasticsearch.entitlement.runtime.policy.entitlements.CreateClassLoaderEntitlement;
2020
import org.elasticsearch.entitlement.runtime.policy.entitlements.ExitVMEntitlement;
2121
import org.elasticsearch.entitlement.runtime.policy.entitlements.FilesEntitlement;
22+
import org.elasticsearch.entitlement.runtime.policy.entitlements.OutboundNetworkEntitlement;
2223
import org.elasticsearch.test.ESTestCase;
2324
import org.elasticsearch.test.compiler.InMemoryJavaCompiler;
2425
import org.elasticsearch.test.jar.JarUtils;
@@ -31,20 +32,17 @@
3132
import java.net.URL;
3233
import java.net.URLClassLoader;
3334
import java.nio.file.Path;
34-
import java.util.Arrays;
3535
import java.util.List;
3636
import java.util.Map;
3737
import java.util.Set;
38+
import java.util.concurrent.atomic.AtomicReference;
3839
import java.util.stream.Stream;
3940

4041
import static java.util.Map.entry;
41-
import static org.elasticsearch.entitlement.runtime.policy.PolicyManager.ALL_UNNAMED;
4242
import static org.elasticsearch.entitlement.runtime.policy.PolicyManager.ComponentKind.SERVER;
43-
import static org.hamcrest.Matchers.aMapWithSize;
4443
import static org.hamcrest.Matchers.allOf;
4544
import static org.hamcrest.Matchers.containsString;
4645
import static org.hamcrest.Matchers.is;
47-
import static org.hamcrest.Matchers.sameInstance;
4846

4947
@ESTestCase.WithoutSecurityManager
5048
public class PolicyManagerTests extends ESTestCase {
@@ -89,223 +87,81 @@ public static void beforeClass() {
8987
}
9088
}
9189

92-
public void testGetEntitlementsThrowsOnMissingPluginUnnamedModule() {
93-
var plugin1SourcePath = Path.of("modules", "plugin1");
94-
var policyManager = new PolicyManager(
95-
createEmptyTestServerPolicy(),
96-
List.of(),
97-
Map.of("plugin1", createPluginPolicy("plugin.module")),
98-
c -> PolicyScope.plugin("plugin1", moduleName(c)),
99-
Map.of("plugin1", plugin1SourcePath),
100-
NO_ENTITLEMENTS_MODULE,
101-
TEST_PATH_LOOKUP,
102-
Set.of()
103-
);
104-
105-
// Any class from the current module (unnamed) will do
106-
var callerClass = this.getClass();
107-
var requestingModule = callerClass.getModule();
108-
109-
assertEquals(
110-
"No policy for the unnamed module",
111-
policyManager.defaultEntitlements("plugin1", plugin1SourcePath, requestingModule.getName()),
112-
policyManager.getEntitlements(callerClass)
113-
);
114-
115-
assertEquals(
116-
Map.of(requestingModule, policyManager.defaultEntitlements("plugin1", plugin1SourcePath, requestingModule.getName())),
117-
policyManager.moduleEntitlementsMap
118-
);
119-
}
120-
121-
public void testGetEntitlementsThrowsOnMissingPolicyForPlugin() {
122-
var plugin1SourcePath = Path.of("modules", "plugin1");
123-
var policyManager = new PolicyManager(
124-
createEmptyTestServerPolicy(),
125-
List.of(),
126-
Map.of(),
127-
c -> PolicyScope.plugin("plugin1", moduleName(c)),
128-
Map.of("plugin1", plugin1SourcePath),
129-
NO_ENTITLEMENTS_MODULE,
130-
TEST_PATH_LOOKUP,
131-
Set.of()
132-
);
133-
134-
// Any class from the current module (unnamed) will do
135-
var callerClass = this.getClass();
136-
var requestingModule = callerClass.getModule();
137-
138-
assertEquals(
139-
"No policy for this plugin",
140-
policyManager.defaultEntitlements("plugin1", plugin1SourcePath, requestingModule.getName()),
141-
policyManager.getEntitlements(callerClass)
142-
);
90+
public void testGetEntitlements() {
91+
// A mutable policyScope we can use to program specific replies
92+
AtomicReference<PolicyScope> policyScope = new AtomicReference<>();
14393

144-
assertEquals(
145-
Map.of(requestingModule, policyManager.defaultEntitlements("plugin1", plugin1SourcePath, requestingModule.getName())),
146-
policyManager.moduleEntitlementsMap
147-
);
148-
}
149-
150-
public void testGetEntitlementsFailureIsCached() {
94+
// A common policy with a variety of entitlements to test
95+
Path thisSourcePath = PolicyManager.getComponentPathFromClass(getClass());
15196
var plugin1SourcePath = Path.of("modules", "plugin1");
15297
var policyManager = new PolicyManager(
153-
createEmptyTestServerPolicy(),
98+
new Policy("server", List.of(new Scope("org.example.httpclient", List.of(new OutboundNetworkEntitlement())))),
15499
List.of(),
155-
Map.of(),
156-
c -> PolicyScope.plugin("plugin1", moduleName(c)),
100+
Map.of("plugin1", new Policy("plugin1", List.of(new Scope("plugin.module1", List.of(new ExitVMEntitlement()))))),
101+
c -> policyScope.get(),
157102
Map.of("plugin1", plugin1SourcePath),
158103
NO_ENTITLEMENTS_MODULE,
159104
TEST_PATH_LOOKUP,
160105
Set.of()
161106
);
162107

163-
// Any class from the current module (unnamed) will do
164-
var callerClass = this.getClass();
165-
var requestingModule = callerClass.getModule();
108+
// "Unspecified" below means that the module is not named in the policy
166109

167-
assertEquals(
168-
policyManager.defaultEntitlements("plugin1", plugin1SourcePath, requestingModule.getName()),
169-
policyManager.getEntitlements(callerClass)
170-
);
171-
assertEquals(
172-
Map.of(requestingModule, policyManager.defaultEntitlements("plugin1", plugin1SourcePath, requestingModule.getName())),
173-
policyManager.moduleEntitlementsMap
110+
policyScope.set(PolicyScope.server("org.example.httpclient"));
111+
resetAndCheckEntitlements(
112+
"Specified entitlements for server",
113+
getClass(),
114+
policyManager.policyEntitlements(
115+
SERVER.componentName,
116+
thisSourcePath,
117+
"org.example.httpclient",
118+
List.of(new OutboundNetworkEntitlement())
119+
),
120+
policyManager
174121
);
175122

176-
// A second time
177-
assertEquals(
178-
policyManager.defaultEntitlements("plugin1", plugin1SourcePath, requestingModule.getName()),
179-
policyManager.getEntitlements(callerClass)
123+
policyScope.set(PolicyScope.server("plugin.unspecifiedModule"));
124+
resetAndCheckEntitlements(
125+
"Default entitlements for unspecified module",
126+
getClass(),
127+
policyManager.defaultEntitlements(SERVER.componentName, thisSourcePath, "plugin.unspecifiedModule"),
128+
policyManager
180129
);
181130

182-
// Nothing new in the map
183-
assertEquals(
184-
Map.of(requestingModule, policyManager.defaultEntitlements("plugin1", plugin1SourcePath, requestingModule.getName())),
185-
policyManager.moduleEntitlementsMap
131+
policyScope.set(PolicyScope.plugin("plugin1", "plugin.module1"));
132+
resetAndCheckEntitlements(
133+
"Specified entitlements for plugin",
134+
getClass(),
135+
policyManager.policyEntitlements("plugin1", plugin1SourcePath, "plugin.module1", List.of(new ExitVMEntitlement())),
136+
policyManager
186137
);
187-
}
188138

189-
public void testGetEntitlementsReturnsEntitlementsForPluginUnnamedModule() {
190-
var policyManager = new PolicyManager(
191-
createEmptyTestServerPolicy(),
192-
List.of(),
193-
Map.ofEntries(entry("plugin2", createPluginPolicy(ALL_UNNAMED))),
194-
c -> PolicyScope.plugin("plugin2", moduleName(c)),
195-
Map.of("plugin2", Path.of("modules", "plugin2")),
196-
NO_ENTITLEMENTS_MODULE,
197-
TEST_PATH_LOOKUP,
198-
Set.of()
139+
policyScope.set(PolicyScope.plugin("plugin1", "plugin.unspecifiedModule"));
140+
resetAndCheckEntitlements(
141+
"Default entitlements for plugin",
142+
getClass(),
143+
policyManager.defaultEntitlements("plugin1", plugin1SourcePath, "plugin.unspecifiedModule"),
144+
policyManager
199145
);
200-
201-
// Any class from the current module (unnamed) will do
202-
var callerClass = this.getClass();
203-
204-
var entitlements = policyManager.getEntitlements(callerClass);
205-
assertThat(entitlements.hasEntitlement(CreateClassLoaderEntitlement.class), is(true));
206146
}
207147

208-
public void testGetEntitlementsReturnsDefaultOnMissingPolicyForServer() throws ClassNotFoundException {
209-
var policyManager = new PolicyManager(
210-
createTestServerPolicy("example"),
211-
List.of(),
212-
Map.of(),
213-
c -> PolicyScope.server(moduleName(c)),
214-
Map.of(),
215-
NO_ENTITLEMENTS_MODULE,
216-
TEST_PATH_LOOKUP,
217-
Set.of()
218-
);
219-
220-
// Any class will do, since our resolver is hardcoded to use SERVER_COMPONENT_NAME.
221-
// Let's pick one with a known module name.
222-
String httpserverModuleName = "jdk.httpserver";
223-
var mockServerClass = ModuleLayer.boot().findLoader(httpserverModuleName).loadClass("com.sun.net.httpserver.HttpServer");
224-
var mockServerSourcePath = PolicyManager.getComponentPathFromClass(mockServerClass);
225-
var requestingModule = mockServerClass.getModule();
226-
148+
private void resetAndCheckEntitlements(
149+
String message,
150+
Class<?> requestingClass,
151+
ModuleEntitlements expectedEntitlements,
152+
PolicyManager policyManager
153+
) {
154+
policyManager.moduleEntitlementsMap.clear();
155+
assertEquals(message, expectedEntitlements, policyManager.getEntitlements(requestingClass));
227156
assertEquals(
228-
"No policy for this module in server",
229-
policyManager.defaultEntitlements(SERVER.componentName, mockServerSourcePath, httpserverModuleName),
230-
policyManager.getEntitlements(mockServerClass)
231-
);
232-
233-
assertEquals(
234-
Map.of(requestingModule, policyManager.defaultEntitlements(SERVER.componentName, mockServerSourcePath, httpserverModuleName)),
157+
"Map has precisely the one expected entry",
158+
Map.of(requestingClass.getModule(), expectedEntitlements),
235159
policyManager.moduleEntitlementsMap
236160
);
237-
}
238161

239-
public void testGetEntitlementsReturnsEntitlementsForServerModule() throws ClassNotFoundException {
240-
String httpserverModuleName = "jdk.httpserver";
241-
var policyManager = new PolicyManager(
242-
createTestServerPolicy(httpserverModuleName),
243-
List.of(),
244-
Map.of(),
245-
c -> PolicyScope.server(moduleName(c)),
246-
Map.of(),
247-
NO_ENTITLEMENTS_MODULE,
248-
TEST_PATH_LOOKUP,
249-
Set.of()
250-
);
251-
252-
// Any class will do, since our resolver is hardcoded to use SERVER_COMPONENT_NAME.
253-
// Let's pick one with a known module name.
254-
var mockServerClass = ModuleLayer.boot().findLoader(httpserverModuleName).loadClass("com.sun.net.httpserver.HttpServer");
255-
256-
var entitlements = policyManager.getEntitlements(mockServerClass);
257-
assertThat(entitlements.hasEntitlement(CreateClassLoaderEntitlement.class), is(true));
258-
assertThat(entitlements.hasEntitlement(ExitVMEntitlement.class), is(true));
259-
}
260-
261-
public void testGetEntitlementsReturnsEntitlementsForPluginModule() throws IOException, ClassNotFoundException {
262-
final Path home = createTempDir();
263-
264-
Path jar = createMockPluginJar(home);
265-
266-
var policyManager = new PolicyManager(
267-
createEmptyTestServerPolicy(),
268-
List.of(),
269-
Map.of("mock-plugin", createPluginPolicy("org.example.plugin")),
270-
c -> PolicyScope.plugin("mock-plugin", moduleName(c)),
271-
Map.of("mock-plugin", Path.of("modules", "mock-plugin")),
272-
NO_ENTITLEMENTS_MODULE,
273-
TEST_PATH_LOOKUP,
274-
Set.of()
275-
);
276-
277-
var layer = createLayerForJar(jar, "org.example.plugin");
278-
var mockPluginClass = layer.findLoader("org.example.plugin").loadClass("q.B");
279-
280-
var entitlements = policyManager.getEntitlements(mockPluginClass);
281-
assertThat(entitlements.hasEntitlement(CreateClassLoaderEntitlement.class), is(true));
282-
assertThat(entitlements.fileAccess().canRead(TEST_BASE_DIR), is(true));
283-
}
284-
285-
public void testGetEntitlementsResultIsCached() {
286-
var policyManager = new PolicyManager(
287-
createEmptyTestServerPolicy(),
288-
List.of(),
289-
Map.ofEntries(entry("plugin2", createPluginPolicy(ALL_UNNAMED))),
290-
c -> PolicyScope.plugin("plugin2", moduleName(c)),
291-
Map.of("plugin2", Path.of("modules", "plugin2")),
292-
NO_ENTITLEMENTS_MODULE,
293-
TEST_PATH_LOOKUP,
294-
Set.of()
295-
);
296-
297-
// Any class from the current module (unnamed) will do
298-
var callerClass = this.getClass();
299-
300-
var entitlements = policyManager.getEntitlements(callerClass);
301-
assertThat(entitlements.hasEntitlement(CreateClassLoaderEntitlement.class), is(true));
302-
assertThat(policyManager.moduleEntitlementsMap, aMapWithSize(1));
303-
var cachedResult = policyManager.moduleEntitlementsMap.values().stream().findFirst().orElseThrow();
304-
var entitlementsAgain = policyManager.getEntitlements(callerClass);
305-
306-
// Nothing new in the map
307-
assertThat(policyManager.moduleEntitlementsMap, aMapWithSize(1));
308-
assertThat(entitlementsAgain, sameInstance(cachedResult));
162+
// Fetch a second time and verify the map is unchanged
163+
policyManager.getEntitlements(requestingClass);
164+
assertEquals("Map is unchanged", Map.of(requestingClass.getModule(), expectedEntitlements), policyManager.moduleEntitlementsMap);
309165
}
310166

311167
public void testRequestingClassFastPath() throws IOException, ClassNotFoundException {
@@ -560,24 +416,6 @@ public void testFilesEntitlementsWithExclusive() {
560416
);
561417
}
562418

563-
/**
564-
* If the plugin resolver tells us a class is in a plugin, don't conclude that it's in an agent.
565-
*/
566-
public void testPluginResolverOverridesAgents() {
567-
var policyManager = new PolicyManager(
568-
createEmptyTestServerPolicy(),
569-
List.of(new CreateClassLoaderEntitlement()),
570-
Map.of(),
571-
c -> PolicyScope.plugin("test", moduleName(c)), // Insist that the class is in a plugin
572-
Map.of(),
573-
NO_ENTITLEMENTS_MODULE,
574-
TEST_PATH_LOOKUP,
575-
Set.of()
576-
);
577-
ModuleEntitlements notAgentsEntitlements = policyManager.getEntitlements(TestAgent.class);
578-
assertThat(notAgentsEntitlements.hasEntitlement(CreateClassLoaderEntitlement.class), is(false));
579-
}
580-
581419
private static Class<?> makeClassInItsOwnModule() throws IOException, ClassNotFoundException {
582420
final Path home = createTempDir();
583421
Path jar = createMockPluginJar(home);
@@ -602,27 +440,6 @@ private static Policy createEmptyTestServerPolicy() {
602440
return new Policy("server", List.of());
603441
}
604442

605-
private static Policy createTestServerPolicy(String scopeName) {
606-
return new Policy("server", List.of(new Scope(scopeName, List.of(new ExitVMEntitlement(), new CreateClassLoaderEntitlement()))));
607-
}
608-
609-
private static Policy createPluginPolicy(String... pluginModules) {
610-
return new Policy(
611-
"plugin",
612-
Arrays.stream(pluginModules)
613-
.map(
614-
name -> new Scope(
615-
name,
616-
List.of(
617-
new FilesEntitlement(List.of(FilesEntitlement.FileData.ofPath(TEST_BASE_DIR, FilesEntitlement.Mode.READ))),
618-
new CreateClassLoaderEntitlement()
619-
)
620-
)
621-
)
622-
.toList()
623-
);
624-
}
625-
626443
private static Path createMockPluginJarForUnnamedModule(Path home) throws IOException {
627444
Path jar = home.resolve("unnamed-mock-plugin.jar");
628445

0 commit comments

Comments
 (0)