blob: 93648ce986ad69687c4939e0ac9bcc268f9f411f [file] [log] [blame]
package controllers
import com.kakao.s2graph.core._
import com.kakao.s2graph.core.mysqls._
import org.specs2.mutable.Specification
import play.api.libs.json._
import play.api.test.FakeApplication
import play.api.test.Helpers._
import scala.concurrent.Future
import scala.concurrent.duration._
import scala.util.Random
trait SpecCommon extends Specification {
sequential
object Helper {
import org.json4s.native.Serialization
type KV = Map[String, Any]
import scala.language.dynamics
def $aa[T](args: T*) = List($a(args: _ *))
def $a[T](args: T*) = args.toList
object $ extends Dynamic {
def applyDynamicNamed(name: String)(args: (String, Any)*): Map[String, Any] = args.toMap
}
implicit class anyMapOps(map: Map[String, Any]) {
def toJson: JsValue = {
val js = Serialization.write(map)(org.json4s.DefaultFormats)
Json.parse(js)
}
}
implicit class S2Context(val sc: StringContext) {
def edge(args: Any*)(implicit map: Map[String, Any] = Map.empty): String = {
val parts = sc.s(args: _*).split("\\s")
assert(parts.length == 6)
(parts.toList :+ map.toJson.toString).mkString("\t")
}
}
}
val curTime = System.currentTimeMillis
val t1 = curTime + 0
val t2 = curTime + 1
val t3 = curTime + 2
val t4 = curTime + 3
val t5 = curTime + 4
protected val testServiceName = "s2graph"
protected val testLabelName = "s2graph_label_test"
protected val testLabelName2 = "s2graph_label_test_2"
protected val testLabelNameV1 = "s2graph_label_test_v1"
protected val testLabelNameWeak = "s2graph_label_test_weak"
protected val testColumnName = "user_id_test"
protected val testColumnType = "long"
protected val testTgtColumnName = "item_id_test"
protected val testHTableName = "test-htable"
protected val newHTableName = "new-htable"
val NUM_OF_EACH_TEST = 100
val HTTP_REQ_WAITING_TIME = Duration(300, SECONDS)
val asyncFlushInterval = 100
val createService = s"""{"serviceName" : "$testServiceName"}"""
val testLabelNameCreate =
s"""
{
"label": "$testLabelName",
"srcServiceName": "$testServiceName",
"srcColumnName": "$testColumnName",
"srcColumnType": "long",
"tgtServiceName": "$testServiceName",
"tgtColumnName": "$testColumnName",
"tgtColumnType": "long",
"indices": [
{"name": "idx_1", "propNames": ["weight", "time", "is_hidden", "is_blocked"]},
{"name": "idx_2", "propNames": ["_timestamp"]}
],
"props": [
{
"name": "time",
"dataType": "long",
"defaultValue": 0
},
{
"name": "weight",
"dataType": "long",
"defaultValue": 0
},
{
"name": "is_hidden",
"dataType": "boolean",
"defaultValue": false
},
{
"name": "is_blocked",
"dataType": "boolean",
"defaultValue": false
}
],
"consistencyLevel": "strong",
"schemaVersion": "v2",
"compressionAlgorithm": "gz",
"hTableName": "$testHTableName"
}"""
val testLabelName2Create =
s"""
{
"label": "$testLabelName2",
"srcServiceName": "$testServiceName",
"srcColumnName": "$testColumnName",
"srcColumnType": "long",
"tgtServiceName": "$testServiceName",
"tgtColumnName": "$testTgtColumnName",
"tgtColumnType": "string",
"indices": [{"name": "idx_1", "propNames": ["time", "weight", "is_hidden", "is_blocked"]}],
"props": [
{
"name": "time",
"dataType": "long",
"defaultValue": 0
},
{
"name": "weight",
"dataType": "long",
"defaultValue": 0
},
{
"name": "is_hidden",
"dataType": "boolean",
"defaultValue": false
},
{
"name": "is_blocked",
"dataType": "boolean",
"defaultValue": false
}
],
"consistencyLevel": "strong",
"isDirected": false,
"schemaVersion": "v3",
"compressionAlgorithm": "gz"
}"""
val testLabelNameV1Create =
s"""
{
"label": "$testLabelNameV1",
"srcServiceName": "$testServiceName",
"srcColumnName": "$testColumnName",
"srcColumnType": "long",
"tgtServiceName": "$testServiceName",
"tgtColumnName": "${testTgtColumnName}_v1",
"tgtColumnType": "string",
"indices": [{"name": "idx_1", "propNames": ["time", "weight", "is_hidden", "is_blocked"]}],
"props": [
{
"name": "time",
"dataType": "long",
"defaultValue": 0
},
{
"name": "weight",
"dataType": "long",
"defaultValue": 0
},
{
"name": "is_hidden",
"dataType": "boolean",
"defaultValue": false
},
{
"name": "is_blocked",
"dataType": "boolean",
"defaultValue": false
}
],
"consistencyLevel": "strong",
"isDirected": true,
"schemaVersion": "v1",
"compressionAlgorithm": "gz"
}"""
val testLabelNameWeakCreate =
s"""
{
"label": "$testLabelNameWeak",
"srcServiceName": "$testServiceName",
"srcColumnName": "$testColumnName",
"srcColumnType": "long",
"tgtServiceName": "$testServiceName",
"tgtColumnName": "$testTgtColumnName",
"tgtColumnType": "string",
"indices": [{"name": "idx_1", "propNames": ["time", "weight", "is_hidden", "is_blocked"]}],
"props": [
{
"name": "time",
"dataType": "long",
"defaultValue": 0
},
{
"name": "weight",
"dataType": "long",
"defaultValue": 0
},
{
"name": "is_hidden",
"dataType": "boolean",
"defaultValue": false
},
{
"name": "is_blocked",
"dataType": "boolean",
"defaultValue": false
}
],
"consistencyLevel": "weak",
"isDirected": true,
"compressionAlgorithm": "gz"
}"""
val vertexPropsKeys = List(
("age", "int")
)
val createVertex =
s"""{
"serviceName": "$testServiceName",
"columnName": "$testColumnName",
"columnType": "$testColumnType",
"props": [
{"name": "is_active", "dataType": "boolean", "defaultValue": true},
{"name": "phone_number", "dataType": "string", "defaultValue": "-"},
{"name": "nickname", "dataType": "string", "defaultValue": ".."},
{"name": "activity_score", "dataType": "float", "defaultValue": 0.0},
{"name": "age", "dataType": "integer", "defaultValue": 0}
]
}"""
val TS = System.currentTimeMillis()
def queryJson(serviceName: String, columnName: String, labelName: String, id: String, dir: String, cacheTTL: Long = -1L) = {
val s =
s"""{
"srcVertices": [
{
"serviceName": "$serviceName",
"columnName": "$columnName",
"id": $id
}
],
"steps": [
[
{
"label": "$labelName",
"direction": "$dir",
"offset": 0,
"limit": 10,
"cacheTTL": $cacheTTL
}
]
]
}"""
println(s)
Json.parse(s)
}
def checkEdgeQueryJson(params: Seq[(String, String, String, String)]) = {
val arr = for {
(label, dir, from, to) <- params
} yield {
Json.obj("label" -> label, "direction" -> dir, "from" -> from, "to" -> to)
}
val s = Json.toJson(arr)
println(s)
s
}
def vertexQueryJson(serviceName: String, columnName: String, ids: Seq[Int]) = {
Json.parse(
s"""
|[
|{"serviceName": "$serviceName", "columnName": "$columnName", "ids": [${ids.mkString(",")}
]}
|]
""".stripMargin)
}
def randomProps() = {
(for {
(propKey, propType) <- vertexPropsKeys
} yield {
propKey -> Random.nextInt(100)
}).toMap
}
def vertexInsertsPayload(serviceName: String, columnName: String, ids: Seq[Int]): Seq[JsValue] = {
ids.map { id =>
Json.obj("id" -> id, "props" -> randomProps, "timestamp" -> System.currentTimeMillis())
}
}
def commonCheck(rslt: Future[play.api.mvc.Result]): JsValue = {
status(rslt) must equalTo(OK)
contentType(rslt) must beSome.which(_ == "application/json")
val jsRslt = contentAsJson(rslt)
println("======")
println(jsRslt)
println("======")
jsRslt.as[JsObject].keys.contains("size") must equalTo(true)
(jsRslt \ "size").as[Int] must greaterThan(0)
jsRslt.as[JsObject].keys.contains("results") must equalTo(true)
val jsRsltsObj = jsRslt \ "results"
jsRsltsObj.as[JsArray].value(0).as[JsObject].keys.contains("from") must equalTo(true)
jsRsltsObj.as[JsArray].value(0).as[JsObject].keys.contains("to") must equalTo(true)
jsRsltsObj.as[JsArray].value(0).as[JsObject].keys.contains("_timestamp") must equalTo(true)
jsRsltsObj.as[JsArray].value(0).as[JsObject].keys.contains("props") must equalTo(true)
jsRslt
}
def init() = {
running(FakeApplication()) {
println("[init start]: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
Management.deleteService(testServiceName)
// 1. createService
val result = AdminController.createServiceInner(Json.parse(createService))
println(s">> Service created : $createService, $result")
val labelNames = Map(testLabelName -> testLabelNameCreate,
testLabelName2 -> testLabelName2Create,
testLabelNameV1 -> testLabelNameV1Create,
testLabelNameWeak -> testLabelNameWeakCreate)
for {
(labelName, create) <- labelNames
} {
Management.deleteLabel(labelName)
Label.findByName(labelName, useCache = false) match {
case None =>
AdminController.createLabelInner(Json.parse(create))
case Some(label) =>
println(s">> Label already exist: $create, $label")
}
}
// 5. create vertex
vertexPropsKeys.map { case (key, keyType) =>
Management.addVertexProp(testServiceName, testColumnName, key, keyType)
}
println("[init end]: >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
}
}
}