Skip to content

Fix some issues with custom format function #277

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Apr 30, 2025
Merged

Conversation

smaye81
Copy link
Member

@smaye81 smaye81 commented Apr 30, 2025

This fixes a few issues noticed from failing conformance tests:

  • Quotes were being escaped in string values in lists
  • Durations had the word duration added to their formatting (along with escaped quotes)
  • Doubles were not formatting the same as CEL-Go. Namely, insignificant digits were not being removed (1.0 should format as 1, not 1.0)

In addition, this adds some additional unit tests for doubles to ensure the string formatting of doubles is adhering to the same behavior that CEL-Go uses.

Comment on lines +210 to +216
this.testLogging {
events("failed")
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
showExceptions = true
showCauses = true
showStackTraces = true
}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added this bc it's much easier to see failing tests in the terminal than having to navigate out to a browser link to see the failing tests.

}

@Test
void testDouble() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jchadwick-buf this is what I meant by some nuance in testing. We could move these double tests to the conformance tests I guess, but not sure about things like testing the above thrown exception. Wdyt?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally, I'm not overly concerned about handling all of the error cases identically as long as the error cases do fail as-expected, so I don't see this as a huge problem for adding tests to conformance per-se.

@@ -34,6 +34,7 @@
final class Format {
private static final char[] HEX_ARRAY = "0123456789ABCDEF".toCharArray();
private static final char[] LOWER_HEX_ARRAY = "0123456789abcdef".toCharArray();
private static final DecimalFormat decimalFormat = new DecimalFormat("0.#########");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

DecimalFormat instances aren't thread safe - we should use a ThreadLocal to cache these (if we expect they'll be used a lot), add synchronization around them, or create them on demand:

Decimal formats are generally not synchronized. It is recommended to create separate format instances for each thread. If multiple threads access a format concurrently, it must be synchronized externally.

https://docs.oracle.com/javase/8/docs/api/java/text/DecimalFormat.html

} else if (type == TypeEnum.Bytes) {
formatBytes(builder, val);
builder.append(new String((byte[]) val.value(), StandardCharsets.UTF_8));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mainly a question on CEL in general but can we always assume bytes can be converted to a valid UTF-8 string? Is there some fallback where it would display invalid UTF-8 strings as hex or something like that?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Our formatting is pretty inconsistent right now and we need to add more comprehensive tests to make sure it behaves the same. Right now, CEL-Go's built-in formatting function will throw a runtime error with invalid UTF-8, but our Java implementation will print placeholders �� when using %s and will just print hex digits when using %x. It's on the docket to unify all this behavior soon.

} else if (type == TypeEnum.Bytes) {
formatBytes(builder, val);
builder.append(new String((byte[]) val.value(), StandardCharsets.UTF_8));
} else if (type == TypeEnum.Int || type == TypeEnum.Uint || type == TypeEnum.Double) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't we only need to format float/double as decimals? It feels like for int/uint we could just output the string value.

@smaye81 smaye81 requested a review from pkwarren April 30, 2025 17:56
@smaye81 smaye81 merged commit 04f235f into main Apr 30, 2025
4 checks passed
@smaye81 smaye81 deleted the sayers/fix_duration branch April 30, 2025 21:12
@smaye81 smaye81 changed the title Fix some formatting issues Fix some issues with custom format function May 1, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants