Karate - How to delay all scenarios? - unit-testing

I have a 10 scenarios, all of them must have 1 min delay after executing background. I call my delay function in background. The problem is that all scenarios call background, and I have to wait 10 minutes.
Is there a way to call my wait function one for all scenarios?
This is my background and one of my scenarios:
Background:
* call read('classpath:cleanup.feature')
* def login = call read('classpath:init/init.user.feature')
* def sleep =
"""
function(seconds){
for(i = 0; i <= seconds; i++)
{
java.lang.Thread.sleep(1*1000);
karate.log(i);
}
}
"""
* call sleep 60
Scenario: Correct
# Step one: requesting a verification code
Given url karate.get('urlBase') + "account/resendMobileActivationVerificationCode"
And request {"mobile": #(defaultMobile)}
And header X-Authorization = login.token
And header NESBA-Authorization = login.nesba
When method post
Then status 200
And match response ==
"""
{
"status":0,
"message":"#(status0persianMessage)",
"result": true
}
"""

Use callonce:
* callonce sleep 60

Related

Unable to display highcharts graphs with setextremes

I am collecting info from weather sensors(every 5 mins) and through the days and months, the amount of records is huge and render the chart takes for ever....It is working ,but the delay is too high... So instead of displaying all the values at once, I want to make the graph based on range of dates selected, and get data accordingly.
I am using python , sqlite3 and Flask and trying to copy this example from Highcharts
https://jsfiddle.net/gh/get/library/pure/highcharts/highcharts/tree/master/samples/stock/demo/lazy-loading/
In the example they use php , which here is the code
https://github.com/highcharts/highcharts/blob/master/samples/data/from-sql.php
This is my setextreme function in the html page
function setExtremes(e)
// detect zoom button
{
if(typeof(e.rangeSelectorButton)!== 'undefined')
{
if (e.rangeSelectorButton.type=='all')
{
var chart = Highcharts.charts[0];
chart.showLoading('Loading data from server...');
$.getJSON('http://192.168.0.74:5000/rango?start=' + Math.round(e.min) +'&end=' + Math.round(e.max) + '&callback=?', function (data) {
// Arrange data
alert('I am in')
for (i = 0; i< data.length; i++)
{
processed_json_temperatura.push(data[i][0], data[i][1]);
processed_json_presion.push(data[i][0], data[i][2]);
processed_json_humedad.push(data[i][0], data[i][3]);
processed_json_lluvia.push(data[i][0], data[i][4]);
processed_json_horas_frio.push(data[i][0], data[i][5]);
}
temperatura_matriz = listToMatrix( processed_json_temperatura,2);
presion_matriz = listToMatrix( processed_json_presion,2);
humedad_matriz = listToMatrix( processed_json_humedad,2);
lluvia_matriz = listToMatrix( processed_json_lluvia,2);
horas_frio_matriz = listToMatrix(processed_json_horas_frio,2);
//update graphs with new values
chart.series[0].setData(temperatura_matriz);
chart.series[1].setData(presion_matriz);
chart.series[2].setData(humedad_matriz);
chart.series[3].setData(lluvia_matriz);
chart.series[4].setData(horas_frio_matriz);
chart.hideLoading();
});
}
}
}
On server side, this is my python code with flask
#app.route("/rango")
def rango():
start=request.args.get('start')
end=request.args.get('end')
range = int(end)/1000 - int(start)/1000
# find the right table
# two days range loads minute data
if (range < 2 * 24 * 3600 * 1000):
connection = sqlite3.connect("/var/www/nueva_estacion.db")
cursor = connection.cursor()
cursor.execute("select (julianday(timestamp)-2440587.5)*86400000, round(temp1,2) as temp1, presion, round(humedad,2) as humedad, lluvia,aux1 from raw_all_sensors where datetime(timestamp) >=datetime('now', '-6 Day')")
results = cursor.fetchall()
print json.dumps(results)
return json.dumps(results)
When I click the zoom button(on highstock actually) I do see the message " Loading data from Server ..." but never shows the new graphs and never get "I am in" console message..
When monitoring the messaging on server side, I do get
192.168.0.122 - - [22/May/2019 19:47:22] "GET /rango?start=1558050049000&end=1558551372000&callback=jQuery18307335687220269529_1558565228146&_=1558565238543 HTTP/1.1" 200 -
where is clear start date, end date and then I do not understand the callback and the numbers that follow.
Just in case, this is the info coming from server
[1558546562999.989, 17.82, 1021, 76.15, 0, 1]
Can anyone bring some light here?

What does the "throughput-deadline-time" configuration option do?

I've stumbled on the throughput-deadline-time configuration property for Akka dispatchers, and it looks like an interesting option, however the only mention of it I could find in the whole documentation is the following:
# Throughput deadline for Dispatcher, set to 0 or negative for no deadline
throughput-deadline-time = 0ms
I think we can agree that this is not very helpful.
So what does throughput-deadline-time control, and what impact does it have when on my dispatcher?
So I had a look at the Akka source code, and found this method in the Mailbox that seems to implement the behavior of throughput-deadline-time:
/**
* Process the messages in the mailbox
*/
#tailrec private final def processMailbox(
left: Int = java.lang.Math.max(dispatcher.throughput, 1),
deadlineNs: Long = if (dispatcher.isThroughputDeadlineTimeDefined == true) System.nanoTime + dispatcher.throughputDeadlineTime.toNanos else 0L): Unit =
if (shouldProcessMessage) {
val next = dequeue()
if (next ne null) {
if (Mailbox.debug) println(actor.self + " processing message " + next)
actor invoke next
if (Thread.interrupted())
throw new InterruptedException("Interrupted while processing actor messages")
processAllSystemMessages()
if ((left > 1) && ((dispatcher.isThroughputDeadlineTimeDefined == false) || (System.nanoTime - deadlineNs) < 0))
processMailbox(left - 1, deadlineNs)
}
}
This piece of code makes it clear: throughput-deadline-time configures the maximum amount of time that will be spent processing the same mailbox, before switching to the mailbox of another actor.
In other words, if you configure a dispatcher with:
my-dispatcher {
throughput = 100
throughput-deadline-time = 1ms
}
Then the mailbox of the actors will process at most 100 messages at a time, during at most 1ms, whenever the first of those limits is hit, Akka switches to another actor/mailbox.

Using Tkinter as a notification Then returning to function of program

I am using Tkinter as a notification of an upcoming mouse event and I want the program to continue with its main function but it keeps closing after notification appears. What do i need to add to the follow code to get it to return to the function that called it?
def sendMessage():#THIS IS MY NOTIFICATION FUNCTION
popupRoot = Tk()
popupRoot.lift()
popupRoot.attributes('-topmost',True)
popupRoot.after_idle(popupRoot.attributes,'-topmost',False)
popupRoot.after(10000, exit)
popupButton = Button(popupRoot, text = "You have 1 minute until mouse events",
font = ("Verdana", 12), bg = "yellow", command = exit)
popupButton.pack()
popupRoot.geometry('400x50+700+500')
popupRoot.mainloop()
def wait(howLong, runTime, howRuns, day, x): #THIS IS THE FUNCTION THAT CALLED THE NOTIFICATION FUNCTION
while x < howLong:
print "rerun in ", howLong - x, " minute(s)"
messTime = 1
if messTime == 1:
sendMessage()
time.sleep(60)#1 minute delay to allow carts to return
x = x + 1
if x == howLong:
runTime = runTime + 1
print "Run time = ", runTime
print "rerunning program now"
if runTime == howRuns:
exitProgram()
else:
main(howLong, runTime, howRuns, day)
It ends because in after() and in command= you use exit which normally is used to close script.
You need popupRoot.destroy instead of exit in after(10000, popupRoot.destroy) and command=popupRoot.destroy

How to stream (yield) text data to jinja2 template for a flask app on pythonanywhere

I try to implement "streaming contents" on my Pythonanywhere account.
It looks more or less to what is shown there:
cf. http://flask.pocoo.org/docs/0.10/patterns/streaming/
except that my view is calculating a complex process for maybe one minute and yields its data to my template, where a script is supposed to update some progress bars (''source.onmessage'').
This works perfectly on my development machine, but not on my pythonanywhere account. On this server, the process looks jammed (progress bars are never updated, except at the very end where the suddunly grow from 0% to 100%), although everything goes well under the hood, e.g. my print statements are correctly rendered into my server logs).
In the snippet quoted above, there is a note:
Note though that some WSGI middlewares might break streaming, so be
careful there in debug environments with profilers and other things
you might have enabled.
Could it be the problem here? and would there be a workaround?
JS code from my jinja2 template:
<script type="text/javascript">
/* progress bar */
var source = new EventSource("{{ url_for('BP.run', mylongprocess_id=mylongprocess_id) }}");
source.onmessage = function(event) {
console.log(event.data);
var data = event.data.split("!!");
var nodeid = data[0];
var process = data[1];
var process_status = data[2];
var postpro = data[3];
var postpro_status = data[4];
$('.pb1').css('width', process+'%').attr('aria-valuenow', process);
$('.pb2').css('width', postpro+'%').attr('aria-valuenow', process);
document.getElementById("process_status").innerHTML = process_status;
document.getElementById("postpro_status").innerHTML = postpro_status;
document.getElementById("nodeid").innerHTML = nodeid;
if (postpro >= 100) {
setTimeout(function() {
console.log("progress is finished!");
document.getElementById("status").innerHTML = "redirecting to {{url_for('.view_sonix_result', mylongprocess_id=mylongprocess_id)}}";
window.location.replace("{{url_for('.terminate_analysis', mylongprocess_id=mylongprocess_id)}}");
}, 2); // / setTimeout function
} // /if
else {
document.getElementById("status").innerHTML = "pending...";
} // /else
} // /function
</script>
My (simplified) view:
#BP.route('/run/<int:mylongprocess_id>')
#login_required
def run(mylongprocess_id):
mylongprocess = mylongprocess.query.get_or_404(mylongprocess_id)
project = Project.query.get_or_404(mylongprocess.project_id)
check_rights(current_user, project, 'user', 404)
A, lcs = _create_analysis(mylongprocess)
#copy_current_request_context
def gen(mylongprocess, nodeid, store_path):
print('now runing %s' % A)
for (loopnb, total_loops, pct, lclabel) in A.runiterator(lcs):
print('ran %d/%d (%.1f%%) "%s"' % (loopnb, total_loops,
pct, lclabel))
progress = ('data: %s!!%f!!%s!!%f!!%s\n\n' %
(nodeid, pct, lclabel, 0, 'waiting...'))
yield progress
print('now postprocessing %s' % A)
postpro = load_node(store_path, node_id=nodeid)
for step, total, pct, action in postpro._builditer(target='web',
buildfile=None):
progress = ('data: %s!!%f!!%s!!%f!!%s\n\n' %
(nodeid, 100, 'ok', pct, action.replace('_', ' ')))
yield progress
print('now terminating %s' % A)
_terminate_analysis(A, mylongprocess)
return Response(gen(mylongprocess, mylongprocess.nodeid), mimetype='text/event-stream')
Your traffic goes through an nginx proxy when it is hosted on PythonAnywhere and nginx buffers the response unless specified otherwise.
To get everything to flush,
give your flask responses headers response.headers['X-Accel-Buffering'] = 'no'
have a '\n' at the end of the string you are yielding because python also buffers till end of line.

ColdFusion - Get next scheduled task due to run

This thread was useful in finding out the next run-time for a scheduled task.
How do I find out the next run time for a Scheduled Task?
But, is there also a way to simply get the next scheduled task due to run?
If I can get the date and name of the next task due to run, I can plug that date into a jQuery countdown timer, which will display a countdown to the next scheduled task, something like:
TaskABC due to run in:
12 03 20
hrs min sec
. This is for an admin interface in case you're wondering how geeky can people get:-)
EDIT
I had the same thought as Bill. But was curious if there was another way.
I poked around and apparently the internal Scheduler class maintains a list of upcoming tasks. The list is private, but you can use the same reflection technique to access it. Interestingly the list also includes system tasks like the mail spooler, session/application trackers, watchers, etecetera. So you must iterate through it until you find a "scheduled task" ie CronTabEntry
Below is a very lightly tested function that seems to do the trick in CF9. (Note, includes the CreateTimeStruct function from http://www.cflib.org).
Rules:
Returns a structure containing the name and time remaining until the next task. If no tasks were found, result.task is an empty string.
Excludes paused tasks
Usage:
result = new TaskUtil().getNextTask();
WriteDump(result);
CFC
component {
public struct function getNextTask() {
// get list of upcoming tasks from factory (UNDOCUMENTED)
local.scheduler = createObject("java", "coldfusion.server.ServiceFactory").getSchedulerService();
local.taskField = local.scheduler.getClass().getDeclaredField("_tasks");
local.taskField.setAccessible( true );
local.taskList = local.taskField.get(local.scheduler);
// taskList contains system jobs too, so we must iterate
// through the tasks to find the next "scheduled task"
local.nextTask = "";
local.tasks = local.taskList.iterator();
while ( local.tasks.hasNext() ) {
local.currTask = local.tasks.next();
local.className = local.currTask.getRunnable().getClass().name;
// exit as soon as we find a scheduled task that is NOT paused
if (local.className eq "coldfusion.scheduling.CronTabEntry"
&& !local.currTask.getRunnable().paused) {
local.nextTask = local.currTask;
break;
}
}
// if we found a task, calculate how many days, hours, etcetera
// until its next run time
local.details = { task="", remaining={} };
if ( isObject(local.nextTask) ) {
local.secondsToGo = (local.nextTask.getWhen() - now().getTime()) / 1000;
local.details.task = local.nextTask.getRunnable().task;
local.details.remaining = createTimeStruct(local.secondsToGo);
local.details.nextDate = dateAdd("s", local.nextTask.getWhen() / 1000
, "January 1 1970 00:00:00" );
}
return local.details;
}
/**
* Abbreviated version of CreateTimeStruct by Dave Pomerance
* See http://www.cflib.org/index.cfm?event=page.udfbyid&udfid=421
*
* #param timespan The timespan to convert.
* #return Returns a structure.
* #author Dave Pomerance
* #version 1, January 7, 2002
*/
public struct function CreateTimeStruct(required numeric timespan) {
var timestruct = StructNew();
var mask = "s";
// only 4 allowed values for mask - if not one of those, return blank struct
if (ListFind("d,h,m,s", mask)) {
// compute seconds
if (mask eq "s") {
timestruct.s = (timespan mod 60) + (timespan - Int(timespan));
timespan = int(timespan/60);
mask = "m";
} else timestruct.s = 0;
// compute minutes
if (mask eq "m") {
timestruct.m = timespan mod 60;
timespan = int(timespan/60);
mask = "h";
} else timestruct.m = 0;
// compute hours, days
if (mask eq "h") {
timestruct.h = timespan mod 24;
timestruct.d = int(timespan/24);
} else {
timestruct.h = 0;
timestruct.d = timespan;
}
}
return timestruct;
}
}
My first thought is to iterate Leigh's getNextRunTime(string taskName) function over the collection of tasks. You can get an array of structs containing the details of all scheduled tasks using taskArray = createobject("java","coldfusion.server.ServiceFactory").getCronService().listAll();
The key in the struct containing the task name is "task". So you can extract all the task names as an array for example, run Leigh's function on each element and determine which one will run next.