Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
N
neo
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Labels
Merge Requests
2
Merge Requests
2
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Jobs
Commits
Open sidebar
Kirill Smelkov
neo
Commits
a676063e
Commit
a676063e
authored
Jan 03, 2021
by
Kirill Smelkov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
.
parent
fca52539
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
39 additions
and
39 deletions
+39
-39
go/internal/xtracing/tracetest/tracetest.go
go/internal/xtracing/tracetest/tracetest.go
+39
-39
No files found.
go/internal/xtracing/tracetest/tracetest.go
View file @
a676063e
...
...
@@ -44,33 +44,33 @@
// 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: XXX rework
//
Basic package usage is as follows:
//
// XXX tracer -> trace collector?
// - implement tracer that will be synchronously collecting events from
// execution of your program. This can be done with package
// lab.nexedi.com/kirr/go123/tracing or by other similar means.
// 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.
// ...
//
// the tracer have to output events to dispatcher (see below).
// // tell t to which stream an event should go.
// t.SetEventRouter(...)
//
// - implement router that will be making decisions specific to your XXX -> Streams
// particular testing scenario on to which stream an event should belong.
// // run the system and verify it produces expected events
//
// the router will be consulted by dispatcher (see below) for its working.
// // <code to start the system>
// t.Expect("<stream₁>", eventOk₁)
// t.Expect("<stream₂>", eventOk₂)
// ...
//
// - create Dispatcher. This is the central place where events are
// delivered from tracer and are further delivered in accordance to what
// router says.
// // <code to further control/affect the system>
// t.Expect("<stream₃>", eventOk₃)
// t.Expect("<stream₄>", eventOk₄)
// ...
// })
// }
//
// - for every serial stream of events create synchronous delivery channel
// (Chan) and event Checker. XXX
//
//
// XXX more text describing how to use the package.
// XXX link to example.
//
//
// XXX say that deadlocks are detected?
// See example_test.go for more details.
package
tracetest
import
(
...
...
@@ -124,17 +124,17 @@ type _ChanRx interface {
// Recv receives message from a producer.
//
// The consumer, after dealing with the message, must send back an ack.
Recv
()
*
Msg
Recv
()
*
_
Msg
// _rxq returns raw channel that is serving _ChanRx.
// it is used internally to use _ChanRx in select.
_rxq
()
<-
chan
*
Msg
_rxq
()
<-
chan
*
_
Msg
}
// Msg represents message with 1 event sent over _Chan.
//
_
Msg represents message with 1 event sent over _Chan.
//
// The goroutine which sent the message will wait for Ack before continue.
type
Msg
struct
{
type
_
Msg
struct
{
Event
interface
{}
ack
chan
<-
error
// nil on Ack; !nil on nak
}
...
...
@@ -144,7 +144,7 @@ type Msg struct {
// _chan implements _Chan.
type
_chan
struct
{
t
*
T
msgq
chan
*
Msg
msgq
chan
*
_
Msg
down
chan
struct
{}
// becomes ready when closed
_name
string
}
...
...
@@ -164,7 +164,7 @@ func (ch *_chan) Send(event interface{}) {
case
<-
ch
.
down
:
ch
.
t
.
fatalfInNonMain
(
"%s: send: channel was closed"
,
ch
.
name
())
case
ch
.
msgq
<-
&
Msg
{
event
,
ack
}
:
case
ch
.
msgq
<-
&
_
Msg
{
event
,
ack
}
:
err
:=
<-
ack
if
err
!=
nil
{
ch
.
t
.
fatalfInNonMain
(
"%s: send: %s"
,
ch
.
name
(),
err
)
...
...
@@ -178,24 +178,24 @@ func (ch *_chan) Close() {
}
// Recv implements _ChanRx.
func
(
ch
*
_chan
)
Recv
()
*
Msg
{
func
(
ch
*
_chan
)
Recv
()
*
_
Msg
{
msg
:=
<-
ch
.
msgq
return
msg
}
// _rxq implements _ChanRx.
func
(
ch
*
_chan
)
_rxq
()
<-
chan
*
Msg
{
func
(
ch
*
_chan
)
_rxq
()
<-
chan
*
_
Msg
{
return
ch
.
msgq
}
// XXX -> Unpause? Cont? Continue?
// Ack acknowledges the event was processed and unblocks producer goroutine.
func
(
m
*
Msg
)
Ack
()
{
func
(
m
*
_
Msg
)
Ack
()
{
m
.
ack
<-
nil
}
// XXX it should be called only by tracetest internals from under Fatal
func
(
m
*
Msg
)
nak
(
why
string
)
{
func
(
m
*
_
Msg
)
nak
(
why
string
)
{
m
.
ack
<-
errors
.
New
(
why
)
}
...
...
@@ -203,7 +203,7 @@ func (m *Msg) nak(why string) {
func
_NewChan
(
name
string
)
_Chan
{
// XXX somehow avoid channels with duplicate names
// (only allow to create named channels from under dispatcher?)
return
&
_chan
{
msgq
:
make
(
chan
*
Msg
),
down
:
make
(
chan
struct
{}),
_name
:
name
}
return
&
_chan
{
msgq
:
make
(
chan
*
_
Msg
),
down
:
make
(
chan
struct
{}),
_name
:
name
}
}
...
...
@@ -243,12 +243,12 @@ type delayInjectState struct {
}
type
nak
struct
{
msg
*
Msg
msg
*
_
Msg
why
string
}
// XXX place; just use t.Cleanup instead?
func
(
t
*
T
)
queuenak
(
msg
*
Msg
,
why
string
)
{
func
(
t
*
T
)
queuenak
(
msg
*
_
Msg
,
why
string
)
{
t
.
nakq
=
append
(
t
.
nakq
,
nak
{
msg
,
why
})
}
...
...
@@ -362,7 +362,7 @@ func (t *T) Expect(stream string, eventOK interface{}) {
// expect1 receives next event on stream and verifies it to be equal to eventOK (both type and value).
//
// if checks do not pass - fatal testing error is raised.
func
(
t
*
T
)
expect1
(
stream
string
,
eventExpect
interface
{})
*
Msg
{
func
(
t
*
T
)
expect1
(
stream
string
,
eventExpect
interface
{})
*
_
Msg
{
t
.
Helper
()
reventExpect
:=
reflect
.
ValueOf
(
eventExpect
)
...
...
@@ -385,7 +385,7 @@ func (t *T) expect1(stream string, eventExpect interface{}) *Msg {
// xget1 gets 1 event in place and checks it has expected type
//
// if checks do not pass - fatal testing error is raised
func
(
t
*
T
)
xget1
(
stream
string
,
eventp
interface
{})
*
Msg
{
func
(
t
*
T
)
xget1
(
stream
string
,
eventp
interface
{})
*
_
Msg
{
t
.
Helper
()
t
.
mu
.
Lock
()
...
...
@@ -394,7 +394,7 @@ func (t *T) xget1(stream string, eventp interface{}) *Msg {
// XXX ch == nil -> no longer operational
var
msg
*
Msg
var
msg
*
_
Msg
select
{
case
msg
=
<-
ch
.
_rxq
()
:
// unwrapped Recv
...
...
@@ -469,7 +469,7 @@ func (t *T) closeStreamTab() (nnak int) {
}
// print details about pending events and all streams
type
sendInfo
struct
{
ch
_Chan
;
msg
*
Msg
}
type
sendInfo
struct
{
ch
_Chan
;
msg
*
_
Msg
}
var
sendv
[]
sendInfo
// sends are pending here
var
quietv
[]
_Chan
// this channels are quiet
...
...
@@ -572,7 +572,7 @@ func Verify(t *testing.T, f func(t *T)) {
}
streams0
:=
streamsOfTrace
(
trace0
)
// sort trace0 by time just in case - events mig
th
come from multiple
// sort trace0 by time just in case - events mig
ht
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
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment