Skip to content

Commit 33c0e54

Browse files
l46kokcopybara-github
authored andcommitted
Restructure Java test runner to not require JVM classinfo inspection for loading descriptors
PiperOrigin-RevId: 900811839
1 parent 4f9a3a8 commit 33c0e54

13 files changed

Lines changed: 169 additions & 131 deletions

common/BUILD.bazel

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,14 @@ java_library(
118118
exports = ["//common/src/main/java/dev/cel/common:cel_descriptor_util"],
119119
)
120120

121+
java_library(
122+
name = "proto_java_qualified_names",
123+
visibility = [
124+
"//:internal",
125+
],
126+
exports = ["//common/src/main/java/dev/cel/common/internal:proto_java_qualified_names"],
127+
)
128+
121129
java_library(
122130
name = "operator",
123131
exports = ["//common/src/main/java/dev/cel/common:operator"],

testing/BUILD.bazel

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,3 +45,8 @@ java_library(
4545
name = "expr_value_utils",
4646
exports = ["//testing/src/main/java/dev/cel/testing/utils:expr_value_utils"],
4747
)
48+
49+
java_library(
50+
name = "dynamic_default_instance_message_factory",
51+
exports = ["//testing/src/main/java/dev/cel/testing/utils:dynamic_default_instance_message_factory"],
52+
)

testing/src/main/java/dev/cel/testing/testrunner/BUILD.bazel

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ java_library(
8686
":cel_expression_source",
8787
":cel_test_context",
8888
":cel_test_suite",
89+
":proto_descriptor_utils",
8990
":registry_utils",
9091
":result_matcher",
9192
"//bundle:cel",
@@ -104,7 +105,6 @@ java_library(
104105
"//policy:validation_exception",
105106
"//runtime",
106107
"//testing:expr_value_utils",
107-
"//testing/testrunner:proto_descriptor_utils",
108108
"@cel_spec//proto/cel/expr:expr_java_proto",
109109
"@maven//:com_google_guava_guava",
110110
"@maven//:com_google_protobuf_protobuf_java",
@@ -162,14 +162,14 @@ java_library(
162162
deps = [
163163
":cel_expression_source",
164164
":default_result_matcher",
165+
":proto_descriptor_utils",
165166
":result_matcher",
166167
"//:auto_value",
167168
"//bundle:cel",
168169
"//common:cel_descriptor_util",
169170
"//common:options",
170171
"//policy:parser",
171172
"//runtime",
172-
"//testing/testrunner:proto_descriptor_utils",
173173
"@maven//:com_google_errorprone_error_prone_annotations",
174174
"@maven//:com_google_guava_guava",
175175
"@maven//:com_google_protobuf_protobuf_java",
@@ -182,8 +182,19 @@ java_library(
182182
tags = [
183183
],
184184
deps = [
185-
"//common/internal:default_instance_message_factory",
186-
"//testing/testrunner:proto_descriptor_utils",
185+
":proto_descriptor_utils",
186+
"//testing:dynamic_default_instance_message_factory",
187+
"@maven//:com_google_protobuf_protobuf_java",
188+
],
189+
)
190+
191+
java_library(
192+
name = "proto_descriptor_utils",
193+
srcs = ["ProtoDescriptorUtils.java"],
194+
deps = [
195+
"//common:cel_descriptor_util",
196+
"//common:cel_descriptors",
197+
"@maven//:com_google_guava_guava",
187198
"@maven//:com_google_protobuf_protobuf_java",
188199
],
189200
)

testing/src/main/java/dev/cel/testing/testrunner/CelTestContext.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import dev.cel.common.CelOptions;
2929
import dev.cel.policy.CelPolicyParser;
3030
import dev.cel.runtime.CelLateFunctionBindings;
31-
import dev.cel.testing.utils.ProtoDescriptorUtils;
3231
import java.io.IOException;
3332
import java.util.Arrays;
3433
import java.util.Map;
@@ -139,7 +138,7 @@ public Optional<TypeRegistry> typeRegistry() {
139138
if (fileDescriptorSetPath().isPresent()) {
140139
try {
141140
builder.add(
142-
ProtoDescriptorUtils.getAllDescriptorsFromJvm(fileDescriptorSetPath().get())
141+
ProtoDescriptorUtils.getDescriptorsFromFile(fileDescriptorSetPath().get())
143142
.messageTypeDescriptors());
144143
} catch (IOException e) {
145144
throw new IllegalStateException(
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
// Copyright 2026 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// https://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
package dev.cel.testing.testrunner;
16+
17+
import com.google.common.io.Files;
18+
import com.google.protobuf.DescriptorProtos.FileDescriptorSet;
19+
import com.google.protobuf.ExtensionRegistry;
20+
import dev.cel.common.CelDescriptorUtil;
21+
import dev.cel.common.CelDescriptors;
22+
import java.io.File;
23+
import java.io.IOException;
24+
25+
/** Utility class for working with proto descriptors. */
26+
final class ProtoDescriptorUtils {
27+
28+
private static CelDescriptors descriptors;
29+
private static String lastPath;
30+
31+
/**
32+
* Returns all the descriptors from the file descriptor set file.
33+
*
34+
* @return The {@link CelDescriptors} object containing all the descriptors.
35+
*/
36+
static synchronized CelDescriptors getDescriptorsFromFile(String fileDescriptorSetPath)
37+
throws IOException {
38+
if (fileDescriptorSetPath.equals(lastPath) && descriptors != null) {
39+
return descriptors;
40+
}
41+
FileDescriptorSet fileDescriptorSet = getFileDescriptorSet(fileDescriptorSetPath);
42+
descriptors = CelDescriptorUtil.getAllDescriptorsFromFileDescriptor(
43+
CelDescriptorUtil.getFileDescriptorsFromFileDescriptorSet(fileDescriptorSet));
44+
lastPath = fileDescriptorSetPath;
45+
return descriptors;
46+
}
47+
48+
private static FileDescriptorSet getFileDescriptorSet(String fileDescriptorSetPath)
49+
throws IOException {
50+
// We can pass an empty extension registry here because extensions are recovered later when
51+
// creating the extension registry in {@link #createExtensionRegistry}.
52+
return FileDescriptorSet.parseFrom(
53+
Files.toByteArray(new File(fileDescriptorSetPath)), ExtensionRegistry.newInstance());
54+
}
55+
56+
private ProtoDescriptorUtils() {}
57+
}

testing/src/main/java/dev/cel/testing/testrunner/RegistryUtils.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,13 @@
1313
// limitations under the License.
1414
package dev.cel.testing.testrunner;
1515

16-
import static dev.cel.testing.utils.ProtoDescriptorUtils.getAllDescriptorsFromJvm;
16+
1717

1818
import com.google.protobuf.Descriptors.FieldDescriptor;
1919
import com.google.protobuf.ExtensionRegistry;
2020
import com.google.protobuf.Message;
2121
import com.google.protobuf.TypeRegistry;
22-
import dev.cel.common.internal.DefaultInstanceMessageFactory;
22+
import dev.cel.testing.utils.DynamicDefaultInstanceMessageFactory;
2323
import java.io.IOException;
2424
import java.util.NoSuchElementException;
2525

@@ -29,7 +29,7 @@ public final class RegistryUtils {
2929
/** Returns the {@link TypeRegistry} for the given file descriptor set. */
3030
public static TypeRegistry getTypeRegistry(String fileDescriptorSetPath) throws IOException {
3131
return TypeRegistry.newBuilder()
32-
.add(getAllDescriptorsFromJvm(fileDescriptorSetPath).messageTypeDescriptors())
32+
.add(ProtoDescriptorUtils.getDescriptorsFromFile(fileDescriptorSetPath).messageTypeDescriptors())
3333
.build();
3434
}
3535

@@ -38,13 +38,13 @@ public static ExtensionRegistry getExtensionRegistry(String fileDescriptorSetPat
3838
throws IOException {
3939
ExtensionRegistry extensionRegistry = ExtensionRegistry.newInstance();
4040

41-
getAllDescriptorsFromJvm(fileDescriptorSetPath)
41+
ProtoDescriptorUtils.getDescriptorsFromFile(fileDescriptorSetPath)
4242
.extensionDescriptors()
4343
.forEach(
4444
(descriptorName, descriptor) -> {
4545
if (descriptor.getType().equals(FieldDescriptor.Type.MESSAGE)) {
4646
Message output =
47-
DefaultInstanceMessageFactory.getInstance()
47+
DynamicDefaultInstanceMessageFactory.getInstance()
4848
.getPrototype(descriptor.getMessageType())
4949
.orElseThrow(
5050
() ->

testing/src/main/java/dev/cel/testing/testrunner/TestExecutor.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,8 @@ public String describe() {
236236
testResult.setStatus(JUnitXmlReporter.TestResult.FAILURE);
237237
testResult.setThrowable(result.getFailures().get(0).getException());
238238
testReporter.onTestFailure(testResult);
239+
System.err.println("Test failed: " + testName);
240+
result.getFailures().forEach(failure -> failure.getException().printStackTrace());
239241
}
240242
}
241243
}

testing/src/main/java/dev/cel/testing/testrunner/TestRunnerLibrary.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@
5252
import dev.cel.testing.testrunner.CelTestSuite.CelTestSection.CelTestCase;
5353
import dev.cel.testing.testrunner.CelTestSuite.CelTestSection.CelTestCase.Input.Binding;
5454
import dev.cel.testing.testrunner.ResultMatcher.ResultMatcherParams;
55-
import dev.cel.testing.utils.ProtoDescriptorUtils;
5655
import java.io.File;
5756
import java.io.IOException;
5857
import java.nio.file.Paths;
@@ -206,7 +205,7 @@ private static Cel extendCel(CelTestContext celTestContext, CelOptions celOption
206205
extendedCel
207206
.toCelBuilder()
208207
.addMessageTypes(
209-
ProtoDescriptorUtils.getAllDescriptorsFromJvm(
208+
ProtoDescriptorUtils.getDescriptorsFromFile(
210209
celTestContext.fileDescriptorSetPath().get())
211210
.messageTypeDescriptors())
212211
.setExtensionRegistry(

testing/src/main/java/dev/cel/testing/utils/BUILD.bazel

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,7 @@ java_library(
1515
tags = [
1616
],
1717
deps = [
18-
"//common:cel_descriptor_util",
19-
"//common:cel_descriptors",
20-
"//common/internal:default_instance_message_factory",
18+
":dynamic_default_instance_message_factory",
2119
"//common/internal:proto_time_utils",
2220
"//common/types",
2321
"//common/types:type_providers",
@@ -26,8 +24,6 @@ java_library(
2624
"//runtime:unknown_attributes",
2725
"//testing/testrunner:registry_utils",
2826
"@cel_spec//proto/cel/expr:expr_java_proto",
29-
"@cel_spec//proto/cel/expr/conformance/proto2:test_all_types_java_proto",
30-
"@cel_spec//proto/cel/expr/conformance/proto3:test_all_types_java_proto",
3127
"@maven//:com_google_guava_guava",
3228
"@maven//:com_google_protobuf_protobuf_java",
3329
"@maven_android//:com_google_protobuf_protobuf_javalite",
@@ -41,21 +37,19 @@ java_library(
4137
],
4238
deps = [
4339
"@maven//:com_google_guava_guava",
44-
"@maven//:com_google_protobuf_protobuf_java",
4540
"@maven//:io_github_classgraph_classgraph",
4641
],
4742
)
4843

4944
java_library(
50-
name = "proto_descriptor_utils",
51-
srcs = ["ProtoDescriptorUtils.java"],
52-
tags = [
45+
name = "dynamic_default_instance_message_factory",
46+
srcs = ["DynamicDefaultInstanceMessageFactory.java"],
47+
visibility = [
48+
"//testing:__pkg__",
49+
"//testing/src/main/java/dev/cel/testing/testrunner:__pkg__",
5350
],
5451
deps = [
55-
"//common:cel_descriptor_util",
56-
"//common:cel_descriptors",
57-
"//testing/testrunner:class_loader_utils",
58-
"@maven//:com_google_guava_guava",
52+
"//common:proto_java_qualified_names",
5953
"@maven//:com_google_protobuf_protobuf_java",
6054
],
6155
)

testing/src/main/java/dev/cel/testing/utils/ClassLoaderUtils.java

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,51 +15,19 @@
1515

1616
import com.google.common.base.Supplier;
1717
import com.google.common.base.Suppliers;
18-
import com.google.common.collect.ImmutableList;
19-
import com.google.protobuf.Descriptors.Descriptor;
2018
import io.github.classgraph.ClassGraph;
2119
import io.github.classgraph.ClassInfo;
2220
import io.github.classgraph.ClassInfoList;
2321
import io.github.classgraph.ScanResult;
24-
import java.io.IOException;
25-
import java.lang.reflect.InvocationTargetException;
26-
import java.util.logging.Logger;
2722

2823
/** Utility class for loading classes using {@link ClassGraph}. */
2924
public final class ClassLoaderUtils {
3025

31-
private static final Logger logger = Logger.getLogger(ClassLoaderUtils.class.getName());
32-
3326
// Using `enableAllInfo()` to scan all class files upfront. This avoids repeated parsing
3427
// of class files by individual methods, improving efficiency.
3528
private static final Supplier<ScanResult> CLASS_SCAN_RESULT =
3629
Suppliers.memoize(() -> new ClassGraph().enableAllInfo().scan());
3730

38-
/**
39-
* Loads all descriptor type classes from the JVM.
40-
*
41-
* @return A list of {@link Descriptor} objects representing the descriptors loaded from the JVM.
42-
* @throws IOException If there is an error during the loading process.
43-
*/
44-
public static ImmutableList<Descriptor> loadDescriptors() throws IOException {
45-
ClassInfoList classInfoList = CLASS_SCAN_RESULT.get().getAllStandardClasses();
46-
ImmutableList.Builder<Descriptor> compileTimeLoadedDescriptors = ImmutableList.builder();
47-
48-
for (ClassInfo classInfo : classInfoList) {
49-
try {
50-
Class<?> classInfoClass = classInfo.loadClass();
51-
Descriptor descriptor = (Descriptor) classInfoClass.getMethod("getDescriptor").invoke(null);
52-
compileTimeLoadedDescriptors.add(descriptor);
53-
} catch (InvocationTargetException e) {
54-
logger.severe(
55-
"Failed to load descriptor: " + classInfo.getName() + " with error: " + e);
56-
} catch (Exception e) {
57-
// Ignore classes that do not have a getDescriptor method.
58-
}
59-
}
60-
return compileTimeLoadedDescriptors.build();
61-
}
62-
6331
/**
6432
* Loads all subclasses of the given class from the JVM.
6533
*

0 commit comments

Comments
 (0)