how to access secrets from jenkins in .scala file? - scala

I have a Secret text binding Variable SECRET_TKN in jenkins job configuration. I want to access this var in .scala file . How do I access this var generically in my code?
I have tried the following but it doesn't seem to work correctly:
val token =sys.env("${SECRET_TKN}")
println ("value = " +token)
Console output shows value as SOME(***) thus causing the api calls to fail as I believe the keyword SOME is coming along with the actual fetched value.
Also, tried sys.env("${?STG_SERVICE_TKN}") but no luck.

sys.env is keyed by variable name, so this should work:
val token = sys.env("SECRET_TKN")

For your case, it would work if the SECRET_TKN is a variable being populated, it would work fine:
val SECRET_TKN = "SECRET_TKN"
val token =sys.env(s"${SECRET_TKN}")
It's better practice to use sys.env.get("mySecret") which will give you an Option[String] rather than throw an error if that variable is missing.

Related

How to pass and get attributes in Gatling session from and to "exec" blocks

I'm pretty new at Scala/Gatling so forgive me if you see an anti-pattern or something wrong, I have a Gatling scenario in which I have to run some bash external scripts, and have to save some variables for their use in another exec block (I've tried calling the .exec right after the " exec(session => { ..." block, and have tried calling it as a method in another object.
exec(session => {
val scriptOutput = s"src/main/resources/thepath/myscript.sh ${arg1} ${arg2}".!!
val x_variable = "123" + scriptOutput
session.set("x_variable",x_variable)
})
.exec(MyClient.calling)
In "MyClient", I need to use the value of "x_variable", I currently have something like this:
def calling() = {
exec(http("POST to ${x_variable}")
.post("/${x_variable}"))
}
But when doing so, it doesn't work, the Post call is made but the variable "x_variable" is empty. To summarize, the question is how to pass that "session" information to any next "exec" block (right after or in another object), and how to consume it from that "session"?
The code described is working now, it seems I had some "trash" in the environment, after doing an mvn clean install it worked as expected.

Passing In Config In Gatling Tests

Noob to Gatling/Scala here.
This might be a bit of a silly question but I haven't been able to find an example of what I am trying to do.
I want to pass in things such as the baseURL, username and passwords for some of my calls. This would change from env to env, so I want to be able to change these values between the envs but still have the same tests in each.
I know we can feed in values but it appears that more for iterating over datasets and not so much for passing in the config values like I have.
Ideally I would like to house this information in a JSON file and not pass it in on the command line, but maybe thats not doable?
Any guidance on this would be awesome.
I have a similar setup and you can use pure scala here .In this scenario you can create an object called Config for eg
object Configuration { var INPUT_PROFILE_FILE_NAME = ""; }
This class can also read a file , I have the below code in the above object
val file = getClass.getResource("data/config.properties").getFile()
val prop = new Properties()
prop.load(new FileInputStream(file));
INPUT_PROFILE_FILE_NAME = prop.getProperty("inputProfileFileName")
Now you can import this object in Gattling Simulation File
val profileName= Configuration.INPUT_PROFILE_FILE_NAME ;
https://docs.scala-lang.org/tutorials/tour/singleton-objects.html.html

Why sbt.Extracted remove the previously defined TaskKey while append method?

There is a suitable method in the sbt.Exctracted to add the TaskKey to the current state. Assume I have inState: State:
val key1 = TaskKey[String]("key1")
Project.extract(inState).append(Seq(key1 := "key1 value"), inState)
I have faced with the strange behavior when I do it twice. I got the exception in the following example:
val key1 = TaskKey[String]("key1")
val key2 = TaskKey[String]("key2")
val st1: State = Project.extract(inState).append(Seq(key1 := "key1 value"), inState)
val st2: State = Project.extract(st1).append(Seq(key2 := "key2 value"), st1)
Project.extract(st2).runTask(key1, st2)
leads to:
java.lang.RuntimeException: */*:key1 is undefined.
The question is - why does it work like this? Is it possible to add several TaskKeys while executing the particular task by several calls to sbt.Extracted.append?
The example sbt project is sbt.Extracted append-example, to reproduce the issue just run sbt fooCmd
Josh Suereth posted the answer to sbt-dev mail list. Quote:
The append function is pretty dirty/low-level. This is probably a bug in its implementation (or the lack of documentation), but it blows away any other appended setting when used.
What you want to do, (I think) is append into the current "Session" so things will stick around and the user can remove what you've done via "sesison clear" command.
Additonally, the settings you're passing are in "raw" or "fully qualified" form. If you'd for the setting you write to work exactly the same as it would from a build.sbt file, you need to transform it first, so the Scopes match the current project, etc.
We provide a utility in sbt-server that makes it a bit easier to append settings into the current session:
https://github.com/sbt/sbt-remote-control/blob/master/server/src/main/scala/sbt/server/SettingUtil.scala#L11-L29
I have tested the proposed solution and that works like a charm.

Is there a way to find out which pytest-xdist gateway is running?

I would like to create a separate log file for each subprocess/gateway that is spawned by pytest-xdist. Is there an elegant way of finding out in which subprocess/gateway pytest is currently in? I'm configuring my root logger with a session scoped fixture located in conftest.py, something like this:
#pytest.fixture(scope='session', autouse=True)
def setup_logging():
logger = logging.getLogger(__name__)
logger.setLevel(logging.INFO)
fh = logging.FileHandler('xdist.log')
fh.setLevel(logging.INFO)
formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
fh.setFormatter(formatter)
logger.addHandler(fh)
It would be great if i could add a prefix to the log file name based on the gateway number, e.g:
fh = logging.FileHandler('xdist_gateway_%s.log' % gateway_number)
Without this each gateway will use the same log and the logs will get messy. I know that I can add a time stamp to the filename. But this doesn't let me to distinguish quickly which file is from which gateway.
Similar to #Kanguros's answer but plugging into the pytest fixture paradigm:
You can get the worker id by [accessing] the slaveinput dictionary. Here's a fixture which makes that information available to tests and other fixtures:
#pytest.fixture
def worker_id(request):
if hasattr(request.config, 'workerinput'):
return request.config.workerinput['workerid']
else:
return 'master'
This is quoted from a comment on the pytest-xdist Issues tracker/discussion (2016).
I found out that you can access the gateway id in the following way:
slaveinput = getattr(session.config, "slaveinput", None)
if slaveinput:
gatewayid = slaveinput['slaveid']
Of course you need to be in a place where you can access the session.config object.

How do I read environment variables in Postman tests?

I'm using the packaged app version of Postman to write tests against my Rest API. I'm trying to manage state between consecutive tests. To faciliate this, the Postman object exposed to the Javascript test runtime has methods for setting variables, but none for reading.
postman.setEnvironmentVariable("key", value );
Now, I can read this value in the next call via the {{key}} structure that sucks values in from the current environment. BUT, this doesn't work in the tests; it only works in the request building stuff.
So, is there away to read this stuff from the tests?
According to the docs here you can use
environment["foo"] OR environment.foo
globals["bar"] OR globals.bar
to access them.
ie;
postman.setEnvironmentVariable("foo", "bar");
tests["environment var foo = bar"] = environment.foo === "bar";
postman.setGlobalVariable("foobar", "1");
tests["global var foobar = true"] = globals.foobar == true;
postman.setGlobalVariable("bar", "0");
tests["global var bar = false"] = globals.bar == false;
Postman updated their sandbox and added a pm.* API. Although the older syntax for reading variables in the test scripts still works, according to the docs:
Once a variable has been set, use the pm.variables.get() method or,
alternatively, use the pm.environment.get() or pm.globals.get()
method depending on the appropriate scope to fetch the variable. The
method requires the variable name as a parameter to retrieve the
stored value in a script.