blob: 1486f4c938d3615791faac24cb7d3cc6eed56d10 [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
*
* https://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.nlpcraft.model.tools.cmdline
import org.apache.commons.lang3.SystemUtils
import org.apache.nlpcraft.common.U
import org.junit.jupiter.api.Test
import java.io.{BufferedReader, File, FileFilter, InputStreamReader}
import java.util.concurrent.{CountDownLatch, TimeUnit}
import scala.collection.mutable
import scala.util.Using
/**
* This test designed only for maven tests (mvn clean verify)
* It cannot be started together with other server instances.
*/
class NCCliSpec {
private def check(dirs: File*): Unit = dirs.foreach(d => require(d.exists() && d.isDirectory, s"Invalid folder: $d"))
private def getAllDepsJar(dirTarget: File): File = {
val jars = dirTarget.listFiles(new FileFilter {
override def accept(f: File): Boolean = f.isFile && f.getName.toLowerCase().endsWith("all-deps.jar")
})
require(jars != null && jars.length == 1, s"Required jar file not found in ${dirTarget.getAbsolutePath}")
jars.head
}
private def makeProcess(
scriptArg: String,
script: String,
allDepsJar: File,
dirBin: File,
timeoutSecs: Int,
expectedLines: String*
): Process = {
val args = if (SystemUtils.IS_OS_UNIX) Seq("bash", "-f", script, scriptArg) else Seq(script, scriptArg)
val builder = new ProcessBuilder(args: _*)
builder.environment().put("CP", allDepsJar.getAbsolutePath)
builder.directory(dirBin)
builder.redirectErrorStream(true)
val process = builder.start()
val cdl = new CountDownLatch(1)
var done = false
val thread = new Thread() {
override def run(): Unit = {
Using.resource { new BufferedReader(new InputStreamReader(process.getInputStream)) }(reader => {
var line: String = reader.readLine()
while (line != null && !done) {
if (expectedLines.exists(line.contains)) {
done = true
println(s"$scriptArg finished fine by expected line: '$line'")
println()
cdl.countDown()
}
else {
println(s"($scriptArg) $line")
line = reader.readLine()
}
}
})
}
}
thread.start()
cdl.await(timeoutSecs, TimeUnit.SECONDS)
U.stopThread(thread)
require(done, s"Command cannot be started: $scriptArg")
process
}
@Test
def test(): Unit = {
// All folders should be exists because tests started from maven phase, after build project.
val ext = if (SystemUtils.IS_OS_UNIX) "sh" else "cmd"
val dirUsr = new File(SystemUtils.USER_DIR).getParentFile.getParentFile
val dirBin = new File(dirUsr, "bin")
val dirTarget = new File(dirUsr, "nlpcraft/target")
val script = new File(dirBin, s"nlpcraft.$ext").getAbsolutePath
check(dirUsr, dirBin, dirTarget)
val allDepsJar = getAllDepsJar(dirTarget)
def make(scriptArg: String, timeoutSecs: Int, expectedLines: String*): Process =
makeProcess(scriptArg, script, allDepsJar, dirBin, timeoutSecs, expectedLines: _*)
val procs = mutable.Buffer.empty[Process]
def stopInstances(): Unit = {
// Both variant (stopped or already stopped) are fine.
def stop(cmd: String): Process = make(cmd, 10, "has been stopped", "not found")
procs += stop("stop-server")
procs += stop("stop-probe")
}
try {
stopInstances()
procs += make("start-server", 120, "Started on")
procs += make("start-probe", 30, "Started on")
procs += make("info", 10, "Local server")
}
finally
try
stopInstances()
finally
procs.foreach(_.destroy())
}
}