Skip to content

Commit

Permalink
[KYUUBI #1631] Migrating existing rest fe tests to real cases
Browse files Browse the repository at this point in the history
<!--
Thanks for sending a pull request!

Here are some tips for you:
  1. If this is your first time, please read our contributor guidelines: https://kyuubi.readthedocs.io/en/latest/community/contributions.html
  2. If the PR is related to an issue in https://github.com/apache/incubator-kyuubi/issues, add '[KYUUBI #XXXX]' in your PR title, e.g., '[KYUUBI #XXXX] Your PR title ...'.
  3. If the PR is unfinished, add '[WIP]' in your PR title, e.g., '[WIP][KYUUBI #XXXX] Your PR title ...'.
-->

### _Why are the changes needed?_
<!--
Please clarify why the changes are needed. For instance,
  1. If you add a feature, you can talk about the use case of it.
  2. If you fix a bug, you can clarify why it is a bug.
-->

In this PR, we target the existing UTs from a noop server to a real shared Kyuubi server.

### _How was this patch tested?_
- [x] Add some test cases that check the changes thoroughly including negative and positive cases if possible

- [ ] Add screenshots for manual tests if appropriate

- [ ] [Run test](https://kyuubi.readthedocs.io/en/latest/develop_tools/testing.html#running-tests) locally before make a pull request

Closes #1631 from yaooqinn/resttest.

Closes #1631

2726ab4 [Kent Yao] address comments
c0da809 [Kent Yao] ci
5d12f70 [Kent Yao] address comments
80e1404 [Kent Yao] Migrating existing rest fe test to real cases
a31ab50 [Kent Yao] Migrating existing rest fe test to real cases
0c1feb4 [Kent Yao] Migrating existing rest fe test to real cases
fbd9769 [Kent Yao] Migrating existing rest fe test to real cases
75cca5f [Kent Yao] Migrating existing rest fe test to real cases
119712e [Kent Yao] Migrating existing rest fe test to real cases
8196e4d [Kent Yao] Migrating existing rest fe test to real cases

Authored-by: Kent Yao <yao@apache.org>
Signed-off-by: Kent Yao <yao@apache.org>
  • Loading branch information
yaooqinn committed Dec 28, 2021
1 parent 2af105a commit e1587ee
Show file tree
Hide file tree
Showing 8 changed files with 314 additions and 462 deletions.
Expand Up @@ -76,7 +76,7 @@ class KyuubiRestFrontendService(override val serverable: Serverable)

override def connectionUrl: String = {
checkInitialized()
s"${serverAddr.getCanonicalHostName}:$portNum"
s"${serverAddr.getCanonicalHostName}:${connector.getLocalPort}"
}

override def start(): Unit = {
Expand Down
Expand Up @@ -211,13 +211,15 @@ private[v1] class SessionsResource extends ApiRequestContext {
@PathParam("sessionHandle") sessionHandleStr: String,
request: GetSchemasRequest): OperationHandle = {
try {
backendService.getSchemas(
parseSessionHandle(sessionHandleStr),
val sessionHandle = parseSessionHandle(sessionHandleStr)
val operationHandle = backendService.getSchemas(
sessionHandle,
request.catalogName,
request.schemaName)
operationHandle
} catch {
case NonFatal(_) =>
throw new NotFoundException(s"Error getting schemas")
case NonFatal(e) =>
throw new NotFoundException(s"Error getting schemas", e)
}
}

Expand Down
Expand Up @@ -17,6 +17,7 @@

package org.apache.kyuubi

import java.net.URI
import javax.ws.rs.client.WebTarget
import javax.ws.rs.core.{Application, UriBuilder}

Expand All @@ -28,9 +29,10 @@ import org.glassfish.jersey.test.spi.TestContainerFactory

import org.apache.kyuubi.RestFrontendTestHelper.RestApiBaseSuite
import org.apache.kyuubi.config.KyuubiConf
import org.apache.kyuubi.server.KyuubiRestFrontendService
import org.apache.kyuubi.config.KyuubiConf.FrontendProtocols
import org.apache.kyuubi.config.KyuubiConf.FrontendProtocols.FrontendProtocol
import org.apache.kyuubi.server.api.KyuubiScalaObjectMapper
import org.apache.kyuubi.service.NoopRestFrontendServer
import org.apache.kyuubi.service.AbstractFrontendService

object RestFrontendTestHelper {

Expand All @@ -46,40 +48,28 @@ object RestFrontendTestHelper {
}
}

trait RestFrontendTestHelper {
trait RestFrontendTestHelper extends WithKyuubiServer {

val restFrontendHost: String = "localhost"
val restFrontendPort: Int = KyuubiConf().get(KyuubiConf.FRONTEND_REST_BIND_PORT)
override protected val conf: KyuubiConf = KyuubiConf()

def withKyuubiRestServer(
f: (KyuubiRestFrontendService, String, Int, WebTarget) => Unit): Unit = {
override protected val frontendProtocols: Seq[FrontendProtocol] =
FrontendProtocols.REST :: Nil

val server = new NoopRestFrontendServer()
server.stop()
val conf = KyuubiConf()
conf.set(KyuubiConf.FRONTEND_REST_BIND_HOST, Some(restFrontendHost))
private val restApiBaseSuite = new RestApiBaseSuite

server.initialize(conf)
server.start()

val restApiBaseSuite = new RestApiBaseSuite
override def beforeAll(): Unit = {
super.beforeAll()
restApiBaseSuite.setUp()
// noinspection HttpUrlsUsage
val baseUri = UriBuilder
.fromUri(s"http://$restFrontendHost/")
.port(restFrontendPort)
.build()
val webTarget = restApiBaseSuite.client.target(baseUri)

try {
f(
server.frontendServices.head,
conf.get(KyuubiConf.FRONTEND_REST_BIND_HOST).get,
restFrontendPort,
webTarget)
} finally {
restApiBaseSuite.tearDown()
server.stop()
}
}

override def afterAll(): Unit = {
restApiBaseSuite.tearDown()
super.afterAll()
}

protected lazy val fe: AbstractFrontendService = server.frontendServices.head

protected lazy val baseUri: URI = UriBuilder.fromUri(s"http://${fe.connectionUrl}/").build()

protected lazy val webTarget: WebTarget = restApiBaseSuite.client.target(baseUri)
}
Expand Up @@ -19,6 +19,7 @@ package org.apache.kyuubi

import org.apache.kyuubi.config.KyuubiConf
import org.apache.kyuubi.config.KyuubiConf._
import org.apache.kyuubi.config.KyuubiConf.FrontendProtocols.FrontendProtocol
import org.apache.kyuubi.ha.HighAvailabilityConf.{HA_ZK_AUTH_TYPE, HA_ZK_QUORUM}
import org.apache.kyuubi.ha.client.ZooKeeperAuthTypes
import org.apache.kyuubi.server.KyuubiServer
Expand All @@ -28,7 +29,7 @@ trait WithKyuubiServer extends KyuubiFunSuite {

protected val conf: KyuubiConf

protected val frontendProtocols: Seq[FrontendProtocols.Value] =
protected val frontendProtocols: Seq[FrontendProtocol] =
FrontendProtocols.THRIFT_BINARY :: Nil

private var zkServer: EmbeddedZookeeper = _
Expand Down
Expand Up @@ -17,80 +17,36 @@

package org.apache.kyuubi.server

import java.util.Locale
import org.apache.kyuubi.RestFrontendTestHelper

import scala.io.Source
class KyuubiRestFrontendServiceSuite extends RestFrontendTestHelper {

import org.scalatest.time.SpanSugar._

import org.apache.kyuubi.{KyuubiFunSuite, RestFrontendTestHelper}
import org.apache.kyuubi.config.KyuubiConf
import org.apache.kyuubi.service.NoopRestFrontendServer
import org.apache.kyuubi.service.ServiceState._

class KyuubiRestFrontendServiceSuite extends KyuubiFunSuite with RestFrontendTestHelper {

test("kyuubi REST frontend service basic") {
val server = new NoopRestFrontendServer()
server.stop()
val conf = KyuubiConf()
assert(server.getServices.isEmpty)
assert(server.getServiceState === LATENT)
val e = intercept[IllegalStateException](server.frontendServices.head.connectionUrl)
assert(e.getMessage startsWith "Illegal Service State: LATENT")
assert(server.getConf === null)
test("kyuubi REST frontend service http basic") {
val resp = webTarget.path("/api/v1/ping").request().get()
assert(resp.readEntity(classOf[String]) === "pong")
}

server.initialize(conf)
assert(server.getServiceState === INITIALIZED)
val frontendService = server.frontendServices.head
assert(frontendService.getServiceState == INITIALIZED)
assert(server.frontendServices.head.connectionUrl.split(":").length === 2)
assert(server.getConf === conf)
assert(server.getStartTime === 0)
server.stop()
test("error and exception response") {
var response = webTarget.path("api/v1/pong").request().get()
assert(404 == response.getStatus)
assert(response.getStatusInfo.getReasonPhrase.equalsIgnoreCase("not found"))

server.start()
assert(server.getServiceState === STARTED)
assert(frontendService.getServiceState == STARTED)
assert(server.getStartTime !== 0)
response = webTarget.path("api/v1/ping").request().post(null)
assert(405 == response.getStatus)
assert(response.getStatusInfo.getReasonPhrase.equalsIgnoreCase("method not allowed"))

server.stop()
assert(server.getServiceState === STOPPED)
assert(frontendService.getServiceState == STOPPED)
server.stop()
response = webTarget.path("api/v1/exception").request().get()
assert(500 == response.getStatus)
assert(response.getStatusInfo.getReasonPhrase.equalsIgnoreCase("server error"))
}

test("kyuubi REST frontend service http basic") {
withKyuubiRestServer { (_, host, port, _) =>
eventually(timeout(10.seconds), interval(50.milliseconds)) {
val html = {
// noinspection HttpUrlsUsage
val s = Source.fromURL(s"http://$host:$port/api/v1/ping")
val str = s.mkString
s.close()
str
}
assert(html.toLowerCase(Locale.ROOT).equals("pong"))
}
}
test("swagger ui") {
val resp = webTarget.path("/api/v1/swagger-ui").request().get()
assert(resp.getStatus === 200)
}

test("test error and exception response") {
withKyuubiRestServer { (_, _, _, webTarget) =>
// send a not exists request
var response = webTarget.path("api/v1/pong").request().get()
assert(404 == response.getStatus)
assert(response.getStatusInfo.getReasonPhrase.equalsIgnoreCase("not found"))

// send a exists request but wrong http method
response = webTarget.path("api/v1/ping").request().post(null)
assert(405 == response.getStatus)
assert(response.getStatusInfo.getReasonPhrase.equalsIgnoreCase("method not allowed"))

// send a request but throws a exception on the server side
response = webTarget.path("api/v1/exception").request().get()
assert(500 == response.getStatus)
assert(response.getStatusInfo.getReasonPhrase.equalsIgnoreCase("server error"))
}
test("swagger ui json data") {
val resp = webTarget.path("/openapi.json").request().get()
assert(resp.getStatus === 200)
}
}

0 comments on commit e1587ee

Please sign in to comment.