Read and write a file in groovy - 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()

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
}

external groovy script is giving error : groovy.lang.MissingPropertyException: No such property: hudson. while using in Jenkins

I am currently using "Execute System groovy script" in Jenkins. The following code I have written inside the editor box inside Jenkins.
import hudson.model.*
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
// Get the list of all jobs and print them
activeJobs = hudson.model.Hudson.instance.items.findAll{job -> job.isBuildable()}
//activeJobs.each{run -> println(run.name)}
println ('total number of jobs :'+ activeJobs.size())
// find failed runs
failedRuns = activeJobs.findAll{job -> job.lastBuild != null && job.lastBuild.result == hudson.model.Result.FAILURE}
//failedRuns.each{run -> println(run.name)}
println ('total number of jobs :'+ failedRuns.size())
// find successful runs
successfulRuns = activeJobs.findAll{job -> job.lastBuild != null && job.lastBuild.result == hudson.model.Result.SUCCESS}
//successfulRuns.each{run -> println(run.name)}
println ('total number of jobs :'+ successfulRuns.size())
//get current date
Date date = new Date(System.currentTimeMillis())
String formattedDate = date.format('yyyy.MM.dd')
//writing to JSON Object
def directory = "D:\\Programs\\Jenkins\\jobs\\Groovy-Project\\workspace\\History\\"
def fileName = "build_job_data"
def extension = ".csv"
def filePath = directory+fileName+extension
File file = new File(filePath)
//check if the file exists
if(!file.exists()){
println("File doesn't exists. Creating the file ..");
}
else{
println("File already exists");
//reading the file
String fileContents = new File(filePath).text
int flag = 0;
if(fileContents.contains(formattedDate)){
println("Already deployed today at least once! Deleting old values and writing the new one..")
flag = 1;
}
def result = []
String textToWrite = "";
int count = 0;
result = fileContents.split('\n')
if(flag==1){
for(int i = 0; i<result.size();i++){
if(result[i].contains(formattedDate)){
println(result[i])
}
else{
textToWrite = textToWrite + '\n' + result[i]
}
}
}
else
{
for(int i = 0; i<result.size();i++){
textToWrite = textToWrite+ '\n' + result[i]
}
}
//make a backup of old record
def newFile = directory+fileName+"_bkp_"+new Date(System.currentTimeMillis()).format('yyyy-MM-dd_hh_mm_ss') + extension
println("creating back up file At :: " + newFile)
File bkpfile = new File(newFile)
bkpfile<<fileContents
println("file creation done")
//update the current history file
file.delete()
file = new File(filePath)
file<<textToWrite
file<<'\n'
}
def newDataToAdd = formattedDate+","+activeJobs.size()+","+failedRuns.size()+","+successfulRuns.size()+"\r\n"
file<<newDataToAdd
println('print done')
Now, I need to run this same script( I mean same functionality) as an external groovy script in Jenkins. I created a groovy file with the above code and added the groovy file in the job workspace. But, while running the job, this error is coming :
Caught: groovy.lang.MissingPropertyException: No such property: hudson for class: TestClass
groovy.lang.MissingPropertyException: No such property: hudson for class: TestClass
at TestClass.run(TestClass.groovy:7)
Build step 'Execute Groovy script' marked build as failure
Can anyone please point out what is the cause of this error?
Thanks!!
I solved the problem. By mistake I was trying to execute it as a groovy script , but I should have used Execute System Groovy script.
Now it is running fine.

How to use not equalto in Groovy in this case

I just want to print files which are not located in ss
def folder = "./test-data"
// println "reading files from directory '$folder'"
def basedir = new File(folder)
basedir.traverse {
if (it.isFile()) {
def rec = it
// println it
def ss = rec.toString().substring(12)
if(!allRecords contains(ss)) {
println ss
}
}
Your question isn't exactly clear, but it looks like you're just trying to do
if (!allRecords.contains(ss)) {
println ss
}
in the last part of your code segment.

Tail a file in Groovy

I am wondering is there is a simple way to tail a file in Groovy? I know how to read a file, but how do I read a file and then wait for more lines to be added, read them, wait, etc...
I have what I am sure is a really stupid solution:
def lNum = 0
def num= 0
def numLines = 0
def myFile = new File("foo.txt")
def origNumLines = myFile.eachLine { num++ }
def precIndex = origNumLines
while (true) {
num = 0
lNum = 0
numLines = myFile.eachLine { num++ }
if (numLines > origNumLines) {
myFile.eachLine({ line ->
if (lNum > precIndex) {
println line
}
lNum++
})
}
precIndex = numLines
Thread.sleep(5000)
}
Note that I am not really interested in invoking the Unix "tail" command. Unless it is the only solution.
I wrote a groovy class which resembles the basic tail functionality:
class TailReader {
boolean stop = false
public void stop () {
stop = true
}
public void tail (File file, Closure c) {
def runnable = {
def reader
try {
reader = file.newReader()
reader.skip(file.length())
def line
while (!stop) {
line = reader.readLine()
if (line) {
c.call(line)
}
else {
Thread.currentThread().sleep(1000)
}
}
}
finally {
reader?.close()
}
} as Runnable
def t = new Thread(runnable)
t.start()
}
}
The tail method taks a file and closure as parameters. It will run in a separate thread and will pass each new line that will be appended to the file to the given closure. The tail method will run until the stop method is called on the TailReader instance. Here's a short example of how to use the TailReader class:
def reader = new TailReader()
reader.tail(new File("/tmp/foo.log")) { println it }
// Do something else, e.g.
// Thread.currentThread().sleep(30 * 1000)
reader.stop()
In reply to Christoph :
For my use case, I've replaced the block
line = reader.readLine()
if (line) {
c.call(line)
}
else {
Thread.currentThread().sleep(1000)
}
with
while ((line = reader.readLine()) != null)
c.call(line)
Thread.currentThread().sleep(1000)`
... != null => to ensure empty lines are outputted as well
while (... => to ensure every line is read as fast as possible

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

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().

Resources