Jenkins: spawn multiple processes and wait for them to terminate - jenkins

I've set up a Jenkins build server that's running a nightly build for a Unity project, building two different instances of it. Once these builds are done it runs a job on a different node to copy over the build binaries and run them. What I'm running into is finding a good way for the job to (1) run both executables simultaneously, (2) wait for both of them to finish before moving to the next 'build step' in the job (where it verifies test logs etc).
Initially this seemed to work when I tested it on my own computer: https://stackoverflow.com/a/18762607/14764114
.. but it does not in Jenkins, because the Jenkins node runs as a Windows Service and thus cannot use the START command in Batch.
I'm reading that running separate services might be a solution to explore here, but before I start diving into that I figured I'd ask the community if there isn't a more elegant solution here. In summary, I want to:
Run two executables from a Jenkins build step at the same time (from a Jenkins node running on Windows)
Wait for both executables to exit before continuing to the next build step

In the end I went with this solution, as it seems the Task Scheduler seems to be the only thing capable of starting a Unity game window in my scenario. So I create a task, run it and then delete it, after which I just wait for the processes to disappear from the tasklist:
#echo off
echo "Run FirstApp"
schtasks /create /sc MONTHLY /tn FirstAppTask /tr "%TARGET_DIR%\%APP_First%\FirstApp.exe -automatedtest -duration=%TEST_DURATION_SECONDS%"
schtasks /run /tn FirstAppTask
schtasks /delete /f /tn FirstAppTask
echo "Run SecondApp"
schtasks /create /sc MONTHLY /tn SecondAppTask /tr "%TARGET_DIR%\%APP_Second%\SecondApp.exe -automatedtest -duration=%TEST_DURATION_SECONDS%"
schtasks /run /tn SecondAppTask
schtasks /delete /f /tn SecondAppTask
echo "Wait for FirstApp.exe to end"
:LOOP1
tasklist | find /i "FirstApp" >nul 2>&1
IF ERRORLEVEL 1 (
GOTO CONTINUE1
) ELSE (
ping -n 5 ::1 >NUL
GOTO LOOP1
)
:CONTINUE1
echo "Wait for SecondApp.exe to end"
:LOOP2
tasklist | find /i "SecondApp" >nul 2>&1
IF ERRORLEVEL 1 (
GOTO CONTINUE2
) ELSE (
ping -n 5 ::1 >NUL
GOTO LOOP2
)
:CONTINUE2
echo Done running tests

Related

Pinging Hostnames from a Parsed File and Logging in Batch

I'm still pretty new to batch but I wanted to try out some different functionalities within the same batch program. Essentially, I am attempting to parse through a .txt file of hostnames and ping them 1 time each, and return a pass or fail by utilizing a find query for the specific ping result. The second find query is redundant but left in. A string of "timed out" indicates that the host is down. I have been able to achieve this with this bulky code, but my actual ping statistics are no longer being written to this log file.
I'm not too familiar with the command pipeline character but it may just be incompatible for this specific use case. If I remove the piped command for the find query, it is able to write the output of the ping command just fine, but then I lose the utility of a return pass or fail value. Is this just a simple syntax error? I've tried moving the location of the actual write to file argument on the line itself but it hasn't worked. Also, why are the errorlevel values inverted (line 21)? I can't seem to return what I'm looking for.
Is there anyway I can get all these parts to play nice together? I apologize if the answer is quite obvious...
#echo off
setlocal
set hosts=temp.txt
set count=0
echo.
echo Parsing File: %hosts%
echo.
echo Start > C:\Users\___\Downloads\pingLOG.txt
for /F "tokens=*" %%i in (%hosts%) do (
set /A count=count+1
echo+
echo.
echo [+] Pinging: %%i
echo [+] Pinging: %%i >> C:\Users\___\Downloads\pingLOG.txt
echo.
ping -n 1 "%%i" | find /I "timed out" >> C:\Users\___\Downloads\pingLOG.txt
if errorlevel == 1 (
echo Pass
) else (
echo Fail
)
echo.
echo %TIME% >> C:\Users\___\Downloads\pingLOG.txt
)
echo.
echo %count% Hosts Scanned
find /c "timed out" C:\Users\___\Downloads\pingLOG.txt
echo.
pause
You can't filter the output for a certain string and expect the complete output (eliminating unwanted parts is the very reason for filtering).
To accomplish your goal, you need a temporary file (the complete output) and filter that file, so you have both variants (filtered and unfiltered) (suboptimal, but well...):
ping -n 1 "%%i" >"%temp%\temp.tmp"
find /I "timed out" "%temp%\temp.tmp" >nul && set "status=Fail" || set "status=Pass"
type "%temp%\temp.tmp" >> "C:\Users\___\Downloads\pingLOG.txt"
echo %status% >> "C:\Users\___\Downloads\pingLOG.txt"

Trigger specific job on push to specific directory

We have 12 different projects inside the same repository and have a different job to run for each of these.
I want to know how I can trigger a job only when a change has happened in a specific folder, since running all 12 on every push takes too long to finish.
Well I have hacked a solution that works for us.
First, add an Execute Shell Build Step:
#!/bin/bash
export DIRS="api objects"
DIFF=`git diff --name-only develop`
echo "export RUN_TEST=0" > "$WORKSPACE/RUN_TEST"
for DIR in $DIRS; do
for LINE in $DIFF; do
# Is this file inside an interesting directory?
echo $LINE | grep -e "^$DIR/"
# Checking if it is inside
if [ $? -eq 0 ]; then
echo "export RUN_TEST=1" > "$WORKSPACE/RUN_TEST"
fi
done
done
Here:
api and objects are the 2 directories I want to trigger this Job
develop is the main branch we use, so I want to know how my directories compare to that branch in particular
I create a file $WORKSPACE/RUN_TEST to set a variable if I should or not run it
Then in the time-consuming build steps add:
#!/bin/sh
. "$WORKSPACE/RUN_TEST"
if [ $RUN_TEST -eq 1 ]; then
# Time consuming code here
fi
That way the job is triggered but runs as fast as if it wasn't triggered.
Now I modified it to:
#!/bin/bash
export DIRS="api objects"
DIFF=`git diff --name-only origin/develop`
RUN_TEST=111
for DIR in $DIRS; do
for LINE in $DIFF; do
# Is this file inside an interesting directory?
echo $LINE | grep -e "^$DIR/"
# Checking if it is inside
if [ $? -eq 0 ]; then
RUN_TEST=0
fi
done
done
echo "RUN_TEST=$RUN_TEST"
echo "return $RUN_TEST" > "$WORKSPACE/RUN_TEST"
exit $RUN_TEST
And set Exit code to set build unstable to 111 on all build steps. Then, in all following build steps I did:
#!/bin/bash
# Exit on any error
set -euo pipefail
. "$WORKSPACE/RUN_TEST"
# Rest of build step

Getting VncRecorder working on Jenkins

I am trying to set Jenkins up to perform continuous testing of some online applications.
I have installed Jenkins on Ubuntu 16.04 and have a slave which is running Windoze 10.
I have installed UltraVnc on the slave and am trying to get VncRecorder to record the test session.
At the moment, my job simply does some random stuff. The console output is as follows:
Started by user anonymous
Building remotely on Nove1 (UITest) in workspace
C:\Users\Jenkins\workspace\TestTester
[WS-CLEANUP] Deleting project workspace...
[WS-CLEANUP] Done
Starting xvnc
[TestTester] $ "C:\Program Files\uvnc bvba\UltraVNC\winvnc.exe" -connect host:76 Recording from vnc server: 172.24.27.210:0
Using vnc passwd file: /var/lib/jenkins/secrets/vncpassword
job/TestTester/14/Recording from server: 172.24.27.210:0, to: /var/lib/jenkins/jobs/TestTester/builds/14/archive/TestTester_14.swf
[TestTester] $ cmd /c call
C:\Users\Jenkins\AppData\Local\Temp\hudson6483326613410629302.bat
C:\Users\Jenkins\workspace\TestTester>echo "Start" "Start"
C:\Users\Jenkins\workspace\TestTester>exit 0
ERROR: File
/var/lib/jenkins/jobs/TestTester/builds/14/archive/TestTester_14.swf doesn't exist.
Feature "Record VNC session" failed!
Terminating xvnc.
Finished: FAILURE
I've spent the past 2 days searching on Google and found nothing, so can ay of you good folks help?
Thanks!
Paul
Problem Steps Recorder is a cool Windows tool that can record your actions as a series of images. You can use this tool which is built-into windows :)
psr.exe [/start |/stop][/output <fullfilepath>] [/sc (0|1)] [/maxsc <value>]
[/sketch (0|1)] [/slides (0|1)] [/gui (o|1)]
[/arcetl (0|1)] [/arcxml (0|1)] [/arcmht (0|1)]
[/stopevent <eventname>] [/maxlogsize <value>] [/recordpid <pid>]
/start :Start Recording. (Outputpath flag SHOULD be specified)
/stop :Stop Recording.
/sc :Capture screenshots for recorded steps.
/maxsc :Maximum number of recent screen captures.
/maxlogsize :Maximum log file size (in MB) before wrapping occurs.
/gui :Display control GUI.
/arcetl :Include raw ETW file in archive output.
/arcxml :Include MHT file in archive output.
/recordpid :Record all actions associated with given PID.
/sketch :Sketch UI if no screenshot was saved.
/slides :Create slide show HTML pages.
/output :Store output of record session in given path.
/stopevent :Event to signal after output files are generated.
PSR Usage Examples:
psr.exe
psr.exe /start /output fullfilepath.zip /sc1 /gui 0 /record <PID>
/stopevent <eventname> /arcetl 1
psr.exe /start /output fullfilepath.xml /gui 0 /recordpid <PID>
/stopevent <eventname>
psr.exe /start /output fullfilepath.xml /gui 0 /sc 1 /maxsc <number>
/maxlogsize <value> /stopevent <eventname>
psr.exe /stop
Notes:
1. Output path should include a directory path (e.g. '.\file.xml').
2. Output file can either be a ZIP file or XML file
3. Can't specify /arcxml /arcetl /arcmht /sc etc. if output is not a ZIP file.
The port number of your VNC server 0 looks suspicious..
What about the firewall settings of your slave - is the vnc port blocked ?
You could verify port of your vncserver with vncviewer 172.24.27.210:.
Regards,
Dimitri (developer of vncrecorder plugin)

pre-build script path not logging output

I have a pre-build PowerShell script defined in my Build Definition. The PowerShell script execute a program:
& "c:\Program Files\nodejs\npm.cmd" "run" "build"
When npm runs, npm writes things to stdout/console. This output doesn't show up in my logs for the build though.
What do I need to do to make sure the build logs capture this console output?
In other words, is there something I can add to & "c:\Program Files\nodejs\npm.cmd" "run" "build" that will pipe the output to the build log?
EDIT:
I think it's one of these three but not sure which:
& "c:\Program Files\nodejs\npm.cmd" "run" "build-release" 2>&1 | Out-Host
& "c:\Program Files\nodejs\npm.cmd" "run" "build-release" 2>&1 | Write-Host
& "c:\Program Files\nodejs\npm.cmd" "run" "build-release" 2>&1 | Write-Output
If you set logging to verbose it will log everything...
I normally add a -Verbose at the end of every line

jenkins plugin for triggering build whenever any file changed in a given directory

I am looking for functionality where we have a directory with some files in it.
Whenever any one makes a change in any of the files in the directory, jenkins shoukd trigger a build.
Is there any plugin or mathod for this functionality. Please advise.
Thanks in advance.
I have not tried it myself, but The FSTrigger plugin seems to do what you want:
FSTrigger provides polling mechanisms to monitor a file system and
trigger a build if a file or a set of files have changed.
If you can monitor the directory with a script, you can trigger the build with a HTTP GET, for example with wget or curl:
wget -O- $JENKINS_URL/job/JOBNAME/build
Although slightly related.. it seems like this issue was about monitoring static files on system.. however there are many version control systems for just this purpose.
I answered this in another post if you're using git to track changes on the files themselves:
#!/bin/bash
set -e
job_name="whatever"
JOB_URL="http://myserver:8080/job/${job_name}/"
FILTER_PATH="path/to/folder/to/monitor"
python_func="import json, sys
obj = json.loads(sys.stdin.read())
ch_list = obj['changeSet']['items']
_list = [ j['affectedPaths'] for j in ch_list ]
for outer in _list:
for inner in outer:
print inner
"
_affected_files=`curl --silent ${JOB_URL}${BUILD_NUMBER}'/api/json' | python -c "$python_func"`
if [ -z "`echo \"$_affected_files\" | grep \"${FILTER_PATH}\"`" ]; then
echo "[INFO] no changes detected in ${FILTER_PATH}"
exit 0
else
echo "[INFO] changed files detected: "
for a_file in `echo "$_affected_files" | grep "${FILTER_PATH}"`; do
echo " $a_file"
done;
fi;
You can add the check directly to the top of the job's exec shell, and it will exit 0 if no changes detected.. Hence, you can always poll the top level of the repo for check-in's to trigger a build. And only complete a build if the files in question change.

Resources