blob: e8d97f0cea5cea23ba0d623cecac79d335d71f37 [file] [log] [blame]
/*
* 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.openwhisk.standalone
import java.io.File
import java.net.URI
import java.nio.charset.StandardCharsets.UTF_8
import com.google.common.base.Stopwatch
import common.WhiskProperties.WHISK_SERVER
import common.{FreePortFinder, StreamLogging, WhiskProperties, Wsk}
import io.restassured.RestAssured
import org.apache.commons.io.{FileUtils, FilenameUtils}
import org.apache.openwhisk.core.WhiskConfig
import org.apache.openwhisk.utils.retry
import org.scalatest.{BeforeAndAfterAll, Suite, TestSuite}
import scala.collection.mutable.ListBuffer
import scala.concurrent.duration._
import scala.sys.process._
import scala.util.control.NonFatal
trait StandaloneServerFixture extends TestSuite with BeforeAndAfterAll with StreamLogging {
self: Suite =>
private val jarPathProp = "whisk.server.jar"
private var serverProcess: Process = _
protected val serverPort: Int = FreePortFinder.freePort()
protected var serverUrl: String = System.getProperty(WHISK_SERVER, s"http://localhost:$serverPort/")
private val disablePullConfig = "whisk.docker.standalone.container-factory.pull-standard-images"
private var serverStartedForTest = false
private val tempFiles = ListBuffer[File]()
private val whiskServerPreDefined = System.getProperty(WHISK_SERVER) != null
protected def extraArgs: Seq[String] = Seq.empty
protected def extraVMArgs: Seq[String] = Seq.empty
protected def customConfig: Option[String] = None
protected def waitForOtherThings(): Unit = {}
protected def dumpLogsAlways: Boolean = false
protected def dumpStartupLogs: Boolean = false
protected def disablePlayGround: Boolean = true
protected val dataDirPath: String = FilenameUtils.concat(FileUtils.getTempDirectoryPath, "standalone")
override def beforeAll(): Unit = {
val serverUrlViaSysProp = Option(System.getProperty(WHISK_SERVER))
serverUrlViaSysProp match {
case Some(u) =>
serverUrl = u
println(s"Connecting to existing server at $serverUrl")
case None =>
System.setProperty(WHISK_SERVER, serverUrl)
super.beforeAll()
println(s"Running standalone server from ${standaloneServerJar.getAbsolutePath}")
val pgArgs = if (disablePlayGround) Seq("--no-ui") else Seq.empty
val args = Seq(
Seq(
"java",
//For tests let it bound on all ip to make it work on travis which uses linux
"-Dwhisk.controller.interface=0.0.0.0",
s"-Dwhisk.standalone.wsk=${Wsk.defaultCliPath}",
s"-D$disablePullConfig=false")
++ extraVMArgs
++ Seq("-jar", standaloneServerJar.getAbsolutePath, "--disable-color-logging", "--data-dir", dataDirPath)
++ configFileOpts
++ manifestFileOpts
++ pgArgs
++ extraArgs,
Seq("-p", serverPort.toString)).flatten
serverProcess = args.run(ProcessLogger(s => printstream.println(s)))
val w = waitForServerToStart()
serverStartedForTest = true
println(s"Started test server at $serverUrl in [$w]")
waitForOtherThings()
if (dumpStartupLogs) {
println(logLines.mkString("\n"))
}
}
}
override def afterAll(): Unit = {
super.afterAll()
if (!whiskServerPreDefined) {
System.clearProperty(WHISK_SERVER)
}
if (serverStartedForTest) {
serverProcess.destroy()
FileUtils.forceDelete(new File(dataDirPath))
tempFiles.foreach(FileUtils.deleteQuietly)
}
}
override def withFixture(test: NoArgTest) = {
val outcome = super.withFixture(test)
if (outcome.isFailed || (outcome.isSucceeded && dumpLogsAlways)) {
println(logLines.mkString("\n"))
}
stream.reset()
outcome
}
def waitForServerToStart(): Stopwatch = {
val w = Stopwatch.createStarted()
try {
retry({
println(s"Waiting for OpenWhisk server to start since $w")
val response = RestAssured.get(new URI(serverUrl))
require(response.statusCode() == 200)
}, 60, Some(1.second))
} catch {
case NonFatal(e) =>
println(logLines.mkString("\n"))
throw e
}
w
}
private def configFileOpts: Seq[String] = {
customConfig
.map(fileOpt("-c", _))
.getOrElse(Seq.empty)
}
private def manifestFileOpts: Seq[String] = {
Option(WhiskProperties.getProperty(WhiskConfig.runtimesManifest))
.map(fileOpt("-m", _))
.getOrElse(Seq.empty)
}
private def fileOpt(optName: String, content: String): Seq[String] = {
val f = File.createTempFile("whisktest", null, null)
tempFiles += f
FileUtils.write(f, content, UTF_8)
Seq(optName, f.getAbsolutePath)
}
private def standaloneServerJar: File = {
Option(System.getProperty(jarPathProp)) match {
case Some(p) =>
val jarFile = new File(p)
assert(
jarFile.canRead,
s"OpenWhisk standalone server jar file [$p] specified via system property [$jarPathProp] not found")
jarFile
case None =>
fail(s"No jar file specified via system property [$jarPathProp]")
}
}
}