blob: ea8082d3480fb0d955af8c7f2f5e5eae7992728b [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.daffodil.CLI
import org.apache.daffodil.util.Misc
import net.sf.expectit.ExpectBuilder
import net.sf.expectit.Expect
import net.sf.expectit.filter.Filters.replaceInString
import java.nio.file.Paths
import java.io.{File, PrintWriter}
import scala.collection.JavaConverters._
import java.util.concurrent.TimeUnit
import org.apache.daffodil.xml.XMLUtils
object Util {
//val testDir = "daffodil-cli/src/it/resources/org/apache/daffodil/CLI/"
val testDir = "/org/apache/daffodil/CLI/"
val outputDir = testDir + "output/"
val isWindows = System.getProperty("os.name").toLowerCase().startsWith("windows")
val dafRoot = sys.env.get("DAFFODIL_HOME").getOrElse(".")
def daffodilPath(dafRelativePath: String): String = {
XMLUtils.slashify(dafRoot) + dafRelativePath
}
val binPath = Paths.get(dafRoot, "daffodil-cli", "target", "universal", "stage", "bin", String.format("daffodil%s", (if (isWindows) ".bat" else ""))).toString()
def getExpectedString(filename: String, convertToDos: Boolean = false): String = {
val rsrc = Misc.getRequiredResource(outputDir + filename)
val is = rsrc.toURL.openStream()
val source = scala.io.Source.fromInputStream(is)
val lines = source.mkString.trim()
source.close()
fileConvert(lines)
}
def start(cmd: String, expectErr: Boolean = false, envp: Map[String, String] = Map.empty[String, String], timeout: Long = 30): Expect = {
val spawnCmd = if (isWindows) {
"cmd /k " + cmdConvert(cmd)
} else {
"/bin/bash"
}
return getShell(cmd, spawnCmd, expectErr, envp, timeout)
}
def startIncludeErrors(cmd: String, envp: Map[String, String] = Map.empty[String, String], timeout: Long = 30): Expect = {
val spawnCmd = if (isWindows) {
"cmd /k" + cmdConvert(cmd)
} else {
"/bin/bash"
}
getShellWithErrors(cmd, spawnCmd, envp, timeout)
}
// This function will be used if you are providing two separate commands
// and doing the os check on the 'front end' (not within this utility class)
def startNoConvert(cmd: String, envp: Map[String, String] = Map.empty[String, String], timeout: Long = 30): Expect = {
val spawnCmd = if (isWindows) {
"cmd /k" + cmd
} else {
"/bin/bash"
}
return getShell(cmd, spawnCmd, envp = envp, timeout = timeout)
}
def getShell(cmd: String, spawnCmd: String, expectErr: Boolean = false, envp: Map[String, String] = Map.empty[String, String], timeout: Long): Expect = {
val newEnv = System.getenv().asScala ++ envp
val envAsArray = newEnv.toArray.map { case (k, v) => k + "=" + v }
val process = Runtime.getRuntime().exec(spawnCmd, envAsArray)
val inputStream = if (expectErr) {
process.getErrorStream()
} else {
process.getInputStream()
}
val shell = new ExpectBuilder()
.withInputs(inputStream)
.withInputFilters(replaceInString("\r\n", "\n"))
.withOutput(process.getOutputStream())
.withEchoOutput(System.out)
.withEchoInput(System.out)
.withTimeout(timeout, TimeUnit.SECONDS)
.withExceptionOnFailure()
.build();
if (!isWindows) {
shell.send(cmd)
}
return shell
}
// Return a shell object with two streams
// The inputStream will be at index 0
// The errorStream will be at index 1
def getShellWithErrors(cmd: String, spawnCmd: String, envp: Map[String, String] = Map.empty[String, String], timeout: Long): Expect = {
val newEnv = System.getenv().asScala ++ envp
val envAsArray = newEnv.toArray.map { case (k, v) => k + "=" + v }
val process = Runtime.getRuntime().exec(spawnCmd, envAsArray)
val shell = new ExpectBuilder()
.withInputs(process.getInputStream(), process.getErrorStream())
.withInputFilters(replaceInString("\r\n", "\n"))
.withOutput(process.getOutputStream())
.withEchoOutput(System.out)
.withEchoInput(System.out)
.withTimeout(timeout, TimeUnit.SECONDS)
.withExceptionOnFailure()
.build();
if (!isWindows) {
shell.send(cmd)
}
return shell
}
def cmdConvert(str: String): String = {
if (isWindows)
str.replaceAll("/", "\\\\")
else
str
}
def fileConvert(str: String): String = {
val newstr = str.replaceAll("\r\n", "\n")
return newstr
}
def echoN(str: String): String = {
if (isWindows) {
"echo|set /p=" + str
} else {
"echo -n " + str
}
}
def devNull(): String = {
if (isWindows) {
"NUL"
} else {
"/dev/null"
}
}
def makeMultipleCmds(cmds: Array[String]): String = {
if (isWindows) {
cmds.mkString(" & ")
} else {
cmds.mkString("; ")
}
}
def md5sum(blob_path: String): String = {
if (isWindows) {
String.format("certutil -hashfile %s MD5", blob_path)
} else {
String.format("md5sum %s", blob_path)
}
}
def rmdir(path: String): String = {
if (Util.isWindows)
String.format("rmdir /Q /S %s", path)
else
String.format("rm -rf %s", path)
}
def cat(str: String): String = {
if (isWindows) {
"type " + str
} else {
"cat " + str
}
}
def newTempFile(filePrefix: String, fileSuffix: String, optFileContents: Option[String] = None): File = {
val inputFile = File.createTempFile(filePrefix, fileSuffix)
inputFile.deleteOnExit
if (optFileContents.nonEmpty) {
val contents = optFileContents.get
val pw = new PrintWriter(inputFile)
pw.write(contents)
pw.close
}
inputFile
}
}