This is an automated email from the ASF dual-hosted git repository. sergeykamov pushed a commit to branch NLPCRAFT-381 in repository https://gitbox.apache.org/repos/asf/incubator-nlpcraft.git
commit d895788ea047fefd64861c90cbc88aa42ae850ff Author: Sergey Kamov <[email protected]> AuthorDate: Wed Aug 11 14:48:18 2021 +0300 WIP. --- nlpcraft-tests/cli/pom.xml | 62 +++++++++ .../nlpcraft/model/tools/cmdline/NCCliSpec.scala | 141 +++++++++++++++++++++ pom.xml | 7 + 3 files changed, 210 insertions(+) diff --git a/nlpcraft-tests/cli/pom.xml b/nlpcraft-tests/cli/pom.xml new file mode 100644 index 0000000..7c2f588 --- /dev/null +++ b/nlpcraft-tests/cli/pom.xml @@ -0,0 +1,62 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<!-- + 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. +--> + +<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + + <name>NLPCraft CLI Tests</name> + <artifactId>nlpcraft-tests-cli</artifactId> + + <parent> + <groupId>org.apache.nlpcraft</groupId> + <artifactId>nlpcraft-parent</artifactId> + <version>0.9.0</version> + <relativePath>../../pom.xml</relativePath> + </parent> + + <dependencies> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>nlpcraft</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- Test dependencies. --> + <dependency> + <groupId>org.junit.jupiter</groupId> + <artifactId>junit-jupiter-engine</artifactId> + <scope>test</scope> + </dependency> + </dependencies> + + <build> + <resources> + <resource> + <directory>src/main/scala</directory> + </resource> + <resource> + <directory>src/main/resources</directory> + <includes> + <include>**/*.*</include> + </includes> + </resource> + </resources> + </build> +</project> diff --git a/nlpcraft-tests/cli/src/test/java/org/apache/nlpcraft/model/tools/cmdline/NCCliSpec.scala b/nlpcraft-tests/cli/src/test/java/org/apache/nlpcraft/model/tools/cmdline/NCCliSpec.scala new file mode 100644 index 0000000..1486f4c --- /dev/null +++ b/nlpcraft-tests/cli/src/test/java/org/apache/nlpcraft/model/tools/cmdline/NCCliSpec.scala @@ -0,0 +1,141 @@ +/* + * 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()) + } +} diff --git a/pom.xml b/pom.xml index 4a6649e..b27bfe7 100644 --- a/pom.xml +++ b/pom.xml @@ -648,6 +648,13 @@ </profile> <profile> + <id>tests</id> + <modules> + <module>nlpcraft-tests/cli</module> + </modules> + </profile> + + <profile> <id>release</id> <activation> <property>
