In gatling,I want to exit the interation on failure and start a new iteration. I have used exitHereIfFailed but see that it completely stops the scenario. althought my scenario is configured to run for 30 minutes. Please advice if I have got this right.
Also how do I handle the errors in Gatling, and print to a file with relavent details. In my example below on check failure, I want to exit the iteration and write the details to a file will details like username, timestamp etc.. Kindly help.
import scala.concurrent.duration._
import io.gatling.core.Predef.{exec, _}
import io.gatling.http.Predef.{http, _}
import io.gatling.jdbc.Predef._
import scala.language.postfixOps
object Login {
val login = group("ABC_Login") {
feed(userFeeder)
.exec(http("Login")
.post(uri16 + "/login")
.formParam("username", "${username}")
.formParam("password", "${password}")
.formParam("login", "Login")
.check(substring("Welcome to ABC Professionalllll")))
.exitHereIfFailed
}
//scenario definition and injection setup
val BP01AddSearch = scenario("BP01Search").during(30 minutes)
{
pace(50 seconds)
.exec(Homepage.homepage, Login.login, SearchLink.search, Logout.logout)
}
setUp(BP01AddSearch.inject(atOnceUsers(1)).protocols(httpProtocol) )
Use tryMax, see https://gatling.io/docs/gatling/reference/current/general/scenario/#trymax
during(30 minutes) {
tryMax(5) {
pace(50 seconds)
.exec(Homepage.homepage, Login.login, SearchLink.search, Logout.logout)
}
}
Related
Is it possible to schedule a task in celery from another task?
I've got this Python script:
import logging
from celery import Celery
from datetime import datetime
logger = logging.getLogger(__name__)
app = Celery('app', backend='amqp://', broker='pyamqp://guest#localhost:5672//')
#app.task()
def add(x, y):
result = x + y
logger.info(f'Add: {x} + {y} = {result}')
return result
#app.task()
def setPeriodicTask():
#option 1
app.add_periodic_task(10, add.s(30, 1))
#option 2
app.conf.beat_schedule = {
'add-every-5-seconds': {
'task': 'app.add',
'schedule': 5.0,
'args': (now.hour, now.second)
}
}
logger.info(f'setPeriodicTask succeeded')
return 1
When I call the add task, it works OK.
If I call the setPeriodicTask task it does not throw any error but the add task is not scheduled.
I've tried both options, none is working:
add_periodic_task
modify the beat_schedule
If I add this code to my Python script (as I've seen in the celery docs):
#app.on_after_configure.connect
def setup_periodic_tasks(sender, **kwargs):
sender.add_periodic_task(5.0, add.s(10, 1))
I can see the add task running scheduled as expected. So celery and celery beat seem to be working fine.
But I want to enable/disable the task on demand.
Is it possible? And if so, what am I doing wrong?
In case someone else faces this issue.
I ended up using a database with a similar approach as the one mention in the django -celery-beat doc: django-celery-beat - Database-backed Periodic Tasks
Slightly off topic question here but I'm looking to mock the calls to the sender.add_periodic_task(5.0, add.s(10, 1)) and I can not find anything that would tell me where it is
I'm using #mock.patch("celery.add_periodic_task")
any ideas would be welcome
import pytest
from ddt import ddt, data, unpack
from unittest import mock
from django.test import TestCase
from myapp.celery import setup_periodic_tasks
class CeleryTasksTest(TestCase):
#mock.patch("celery.add_periodic_task")
#mock.patch("os.environ.get")
#data(
{"env_to_test":"local", "number_of_tasks":0},
{"env_to_test":"TEST", "number_of_tasks":0},
{"env_to_test":"STAGING", "number_of_tasks":5},
{"env_to_test":"LIVE", "number_of_tasks":1},
)
#unpack
def test_setup_periodic_tasks_per_environment(self, mock_os_environ_get, mock_add_periodic_task, env_to_test, number_of_tasks):
setup_periodic_tasks([])
mock_os_environ_get.return_value=env_to_test
self.assertEqual(mock_add_periodic_task.call_count, number_of_tasks)
New to Gatling and trying to understand how to get "exec(flushHttpCache)" incorporated into my script as I am trying to stop redirects from occurring as these will skew my results.
I have:
val getStartPage = feed(feeder).exec(http("Test start page (start-page)")
.exec(flushHttpCache) // <- this fails on compile "flushHttpCache is not a member of io.gatling.http.request.builder.Http"
.get("/start-page?id=${userId}")
.check(status.is(200))
.check(regex("Start now").exists))
.pause(longPause)
then:
class myPerformanceTest extends Simulation with HttpConfiguration
{
val happyPath = scenario("testUsers")
.exec(getStartPage)
setUp(
happyPath.inject(atOnceUsers(1))
).protocols(httpconf)
}
I tried moving ".exec(flushHttpCache)" to: val happyPath = scenario("testUsers").exec(flushHttpCache) still no luck.
How do I incorporate the "flushHttpCache" into a script?
Any help appreciated
You should import
import io.gatling.http.Predef._
not
import io.gatling.http.request.builder.Http
The second part of question will work as you tried, with this import.
I am working with the spray api. I have the following code:
import akka.actor.ActorSystem
import spray.routing.SimpleRoutingApp
import spray.json.DefaultJsonProtocol._
object Server1 extends App with SimpleRoutingApp{
implicit val actorSystem = ActorSystem()
startServer(interface="localhost",port = 8080){
println("Listening...")
get{
println("incoming..")
path("state"){
complete{
"in the complete block"
}
}
}
}
}
It is giving a single response on api. It will print "in the complete block" when i call from web browser. Can I make it iterative means that i use a variable and send its value in complete block then I can change the value of that variable and then send its new value in complete block.
You mean something like this:
var state = 0
get{
println("incoming..")
path("state"){
complete{
state = state + 1
s"in the complete block ${state}"
}
}
}
I am making a Play web-socket app. When a client connects, I want to send a welcome message.
The code I use is below:
package controllers
import play.api._
import play.api.mvc._
import play.api.libs.iteratee.Concurrent
import play.api.libs.iteratee.Iteratee
import play.api.libs.concurrent.Execution.Implicits.defaultContext
object Test extends Controller {
def index = WebSocket.using[String] { _ =>
val (out,channel) = Concurrent.broadcast[String]
channel.push("Welcome to MyWebSocket")
val in = Iteratee.foreach[String] {
_ match {
case any => channel.push(any)
}
}
(in, out)
}
}
The code works fine when a client sends a message and the server has to respond to it. However, the initial welcome message Welcome to MyWebSocket is not sent. How can I fix this code?
[EDIT]
I kind of figured out the problem, but not a solution yet. The problem probably occurs because the websocket is not yet initialized when the welcome message is being pushed. I modified the code and replaced:
channel.push("Welcome to MyWebSocket")
with
val a = scala.concurrent.Future {
Thread.sleep(1000)
channel.push("Welcome to MyWebSocket")
}
After this I get the expected results (welcome message received by client). I think using the above approach (Thread.sleep and Future) is not the right way to solve this problem, so other solutions are welcome. It could also be a problem with the client side code which takes a while to initialize the socket. I used Firefox and echo web-socket test for the client.
You can use WebSocket.acceptWithActor helper method (have a look at this) and in actor body make something like
out ! "Welcome to MyWebSocket"
It works nicely.
I need to make some consuming calculations on the server side (such as DB querying and data analisys). And the results need to be printed in browser. For these purpose I send Future result from server to client (to load web page immediately and gradually print future results from server). For example, on the server side
import scala.concurrent.Future
import scala.concurrent.ExecutionContext.Implicits.global
def futureResult = Future {
val cc = ConsumingCalculations();
"some result"
}
on the client side
#import scala.concurrent.ExecutionContext.Implicits.global
#main{
#futureResult.onSuccess{ case res =>
#println("This line is printed in console: "+res);
<div>Any html code is NOT printed in browser</div>
}
Future result is NOT posted
}
In server consol we have: "This line is printed in console: some result"
But in the browser we have only: "Future result is NOT posted"
Play 2.1, scala 2.10 are currently used. What's may be wrong, are there any idea?
A future cannot be sent on client side, it must be resolved on server side before displaying to the client.
The classic exemple is to map the result of your future in your controller
def myAction = Action {
Async {
futureResult.map(result =>
Ok(views.html.myView(result))
)
}
}
And in your template, use the result, not the future.