Skip to content

Commit 0737691

Browse files
l46kokcopybara-github
authored andcommitted
Add conformance tests for planner
PiperOrigin-RevId: 875410045
1 parent 5006390 commit 0737691

18 files changed

Lines changed: 183 additions & 58 deletions

File tree

MODULE.bazel

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,18 +16,23 @@ module(
1616
name = "cel_java",
1717
)
1818

19-
bazel_dep(name = "bazel_skylib", version = "1.8.2")
20-
bazel_dep(name = "rules_jvm_external", version = "6.9")
19+
bazel_dep(name = "bazel_skylib", version = "1.9.0")
20+
bazel_dep(name = "rules_jvm_external", version = "6.10")
2121
bazel_dep(name = "protobuf", version = "33.4", repo_name = "com_google_protobuf") # see https://github.com/bazelbuild/rules_android/issues/373
22-
bazel_dep(name = "googleapis", version = "0.0.0-20241220-5e258e33.bcr.1", repo_name = "com_google_googleapis")
23-
bazel_dep(name = "rules_pkg", version = "1.0.1")
22+
bazel_dep(name = "googleapis", version = "0.0.0-20260223-edfe7983", repo_name = "com_google_googleapis")
23+
bazel_dep(name = "rules_pkg", version = "1.2.0")
2424
bazel_dep(name = "rules_license", version = "1.0.0")
2525
bazel_dep(name = "rules_proto", version = "7.1.0")
2626
bazel_dep(name = "rules_java", version = "9.3.0")
2727
bazel_dep(name = "rules_android", version = "0.7.1")
2828
bazel_dep(name = "rules_shell", version = "0.6.1")
2929
bazel_dep(name = "googleapis-java", version = "1.0.0")
30-
bazel_dep(name = "cel-spec", version = "0.24.0", repo_name = "cel_spec")
30+
bazel_dep(name = "cel-spec", version = "0.25.1", repo_name = "cel_spec")
31+
bazel_dep(name = "rules_go", version = "0.50.1")
32+
33+
# Required by cel-spec to satisfy gazelle transitive dependency
34+
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
35+
go_sdk.download(version = "1.23.0")
3136

3237
switched_rules = use_extension("@com_google_googleapis//:extensions.bzl", "switched_rules")
3338
switched_rules.use_languages(java = True)

bundle/src/main/java/dev/cel/bundle/CelEnvironment.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,10 @@ public CelType toCelType(CelTypeProvider celTypeProvider) {
672672
return TypeParamType.create(name());
673673
}
674674

675+
if (name().equals("dyn")) {
676+
return SimpleType.DYN;
677+
}
678+
675679
CelType simpleType = SimpleType.findByName(name()).orElse(null);
676680
if (simpleType != null) {
677681
return simpleType;

common/src/main/java/dev/cel/common/types/SimpleType.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ public abstract class SimpleType extends CelType {
4646

4747
public static final ImmutableMap<String, CelType> TYPE_MAP =
4848
ImmutableMap.of(
49-
DYN.name(), DYN,
5049
BOOL.name(), BOOL,
5150
BYTES.name(), BYTES,
5251
DOUBLE.name(), DOUBLE,

common/src/main/java/dev/cel/common/values/BaseProtoCelValueConverter.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
import static com.google.common.collect.ImmutableList.toImmutableList;
1818
import static com.google.common.collect.ImmutableMap.toImmutableMap;
1919

20+
import com.google.common.base.CaseFormat;
21+
import com.google.common.base.Joiner;
2022
import com.google.common.base.Preconditions;
2123
import com.google.common.collect.ImmutableList;
2224
import com.google.common.collect.ImmutableMap;
@@ -27,6 +29,7 @@
2729
import com.google.protobuf.BytesValue;
2830
import com.google.protobuf.DoubleValue;
2931
import com.google.protobuf.Duration;
32+
import com.google.protobuf.FieldMask;
3033
import com.google.protobuf.FloatValue;
3134
import com.google.protobuf.Int32Value;
3235
import com.google.protobuf.Int64Value;
@@ -41,6 +44,8 @@
4144
import dev.cel.common.annotations.Internal;
4245
import dev.cel.common.internal.ProtoTimeUtils;
4346
import dev.cel.common.internal.WellKnownProto;
47+
import java.util.ArrayList;
48+
import java.util.List;
4449

4550
/**
4651
* {@code BaseProtoCelValueConverter} contains the common logic for converting between native Java
@@ -98,6 +103,17 @@ protected Object fromWellKnownProto(MessageLiteOrBuilder message, WellKnownProto
98103
return UnsignedLong.valueOf(((UInt32Value) message).getValue());
99104
case UINT64_VALUE:
100105
return UnsignedLong.fromLongBits(((UInt64Value) message).getValue());
106+
case FIELD_MASK:
107+
FieldMask fieldMask = (FieldMask) message;
108+
List<String> paths = new ArrayList<>(fieldMask.getPathsCount());
109+
for (String path : fieldMask.getPathsList()) {
110+
if (!path.isEmpty()) {
111+
paths.add(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, path));
112+
}
113+
}
114+
return normalizePrimitive(Joiner.on(",").join(paths));
115+
case EMPTY:
116+
return ImmutableMap.of();
101117
default:
102118
throw new UnsupportedOperationException(
103119
"Unsupported well known proto conversion - " + wellKnownProto);

common/src/main/java/dev/cel/common/values/CelValueConverter.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ public Object unwrap(CelValue celValue) {
5454
return Optional.of(optionalValue.value());
5555
}
5656

57+
if (celValue instanceof ErrorValue) {
58+
return celValue;
59+
}
60+
5761
return celValue.value();
5862
}
5963

conformance/src/test/java/dev/cel/conformance/BUILD.bazel

Lines changed: 70 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ java_library(
2929
"//parser:parser_builder",
3030
"//parser:parser_factory",
3131
"//runtime",
32+
"//runtime:runtime_planner_impl",
3233
"//testing:expr_value_utils",
3334
"@cel_spec//proto/cel/expr:expr_java_proto",
3435
"@cel_spec//proto/cel/expr/conformance/proto2:test_all_types_java_proto",
@@ -57,6 +58,8 @@ java_library(
5758
deps = MAVEN_JAR_DEPS + [
5859
"//:java_truth",
5960
"//compiler:compiler_builder",
61+
"//parser:parser_factory",
62+
"//runtime:runtime_planner_impl",
6063
"//testing:expr_value_utils",
6164
"@cel_spec//proto/cel/expr:expr_java_proto",
6265
"@cel_spec//proto/cel/expr/conformance/proto2:test_all_types_java_proto",
@@ -100,14 +103,8 @@ _ALL_TESTS = [
100103
"@cel_spec//tests/simple:testdata/wrappers.textproto",
101104
]
102105

103-
_TESTS_TO_SKIP = [
104-
# Tests which require spec changes.
105-
# TODO: Deprecate Duration.get_milliseconds
106-
"timestamps/duration_converters/get_milliseconds",
107-
106+
_TESTS_TO_SKIP_LEGACY = [
108107
# Broken test cases which should be supported.
109-
# TODO: Invalid bytes to string conversion should error.
110-
"conversions/string/bytes_invalid",
111108
# TODO: Support setting / getting enum values out of the defined enum value range.
112109
"enums/legacy_proto2/select_big,select_neg",
113110
"enums/legacy_proto2/assign_standalone_int_big,assign_standalone_int_neg",
@@ -116,7 +113,6 @@ _TESTS_TO_SKIP = [
116113
# TODO: Ensure overflow occurs on conversions of double values which might not work properly on all platforms.
117114
"conversions/int/double_int_min_range",
118115
# TODO: Duration and timestamp operations should error on overflow.
119-
"timestamps/duration_range/from_string_under,from_string_over",
120116
"timestamps/timestamp_range/sub_time_duration_over,sub_time_duration_under",
121117
# TODO: Ensure adding negative duration values is appropriately supported.
122118
"timestamps/timestamp_arithmetic/add_time_to_duration_nanos_negative",
@@ -159,21 +155,85 @@ _TESTS_TO_SKIP = [
159155
"type_deductions/legacy_nullable_types/null_assignable_to_timestamp_parameter_candidate",
160156
]
161157

158+
_TESTS_TO_SKIP_PLANNER = [
159+
# TODO: Add strings.format and strings.quote.
160+
"string_ext/quote",
161+
"string_ext/format",
162+
"string_ext/format_errors",
163+
164+
# TODO: Check behavior for go/cpp
165+
"basic/functions/unbound",
166+
"basic/functions/unbound_is_runtime_error",
167+
168+
# TODO: Ensure overflow occurs on conversions of double values which might not work properly on all platforms.
169+
"conversions/int/double_int_min_range",
170+
"enums/legacy_proto3/assign_standalone_int_too_big",
171+
"enums/legacy_proto3/assign_standalone_int_too_neg",
172+
173+
# TODO: Duration and timestamp operations should error on overflow.
174+
"timestamps/timestamp_range/sub_time_duration_over",
175+
"timestamps/timestamp_range/sub_time_duration_under",
176+
177+
# Skip until fixed.
178+
"fields/qualified_identifier_resolution/map_key_float",
179+
"fields/qualified_identifier_resolution/map_key_null",
180+
"fields/qualified_identifier_resolution/map_value_repeat_key_heterogeneous",
181+
"optionals/optionals/map_null_entry_no_such_key",
182+
"optionals/optionals/map_present_key_invalid_field",
183+
"parse/receiver_function_names",
184+
"proto2/extensions_get/package_scoped_test_all_types_ext",
185+
"proto2/extensions_get/package_scoped_repeated_test_all_types",
186+
"proto2/extensions_get/message_scoped_nested_ext",
187+
"proto2/extensions_get/message_scoped_repeated_test_all_types",
188+
"proto2_ext/get_ext/package_scoped_repeated_test_all_types",
189+
"proto2_ext/get_ext/message_scoped_repeated_test_all_types",
190+
191+
# TODO: Fix null assignment to a field
192+
"proto2/set_null/single_message",
193+
"proto2/set_null/single_duration",
194+
"proto2/set_null/single_timestamp",
195+
"proto3/set_null/single_message",
196+
"proto3/set_null/single_duration",
197+
"proto3/set_null/single_timestamp",
198+
199+
# Type inference edgecases around null(able) assignability.
200+
# These type check, but resolve to a different type.
201+
# list(int), want list(wrapper(int))
202+
"type_deductions/wrappers/wrapper_promotion",
203+
# list(null), want list(Message)
204+
"type_deductions/legacy_nullable_types/null_assignable_to_message_parameter_candidate",
205+
"type_deductions/legacy_nullable_types/null_assignable_to_abstract_parameter_candidate",
206+
"type_deductions/legacy_nullable_types/null_assignable_to_duration_parameter_candidate",
207+
"type_deductions/legacy_nullable_types/null_assignable_to_timestamp_parameter_candidate",
208+
209+
# Future features for CEL 1.0
210+
# TODO: Strong typing support for enums, specified but not implemented.
211+
"enums/strong_proto2",
212+
"enums/strong_proto3",
213+
]
214+
162215
conformance_test(
163216
name = "conformance",
164217
data = _ALL_TESTS,
165-
skip_tests = _TESTS_TO_SKIP,
218+
skip_tests = _TESTS_TO_SKIP_LEGACY,
166219
)
167220

168221
conformance_test(
169222
name = "conformance_maven",
170223
data = _ALL_TESTS,
171224
mode = MODE.MAVEN_TEST,
172-
skip_tests = _TESTS_TO_SKIP,
225+
skip_tests = _TESTS_TO_SKIP_LEGACY,
173226
)
174227

175228
conformance_test(
176229
name = "conformance_dashboard",
177230
data = _ALL_TESTS,
178231
mode = MODE.DASHBOARD,
179232
)
233+
234+
conformance_test(
235+
name = "conformance_planner",
236+
data = _ALL_TESTS,
237+
skip_tests = _TESTS_TO_SKIP_PLANNER,
238+
use_planner = True,
239+
)

conformance/src/test/java/dev/cel/conformance/ConformanceTest.java

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,9 @@
4545
import dev.cel.runtime.CelEvaluationException;
4646
import dev.cel.runtime.CelRuntime;
4747
import dev.cel.runtime.CelRuntime.Program;
48+
import dev.cel.runtime.CelRuntimeBuilder;
4849
import dev.cel.runtime.CelRuntimeFactory;
50+
import dev.cel.runtime.CelRuntimeImpl;
4951
import dev.cel.runtime.CelRuntimeLibrary;
5052
import java.util.Map;
5153
import org.junit.runners.model.Statement;
@@ -118,15 +120,25 @@ private static CelChecker getChecker(SimpleTest test) throws Exception {
118120
.build();
119121
}
120122

121-
private static final CelRuntime RUNTIME =
122-
CelRuntimeFactory.standardCelRuntimeBuilder()
123-
.setOptions(OPTIONS)
124-
.addLibraries(CANONICAL_RUNTIME_EXTENSIONS)
125-
.setExtensionRegistry(DEFAULT_EXTENSION_REGISTRY)
126-
.addMessageTypes(dev.cel.expr.conformance.proto2.TestAllTypes.getDescriptor())
127-
.addMessageTypes(dev.cel.expr.conformance.proto3.TestAllTypes.getDescriptor())
128-
.addFileTypes(dev.cel.expr.conformance.proto2.TestAllTypesExtensions.getDescriptor())
129-
.build();
123+
private static CelRuntime getRuntime(SimpleTest test, boolean usePlanner) {
124+
CelRuntimeBuilder builder =
125+
usePlanner ? CelRuntimeImpl.newBuilder() : CelRuntimeFactory.standardCelRuntimeBuilder();
126+
127+
builder
128+
// CEL-Internal-2
129+
.setOptions(OPTIONS)
130+
.addLibraries(CANONICAL_RUNTIME_EXTENSIONS)
131+
.setExtensionRegistry(DEFAULT_EXTENSION_REGISTRY)
132+
.addMessageTypes(dev.cel.expr.conformance.proto2.TestAllTypes.getDescriptor())
133+
.addMessageTypes(dev.cel.expr.conformance.proto3.TestAllTypes.getDescriptor())
134+
.addFileTypes(dev.cel.expr.conformance.proto2.TestAllTypesExtensions.getDescriptor());
135+
136+
if (usePlanner) {
137+
builder.setContainer(CelContainer.ofName(test.getContainer()));
138+
}
139+
140+
return builder.build();
141+
}
130142

131143
private static ImmutableMap<String, Object> getBindings(SimpleTest test) throws Exception {
132144
ImmutableMap.Builder<String, Object> bindings =
@@ -157,13 +169,15 @@ private static SimpleTest defaultTestMatcherToTrueIfUnset(SimpleTest test) {
157169
private final String name;
158170
private final SimpleTest test;
159171
private final boolean skip;
172+
private final boolean usePlanner;
160173

161-
public ConformanceTest(String name, SimpleTest test, boolean skip) {
174+
public ConformanceTest(String name, SimpleTest test, boolean skip, boolean usePlanner) {
162175
this.name = Preconditions.checkNotNull(name);
163176
this.test =
164177
Preconditions.checkNotNull(
165178
defaultTestMatcherToTrueIfUnset(Preconditions.checkNotNull(test)));
166179
this.skip = skip;
180+
this.usePlanner = usePlanner;
167181
}
168182

169183
public String getName() {
@@ -178,7 +192,9 @@ public boolean shouldSkip() {
178192
public void evaluate() throws Throwable {
179193
CelValidationResult response = getParser(test).parse(test.getExpr(), test.getName());
180194
assertThat(response.hasError()).isFalse();
181-
response = getChecker(test).check(response.getAst());
195+
if (!test.getDisableCheck()) {
196+
response = getChecker(test).check(response.getAst());
197+
}
182198
assertThat(response.hasError()).isFalse();
183199
Type resultType = CelProtoTypes.celTypeToType(response.getAst().getResultType());
184200

@@ -188,7 +204,13 @@ public void evaluate() throws Throwable {
188204
return;
189205
}
190206

191-
Program program = RUNTIME.createProgram(response.getAst());
207+
if (!usePlanner && test.getDisableCheck()) {
208+
// Only planner supports parsed-only evaluation
209+
return;
210+
}
211+
212+
CelRuntime runtime = getRuntime(test, usePlanner);
213+
Program program = runtime.createProgram(response.getAst());
192214
ExprValue result = null;
193215
CelEvaluationException error = null;
194216
try {

conformance/src/test/java/dev/cel/conformance/ConformanceTestRunner.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ public final class ConformanceTestRunner extends ParentRunner<ConformanceTest> {
4343

4444
private final ImmutableSortedMap<String, SimpleTestFile> testFiles;
4545
private final ImmutableList<String> testsToSkip;
46+
private final boolean usePlanner;
4647

4748
private static ImmutableSortedMap<String, SimpleTestFile> loadTestFiles() {
4849
List<String> testPaths =
@@ -75,6 +76,9 @@ public ConformanceTestRunner(Class<?> clazz) throws InitializationError {
7576
ImmutableList.copyOf(
7677
SPLITTER.splitToList(
7778
System.getProperty("dev.cel.conformance.ConformanceTests.skip_tests")));
79+
usePlanner =
80+
Boolean.parseBoolean(
81+
System.getProperty("dev.cel.conformance.ConformanceTests.use_planner", "false"));
7882
}
7983

8084
private boolean shouldSkipTest(String name) {
@@ -97,8 +101,7 @@ protected List<ConformanceTest> getChildren() {
97101
for (SimpleTest test : testSection.getTestList()) {
98102
String name =
99103
String.format("%s/%s/%s", testFile.getName(), testSection.getName(), test.getName());
100-
tests.add(
101-
new ConformanceTest(name, test, test.getDisableCheck() || shouldSkipTest(name)));
104+
tests.add(new ConformanceTest(name, test, shouldSkipTest(name), usePlanner));
102105
}
103106
}
104107
}

0 commit comments

Comments
 (0)