You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@s2graph.apache.org by st...@apache.org on 2017/07/01 15:27:56 UTC

[05/46] incubator-s2graph git commit: [VertexTest]: passed except shouldHaveExceptionConsistencyWhenAssigningSameIdOnEdge.

[VertexTest]: passed except shouldHaveExceptionConsistencyWhenAssigningSameIdOnEdge.


Project: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/commit/9ce28472
Tree: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/tree/9ce28472
Diff: http://git-wip-us.apache.org/repos/asf/incubator-s2graph/diff/9ce28472

Branch: refs/heads/master
Commit: 9ce284729348ada3a6b2146844f97806159e2433
Parents: 20b51ce
Author: DO YUNG YOON <st...@apache.org>
Authored: Wed Apr 5 22:54:25 2017 +0900
Committer: DO YUNG YOON <st...@apache.org>
Committed: Wed Apr 5 22:54:25 2017 +0900

----------------------------------------------------------------------
 .../org/apache/s2graph/core/QueryParam.scala    |  2 +-
 .../scala/org/apache/s2graph/core/S2Graph.scala | 56 ++++++++++++++---
 .../org/apache/s2graph/core/S2Vertex.scala      | 44 +++++++++++--
 .../core/features/S2ElementFeatures.scala       |  4 +-
 .../features/S2VertexPropertyFeatures.scala     |  2 +-
 .../core/tinkerpop/S2GraphProvider.scala        | 65 ++++++++++++++++----
 .../core/tinkerpop/structure/S2GraphTest.scala  | 56 ++++++++++++++++-
 7 files changed, 195 insertions(+), 34 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/9ce28472/s2core/src/main/scala/org/apache/s2graph/core/QueryParam.scala
----------------------------------------------------------------------
diff --git a/s2core/src/main/scala/org/apache/s2graph/core/QueryParam.scala b/s2core/src/main/scala/org/apache/s2graph/core/QueryParam.scala
index eb36258..0228b3b 100644
--- a/s2core/src/main/scala/org/apache/s2graph/core/QueryParam.scala
+++ b/s2core/src/main/scala/org/apache/s2graph/core/QueryParam.scala
@@ -270,7 +270,7 @@ case class QueryParam(labelName: String,
                         limit: Int = 100,
                         sample: Int = -1,
                         maxAttempt: Int = 2,
-                        rpcTimeout: Int = 1000,
+                        rpcTimeout: Int = 60000,
                         cacheTTLInMillis: Long = -1L,
                         indexName: String = LabelIndex.DefaultName,
                         where: Try[Where] = Success(WhereParser.success),

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/9ce28472/s2core/src/main/scala/org/apache/s2graph/core/S2Graph.scala
----------------------------------------------------------------------
diff --git a/s2core/src/main/scala/org/apache/s2graph/core/S2Graph.scala b/s2core/src/main/scala/org/apache/s2graph/core/S2Graph.scala
index 182b8ed..1d1150e 100644
--- a/s2core/src/main/scala/org/apache/s2graph/core/S2Graph.scala
+++ b/s2core/src/main/scala/org/apache/s2graph/core/S2Graph.scala
@@ -597,7 +597,7 @@ class S2Graph(_config: Config)(implicit val ec: ExecutionContext) extends Graph
   val MaxSize = config.getInt("future.cache.max.size")
   val ExpireAfterWrite = config.getInt("future.cache.expire.after.write")
   val ExpireAfterAccess = config.getInt("future.cache.expire.after.access")
-  val WaitTimeout = Duration(60, TimeUnit.SECONDS)
+  val WaitTimeout = Duration(300, TimeUnit.SECONDS)
   val scheduledEx = ExecutionContext.fromExecutor(Executors.newSingleThreadExecutor())
 
   val management = new Management(this)
@@ -654,7 +654,7 @@ class S2Graph(_config: Config)(implicit val ec: ExecutionContext) extends Graph
   } logger.info(s"[Initialized]: $k, ${this.config.getAnyRef(k)}")
 
   /* TODO */
-  val DefaultService = management.createService("_s2graph", "localhost", "s2graph", 0, None).get
+  val DefaultService = management.createService("", "localhost", "s2graph", 0, None).get
   val DefaultColumn = ServiceColumn.findOrInsert(DefaultService.id.get, "vertex", Some("string"), HBaseType.DEFAULT_VERSION, useCache = false)
   val DefaultColumnMetas = {
     ColumnMeta.findOrInsert(DefaultColumn.id.get, "test", "string", useCache = false)
@@ -672,11 +672,16 @@ class S2Graph(_config: Config)(implicit val ec: ExecutionContext) extends Graph
     ColumnMeta.findOrInsert(DefaultColumn.id.get, "double", "double", useCache = false)
     ColumnMeta.findOrInsert(DefaultColumn.id.get, "integer", "integer", useCache = false)
     ColumnMeta.findOrInsert(DefaultColumn.id.get, "aKey", "string", useCache = false)
+    ColumnMeta.findOrInsert(DefaultColumn.id.get, "x", "integer", useCache = false)
+    ColumnMeta.findOrInsert(DefaultColumn.id.get, "y", "integer", useCache = false)
+    ColumnMeta.findOrInsert(DefaultColumn.id.get, "location", "string", useCache = false)
+    ColumnMeta.findOrInsert(DefaultColumn.id.get, "status", "string", useCache = false)
+    ColumnMeta.findOrInsert(DefaultColumn.id.get, "myId", "integer", useCache = false)
   }
 
   val DefaultLabel = management.createLabel("_s2graph", DefaultService.serviceName, DefaultColumn.columnName, DefaultColumn.columnType,
     DefaultService.serviceName, DefaultColumn.columnName, DefaultColumn.columnType, true, DefaultService.serviceName, Nil, Nil, "weak", None, None,
-    options = Option("""{"skipReverse": true}""")
+    options = Option("""{"skipReverse": false}""")
   )
 
   def getStorage(service: Service): Storage[_, _] = {
@@ -909,6 +914,20 @@ class S2Graph(_config: Config)(implicit val ec: ExecutionContext) extends Graph
     }
   }
 
+//  def deleteAllAdjacentEdges(vertex: S2Vertex,
+//                             labels: Seq[Label],
+//                             ts: Long = System.currentTimeMillis()): Future[Boolean] = {
+//    val indexEdges = labels.flatMap { label =>
+//      val propsPlusTs = Map(LabelMeta.timestamp.name -> ts)
+//      val propsWithTs = label.propsToInnerValsWithTs(propsPlusTs, ts)
+//      val edge = newEdge(vertex, vertex, label,
+//        GraphUtil.directions("out"),
+//        GraphUtil.operations("delete"), propsWithTs = propsWithTs)
+//      edge.relatedEdges.flatMap(e => e.edgesWithIndexValid)
+//    }
+//    val kvs = indexEdges.flatMap(ie => defaultStorage.indexEdgeSerializer(ie).toKeyValues)
+//    defaultStorage.writeToStorage(vertex.hbaseZkAddr, kvs, withWait = true)
+//  }
   /** mutate */
   def deleteAllAdjacentEdges(srcVertices: Seq[S2Vertex],
                              labels: Seq[Label],
@@ -947,7 +966,7 @@ class S2Graph(_config: Config)(implicit val ec: ExecutionContext) extends Graph
       stepInnerResultLs <- Future.sequence(queries.map(getEdgesStepInner(_, true)))
       (allDeleted, ret) <- deleteAllFetchedEdgesLs(stepInnerResultLs, requestTs)
     } yield {
-      //        logger.debug(s"fetchAndDeleteAll: ${allDeleted}, ${ret}")
+      logger.debug(s"fetchAndDeleteAll: ${allDeleted}, ${ret}")
       (allDeleted, ret)
     }
 
@@ -993,7 +1012,7 @@ class S2Graph(_config: Config)(implicit val ec: ExecutionContext) extends Graph
       }
       ret
     }
-
+    logger.error(s"[FutureSize]: ${futures.size}")
     if (futures.isEmpty) {
       // all deleted.
       Future.successful(true -> true)
@@ -1008,6 +1027,8 @@ class S2Graph(_config: Config)(implicit val ec: ExecutionContext) extends Graph
     }
     if (filtered.isEmpty) StepResult.Empty
     else {
+      logger.error(s"[buildEdgesToDelete]: ${filtered.size}")
+
       val head = filtered.head
       val label = head.edge.innerLabel
       val edgeWithScoreLs = filtered.map { edgeWithScore =>
@@ -1035,7 +1056,8 @@ class S2Graph(_config: Config)(implicit val ec: ExecutionContext) extends Graph
 //          edgeWithScore.edge.copy(op = newOp, version = newVersion, propsWithTs = newPropsWithTs)
 
         val edgeToDelete = edgeWithScore.copy(edge = copiedEdge)
-        //      logger.debug(s"delete edge from deleteAll: ${edgeToDelete.edge.toLogString}")
+        logger.error(s"delete edge from deleteAll: ${edgeToDelete.edge.toLogString}")
+        logger.error(s"delete edge from deleteAll edge: ${edge.toLogString}")
         edgeToDelete
       }
       //Degree edge?
@@ -1234,11 +1256,14 @@ class S2Graph(_config: Config)(implicit val ec: ExecutionContext) extends Graph
              operation: String = "insert"): S2Edge = {
     val label = Label.findByName(labelName).getOrElse(throw new LabelNotExistException(labelName))
 
-    val srcVertexIdInnerVal = toInnerVal(srcId, label.srcColumn.columnType, label.schemaVersion)
-    val tgtVertexIdInnerVal = toInnerVal(tgtId, label.tgtColumn.columnType, label.schemaVersion)
+    val srcColumn = if (direction == "out") label.srcColumn else label.tgtColumn
+    val tgtColumn = if (direction == "out") label.tgtColumn else label.srcColumn
 
-    val srcVertex = newVertex(SourceVertexId(label.srcColumn, srcVertexIdInnerVal), System.currentTimeMillis())
-    val tgtVertex = newVertex(TargetVertexId(label.tgtColumn, tgtVertexIdInnerVal), System.currentTimeMillis())
+    val srcVertexIdInnerVal = toInnerVal(srcId, srcColumn.columnType, label.schemaVersion)
+    val tgtVertexIdInnerVal = toInnerVal(tgtId, tgtColumn.columnType, label.schemaVersion)
+
+    val srcVertex = newVertex(SourceVertexId(srcColumn, srcVertexIdInnerVal), System.currentTimeMillis())
+    val tgtVertex = newVertex(TargetVertexId(tgtColumn, tgtVertexIdInnerVal), System.currentTimeMillis())
     val dir = GraphUtil.toDir(direction).getOrElse(throw new RuntimeException(s"$direction is not supported."))
 
     val propsPlusTs = props ++ Map(LabelMeta.timestamp.name -> ts)
@@ -1551,11 +1576,22 @@ class S2Graph(_config: Config)(implicit val ec: ExecutionContext) extends Graph
 
   override def configuration(): Configuration = apacheConfiguration
 
+  override def addVertex(label: String): Vertex = {
+    if (label == null) throw Element.Exceptions.labelCanNotBeNull
+    if (label.isEmpty) throw Element.Exceptions.labelCanNotBeEmpty
+
+    addVertex(Seq(T.label, label): _*)
+  }
+
   override def addVertex(kvs: AnyRef*): structure.Vertex = {
     if (!features().vertex().supportsUserSuppliedIds() && kvs.contains(T.id)) {
       throw Vertex.Exceptions.userSuppliedIdsNotSupported
     }
+
     val kvsMap = S2Property.kvsToProps(kvs)
+    if (kvsMap.contains(T.label.name()) && kvsMap(T.label.name).toString.isEmpty)
+      throw Element.Exceptions.labelCanNotBeEmpty
+
     val id = kvsMap.getOrElse(T.id.toString, Random.nextLong)
 
     val serviceColumnNames = kvsMap.getOrElse(T.label.toString, DefaultColumn.columnName).toString

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/9ce28472/s2core/src/main/scala/org/apache/s2graph/core/S2Vertex.scala
----------------------------------------------------------------------
diff --git a/s2core/src/main/scala/org/apache/s2graph/core/S2Vertex.scala b/s2core/src/main/scala/org/apache/s2graph/core/S2Vertex.scala
index 643b469..797ed98 100644
--- a/s2core/src/main/scala/org/apache/s2graph/core/S2Vertex.scala
+++ b/s2core/src/main/scala/org/apache/s2graph/core/S2Vertex.scala
@@ -33,6 +33,7 @@ import org.apache.tinkerpop.gremlin.structure.{Direction, Edge, Property, T, Ver
 import play.api.libs.json.Json
 
 import scala.collection.JavaConverters._
+import scala.concurrent.Await
 
 case class S2Vertex(graph: S2Graph,
                   id: VertexId,
@@ -181,22 +182,32 @@ case class S2Vertex(graph: S2Graph,
     }
   }
 
-  override def addEdge(label: String, vertex: Vertex, kvs: AnyRef*): Edge = {
+  override def addEdge(labelName: String, vertex: Vertex, kvs: AnyRef*): Edge = {
+    val containsId = kvs.contains(T.id)
     vertex match {
       case otherV: S2Vertex =>
-        if (!graph.features().edge().supportsUserSuppliedIds() && kvs.contains(T.id)) {
+        if (!graph.features().edge().supportsUserSuppliedIds() && containsId) {
           throw Exceptions.userSuppliedIdsNotSupported()
         }
 
         val props = S2Property.kvsToProps(kvs)
 
         //TODO: direction, operation, _timestamp need to be reserved property key.
-        val direction = props.get("direction").getOrElse("out").toString
-        val ts = props.get(LabelMeta.timestamp.name).map(_.toString.toLong).getOrElse(System.currentTimeMillis())
-        val operation = props.get("operation").map(_.toString).getOrElse("insert")
 
         try {
-          graph.addEdgeInner(this, otherV, label, direction, props, ts, operation)
+          val direction = props.get("direction").getOrElse("out").toString
+          val ts = props.get(LabelMeta.timestamp.name).map(_.toString.toLong).getOrElse(System.currentTimeMillis())
+          val operation = props.get("operation").map(_.toString).getOrElse("insert")
+          val label = Label.findByName(labelName).getOrElse(throw new LabelNotExistException(labelName))
+          val dir = GraphUtil.toDir(direction).getOrElse(throw new RuntimeException(s"$direction is not supported."))
+          val propsPlusTs = props ++ Map(LabelMeta.timestamp.name -> ts)
+          val propsWithTs = label.propsToInnerValsWithTs(propsPlusTs, ts)
+          val op = GraphUtil.toOp(operation).getOrElse(throw new RuntimeException(s"$operation is not supported."))
+
+          val edge = graph.newEdge(this, otherV, label, dir, op = op, version = ts, propsWithTs = propsWithTs)
+          val future = graph.mutateEdges(edge.relatedEdges, withWait = true)
+          Await.ready(future, graph.WaitTimeout)
+          edge
         } catch {
           case e: LabelNotExistException => throw new java.lang.IllegalArgumentException
          }
@@ -239,6 +250,27 @@ case class S2Vertex(graph: S2Graph,
   override def remove(): Unit = {
     if (graph.features().vertex().supportsRemoveVertices()) {
       // remove edge
+      // TODO: remove related edges also.
+      implicit val ec = graph.ec
+      val ts = System.currentTimeMillis()
+      val outLabels = Label.findBySrcColumnId(id.colId)
+      val inLabels = Label.findByTgtColumnId(id.colId)
+      val verticesToDelete = Seq(this.copy(op = GraphUtil.operations("delete")))
+      val outFuture = graph.deleteAllAdjacentEdges(verticesToDelete, outLabels, GraphUtil.directions("out"), ts)
+      val inFuture = graph.deleteAllAdjacentEdges(verticesToDelete, inLabels, GraphUtil.directions("in"), ts)
+      val vertexFuture = graph.mutateVertices(verticesToDelete, withWait = true)
+      val future = for {
+        outSuccess <- outFuture
+        inSuccess <- inFuture
+        vertexSuccess <- vertexFuture
+      } yield {
+        if (!outSuccess) throw new RuntimeException("Vertex.remove out direction edge delete failed.")
+        if (!inSuccess) throw new RuntimeException("Vertex.remove in direction edge delete failed.")
+        if (!vertexSuccess.forall(identity)) throw new RuntimeException("Vertex.remove vertex delete failed.")
+        true
+      }
+      Await.result(future, graph.WaitTimeout)
+
     } else {
       throw Vertex.Exceptions.vertexRemovalNotSupported()
     }

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/9ce28472/s2core/src/main/scala/org/apache/s2graph/core/features/S2ElementFeatures.scala
----------------------------------------------------------------------
diff --git a/s2core/src/main/scala/org/apache/s2graph/core/features/S2ElementFeatures.scala b/s2core/src/main/scala/org/apache/s2graph/core/features/S2ElementFeatures.scala
index 06f1c68..7e66c62 100644
--- a/s2core/src/main/scala/org/apache/s2graph/core/features/S2ElementFeatures.scala
+++ b/s2core/src/main/scala/org/apache/s2graph/core/features/S2ElementFeatures.scala
@@ -3,7 +3,7 @@ package org.apache.s2graph.core.features
 import org.apache.tinkerpop.gremlin.structure.Graph.Features
 
 abstract class S2ElementFeatures extends Features.ElementFeatures {
-  override def supportsStringIds(): Boolean = true
+  override def supportsStringIds(): Boolean = false
 
   override def supportsCustomIds(): Boolean = true
 
@@ -15,7 +15,7 @@ abstract class S2ElementFeatures extends Features.ElementFeatures {
 
   override def supportsUserSuppliedIds(): Boolean = true
 
-  override def supportsAnyIds(): Boolean = true
+  override def supportsAnyIds(): Boolean = false
 
   override def supportsNumericIds(): Boolean = false
 

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/9ce28472/s2core/src/main/scala/org/apache/s2graph/core/features/S2VertexPropertyFeatures.scala
----------------------------------------------------------------------
diff --git a/s2core/src/main/scala/org/apache/s2graph/core/features/S2VertexPropertyFeatures.scala b/s2core/src/main/scala/org/apache/s2graph/core/features/S2VertexPropertyFeatures.scala
index 592cc0b..fe74c85 100644
--- a/s2core/src/main/scala/org/apache/s2graph/core/features/S2VertexPropertyFeatures.scala
+++ b/s2core/src/main/scala/org/apache/s2graph/core/features/S2VertexPropertyFeatures.scala
@@ -18,7 +18,7 @@ class S2VertexPropertyFeatures extends S2PropertyFeatures with Features.VertexPr
 
   override def supportsUuidIds(): Boolean = false
 
-  override def supportsCustomIds(): Boolean = false
+  override def supportsCustomIds(): Boolean = true
 
   override def supportsAnyIds(): Boolean = false
 }

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/9ce28472/s2core/src/test/scala/org/apache/s2graph/core/tinkerpop/S2GraphProvider.scala
----------------------------------------------------------------------
diff --git a/s2core/src/test/scala/org/apache/s2graph/core/tinkerpop/S2GraphProvider.scala b/s2core/src/test/scala/org/apache/s2graph/core/tinkerpop/S2GraphProvider.scala
index 741be06..e0fc765 100644
--- a/s2core/src/test/scala/org/apache/s2graph/core/tinkerpop/S2GraphProvider.scala
+++ b/s2core/src/test/scala/org/apache/s2graph/core/tinkerpop/S2GraphProvider.scala
@@ -41,12 +41,14 @@ class S2GraphProvider extends AbstractGraphProvider {
     if (graph != null) {
       val s2Graph = graph.asInstanceOf[S2Graph]
       if (s2Graph.isRunning) {
-        val labels = Label.findAll()
-        labels.groupBy(_.hbaseTableName).values.foreach { labelsWithSameTable =>
-          labelsWithSameTable.headOption.foreach { label =>
-            s2Graph.management.truncateStorage(label.label)
-          }
-        }
+//        val labels = Label.findAll()
+//        labels.groupBy(_.hbaseTableName).values.foreach { labelsWithSameTable =>
+//          labelsWithSameTable.headOption.foreach { label =>
+//            s2Graph.management.truncateStorage(label.label)
+//          }
+//        }
+//        s2Graph.shutdown(modelDataDelete = true)
+        cleanupSchema(graph)
         s2Graph.shutdown(modelDataDelete = true)
         logger.info("S2Graph Shutdown")
       }
@@ -61,6 +63,24 @@ class S2GraphProvider extends AbstractGraphProvider {
     }
   }
 
+  private def cleanupSchema(graph: Graph): Unit = {
+    val s2Graph = graph.asInstanceOf[S2Graph]
+    val mnt = s2Graph.getManagement()
+    val defaultService = s2Graph.DefaultService
+    val defaultServiceColumn = s2Graph.DefaultColumn
+
+    val columnNames = Set(defaultServiceColumn.columnName, "person", "software", "product", "dog")
+    val labelNames = Set("knows", "created", "bought", "test", "self", "friends", "friend", "hate", "collaborator", "test1", "test2", "test3", "pets", "walks", "knows")
+
+    Management.deleteService(defaultService.serviceName)
+    columnNames.foreach { columnName =>
+      Management.deleteColumn(defaultServiceColumn.service.serviceName, columnName)
+    }
+    labelNames.foreach { labelName =>
+      Management.deleteLabel(labelName)
+    }
+  }
+
   override def loadGraphData(graph: Graph, loadGraphWith: LoadGraphWith, testClass: Class[_], testName: String): Unit = {
     val s2Graph = graph.asInstanceOf[S2Graph]
     val mnt = s2Graph.getManagement()
@@ -74,14 +94,17 @@ class S2GraphProvider extends AbstractGraphProvider {
     var knowsProp = Vector(
       Prop("weight", "0.0", "double"),
       Prop("data", "-", "string"),
-      Prop("year", "-1", "integer"),
+      Prop("year", "0", "integer"),
       Prop("boolean", "false", "boolean"),
       Prop("float", "0.0", "float"),
       Prop("double", "0.0", "double"),
       Prop("long", "0.0", "long"),
       Prop("string", "-", "string"),
-      Prop("integer", "-", "integer"),
-      Prop("aKey", "-", "string")
+      Prop("integer", "0", "integer"),
+      Prop("aKey", "-", "string"),
+      Prop("stars", "0", "integer"),
+      Prop("since", "0", "integer"),
+      Prop("myEdgeId", "0", "integer")
     )
 
    // Change dataType for ColumnMeta('aKey') for PropertyFeatureSupportTest
@@ -115,12 +138,15 @@ class S2GraphProvider extends AbstractGraphProvider {
     }
 
     // knows props
-    if (testClass.getSimpleName == "EdgeTest" && testName == "shouldAutotypeDoubleProperties") {
+//    mnt.createLabel("knows", defaultService.serviceName, "vertex", "string", defaultService.serviceName, "vertex", "string",
+//      true, defaultService.serviceName, Nil, knowsProp, "strong", None, None, options = Option("""{"skipReverse": false}"""))
+
+    if (testClass.getSimpleName.contains("VertexTest") || (testClass.getSimpleName == "EdgeTest" && testName == "shouldAutotypeDoubleProperties")) {
       mnt.createLabel("knows", defaultService.serviceName, "vertex", "string", defaultService.serviceName, "vertex", "string",
-        true, defaultService.serviceName, Nil, knowsProp, "strong", None, None, options = Option("""{"skipReverse": true}"""))
+        true, defaultService.serviceName, Nil, knowsProp, "strong", None, None, options = Option("""{"skipReverse": false}"""))
     } else {
       mnt.createLabel("knows", defaultService.serviceName, "person", "integer", defaultService.serviceName, "person", "integer",
-        true, defaultService.serviceName, Nil, knowsProp, "strong", None, None, options = Option("""{"skipReverse": true}"""))
+        true, defaultService.serviceName, Nil, knowsProp, "strong", None, None, options = Option("""{"skipReverse": false}"""))
     }
 
     val personColumn = Management.createServiceColumn(defaultService.serviceName, "person", "integer", Seq(Prop(T.id.toString, "-1", "integer"), Prop("name", "-", "string"), Prop("age", "0", "integer"), Prop("location", "-", "string")))
@@ -186,6 +212,21 @@ class S2GraphProvider extends AbstractGraphProvider {
       true, defaultService.serviceName, Nil, Nil, "weak", None, None,
       options = Option("""{"skipReverse": false}""")
     )
+    val pets = mnt.createLabel("pets", defaultService.serviceName, defaultServiceColumn.columnName, defaultServiceColumn.columnType, defaultService.serviceName, defaultServiceColumn.columnName, defaultServiceColumn.columnType,
+      true, defaultService.serviceName, Nil, Nil, "weak", None, None,
+      options = Option("""{"skipReverse": false}""")
+    )
+    val walks = mnt.createLabel("walks", defaultService.serviceName, defaultServiceColumn.columnName, defaultServiceColumn.columnType, defaultService.serviceName, defaultServiceColumn.columnName, defaultServiceColumn.columnType,
+      true, defaultService.serviceName, Nil,
+      Seq(
+        Prop("location", "-", "string")
+      ), "weak", None, None,
+      options = Option("""{"skipReverse": false}""")
+    )
+    val livesWith = mnt.createLabel("livesWith", defaultService.serviceName, defaultServiceColumn.columnName, defaultServiceColumn.columnType, defaultService.serviceName, defaultServiceColumn.columnName, defaultServiceColumn.columnType,
+      true, defaultService.serviceName, Nil, Nil, "weak", None, None,
+      options = Option("""{"skipReverse": false}""")
+    )
 
     super.loadGraphData(graph, loadGraphWith, testClass, testName)
   }

http://git-wip-us.apache.org/repos/asf/incubator-s2graph/blob/9ce28472/s2core/src/test/scala/org/apache/s2graph/core/tinkerpop/structure/S2GraphTest.scala
----------------------------------------------------------------------
diff --git a/s2core/src/test/scala/org/apache/s2graph/core/tinkerpop/structure/S2GraphTest.scala b/s2core/src/test/scala/org/apache/s2graph/core/tinkerpop/structure/S2GraphTest.scala
index e69004c..28a16d3 100644
--- a/s2core/src/test/scala/org/apache/s2graph/core/tinkerpop/structure/S2GraphTest.scala
+++ b/s2core/src/test/scala/org/apache/s2graph/core/tinkerpop/structure/S2GraphTest.scala
@@ -24,7 +24,7 @@ import org.apache.s2graph.core.mysqls.Label
 import org.apache.s2graph.core.utils.logger
 import org.apache.s2graph.core.{Management, S2Graph, S2Vertex, TestCommonWithModels}
 import org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.GraphTraversal
-import org.apache.tinkerpop.gremlin.structure.{Edge, T, Vertex}
+import org.apache.tinkerpop.gremlin.structure.{Direction, Edge, T, Vertex}
 import org.scalatest.{FunSuite, Matchers}
 
 
@@ -181,7 +181,59 @@ class S2GraphTest extends FunSuite with Matchers with TestCommonWithModels {
 //    logger.error(x)
   }
 
-  test("addVertex with empty parameter") {
+//  test("addVertex with empty parameter") {
+//
+//  }
+  test("aaa") {
+    val mnt = graph.management
+    val defaultService = graph.DefaultService
+    val defaultServiceColumn = graph.DefaultColumn
+    val columnNames = Set(defaultServiceColumn.columnName, "person", "software", "product", "dog")
+    val labelNames = Set("knows", "created", "bought", "test", "self", "friends", "friend", "hate", "collaborator", "test1", "test2", "test3", "pets", "walks", "knows")
+
+    Management.deleteService(defaultService.serviceName)
+    columnNames.foreach { columnName =>
+      Management.deleteColumn(defaultServiceColumn.service.serviceName, columnName)
+    }
+    labelNames.foreach { labelName =>
+      Management.deleteLabel(labelName)
+    }
+
+    val knows = mnt.createLabel("knows",
+      defaultService.serviceName, defaultServiceColumn.columnName, defaultServiceColumn.columnType,
+      defaultService.serviceName, defaultServiceColumn.columnName, defaultServiceColumn.columnType,
+      true, defaultService.serviceName, Nil, Seq(Prop("since", "0", "integer")), "strong", None, None,
+      options = Option("""{"skipReverse": false}"""))
+
+    val pets = mnt.createLabel("pets",
+      defaultService.serviceName, defaultServiceColumn.columnName, defaultServiceColumn.columnType,
+      defaultService.serviceName, defaultServiceColumn.columnName, defaultServiceColumn.columnType,
+      true, defaultService.serviceName, Nil, Nil, "strong", None, None,
+      options = Option("""{"skipReverse": false}"""))
+
+    val walks = mnt.createLabel("walks",
+      defaultService.serviceName, defaultServiceColumn.columnName, defaultServiceColumn.columnType,
+      defaultService.serviceName, defaultServiceColumn.columnName, defaultServiceColumn.columnType,
+      true, defaultService.serviceName, Nil, Seq(Prop("location", "-", "string")), "strong", None, None,
+      options = Option("""{"skipReverse": false}"""))
+
+    val livesWith = mnt.createLabel("livesWith",
+      defaultService.serviceName, defaultServiceColumn.columnName, defaultServiceColumn.columnType,
+      defaultService.serviceName, defaultServiceColumn.columnName, defaultServiceColumn.columnType,
+      true, defaultService.serviceName, Nil, Nil, "strong", None, None,
+      options = Option("""{"skipReverse": false}"""))
+
+    (0 until 2).foreach(i => graph.addVertex("myId", Int.box(i)))
+
+    graph.vertices().foreach(v =>
+      graph.vertices().foreach(u => v.addEdge("knows", u, "myEdgeId", Int.box(12)))
+    )
+
+    val v = graph.vertices().toSeq.head
+    v.remove()
 
+    graph.edges().foreach(e =>
+      logger.error(s"[Edge]: $e")
+    )
   }
 }
\ No newline at end of file