How to use gradle to add directory to os environment path? - gradle

I'm using selenium to do automated testing, and I want to write a gradle script to setup local environment for selenium. I've setup a task to starting selenium-server before run tests. But I am confused when trying to add a directory which stores browser drivers to os environment path before starting selenium-server. Any helps, thx.
[Edited]:
I know there are alreadly similar questions that have been asked, but I wonder whether there are an elegant way to add dir to path in both windows and linux with gradle.

Just provide an optional solution:
import org.gradle.internal.os.OperatingSystem;
task runSelenium(type: Exec) {
String path = System.getenv('PATH')
doFirst{
String webdriverDir = "$projectDir/webdriver"
if(OperatingSystem.current().isWindows()){
path = path + ";" + webdriverDir
}
if(OperatingSystem.current().isLinux()){
path = path + ":" + webdriverDir
}
environment 'PATH', path
commandLine 'java', '-jar', 'webdriver/selenium-server-standalone-3.4.0.jar'
}
}

Instead of juggling with the question of the operating system, just use System.getProperty("path.separator") directly.

Related

How to get the absolute folder location of a Jmeter .jmx project file from within itself?

I have a Jmeter project that is executed by Maven and is able to locate external Beanshell scripts by the path src/test/jmeter/external-scripts-dir/script1.bsh , but when I run Jmeter directly in the GUI on my computer the relative location doesn't work and the tests cannot be ran standalone. This forces me to run Jmeter from Maven.
So, I have a project file located at a Maven layout location like C:\files\git\projectA\src\test\jmeter\Project.jmx but since I ran jmeter from its installation folder at C:\Jmeter2.12 , it cannot find the relative location of the external script I mentioned earlier.
To solve this, all I need is to set a variable to the directory containing the .jmx file. Is there any possible way to do this?
I can dynamically determine the home of Jmeter ( C:\Jmeter2.12 ) pretty easily (using the following code) but that doesn't help me get the location of the project file.
${__BeanShell(import org.apache.jmeter.services.FileServer; FileServer
.getFileServer().getBaseDir();)}${__BeanShell(File.separator,)}
Is there something similar to the above code that would allow me to deduce the project file location?
If you're looking for the way to locate current script when you run JMeter in GUI mode you can try the following Beanshell expression:
${__BeanShell(import org.apache.jmeter.gui.GuiPackage;GuiPackage.getInstance().getTestPlanFile();)}
If you brake this down into 5 lines there will be:
import org.apache.jmeter.gui.GuiPackage;
import org.apache.commons.io.FilenameUtils;
String testPlanFile = GuiPackage.getInstance().getTestPlanFile();
String testPlanFileDir = FilenameUtils.getFullPathNoEndSeparator(testPlanFile);
vars.put("testPlanFileDir", testPlanFileDir);
log.info("testPlanFileDir:" + testPlanFileDir);
Your current .jmx file fill be stored as scriptFile JMeter Variable.
References:
GuiPackage class JavaDoc
How to use BeanShell: JMeter's favorite built-in component guide
The solution was (thanks to Ardesco) to do the following:
Use the following variables, set in the Test Plan global variables:
projectHome = ${__BeanShell(import org.apache.jmeter.services.FileServer; FileServer.getFileServer().getBaseDir();)}
jmeterHome = ${__BeanShell(System.getProperty("user.dir");)}
scriptHome = ${projectHome}/scripts
Thanks to the accepted answer, I was able to solve a related problem.
Now, I can calculate this parameter once and re-use it as a user variable.
JMETER_SCRIPTS_DIRECTORY=${__BeanShell(import org.apache.jmeter.services.FileServer; FileServer.getFileServer().getBaseDir();)}
Its usage is ${JMETER_SCRIPTS_DIRECTORY}.
Interestingly, it works in both GUI mode and NON GUI mode (from command line).

TeamCity - how to access environment variable in gradle

I have specified environment variable named DIR in my build agent. It is visible in my parameters/environment variables section of my Build Agent properties. I want to access this variable from gradle. I don't know how. I tried many things like:
if (project.hasProperty("teamcity")) {
println teamcity
println teamcity["teamcity.build.properties.file"]
def properties = file(teamcity["teamcity.build.properties.file"])
println properties.DIR
println DIR
println env.DIR
}
My teamcity file looks like:
{teamcity.buildType.id=Taxi5Mobile_BuildDev, build.vcs.number.Taxi5Mobile_Taxi5devVCS=a23e58c8ff92, teamcity.version=8.1.1 (build 29939), teamcity.buildConfName=Build-dev, teamcity.agent.dotnet.agent_url=http://localhost:9090/RPC2, teamcity.build.id=111, agent.ownPort=9090, agent.name=MacAgent, build.number=82, teamcity.runner.properties.file=/Users/surecase/Desktop/buildAgent/temp/buildTmp/teamcity.runner3909938768619827374.properties, teamcity.build.changedFiles.file=/Users/surecase/Desktop/buildAgent/temp/buildTmp/changedFiles8064633368222257261.txt, teamcity.agent.cpuBenchmark=552, teamcity.build.workingDir=/Users/surecase/Desktop/buildAgent/work/88410410f80bbc04/Mobile/Android, agent.home.dir=/Users/surecase/Desktop/buildAgent, teamcity.auth.userId=TeamCityBuildId=111, teamcity.build.checkoutDir=/Users/surecase/Desktop/buildAgent/work/88410410f80bbc04, teamcity.configuration.properties.file=/Users/surecase/Desktop/buildAgent/temp/buildTmp/teamcity.config8874044708331653991.properties, build.vcs.number=a23e58c8ff92, teamcity.tests.recentlyFailedTests.file=/Users/surecase/Desktop/buildAgent/temp/buildTmp/testsToRunFirst6286498944890258669.txt, teamcity.projectName=Taxi5Mobile, agent.work.dir=/Users/surecase/Desktop/buildAgent/work, teamcity.build.tempDir=/Users/surecase/Desktop/buildAgent/temp/buildTmp, build.vcs.number.1=a23e58c8ff92, teamcity.auth.password=8dYVHDftOmXenz9cJjnCyctBrF5NKq7G, java.io.tmpdir=/Users/surecase/Desktop/buildAgent/temp/buildTmp, teamcity.build.properties.file=/Users/surecase/Desktop/buildAgent/temp/buildTmp/teamcity.build174113942945941853.properties, teamcity.agent.dotnet.build_id=111}
There are some files which contains properties but I don't know how to access them.
Any ideas?
Environment variables can be read using the standard Java API:
def dir = System.getenv("DIR")
It might make sense to use a name that's a little less ambiguous than DIR.

Using sbt-native-packager, how can I simply prepend a directory to my bash script's ${app_classpath}?

My project uses sbt-native-packager with packageArchetype.java_application.
During sbt stage I have a task that generates some final Typesafe style configuration file that I then copy to:
target/universal/stage/conf/application.conf
I'd like to prepend this directory to the runtime classpath in the bash script, and am looking for the simplest way to do that. I'd hate to maintain a separate src/main/templates/bash-template for something so simple, and am not seeing exactly how to go about it otherwise.
Thanks!
Short Answer
Define a package mapping
mappings in Universal <+= (packageBin in Compile, sourceDirectory ) map {
(_, src) =>
// we are using the reference.conf as default application.conf
// the user can override settings here
val conf = src / "main" / "resources" / "reference.conf"
conf -> "conf/application.conf"
}
Create a jvmopts in src/universal/conf with
-Dconfig.file=/<installation-path>/conf/application.conf
Add to build.sbt
bashScriptConfigLocation := Some("${app_home}/../conf/jvmopts")
Example for server_archetype:
Follow the example application. A bit of description can be found here.
Long answer
Changing the classpath is not supported directly by the sbt-native-packager, because it can cause problems like
classpath ordering
security issues
Like Typesafe Config, most libraries which use config files, provide a parameter to define the location of the configuration file. Use the parameters describe in the documentation.
It seems your are trying to run a server, which means you can use the
packageArchetype.java_server
which is designed to read external configurations. Take a look at the example application how to use it.
The following setting:
scriptClasspath in bashScriptDefines ~= (cp => "../conf" +: cp),
Allows you to do exactly what you need.
In this specific example I prepend the "../conf" directory to the classpath entries.
Also, you need to import the following configuration keys to your build SBT:
import com.typesafe.sbt.packager.Keys.bashScriptDefines
import com.typesafe.sbt.packager.Keys.scriptClasspath
The question you asked in the title is a bit different from the description. I am answering the question in the title here - i.e. how can you prepend a directory into the classpath:
This is very hacky and brittle in that it will probably break if/when the sbt-native-packager makes changes to how the script is generated, but for now it works for me:
private lazy val ClasspathPattern = "declare -r app_classpath=\"(.*)\"\n".r
bashScriptDefines := bashScriptDefines.value.map {
case ClasspathPattern(classpath) => "declare -r app_classpath=\"/path/to/some/external/lib/*:" + classpath + "\"\n"
case _#entry => entry
},

Access to build environment variables from a groovy script in a Jenkins build step (Windows)

I'm using Scriptler plugin, so I can run a groovy script as a build step. My Jenkins slaves are running on windows in service mode. With scriptler, I don't need to use windows batch scripts.
But I have trouble to get the environment variables in a build step... This is working:
System.getenv("BASE")
Where BASE is part of the env-vars on jenkins startup. However, I would like to get
%JOB_NAME%
If I'm adding an "Execute Windows batch command" build step:
echo %JOB_NAME%
It works.
If I'm adding a scriptler script as a build step with the same settings:
println "JOB_NAME: " + System.getenv("JOB_NAME")
I'm getting:
JOB_NAME: null
So how can I reach the injected environment variables from a groovy script as a build step?
build and listener objects are presenting during system groovy execution. You can do this:
def myVar = build.getEnvironment(listener).get('myVar')
You might be able to get them like this:
def thr = Thread.currentThread()
def build = thr?.executable
def envVarsMap = build.parent.builds[0].properties.get("envVars")
On jenkins 2.x, with groovy plugin 2.0, running SystemGroovyScript I managed to get to build variables, as below:
def build = this.getProperty('binding').getVariable('build')
def listener = this.getProperty('binding').getVariable('listener')
def env = build.getEnvironment(listener)
println env.MY_VARIABLE
If you are using goovy from file, simple System.getenv('MY_VARIABLE') is sufficient
The Scriptler Groovy script doesn't seem to get all the environment variables of the build. But what you can do is force them in as parameters to the script:
When you add the Scriptler build step into your job, select the option "Define script parameters"
Add a parameter for each environment variable you want to pass in. For example "Name: JOB_NAME", "Value: $JOB_NAME". The value will get expanded from the Jenkins build environment using '$envName' type variables, most fields in the job configuration settings support this sort of expansion from my experience.
In your script, you should have a variable with the same name as the parameter, so you can access the parameters with something like:
println "JOB_NAME = $JOB_NAME"
I haven't used Sciptler myself apart from some experimentation, but your question posed an interesting problem. I hope this helps!
The only way I could get this to work (on Linux) was to follow this advice:
https://wiki.jenkins-ci.org/display/JENKINS/Parameterized+System+Groovy+script
import hudson.model.*
// get current thread / Executor and current build
def thr = Thread.currentThread()
def build = thr?.executable
// if you want the parameter by name ...
def hardcoded_param = "FOOBAR"
def resolver = build.buildVariableResolver
def hardcoded_param_value = resolver.resolve(hardcoded_param)
println "param ${hardcoded_param} value : ${hardcoded_param_value}"
This is on Jenkins 1.624 running on CentOS 6.7
Jenkins 2.x has the global variables. env is one of them from any script...
println env.JOB_NAME
More at https://build.intuit.com/services-config/pipeline-syntax/globals#env
One thing to note, if you are using a freestyle job, you won't be able to access build parameters or the Jenkins JVM's environment UNLESS you are using System Groovy Script build steps. I spent hours googling and researching before gathering enough clues to figure that out.
In System Groovy Script (Jenkins 2.89), I was able to use the environmental variable to disable another Jenkins job
import jenkins.*
import jenkins.model.*
def env = binding.build.environment
Jenkins.instance.getItemByFullName(env.job_name).setDisabled(false)
I also added a conditional step so as to either enable or disable another Jenkins job.
Thanks #Allan Lewis, your comment was helpful.

Unable to locate file 'C:\BuildAgent\temp\buildTmp\SYSTEM_[AGENT NAME] 2013-02-06 16_25_11\

I have an MSTest build step in my TeamCity build. Some of the tests are looking for a file in a relative path which they cannot find and the tests are throwing the error...
Cannot find path...
'C:\BuildAgent\temp\buildTmp\SYSTEM_[AGENT NAME] 2013-02-06 16_25_11\Documents\json.value.list.txt'
I have a PowerShell script that I want to use to create and copy the file out to the above path. However, I cant seem to figure out the appropriate TeamCity parameters to use to construct the path...
I have...
%system.teamcity.build.tempDir%\%teamcity.agent.name%\documents
However, that gives me...
'C:\BuildAgent\temp\buildTmp[AGENT NAME]\Documents\'
What can parameters or TeamCity variables can I use to construct...
C:\BuildAgent\temp\buildTmp\SYSTEM_[AGENT NAME] 2013-02-06 16_25_11\Documents
Thanks!
If your test is reading the contents of a file, this will ensure that relative paths are resolved correctly so tests can be run on TeamCity as well as locally:
string currentDir = new System.Diagnostics.StackFrame(true).GetFileName();
var workingFile = new FileInfo(currentDir);
string fileContents = File.ReadAllText(workingFile.Directory + relativeFilePath);
relativeFilePath is the variable containing the file. fileContents will contain the contents of this file when run from TeamCity or locally.

Resources