BP-Base
BP-Base is the common base language for all Provengo languages. Commands and constructs listed here are available throughout the system. Other Provengo languages build on this one, in the same way high-level programming languages (e.g. Java and Python) are built on top of lower-level ones (e.g. Assembly or C).
Use this language to create the higher-resolutions parts of your model, and to coordinate between model parts, especially when these are written in different languages. For larger model parts, or for parts that fit common conceptual models such as user stories or state machines, consider working with one of Provengo’s higher-level DSLs.
There is no need to import this language in order to use it - it’s always there for you. |
Provengo Models and Behavioral Programming
At its basic level, a Provengo model consists of b-threads: Threads of simple behaviors that synchronize with each other using events. The Provengo engine interweaves these simple b-threads into complex scenarios. A scenario is a series of events - it can describe desired system behavior or a test scenario.
B-Threads synchronize by calling the sync
method. Using this method, b-threads can request, wait for, and block events. After calling sync
, the b-thread is paused until an event is selected. When all b-threads have called sync
, the engine selects an event that was requested and not blocked. It then resumes b-threads that have requested or waited for the selected event. The rest of the b-threads remain paused. They may or may not resume execution after the next event is selected - depending on what event this will be.
sync has some convenience variants: request(e) is for only requesting event e , waitFor(es) is for waiting for events in the es event set, and block(es) blocks all events in es . These methods and also be used for composing requests - see Core Commands.
|
Events and Event Sets
Scenarios, such as those used for tests and during requirement evaluation, are a series of events. The events themselves are small data objects. Each one has a name, and might also have associated data. Event sets are objects that contain multiple events. They can be composed using methods such as set1.or(set2)
.
An event is also an event set - one that contains only itself. |
The Event
class
The EventSet
class
EventSet(name, predicate)
Creates a new event set, based on predicate
.
name
-
String. Name of the created event set.
predicate
-
Function. Gets an event, should return
true
if the event is a member of the event set, andfalse
otherwise.
Returns: An event set named name
, that uses predicate
to decide event membership.
Properties and Methods
eventSet.name
-
String. The name of the event set.
eventSet.contains(e)
-
Returns
true
if the evente
is a member ofthis
set, andfalse
otherwise. eventSet.or(otherSet)
-
Returns a new event set that contains events that are members of
this
set, or members ofotherSet
. eventSet.and(otherSet)
-
Returns a new event set that contains events that are members of
this
set and members ofotherSet
. eventSet.negate()
-
Returns a new event set that contains all events
this
set does not contain. eventSet.xor(otherSet)
-
Returns a new event set that contains events that are members of
this
set or members ofotherSet
, but not members of both. eventSet.nor(otherSet)
-
Returns a new event set that contains events that are not members of either
this
orotherSet
. eventSet.nand(otherSet)
-
Returns a new event set that contains events that are not members of both
this
andotherSet
.
EventSets
EventSets.all
-
An event set that contains all events.
EventSets.none
-
An event set that does not contain any event.
EventSets.not(es)
-
An event set containing all events that are not members of
es
. EventSets.anyOf(es1, es2, es3…)
-
An event set that contains
es1
,es2
, andes3
. Similar toes1.or(es2).or(es3)
. EventSets.allOf(es1, es2, es3…)
-
An event set that is the conjunction of
es1
,es2
, andes3
(so, contains only events that are ines1
andes2
ANDes3
). Similar toes1.and(es2).and(es3)
.
Core Commands
Commands marked with sync contain a Synchronization Point. |
bthread(name, data, body)
Adds a new b-thread to the specification. The optional data field allows passing information to the newly-created bthread.
name
-
String. The name of new b-thread.
data
-
Optional. Object. Initial data field for the new b-thread. Can be used to send data for the b-thread, so the b-thread can read it when it starts.
body
-
Function. The body of new b-thread. Does not take any parameters.
Returns: Nothing
request(evt, fn)
When fn
is present, executes it, and adds a request for evt
on each synchronization point.
When fn
is missing, requests evt
.
If evt
is an array of events, the system is free to select any one of them that’s not blocked. This allows splitting a scenario to multiple ones. For example, in a use-case scenario where a customer needs to select one of three products, the bthread modeling it can request selection events for these products. At the point of the request, the test will be split into 3 test scenarios, one for each possible selection.
When fn is missing, this a convenient version of sync({request:evt}) .
|
evt
-
Event/Event Array. The event to request, either immediately or as an addition to synchronization
fn
makes. fn
-
Optional. Function. If present, executed as usual, except that in any synchronization it issues, it also requests for
evt
.fn
does not take any parameters.
Returns: If fn
is present, returns its result. Otherwise, returns the event selected during synchronization.
waitFor(evtSet, fn)
When fn
is missing, waits for events in evtSet
. When fn
is present, executes it, and adds a wait-for evtSet
at each synchronization point fn
makes.
evtSet
-
An event set. The event set to wait for, either immediately or as an addition to synchronizations
fn
makes. fn
-
Optional. Function. If present, executed as usual, except that in any synchronization it issues, it also waits for
evtSet
.
Returns: If fn
is present, returns its result. Otherwise, returns the event selected during synchronization. fn
does not take any parameters.
When fn is missing, this a convenient version of sync({waitFor:evt}) .
|
block(evtSet, fn)
When fn
is missing, blocks events in evtSet
. When fn
is present, executes it while blocking events in evtSet
.
evtSet
-
An event set. The event set to block.
fn
-
Optional. Function. If present, executed as usual, while blocking events in
evtSet
.fn
does not take any parameters.
Returns: If fn
is present, returns its result. Otherwise, returns the event selected during synchronization. Note that when not nested in any request
or waitFor
, it does not return, and the block stays for the remainder of the run.
When fn is missing, this a convenient version of sync({block:evt}) .
|
sync(statement, data, hot)
Enters a synchronization point, based on the passed synchronization statement and any parent request
, waitFor
, block
, and interrupt
. All parameters are optional - it can also be used as sync()
, in which case the statement contains only components from parent elements.
stmt
-
Synchronization statement: A synchronization statement for this point
data
-
Additional data that can be added to the synchronization point.
hot
-
Boolean, defaults to
false
. Whentrue
, marks this synchronization point as hot, meaning that the b-thread must advance beyond this point.
Returns: The selected event
Extended Commands
choiceEvent(value)
An event selected when a call to choose(value, otherValue, …)
selects value
.
value
-
Object. The value that was chosen by
choose()
.
choose(v1, v2, v3… / valueArray)
Choose one of the values passed. The choice is announced by a choiceEvent(value)
.
v1, v2, v3…`
-
Object. Argument list of values to choose from.
valueArray
-
Array of Objects. Lists values to choose from.
Returns: One of the passed values.
chooseSome(v1, v2, v3… / valueArray)
Chooses a sub-set of the passed values. The intermediate choices are announced by choiceEvent(value)
s. In the returned array, element relative order is maintained. So a call to chooseSome(a,b,c)
may return [a,c]
but not [c,a]
.
v1, v2, v3…
-
Object. Argument list of values to choose from.
valueArray
-
Array of Objects. Lists values to choose from.
Returns: An array containing a sub-set of the passed values. May be empty (which is a valid subset).
halt(message)
Reports a requirement violation or breach (formally: safety requirement violation), and stops the model execution. During analysis, halts are shown as red hexagons.
message
-
A (typically short) human-readable text explaining why a scenario had to be halted.
inParallel(f1, f2, f3… / functionArray)
When called from within a b-thread, runs functions f1
…fn
in parallel b-threads. Returns when all functions returned. When called from the the top-level b-program scope, creates a b-thread for each function and returns immediately.
f1, f2, f3…
-
Functions to run in parallel. These functions do not take any parameters, and their return value is ignored.
functionArray
-
An array of functions to be run in parallel.
Returns: Nothing. When called from within a b-thread, returns after all functions completed their execution.
maybe()
Returns true
or false
. Splits the scenario into two sub-scenarios, depending on its return value. This statement request maybeEvent().yes
and maybeEvent().no
, only one of which will be selected in a given scenario.
Returns: true
or false
maybe(v)
Returns true
or false
. The v
parameter describes the choice being made. This description can be used by other b-thread to detect the choice, and by trace post-processing tools (such as the gen-book
sub-command) to tag and filter the generated trace. This statement requests maybeEvent(v).yes
and maybeEvent(v).no
. Of course, only one of these events will be selected.
v
-
String. Describes what may or may not be.
Returns: true
or false
maybeEvent(v)
Returns an object containing events and event sets related to maybe(v)
calls. Can be used to waitFor
and block
calls to maybe
. For example:
bthread("main", function(){
if ( maybe("go") ) {
...
}
});
bthread("addon", function(){
waitFor(maybeEvent("go").yes);
request(Event("Test for Go"))
})
v
-
String. The name of that thing that may or may not be.
Returns: an object with the following fields:
yes
-
The event causing
maybe(v)
to returntrue
. no
-
The event causing
maybe(v)
to returnfalse
. any
-
An event set containing both events above.
on(eventSet, handlerFn)
Registers a new b-thread that executes handlerFn
whenever an event from eventSet
is selected. Stops if handlerFn
returns false
. Returns immediately.
If an event from eventSet is selected while handlerFn is running, a parallel version of handlerFn will not be invoked. To respond to any selection an event in eventSet , have handlerFn create a new bthread and return immediately.
|
eventSet
-
EventSet. The event set to trigger the function on whenever
handlerFn
-
Function. Gets an event, and returns a boolean.
Returns: Nothing.
requestAtAnyOrder(e1, e2, e3… / eventArray)
Requests the passed events in any order (that is, splits the scenario into many scenarios, one for each request order). Returns after the last event has been selected.
e1, e2, e3 …
-
Events. These events will be selected in some order for any given scenario - a scenario will be generated for each possible order. Note that other b-threads might be blocking these events, which may affect the actual choice the system has.
eventArray
-
Array of Events. An alternative way of passing events to this call.
Returns: Nothing, but after the last event was selected.
requestOne(e1, e2, e3… / eventArray)
Requests one of the passed events, or one of the events in the eventArray
array. From a test-space standpoint, this splits the test scenario info multiple scenarios, one for each possible choice.
e1, e2, e3 …
-
Events. One of these will be selected. Note that other b-threads might be blocking these events, which may affect the actual choice the system has.
eventArray
-
Array of Events. An alternative way of passing events to this call.
This method is a convenience wrapper around request(eventArray) .
|
Returns: The selected event.
select(name).from(v1, v2, v3… / valueArray)
Select one of the values passed passed to from
, marking their role as name
. The choice is announced by a selectEvent(name, value)
.
name
-
String. Name of the select event and role of the selected value.
v1, v2, v3…
-
Objects. Argument list of values to choose from.
valueArray
-
Array of Objects. Lists values to choose from.
select(name).any()
Creates an event set containing all selectEvent
s whose name is name
. For example:
// create a selectEvent with "fruit" as a name and either "banana" or "apple" as a value.
select("fruit").from("apple", "banana");
// (in another b-thread)
// wait for any of the events above
const chosenFruit = waitFor( select("fruit").any() ).data.value;
name
-
String. Name of the select event and role of the selected value.
Returns: Event set that will match select events with the name: name
selectEvent(name, value)
An event announcing that a call to select(name).from(value, anotherValue,…)
resulted in value
being selected.
name
-
String. Role / semantics of the selected value.
value
-
Object. The value selected for role
name
.
selectSome(name).from(v1, v2, v3… / valueArray)
Select a sub-set of the values passed to from
, marking their role as name
. The intermediate choices are announced by selectEvent(value)
s.
In the returned array maintains relative values order, so a call to selectSome("letters").from("a","b","c")
may return ["a","c"]
but not ["c","a"]
.
name
-
name of the select event and role of the selected values.
v1, v2, v3…
-
Object. Argument list of values to choose from.
valueArray
-
Array of Objects. Lists values to choose from.
Returns: An array containing a sub-set of the values passed to from
. May be empty (which is a valid subset).
waitForAll(es1, es2, es3… / eventSetArray)
Waits for all the passed events, regardless of the order they appear in. Returns after events from all event sets were selected. Note that a single event may be a member of more than a single event set.
es1, es2, es3 …
-
Event sets. These events sets will be waited for.
eventSetArray
-
Array of Event sets. An alternative way of passing event sets to this call.
Returns: The last event that was selected.
Extended Events and Event Sets
any(filterData)
Creates an event set based on filterData
.
filterData
-
-
When
filterData
is a String, returns an event set that contains all events whose name isfilterData
. -
When
filterData
is a regular expression, returns an event set that contains all events whose name matchesfilterData
. -
When
filterData
is an object, returns an event set that contains all events whose data object existing fields match the field values infilterData
.
-
Returns: an event set based on filterData
choiceEvent(value)
Creates an event describing value
being selected by choose()
(see below).
value
-
Object. The selected value.
Returns: The event that marks value
being selected as a result of calling choose()
.
selectEvent(name, value)
Creates a selection event, describing value
being selected as a name
. For example, if we want to choose a car type,
an appropriate selection event might be selectEvent("carType", "DeLorian")
.
name
-
String. Describes the purpose/role of the selected value.
value
-
Object. The selected value itself.
Utility Calls
getEnv(name)
Returns the environment variable with with the passed name.
name
-
String. Name of environment variable
Returns: Value of environment variable.
isInBThread()
Checks whether the current code is running in a b-thread or not.
Returns: true
if the code runs in a b-thread, false
otherwise.
isEvent(e)
Checks whether e
is an event or not.
e
-
The object we test for being an event.
Returns: true
if e
is an event, false
otherwise.
isEventSet(e)
Checks whether e
is an event or not.
An event is an event set (containing itself only). So isEventSet(anEvent) returns true .
|
e
-
The object we test for being an event.
Returns: true
if e
is an event, false
otherwise.
pair(arrayA, arrayB)
Create new Array<Array<EventSet>> that represent a Cartesian product of this 2 arrays.
let arrayA = [1, 2];
let arrayB = [A, B];
let ABpair = pair(arrayA, arrayB);
// [ [1, A], [1, B], [2, A], [2, B] ];
This function is for ensemble command with goals algorithm. |
arrayA
-
EventSet array
arrayB
-
EventSet array
Returns: Array<Array<EventSet>>
, Cartesian product of arrayA and arrayB