From c25a4cab0a1923d27220f7c7512e5e114a66470f Mon Sep 17 00:00:00 2001 From: 1fanwang <1fannnw@gmail.com> Date: Sun, 30 Aug 2026 00:00:35 -0400 Subject: [PATCH 1/3] fix(core): reject unsupported vertex meta-properties Signed-off-by: 1fanwang <1fannnw@gmail.com> --- .../optimize/HugePrimaryKeyStrategy.java | 9 +- .../apache/hugegraph/core/CoreTestSuite.java | 1 + .../core/PrimaryKeyStrategyCoreTest.java | 122 ++++++++++++++++++ 3 files changed, 125 insertions(+), 7 deletions(-) create mode 100644 hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PrimaryKeyStrategyCoreTest.java diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugePrimaryKeyStrategy.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugePrimaryKeyStrategy.java index e6fa880837..8fd1f91516 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugePrimaryKeyStrategy.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugePrimaryKeyStrategy.java @@ -30,6 +30,7 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.AddPropertyStep; import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy; import org.apache.tinkerpop.gremlin.structure.T; +import org.apache.tinkerpop.gremlin.structure.VertexProperty; import org.apache.tinkerpop.gremlin.structure.VertexProperty.Cardinality; public class HugePrimaryKeyStrategy @@ -76,7 +77,6 @@ public void apply(Traversal.Admin traversal) { || propertyStep.getCardinality() == null) { Object[] kvs = new Object[2]; - List kvList = new LinkedList<>(); propertyStep.getParameters().getRaw().forEach((k, v) -> { if (T.key.equals(k)) { @@ -84,17 +84,12 @@ public void apply(Traversal.Admin traversal) { } else if (T.value.equals(k)) { kvs[1] = v.get(0); } else { - kvList.add(k.toString()); - kvList.add(v.get(0)); + throw VertexProperty.Exceptions.metaPropertiesNotSupported(); } }); curAddStep.configure(kvs); - if (!kvList.isEmpty()) { - curAddStep.configure(kvList.toArray(new Object[0])); - } - removeSteps.add(step); } else { curAddStep = null; diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/CoreTestSuite.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/CoreTestSuite.java index 230b8d2d06..f18d656c08 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/CoreTestSuite.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/CoreTestSuite.java @@ -41,6 +41,7 @@ VertexCoreTest.class, EdgeCoreTest.class, CountStrategyCoreTest.class, + PrimaryKeyStrategyCoreTest.class, ParentAndSubEdgeCoreTest.class, PropertyCoreTest.VertexPropertyCoreTest.class, PropertyCoreTest.EdgePropertyCoreTest.class, diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PrimaryKeyStrategyCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PrimaryKeyStrategyCoreTest.java new file mode 100644 index 0000000000..6ca5d48210 --- /dev/null +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PrimaryKeyStrategyCoreTest.java @@ -0,0 +1,122 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.hugegraph.core; + +import org.apache.hugegraph.schema.SchemaManager; +import org.apache.hugegraph.testutil.Assert; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; +import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.junit.Test; + +public class PrimaryKeyStrategyCoreTest extends BaseCoreTest { + + private static final String PRIMARY_LABEL = "primary"; + private static final String AUTOMATIC_LABEL = "automatic"; + + private void initSchema() { + SchemaManager schema = graph().schema(); + schema.propertyKey("name").asText().create(); + schema.propertyKey("country").asText().create(); + schema.vertexLabel(PRIMARY_LABEL) + .properties("name", "country") + .primaryKeys("name") + .nullableKeys("country") + .create(); + schema.vertexLabel(AUTOMATIC_LABEL) + .useAutomaticId() + .properties("name", "country") + .nullableKeys("name", "country") + .create(); + } + + @Test + public void testStartStepRejectsMetaPropertiesForPrimaryKeyLabel() { + this.assertMetaPropertiesRejected(PRIMARY_LABEL, false); + } + + @Test + public void testStartStepRejectsMetaPropertiesForAutomaticLabel() { + this.assertMetaPropertiesRejected(AUTOMATIC_LABEL, false); + } + + @Test + public void testMidTraversalStepRejectsMetaPropertiesForPrimaryKeyLabel() { + this.assertMetaPropertiesRejected(PRIMARY_LABEL, true); + } + + @Test + public void testMidTraversalStepRejectsMetaPropertiesForAutomaticLabel() { + this.assertMetaPropertiesRejected(AUTOMATIC_LABEL, true); + } + + @Test + public void testStartStepCreatesPrimaryKeyVertexWithOneProperty() { + this.initSchema(); + + Vertex vertex = graph().traversal() + .addV(PRIMARY_LABEL) + .property("name", "marko") + .next(); + commitTx(); + + Assert.assertEquals("marko", vertex.value("name")); + Assert.assertEquals(1L, graph().traversal().V() + .hasLabel(PRIMARY_LABEL) + .count().next()); + } + + @Test + public void testMidTraversalStepCreatesAutomaticVertexWithTwoProperties() { + this.initSchema(); + + Vertex vertex = graph().traversal() + .inject(1) + .addV(AUTOMATIC_LABEL) + .property("name", "marko") + .property("country", "cn") + .next(); + commitTx(); + + Assert.assertEquals("marko", vertex.value("name")); + Assert.assertEquals("cn", vertex.value("country")); + Assert.assertEquals(1L, graph().traversal().V() + .hasLabel(AUTOMATIC_LABEL) + .count().next()); + } + + private void assertMetaPropertiesRejected(String label, + boolean midTraversal) { + this.initSchema(); + + GraphTraversal traversal = midTraversal ? + graph().traversal() + .inject(1) + .addV(label) : + graph().traversal().addV(label); + traversal.property("name", "marko", "country", "cn"); + + Assert.assertThrows(UnsupportedOperationException.class, + traversal::next, + e -> Assert.assertEquals( + "Properties on a vertex property is not " + + "supported", + e.getMessage())); + Assert.assertEquals(0L, graph().traversal().V() + .hasLabel(label).count().next()); + } +} From e28cd1439f743e765173517fbac032678619f80a Mon Sep 17 00:00:00 2001 From: 1fanwang <1fannnw@gmail.com> Date: Sun, 30 Aug 2026 00:27:39 -0400 Subject: [PATCH 2/3] test(core): exercise metadata folding strategy Signed-off-by: 1fanwang <1fannnw@gmail.com> --- .../core/PrimaryKeyStrategyCoreTest.java | 94 +++++++------------ 1 file changed, 36 insertions(+), 58 deletions(-) diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PrimaryKeyStrategyCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PrimaryKeyStrategyCoreTest.java index 6ca5d48210..9c851b90f1 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PrimaryKeyStrategyCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PrimaryKeyStrategyCoreTest.java @@ -20,96 +20,74 @@ import org.apache.hugegraph.schema.SchemaManager; import org.apache.hugegraph.testutil.Assert; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; +import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.AddPropertyStep; import org.apache.tinkerpop.gremlin.structure.Vertex; +import org.apache.tinkerpop.gremlin.structure.VertexProperty; import org.junit.Test; public class PrimaryKeyStrategyCoreTest extends BaseCoreTest { - private static final String PRIMARY_LABEL = "primary"; - private static final String AUTOMATIC_LABEL = "automatic"; + private static final String LABEL = "person"; private void initSchema() { SchemaManager schema = graph().schema(); schema.propertyKey("name").asText().create(); schema.propertyKey("country").asText().create(); - schema.vertexLabel(PRIMARY_LABEL) + schema.vertexLabel(LABEL) .properties("name", "country") .primaryKeys("name") .nullableKeys("country") .create(); - schema.vertexLabel(AUTOMATIC_LABEL) - .useAutomaticId() - .properties("name", "country") - .nullableKeys("name", "country") - .create(); - } - - @Test - public void testStartStepRejectsMetaPropertiesForPrimaryKeyLabel() { - this.assertMetaPropertiesRejected(PRIMARY_LABEL, false); - } - - @Test - public void testStartStepRejectsMetaPropertiesForAutomaticLabel() { - this.assertMetaPropertiesRejected(AUTOMATIC_LABEL, false); - } - - @Test - public void testMidTraversalStepRejectsMetaPropertiesForPrimaryKeyLabel() { - this.assertMetaPropertiesRejected(PRIMARY_LABEL, true); } @Test - public void testMidTraversalStepRejectsMetaPropertiesForAutomaticLabel() { - this.assertMetaPropertiesRejected(AUTOMATIC_LABEL, true); + public void testStartStepRejectsMetaProperties() { + this.initSchema(); + GraphTraversal traversal = graph().traversal() + .addV(LABEL) + .property("name", "marko", + "country", "cn"); + this.assertMetaPropertiesRejected(traversal); } @Test - public void testStartStepCreatesPrimaryKeyVertexWithOneProperty() { + public void testMidTraversalStepRejectsMetaProperties() { this.initSchema(); - - Vertex vertex = graph().traversal() - .addV(PRIMARY_LABEL) - .property("name", "marko") - .next(); - commitTx(); - - Assert.assertEquals("marko", vertex.value("name")); - Assert.assertEquals(1L, graph().traversal().V() - .hasLabel(PRIMARY_LABEL) - .count().next()); + GraphTraversal traversal = graph().traversal() + .inject(1) + .addV(LABEL) + .property("name", "marko", + "country", "cn"); + this.assertMetaPropertiesRejected(traversal); } @Test - public void testMidTraversalStepCreatesAutomaticVertexWithTwoProperties() { + public void testFoldsSingleCardinalityProperties() { this.initSchema(); - Vertex vertex = graph().traversal() - .inject(1) - .addV(AUTOMATIC_LABEL) - .property("name", "marko") - .property("country", "cn") - .next(); + GraphTraversal traversal = graph().traversal() + .addV(LABEL) + .property( + VertexProperty.Cardinality.single, + "name", "marko") + .property( + VertexProperty.Cardinality.single, + "country", "cn"); + traversal.asAdmin().applyStrategies(); + Assert.assertFalse(traversal.asAdmin().getSteps().stream() + .anyMatch(AddPropertyStep.class::isInstance)); + + Vertex vertex = traversal.next(); commitTx(); Assert.assertEquals("marko", vertex.value("name")); Assert.assertEquals("cn", vertex.value("country")); Assert.assertEquals(1L, graph().traversal().V() - .hasLabel(AUTOMATIC_LABEL) - .count().next()); + .hasLabel(LABEL).count().next()); } - private void assertMetaPropertiesRejected(String label, - boolean midTraversal) { - this.initSchema(); - - GraphTraversal traversal = midTraversal ? - graph().traversal() - .inject(1) - .addV(label) : - graph().traversal().addV(label); - traversal.property("name", "marko", "country", "cn"); - + private void assertMetaPropertiesRejected( + GraphTraversal traversal) { Assert.assertThrows(UnsupportedOperationException.class, traversal::next, e -> Assert.assertEquals( @@ -117,6 +95,6 @@ private void assertMetaPropertiesRejected(String label, "supported", e.getMessage())); Assert.assertEquals(0L, graph().traversal().V() - .hasLabel(label).count().next()); + .hasLabel(LABEL).count().next()); } } From cf4f1598608b074579a778ca0a5e810ff29d6ebc Mon Sep 17 00:00:00 2001 From: 1fanwang <1fannnw@gmail.com> Date: Sun, 30 Aug 2026 04:28:09 -0400 Subject: [PATCH 3/3] fix(core): defer vertex meta-property rejection to execution Throwing from HugePrimaryKeyStrategy validated eagerly, so an unreachable coalesce()/choose() addV() fallback failed before its branch was picked. Fold only T.key/T.value into addV so PRIMARY_KEY labels keep their primary key, leave a metadata-bearing AddPropertyStep in place, and stop folding across it. HugeVertex.property() then rejects it, T.id case included. Signed-off-by: 1fanwang <1fannnw@gmail.com> --- .../optimize/HugePrimaryKeyStrategy.java | 33 ++-- .../core/PrimaryKeyStrategyCoreTest.java | 157 ++++++++++++++---- 2 files changed, 144 insertions(+), 46 deletions(-) diff --git a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugePrimaryKeyStrategy.java b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugePrimaryKeyStrategy.java index 8fd1f91516..f371c0f303 100644 --- a/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugePrimaryKeyStrategy.java +++ b/hugegraph-server/hugegraph-core/src/main/java/org/apache/hugegraph/traversal/optimize/HugePrimaryKeyStrategy.java @@ -19,6 +19,7 @@ import java.util.LinkedList; import java.util.List; +import java.util.Map; import org.apache.tinkerpop.gremlin.process.traversal.Step; import org.apache.tinkerpop.gremlin.process.traversal.Traversal; @@ -30,7 +31,6 @@ import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.AddPropertyStep; import org.apache.tinkerpop.gremlin.process.traversal.strategy.AbstractTraversalStrategy; import org.apache.tinkerpop.gremlin.structure.T; -import org.apache.tinkerpop.gremlin.structure.VertexProperty; import org.apache.tinkerpop.gremlin.structure.VertexProperty.Cardinality; public class HugePrimaryKeyStrategy @@ -77,20 +77,33 @@ public void apply(Traversal.Admin traversal) { || propertyStep.getCardinality() == null) { Object[] kvs = new Object[2]; - - propertyStep.getParameters().getRaw().forEach((k, v) -> { - if (T.key.equals(k)) { - kvs[0] = v.get(0); - } else if (T.value.equals(k)) { - kvs[1] = v.get(0); + boolean extraParams = false; + + for (Map.Entry> param : + propertyStep.getParameters().getRaw().entrySet()) { + Object paramKey = param.getKey(); + if (T.key.equals(paramKey)) { + kvs[0] = param.getValue().get(0); + } else if (T.value.equals(paramKey)) { + kvs[1] = param.getValue().get(0); } else { - throw VertexProperty.Exceptions.metaPropertiesNotSupported(); + extraParams = true; } - }); + } curAddStep.configure(kvs); - removeSteps.add(step); + if (extraParams) { + /* + * Rejecting here would run for every child traversal, so an + * unreachable coalesce()/choose() branch would fail too. Leave + * the step for HugeVertex.property() to reject when it really + * runs, and stop folding across it. + */ + curAddStep = null; + } else { + removeSteps.add(step); + } } else { curAddStep = null; } diff --git a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PrimaryKeyStrategyCoreTest.java b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PrimaryKeyStrategyCoreTest.java index 9c851b90f1..0561906ce6 100644 --- a/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PrimaryKeyStrategyCoreTest.java +++ b/hugegraph-server/hugegraph-test/src/main/java/org/apache/hugegraph/core/PrimaryKeyStrategyCoreTest.java @@ -20,7 +20,9 @@ import org.apache.hugegraph.schema.SchemaManager; import org.apache.hugegraph.testutil.Assert; import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal; +import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.__; import org.apache.tinkerpop.gremlin.process.traversal.step.sideEffect.AddPropertyStep; +import org.apache.tinkerpop.gremlin.structure.T; import org.apache.tinkerpop.gremlin.structure.Vertex; import org.apache.tinkerpop.gremlin.structure.VertexProperty; import org.junit.Test; @@ -29,50 +31,128 @@ public class PrimaryKeyStrategyCoreTest extends BaseCoreTest { private static final String LABEL = "person"; + private static final String META_PROPERTIES_ERROR = + VertexProperty.Exceptions.metaPropertiesNotSupported().getMessage(); + private static final String USER_SUPPLIED_IDS_ERROR = + VertexProperty.Exceptions.userSuppliedIdsNotSupported().getMessage(); + private void initSchema() { SchemaManager schema = graph().schema(); schema.propertyKey("name").asText().create(); schema.propertyKey("country").asText().create(); - schema.vertexLabel(LABEL) - .properties("name", "country") - .primaryKeys("name") - .nullableKeys("country") - .create(); + schema.propertyKey("since").asText().create(); + schema.vertexLabel(LABEL).properties("name", "country", "since") + .primaryKeys("name").nullableKeys("country", "since").create(); + } + + /** + * Applying the strategy must stay side effect free: the metadata-bearing step is left in the + * traversal so that HugeVertex.property() can reject it when the step really runs. + */ + @Test + public void testKeepsMetaPropertyStepUnfolded() { + this.initSchema(); + + GraphTraversal traversal = graph().traversal().addV(LABEL) + .property("country", "cn", "since", "2024"); + traversal.asAdmin().applyStrategies(); + + Assert.assertTrue(traversal.asAdmin().getSteps().stream() + .anyMatch(AddPropertyStep.class::isInstance)); + Assert.assertEquals(0L, graph().traversal().V().hasLabel(LABEL).count().next()); } @Test public void testStartStepRejectsMetaProperties() { this.initSchema(); - GraphTraversal traversal = graph().traversal() - .addV(LABEL) - .property("name", "marko", - "country", "cn"); - this.assertMetaPropertiesRejected(traversal); + + GraphTraversal traversal = graph().traversal().addV(LABEL) + .property("name", "marko") + .property("country", "cn", "since", "2024"); + + this.assertRejectedWhenExecuted(traversal, META_PROPERTIES_ERROR); } @Test public void testMidTraversalStepRejectsMetaProperties() { this.initSchema(); - GraphTraversal traversal = graph().traversal() - .inject(1) - .addV(LABEL) - .property("name", "marko", - "country", "cn"); - this.assertMetaPropertiesRejected(traversal); + + GraphTraversal traversal = graph().traversal().inject(1).addV(LABEL) + .property("name", "marko") + .property("country", "cn", "since", "2024"); + + this.assertRejectedWhenExecuted(traversal, META_PROPERTIES_ERROR); + } + + /** + * The metadata-bearing step carries the primary key, so the strategy still has to fold + * T.key/T.value into addV(). Otherwise the vertex creation fails first with an + * IllegalArgumentException about the missing primary key, and the traversal never reaches the + * metadata validation this test is about. + */ + @Test + public void testPrimaryKeyIsFoldedIntoAddVBeforeMetaPropertyCheck() { + this.initSchema(); + + GraphTraversal traversal = graph().traversal().addV(LABEL) + .property("name", "marko", "since", "2024"); + + this.assertRejectedWhenExecuted(traversal, META_PROPERTIES_ERROR); + } + + @Test + public void testUserSuppliedVertexPropertyIdRejected() { + this.initSchema(); + + GraphTraversal traversal = graph().traversal().addV(LABEL) + .property("name", "marko", T.id, 1); + + this.assertRejectedWhenExecuted(traversal, USER_SUPPLIED_IDS_ERROR); + } + + /** + * TinkerPop applies strategies to coalesce() children before a branch is selected, so eager + * validation would fail this traversal even though unfold() answers it and the addV() fallback + * never runs. + */ + @Test + @SuppressWarnings("unchecked") + public void testUnreachableCoalesceBranchIsNotValidated() { + this.initSchema(); + graph().addVertex(T.label, LABEL, "name", "marko"); + commitTx(); + + GraphTraversal traversal = + graph().traversal().V().hasLabel(LABEL).fold() + .coalesce(__.unfold(), + __.addV(LABEL).property("name", "marko", "since", "2024")); + + this.assertFallbackNotExecuted(traversal); + } + + @Test + public void testUnreachableChooseBranchIsNotValidated() { + this.initSchema(); + graph().addVertex(T.label, LABEL, "name", "marko"); + commitTx(); + + GraphTraversal traversal = + graph().traversal().V().hasLabel(LABEL).fold() + .choose(__.unfold().count().is(0L), + __.addV(LABEL).property("name", "marko", "since", "2024"), + __.unfold()); + + this.assertFallbackNotExecuted(traversal); } @Test public void testFoldsSingleCardinalityProperties() { this.initSchema(); - GraphTraversal traversal = graph().traversal() - .addV(LABEL) - .property( - VertexProperty.Cardinality.single, - "name", "marko") - .property( - VertexProperty.Cardinality.single, - "country", "cn"); + GraphTraversal traversal = + graph().traversal().addV(LABEL) + .property(VertexProperty.Cardinality.single, "name", "marko") + .property(VertexProperty.Cardinality.single, "country", "cn"); traversal.asAdmin().applyStrategies(); Assert.assertFalse(traversal.asAdmin().getSteps().stream() .anyMatch(AddPropertyStep.class::isInstance)); @@ -82,19 +162,24 @@ public void testFoldsSingleCardinalityProperties() { Assert.assertEquals("marko", vertex.value("name")); Assert.assertEquals("cn", vertex.value("country")); - Assert.assertEquals(1L, graph().traversal().V() - .hasLabel(LABEL).count().next()); + Assert.assertEquals(1L, graph().traversal().V().hasLabel(LABEL).count().next()); } - private void assertMetaPropertiesRejected( - GraphTraversal traversal) { - Assert.assertThrows(UnsupportedOperationException.class, - traversal::next, - e -> Assert.assertEquals( - "Properties on a vertex property is not " + - "supported", - e.getMessage())); - Assert.assertEquals(0L, graph().traversal().V() - .hasLabel(LABEL).count().next()); + private void assertRejectedWhenExecuted(GraphTraversal traversal, String expectedError) { + Assert.assertThrows(UnsupportedOperationException.class, traversal::next, + e -> Assert.assertEquals(expectedError, e.getMessage())); + + // The addV() step already ran, so only the rollback guarantees that nothing survives + graph().tx().rollback(); + Assert.assertEquals(0L, graph().traversal().V().hasLabel(LABEL).count().next()); + } + + private void assertFallbackNotExecuted(GraphTraversal traversal) { + Vertex vertex = traversal.next(); + commitTx(); + + Assert.assertEquals("marko", vertex.value("name")); + Assert.assertFalse(vertex.property("since").isPresent()); + Assert.assertEquals(1L, graph().traversal().V().hasLabel(LABEL).count().next()); } }