This is an automated email from the ASF dual-hosted git repository.

lhotari pushed a commit to branch branch-4.0
in repository https://gitbox.apache.org/repos/asf/pulsar.git


The following commit(s) were added to refs/heads/branch-4.0 by this push:
     new ec4eef5ddae [fix][test] Made ProtobufNativeSchemaTest.testSchema 
order-independent (#24805)
ec4eef5ddae is described below

commit ec4eef5ddae2ea9cff5a15b44ed42a8ed9228a2c
Author: Lucas Eby <[email protected]>
AuthorDate: Tue Nov 11 10:04:58 2025 -0600

    [fix][test] Made ProtobufNativeSchemaTest.testSchema order-independent 
(#24805)
    
    (cherry picked from commit b8d0f142567a038545a9148cb518272751c3a4a8)
---
 .../impl/schema/ProtobufNativeSchemaTest.java      | 73 +++++++++++++++++++++-
 1 file changed, 70 insertions(+), 3 deletions(-)

diff --git 
a/pulsar-client/src/test/java/org/apache/pulsar/client/impl/schema/ProtobufNativeSchemaTest.java
 
b/pulsar-client/src/test/java/org/apache/pulsar/client/impl/schema/ProtobufNativeSchemaTest.java
index 59b282dec0c..a0ea3c1cc6e 100644
--- 
a/pulsar-client/src/test/java/org/apache/pulsar/client/impl/schema/ProtobufNativeSchemaTest.java
+++ 
b/pulsar-client/src/test/java/org/apache/pulsar/client/impl/schema/ProtobufNativeSchemaTest.java
@@ -20,14 +20,25 @@ package org.apache.pulsar.client.impl.schema;
 
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotNull;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.google.protobuf.DescriptorProtos;
 import com.google.protobuf.Descriptors;
+import com.google.protobuf.InvalidProtocolBufferException;
+import com.google.protobuf.util.JsonFormat;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.ByteBufAllocator;
 import java.nio.charset.StandardCharsets;
+import java.util.Base64;
 import java.util.Collections;
 import java.util.HashMap;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.pulsar.common.schema.SchemaType;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.skyscreamer.jsonassert.JSONAssert;
+import org.skyscreamer.jsonassert.JSONCompareMode;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
@@ -46,6 +57,28 @@ public class ProtobufNativeSchemaTest {
             + 
"gBQjUKJW9yZy5hcGFjaGUucHVsc2FyLmNsaWVudC5zY2hlbWEucHJvdG9CDEV4dGVybmFsVGVzdGIGcHJvdG8z\",\"rootMessageT"
             + 
"ypeName\":\"proto.TestMessage\",\"rootFileDescriptorName\":\"Test.proto\"}";
 
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+
+    /**
+     * Decode a base64-encoded Protobuf FileDescriptorSet into a canonical 
JSON tree.
+     * @param b64 a base64 string
+     * @return a normalized JSON tree that can be compared with JSONAssert, 
ensuring deterministic
+     * equality checks regardless of field ordering.
+     * @throws IllegalArgumentException if b64 isn't valid Base64
+     * @throws InvalidProtocolBufferException if the decoded bytes are not a 
valid FileDescriptorSet
+     * @throws JSONException if the JSON string is invalid
+     */
+    private static JSONObject fdsToJson(String b64)
+            throws IllegalArgumentException, InvalidProtocolBufferException, 
JSONException {
+        DescriptorProtos.FileDescriptorSet fds =
+            
DescriptorProtos.FileDescriptorSet.parseFrom(Base64.getDecoder().decode(b64));
+        String json = JsonFormat.printer()
+            .includingDefaultValueFields()
+            .omittingInsignificantWhitespace()
+            .print(fds);
+        return new JSONObject(json);
+    }
+
     @Test
     public void testEncodeAndDecode() {
         final String stringFieldValue = "StringFieldValue";
@@ -61,15 +94,49 @@ public class ProtobufNativeSchemaTest {
     }
 
     @Test
-    public void testSchema() {
+    public void testSchema() throws Exception {
         
ProtobufNativeSchema<org.apache.pulsar.client.schema.proto.Test.TestMessage> 
protobufSchema =
                 
ProtobufNativeSchema.of(org.apache.pulsar.client.schema.proto.Test.TestMessage.class);
 
         assertEquals(protobufSchema.getSchemaInfo().getType(), 
SchemaType.PROTOBUF_NATIVE);
 
         
assertNotNull(ProtobufNativeSchemaUtils.deserialize(protobufSchema.getSchemaInfo().getSchema()));
-        assertEquals(new String(protobufSchema.getSchemaInfo().getSchema(),
-                StandardCharsets.UTF_8), EXPECTED_SCHEMA_JSON);
+
+        // Parse the actual/expected JSON into trees
+        String actualJson   = new 
String(protobufSchema.getSchemaInfo().getSchema(), StandardCharsets.UTF_8);
+        JsonNode actualRoot   = MAPPER.readTree(actualJson);
+        JsonNode expectedRoot = MAPPER.readTree(EXPECTED_SCHEMA_JSON);
+
+        // Extract and validate the FileDescriptorSet field for semantic 
comparison
+        // (When decoded, Protobuf descriptors can serialize fields in varying 
orders
+        // causing hard coded string comparisons to fail)
+        String fdSetField = "fileDescriptorSet";
+        JsonNode actualB64Node = actualRoot.path(fdSetField);
+        JsonNode expectedB64Node = expectedRoot.path(fdSetField);
+        Assert.assertFalse(actualB64Node.isMissingNode());
+        Assert.assertFalse(expectedB64Node.isMissingNode());
+        Assert.assertTrue(actualB64Node.isValueNode());
+        Assert.assertTrue(expectedB64Node.isValueNode());
+
+        // Decode FileDescriptorSets to JSON and compare semantically 
(order-insensitive)
+        JSONObject actualFdsObj   = fdsToJson(actualB64Node.asText());
+        JSONObject expectedFdsObj = fdsToJson(expectedB64Node.asText());
+        JSONAssert.assertEquals(
+                "FileDescriptorSet mismatch: decoded Protobuf descriptors have 
mismatched schema contents",
+                expectedFdsObj,
+                actualFdsObj,
+                JSONCompareMode.NON_EXTENSIBLE
+        );
+
+        // Remove the already verified field and compare remaining schema 
attributes, order does not matter
+        ((ObjectNode) actualRoot).remove(fdSetField);
+        ((ObjectNode) expectedRoot).remove(fdSetField);
+        JSONAssert.assertEquals(
+                "Schema metadata mismatch: remaining JSON fields differ after 
verifying FileDescriptorSet",
+                MAPPER.writeValueAsString(expectedRoot),
+                MAPPER.writeValueAsString(actualRoot),
+                JSONCompareMode.NON_EXTENSIBLE
+        );
     }
 
     @Test

Reply via email to