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

Event(name, data)

Creates an event whose name is name, and whose data field is data.

name

String. Name of the new event.

data

Optional. Object. The data field of the event.

Properties and Methods

event.name

String. The name of the event.

event.data

Object. The data field of the event. May be null.

All methods from EventSet.

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, and false 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 event e is a member of this set, and false otherwise.

eventSet.or(otherSet)

Returns a new event set that contains events that are members of this set, or members of otherSet.

eventSet.and(otherSet)

Returns a new event set that contains events that are members of this set and members of otherSet.

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 of otherSet, but not members of both.

eventSet.nor(otherSet)

Returns a new event set that contains events that are not members of either this or otherSet.

eventSet.nand(otherSet)

Returns a new event set that contains events that are not members of both this and otherSet.

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, and es3. Similar to es1.or(es2).or(es3).

EventSets.allOf(es1, es2, es3…​)

An event set that is the conjunction of es1, es2, and es3 (so, contains only events that are in es1 and es2 AND es3). Similar to es1.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. When true, marks this synchronization point as hot, meaning that the b-thread must advance beyond this point.

Returns: The selected event

interrupt(evtSet, fn)

Executes fn. During execution, terminates the b-thread if any event contained in evtSet is selected.

evtSet

Members of this event set will terminate the b-thread while fn is executing.

fn

The function to execute. Does not take any parameters.

Returns: The result of fn().

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 return true.

no

The event causing maybe(v) to return false.

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 selectEvents 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 is filterData.

  • When filterData is a regular expression, returns an event set that contains all events whose name matches filterData.

  • When filterData is an object, returns an event set that contains all events whose data object existing fields match the field values in filterData.

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