Passing parameter from feature file to another feature file [duplicate] - parameter-passing

https://github.com/intuit/karate#calling-other-feature-files
The link above contains an example of calling a feature file in order to reuse the code. The feature file which is reused is called with the inputs
Background:
* configure headers = read('classpath:my-headers.js')
* def signIn = call read('classpath:my-signin.feature') { username:'john', password: 'secret' }
* def authToken = signIn.authToken
The called my-signin.feature:
Scenario:
Given url loginUrlBase
And request { userId: '#(username)', userPass: '#(password)' }
When method post
Then status 200
And def authToken = response
...
In this example the my-signin.feature must be run with the inputs username and password. I know that if you had the following:
Background:
* def username = "foo"
* def password = "secret"
at the top of the my-signing.feature file, the parameters input by the feature attempting to reuse the feature file would be overwritten.
My question is:
If reuse is the main interest of being able to call other feature files, is there a way to have the calling feature file overwrite the username and password parameters if they had been defined in the background?
It seems to me that having the background overwrite the input parameters instead of vice versa makes it harder to reuse *.feature files. I know I found it a little frustrating on my project not being able to reuse tests I had already written without refactoring out the reusable code into another file.

Any called feature in karate will have a magic variable __arg, you can check for this before assigning values to your variables in your called script.
Background:
* def username = (__arg == null) ? "foo" : __arg.username
* def password = (__arg == null)? "secret" : __arg.password
this will check for values passed,
if none passed it will assign default
* def signIn = call read('classpath:my-signin.feature')
if passed with arguments passed arguments will be assigned
* def signIn = call read('classpath:my-signin.feature') { username: 'notfoo', password: 'notsecret' }
For simplicity don't have anyother parameters that need to passed other than this.

Related

which beanshell code or groovy code are used to to push the jtl results to db by using single one sampler

In jmeter,I want the results while the running the test,which beansheel code add to sampler and convert summary report values in to milliseconds and push those values in MySQL db automatically by adding one sampler.
please give me step by step process and all possible ways explain
and how create a table in particular values on jtl file values in avg,min,max,response time,error values in mysql db please explain
Wouldn't that be easier to use InfluxDB instead? JMeter provides Backend Listener which automatically sends metrics to InfluxDB and they can be visualized via Grafana. Check out How to Use Grafana to Monitor JMeter Non-GUI Results - Part 2 article for more details.
If you have to use MySQL the correct approach would be writing your own implementation of the AbstractBackendListenerClient
If you need a "single sampler" - take a look at JSR223 Listener, it has prev shorthand for SampleResult class instance providing access to all the necessary information like:
def name = prev.getSampleLabel() // get sampler name
def elapsed = prev.getTime() // get elapsed time (in milliseconds)
// etc.
and in order to insert them into the database you could do something like:
import groovy.sql.Sql
def url = 'jdbc:mysql://localhost:3306/your-database'
def user = 'your-username'
def password = 'your-password'
def driver = 'com.mysql.cj.jdbc.Driver'
def sql = Sql.newInstance(url, user, password, driver)
def insertSql = 'INSERT INTO your-table-name (sampler, elapsed) VALUES (?,?)'
def params = [name , elapsed]
def keys = sql.executeInsert insertSql, params
sql.close()

Fetch the response from sql, store it in a object and use conditions?

I have two sql statements to be executed with a validity check. My need is that I execute the 1st query and store the response in one object and check the object is empty or not and execute the second query if it is not empty.
So, I have tried something like
In rolerepository.scala=>
override val allQuery = s"""
select UserRoles.* from
(select CASE rbac.roleTypeID
ELSE rbac.name JOIN dirNetworkInfo ni
ON UserRoles.PersonID = ni.PersonID
where ni.Loginname = {loginName}
and UserRoles.roleName in ( 'Business User ','Administrator')"""
(This is just some sample of the query - it is not fully written here.)
Then I map it to an object with model class written outside
override def map2Object(implicit map: Map[String, Any]):
HierarchyEntryBillingRoleCheck = {
HierarchyEntryBillingRoleCheck(str("roleName"), oint("PersonID")) }
Then I have written the getall method to execute the query
override def getAll(implicit loginName: String):
Future[Seq[HierarchyEntryBillingRoleCheck]] = {
doQueryIgnoreRowErrors(allQuery, "loginName" -> loginName) }
Then I have written the method to check whether the response from the 1st sql is empty or not. This is were I'm stuck and not able to proceed further.
def method1()= {
val getallresponse = HierarchyEntryBillingRoleCheck
getallresponse.toString
if (getallresponse != " ")
billingMonthCheckRepository.getrepo()
}
I am getting an error (type mismatch) in last closing brace and I don't know what other logic can be used here.
Can any one of you please explain and give me some solution for this?
And i also tried to use for loop in controller but not getting how to do that.
i tried ->
def getAll(implicit queryParams: QueryParams,
billingMonthmodel:Seq[HierarchyEntryBillingRoleCheck]):
Action[AnyContent] = securityService.authenticate() { implicit request
=> withErrorRecovery { req =>
toJson {
repository.getAll(request.user.loginName)
for {
rolenamecheck <- billingMonthmodel
}yield rolenamecheck
}}}}
You don't say which db access method you are using. (I'm assuming anorm). One way of approaching this is:
Create a case class matching your table
Create a parser matching your case class
use Option (or Either) to return a row for a specific set of parameters
For example, perhaps you have:
case class UserRole (id:Int, loginName:String, roleName:String)
And then
object UserRole {
val sqlFields = "ur.id, ur.loginName, ur.roleName"
val userRoleParser = {
get[Int]("id") ~
get[String]("loginName") ~
get[String]("roleName") map {
case id ~ loginName ~ roleName => {
UserRole(id, loginName, roleName)
}
}
}
...
The parser maps the row to your case class. The next step is creating either single row methods like findById or findByLoginName and multi-row methods, perhaps allForRoleName or other generic filter methods. In your case there might (assuming a single role per loginName) be something like:
def findByLoginName(loginName:String):Option[UserRole) = DB.withConnection { implicit c =>
SQL(s"select $sqlFields from userRoles ur ...")
.on('loginName -> loginName)
.as(userRoleParser.singleOpt)
}
The .as(parser... is key. Typically, you'll need at least:
as(parser.singleOpt) which returns an Option of your case class
as(parser *) which returns a List of your case class (you'll need this if multiple roles could exist for a login
as(scalar[Long].singleOpt) which returns an Option[Long] and which is handy for returning counts or exists values
Then, to eventually return to your question a little more directly, you can call your find method, and if it returns something, continue with the second method call, perhaps like this:
val userRole = findByLoginName(loginName)
if (userRole.isDefined)
billingMonthCheckRepository.getrepo()
or, a little more idiomatically
findByLoginName(loginName).map { userRole =>
billingMonthCheckRepository.getrepo()
...
I've shown the find method returning an Option, but in reality we find it more useful to return an Either[String,(your case class)], and then the string contains the reason for failure. Either is cool.
On my version of play (2.3.x), the imports for the above are:
import play.api.db._
import play.api.Play.current
import anorm._
import anorm.SqlParser._
You're going to be doing this sort of thing a lot so worth finding a set of patterns that works for you.
WOW I don't know what's happening with the formatting here, I am really attempting to use the code formatter on the toolbar but I don't know why it won't format it, even when pressed multiple times. I invite the community to edit my code formatting because I can't figure it out. Apologies to OP.
Because I find Play's documentation to be very tough to trudge through if you're unfamiliar with it, I won't just leave a link to it only.
You have to inject an instance of your database into your controller. This will then give it to you as a global variable:
#Singleton
class LoginRegController #Inject()(**myDB: Database**, cc: ControllerComponents ) {
// do stuff
}
But, it's bad practice to actually use this connection within the controller, because the JDBC is a blocking operation, so you need to create a Model which takes the db as a parameter to a method. Don't set the constructor of the object to take the DB and store it as a field. For some reason this creates connection leaks and the connections won't release when they are done with your query. Not sure why, but that's how it is.
Create a Model object that you will use to execute your query. Instead of passing the DB through the object's constructor, pass it through the method you will create:
object DBChecker {
def attemptLogin(db:Database, password:String): String = {
}}
In your method, use the method .withConnection { conn => to access your JDBC connection. So, something like this:
object DBChecker {
def attemptLogin(db:Database, password:String):String = {
var username: String = ""
db.withConnection{ conn =>
val query:String = s"SELECT uploaded_by, date_added FROM tableName where PASSWORD = $password ;"
val stmt = conn.createStatement()
val qryResult:ResultSet = stmt.executeQuery(query)
// then iterate over your ResultSet to get the results from the query
if (qryResult.next()) {
userName = qryResult.getString("uploaded_by")
}
}
}
return username
}
// but note, please look into the use of PreparedStatement objects, doing it this way leaves you vulnerable to SQL injection.
In your Controller, as long as you import the object, you can then call that object's methods from your controller you made in Step 1.
import com.path.to.object.DBChecker
#Singleton
class LoginRegController #Inject()(myDB: Database, cc: ControllerComponents ) { def attemptLogin(pass:String) = Action {
implicit request: Request[AnyContent] => {
val result:String = DbChecker.attemptLogin(pass)
// do your work with the results here
}

Passing the value from a ruby block to a resource in chef

I am writing a chef resource, which will generate a password, and I am calling that resource in a recipe with the list of inputs.
Following is my scenario: Once my resource got executed, a new set of passwords will be generated in a folder, and I want to retrieve that password which is newly generated. But I am unable to retrieve that password because the value I am trying to retrieve is executing at the convergence phase.
Simple code block to explain my scenario:
Chef::Log.info("Creating new keys")
create_password 'New Password is being generated' do
action :change_passwords
password_util_dir node[:password][:passwd_util_dir]
rgbu_chef node[:password][:rgbu_chef]
old_data_bags node[:password][:old_data_bags]
new_data_bags node[:password][:new_data_bags]
end
The code above will create new passwords in a folder.
Later, I am trying to take the passwords through a JSON Parser:
text =::File.read("#{new_password_dir}")
data_hash = JSON.parse(text)
new_wls_password = data_hash['rase_wlsadmin_pwd']
The #{new_password_dir} is the directory location of the newly created password.json file.
I am trying to use the value of "new_wls_password" in the another resource like below:
Chef::Log.info("Updating WLSADMIN Password")
passwd_backup 'Updating wlsadmin password' do
action :update_wlsadmin
osuser node[:password][:wls_config_user]
usergroup node[:password][:wls_install_group]
new_wls_password "#{new_wls_password}"
end
Here, the new password which I am trying to retrieve is empty, since the following three lines are executed in the first place:
text =::File.read("#{new_password_dir}")
data_hash = JSON.parse(text)
new_wls_password = data_hash['rase_wlsadmin_pwd']
So, by that time, the new passwords resource has not been run.
I tried many stack overflow suggestions, like:
putting those three lines in a ruby_block like this
ruby_block "new_password" do
block do
text =::File.read("#{new_password_dir}")
data_hash = JSON.parse(text)
node.set[:new_wls_password] = data_hash['rase_wlsadmin_pwd']
end
end
Then I tried fetching the value into the resource as below
Chef::Log.info("Updating WLSADMIN Password")
passwd_backup 'Updating wlsadmin password' do
action :update_wlsadmin
osuser node[:password][:wls_config_user]
usergroup node[:password][:wls_install_group]
new_wls_password "#{node[:new_wls_password]"
end
With the above approach still the value is empty
Trying the value with lazy and calling that value.
Passing the value from one ruby block to another ruby block, which I can do, but not with the resources.
Please, can you help?
EDIT #1 :
I need to pass the value from the resource to the template.
Something like this, after running the following resource:
Chef::Log.info("Creating new keys")
create_password 'New Password is being generated' do
action :change_passwords
password_util_dir node[:password][:passwd_util_dir]
rgbu_chef node[:password][:rgbu_chef]
old_data_bags node[:password][:old_data_bags]
new_data_bags node[:password][:new_data_bags]
end
A new set of passwords will be generated in a folder, like the /tmp/password.json file.
After the resource execution above I am writing a template like:
template "#{Chef::Config[:file_cache_path]}/domain.properties" do
source 'domain_properties.erb'
variables
({ :domain_name => "#{domain_name}",
:admin_url => "#{admin_url}",
:new_wls_password => "#{new_wls_password}" })
end
Here, how can I parse the newly created value of "new_wls_password" ?
You can use lazy attribute like below:-
Chef::Log.info("Updating WLSADMIN Password")
passwd_backup 'Updating wlsadmin password' do
action :update_wlsadmin
osuser node[:password][:wls_config_user]
usergroup node[:password][:wls_install_group]
new_wls_password lazy { JSON.parse(File.read("/tmp/password.json"))['rase_wlsadmin_pwd'] }
end
Template resource can be written as:-
template "#{Chef::Config[:file_cache_path]}/domain.properties" do
source 'domain_properties.erb'
variables (lazy{{ :domain_name => "#{domain_name}",
:admin_url => "#{admin_url}",
:new_wls_password => JSON.parse(File.read("/tmp/password.json"))['rase_wlsadmin_pwd'] }})
end
Output:-
* template[/tmp/kitchen/cache/domain.properties] action create
- create new file /tmp/kitchen/cache/domain.properties
- update content in file /tmp/kitchen/cache/domain.properties from none to fa22e0
--- /tmp/kitchen/cache/domain.properties 2017-01-12 03:30:13.002968715 +0000
+++ /tmp/kitchen/cache/.chef-domain20170112-11387-1ytkyk2.properties 2017-01-12 03:30:13.002968715 +0000
## -1 +1,4 ##
+domain_name= mmm
+admin_url= nnn
+new_wls_password= xH#3zIS9Q4Hc#B

Using Groovy in Confluence

I'm new to Groovy and coding in general, but I've come a long way in a very short amount of time. I'm currently working in Confluence to create a tracking tool, which connects to a MySql Database. We've had some great success with this, but have hit a wall with using Groovy and the Run Macro.
Currently, we can use Groovy to populate fields within the Run Macro, which really works well for drop down options, example:
{groovy:output=wiki}
import com.atlassian.renderer.v2.RenderMode
def renderMode = RenderMode.suppress(RenderMode.F_FIRST_PARA)
def getSql = "select * from table where x = y"
def getMacro = '{sql-query:datasource=testdb|table=false} ${getSql} {sql-query}"
def get = subRenderer.render(getMacro, context, renderMode)
def runMacro = """
{run:id=test|autorun=false|replace=name::Name, type::Type:select::${get}|keepRequestParameters = true}
{sql:datasource=testdb|table=false|p1=\$name|p2=\$type}
insert into table1 (name, type) values (?, ?)
{sql}
{run}
"""
out.println runMacro
{groovy}
We've also been able to use Groovy within the Run Macro, example:
enter code here
{run:id=test|autorun=false|replace=name::Name, type::Type:select::${get}|keepRequestParameters = true}
{groovy}
def checkSql = "{select * from table where name = '\name' and type = '\$type'}"
def checkMacro = "{sql-query:datasource=testdb|table=false} ${checkSql} {sql-query}"
def check = subRenderer.render(checkMacro, context, renderMode)
if (check == "")
{
println("This information does not exist.")
} else {
println(checkMacro)
}
{groovy}
{run}
However, we can't seem to get both scenarios to work together, Groovy inside of a Run Macro inside of Groovy.
We need to be able to get the variables out of the Run Macro form so that we can perform other functions, like checking the DB for duplicates before inserting data.
My first thought is to bypass the Run Macro and create a simple from in groovy, but I haven't been too lucky with finding good examples. Can anyone help steer me in the right direction for creating a simple form in Groovy that would replace the Run Macro? Or have suggestions on how to get the rendered variables out of the Run Macro?

Play + Slick: How to do partial model updates?

I am using Play 2.2.x with Slick 2.0 (with MYSQL backend) to write a REST API. I have a User model with bunch of fields like age, name, gender etc. I want to create a route PATCH /users/:id which takes in partial user object (i.e. a subset of the fields of a full user model) in the body and updates the user's info. I am confused how I can achieve this:
How do I use PATCH verb in Play 2.2.x?
What is a generic way to parse the partial user object into an update query to execute in Slick 2.0?I am expecting to execute a single SQL statement e.g. update users set age=?, dob=? where id=?
Disclaimer: I haven't used Slick, so am just going by their documentation about Plain SQL Queries for this.
To answer your first question:
PATCH is just-another HTTP verb in your routes file, so for your example:
PATCH /users/:id controllers.UserController.patchById(id)
Your UserController could then be something like this:
val possibleUserFields = Seq("firstName", "middleName", "lastName", "age")
def patchById(id:String) = Action(parse.json) { request =>
def addClause(fieldName:String) = {
(request.body \ fieldName).asOpt[String].map { fieldValue =>
s"$fieldName=$fieldValue"
}
}
val clauses = possibleUserFields.flatMap ( addClause )
val updateStatement = "update users set " + clauses.mkString(",") + s" where id = $id"
// TODO: Actually make the Slick call, possibly using the 'sqlu' interpolator (see docs)
Ok(s"$updateStatement")
}
What this does:
Defines the list of JSON field names that might be present in the PATCH JSON
Defines an Action that will parse the incoming body as JSON
Iterates over all of the possible field names, testing whether they exist in the incoming JSON
If so, adds a clause of the form fieldname=<newValue> to a list
Builds an SQL update statement, comma-separating each of these clauses as required
I don't know if this is generic enough for you, there's probably a way to get the field names (i.e. the Slick column names) out of Slick, but like I said, I'm not even a Slick user, let alone an expert :-)