How to use task method in stryker-parent

Best JavaScript code snippet using stryker-parent

task.js

Source:task.js Github

copy

Full Screen

1/**2 * Support for concurrent task management and synchronization in web3 * applications.4 *5 * @author Dave Longley6 * @author David I. Lehn <dlehn@digitalbazaar.com>7 *8 * Copyright (c) 2009-2013 Digital Bazaar, Inc.9 */10var forge = require('./forge');11require('./debug');12require('./log');13require('./util');14// logging category15var cat = 'forge.task';16// verbose level17// 0: off, 1: a little, 2: a whole lot18// Verbose debug logging is surrounded by a level check to avoid the19// performance issues with even calling the logging code regardless if it20// is actually logged. For performance reasons this should not be set to 221// for production use.22// ex: if(sVL >= 2) forge.log.verbose(....)23var sVL = 0;24// track tasks for debugging25var sTasks = {};26var sNextTaskId = 0;27// debug access28forge.debug.set(cat, 'tasks', sTasks);29// a map of task type to task queue30var sTaskQueues = {};31// debug access32forge.debug.set(cat, 'queues', sTaskQueues);33// name for unnamed tasks34var sNoTaskName = '?';35// maximum number of doNext() recursions before a context swap occurs36// FIXME: might need to tweak this based on the browser37var sMaxRecursions = 30;38// time slice for doing tasks before a context swap occurs39// FIXME: might need to tweak this based on the browser40var sTimeSlice = 20;41/**42 * Task states.43 *44 * READY: ready to start processing45 * RUNNING: task or a subtask is running46 * BLOCKED: task is waiting to acquire N permits to continue47 * SLEEPING: task is sleeping for a period of time48 * DONE: task is done49 * ERROR: task has an error50 */51var READY = 'ready';52var RUNNING = 'running';53var BLOCKED = 'blocked';54var SLEEPING = 'sleeping';55var DONE = 'done';56var ERROR = 'error';57/**58 * Task actions. Used to control state transitions.59 *60 * STOP: stop processing61 * START: start processing tasks62 * BLOCK: block task from continuing until 1 or more permits are released63 * UNBLOCK: release one or more permits64 * SLEEP: sleep for a period of time65 * WAKEUP: wakeup early from SLEEPING state66 * CANCEL: cancel further tasks67 * FAIL: a failure occured68 */69var STOP = 'stop';70var START = 'start';71var BLOCK = 'block';72var UNBLOCK = 'unblock';73var SLEEP = 'sleep';74var WAKEUP = 'wakeup';75var CANCEL = 'cancel';76var FAIL = 'fail';77/**78 * State transition table.79 *80 * nextState = sStateTable[currentState][action]81 */82var sStateTable = {};83sStateTable[READY] = {};84sStateTable[READY][STOP] = READY;85sStateTable[READY][START] = RUNNING;86sStateTable[READY][CANCEL] = DONE;87sStateTable[READY][FAIL] = ERROR;88sStateTable[RUNNING] = {};89sStateTable[RUNNING][STOP] = READY;90sStateTable[RUNNING][START] = RUNNING;91sStateTable[RUNNING][BLOCK] = BLOCKED;92sStateTable[RUNNING][UNBLOCK] = RUNNING;93sStateTable[RUNNING][SLEEP] = SLEEPING;94sStateTable[RUNNING][WAKEUP] = RUNNING;95sStateTable[RUNNING][CANCEL] = DONE;96sStateTable[RUNNING][FAIL] = ERROR;97sStateTable[BLOCKED] = {};98sStateTable[BLOCKED][STOP] = BLOCKED;99sStateTable[BLOCKED][START] = BLOCKED;100sStateTable[BLOCKED][BLOCK] = BLOCKED;101sStateTable[BLOCKED][UNBLOCK] = BLOCKED;102sStateTable[BLOCKED][SLEEP] = BLOCKED;103sStateTable[BLOCKED][WAKEUP] = BLOCKED;104sStateTable[BLOCKED][CANCEL] = DONE;105sStateTable[BLOCKED][FAIL] = ERROR;106sStateTable[SLEEPING] = {};107sStateTable[SLEEPING][STOP] = SLEEPING;108sStateTable[SLEEPING][START] = SLEEPING;109sStateTable[SLEEPING][BLOCK] = SLEEPING;110sStateTable[SLEEPING][UNBLOCK] = SLEEPING;111sStateTable[SLEEPING][SLEEP] = SLEEPING;112sStateTable[SLEEPING][WAKEUP] = SLEEPING;113sStateTable[SLEEPING][CANCEL] = DONE;114sStateTable[SLEEPING][FAIL] = ERROR;115sStateTable[DONE] = {};116sStateTable[DONE][STOP] = DONE;117sStateTable[DONE][START] = DONE;118sStateTable[DONE][BLOCK] = DONE;119sStateTable[DONE][UNBLOCK] = DONE;120sStateTable[DONE][SLEEP] = DONE;121sStateTable[DONE][WAKEUP] = DONE;122sStateTable[DONE][CANCEL] = DONE;123sStateTable[DONE][FAIL] = ERROR;124sStateTable[ERROR] = {};125sStateTable[ERROR][STOP] = ERROR;126sStateTable[ERROR][START] = ERROR;127sStateTable[ERROR][BLOCK] = ERROR;128sStateTable[ERROR][UNBLOCK] = ERROR;129sStateTable[ERROR][SLEEP] = ERROR;130sStateTable[ERROR][WAKEUP] = ERROR;131sStateTable[ERROR][CANCEL] = ERROR;132sStateTable[ERROR][FAIL] = ERROR;133/**134 * Creates a new task.135 *136 * @param options options for this task137 * run: the run function for the task (required)138 * name: the run function for the task (optional)139 * parent: parent of this task (optional)140 *141 * @return the empty task.142 */143var Task = function(options) {144 // task id145 this.id = -1;146 // task name147 this.name = options.name || sNoTaskName;148 // task has no parent149 this.parent = options.parent || null;150 // save run function151 this.run = options.run;152 // create a queue of subtasks to run153 this.subtasks = [];154 // error flag155 this.error = false;156 // state of the task157 this.state = READY;158 // number of times the task has been blocked (also the number159 // of permits needed to be released to continue running)160 this.blocks = 0;161 // timeout id when sleeping162 this.timeoutId = null;163 // no swap time yet164 this.swapTime = null;165 // no user data166 this.userData = null;167 // initialize task168 // FIXME: deal with overflow169 this.id = sNextTaskId++;170 sTasks[this.id] = this;171 if(sVL >= 1) {172 forge.log.verbose(cat, '[%s][%s] init', this.id, this.name, this);173 }174};175/**176 * Logs debug information on this task and the system state.177 */178Task.prototype.debug = function(msg) {179 msg = msg || '';180 forge.log.debug(cat, msg,181 '[%s][%s] task:', this.id, this.name, this,182 'subtasks:', this.subtasks.length,183 'queue:', sTaskQueues);184};185/**186 * Adds a subtask to run after task.doNext() or task.fail() is called.187 *188 * @param name human readable name for this task (optional).189 * @param subrun a function to run that takes the current task as190 * its first parameter.191 *192 * @return the current task (useful for chaining next() calls).193 */194Task.prototype.next = function(name, subrun) {195 // juggle parameters if it looks like no name is given196 if(typeof(name) === 'function') {197 subrun = name;198 // inherit parent's name199 name = this.name;200 }201 // create subtask, set parent to this task, propagate callbacks202 var subtask = new Task({203 run: subrun,204 name: name,205 parent: this206 });207 // start subtasks running208 subtask.state = RUNNING;209 subtask.type = this.type;210 subtask.successCallback = this.successCallback || null;211 subtask.failureCallback = this.failureCallback || null;212 // queue a new subtask213 this.subtasks.push(subtask);214 return this;215};216/**217 * Adds subtasks to run in parallel after task.doNext() or task.fail()218 * is called.219 *220 * @param name human readable name for this task (optional).221 * @param subrun functions to run that take the current task as222 * their first parameter.223 *224 * @return the current task (useful for chaining next() calls).225 */226Task.prototype.parallel = function(name, subrun) {227 // juggle parameters if it looks like no name is given228 if(forge.util.isArray(name)) {229 subrun = name;230 // inherit parent's name231 name = this.name;232 }233 // Wrap parallel tasks in a regular task so they are started at the234 // proper time.235 return this.next(name, function(task) {236 // block waiting for subtasks237 var ptask = task;238 ptask.block(subrun.length);239 // we pass the iterator from the loop below as a parameter240 // to a function because it is otherwise included in the241 // closure and changes as the loop changes -- causing i242 // to always be set to its highest value243 var startParallelTask = function(pname, pi) {244 forge.task.start({245 type: pname,246 run: function(task) {247 subrun[pi](task);248 },249 success: function(task) {250 ptask.unblock();251 },252 failure: function(task) {253 ptask.unblock();254 }255 });256 };257 for(var i = 0; i < subrun.length; i++) {258 // Type must be unique so task starts in parallel:259 // name + private string + task id + sub-task index260 // start tasks in parallel and unblock when the finish261 var pname = name + '__parallel-' + task.id + '-' + i;262 var pi = i;263 startParallelTask(pname, pi);264 }265 });266};267/**268 * Stops a running task.269 */270Task.prototype.stop = function() {271 this.state = sStateTable[this.state][STOP];272};273/**274 * Starts running a task.275 */276Task.prototype.start = function() {277 this.error = false;278 this.state = sStateTable[this.state][START];279 // try to restart280 if(this.state === RUNNING) {281 this.start = new Date();282 this.run(this);283 runNext(this, 0);284 }285};286/**287 * Blocks a task until it one or more permits have been released. The288 * task will not resume until the requested number of permits have289 * been released with call(s) to unblock().290 *291 * @param n number of permits to wait for(default: 1).292 */293Task.prototype.block = function(n) {294 n = typeof(n) === 'undefined' ? 1 : n;295 this.blocks += n;296 if(this.blocks > 0) {297 this.state = sStateTable[this.state][BLOCK];298 }299};300/**301 * Releases a permit to unblock a task. If a task was blocked by302 * requesting N permits via block(), then it will only continue303 * running once enough permits have been released via unblock() calls.304 *305 * If multiple processes need to synchronize with a single task then306 * use a condition variable (see forge.task.createCondition). It is307 * an error to unblock a task more times than it has been blocked.308 *309 * @param n number of permits to release (default: 1).310 *311 * @return the current block count (task is unblocked when count is 0)312 */313Task.prototype.unblock = function(n) {314 n = typeof(n) === 'undefined' ? 1 : n;315 this.blocks -= n;316 if(this.blocks === 0 && this.state !== DONE) {317 this.state = RUNNING;318 runNext(this, 0);319 }320 return this.blocks;321};322/**323 * Sleep for a period of time before resuming tasks.324 *325 * @param n number of milliseconds to sleep (default: 0).326 */327Task.prototype.sleep = function(n) {328 n = typeof(n) === 'undefined' ? 0 : n;329 this.state = sStateTable[this.state][SLEEP];330 var self = this;331 this.timeoutId = setTimeout(function() {332 self.timeoutId = null;333 self.state = RUNNING;334 runNext(self, 0);335 }, n);336};337/**338 * Waits on a condition variable until notified. The next task will339 * not be scheduled until notification. A condition variable can be340 * created with forge.task.createCondition().341 *342 * Once cond.notify() is called, the task will continue.343 *344 * @param cond the condition variable to wait on.345 */346Task.prototype.wait = function(cond) {347 cond.wait(this);348};349/**350 * If sleeping, wakeup and continue running tasks.351 */352Task.prototype.wakeup = function() {353 if(this.state === SLEEPING) {354 cancelTimeout(this.timeoutId);355 this.timeoutId = null;356 this.state = RUNNING;357 runNext(this, 0);358 }359};360/**361 * Cancel all remaining subtasks of this task.362 */363Task.prototype.cancel = function() {364 this.state = sStateTable[this.state][CANCEL];365 // remove permits needed366 this.permitsNeeded = 0;367 // cancel timeouts368 if(this.timeoutId !== null) {369 cancelTimeout(this.timeoutId);370 this.timeoutId = null;371 }372 // remove subtasks373 this.subtasks = [];374};375/**376 * Finishes this task with failure and sets error flag. The entire377 * task will be aborted unless the next task that should execute378 * is passed as a parameter. This allows levels of subtasks to be379 * skipped. For instance, to abort only this tasks's subtasks, then380 * call fail(task.parent). To abort this task's subtasks and its381 * parent's subtasks, call fail(task.parent.parent). To abort382 * all tasks and simply call the task callback, call fail() or383 * fail(null).384 *385 * The task callback (success or failure) will always, eventually, be386 * called.387 *388 * @param next the task to continue at, or null to abort entirely.389 */390Task.prototype.fail = function(next) {391 // set error flag392 this.error = true;393 // finish task394 finish(this, true);395 if(next) {396 // propagate task info397 next.error = this.error;398 next.swapTime = this.swapTime;399 next.userData = this.userData;400 // do next task as specified401 runNext(next, 0);402 } else {403 if(this.parent !== null) {404 // finish root task (ensures it is removed from task queue)405 var parent = this.parent;406 while(parent.parent !== null) {407 // propagate task info408 parent.error = this.error;409 parent.swapTime = this.swapTime;410 parent.userData = this.userData;411 parent = parent.parent;412 }413 finish(parent, true);414 }415 // call failure callback if one exists416 if(this.failureCallback) {417 this.failureCallback(this);418 }419 }420};421/**422 * Asynchronously start a task.423 *424 * @param task the task to start.425 */426var start = function(task) {427 task.error = false;428 task.state = sStateTable[task.state][START];429 setTimeout(function() {430 if(task.state === RUNNING) {431 task.swapTime = +new Date();432 task.run(task);433 runNext(task, 0);434 }435 }, 0);436};437/**438 * Run the next subtask or finish this task.439 *440 * @param task the task to process.441 * @param recurse the recursion count.442 */443var runNext = function(task, recurse) {444 // get time since last context swap (ms), if enough time has passed set445 // swap to true to indicate that doNext was performed asynchronously446 // also, if recurse is too high do asynchronously447 var swap =448 (recurse > sMaxRecursions) ||449 (+new Date() - task.swapTime) > sTimeSlice;450 var doNext = function(recurse) {451 recurse++;452 if(task.state === RUNNING) {453 if(swap) {454 // update swap time455 task.swapTime = +new Date();456 }457 if(task.subtasks.length > 0) {458 // run next subtask459 var subtask = task.subtasks.shift();460 subtask.error = task.error;461 subtask.swapTime = task.swapTime;462 subtask.userData = task.userData;463 subtask.run(subtask);464 if(!subtask.error) {465 runNext(subtask, recurse);466 }467 } else {468 finish(task);469 if(!task.error) {470 // chain back up and run parent471 if(task.parent !== null) {472 // propagate task info473 task.parent.error = task.error;474 task.parent.swapTime = task.swapTime;475 task.parent.userData = task.userData;476 // no subtasks left, call run next subtask on parent477 runNext(task.parent, recurse);478 }479 }480 }481 }482 };483 if(swap) {484 // we're swapping, so run asynchronously485 setTimeout(doNext, 0);486 } else {487 // not swapping, so run synchronously488 doNext(recurse);489 }490};491/**492 * Finishes a task and looks for the next task in the queue to start.493 *494 * @param task the task to finish.495 * @param suppressCallbacks true to suppress callbacks.496 */497var finish = function(task, suppressCallbacks) {498 // subtask is now done499 task.state = DONE;500 delete sTasks[task.id];501 if(sVL >= 1) {502 forge.log.verbose(cat, '[%s][%s] finish',503 task.id, task.name, task);504 }505 // only do queue processing for root tasks506 if(task.parent === null) {507 // report error if queue is missing508 if(!(task.type in sTaskQueues)) {509 forge.log.error(cat,510 '[%s][%s] task queue missing [%s]',511 task.id, task.name, task.type);512 } else if(sTaskQueues[task.type].length === 0) {513 // report error if queue is empty514 forge.log.error(cat,515 '[%s][%s] task queue empty [%s]',516 task.id, task.name, task.type);517 } else if(sTaskQueues[task.type][0] !== task) {518 // report error if this task isn't the first in the queue519 forge.log.error(cat,520 '[%s][%s] task not first in queue [%s]',521 task.id, task.name, task.type);522 } else {523 // remove ourselves from the queue524 sTaskQueues[task.type].shift();525 // clean up queue if it is empty526 if(sTaskQueues[task.type].length === 0) {527 if(sVL >= 1) {528 forge.log.verbose(cat, '[%s][%s] delete queue [%s]',529 task.id, task.name, task.type);530 }531 /* Note: Only a task can delete a queue of its own type. This532 is used as a way to synchronize tasks. If a queue for a certain533 task type exists, then a task of that type is running.534 */535 delete sTaskQueues[task.type];536 } else {537 // dequeue the next task and start it538 if(sVL >= 1) {539 forge.log.verbose(cat,540 '[%s][%s] queue start next [%s] remain:%s',541 task.id, task.name, task.type,542 sTaskQueues[task.type].length);543 }544 sTaskQueues[task.type][0].start();545 }546 }547 if(!suppressCallbacks) {548 // call final callback if one exists549 if(task.error && task.failureCallback) {550 task.failureCallback(task);551 } else if(!task.error && task.successCallback) {552 task.successCallback(task);553 }554 }555 }556};557/* Tasks API */558module.exports = forge.task = forge.task || {};559/**560 * Starts a new task that will run the passed function asynchronously.561 *562 * In order to finish the task, either task.doNext() or task.fail()563 * *must* be called.564 *565 * The task must have a type (a string identifier) that can be used to566 * synchronize it with other tasks of the same type. That type can also567 * be used to cancel tasks that haven't started yet.568 *569 * To start a task, the following object must be provided as a parameter570 * (each function takes a task object as its first parameter):571 *572 * {573 * type: the type of task.574 * run: the function to run to execute the task.575 * success: a callback to call when the task succeeds (optional).576 * failure: a callback to call when the task fails (optional).577 * }578 *579 * @param options the object as described above.580 */581forge.task.start = function(options) {582 // create a new task583 var task = new Task({584 run: options.run,585 name: options.name || sNoTaskName586 });587 task.type = options.type;588 task.successCallback = options.success || null;589 task.failureCallback = options.failure || null;590 // append the task onto the appropriate queue591 if(!(task.type in sTaskQueues)) {592 if(sVL >= 1) {593 forge.log.verbose(cat, '[%s][%s] create queue [%s]',594 task.id, task.name, task.type);595 }596 // create the queue with the new task597 sTaskQueues[task.type] = [task];598 start(task);599 } else {600 // push the task onto the queue, it will be run after a task601 // with the same type completes602 sTaskQueues[options.type].push(task);603 }604};605/**606 * Cancels all tasks of the given type that haven't started yet.607 *608 * @param type the type of task to cancel.609 */610forge.task.cancel = function(type) {611 // find the task queue612 if(type in sTaskQueues) {613 // empty all but the current task from the queue614 sTaskQueues[type] = [sTaskQueues[type][0]];615 }616};617/**618 * Creates a condition variable to synchronize tasks. To make a task wait619 * on the condition variable, call task.wait(condition). To notify all620 * tasks that are waiting, call condition.notify().621 *622 * @return the condition variable.623 */624forge.task.createCondition = function() {625 var cond = {626 // all tasks that are blocked627 tasks: {}628 };629 /**630 * Causes the given task to block until notify is called. If the task631 * is already waiting on this condition then this is a no-op.632 *633 * @param task the task to cause to wait.634 */635 cond.wait = function(task) {636 // only block once637 if(!(task.id in cond.tasks)) {638 task.block();639 cond.tasks[task.id] = task;640 }641 };642 /**643 * Notifies all waiting tasks to wake up.644 */645 cond.notify = function() {646 // since unblock() will run the next task from here, make sure to647 // clear the condition's blocked task list before unblocking648 var tmp = cond.tasks;649 cond.tasks = {};650 for(var id in tmp) {651 tmp[id].unblock();652 }653 };654 return cond;...

Full Screen

Full Screen

test_play_iterator.py

Source:test_play_iterator.py Github

copy

Full Screen

...137 )138 # lookup up an original task139 target_task = p._entries[0].tasks[0].block[0]140 task_copy = target_task.copy(exclude_parent=True)141 found_task = itr.get_original_task(hosts[0], task_copy)142 self.assertEqual(target_task, found_task)143 bad_task = Task()144 found_task = itr.get_original_task(hosts[0], bad_task)145 self.assertIsNone(found_task)146 # pre task147 (host_state, task) = itr.get_next_task_for_host(hosts[0])148 self.assertIsNotNone(task)149 self.assertEqual(task.action, 'debug')150 # implicit meta: flush_handlers151 (host_state, task) = itr.get_next_task_for_host(hosts[0])152 self.assertIsNotNone(task)153 self.assertEqual(task.action, 'meta')154 # role task155 (host_state, task) = itr.get_next_task_for_host(hosts[0])156 self.assertIsNotNone(task)157 self.assertEqual(task.action, 'debug')158 self.assertEqual(task.name, "role task")...

Full Screen

Full Screen

ecs_task.py

Source:ecs_task.py Github

copy

Full Screen

...184 for c in response['taskArns']:185 if c.endswith(service_name):186 return c187 return None188 def run_task(self, cluster, task_definition, overrides, count, startedBy):189 if overrides is None:190 overrides = dict()191 response = self.ecs.run_task(192 cluster=cluster,193 taskDefinition=task_definition,194 overrides=overrides,195 count=count,196 startedBy=startedBy)197 # include tasks and failures198 return response['tasks']199 def start_task(self, cluster, task_definition, overrides, container_instances, startedBy):200 args = dict()201 if cluster:202 args['cluster'] = cluster203 if task_definition:204 args['taskDefinition']=task_definition205 if overrides:206 args['overrides']=overrides207 if container_instances:208 args['containerInstances']=container_instances209 if startedBy:210 args['startedBy']=startedBy211 response = self.ecs.start_task(**args)212 # include tasks and failures213 return response['tasks']214 def stop_task(self, cluster, task):215 response = self.ecs.stop_task(cluster=cluster, task=task)216 return response['task']217def main():218 argument_spec = ec2_argument_spec()219 argument_spec.update(dict(220 operation=dict(required=True, choices=['run', 'start', 'stop'] ),221 cluster=dict(required=False, type='str' ), # R S P222 task_definition=dict(required=False, type='str' ), # R* S*223 overrides=dict(required=False, type='dict'), # R S224 count=dict(required=False, type='int' ), # R225 task=dict(required=False, type='str' ), # P*226 container_instances=dict(required=False, type='list'), # S*227 started_by=dict(required=False, type='str' ) # R S228 ))229 module = AnsibleModule(argument_spec=argument_spec, supports_check_mode=True)230 # Validate Requirements231 if not HAS_BOTO:232 module.fail_json(msg='boto is required.')233 if not HAS_BOTO3:234 module.fail_json(msg='boto3 is required.')235 # Validate Inputs236 if module.params['operation'] == 'run':237 if not 'task_definition' in module.params and module.params['task_definition'] is None:238 module.fail_json(msg="To run a task, a task_definition must be specified")239 task_to_list = module.params['task_definition']240 status_type = "RUNNING"241 if module.params['operation'] == 'start':242 if not 'task_definition' in module.params and module.params['task_definition'] is None:243 module.fail_json(msg="To start a task, a task_definition must be specified")244 if not 'container_instances' in module.params and module.params['container_instances'] is None:245 module.fail_json(msg="To start a task, container instances must be specified")246 task_to_list = module.params['task']247 status_type = "RUNNING"248 if module.params['operation'] == 'stop':249 if not 'task' in module.params and module.params['task'] is None:250 module.fail_json(msg="To stop a task, a task must be specified")251 if not 'task_definition' in module.params and module.params['task_definition'] is None:252 module.fail_json(msg="To stop a task, a task definition must be specified")253 task_to_list = module.params['task_definition']254 status_type = "STOPPED"255 service_mgr = EcsExecManager(module)256 existing = service_mgr.list_tasks(module.params['cluster'], task_to_list, status_type)257 results = dict(changed=False)258 if module.params['operation'] == 'run':259 if existing:260 # TBD - validate the rest of the details261 results['task']=existing262 else:263 if not module.check_mode:264 results['task'] = service_mgr.run_task(265 module.params['cluster'],266 module.params['task_definition'],267 module.params['overrides'],268 module.params['count'],269 module.params['started_by'])270 results['changed'] = True271 elif module.params['operation'] == 'start':272 if existing:273 # TBD - validate the rest of the details274 results['task']=existing275 else:276 if not module.check_mode:277 results['task'] = service_mgr.start_task(278 module.params['cluster'],279 module.params['task_definition'],280 module.params['overrides'],281 module.params['container_instances'],282 module.params['started_by']283 )284 results['changed'] = True285 elif module.params['operation'] == 'stop':286 if existing:287 results['task']=existing288 else:289 if not module.check_mode:290 # it exists, so we should delete it and mark changed.291 # return info about the cluster deleted292 results['task'] = service_mgr.stop_task(293 module.params['cluster'],294 module.params['task']295 )296 results['changed'] = True297 module.exit_json(**results)298if __name__ == '__main__':...

Full Screen

Full Screen

test_tasks.py

Source:test_tasks.py Github

copy

Full Screen

...102 rollout.save()103 rollouts[cls][sigs] = rollout104 rollout_ids[cls][sigs] = rollout.id105 if cls is DelayTask:106 task = create_task(rollout, DelayTask, seconds=15)107 tasks[cls][sigs] = task108 else:109 t1, t2, t3 = [create_task(rollout, DelayTask, seconds=15) for _ in range(3)]110 task = create_task(rollout, cls, [t1, t2, t3])111 tasks[cls][sigs] = t3112 for cls in classes:113 for sigs in signals:114 rollout = rollouts[cls][sigs]115 rollout.rollout_async()116 # Enough time for rollouts to start117 time.sleep(0.5)118 for cls in classes:119 for sigs in signals:120 id = rollout_ids[cls][sigs]121 for sig in sigs:122 self.assertTrue(Rollout._can_signal(id, sig))123 self.assertTrue(Rollout._do_signal(id, sig))124 self.assertTrue(Rollout._is_signalling(id, sig))...

Full Screen

Full Screen

task.spec.js

Source:task.spec.js Github

copy

Full Screen

1import { expect } from 'chai';2import {3 request,4 data,5 seedUsers,6 seedTasks,7 seedProjects,8 db,9 ROUTES,10 login,11} from './config';12//models13import { User, Project, Task } from '../models';14before(async () => {15 await db.connect();16});17after(async () => {18 await db.disconnect();19});20afterEach(async () => {21 await User.deleteMany({});22 await Project.deleteMany({});23 await Task.deleteMany({});24});25describe('task API', () => {26 describe('GET /api/tasks/:task_id', () => {27 const task = data.tasks[0];28 beforeEach(async () => {29 await seedUsers();30 await seedProjects();31 await seedTasks();32 });33 it('should return task when user has access to it', async () => {34 const { username, password } = data.users[2];35 await login(username, password);36 const res = await request.get(`${ROUTES.TASK.ROOT}/${task._id}`);37 expect(res.body.task._id).to.equal(task._id);38 });39 it('should not return task when user does not have access to it', async () => {40 const { username, password } = data.users[0];41 await login(username, password);42 const res = await request.get(`${ROUTES.TASK.ROOT}/${task._id}`);43 expect(res.body.task).to.not.be.ok;44 });45 it('should not return task when task doesnt exist', async () => {46 const { username, password } = data.users[2];47 await login(username, password);48 const res = await request.get(49 `${ROUTES.TASK.ROOT}/bdbdf88028e375d81dccee42`50 );51 expect(res.body.task).to.not.be.ok;52 });53 });54 describe('PATCH /api/tasks/:task_id', () => {55 const task = data.tasks[0];56 beforeEach(async () => {57 await seedUsers();58 await seedProjects();59 await seedTasks();60 });61 it('should update when user is member and updates are valid', async () => {62 const description = 'New description';63 const isCompleted = true;64 const { username, password } = data.users[2];65 await login(username, password);66 await request67 .patch(`${ROUTES.TASK.ROOT}/${task._id}`)68 .send({ description, isCompleted });69 const $task = await Task.findById(task._id);70 expect($task.description).to.equal(description);71 });72 it('should not update when user is member and updates are not valid', async () => {73 const description = 'New description';74 const milk = 'Invalid';75 const { username, password } = data.users[2];76 await login(username, password);77 await request78 .patch(`${ROUTES.TASK.ROOT}/${task._id}`)79 .send({ description, milk });80 const $task = await Task.findById(task._id);81 expect($task.description).to.not.equal(description);82 });83 it('should not update when user is not a member and updates are valid', async () => {84 const description = 'New description';85 const isCompleted = true;86 const { username, password } = data.users[0];87 await login(username, password);88 await request89 .patch(`${ROUTES.TASK.ROOT}/${task._id}`)90 .send({ description, isCompleted });91 const $task = await Task.findById(task._id);92 expect($task.description).to.not.equal(description);93 });94 it('should return updated task when its updated', async () => {95 const description = 'New description';96 const isCompleted = true;97 const { username, password } = data.users[2];98 await login(username, password);99 const res = await request100 .patch(`${ROUTES.TASK.ROOT}/${task._id}`)101 .send({ description, isCompleted });102 expect(res.body.task.description).to.equal(description);103 });104 });105 describe('DELETE /api/tasks/:task_id', () => {106 beforeEach(async () => {107 await seedUsers();108 await seedProjects();109 await seedTasks();110 });111 it('should delete task when user is a project member', async () => {112 const { username, password } = data.users[1];113 const task = data.tasks[0];114 await login(username, password);115 await request.delete(`${ROUTES.TASK.ROOT}/${task._id}`);116 const $task = await Task.findById(task._id);117 expect($task).to.not.be.ok;118 });119 it('should delete child tasks when parent task is deleted', async () => {120 const { username, password } = data.users[1];121 const taskParent = data.tasks[0];122 const task = data.tasks[1];123 await login(username, password);124 await request.delete(`${ROUTES.TASK.ROOT}/${taskParent._id}`);125 const $task = await Task.findById(task._id);126 expect($task).to.not.be.ok;127 });128 it('should remove task from project tasks when task is deleted', async () => {129 const { username, password } = data.users[1];130 const task = data.tasks[0];131 const project = data.projects[0];132 await login(username, password);133 await request.delete(`${ROUTES.TASK.ROOT}/${task._id}`);134 const $project = await Project.findById(project._id);135 const isTaskIncluded = $project.tasks.includes(task._id);136 expect(isTaskIncluded).to.equal(false);137 });138 it('should remove task from parent task when child task is deleted', async () => {139 const { username, password } = data.users[1];140 const taskParent = data.tasks[0];141 const task = data.tasks[1];142 await login(username, password);143 await request.delete(`${ROUTES.TASK.ROOT}/${task._id}`);144 const $task = await Task.findById(taskParent._id);145 const isTaskIncluded = $task.tasks.includes(task._id);146 expect(isTaskIncluded).to.equal(false);147 });148 it('should not remove task when user is not a project member', async () => {149 const { username, password } = data.users[0];150 const task = data.tasks[0];151 await login(username, password);152 await request.delete(`${ROUTES.TASK.ROOT}/${task._id}`);153 const $task = await Task.findById(task._id);154 expect($task).to.be.ok;155 });156 });...

Full Screen

Full Screen

test_rollout.py

Source:test_rollout.py Github

copy

Full Screen

...12 rollout.save()13 def test_generate_tasks_clears(self):14 class GenTasksRollout(Rollout):15 def _generate_tasks(self):16 create_task(self)17 rollout = GenTasksRollout({})18 rollout.save()19 rollout.generate_tasks()20 self.assertEqual(len(rollout.tasks), 1)21 rollout.generate_tasks()22 self.assertEqual(len(rollout.tasks), 1)23 def test_generate_tasks_after_run(self):24 rollout = Rollout({})25 rollout.save()26 create_task(rollout)27 rollout.rollout()28 self.assertRaises(Exception, rollout.generate_tasks)29 def test_single_task_rollout(self):30 rollout = Rollout({})31 rollout.save()32 root = create_task(rollout)33 rollout.rollout()34 self.assertRun(root)35 self.assertNotReverted(root)36 def test_single_task_rollback(self):37 rollout = Rollout({})38 rollout.save()39 root = create_task(rollout, TestTaskFail)40 rollout.rollout()41 self.assertRun(root)42 self.assertReverted(root)43 def _test_exec_rollout(self, exec_cls):44 rollout = Rollout({})45 rollout.save()46 task1 = create_task(rollout)47 task2 = create_task(rollout)48 task3 = create_task(rollout)49 task4 = create_task(rollout)50 root = create_task(rollout, exec_cls, [task1, task2, task3, task4])51 rollout.rollout()52 # Do not assert parents or root is run since otherwise we'd have to53 # override their call methods54 for task in task1, task2, task3, task4:55 self.assertRun(task)56 self.assertNotReverted(task)57 def _test_exec_rollout_nested(self, exec_cls):58 rollout = Rollout({})59 rollout.save()60 task1 = create_task(rollout)61 task2 = create_task(rollout)62 task3 = create_task(rollout)63 task4 = create_task(rollout)64 parent1 = create_task(rollout, exec_cls, [task1, task2])65 parent2 = create_task(rollout, exec_cls, [task3, task4])66 root = create_task(rollout, exec_cls, [parent1, parent2])67 rollout.rollout()68 # Do not assert parents or root is run since otherwise we'd have to69 # override their call methods70 for task in task1, task2, task3, task4:71 self.assertRun(task)72 self.assertNotReverted(task)73 def test_sequential_exec_rollout(self):74 self._test_exec_rollout(SequentialExecTask)75 def test_parallel_exec_rollout(self):76 self._test_exec_rollout(ParallelExecTask)77 def test_sequential_exec_rollout_nested(self):78 self._test_exec_rollout_nested(SequentialExecTask)79 def test_parallel_exec_rollout_nested(self):80 self._test_exec_rollout_nested(ParallelExecTask)81 def test_sequential_quit_and_rollback_on_failure(self):82 class RecordedRollout(Rollout):83 rollback_calls = []84 def rollback(self):85 self.rollback_calls.append(self)86 super(RecordedRollout, self).rollback()87 rollout = RecordedRollout({})88 rollout.save()89 task1 = create_task(rollout)90 task_error = create_task(rollout, TestTaskFail)91 task2 = create_task(rollout)92 root = create_task(rollout, SequentialExecTask, [task1, task_error, task2])93 rollout.rollout()94 self.assertRun(task1)95 self.assertRun(task_error)96 self.assertNotRun(task2)97 self.assertEqual(RecordedRollout.rollback_calls, [rollout])98 self.assertReverted(task_error)99 self.assertReverted(task1)100 self.assertNotReverted(task2)101 102 def test_monitor_rolls_back(self):103 monitor_wake_event = Event()104 finish_step_event = Event()105 def monitor(monitor_event, abort_event):106 monitor_wake_event.wait()107 abort_event.set()108 finish_step_event.set()109 class MonitoredRollout(Rollout):110 monitors = {111 'mon': monitor,112 }113 rollback_calls = []114 def rollback(self):115 self.rollback_calls.append(self)116 super(MonitoredRollout, self).rollback()117 rollout = MonitoredRollout({'monitors': ['mon']})118 rollout.save()119 def wake_monitor_then_wait():120 monitor_wake_event.set()121 finish_step_event.wait()122 self.assertFalse(MonitoredRollout.rollback_calls)123 class WakeMonitorWaitTask(TestTask):124 @classmethod125 def _run(cls, state, children, abort, term):126 wake_monitor_then_wait()127 task_run = create_task(rollout)128 task_wake_monitor_wait = create_task(rollout, WakeMonitorWaitTask)129 task_not_called = create_task(rollout)130 root = create_task(rollout, SequentialExecTask, [task_run, task_wake_monitor_wait, task_not_called])131 rollout.rollout()132 self.assertRun(task_run)133 self.assertRun(task_wake_monitor_wait)134 self.assertNotRun(task_not_called)135 self.assertEqual(MonitoredRollout.rollback_calls, [rollout])136 self.assertReverted(task_run)...

Full Screen

Full Screen

currentTask.js

Source:currentTask.js Github

copy

Full Screen

1//constants2import NOTIFICATIONS from '../../../constants/notifications';3import { CURRENT_TASK, MODALS } from '../constants';4//actions5import {6 addSuccessNotification,7 addErrorNotification,8} from '../../shared/actions/notifications';9import { startRequest, endRequest } from '../../shared/actions/requests';10import { closeModal } from '../actions/activeModals';11//services12import { getTask, updateTask, deleteTask } from '../services/tasks';13import { createTask } from '../services/projects';14const getCurrentTaskSuccess = (task) => ({15 type: CURRENT_TASK.GET_SUCCESS,16 payload: { task },17});18const getCurrentTaskError = () => ({ type: CURRENT_TASK.GET_ERROR });19const getCurrentTask = (id) => async (dispatch) => {20 dispatch(startRequest(CURRENT_TASK.GET));21 try {22 const { task } = await getTask(id);23 dispatch(getCurrentTaskSuccess(task));24 } catch (err) {25 dispatch(getCurrentTaskError());26 }27 dispatch(endRequest(CURRENT_TASK.GET));28};29const createTaskSuccess = (task) => ({30 type: CURRENT_TASK.CREATE_SUCCESS,31 payload: { task },32});33const _createTask = ({ title, description, projectId, parentTask }) => async (34 dispatch35) => {36 dispatch(startRequest(CURRENT_TASK.CREATE));37 try {38 const { task } = await createTask({39 title,40 description,41 projectId,42 parentTask,43 });44 dispatch(createTaskSuccess(task));45 dispatch(addSuccessNotification(NOTIFICATIONS.TASK.CREATE_SUCCESS));46 } catch {47 dispatch(addErrorNotification(NOTIFICATIONS.TASK.CREATE_ERROR));48 }49 dispatch(endRequest(CURRENT_TASK.CREATE));50 dispatch(closeModal(MODALS.TASK_CREATE));51};52const deleteCurrentTaskSuccess = () => ({53 type: CURRENT_TASK.DELETE_SUCCESS,54});55const deleteCurrentTask = (id) => async (dispatch) => {56 dispatch(startRequest(CURRENT_TASK.DELETE));57 let error = null;58 try {59 await deleteTask(id);60 dispatch(deleteCurrentTaskSuccess());61 dispatch(addSuccessNotification(NOTIFICATIONS.TASK.DELETE_SUCCESS));62 } catch (err) {63 dispatch(addErrorNotification(NOTIFICATIONS.TASK.DELETE_ERROR));64 error = err;65 }66 dispatch(endRequest(CURRENT_TASK.DELETE));67 return error;68};69const updateCurrentTaskSuccess = (task) => ({70 type: CURRENT_TASK.UPDATE_SUCCESS,71 payload: { task },72});73const updateCurrentTask = ({ taskId, updates }) => async (dispatch) => {74 dispatch(startRequest(CURRENT_TASK.UPDATE));75 let error = null;76 try {77 const { task } = await updateTask({ taskId, updates });78 dispatch(updateCurrentTaskSuccess(task));79 dispatch(addSuccessNotification(NOTIFICATIONS.TASK.UPDATE_SUCCESS));80 } catch (err) {81 dispatch(addErrorNotification(NOTIFICATIONS.TASK.UPDATE_ERROR));82 erorr = err;83 }84 dispatch(endRequest(CURRENT_TASK.UPDATE));85 return error;86};87const clearCurrentTask = () => ({88 type: CURRENT_TASK.CLEAR,89});90export {91 getCurrentTask,92 clearCurrentTask,93 _createTask as createTask,94 deleteCurrentTask,95 updateCurrentTask,...

Full Screen

Full Screen

tasks.py

Source:tasks.py Github

copy

Full Screen

1#2# gdb helper commands and functions for Linux kernel debugging3#4# task & thread tools5#6# Copyright (c) Siemens AG, 2011-20137#8# Authors:9# Jan Kiszka <jan.kiszka@siemens.com>10#11# This work is licensed under the terms of the GNU GPL version 2.12#13import gdb14from linux import utils15task_type = utils.CachedType("struct task_struct")16def task_lists():17 task_ptr_type = task_type.get_type().pointer()18 init_task = gdb.parse_and_eval("init_task").address19 t = g = init_task20 while True:21 while True:22 yield t23 t = utils.container_of(t['thread_group']['next'],24 task_ptr_type, "thread_group")25 if t == g:26 break27 t = g = utils.container_of(g['tasks']['next'],28 task_ptr_type, "tasks")29 if t == init_task:30 return31def get_task_by_pid(pid):32 for task in task_lists():33 if int(task['pid']) == pid:34 return task35 return None36class LxTaskByPidFunc(gdb.Function):37 """Find Linux task by PID and return the task_struct variable.38$lx_task_by_pid(PID): Given PID, iterate over all tasks of the target and39return that task_struct variable which PID matches."""40 def __init__(self):41 super(LxTaskByPidFunc, self).__init__("lx_task_by_pid")42 def invoke(self, pid):43 task = get_task_by_pid(pid)44 if task:45 return task.dereference()46 else:47 raise gdb.GdbError("No task of PID " + str(pid))48LxTaskByPidFunc()49class LxPs(gdb.Command):50 """Dump Linux tasks."""51 def __init__(self):52 super(LxPs, self).__init__("lx-ps", gdb.COMMAND_DATA)53 def invoke(self, arg, from_tty):54 for task in task_lists():55 gdb.write("{address} {pid} {comm}\n".format(56 address=task,57 pid=task["pid"],58 comm=task["comm"].string()))59LxPs()60thread_info_type = utils.CachedType("struct thread_info")61ia64_task_size = None62def get_thread_info(task):63 thread_info_ptr_type = thread_info_type.get_type().pointer()64 if utils.is_target_arch("ia64"):65 global ia64_task_size66 if ia64_task_size is None:67 ia64_task_size = gdb.parse_and_eval("sizeof(struct task_struct)")68 thread_info_addr = task.address + ia64_task_size69 thread_info = thread_info_addr.cast(thread_info_ptr_type)70 else:71 thread_info = task['stack'].cast(thread_info_ptr_type)72 return thread_info.dereference()73class LxThreadInfoFunc (gdb.Function):74 """Calculate Linux thread_info from task variable.75$lx_thread_info(TASK): Given TASK, return the corresponding thread_info76variable."""77 def __init__(self):78 super(LxThreadInfoFunc, self).__init__("lx_thread_info")79 def invoke(self, task):80 return get_thread_info(task)...

Full Screen

Full Screen

Using AI Code Generation

copy

Full Screen

1task('test', function() {2 return gulp.src('src/**/*.js')3 .pipe(istanbul())4 .pipe(istanbul.hookRequire())5 .on('finish', function() {6 gulp.src('test/**/*.js')7 .pipe(mocha())8 .pipe(istanbul.writeReports())9 .pipe(istanbul.enforceThresholds({ thresholds: { global: 90 } }));10 });11});12var gulp = require('gulp');13require('stryker-parent')(gulp);14gulp.start('test');15task('test', function() {16 return gulp.src('src/**/*.js')17 .pipe(istanbul())18 .pipe(istanbul.hookRequire())19 .on('finish', function() {20 gulp.src('test/**/*.js')21 .pipe(mocha())22 .pipe(istanbul.writeReports())23 .pipe(istanbul.enforceThresholds({ thresholds: { global: 90 } }));24 });25});26var gulp = require('gulp');27require('stryker-parent')(gulp);28gulp.start('test');29gulp.watch(['src/**/*.js', 'test/**/*.js'], ['test']);30task('test', function() {31 return gulp.src('src/**/*.js')32 .pipe(istanbul())33 .pipe(istanbul.hookRequire())34 .on('finish', function() {35 gulp.src('test/**/*.js')36 .pipe(mocha())37 .pipe(istanbul.writeReports())38 .pipe(istanbul.enforceThresholds({ thresholds: { global: 90 } }));39 });40});

Full Screen

Using AI Code Generation

copy

Full Screen

1var stryker = require('stryker-parent').task;2var stryker = require('stryker').task;3var stryker = require('stryker-typescript').task;4var stryker = require('stryker-typescript').task;5var stryker = require('stryker-babel').task;6var stryker = require('stryker-esnext').task;7var stryker = require('stryker-javascript-mutator').task;8var stryker = require('stryker-javascript-mutator').task;9var stryker = require('stryker-javascript-mutator').task;10var stryker = require('stryker-javascript-mutator').task;11var stryker = require('stryker-javascript-mutator').task;12var stryker = require('stryker-javascript-mutator').task;13var stryker = require('stryker-javascript-mutator').task;14var stryker = require('stryker-javascript-mutator').task;15var stryker = require('stryker-javascript-mutator').task;16var stryker = require('stryker-javascript-mutator').task;17var stryker = require('stryker

Full Screen

Using AI Code Generation

copy

Full Screen

1const task = require('stryker-parent').task;2task('myTask', function () {3});4task('myTask2', function () {5});6task('myTask3', function () {7});8const task = require('stryker-parent').task;9task('myTask', function () {10});11task('myTask2', function () {12});13task('myTask3', function () {14});15const task = require('stryker-parent').task;16task('myTask', function () {17});18task('myTask2', function () {19});20task('myTask3', function () {21});22const task = require('stryker-parent').task;23task('myTask', function () {24});25task('myTask2', function () {26});27task('myTask3', function () {28});29const task = require('stryker-parent').task;30task('myTask', function () {31});32task('myTask2', function () {33});34task('myTask3', function () {35});36const task = require('stryker-parent').task;37task('myTask', function () {38});39task('myTask2', function () {40});41task('myTask3', function () {42});43const task = require('stryker-parent').task;44task('myTask', function () {45});46task('myTask2', function () {47});48task('myTask3', function () {49});50const task = require('stryker-parent').task;51task('myTask', function () {52});53task('myTask2

Full Screen

Using AI Code Generation

copy

Full Screen

1task('test', function() {2 return gulp.src('test.js')3 .pipe(gulpMocha());4});5var gulp = require('gulp');6var gulpMocha = require('gulp-mocha');7gulp.task('test', function() {8 return gulp.src('test.js')9 .pipe(gulpMocha());10});11var gulp = require('gulp');12var gulpMocha = require('gulp-mocha');13function test() {14 return gulp.src('test.js')15 .pipe(gulpMocha());16}17module.exports = {18};19var strykerParent = require('stryker-parent');20strykerParent.test();21var gulp = require('gulp');22var gulpMocha = require('gulp-mocha');23function test() {24 return gulp.src('test.js')25 .pipe(gulpMocha());26}27module.exports = {28};29var strykerParent = require('stryker-parent');30strykerParent.test();31var gulp = require('gulp');32var gulpMocha = require('gulp-mocha');33function test() {34 return gulp.src('test.js')35 .pipe(gulpMocha());36}37module.exports = {38};39var strykerParent = require('stryker-parent');40strykerParent.test();41var gulp = require('gulp');42var gulpMocha = require('gulp-mocha');43function test() {44 return gulp.src('test.js')45 .pipe(gulpMocha());46}47module.exports = {48};49var strykerParent = require('stryker-parent');50strykerParent.test();51var gulp = require('gulp');52var gulpMocha = require('gulp-mocha');53function test() {54 return gulp.src('test.js')55 .pipe(gulpMocha());56}57module.exports = {

Full Screen

Using AI Code Generation

copy

Full Screen

1task('default', function() {2 console.log('Default task');3});4task('default', function() {5 console.log('Default task');6});7gulp.task('default', function() {8 console.log('Default task');9});10gulp.task('default', function() {11 console.log('Default task');12});

Full Screen

Using AI Code Generation

copy

Full Screen

1var task = require('stryker/lib/utils/taskRunner').task;2task('test', function () {3 return gulp.src(['src/**/*.js', 'test/**/*.js'])4 .pipe(mocha());5});6task('default', ['test']);7var task = require('stryker-parent').task;8task('test', function () {9 return gulp.src(['src/**/*.js', 'test/**/*.js'])10 .pipe(mocha());11});12task('default', ['test']);13var task = require('stryker-parent').task;14task('test', function () {15 return gulp.src(['src/**/*.js', 'test/**/*.js'])16 .pipe(mocha());17});18task('default', ['test']);19var task = require('stryker-parent').task;20task('test', function () {21 return gulp.src(['src/**/*.js', 'test/**/*.js'])22 .pipe(mocha());23});24task('default', ['test']);25var task = require('stryker-parent').task;26task('test', function () {27 return gulp.src(['src/**/*.js', 'test/**/*.js'])28 .pipe(mocha());29});30task('default', ['test']);

Full Screen

Using AI Code Generation

copy

Full Screen

1task('stryker', function() {2 return gulp.src('stryker.conf.js')3 .pipe(stryker({ reporters: ['progress', 'clear-text', 'dots', 'html'] }));4});5task('stryker', function() {6 return gulp.src('stryker.conf.js')7 .pipe(stryker({ reporters: ['progress', 'clear-text', 'dots', 'html'] }));8});9MIT © [Sander Koenders](

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run stryker-parent automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful