NOISSUE - Add test suite for WebSocket adapter (#299)
* Add load test for WebSocket adapter Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com> * Add new test suite to README file Signed-off-by: Aleksandar Novakovic <aleksandar.novakovic@mainflux.com>
This commit is contained in:
parent
808ac50792
commit
ef3627f4ee
|
@ -18,14 +18,16 @@ default values.
|
|||
| users | Users service URL | http://localhost:8180 |
|
||||
| things | Things service URL | http://localhost:8182 |
|
||||
| http | HTTP adapter service URL | http://localhost:8185 |
|
||||
| ws | WebSocket adapter service URL | localhost:8186 |
|
||||
| requests | Number of requests to be sent per second | 100 |
|
||||
|
||||
## Usage
|
||||
|
||||
This project contains two simulations:
|
||||
This project contains three simulations:
|
||||
|
||||
- `CreateAndRetrieveThings`
|
||||
- `PublishMessages`
|
||||
- `PublishHttpMessages`
|
||||
- `PublishWsMessages`
|
||||
|
||||
To run all tests you will have to run following commands:
|
||||
|
||||
|
@ -43,11 +45,20 @@ Execute the following command to run the suite:
|
|||
sbt "gatling:testOnly com.mainflux.loadtest.CreateAndRetrieveThings"
|
||||
```
|
||||
|
||||
### Message publishing
|
||||
### Message publishing over HTTP adapter
|
||||
|
||||
`PublishMessages` contains load tests for publishing messages. Execute the following
|
||||
command to run the suite:
|
||||
`PublishHttpMessages` contains load tests for publishing messages over HTTP.
|
||||
Execute the following command to run the suite:
|
||||
|
||||
```bash
|
||||
sbt "gatling:testOnly com.mainflux.loadtest.PublishMessages"
|
||||
sbt "gatling:testOnly com.mainflux.loadtest.PublishHttpMessages"
|
||||
```
|
||||
|
||||
### Message publishing over WebSocket adapter
|
||||
|
||||
`PublishWsMessages` contains load tests for publishing messages over WebSocket.
|
||||
Execute the following command to run the suite:
|
||||
|
||||
```bash
|
||||
sbt "gatling:testOnly com.mainflux.loadtest.PublishWsMessages"
|
||||
```
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
package com.mainflux.loadtest
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import io.gatling.core.Predef._
|
||||
import io.gatling.http.Predef._
|
||||
import io.gatling.http.request.builder.HttpRequestBuilder.toActionBuilder
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
final class CreateAndRetrieveThings extends TestCase {
|
||||
override def prepareAndExecute(): SetUp = {
|
||||
val token = authenticate()
|
||||
|
@ -27,4 +27,3 @@ final class CreateAndRetrieveThings extends TestCase {
|
|||
setUp(scn.inject(constantUsersPerSec(RequestsPerSecond) during 15.seconds)).protocols(httpProtocol(ThingsURL))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
package com.mainflux.loadtest
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import io.gatling.core.Predef._
|
||||
import io.gatling.http.Predef._
|
||||
import io.gatling.http.request.builder.HttpRequestBuilder.toActionBuilder
|
||||
|
||||
final class PublishHttpMessages extends PublishMessages {
|
||||
override def prepareAndExecute(): SetUp = {
|
||||
val message =
|
||||
"""
|
||||
|[
|
||||
| {"bn":"some-base-name:","bt":1.276020076001e+09,"bu":"A","bver":5,"n":"voltage","u":"V","v":120.1},
|
||||
| {"n":"current","t":-5,"v":1.2},
|
||||
| {"n":"current","t":-4,"v":1.3}
|
||||
|]""".stripMargin
|
||||
|
||||
val token = authenticate()
|
||||
val (thingID, thingKey) = makeThing(token)
|
||||
val channelID = makeChannel(token)
|
||||
|
||||
connect(channelID, thingID, token)
|
||||
|
||||
val scn = scenario("publish message over HTTP")
|
||||
.exec(http("publish message request")
|
||||
.post(s"/channels/$channelID/messages")
|
||||
.header(HttpHeaderNames.ContentType, "application/senml+json")
|
||||
.header(HttpHeaderNames.Authorization, thingKey)
|
||||
.body(StringBody(message))
|
||||
.check(status.is(202)))
|
||||
|
||||
setUp(scn.inject(constantUsersPerSec(RequestsPerSecond) during 15.seconds)).protocols(httpProtocol(url()))
|
||||
}
|
||||
|
||||
private def url(): String = System.getProperty("http", "http://localhost:8185")
|
||||
}
|
|
@ -2,79 +2,47 @@ package com.mainflux.loadtest
|
|||
|
||||
import io.circe._
|
||||
import io.circe.parser._
|
||||
import io.gatling.core.Predef._
|
||||
import io.gatling.http.Predef._
|
||||
import io.gatling.http.request.builder.HttpRequestBuilder.toActionBuilder
|
||||
import scalaj.http.Http
|
||||
|
||||
import scala.concurrent.duration._
|
||||
abstract class PublishMessages extends TestCase {
|
||||
def makeThing(token: String): (String, String) = {
|
||||
val thing = """{"type":"device", "name":"weio"}"""
|
||||
|
||||
final class PublishMessages extends TestCase {
|
||||
override def prepareAndExecute(): SetUp = {
|
||||
def makeThing(token: String): (String, String) = {
|
||||
val thing = """{"type":"device", "name":"weio"}"""
|
||||
val id = Http(s"$ThingsURL/things")
|
||||
.postData(thing)
|
||||
.header(HttpHeaderNames.Authorization, token)
|
||||
.header(HttpHeaderNames.ContentType, jsonType)
|
||||
.asString
|
||||
.headers(HttpHeaderNames.Location)(0).split("/")(2)
|
||||
|
||||
val id = Http(s"$ThingsURL/things")
|
||||
.postData(thing)
|
||||
.header(HttpHeaderNames.Authorization, token)
|
||||
.header(HttpHeaderNames.ContentType, jsonType)
|
||||
.asString
|
||||
.headers(HttpHeaderNames.Location)(0).split("/")(2)
|
||||
val res = Http(s"$ThingsURL/things/$id")
|
||||
.header(HttpHeaderNames.Authorization, token)
|
||||
.header(HttpHeaderNames.ContentType, jsonType)
|
||||
.asString
|
||||
.body
|
||||
|
||||
val res = Http(s"$ThingsURL/things/$id")
|
||||
.header(HttpHeaderNames.Authorization, token)
|
||||
.header(HttpHeaderNames.ContentType, jsonType)
|
||||
.asString
|
||||
.body
|
||||
val key = parse(res).getOrElse(Json.Null).hcursor.downField("key").as[String].getOrElse("")
|
||||
|
||||
val key = parse(res).getOrElse(Json.Null).hcursor.downField("key").as[String].getOrElse("")
|
||||
|
||||
(id, key)
|
||||
}
|
||||
|
||||
def makeChannel(token: String): String = {
|
||||
val channel = """{"name":"mychan"}"""
|
||||
|
||||
Http(s"$ThingsURL/channels")
|
||||
.postData(channel)
|
||||
.header(HttpHeaderNames.Authorization, token)
|
||||
.header(HttpHeaderNames.ContentType, jsonType)
|
||||
.asString
|
||||
.headers(HttpHeaderNames.Location)(0)
|
||||
.split("/")(2)
|
||||
}
|
||||
|
||||
def connect(channel: String, thing: String, token: String): Unit = {
|
||||
Http(s"$ThingsURL/channels/$channel/things/$thing")
|
||||
.method("PUT")
|
||||
.header(HttpHeaderNames.Authorization, token)
|
||||
.asString
|
||||
}
|
||||
|
||||
val message =
|
||||
"""
|
||||
|[
|
||||
| {"bn":"some-base-name:","bt":1.276020076001e+09,"bu":"A","bver":5,"n":"voltage","u":"V","v":120.1},
|
||||
| {"n":"current","t":-5,"v":1.2},
|
||||
| {"n":"current","t":-4,"v":1.3}
|
||||
|]""".stripMargin
|
||||
|
||||
val token = authenticate()
|
||||
val (thingID, thingKey) = makeThing(token)
|
||||
val channelID = makeChannel(token)
|
||||
|
||||
connect(channelID, thingID, thingKey)
|
||||
|
||||
val scn = scenario("publish message")
|
||||
.exec(http("publish message request")
|
||||
.post(s"/channels/$channelID/messages")
|
||||
.header(HttpHeaderNames.ContentType, "application/senml+json")
|
||||
.header(HttpHeaderNames.Authorization, thingKey)
|
||||
.body(StringBody(message))
|
||||
.check(status.is(202)))
|
||||
|
||||
setUp(scn.inject(constantUsersPerSec(RequestsPerSecond) during 15.seconds)).protocols(httpProtocol(url()))
|
||||
(id, key)
|
||||
}
|
||||
|
||||
private def url(): String = System.getProperty("http", "http://localhost:8185")
|
||||
def makeChannel(token: String): String = {
|
||||
val channel = """{"name":"mychan"}"""
|
||||
|
||||
Http(s"$ThingsURL/channels")
|
||||
.postData(channel)
|
||||
.header(HttpHeaderNames.Authorization, token)
|
||||
.header(HttpHeaderNames.ContentType, jsonType)
|
||||
.asString
|
||||
.headers(HttpHeaderNames.Location)(0)
|
||||
.split("/")(2)
|
||||
}
|
||||
|
||||
def connect(channel: String, thing: String, token: String): Unit = {
|
||||
Http(s"$ThingsURL/channels/$channel/things/$thing")
|
||||
.method("PUT")
|
||||
.header(HttpHeaderNames.Authorization, token)
|
||||
.asString
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
package com.mainflux.loadtest
|
||||
|
||||
import scala.concurrent.duration._
|
||||
|
||||
import io.gatling.core.Predef._
|
||||
import io.gatling.http.Predef._
|
||||
|
||||
final class PublishWsMessages extends PublishMessages {
|
||||
override def prepareAndExecute(): SetUp = {
|
||||
val message =
|
||||
"""
|
||||
|[
|
||||
| {"bn":"some-base-name:","bt":1.276020076001e+09,"bu":"A","bver":5,"n":"voltage","u":"V","v":120.1},
|
||||
| {"n":"current","t":-5,"v":1.2},
|
||||
| {"n":"current","t":-4,"v":1.3}
|
||||
|]""".stripMargin
|
||||
|
||||
val token = authenticate()
|
||||
val (thingID, thingKey) = makeThing(token)
|
||||
val channelID = makeChannel(token)
|
||||
|
||||
connect(channelID, thingID, token)
|
||||
|
||||
val scn = scenario("publish message over WebSocket")
|
||||
.exec(ws("Connect WS")
|
||||
.open(s"/channels/$channelID/messages?authorization=$thingKey"))
|
||||
.exec(ws("Send message")
|
||||
.sendText(message)
|
||||
.check(wsAwait.within(30).until(1)))
|
||||
.exec(ws("Close WS").close)
|
||||
|
||||
setUp(scn.inject(constantUsersPerSec(RequestsPerSecond) during 15.seconds)).protocols(wsProtocol(url()))
|
||||
}
|
||||
|
||||
private def url(): String = System.getProperty("ws", "localhost:8186")
|
||||
}
|
|
@ -12,7 +12,7 @@ trait TestCase extends Simulation {
|
|||
protected lazy val ThingsURL: String = System.getProperty("things", "http://localhost:8182")
|
||||
protected lazy val RequestsPerSecond: Double = Integer.getInteger("requests", 100).toDouble
|
||||
|
||||
protected val jsonType: String = "application/jsonType"
|
||||
protected val jsonType: String = "application/json"
|
||||
|
||||
def authenticate(): String = {
|
||||
val user = """{"email":"john.doe@email.com", "password":"123"}"""
|
||||
|
@ -42,6 +42,14 @@ trait TestCase extends Simulation {
|
|||
.userAgentHeader("curl/7.54.0")
|
||||
.build
|
||||
|
||||
def wsProtocol(url: String): HttpProtocol = http
|
||||
.baseURL(s"http://$url")
|
||||
.inferHtmlResources()
|
||||
.acceptHeader("*/*")
|
||||
.userAgentHeader("Gatling2")
|
||||
.wsBaseURL(s"ws://$url")
|
||||
.build
|
||||
|
||||
def prepareAndExecute(): SetUp
|
||||
|
||||
prepareAndExecute()
|
||||
|
|
Loading…
Reference in New Issue