Skip to content

Commit b029be3

Browse files
l46kokcopybara-github
authored andcommitted
Support parsed-only evaluation to encoders extension
PiperOrigin-RevId: 902832943
1 parent 64bd51a commit b029be3

2 files changed

Lines changed: 51 additions & 52 deletions

File tree

extensions/src/main/java/dev/cel/extensions/CelEncoderExtensions.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,9 +135,13 @@ public void setRuntimeOptions(CelRuntimeBuilder runtimeBuilder) {
135135
functions.forEach(
136136
function -> {
137137
if (celOptions.evaluateCanonicalTypesToNativeValues()) {
138-
runtimeBuilder.addFunctionBindings(function.nativeBytesFunctionBinding);
138+
runtimeBuilder.addFunctionBindings(
139+
CelFunctionBinding.fromOverloads(
140+
function.getFunction(), function.nativeBytesFunctionBinding));
139141
} else {
140-
runtimeBuilder.addFunctionBindings(function.protoBytesFunctionBinding);
142+
runtimeBuilder.addFunctionBindings(
143+
CelFunctionBinding.fromOverloads(
144+
function.getFunction(), function.protoBytesFunctionBinding));
141145
}
142146
});
143147
}

extensions/src/test/java/dev/cel/extensions/CelEncoderExtensionsTest.java

Lines changed: 45 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -19,36 +19,45 @@
1919
import static org.junit.Assert.assertThrows;
2020

2121
import com.google.common.collect.ImmutableMap;
22+
import com.google.testing.junit.testparameterinjector.TestParameter;
2223
import com.google.testing.junit.testparameterinjector.TestParameterInjector;
24+
import dev.cel.bundle.Cel;
2325
import dev.cel.common.CelAbstractSyntaxTree;
2426
import dev.cel.common.CelFunctionDecl;
2527
import dev.cel.common.CelOptions;
2628
import dev.cel.common.CelValidationException;
2729
import dev.cel.common.types.SimpleType;
2830
import dev.cel.common.values.CelByteString;
29-
import dev.cel.compiler.CelCompiler;
30-
import dev.cel.compiler.CelCompilerFactory;
3131
import dev.cel.runtime.CelEvaluationException;
32-
import dev.cel.runtime.CelRuntime;
33-
import dev.cel.runtime.CelRuntimeFactory;
32+
import dev.cel.testing.CelRuntimeFlavor;
33+
import org.junit.Assume;
34+
import org.junit.Before;
3435
import org.junit.Test;
3536
import org.junit.runner.RunWith;
3637

3738
@RunWith(TestParameterInjector.class)
3839
public class CelEncoderExtensionsTest {
3940
private static final CelOptions CEL_OPTIONS =
40-
CelOptions.current().build();
41-
42-
private static final CelCompiler CEL_COMPILER =
43-
CelCompilerFactory.standardCelCompilerBuilder()
44-
.addVar("stringVar", SimpleType.STRING)
45-
.addLibraries(CelExtensions.encoders(CEL_OPTIONS))
46-
.build();
47-
private static final CelRuntime CEL_RUNTIME =
48-
CelRuntimeFactory.standardCelRuntimeBuilder()
49-
.setOptions(CEL_OPTIONS)
50-
.addLibraries(CelExtensions.encoders(CEL_OPTIONS))
51-
.build();
41+
CelOptions.current().enableHeterogeneousNumericComparisons(true).build();
42+
43+
@TestParameter public CelRuntimeFlavor runtimeFlavor;
44+
@TestParameter public boolean isParseOnly;
45+
46+
private Cel cel;
47+
48+
@Before
49+
public void setUp() {
50+
// Legacy runtime does not support parsed-only evaluation mode.
51+
Assume.assumeFalse(runtimeFlavor.equals(CelRuntimeFlavor.LEGACY) && isParseOnly);
52+
this.cel =
53+
runtimeFlavor
54+
.builder()
55+
.setOptions(CEL_OPTIONS)
56+
.addCompilerLibraries(CelExtensions.encoders(CEL_OPTIONS))
57+
.addRuntimeLibraries(CelExtensions.encoders(CEL_OPTIONS))
58+
.addVar("stringVar", SimpleType.STRING)
59+
.build();
60+
}
5261

5362
@Test
5463
public void library() {
@@ -63,86 +72,72 @@ public void library() {
6372

6473
@Test
6574
public void encode_success() throws Exception {
66-
String encodedBytes =
67-
(String)
68-
CEL_RUNTIME
69-
.createProgram(CEL_COMPILER.compile("base64.encode(b'hello')").getAst())
70-
.eval();
75+
String encodedBytes = (String) eval("base64.encode(b'hello')");
7176

7277
assertThat(encodedBytes).isEqualTo("aGVsbG8=");
7378
}
7479

7580
@Test
7681
public void decode_success() throws Exception {
77-
CelByteString decodedBytes =
78-
(CelByteString)
79-
CEL_RUNTIME
80-
.createProgram(CEL_COMPILER.compile("base64.decode('aGVsbG8=')").getAst())
81-
.eval();
82+
CelByteString decodedBytes = (CelByteString) eval("base64.decode('aGVsbG8=')");
8283

8384
assertThat(decodedBytes.size()).isEqualTo(5);
8485
assertThat(new String(decodedBytes.toByteArray(), ISO_8859_1)).isEqualTo("hello");
8586
}
8687

8788
@Test
8889
public void decode_withoutPadding_success() throws Exception {
89-
CelByteString decodedBytes =
90-
(CelByteString)
91-
CEL_RUNTIME
92-
// RFC2045 6.8, padding can be ignored.
93-
.createProgram(CEL_COMPILER.compile("base64.decode('aGVsbG8')").getAst())
94-
.eval();
90+
CelByteString decodedBytes = (CelByteString) eval("base64.decode('aGVsbG8')");
9591

9692
assertThat(decodedBytes.size()).isEqualTo(5);
9793
assertThat(new String(decodedBytes.toByteArray(), ISO_8859_1)).isEqualTo("hello");
9894
}
9995

10096
@Test
10197
public void roundTrip_success() throws Exception {
102-
String encodedString =
103-
(String)
104-
CEL_RUNTIME
105-
.createProgram(CEL_COMPILER.compile("base64.encode(b'Hello World!')").getAst())
106-
.eval();
98+
String encodedString = (String) eval("base64.encode(b'Hello World!')");
10799
CelByteString decodedBytes =
108100
(CelByteString)
109-
CEL_RUNTIME
110-
.createProgram(CEL_COMPILER.compile("base64.decode(stringVar)").getAst())
111-
.eval(ImmutableMap.of("stringVar", encodedString));
101+
eval("base64.decode(stringVar)", ImmutableMap.of("stringVar", encodedString));
112102

113103
assertThat(new String(decodedBytes.toByteArray(), ISO_8859_1)).isEqualTo("Hello World!");
114104
}
115105

116106
@Test
117107
public void encode_invalidParam_throwsCompilationException() {
108+
Assume.assumeFalse(isParseOnly);
118109
CelValidationException e =
119110
assertThrows(
120-
CelValidationException.class,
121-
() -> CEL_COMPILER.compile("base64.encode('hello')").getAst());
111+
CelValidationException.class, () -> cel.compile("base64.encode('hello')").getAst());
122112

123113
assertThat(e).hasMessageThat().contains("found no matching overload for 'base64.encode'");
124114
}
125115

126116
@Test
127117
public void decode_invalidParam_throwsCompilationException() {
118+
Assume.assumeFalse(isParseOnly);
128119
CelValidationException e =
129120
assertThrows(
130-
CelValidationException.class,
131-
() -> CEL_COMPILER.compile("base64.decode(b'aGVsbG8=')").getAst());
121+
CelValidationException.class, () -> cel.compile("base64.decode(b'aGVsbG8=')").getAst());
132122

133123
assertThat(e).hasMessageThat().contains("found no matching overload for 'base64.decode'");
134124
}
135125

136126
@Test
137127
public void decode_malformedBase64Char_throwsEvaluationException() throws Exception {
138-
CelAbstractSyntaxTree ast = CEL_COMPILER.compile("base64.decode('z!')").getAst();
139-
140128
CelEvaluationException e =
141-
assertThrows(CelEvaluationException.class, () -> CEL_RUNTIME.createProgram(ast).eval());
129+
assertThrows(CelEvaluationException.class, () -> eval("base64.decode('z!')"));
142130

143-
assertThat(e)
144-
.hasMessageThat()
145-
.contains("Function 'base64_decode_string' failed with arg(s) 'z!'");
131+
assertThat(e).hasMessageThat().contains("failed with arg(s) 'z!'");
146132
assertThat(e).hasCauseThat().hasMessageThat().contains("Illegal base64 character");
147133
}
134+
135+
private Object eval(String expr) throws Exception {
136+
return eval(expr, ImmutableMap.of());
137+
}
138+
139+
private Object eval(String expr, ImmutableMap<String, Object> vars) throws Exception {
140+
CelAbstractSyntaxTree ast = isParseOnly ? cel.parse(expr).getAst() : cel.compile(expr).getAst();
141+
return cel.createProgram(ast).eval(vars);
142+
}
148143
}

0 commit comments

Comments
 (0)