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

colegreer pushed a commit to branch 3.7-dev
in repository https://gitbox.apache.org/repos/asf/tinkerpop.git


The following commit(s) were added to refs/heads/3.7-dev by this push:
     new 85449b08d7 Deflake tests in GraphSONTypedCompatibilityTest, 
GraphSONUntypedCompatibilityTest and GraphBinaryCompatibilityTest (#3237)
85449b08d7 is described below

commit 85449b08d76d4338cb215d6db05c72c0854d7a30
Author: Kangwei Zhu <[email protected]>
AuthorDate: Thu Nov 13 08:50:54 2025 +0800

    Deflake tests in GraphSONTypedCompatibilityTest, 
GraphSONUntypedCompatibilityTest and GraphBinaryCompatibilityTest (#3237)
    
    We observed several tests in GraphSONTypedCompatibilityTest  that exhibited 
flaky behavior when executed with NonDex. Specifically speaking, we can 
reproduce them by using the following commands.
    ```
    mvn clean install -DskipTests -Drat.skip=true
    ```
    * Test shouldReadWriteEdge[expect(v2)]
    ```bash
    mvn clean -pl gremlin-util edu.illinois:nondex-maven-plugin:2.2.1:nondex 
-Dtest="org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTypedCompatibilityTest#shouldReadWriteEdge[expect(v2)]"
 -Drat.skip=true
    ```
    
    * Test shouldReadWriteEdge[expect(v3)]
    ```bash
    mvn clean -pl gremlin-util edu.illinois:nondex-maven-plugin:2.2.1:nondex 
-Dtest="org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTypedCompatibilityTest#shouldReadWriteEdge[expect(v3)]"
 -Drat.skip=true
    ```
    
    * Test shouldReadWritePath[expect(v2)]
    ```bash
    mvn clean -pl gremlin-util edu.illinois:nondex-maven-plugin:2.2.1:nondex 
-Dtest="org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTypedCompatibilityTest#shouldReadWritePath[expect(v2)]"
 -Drat.skip=true
    ```
    
    * Test shouldReadWritePath[expect(v3)]
    ```bash
    mvn clean -pl gremlin-util edu.illinois:nondex-maven-plugin:2.2.1:nondex 
-Dtest="org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTypedCompatibilityTest#shouldReadWritePath[expect(v3)]"
 -Drat.skip=true
    ```
    
    * Test shouldReadWriteProperty[expect(v2)]
    ```bash
    mvn clean -pl gremlin-util edu.illinois:nondex-maven-plugin:2.2.1:nondex 
-Dtest="org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTypedCompatibilityTest#shouldReadWriteProperty[expect(v2)]"
 -Drat.skip=true
    ```
    
    * Test shouldReadWriteProperty[expect(v3)]
    ```bash
    mvn clean -pl gremlin-util edu.illinois:nondex-maven-plugin:2.2.1:nondex 
-Dtest="org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTypedCompatibilityTest#shouldReadWriteProperty[expect(v3)]"
 -Drat.skip=true
    ```
    
    * Test shouldReadWriteTraverser[expect(v2)]
    ```bash
    mvn clean -pl gremlin-util edu.illinois:nondex-maven-plugin:2.2.1:nondex 
-Dtest="org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTypedCompatibilityTest#shouldReadWriteTraverser[expect(v2)]"
 -Drat.skip=true
    ```
    
    * Test shouldReadWriteTraverser[expect(v3)]
    ```bash
    mvn clean -pl gremlin-util edu.illinois:nondex-maven-plugin:2.2.1:nondex 
-Dtest="org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTypedCompatibilityTest#shouldReadWriteTraverser[expect(v3)]"
 -Drat.skip=true
    ```
    
    * Test shouldReadWriteVertexProperty[expect(v2)]
    ```bash
    mvn clean -pl gremlin-util edu.illinois:nondex-maven-plugin:2.2.1:nondex 
-Dtest="org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTypedCompatibilityTest#shouldReadWriteVertexProperty[expect(v2)]"
 -Drat.skip=true
    ```
    
    * Test shouldReadWriteVertexProperty[expect(v3)]
    ```bash
    mvn clean -pl gremlin-util edu.illinois:nondex-maven-plugin:2.2.1:nondex 
-Dtest="org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTypedCompatibilityTest#shouldReadWriteVertexProperty[expect(v3)]"
 -Drat.skip=true
    ```
    
    * Test shouldReadWriteVertex[expect(v2)]
    ```bash
    mvn clean -pl gremlin-util edu.illinois:nondex-maven-plugin:2.2.1:nondex 
-Dtest="org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTypedCompatibilityTest#shouldReadWriteVertex[expect(v2)]"
 -Drat.skip=true
    ```
    
    * Test shouldReadWriteVertex[expect(v3)]
    ```bash
    mvn clean -pl gremlin-util edu.illinois:nondex-maven-plugin:2.2.1:nondex 
-Dtest="org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONTypedCompatibilityTest#shouldReadWriteVertex[expect(v3)]"
 -Drat.skip=true
    ```
    And the error should be something like this:
    ```
    [ERROR] Failures:
    [ERROR]   
GraphSONTypedCompatibilityTest>AbstractTypedCompatibilityTest.shouldReadWriteEdge:322
 expected:<e[17][7-develops->10]> but was:<e[13][1-develops->10]>
    [ERROR]   
GraphSONTypedCompatibilityTest>AbstractTypedCompatibilityTest.shouldReadWriteEdge:322
 expected:<e[17][7-develops->10]> but was:<e[13][1-develops->10]>
    ```
    
    Upon our investigation, the root cause is the use of:
    ```
    protected Map<Object, Vertex> vertices = new ConcurrentHashMap<>();
    protected Map<Object, Edge> edges = new ConcurrentHashMap<>();
    ```
    in TinkerGraph.java, which does not guarantee a deterministic order.
    
    The simplest fix would be to replace ConcurrentHashMap with LinkedHashMap, 
as we did in a previous PR. We've confirmed that this change could remove the 
flakiness of these tests. However, we are concerned that such a change might 
introduce unintended side effects in the code under test. Another possible fix 
would be to deterministically select a fixed id, but that approach would make 
the test become sensitive to future implementation changes. Thus, we decided to 
use this sorting-based [...]
    
    This fix also deflakes the entire GraphSONUntypedCompatibilityTest and 
GraphBinaryCompatibilityTest, which used to fail under NonDex in the 3.7-dev 
branch, this could be verified by:
    ```
    mvn clean -pl gremlin-util edu.illinois:nondex-maven-plugin:2.2.1:nondex 
-Dtest="org.apache.tinkerpop.gremlin.structure.io.graphson.GraphSONUntypedCompatibilityTest"
 -Drat.skip=true
    ```
    ```
    mvn clean -pl gremlin-util edu.illinois:nondex-maven-plugin:2.2.1:nondex 
-Dtest="org.apache.tinkerpop.gremlin.structure.io.graphbinary.GraphBinaryCompatibilityTest"
 -Drat.skip=true
    ```
    
    Co-authored-by: Siddhi Jhunjhunwala <[email protected]>
---
 .../tinkerpop/gremlin/structure/io/Model.java      | 29 ++++++++++++++++------
 1 file changed, 22 insertions(+), 7 deletions(-)

diff --git 
a/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/structure/io/Model.java
 
b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/structure/io/Model.java
index 19969f2760..dd2a5b1309 100644
--- 
a/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/structure/io/Model.java
+++ 
b/gremlin-util/src/test/java/org/apache/tinkerpop/gremlin/structure/io/Model.java
@@ -40,6 +40,7 @@ import org.apache.tinkerpop.gremlin.structure.T;
 import org.apache.tinkerpop.gremlin.structure.VertexProperty;
 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerFactory;
 import org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerGraph;
+import org.apache.tinkerpop.gremlin.util.iterator.IteratorUtils;
 import org.apache.tinkerpop.gremlin.util.message.RequestMessage;
 import org.apache.tinkerpop.gremlin.util.message.ResponseMessage;
 
@@ -115,12 +116,24 @@ public class Model {
         addCoreEntry(new java.sql.Timestamp(1481750076295L), "Timestamp", "");
         addCoreEntry(UUID.fromString("41d2e28a-20a4-4ab0-b379-d810dede3786"), 
"UUID");
 
-        addGraphStructureEntry(graph.edges().next(), "Edge", "");
-        addGraphStructureEntry(g.V().out().out().path().next(), "Path", "");
-        addGraphStructureEntry(graph.edges().next().properties().next(), 
"Property", "");
+        addGraphStructureEntry(IteratorUtils.list(graph.edges()).stream()
+                .sorted((e1, e2) -> Integer.compare((Integer)e1.id(), 
(Integer)e2.id()))
+                .iterator().next(), "Edge", "");
+        
addGraphStructureEntry(g.V().order().by(T.id).out().out().path().next(), 
"Path", "");
+        
addGraphStructureEntry(IteratorUtils.list(IteratorUtils.list(graph.edges()).stream()
+                .sorted((e1, e2) -> Integer.compare((Integer)e1.id(), 
(Integer)e2.id()))
+                .iterator().next().properties()).stream()
+                .sorted((p1, p2) -> p1.key().compareTo(p2.key()))
+                .iterator().next(), "Property", "");
         addGraphStructureEntry(graph, "TinkerGraph", "`TinkerGraph` has a 
custom serializer that is registered as part of the `TinkerIoRegistry`.");
-        addGraphStructureEntry(graph.vertices().next(), "Vertex", "");
-        addGraphStructureEntry(graph.vertices().next().properties().next(), 
"VertexProperty", "");
+        addGraphStructureEntry(IteratorUtils.list(graph.vertices()).stream()
+                .sorted((v1, v2) -> Integer.compare((Integer)v1.id(), 
(Integer)v2.id()))
+                .iterator().next(), "Vertex", "");
+        
addGraphStructureEntry(IteratorUtils.list(IteratorUtils.list(graph.vertices()).stream()
+                .sorted((v1, v2) -> Integer.compare((Integer)v1.id(), 
(Integer)v2.id()))
+                .iterator().next().properties()).stream()
+                .sorted((p1, p2) -> Long.compare((Long)p1.id(), (Long)p2.id()))
+                .iterator().next(), "VertexProperty", "");
 
         addGraphProcessEntry(SackFunctions.Barrier.normSack, "Barrier", "");
         addGraphProcessEntry(new Bytecode.Binding("x", 1), "Binding", "A 
\"Binding\" refers to a `Bytecode.Binding`.");
@@ -153,7 +166,7 @@ public class Model {
         // TextP was only added at 3.4.0 and is not supported with untyped 
GraphSON of any sort
         addGraphProcessEntry(TextP.containing("ark"), "TextP", "");
         addGraphProcessEntry(createStaticTraversalMetrics(), 
"TraversalMetrics", "");
-        
addGraphProcessEntry(g.V().hasLabel("person").asAdmin().nextTraverser(), 
"Traverser", "");
+        
addGraphProcessEntry(g.V().hasLabel("person").order().by(T.id).asAdmin().nextTraverser(),
 "Traverser", "");
 
         final Map<String,Object> requestBindings = new HashMap<>();
         requestBindings.put("x", 1);
@@ -192,7 +205,9 @@ public class Model {
         addResponseMessageEntry(responseMessage, "Authentication Challenge", 
"When authentication is enabled, an initial request to the server will result 
in an authentication challenge. The typical response message will appear as 
follows, but handling it could be different depending on the SASL 
implementation (e.g. multiple challenges maybe requested in some cases, but not 
in the default provided by Gremlin Server).");
         responseMessage = 
ResponseMessage.build(UUID.fromString("41d2e28a-20a4-4ab0-b379-d810dede3786")).
                 
code(org.apache.tinkerpop.gremlin.util.message.ResponseStatusCode.SUCCESS).
-                
result(Collections.singletonList(graph.vertices().next())).create();
+                
result(Collections.singletonList(IteratorUtils.list(graph.vertices()).stream()
+                        .sorted((v1, v2) -> Integer.compare((Integer)v1.id(), 
(Integer)v2.id()))
+                        .iterator().next())).create();
         addResponseMessageEntry(responseMessage, "Standard Result", "The 
following `ResponseMessage` is a typical example of the typical successful 
response Gremlin Server will return when returning results from a script.");
         
         addExtendedEntry(new BigDecimal(new 
BigInteger("123456789987654321123456789987654321")), "BigDecimal", "");

Reply via email to