QTools  8.0.1
Collection of Host-Based Tools
Loading...
Searching...
No Matches
qutest_dsl.py
Go to the documentation of this file.
1#=============================================================================
2# QUTest Python scripting support
3# Copyright (C) 2005 Quantum Leaps, LLC. All rights reserved.
4#
5# SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-QL-commercial
6#
7# This software is dual-licensed under the terms of the open source GNU
8# General Public License version 3 (or any later version), or alternatively,
9# under the terms of one of the closed source Quantum Leaps commercial
10# licenses.
11#
12# The terms of the open source GNU General Public License version 3
13# can be found at: <www.gnu.org/licenses/gpl-3.0>
14#
15# The terms of the closed source Quantum Leaps commercial licenses
16# can be found at: <www.state-machine.com/licensing>
17#
18# Redistributions in source code must retain this top-level comment block.
19# Plagiarizing this software to sidestep the license obligations is illegal.
20#
21# Contact information:
22# <www.state-machine.com>
23# <info@state-machine.com>
24#=============================================================================
25##
26# @date Last updated on: 2024-06-13
27# @version Last updated for version: 7.4.0
28#
29# @file
30# @brief QUTest Python scripting support (documentation)
31
32## @brief current version of the Python QUTest interface
33VERSION = 740
34
35## @brief include python code in a test script
36# @par Description
37# This @ref qutest_dsl-preamble "preamble command" includes python code
38# in a specified file into the test script. The included file can contain
39# any code that you would put into test scripts (see Example below).
40#
41# @param[in] fname name of the file to include. May contain a path
42# **relative** to the test script.
43#
44# @par Usage
45# @code{py}
46# include("test_include.pyi") # file in the same directory as the script
47# ~ ~ ~
48# include("../my_include/test_include.pyi") # relative directory
49# @endcode
50#
51# __Example__<br>
52# file to be included:<br>
53# @include inc_file.py
54#
55# test script calling `include()`:<br>
56# @include inc_test.py
57#
58def include(fname):
59
60## @brief get the test file name with path
61# @par Description
62# This command returns a string containing the file name of the currently
63# executed test script ("test group").
64#
65# @par Usage
66# @code{py}
67# file_name = test_file()
68# @endcode
70
71## @brief get the test directory (relative to the current directory)
72# @par Description
73# This @ref qutest_complex "complex command" returns a string containing
74# the directory name of the currently executed test script ("test group").
75#
76# @par Usage
77# @code{py}
78# dir_name = test_dir()
79# @endcode
81
82## @brief start a new test
83# @par Description
84# This @ref qutest_complex "complex command" starts a new test
85# and gives it a name.
86#
87# @param[in] title title of the test
88# @param[in] opt options {0=default, NORESET}
89#
90# @par Usage
91# @code{py}
92# test("my first test") # test with title and with full target reset
93# ~ ~ ~
94# test("my second test", NORESET) # test without target reset
95# ~ ~ ~
96# @endcode
97#
98# @sa skip() @ref scenario() "\@scenario()"
99#
100def test(title, opt=0):
101
102## @brief skip the tests following this command.
103#
104# @param[in] nTests number of tests to skip (default-all remaining tests)
105# e.g., skip(1) will skip one test following this command.
106# @note
107# The skipped tests are not executed, but they **are** checked for syntax
108# errors, such as commands and parameters coded in the skipped tests.
109#
110# @par Usage
111# @code{py}
112# test("my first test")
113# ~ ~ ~
114# skip(1) # skip one subsequent test
115# test("my second test")
116# ~ ~ ~
117# skip() # skip all subsequent tests
118# test("my second test")
119# ~ ~ ~
120# @endcode
121#
122# @sa
123# test()
124#
125def skip(nTests=9999):
126
127## @brief start a new BDD-style scenario (alternative #1)
128# @par Description
129# This function that starts a new BDD-style scenario.
130#
131# @param[in] title title of the scenario
132# @param[in] opt options {0=default, NORESET}
133#
134# The `SCENARIO()` command outputs the provided `title` (text) to the
135# QUTest output (text/log) and the QSPY output (text/log), adding the prefix
136#
137# @par Usage
138# @code{py}
139# SCENARIO("extened->basic->extended") # <=====
140# GIVEN("basic thread priorities: 4,0,0")
141# . . .
142# AND("extended thread priorities: 1,5,0")
143# . . .
144#
145# WHEN("post TEST0_SIG->thrX[0]")
146# . . .
147# THEN("Extpect the following preemptions")
148# . . .
149# @endcode
150#
151# @sa
152# - @ref qutest_dsl::GIVEN() "GIVEN()"
153# - @ref qutest_dsl::WHEN() "WHEN()"
154# - @ref qutest_dsl::THEN() "THEN()"
155# - @ref qutest_dsl::AND() "AND()"
156#
157def SCENARIO(self, title="", opt=0):
158
159## @brief start the "given" section of a BDD-style scenario (alternative #1)
160# @par Description
161# This function defines the "given" section of a BDD-scenario. The `GIVEN()`
162# section typically sets up the context for the "given-when-then"
163# sequence. Therefore, a `GIVEN()` section should follow
164# @ref qutest_dsl::SCENARIO() "SCENARIO()".
165#
166# @param[in] msg optional "given" message
167# @param[in] dest optional destination of the message (both screen and QSPY)
168#
169# @par Usage
170# @code{py}
171# SCENARIO("extened->basic->extended")
172# GIVEN("basic thread priorities: 4,0,0") # <=====
173# . . .
174# AND("extended thread priorities: 1,5,0")
175# . . .
176#
177# WHEN("post TEST0_SIG->thrX[0]")
178# . . .
179# THEN("Extpect the following preemptions")
180# . . .
181# @endcode
182#
183# @sa
184# - @ref qutest_dsl::SCENARIO() "SCENARIO()"
185# - @ref qutest_dsl::WHEN() "WHEN()"
186# - @ref qutest_dsl::THEN() "THEN()"
187# - @ref qutest_dsl::AND() "AND()"
188#
189def GIVEN(self, msg="", dest=0x3):
190
191## @brief start the "when" section of a BDD-style scenario (alternative #1)
192# @par Description
193# This function that defines the "when" section of a BDD-scenario. The commands
194# in this section typically include the @ref qutest_dsl::command() "command()"
195# or @ref qutest_dsl::post() "post()" command. The `WHEN()` section should follow
196# the @ref qutest_dsl::GIVEN() "GIVEN()" section.
197#
198# @param[in] msg optional "when" message
199# @param[in] dest optional destination of the message (both screen and QSPY)
200#
201# @par Usage
202# @code{py}
203# SCENARIO("extened->basic->extended")
204# GIVEN("basic thread priorities: 4,0,0")
205# . . .
206# AND("extended thread priorities: 1,5,0")
207# . . .
208#
209# WHEN("post TEST0_SIG->thrX[0]") # <=====
210# . . .
211# THEN("Extpect the following preemptions")
212# . . .
213# @endcode
214#
215# @sa
216# - @ref qutest_dsl::SCENARIO() "SCENARIO()"
217# - @ref qutest_dsl::GIVEN() "GIVEN()"
218# - @ref qutest_dsl::THEN() "THEN()"
219# - @ref qutest_dsl::AND() "AND()"
220#
221def WHEN(self, msg="", dest=0x3):
222
223## @brief start the "then" section of a BDD-style scenario (alternative #1)
224# @par Description
225# This function that defines the "then" section of a BDD-scenario. The commands
226# in this section typically include the @ref qutest_dsl::expect() "expect()"
227# command. The `THEN()` section should follow the
228# @ref qutest_dsl::WHEN() "WHEN()" section.
229#
230# @param[in] msg optional "when" message
231# @param[in] dest optional destination of the message (both screen and QSPY)
232#
233# @par Usage
234# @code{py}
235# SCENARIO("extened->basic->extended")
236# GIVEN("basic thread priorities: 4,0,0")
237# . . .
238# AND("extended thread priorities: 1,5,0")
239# . . .
240#
241# WHEN("post TEST0_SIG->thrX[0]")
242# . . .
243# THEN("Extpect the following preemptions") # <=====
244# . . .
245# @endcode
246#
247# @sa
248# - @ref qutest_dsl::SCENARIO() "SCENARIO()"
249# - @ref qutest_dsl::GIVEN() "GIVEN()"
250# - @ref qutest_dsl::WHEN() "WHEN()"
251# - @ref qutest_dsl::AND() "AND()"
252#
253def THEN(self, msg="", dest=0x3):
254
255## @brief adds the "and" section of a BDD-style scenario (alternative #1)
256# @par Description
257# This function that defines the "and" section of a BDD-scenario.
258# This section can augment the "given" or the "then" sections to better
259# delimit the additional preconditions or additional effects.
260#
261# @param[in] msg optional "when" message
262# @param[in] dest optional destination of the message (both screen and QSPY)
263#
264# @par Usage
265# @code{py}
266# SCENARIO("extened->basic->extended")
267# GIVEN("basic thread priorities: 4,0,0")
268# . . .
269# AND("extended thread priorities: 1,5,0") # <=====
270# . . .
271#
272# WHEN("post TEST0_SIG->thrX[0]")
273# . . .
274# THEN("Extpect the following preemptions")
275# . . .
276# @endcode
277#
278# @sa
279# - @ref qutest_dsl::SCENARIO() "SCENARIO()"
280# - @ref qutest_dsl::GIVEN() "GIVEN()"
281# - @ref qutest_dsl::WHEN() "WHEN()"
282# - @ref qutest_dsl::THEN() "THEN()"
283#
284def AND(self, msg="", dest=0x3):
285
286
287## @brief start a new BDD-style scenario (alternative #2)
288# @par Description
289# This is a Python decorator to a function that starts a new BDD-style scenario.
290#
291# @param[in] title title of the scenario
292# @param[in] opt options {0=default, NORESET}
293#
294# The `@scenario()` decorator outputs the provided `title` (text) to the
295# QUTest output (text/log) and the QSPY output (text/log), adding the prefix
296# "Scenario:" in front.
297#
298# The _decorated function_ must take the:
299#
300# @param[in,out] context execution context
301# (clean context at the start of a scenario)
302#
303# @note
304# The decorated function can have arbitrary name, but the example tests
305# use the name `do()`.
306#
307# @returns
308# The decorated fucntion returs `context` (to let the QUTest system
309# store any modifications to the `context`)
310#
311# @par Usage
312# @code{py}
313# @scenario("my first test") # <=====
314# def do(context):
315# context.x = ...
316# ...
317# return context
318# @endcode
319#
320# @sa
321# - @ref qutest_dsl::given() "\@given()"
322# - @ref qutest_dsl::when() "\@when()"
323# - @ref qutest_dsl::then() "\@then()"
324# - test()
325# - skip()
326#
327def @scenario(title, opt=0):
328
329
330## @brief start the "given" section of a BDD-style scenario (alternative #2)
331# @par Description
332# This is a Python decorator to a function that defines the "given" section.
333# The `@given` section typically sets up the context for the "given-when-then"
334# sequence. Therefore, a `@given` section should follow
335# @ref qutest_dsl::scenario() "\@scenario()" or it might follow the
336# @ref qutest_dsl::then() "\@then()" section to define another "given-when-then"
337# sequence.
338#
339# @param[in] given_msg optional "given" message
340# @param[in] and_msg optional "and" messages
341#
342# The `@given()` command outputs the provided `given_msg` (text) to the
343# QUTest output (text/log) and the QSPY output (text/log), adding the prefix
344# "Given:" in front. Additionally, every subsequent `and_msg` is also output
345# with the prefix "And:".
346#
347# The _decorated function_ must take the:
348#
349# @param[in,out] context execution context
350#
351# @note
352# The decorated function can have arbitrary name, but the example tests
353# use the name `do()`.
354#
355# @returns
356# The decorated fucntion returs `context` (to let the QUTest system
357# store any modifications to the `context`)
358#
359# @par Usage
360# @code{py}
361# @scenario("my first test", NORESET)
362# def do(context):
363# glb_filter(GRP_SC, GRP_UA)
364# current_obj(OBJ_AP, "pspecB")
365# ...
366# context.x = ...
367# ...
368# return context
369#
370# @given("provided that y=123") # <=====
371# def do(context):
372# context.y = 123
373# ...
374# return context
375#
376# @endcode
377#
378# @sa
379# - @ref qutest_dsl::scenario() "\@scenario()"
380# - @ref qutest_dsl::when() "\@when()"
381# - @ref qutest_dsl::then() "\@then()"
382# - test()
383# - skip()
384#
385def @given(given_msg, and_msg, ...):
386
387
388## @brief start the "when" section of a BDD-style scenario (alternative #2)
389# @par Description
390# This is a Python decorator to a function that defines the "when" section.
391# The `@when` section typically executes a @ref qutest_dsl::command() "command()"
392# or @ref qutest_dsl::post() "post()" command. The `@when` section should follow
393# the @ref qutest_dsl::given() "\@given()" section.
394#
395# @param[in] when_msg optional "when" message
396# @param[in] and_msg optional "and" messages
397#
398# The `@when()` command outputs the provided `when_msg` (text) to the
399# QUTest output (text/log) and the QSPY output (text/log), adding the prefix
400# "When:" in front. Additionally, every subsequent `and_msg` is also output
401# with the prefix "And:".
402#
403# The _decorated function_ must take the:
404#
405# @param[in,out] context execution context
406#
407# @note
408# The decorated function can have arbitrary name, but the example tests
409# use the name `do()`.
410#
411# @par Usage
412# @code{py}
413# @scenario("my first test")
414# def do(context):
415# ...
416# return context
417#
418# @given("provided that y=123")
419# def do(context):
420# ...
421# return context
422#
423# @when("provided that y=123") # <=====
424# def do(context):
425# command(1, context.x, context.y)
426# @endcode
427#
428# @sa
429# - @ref qutest_dsl::scenario() "\@scenario()"
430# - @ref qutest_dsl::given() "\@given()"
431# - @ref qutest_dsl::then() "\@then()"
432# - test()
433# - skip()
434#
435def @when(given_msg, and_msg, ...):
436
437## @brief start the "then" section of a BDD-style scenario (alternative #2)
438# @par Description
439# This is a Python decorator to a function that defines the "then" section.
440# The `@then` section typically calls the @ref qutest_dsl::expect() "expect()"
441# commands to verify the expectaion of the "given-when-then" sequence.
442# The `@then` section should follow the @ref qutest_dsl::when() "\@when()"
443# section.
444#
445# @param[in] then_msg optional "then" message
446# @param[in] and_msg optional "and" messages
447#
448# The `@then` command outputs the provided `then_msg` (text) to the
449# QUTest output (text/log) and the QSPY output (text/log), adding the prefix
450# "Then:" in front. Additionally, every subsequent `and_msg` is also output
451# with the prefix "And:".
452#
453# The _decorated function_ must take the:
454#
455# @param[in,out] context execution context
456#
457# @note
458# The decorated function can have arbitrary name, but the example tests
459# use the name `do()`.
460#
461# @par Usage
462# @code{py}
463# @scenario("my first test")
464# def do(context):
465# ...
466# return context
467#
468# @given("provided that y=123")
469# def do(context):
470# ...
471# return context
472#
473# @when("provided that y=123") # <=====
474# def do(context):
475# command(1, context.x, context.y)
476#
477# @then("the following sequence shall happen...") # <=====
478# def do(context):
479# expect(f"... {context.y} ...")
480# expect(f"... {context.x} ...")
481# @endcode
482#
483# @sa
484# - @ref qutest_dsl::scenario() "\@scenario()"
485# - @ref qutest_dsl::given() "\@given()"
486# - @ref qutest_dsl::when() "\@when()"
487# - test()
488# - skip()
489#
490def @then(given_msg, and_msg, ...):
491
492
493## @brief defines an expectation for the current test
494#
495# @par Description
496# This command defines a new expecation for the textual output produced
497# by QSPY.
498#
499# @param[in] match the expected match for the QSPY output
500# The @p match string can contain special characters, such as:
501# `*`, `?` and `[chars]`, which are matched according to the
502# Python command
503# [fnmatch.fnmatchcase()](https://docs.python.org/2/library/fnmatch.html)
504# @note
505# The @p match string can be the
506# [printf-style %-subsitution string](https://docs.python.org/2/library/stdtypes.html#string-formatting-operations)
507# (compatible with Python 2 and Python 3), or the new
508# ["f-string"](https://realpython.com/python-f-strings/)
509# (compatible only with Python 3).
510#
511# @note
512# The special string "@timestamp" (or "%timestamp") at the beginning
513# of the @p match parameter will be automatically replaced with the current
514# numerical value of the test sequence-counter.
515#
516# @par Usage
517# @include expect.py
518#
519def expect(match):
520
521## @brief ensures that the provided Boolean expression is true
522#
523# @par Description
524# This command performs checking of a condition, which is believed to be true
525# in order for a test to pass. If the provided Boolean expression evaluates
526# to false, the test is failed in the usual way.
527#
528# @param[in] bool_expr the Boolean expression to check
529#
530# @par Usage
531# @include ensure.py
532#
533def ensure(bool_expr):
534
535## @brief Send the QS Global Filter to the Target
536#
537# @par Description
538# This @ref qutest_simple "simple command" sends the complete
539# @ref qs_global "QS Global Filter" to the Target.
540# Any existing Global Filter setting inside the Target will be overwritten.
541#
542# @param[in] args list of Record-Type groups or individual Record-Types
543# to set or clear. A given filter-group or an individual filter is set when
544# it is positive, and cleared with it is preceded with the minus (`-`) sign.
545# <br>
546# The filter list can contain the following:
547# @code{py}
548# GRP_ALL # all Record-Types
549# GRP_SM # State Machine Record-Types
550# GRP_AO # Active Object Record-Types
551# GRP_MP # Memory Pool Record-Types
552# GRP_EQ # Event Queue Record-Types
553# GRP_TE # Time Events Record-Types
554# GRP_QF # Framework Record-Types (e.g., post/publish/..)
555# GRP_SC # Scheduler Record-Types (e.g., scheduler lock/unlock)
556# GRP_SEM # Semaphore Record-Types (e.g., Semaphore take/signal)
557# GRP_MTX # Mutex Record-Types (e.g., Mutex lock/unlock)
558# GRP_U0 # User group 0 (Record-Types 100-104)
559# GRP_U1 # User group 1 (Record-Types 105-109)
560# GRP_U2 # User group 2 (Record-Types 110-114)
561# GRP_U3 # User group 3 (Record-Types 115-119)
562# GRP_U4 # User group 0 (Record-Types 120-124)
563# GRP_UA # All user records (Record-Types 100-124)
564# <num> # Specific QS trace Record-Type in the range 0..127
565# @endcode
566#
567# @returns
568# The 128-bit filter bitmask sent to the target. For each enabled filter
569# with the QS record-ID `recID` the bitmask has a '1' in the position
570# (`1 << recID`).
571#
572# @par Usage
573# @include glb_filter.py
574#
575# @sa
576# loc_filter()
577#
578def glb_filter(*args):
579
580## @brief Send the Local Filter to the Target
581#
582# @par Description
583# This @ref qutest_simple "simple command" sends the complete
584# @ref qs_local "QS Local Filter" to the Target.
585# Any existing Local Filter setting inside the Target will be overwritten.
586#
587# @param[in] args list of QS-ID groups or individual QS-IDs to set or clear.
588# A given filter-group or an individual filter is set when it is positive, and
589# cleared with it is preceded with the minus (`-`) sign.<br>
590#
591# This parameter can take one of the following values:
592# @code{py}
593# IDS_ALL # all QS-IDs
594# IDS_AO # Active Object QS-IDs (1..64)
595# IDS_EP # Event Pool QS-IDs (65-80)
596# IDS_EQ # Event Queue QS-IDs (81-96)
597# IDS_AP # Application-Specific QS-IDs (97-127)
598# @endcode
599#
600# @returns
601# The 128-bit filter bitmask sent to the target. For each enabled filter
602# with the QS-ID `qsID` the bitmask has a '1' in the position
603# (`1 << qsID`).
604#
605# @par Usage
606# @include loc_filter.py
607#
608# @sa
609# glb_filter()
610#
611def loc_filter(*args):
612
613## @brief Updates the Local Filter for a given AO in the Target
614#
615# @par Description
616# This @ref qutest_simple "simple command" sets or clears the
617# @ref qs_local "QS Local Filter" corresponding to the given AO in the Target.
618# Unlike loc_filter(), this facility changes **only** the QS-ID
619# (AO's priority) of the given AO in the Target.
620# All other Local Filters will be left unchanged.
621#
622# @param[in] obj_id active object to set/clear the local filter
623# for in the Target<br>
624#
625# This parameter can be either a string (name of the AO) or the AO's priority.
626# Also, it can be either positive (to set) or negative (to clear) the QS
627# local filter.
628#
629# @par Usage
630# @include ao_filter.py
631#
632# @sa
633# loc_filter()
634#
635def ao_filter(obj_id):
636
637## @brief Set the Current-Object in the Target
638#
639# @par Description
640# This @ref qutest_simple "simple command" sets the "current object"
641# in the Target.
642#
643# @param[in] obj_kind Kind of object to set<br>
644#
645# This parameter can take one of the following values:
646# @code{py}
647# OBJ_SM # State Machine object
648# OBJ_AO # Active Object object
649# OBJ_MP # Memory Pool object
650# OBJ_EQ # Event Queue object
651# OBJ_TE # Time Event object
652# OBJ_AP # Application-Specific object
653# OBJ_SM_AO # Both, State Machine and Active Object
654# @endcode
655#
656# @param[in] obj_id Name or addres of the object
657#
658# @par Usage
659# @include current_obj.py
660#
661# @sa
662# - query_curr()
663# - init()
664# - dispatch()
665#
666def current_obj(obj_kind, obj_id):
667
668## @brief query the @ref current_obj() "current object" in the Target
669#
670# @par Description
671# This @ref qutest_complex "complex command" queries the current object
672# in the Target.
673#
674# @param[in] obj_kind Kind of object to query
675#
676# This parameter can take one of the following values:
677# @code{py}
678# OBJ_SM # State Machine object
679# OBJ_AO # Active Object object
680# OBJ_MP # Memory Pool object
681# OBJ_EQ # Event Queue object
682# OBJ_TE # Time Event object
683# @endcode
684#
685# @par Usage
686# The queries for various objects generate the following QS trace records
687# from the Target
688# @code{py}
689# query_curr(OBJ_SM)
690# "@timestamp Query-SM Obj=<obj-name>,State=<state-name>"
691# query_curr(OBJ_AO)
692# "@timestamp Query-AO Obj=<obj-name>,Queue<Free=<n>,Min=<m>>"
693# query_curr(OBJ_EQ)
694# "@timestamp Query-EQ Obj=<obj-name>,Queue<Free=<n>,Min=<m>>"
695# query_curr(OBJ_MP)
696# "@timestamp Query-MP Obj=<obj-name>,Free=<n>,Min=<m>"
697# query_curr(OBJ_TE)
698# "@timestamp Query-TE Obj=<obj-name>,Rate=<r>,Sig=<s>,Tim=<n>,Int=<m>,Flags=<f>"
699# @endcode
700#
701# @sa
702# current_obj()
703#
704def query_curr(obj_kind):
705
706## @brief trigger system clock tick in the Target
707#
708# @par Description
709# This @ref qutest_complex "complex command" triggers the following actions
710# in the Target:<br>
711# 1. If the @ref current_obj() "current TE object" is defined and
712# the TE is armed, the TE is disarmed (if one-shot) and then
713# posted to the recipient AO.
714# 2. The linked-list of all armed Time Events is updated.
715#
716# @param[in] tick_rate the tick rate (0..QF_MAX_TICK_RATE)
717#
718# @par Usage
719# @include tick.py
720#
721# @sa
722# current_obj()
723#
724def tick(tick_rate=0):
725
726## @brief defines expectation for a Test Pause
727#
728# @par Description
729# This is a special expectation that must match the macro
730# QS_TEST_PAUSE() inside the test fixture.
731#
732# @note
733# If QS_TEST_PAUSE() is called before QF_run(), the `expect_pause()`
734# expectation must be placed in the on_reset() callback.
735#
736# @par Usage
737# @include expect_pause.py
738#
739# @sa
740# continue_test()
741#
743
744## @brief defines expectation for calling QF_run()/QF::run()
745#
746# @par Description
747# This is a special expectation for the target calling the QF_run()/QF::run()
748# function.
749#
750# @note
751# This expectation must be placed at the right place in the
752# on_reset() callback.
753#
754# @par Usage
755# @include expect_run.py
756#
757# @sa
758# on_reset()
759#
761
762## @brief sends the CONTINUE packet to the Target to continue a test
763#
764# @par Description
765# This command continues the test after QS_TEST_PAUSE().
766#
767# @par Usage
768# @include continue_test.py
769#
770# @sa
771# expect_pause()
772#
774
775## @brief executes a given command in the Target
776# @par Description
777# This @ref qutest_complex "complex command" causes execution of the
778# @ref QS_rx::QS_onCommand() "QS_onCommand()" callback in the test fixture.
779#
780# @param[in] cmdId the first `cmdId` argument for the
781# @ref QS_rx::QS_onCommand() "QS_onCommand()" callback
782# function in the test fixture.
783# @note
784# The `cmdId` parameter could be either the raw number or a name
785# that is delivered by QS_ENUM_DICTIONARY(enum, group), where the
786# second `group` argument is ::QS_CMD (numerical value 7).
787#
788# @param[in] param1 the "param1" argument to `QS_onCommand()` (optional)
789# @param[in] param2 the "param2" argument to `QS_onCommand()` (optional)
790# @param[in] param3 the "param3" argument to `QS_onCommand()` (optional)
791#
792# @par Usage
793# @include command.py
794#
795def command(cmdId, param1=0, param2=0, param3=0):
796
797## @brief take the top-most initial transition in the
798# current SM object in the Target
799#
800# @par Description
801# This @ref qutest_complex "complex command" takes the top-most initial transition in the
802# @ref current_obj() "current SM object" in the Target.
803#
804# @param[in] signal the event signal of the "initialization event"
805# @param[in] params the parameters of the "initialization event"
806#
807# @par Usage
808# @code{py}
809# init()
810# init("MY_SIG")
811# init("MY_SIG", pack("<B", 2))
812# ~ ~ ~
813# expect("@timestamp Trg-Done QS_RX_EVENT")
814# @endcode
815#
816def init(signal=0, params=None):
817
818## @brief dispatch a given event in the current SM object in the Target
819#
820# @par Description
821# This @ref qutest_complex "complex command" dispatches a given event in the
822# @ref current_obj() "current SM object" in the Target.
823#
824# @param[in] signal the event signal of the event to be dispatched
825# @param[in] params the parameters of the event to be dispatched
826#
827# @par Usage
828# @code{py}
829# dispatch("MY_SIG")
830# dispatch("MY_SIG", pack("<B", 2))
831# ~ ~ ~
832# expect("@timestamp Trg-Done QS_RX_EVENT")
833# @endcode
834#
835def dispatch(signal, params=None):
836
837## @brief post a given event to the current AO object in the Target
838#
839# @par Description
840# This @ref qutest_complex "complex command" posts a given event to the
841# @ref current_obj() "current AO object" in the Target.
842#
843# @param[in] signal the event signal of the event to be posted
844# @param[in] params the parameters of the event to be posted
845#
846# @par Usage
847# @code{py}
848# post("MY_SIG")
849# post("MY_SIG", pack("<B", 2))
850# ~ ~ ~
851# expect("@timestamp Trg-Done QS_RX_EVENT")
852# @endcode
853#
854def post(signal, params=None):
855
856## @brief publish a given event to subscribers in the Target
857#
858# @par Description
859# This @ref qutest_complex "complex command" publishes a given event
860# in the Target.
861#
862# @param[in] signal the event signal of the event to be posted
863# @param[in] params the parameters of the event to be posted
864#
865# @par Usage
866# @code{py}
867# publish("MY_SIG")
868# publish("MY_SIG", pack("<B", 2))
869# ~ ~ ~
870# expect("@timestamp Trg-Done QS_RX_EVENT")
871# @endcode
872#
873def publish(signal, params=None):
874
875## @brief sends a Test-Probe to the Target
876# @par Description
877# This @ref qutest_simple "simple command" sends the Test Probe data
878# to the Target. The Target collects these Test Probes preserving the
879# order in which they were sent. Subsequently, whenever a given API is
880# called inside the Target, it can obtain the Test-Probe by means of the
881# QS_TEST_PROBE_DEF() macro.
882# The QS_TEST_PROBE_DEF() macro returns the Test-Probes in the same
883# order as they were received to the Target. If there are no more Test-
884# Probes for a given API, the Test-Probe is initialized to zero.
885#
886# @param[in] func the name or raw address of a function
887# @param[in] data the data (uint32_t) for the Test-Probe
888#
889# @note
890# All Test-Probes are cleared when the Target resets and also upon the
891# start of a new test, even if this test does not reset the Target
892# (NORESET tests).
893#
894# @par Usage
895# @code{py}
896# probe("myFunction", 123)
897# @endcode
898#
899def probe(func, data):
900
901## @brief peeks data in the Target
902#
903# @par Description
904# This @ref qutest_complex "complex command" peeks data at the given offset
905# from the start address of the current_obj() inside the Target.
906#
907# @param[in] offset offset [in bytes] from the start of the current_obj()
908# @param[in] size size of the data items (1, 2, or 4)
909# @param[in] num number of data items to peek
910#
911# @par Usage
912# @code{py}
913# peek(0, 1, 10)
914# peek(8, 2, 4)
915# peek(4, 4, 2)
916# ~ ~ ~
917# expect("@timestamp Trg-Peek ...")
918# @endcode
919#
920def peek(offset, size, num):
921
922## @brief pokes data into the Target.
923# @par Description
924# This @ref qutest_simple "simple command" pokes provided data at the
925# given offset from the start address of the
926# @ref current_obj() "current AP object" inside the Target.
927#
928# @param[in] offset offset [in bytes] from the start of the current_obj()
929# @param[in] size size of the data items (1, 2, or 4)
930# @param[in] data binary data to send
931#
932# @par Usage
933# @code{py}
934# poke(4,4,pack("<II",0xB4C4D4E4,0xB5C5D5E5))
935# poke(0, 1, bytearray("dec=%d\0", "ascii"))
936# poke(0, 1, bytes("Hello World!\0","ascii"))
937# @endcode
938#
939def poke(offset, size, data):
940
941## @brief fills data into the Target.
942# @par Description
943# This @ref qutest_simple "simple command" fills provided data at the
944# given offset from the start address of the current_obj() inside the Target.
945#
946# @param[in] offset offset [in bytes] from the start of the current_obj()
947# @param[in] size size of the data item (1, 2, or 4)
948# @param[in] num number of data items to fill
949# @param[in] item data item to fill with
950#
951# @par Usage
952# @code{py}
953# fill(0, 1, 100, 0x1A)
954# fill(0, 2, 50, 0x2A2B)
955# fill(0, 4, 25, 0x4A4B4C4D)
956# @endcode
957#
958def fill(offset, size, num, item=0):
959
960## @brief display a note in the QUTest output and in QSPY output.
961# @par Description
962# This command allows the test script to output a note (text) both
963# to the QUTest output (text/log) and the QSPY output (text/log).
964# This command can be also used for commenting the test scripts.
965#
966# @param[in] msg text message
967# @param[in] dest destination (SCREEN, TRACE), default both
968# @par Usage
969# @code{py}
970# note("This is a short note")
971#
972# note('''
973# This test group checks the MPU (Memory Protection Unit)
974# by reading/writing from/to various memory addresses
975# in the target
976# ''', SCREEN)
977# @endcode
978#
979def note(msg, dest=(SCREEN | TRACE)):
980
981## @brief display a tag in the QUTest output and in QSPY output.
982# @par Description
983# This is an alias for the note() command for the BDD-style
984# testing.
985#
986def tag(msg, dest=(SCREEN | TRACE)):
987
988## @brief packs data into binary string to be sent to QSPY.
989# @par Description
990# This command corresponds to Python
991# [struct.pack()](https://docs.python.org/3/library/struct.html).
992# It returns a bytes object containing the values v1, v2,... packed
993# according to the format string @p format. The arguments must match
994# the values required by the
995# [format](https://docs.python.org/3/library/struct.html#format-strings") exactly.
996# The pack() command is typically used inside other QUTest commands
997# to pack the binary event parameters or binary data for poke() and fill().
998#
999# @param[in] format string
1000# @param[in] v1 one or more data elements requried by format
1001# @param[in] v2 one or more data elements requried by format
1002#
1003# @par Usage
1004# @code{py}
1005# dispatch("MY_SIG", pack("<B", 2))
1006# poke(2, 2, pack("<HH", 0xB2C2, 0xD2E2))
1007# @endcode
1008#
1009def pack(format, v1, v2, ...):
1010
1011## @brief returns last record received from the target as string.
1012#
1013# @par Usage
1014# @code{py}
1015# command("COMMAND_B", 123, 23456, 3456789) # generate record (if needed)
1016# expect("@timestamp COMMAND_B *") # expect the record from the target
1017# last = last_rec().split() # <-- obtain the last record and split it
1018# p1 = int(last[2]) # extract the expected parameter p1 (int)
1019# s1 = last[3] # extract the expected string s1
1020# p2 = int(last[4]) # extract the expected parameter p2 (int)
1021# s2 = last[5] # extract the expected string s2
1022# p3 = int(last[6]) # extract the expected parameter p3 (int)
1023# p4 = float(last[7]) # extract the expected parameter p4 (float)
1024# @endcode
1025#
1027
1028## @brief
1029# callback function invoked after each Target reset
1031
1032## @brief
1033# callback function invoked at the beginning of each test
1035
1036## @brief
1037# callback function invoked at the end of each test
post(signal, params=None)
post a given event to the current AO object in the Target
then(given_msg, and_msg)
start the "then" section of a BDD-style scenario (alternative #2)
on_reset()
callback function invoked after each Target reset
tick(tick_rate=0)
trigger system clock tick in the Target
peek(offset, size, num)
peeks data in the Target
when(given_msg, and_msg)
start the "when" section of a BDD-style scenario (alternative #2)
skip(nTests=9999)
skip the tests following this command.
on_teardown()
callback function invoked at the end of each test
init(signal=0, params=None)
take the top-most initial transition in the current SM object in the Target
glb_filter(*args)
Send the QS Global Filter to the Target.
continue_test()
sends the CONTINUE packet to the Target to continue a test
test_dir()
get the test directory (relative to the current directory)
Definition qutest_dsl.py:80
expect_run()
defines expectation for calling QF_run()/QF::run()
fill(offset, size, num, item=0)
fills data into the Target.
probe(func, data)
sends a Test-Probe to the Target
expect(match)
defines an expectation for the current test
command(cmdId, param1=0, param2=0, param3=0)
executes a given command in the Target
SCENARIO(self, title="", opt=0)
start a new BDD-style scenario (alternative #1)
note(msg, dest=(SCREEN|TRACE))
display a note in the QUTest output and in QSPY output.
query_curr(obj_kind)
query the current object in the Target
loc_filter(*args)
Send the Local Filter to the Target.
WHEN(self, msg="", dest=0x3)
start the "when" section of a BDD-style scenario (alternative #1)
THEN(self, msg="", dest=0x3)
start the "then" section of a BDD-style scenario (alternative #1)
tag(msg, dest=(SCREEN|TRACE))
display a tag in the QUTest output and in QSPY output.
given(given_msg, and_msg)
start the "given" section of a BDD-style scenario (alternative #2)
current_obj(obj_kind, obj_id)
Set the Current-Object in the Target.
expect_pause()
defines expectation for a Test Pause
on_setup()
callback function invoked at the beginning of each test
include(fname)
include python code in a test script
Definition qutest_dsl.py:58
test(title, opt=0)
start a new test
poke(offset, size, data)
pokes data into the Target.
test_file()
get the test file name with path
Definition qutest_dsl.py:69
GIVEN(self, msg="", dest=0x3)
start the "given" section of a BDD-style scenario (alternative #1)
pack(format, v1, v2)
packs data into binary string to be sent to QSPY.
scenario(title, opt=0)
start a new BDD-style scenario (alternative #2)
ensure(bool_expr)
ensures that the provided Boolean expression is true
dispatch(signal, params=None)
dispatch a given event in the current SM object in the Target
last_rec()
returns last record received from the target as string.
publish(signal, params=None)
publish a given event to subscribers in the Target
ao_filter(obj_id)
Updates the Local Filter for a given AO in the Target.
AND(self, msg="", dest=0x3)
adds the "and" section of a BDD-style scenario (alternative #1)