Commit 99977ccd authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent decaff6f
......@@ -17,7 +17,7 @@
// See COPYING file for full licensing terms.
// See https://www.nexedi.com/licensing for rationale and options.
// XXX explain
// Package tracetest_test demonstrates how to use package tracetest.
package tracetest_test
//go:generate gotrace gen .
......@@ -49,72 +49,70 @@ func hello(who string) {
// TestTracetestExample demonstrates how to use tracetest to verify concurrent system with 2 threads.
func TestTracetestExample(t *testing.T) {
tracetest.Verify(t, testTracetestExample)
}
func testTracetestExample(t *tracetest.T) {
type eventHi string
type eventHello string
testf := func(t *tracetest.T) {
// setup tracing to deliver trace events to t XXX not to t, but to something dedicated?
pg := &tracing.ProbeGroup{}
tracing.Lock()
traceHi_Attach(pg, func(who string) {
// XXX NewEvent? IncomingEvent?
t.RxEvent(eventHi(who)) // XXX -> t.OnEvent? not via t?
})
traceHello_Attach(pg, func(who string) {
t.RxEvent(eventHello(who))
})
tracing.Unlock()
defer pg.Done()
// tell tracetest to which stream an event should go.
t.SetEventRouter(func(event interface{}) (stream string) {
// it can be only eventHi and eventHello.
// in this test the convention is that who comes as <threadID>·...
// we used threadID as stream.
who := ""
switch ev := event.(type) {
default:
panic(fmt.Sprintf("unexpected event type %T", event))
case eventHi:
who = string(ev)
case eventHello:
who = string(ev)
}
i := strings.Index(who, "·")
if i == -1 {
panic(fmt.Sprintf("who does not have threadID: %q", who))
}
return strings.ToLower(who[:i])
})
// run the workload
var wg sync.WaitGroup
defer wg.Wait()
wg.Add(2)
go func() { // thread1
defer wg.Done()
hi("T1·A")
hello("T1·B")
}()
go func() { // thread2
defer wg.Done()
hi("T2·C")
}()
// assert that events come as expected
t.Expect("t2", eventHi("T2·C"))
t.Expect("t1", eventHi("T1·A"))
t.Expect("t1", eventHello("T1·B"))
// XXX also t.Recv, t.ExpectNoAck ?
//t1 := t.OnStream("t1")
//t1.Expect(eventHi("X·A"))
}
tracetest.Verify(t, testf)
// setup tracing to deliver trace events to t.
pg := &tracing.ProbeGroup{}
tracing.Lock()
traceHi_Attach(pg, func(who string) {
t.RxEvent(eventHi(who))
})
traceHello_Attach(pg, func(who string) {
t.RxEvent(eventHello(who))
})
tracing.Unlock()
defer pg.Done()
// tell tracetest to which stream an event should go.
t.SetEventRouter(func(event interface{}) (stream string) {
// it can be only eventHi and eventHello.
// in this test the convention is that who comes as <threadID>·...
// we used threadID as stream.
who := ""
switch ev := event.(type) {
default:
panic(fmt.Sprintf("unexpected event type %T", event))
case eventHi:
who = string(ev)
case eventHello:
who = string(ev)
}
i := strings.Index(who, "·")
if i == -1 {
panic(fmt.Sprintf("who does not have threadID: %q", who))
}
return strings.ToLower(who[:i])
})
// run the workload
var wg sync.WaitGroup
defer wg.Wait()
wg.Add(2)
go func() { // thread1
defer wg.Done()
hi("T1·A")
hello("T1·B")
}()
go func() { // thread2
defer wg.Done()
hi("T2·C")
}()
// assert that events come as expected
t.Expect("t2", eventHi("T2·C"))
t.Expect("t1", eventHi("T1·A"))
t.Expect("t1", eventHello("T1·B"))
// XXX also t.Recv, t.ExpectNoAck ?
//t1 := t.OnStream("t1")
//t1.Expect(eventHi("X·A"))
}
......@@ -44,7 +44,7 @@
// causality (i.e. there is some happens-before relation for them) the
// sequence of checking should represent that ordering relation.
//
// The package should be used as follows:
// The package should be used as follows: XXX rework
//
// XXX tracer -> trace collector?
// - implement tracer that will be synchronously collecting events from
......@@ -528,6 +528,8 @@ func (t *T) SetEventRouter(routeEvent func(event interface{}) (stream string)) {
}
// XXX doc; naming
// XXX NewEvent? IncomingEvent? OnEvent?
// XXX pass events in not via t (via something dedicated)?
func (t *T) RxEvent(event interface{}) {
t0 := time.Now()
stream := "default"
......@@ -603,6 +605,7 @@ func (t *T) Expect(stream string, eventOK interface{}) {
// XXX ExpectNoACK
// XXX Recv
// XXX Select? (e.g. Select("a", "b") to fetch from either "a" or "b")
// expect1 receives next event on stream and verifies it to be equal to eventOK (both type and value).
//
......@@ -798,6 +801,17 @@ func Verify(t testing.TB, f func(t *T)) {
f(tT)
/*
// now verify f with injected delays.
trace0 := tT.tracev
// sort trace0 by time just in case - events migth come from multiple
// CPUs simultaneously, and so for close events they might be added to
// tracev not in time order.
sort.Slice(trace0, func(i, j int) bool {
return trace0[i].t.Before(trace[j].t)
}
*/
// XXX in the end: verify that streams are the same from run to run (if completed successfully).
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment