Execute a external program within a groovy script and capture the output - groovy

I need to write a groovy script, that is executing a external program and print the output of that program to the console.
Here is the regarding code snippet:
def pmdCommand = "${scriptDir}/run.sh pmd -d ${filesToAnalyse}"
def sout = new StringBuffer()
def serr = new StringBuffer()
def process = pmdCommand.execute()
process.consumeProcessOutput(sout, serr)
process.waitFor()
if (process.exitValue() !=0 ) {
System.err << serr.toString()
System.exit(-1)
}
else {
System.out << sout.toString()
System.exit(0)
}
I did something similar in Java, but I can't translate it to groovy.
StringBuffer output = new StringBuffer();
String s = null;
try {
Process p = Runtime.getRuntime().exec(command);
p.waitFor();
BufferedReader stdInput = new BufferedReader(new InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(p.getErrorStream()));
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
while ((s = stdError.readLine()) != null) {
System.err.println(s);
}
System.exit(0);
}
catch (Exception e) {
e.printStackTrace();
System.exit(-1);
}
Update: I seems the waitFor() never returns and blocks the execution
Solution provided by Emmanuel Rosa:
def pmdCommand = "/usr/src/app/lib/pmd/bin/run.sh pmd -d ${filesToAnalyse} -f codeclimate -R ${ruleset} -l apex -v 35"
def sout = new StringBuffer()
def serr = new StringBuffer()
def process = pmdCommand.execute()
process.consumeProcessOutput(sout, serr)
process.waitForProcessOutput()
System.out << sout.toString()
System.exit(0)

The documentation states that consumeProcessOutput()...
Gets the output and error streams from a process and reads them to
keep the process from blocking due to a full output buffer. The
processed stream data is appended to the supplied OutputStream. For
this, two Threads are started, so this method will return immediately.
So far so good. Here's the important part...
The threads will not be join()ed, even if waitFor() is called.
And the solution...
To wait
for the output to be fully consumed call waitForProcessOutput().
So what you can do is replace process.waitFor() with process.waitForProcessOutput().

Related

How can I detect <EOF> of a "CSV data set config" in a groovy script sampler in JMeter?

I want to know, how it's possible to react on a in a groovy script.
I'm using a While controller to iterate through all lines in the CSV and generate JMeter variables before my actual testplan. I need to do this several times for different CSV files, therefore I don't want to stop the thread at in the While controller.
I imagined something like this:
if (${CSV_VALUE1} != "<EOF>")
{
def variableName = sprintf('%1$sVALUE',[${CSV_VALUE2}])
vars.put(variableName,${CSV_VALUE1});
}
CSV_VALUE1 is the value for the JMeter variable and CSV_VALUE2 is the name of the variable.
Testplan
I also appreciate better solutions, which iterate through every row of the CSV file and generate JMeter variables according to my conventions of it. A constraint is, that it has to be done in only one single thread group (=> No stopping of threads on EOF)
You can use "BeanShell" to read "CSV file", below is sample csv file, which has below data
answer1,0
answer2,1
answer3,2
...
answerX,X-1
To read this file use below "Beanshell" script
import java.text.*;
import java.io.*;
import java.util.*;
String filename = "oprosnik_" + vars.get("fileNum") + ".csv";
ArrayList strList = new ArrayList();
try {
File file = new File(filename);
if (!file.exists()) {
throw new Exception ("ERROR: file " + filename + " not found");
}
BufferedReader bufRdr = new BufferedReader(new InputStreamReader(new FileInputStream(file), "UTF8"));
String line = null;
Integer i = 0;
while((line = bufRdr.readLine()) != null) {
strList.add(line);
i++;
}
bufRdr.close();
counter = Integer.parseInt(vars.get("counter"));
if (counter != i) {
String[] variables = strList.get(counter).split(",");
vars.put("answer",variables[0]);
vars.put("answerNum",variables[1]);
counter++;
vars.put("counter",Integer.toString(counter));
}
else {
vars.put("answer","<EOF>");
vars.put("eol","<EOF>");
vars.put("counter","0");
}
}
catch (Exception ex) {
IsSuccess = false;
log.error(ex.getMessage());
System.err.println(ex.getMessage());
}
catch (Throwable thex) {
System.err.println(thex.getMessage());
}
For reference check following link
You can handle this <EOF> case using If Controller and While Controller combination like:
While Controller: condition ${__javaScript("${CSV_VALUE1}" != "<EOF>",)}
If Controller: condition "${CSV_VALUE1}" != "<EOF>"
READ - Action Models
JSR223 Sampler
...
See Using the While Controller in JMeter article for details
It's possible to detect the end of file for a CSV data set by using a simple if-condition with quotes for the executing block:
if ("${CSV_VALUE1}" != "<EOF>")
{
//Code to execute if the condition is satisfied
}

bash script does not work when called on jee

i have a script bash which requires parameters.
when i call it directly from putty, it works, hen i do from my jee program it does not work and does not show me any errors.
This is my java code:
String[] cmdArray = {"sudo", "ssh", "-tt", "root#89.40.112.248", "/root/dve", "-l", "89.40.112.120,89.40.112.248", "you.mp4", "-s",".teeeest.avi" };
List<ObjectNode> listFileNode = new ArrayList<ObjectNode>();
try{
Runtime rt = Runtime.getRuntime();
ProcessBuilder pb = new ProcessBuilder(cmdArray);
Process proc = pb.start(); // Start the process.
System.out.println("Script executing");
rc= proc.waitFor(); // Wait for the process to finish.
System.out.printf("Script executed successfully in ", rc);
InputStream stderr = proc.getErrorStream();
InputStreamReader isr = new InputStreamReader(stderr);
BufferedReader br = new BufferedReader(isr);
String line = null;
System.out.println("<ERROR___EXEC>");
while ( (line = br.readLine()) != null){
System.out.println(line);
node.put("line",line );
listFileNode.add(node);
}
System.out.println("</ERROR___EXEC>");
int exitVal = proc.waitFor();
System.out.println("Process exitValue: " + exitVal);
InputStream processInputStream =proc.getInputStream();
InputStreamReader inputStreamReader = new InputStreamReader(processInputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
System.out.println("<RESULTAT___EXEC>");
while ( (line = bufferedReader.readLine()) != null){
System.out.println(line);
node.put("lineR",line );
listFileNode.add(node);
}
System.out.println("</RESULTAT___EXEC>");
}catch (Throwable t)
{
t.printStackTrace();
}
please help me i am stuck on this from a week and i don't find solution
You can't use sudo command in the java code. If you need to run root privileged application you need to switch to root before running your java code.
If you want to do it from your java code, you need to call setuid. But I don't know you can call setuid from a java code. For that purpose you may need a C/C++ wrapper for switching to root. Refer:http://unix.stackexchange.com question for writing wrapper.

Modifying the file contents of a zipfile entry

I would like to update the contents of text file located inside a zipfile.
I cannot find out how to do this, and the code below is not working properly.
May thanks for any help!!
import java.util.zip.ZipFile
import java.util.zip.ZipEntry
import java.util.zip.ZipOutputStream
String zipFileFullPath = "C:/path/to/myzipfile/test.zip"
ZipFile zipFile = new ZipFile(zipFileFullPath)
ZipEntry entry = zipFile.getEntry ( "someFile.txt" )
if(entry){
InputStream input = zipFile.getInputStream(entry)
BufferedReader br = new BufferedReader(new InputStreamReader(input, "UTF-8"))
String s = null
StringBuffer sb = new StringBuffer()
while ((s=br.readLine())!=null){
sb.append(s)
}
sb.append("adding some text..")
ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFileFullPath))
out.putNextEntry(new ZipEntry("someFile.txt"));
int length
InputStream fin = new ByteArrayInputStream(sb.toString().getBytes("UTF8"))
while((length = fin.read(sb)) > 0)
{
out.write(sb, 0, length)
}
out.closeEntry()
}
Just some slight modifications to #Opal's answer, I've just:
used groovy methods where possible
packaged in a method
Groovy Snippet
void updateZipEntry(String zipFile, String zipEntry, String newContent){
def zin = new ZipFile(zipFile)
def tmp = File.createTempFile("temp_${System.nanoTime()}", '.zip')
tmp.withOutputStream { os ->
def zos = new ZipOutputStream(os)
zin.entries().each { entry ->
def isReplaced = entry.name == zipEntry
zos.putNextEntry(isReplaced ? new ZipEntry(zipEntry) : entry)
zos << (isReplaced ? newContent.getBytes('UTF8') : zin.getInputStream(entry).bytes )
zos.closeEntry()
}
zos.close()
}
zin.close()
assert new File(zipFile).delete()
tmp.renameTo(zipFile)
}
Usage
updateZipEntry('/tmp/file.zip', 'META-INF/web.xml', '<foobar>new content!</foobar>')
What exactly isn't working? Is there any exception thrown?
As far as I know it's not possible to modify a zip file in situ. The following script rewrites the file and if desired entry is processed - modifies it.
import java.util.zip.*
def zipIn = new File('lol.zip')
def zip = new ZipFile(zipIn)
def zipTemp = File.createTempFile('out', 'zip')
zipTemp.deleteOnExit()
def zos = new ZipOutputStream(new FileOutputStream(zipTemp))
def toModify = 'lol.txt'
for(e in zip.entries()) {
if(!e.name.equalsIgnoreCase(toModify)) {
zos.putNextEntry(e)
zos << zip.getInputStream(e).bytes
} else {
zos.putNextEntry(new ZipEntry(toModify))
zos << 'lollol\n'.bytes
}
zos.closeEntry()
}
zos.close()
zipIn.delete()
zipTemp.renameTo(zipIn)
UPDATE
I wasn't right. It's possible to modify zip file in situ, but Your solution will omit other files that were zipped. The output file will contain only one single file - the file You wanted to modify. I also suppose that You file was corrupted because of not invoking close() on out.
Below is You script slightly modified (more groovier):
import java.util.zip.*
def zipFileFullPath = 'lol.zip'
def zipFile = new ZipFile(zipFileFullPath)
def entry = zipFile.getEntry('lol.txt')
if(entry) {
def input = zipFile.getInputStream(entry)
def br = new BufferedReader(new InputStreamReader(input, 'UTF-8'))
def sb = new StringBuffer()
sb << br.text
sb << 'adding some text..'
def out = new ZipOutputStream(new FileOutputStream(zipFileFullPath))
out.putNextEntry(new ZipEntry('lol.txt'))
out << sb.toString().getBytes('UTF8')
out.closeEntry()
out.close()
}

Read and write a file in groovy

I'm new to groovy and SOAP UI free. I'm using a groovy script to drive my test for SOAP UI.
I want to write a script that reads a file of person IDs, removes the first one, sets a property, writes the file back out without the one I just read.
Here's my first cut at it:
List pids = new ArrayList()
new File("c:/dev/pids.csv").eachLine { line -> pids.add(line) }
String pid = pids.get(0);
testRunner.testCase.setPropertyValue( "personId", pid )
pids.remove(0)
new File("c:/dev/pids.csv").withWriter { out ->
pids.each() { aPid ->
out.writeLine(aPid)
}
}
The output gets displayed on SOAP UI and the file doesn't get touched. I'm lost.
ArrayList pids = null
PrintWriter writer = null
File f = new File("c:/temp/pids.txt")
if (f.length() > 0){
pids = new ArrayList()
f.eachLine { line -> pids.add(line) }
println("Item to be removed: " + pids.get(0))
//testRunner.testCase.setPropertyValue( "personId", pid )
pids.remove(0)
println pids
writer = new PrintWriter(f)
pids.each { id -> writer.println(id) }
writer.close()
}
else{
println "File is empty!"
}
def myFile = new File("newfile.txt")
def newFile = new File("newfile2.txt")
//testRunner.testCase.setPropertyValue( "personId", pid )
PrintWriter printWriter = new PrintWriter(newFile)
myFile.eachLine { currentLine, lineNumber ->
if(lineNumber > 1 )
printWriter.println(currentLine)
}
printWriter.close()

Groovy InputStream reading closure hanging

I'm trying to make a Java program more "Groovy". The java code reads an InputStream like so:
static int myFunction(InputStream is) throws IOException {
int b=is.read();
if (b==0) return b;
StringBuffer sb=new StringBuffer();
int c;
boolean done = false;
while(!done) {
c=is.read();
sb.append((char)c);
if(c == '\n') {
done=true;
}
}
System.out.println(sb.toString());
if (b == 1) throw new IOException("blah");
return b;
}
My Groovy version looks like this:
def myFunction(InputStream is) throws IOException {
int b=is.read()
if (b==0) return b
def reader = new BufferedReader(new InputStreamReader(is))
reader.eachLine { println(it) }
println("DONE")
if (b == 1) throw new IOException("blah")
return b
}
It prints the contents of the stream and then just hangs as if it's trying to read more. It never prints "DONE" (added for debugging). Next I tried it using is.eachByte and passing a closure with an explicit "if (c == '\n') return" but I found that return inside a closure acts more like a continue and doesn't actually break out of the closure. Any idea what I'm doing wrong?
Instead of
reader.eachLine { println(it) }
Can you try
println reader.readLine()

Resources