Specify arguments in grails command - grails

I'm using grails 3.2.6. I'm writing a custom grails command. It's a command and not a script because I need access to object in the spring application context in the command. I would like for my command to accept command line arguments with values such as "name" and "group" and "id". For example, I'd like to be able to run the command like this:
grails run-command process-group --name=foo --group=bar --id=2
However, when I do this, my command implementation class doesn't seem to have access to any of these arguments (name, group, or id). I've tried accessing them through the args attribute that comes from the GrailsApplicationCommand trait, but that is empty. I've also tried accessing it through various methods of the CommandLine object that is accessible through executionContext.commandLine object which also comes from the GrailsApplicationCommand trait. However, everything there seems to be empty as well (undeclaredOptions is empty, remainingArgs is empty, rawArguments just has my command name which is "process-group", etc.). If I remove the leading "--" from my argument names like this:
grails run-command process-group name=foo group=bar id=2
then the args attribute contains 3 entries: ["name=foo", "group=bar", and "id=2"]. I suppose that I could implement my command this way (no leading "--" on the command arguments), but it's kind of ugly, and it also means that I have to parse the arguments myself. The grails docs (http://docs.grails.org/latest/guide/single.html#creatingCustomCommands) say that, "Since Grails 3.2.0, commands have similar abilities as scripts in regards to retrieving arguments, template generation, file access, and model building." I'm interested in the retrieving arguments part of that statement. The examples shown in the documentation for scripts (not commands) show (http://docs.grails.org/latest/guide/single.html#creatingCustomScripts) how to declare parameters that a script will take from the command line. For example, this command line is supposed to work with a custom script that declares the "force" parameter for the generate-all custom script:
grails generate-all MyClass --force
This all seems to be tied to the use of the description() method in the script:
description( "Generates a controller that performs CRUD operations and the associated views" ) {
usage "grails generate-all <<DOMAIN CLASS>>"
flag name:'force', description:"Whether to overwrite existing files"
argument name:'Domain Class', description:'The name of the domain class'
}
However, there doesn't seem to be a description() method available for use for custom commands as there is for custom scripts. I just confused about how the grails docs state that retrieving arguments is supposed to now work the same for both custom scripts and custom commands, yet I can't seem to retrieve arguments from a custom command like I can from a custom script. Is there a way that I can retrieve the arguments for a custom command just like it can be done for a custom script?

Set the properties using the -D option:
-Dsample.message=foo
Grab the system properties using the follow code:
System.properties['sample.message']
Link to the where I found this example:
Passing Properties

Related

In Jenkins, how do I get the substring of a build parameter to be part of the build name?

I've got a parameterized freestyle Jenkins job, and I'd like to include part of one of the parameters in the build name. The parameter that I'm interested in is called FILE_PATH. Due to the file directory structure of the project used by this job, the file path always starts with the same string, which is 9 characters long. So if FILE_PATH="somepath/what/I/want", I would like the name of my build to be what/I/want.
Some things I've tried putting in the "Set Build Name" field provided by the Build Name Setter plugin:
${FILE_PATH:9}
This gave me the following error:
Failed to evaluate name macro:org.jenkinsci.plugins.tokenmacro.MacroEvaluationException: Unrecognized macro 'FILE_PATH' in '${FILE_PATH:9}'
${"FILE_PATH":9}
FILE_PATH was just treated as a string:
New run name is '${"FILE_PATH":9}'
${$FILE_PATH:9}
This just led to the raw expression being included with FILE_PATH being expanded:
New run name is '${somepath/what/I/want:9}'
${ENV,var="FILE_PATH":9}
This didn't get processed at all:
New run name is '${ENV,var="FILE_PATH":9}'
I've got the Build Name Setter and the Token Macro plugins installed. I'd like to do this in the Build Name plugin, if possible, although I can install any other plugins I need to get this to work.
${ENV:9,var="FILE_PATH"} should do what you are looking for.
An alternative is to also eliminate the beginning of the string, as far as you know what exactly the string is:
${ENV#somepath/,var="FILE_PATH"}
In case you ever need to strip something from the end of the string instead, use % in place of #.
I'm assuming you are using a Jenkinsfile pipeline script?
If so, you can just use the groovy substring method.
variable.substring(9)
Not sure if you can do something similar using parameterized builds.

JMeter: more than nine parameters from Jenkins

I am trying to pass more than nine parameters from Jenkins to JMeter4.0.
As I was reading, I found out that JMeter does not accept more than 9 parameters. As a workaround, I want to pass all the parameters as a string and split it in JMeter BeanShell.
java -jar -Xms512m -Xmx2048m C:\JMeter4\bin\ApacheJMeter.jar -Jjmeter.save.saveservice.output_format=csv -Jjenkinsparams="%Timetorun%,%Users%" -n -t %JMeterPath%\bin\tests\tests.jmx -l %WORKSPACE%\Results.csv
The tests run on a Windows machine. From this call I have
jenkinsparams = "300,2"
I use a BeanShell PreProcessor like this:
String line = "${__P(jenkinsparams)}";
String[] words = line.split(",");
vars.put("timetorun",words[0]);
vars.put("users",words[1]);
log.info(words[1]);
log.info(users);
I tried few log.info to check the values. For words[1] I have the correct value sent from Jenkins: 2. For the users the value displayed is: void.
I am trying to use it for Number of Threads as: ${__P(users,1)}.
What am I doing wrong? The values clearly arrive from Jenkins but I have a problem passing it to my variable. Thank you
You don't have a script variable named users, so you should either log words[0]:
log.info(words[0]);
Or you can log the value of JMeter variable called users:
log.info(vars.get("users"));
Or you can assign words[0] to variable called users:
String users = words[0];
log.info(users);
Also you are saving it as variable, not property, so you can retrieve it elsewhere in script as
${users}
The syntax __P refers to property, so if you want to use it as property, you need to change how you are saving it:
props.put("users", words[1]);
If you do that, ${__P(users,1)} should work
Now, if you want to use this value as number of threads, then you need to do this:
Have Setup thread group with 1 thread, and your script
In the script you must save users as property, otherwise it won't pass between threads
Next thread group then can use it as number of threads
As long as your command line fits into 8191 characters it should not be a problem to pass as many arguments to JMeter as you want, here is an evidence from Debug Sampler and View Results Tree listener combination
So keep calm and pass as many parameters as needed via -J command line arguments.
Be aware that starting from JMeter version 3.1 users are recommended to use JSR223 Test Elements and Groovy language instead of Beanshell so going forward please consider switching to Groovy.

How to pass values for options arguments when running a Dataflow app in Eclipse

I try to test my first Dataflow app by running it in Eclipse.
When I try to pass 4 values for the arguments on "Run Configuration" on "Arguments" tab as following:
projects/poc/subscriptions/poc-TestApp1 poc myDataSet my_logs
I get the error:
Argument 'projects/poc/subscriptions/poc-TestApp1' does not begin
with '--'
adding -- to all arguments produced a different error.
Based on your question, it seems that you have custom argument parsing code in your program (I suppose you're extracting your arguments as args[0], args[1] etc. in your main() function?), but still use PipelineOptionsFactory.fromArgs(args) to configure the options for Dataflow itself.
Dataflow does not support this mixed way of specifying command-line arguments - you need to define your own PipelineOptions to represent your configuration parameters, and specify them prefixed with --.
Please see here for details, in particular here for creating custom options.

How do you use concordion:run with parameters?

I would like to run a Concordion spec using a parameter. What I'd like to do is execute the spec using concordion:run. A little research pointed me to the existence of a concordion:params attribute, but I cannot find any documentation or examples.
I'm not sure how these two commands fit together; should the params element be nested inside the run element or outside? What is the value to fill in concordion:params="?" Where do I specify the param values themselves--in a concordion:set call?
concordion:params is an attribute to be used on the same element as the concordion:run attribute.
For example, in MyIndex.html:
<a concordion:run="concordion" concordion:params="foo=5" href="MySpec.html">My Spec</a>
with the fixture class:
#RunWith(ConcordionRunner.class)
#FullOGNL
public class MyIndex {
public void setFoo(Integer foo) {
System.out.println("foo = " + foo);
}
}
Note that the #FullOGNL attribute is required to allow the syntax foo=5 in the expression that wouldn't otherwise be allowed.
NOTE:
Tim Wright has pointed out an issue with this approach:
The issue I see is that the same specification might be run from two
different specifications (or run twice from a single specification)
with different parameters as well as from jUnit with no parameters. As
we only create one HTML file, the behaviour might not be what the user
expects. It also means that using concordion:run will create a
different specification from running the spec directly as a jUnit test
- which is something we've tried hard to avoid.
The current behaviour (with the concordion run cache) is that the
first one to be called will create the HTML file - and the second one
will return a run results from the cache thus ignoring the parameter.
This may mean that we deprecate concordion:params and remove it in 2.0.

How to set Fitnesse variables in query string

I'm currently setting up Fitnesse, with FitSharp and the .net implementation of dbfit.
I understand how to trigger tests or suites from the submission of a URL, or from a command line, eg:
java -jar fitnesse-standalone.jar -c "MyTest?test&format=text"
What I can't figure out is how to submit variable values in this query string.
So, if I have a test containing a Sql statement which has a Fitnesse variable referenced in the Where clause, and the value of this variable is defined in a sibling static page, I would like to be able to run this test from the command line and submit a value for this variable which overrides the value in the static page. Something like:
java -jar fitnesse-standalone.jar -c "MyTest?test&format=text&${myVar}=abc"
Is this possible at all?
Thanks
Mark
There are two ways to pass variables from the command line, both involving environment variables.
(1) Define an environment variable (or identify one that already exists). You can use general purpose system variables (like %TMP% or %HOMEPATH%) or your own user-defined variables (e.g. %JAVA_HOME%) or create your own. My short Fitnesse launcher (a .CMD file) is this:
set SEED=%RANDOM%
set FITNESSE_PORT=9999
java -jar fitnesse-standalone.jar -p %FITNESSE_PORT% -e 0
The FITNESSE_PORT variable is defined just for use in the very next line. The SEED variable, however, does magic: it allows several people to run the same test simultaneously by generating unique values per session. (This assumes that each user runs their own FitNesse server, so each will thereby have a unique session.) I then instrument my tests by defining ids relative to the seed, e.g.
!define TestClient (MyTestClient_${SEED})
(2) Pass an environment variable setting scoped to just the java process that instantiates the FitNesse runner. This technique gives you precisely the same results with just a different implementation:
java -DSEED=%RANDOM% -jar fitnesse-standalone.jar -p %FITNESSE_PORT% -e 0
This yields precisely the same result within FitNesse, giving you access to the %SEED% environment variable as ${SEED}.
For more, see part 2 of my seven-part series on Acceptance Testing with FitNesse published on Simple-Talk.com.

Resources