Documentation ¶
Overview ¶
Package tracetest provides infrastructure for testing concurrent systems based on synchronous event tracing.
A serial system can be verified by checking that its execution produces expected serial stream of events. But concurrent systems cannot be verified by exactly this way because events are only partly-ordered with respect to each other by causality or so called happens-before relation.
However in a concurrent system one can decompose all events into serial streams in which events should be strictly ordered by causality with respect to each other. This decomposition in turn allows to verify that in every stream events happenned as expected.
Verification of events for all streams can be done by one *sequential* process:
if events A and B in different streams are unrelated to each other by causality, the sequence of checks models a particular possible flow of time. Notably since events are delivered synchronously and sender is blocked until receiver/checker explicitly confirms event has been processed, by checking either A then B, or B then A allows to check for a particular race-condition.
if events A and B in different streams are related to each other by causality (i.e. there is some happens-before relation for them) the sequence of checking should represent that ordering relation.
Basic package usage is as follows:
func TestSomething(t *testing.T) { tracetest.Verify(t, func(t *tracetest.T) { // setup tracing so that events of test system are collected and // synchronously delivered to t.RxEvent. This can be done with e.g. // package lab.nexedi.com/kirr/go123/tracing or by other similar means. ... // tell t to which stream an event should go. t.SetEventRouter(...) // run the system and verify it produces expected events // <code to start the system> t.Expect("<stream₁>", eventOk₁) t.Expect("<stream₂>", eventOk₂) ... // <code to further control/affect the system> t.Expect("<stream₃>", eventOk₃) t.Expect("<stream₄>", eventOk₄) ... }) }
See example_test.go for more details.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type T ¶
type T struct {
// contains filtered or unexported fields
}
T is similar to testing.T and represents tracetest test environment.
It is passed by Verify and Run to tested function.
Besides testing.TB it provides
.RxEvent -- to where events should be synchronously delivered by the test .SetEventRouter -- to tell T to which stream an event should go .Expect -- to assert expectation of an event on a stream
func (*T) Expect ¶
Expect receives next event on stream and verifies it to be equal to eventOK.
If check is successful ACK is sent back to event producer. If check does not pass - fatal testing error is raised.
func (*T) FailNow ¶
func (t *T) FailNow()
T overrides FailNow/Fatal/Fatalf to also cancel all in-progress sends.
func (*T) RxEvent ¶
func (t *T) RxEvent(event interface{})
RxEvent should be synchronously called from test system when an event occurs.
The sequential process of the test system where event originated should be paused until RxEvent returns. This requirement can be usually met via inserting t.RxEvent() call into the code that produces the event.
func (*T) SetEventRouter ¶
SetEventRouter tells t to which stream an event should go.
It should be called not more than once. Before SetEventRouter is called, all events go to "default" stream.