Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
14 changes: 10 additions & 4 deletions conformance/src/test/java/dev/cel/conformance/ConformanceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.extensions.proto.ProtoTruth.assertThat;
import static dev.cel.testing.utils.ExprValueUtils.DEFAULT_EXTENSION_REGISTRY;
import static dev.cel.testing.utils.ExprValueUtils.DEFAULT_TYPE_REGISTRY;
import static dev.cel.testing.utils.ExprValueUtils.fromValue;
import static dev.cel.testing.utils.ExprValueUtils.toExprValue;

Expand All @@ -29,6 +28,7 @@
import com.google.common.base.Preconditions;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.protobuf.TypeRegistry;
import dev.cel.checker.CelChecker;
import dev.cel.common.CelContainer;
import dev.cel.common.CelOptions;
Expand Down Expand Up @@ -84,6 +84,12 @@ public final class ConformanceTest extends Statement {
CelExtensions.strings(),
CelOptionalLibrary.INSTANCE);

static final TypeRegistry CONFORMANCE_TYPE_REGISTRY =
TypeRegistry.newBuilder()
.add(dev.cel.expr.conformance.proto2.TestAllTypes.getDescriptor())
.add(dev.cel.expr.conformance.proto3.TestAllTypes.getDescriptor())
.build();

private static final CelParser PARSER_WITH_MACROS =
CelParserFactory.standardCelParserBuilder()
.setOptions(OPTIONS)
Expand Down Expand Up @@ -151,7 +157,7 @@ private static ImmutableMap<String, Object> getBindings(SimpleTest test) throws
private static Object fromExprValue(ExprValue value) throws Exception {
switch (value.getKindCase()) {
case VALUE:
return fromValue(value.getValue());
return fromValue(value.getValue(), CONFORMANCE_TYPE_REGISTRY, DEFAULT_EXTENSION_REGISTRY);
default:
throw new IllegalArgumentException(
String.format("Unexpected binding value kind: %s", value.getKindCase()));
Expand Down Expand Up @@ -224,7 +230,7 @@ public void evaluate() throws Throwable {
assertThat(result)
.ignoringRepeatedFieldOrderOfFieldDescriptors(
MapValue.getDescriptor().findFieldByName("entries"))
.unpackingAnyUsing(DEFAULT_TYPE_REGISTRY, DEFAULT_EXTENSION_REGISTRY)
.unpackingAnyUsing(CONFORMANCE_TYPE_REGISTRY, DEFAULT_EXTENSION_REGISTRY)
.isEqualTo(ExprValue.newBuilder().setValue(test.getValue()).build());
break;
case EVAL_ERROR:
Expand All @@ -237,7 +243,7 @@ public void evaluate() throws Throwable {
assertThat(result)
.ignoringRepeatedFieldOrderOfFieldDescriptors(
MapValue.getDescriptor().findFieldByName("entries"))
.unpackingAnyUsing(DEFAULT_TYPE_REGISTRY, DEFAULT_EXTENSION_REGISTRY)
.unpackingAnyUsing(CONFORMANCE_TYPE_REGISTRY, DEFAULT_EXTENSION_REGISTRY)
.isEqualTo(ExprValue.newBuilder().setValue(test.getTypedResult().getResult()).build());
assertThat(resultType).isEqualTo(test.getTypedResult().getDeducedType());
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
package dev.cel.conformance;

import static dev.cel.testing.utils.ExprValueUtils.DEFAULT_EXTENSION_REGISTRY;
import static dev.cel.testing.utils.ExprValueUtils.DEFAULT_TYPE_REGISTRY;

import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
Expand Down Expand Up @@ -50,7 +49,9 @@ private static ImmutableSortedMap<String, SimpleTestFile> loadTestFiles() {
SPLITTER.splitToList(System.getProperty("dev.cel.conformance.ConformanceTests.tests"));
try {
TextFormat.Parser parser =
TextFormat.Parser.newBuilder().setTypeRegistry(DEFAULT_TYPE_REGISTRY).build();
TextFormat.Parser.newBuilder()
.setTypeRegistry(ConformanceTest.CONFORMANCE_TYPE_REGISTRY)
.build();
ImmutableSortedMap.Builder<String, SimpleTestFile> testFiles =
ImmutableSortedMap.naturalOrder();
for (String testPath : testPaths) {
Expand Down
13 changes: 9 additions & 4 deletions policy/src/main/java/dev/cel/policy/CelPolicy.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
Expand Down Expand Up @@ -77,8 +78,7 @@ public abstract static class Builder {

public abstract Builder setPolicySource(CelPolicySource policySource);

// This should stay package-private to encourage add/set methods to be used instead.
abstract ImmutableMap.Builder<String, Object> metadataBuilder();
private final HashMap<String, Object> metadata = new HashMap<>();

public abstract Builder setMetadata(ImmutableMap<String, Object> value);

Expand All @@ -90,6 +90,10 @@ public List<Import> imports() {
return Collections.unmodifiableList(importList);
}

public Map<String, Object> metadata() {
return Collections.unmodifiableMap(metadata);
}

@CanIgnoreReturnValue
public Builder addImport(Import value) {
importList.add(value);
Expand All @@ -104,20 +108,21 @@ public Builder addImports(Collection<Import> values) {

@CanIgnoreReturnValue
public Builder putMetadata(String key, Object value) {
metadataBuilder().put(key, value);
metadata.put(key, value);
return this;
}

@CanIgnoreReturnValue
public Builder putMetadata(Map<String, Object> map) {
metadataBuilder().putAll(map);
metadata.putAll(map);
return this;
}

abstract CelPolicy autoBuild();

public CelPolicy build() {
setImports(ImmutableList.copyOf(importList));
setMetadata(ImmutableMap.copyOf(metadata));
return autoBuild();
}
}
Expand Down
3 changes: 3 additions & 0 deletions testing/src/main/java/dev/cel/testing/testrunner/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,13 @@ java_library(
":result_matcher",
"//:auto_value",
"//bundle:cel",
"//common:cel_descriptor_util",
"//common:options",
"//policy:parser",
"//runtime",
"//testing/testrunner:proto_descriptor_utils",
"@maven//:com_google_guava_guava",
"@maven//:com_google_protobuf_protobuf_java",
],
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,21 @@
package dev.cel.testing.testrunner;

import com.google.auto.value.AutoValue;
import com.google.auto.value.extension.memoized.Memoized;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.protobuf.Descriptors.Descriptor;
import com.google.protobuf.Descriptors.FileDescriptor;
import com.google.protobuf.ExtensionRegistry;
import com.google.protobuf.TypeRegistry;
import dev.cel.bundle.Cel;
import dev.cel.bundle.CelFactory;
import dev.cel.common.CelDescriptorUtil;
import dev.cel.common.CelOptions;
import dev.cel.policy.CelPolicyParser;
import dev.cel.runtime.CelLateFunctionBindings;
import dev.cel.testing.utils.ProtoDescriptorUtils;
import java.io.IOException;
import java.util.Map;
import java.util.Optional;

Expand Down Expand Up @@ -63,6 +72,19 @@ public abstract class CelTestContext {
*/
public abstract Optional<CelLateFunctionBindings> celLateFunctionBindings();

/** Interface for transforming bindings before evaluation. */
@FunctionalInterface
public interface BindingTransformer {
ImmutableMap<String, Object> transform(ImmutableMap<String, Object> bindings) throws Exception;
}

/**
* The binding transformer for the CEL test.
*
* <p>This transformer is used to transform the bindings before evaluation.
*/
public abstract Optional<BindingTransformer> bindingTransformer();

/**
* The variable bindings for the CEL test.
*
Expand Down Expand Up @@ -99,6 +121,39 @@ public abstract class CelTestContext {
*/
public abstract Optional<String> fileDescriptorSetPath();

abstract ImmutableSet<Descriptor> messageTypes();

abstract ImmutableSet<FileDescriptor> fileTypes();

@Memoized
public Optional<TypeRegistry> typeRegistry() {
if (messageTypes().isEmpty() && fileTypes().isEmpty() && !fileDescriptorSetPath().isPresent()) {
return Optional.empty();
}
TypeRegistry.Builder builder = TypeRegistry.newBuilder();
if (!messageTypes().isEmpty()) {
builder.add(messageTypes());
}
if (!fileTypes().isEmpty()) {
builder.add(
CelDescriptorUtil.getAllDescriptorsFromFileDescriptor(fileTypes())
.messageTypeDescriptors());
}
if (fileDescriptorSetPath().isPresent()) {
try {
builder.add(
ProtoDescriptorUtils.getAllDescriptorsFromJvm(fileDescriptorSetPath().get())
.messageTypeDescriptors());
} catch (IOException e) {
throw new IllegalStateException(
"Failed to load descriptors from path: " + fileDescriptorSetPath().get(), e);
}
}
return Optional.of(builder.build());
}

public abstract Optional<ExtensionRegistry> extensionRegistry();

/** Returns a builder for {@link CelTestContext} with the current instance's values. */
public abstract Builder toBuilder();

Expand All @@ -123,6 +178,8 @@ public abstract static class Builder {
public abstract Builder setCelLateFunctionBindings(
CelLateFunctionBindings celLateFunctionBindings);

public abstract Builder setBindingTransformer(BindingTransformer bindingTransformer);

public abstract Builder setVariableBindings(Map<String, Object> variableBindings);

public abstract Builder setResultMatcher(ResultMatcher resultMatcher);
Expand All @@ -133,6 +190,36 @@ public abstract Builder setCelLateFunctionBindings(

public abstract Builder setFileDescriptorSetPath(String fileDescriptorSetPath);

abstract ImmutableSet.Builder<Descriptor> messageTypesBuilder();

abstract ImmutableSet.Builder<FileDescriptor> fileTypesBuilder();

public Builder addMessageTypes(Descriptor... descriptors) {
for (Descriptor d : descriptors) {
messageTypesBuilder().add(d);
}
return this;
}

public Builder addMessageTypes(Iterable<Descriptor> descriptors) {
messageTypesBuilder().addAll(descriptors);
return this;
}

public Builder addFileTypes(FileDescriptor... fileDescriptors) {
for (FileDescriptor fd : fileDescriptors) {
fileTypesBuilder().add(fd);
}
return this;
}

public Builder addFileTypes(Iterable<FileDescriptor> fileDescriptors) {
fileTypesBuilder().addAll(fileDescriptors);
return this;
}

public abstract Builder setExtensionRegistry(ExtensionRegistry extensionRegistry);

public abstract CelTestContext build();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,36 @@
* CelTestSuiteTextProtoParser intakes a textproto document that describes the structure of a CEL
* test suite, parses it then creates a {@link CelTestSuite}.
*/
final class CelTestSuiteTextProtoParser {
public final class CelTestSuiteTextProtoParser {

/** Creates a new instance of {@link CelTestSuiteTextProtoParser}. */
static CelTestSuiteTextProtoParser newInstance() {
public static CelTestSuiteTextProtoParser newInstance() {
return new CelTestSuiteTextProtoParser();
}

CelTestSuite parse(String textProto) throws IOException, CelTestSuiteException {
TestSuite testSuite = parseTestSuite(textProto);
public CelTestSuite parse(String textProto) throws IOException, CelTestSuiteException {
return parse(
textProto, TypeRegistry.getEmptyTypeRegistry(), ExtensionRegistry.getEmptyRegistry());
}

public CelTestSuite parse(String textProto, TypeRegistry customTypeRegistry)
throws IOException, CelTestSuiteException {
return parse(textProto, customTypeRegistry, ExtensionRegistry.getEmptyRegistry());
}

public CelTestSuite parse(
String textProto, TypeRegistry customTypeRegistry, ExtensionRegistry customExtensionRegistry)
throws IOException, CelTestSuiteException {
TestSuite testSuite = parseTestSuite(textProto, customTypeRegistry, customExtensionRegistry);
return parseCelTestSuite(testSuite);
}

private TestSuite parseTestSuite(String textProto) throws IOException {
private TestSuite parseTestSuite(
String textProto, TypeRegistry customTypeRegistry, ExtensionRegistry customExtensionRegistry)
throws IOException {
String fileDescriptorSetPath = System.getProperty("file_descriptor_set_path");
TypeRegistry typeRegistry = TypeRegistry.getEmptyTypeRegistry();
ExtensionRegistry extensionRegistry = ExtensionRegistry.getEmptyRegistry();
TypeRegistry typeRegistry = customTypeRegistry;
ExtensionRegistry extensionRegistry = customExtensionRegistry;
if (fileDescriptorSetPath != null) {
extensionRegistry = RegistryUtils.getExtensionRegistry(fileDescriptorSetPath);
typeRegistry = RegistryUtils.getTypeRegistry(fileDescriptorSetPath);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,14 @@
* CelTestSuiteYamlParser intakes a YAML document that describes the structure of a CEL test suite,
* parses it then creates a {@link CelTestSuite}.
*/
final class CelTestSuiteYamlParser {
public final class CelTestSuiteYamlParser {

/** Creates a new instance of {@link CelTestSuiteYamlParser}. */
static CelTestSuiteYamlParser newInstance() {
public static CelTestSuiteYamlParser newInstance() {
return new CelTestSuiteYamlParser();
}

CelTestSuite parse(String celTestSuiteYamlContent) throws CelTestSuiteException {
public CelTestSuite parse(String celTestSuiteYamlContent) throws CelTestSuiteException {
return parseYaml(celTestSuiteYamlContent, "<input>");
}

Expand Down Expand Up @@ -86,7 +86,7 @@ private CelTestSuite parseYaml(String celTestSuiteYamlContent, String descriptio
}

private CelTestSuite.Builder parseTestSuite(ParserContext<Node> ctx, Node node) {
CelTestSuite.Builder builder = CelTestSuite.newBuilder();
CelTestSuite.Builder builder = CelTestSuite.newBuilder().setName("");
long id = ctx.collectMetadata(node);
if (!assertYamlType(ctx, id, node, YamlNodeType.MAP)) {
ctx.reportError(id, "Unknown test suite type: " + node.getTag());
Expand All @@ -110,6 +110,7 @@ private CelTestSuite.Builder parseTestSuite(ParserContext<Node> ctx, Node node)
case "description":
builder.setDescription(newString(ctx, valueNode));
break;
case "section":
case "sections":
builder.setSections(parseSections(ctx, valueNode));
break;
Expand Down Expand Up @@ -143,7 +144,7 @@ private CelTestSection parseSection(ParserContext<Node> ctx, Node node) {
return CelTestSection.newBuilder().build();
}

CelTestSection.Builder celTestSectionBuilder = CelTestSection.newBuilder();
CelTestSection.Builder celTestSectionBuilder = CelTestSection.newBuilder().setDescription("");
MappingNode sectionNode = (MappingNode) node;
for (NodeTuple nodeTuple : sectionNode.getValue()) {
Node keyNode = nodeTuple.getKeyNode();
Expand Down Expand Up @@ -185,7 +186,7 @@ private ImmutableSet<CelTestCase> parseTests(ParserContext<Node> ctx, Node node)

private CelTestCase parseTestCase(ParserContext<Node> ctx, Node node) {
long valueId = ctx.collectMetadata(node);
CelTestCase.Builder celTestCaseBuilder = CelTestCase.newBuilder();
CelTestCase.Builder celTestCaseBuilder = CelTestCase.newBuilder().setDescription("");
if (!assertYamlType(ctx, valueId, node, YamlNodeType.MAP)) {
ctx.reportError(valueId, "Testcase is not a map: " + node.getTag());
return celTestCaseBuilder.build();
Expand Down
Loading