package test
import (
"context"
"os"
"testing"
"time"
arpc "github.com/pancsta/asyncmachine-go/pkg/rpc"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
sst "github.com/pancsta/asyncmachine-go/internal/testing/states"
"github.com/pancsta/asyncmachine-go/internal/testing/utils"
amhelpt "github.com/pancsta/asyncmachine-go/pkg/helpers/testing"
am "github.com/pancsta/asyncmachine-go/pkg/machine"
ampipe "github.com/pancsta/asyncmachine-go/pkg/states/pipes"
)
type S = am .S
type (
Schema = am .Schema
)
func TemplateTestSingleStateActive (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
m := utils .NewNoRelsNetSrc (t , nil , "" )
_ , _ , s , c := newTest (t , ctx , m , nil , 0 , false , nil , nil )
w := c .NetMach
w .Add1 ("A" , nil )
amhelpt .AssertIs (t , c .NetMach , S {"A" })
disposeTest (t , c , s , true )
}
func TemplateTestMultipleStatesActive (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
m := utils .NewNoRelsNetSrc (t , nil , "" )
_ , _ , s , c := newTest (t , ctx , m , nil , 0 , false , nil , nil )
w := c .NetMach
w .Add (S {"A" }, nil )
w .Add (S {"B" }, nil )
amhelpt .AssertIs (t , c .NetMach , S {"A" , "B" })
disposeTest (t , c , s , true )
}
func TemplateTestExposeAllStateNames (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
m := utils .NewNoRelsNetSrc (t , S {"A" }, "" )
_ , _ , s , c := newTest (t , ctx , m , nil , 0 , false , nil , nil )
w := c .NetMach
assert .Subset (t , w .StateNames (), S {"A" , "B" , "C" , "D" })
disposeTest (t , c , s , true )
}
func TemplateTestStateSet (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
m := utils .NewNoRelsNetSrc (t , S {"A" }, "" )
_ , _ , s , c := newTest (t , ctx , m , nil , 0 , false , nil , nil )
w := c .NetMach
w .Set (S {"B" }, nil )
amhelpt .AssertIs (t , w , S {"B" })
disposeTest (t , c , s , true )
}
func TemplateTestStateAdd (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
m := utils .NewNoRelsNetSrc (t , S {"A" }, "" )
_ , _ , s , c := newTest (t , ctx , m , nil , 0 , false , nil , nil )
w := c .NetMach
w .Add (S {"B" }, nil )
amhelpt .AssertIs (t , w , S {"A" , "B" })
disposeTest (t , c , s , true )
}
func TemplateTestStateRemove (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
m := utils .NewNoRelsNetSrc (t , S {"B" , "C" }, "" )
_ , _ , s , c := newTest (t , ctx , m , nil , 0 , false , nil , nil )
c .NetMach .Remove (S {"C" }, nil )
w := c .NetMach
amhelpt .AssertIs (t , w , S {"B" })
disposeTest (t , c , s , true )
}
func TemplateTestRemoveRelation (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
m := utils .NewCustomNetSrc (t , am .Schema {
sst .A : {},
sst .B : {},
sst .C : {Remove : S {sst .D }},
sst .D : {},
})
m .Add1 (sst .D , nil )
_ , _ , s , c := newTest (t , ctx , m , nil , 0 , false , nil , nil )
w := c .NetMach
w .Add (S {"C" }, nil )
amhelpt .AssertIs (t , w , S {"C" })
disposeTest (t , c , s , true )
}
func TemplateTestRemoveRelationSimultaneous (
t *testing .T , newTest NewTestFactory ,
) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
m := utils .NewCustomNetSrc (t , am .Schema {
sst .A : {},
sst .B : {},
sst .C : {Remove : S {sst .D }},
sst .D : {},
})
m .Add1 (sst .D , nil )
_ , _ , s , c := newTest (t , ctx , m , nil , 0 , false , nil , nil )
w := c .NetMach
r := w .Set (S {"C" , "D" }, nil )
assert .Equal (t , am .Canceled , r )
amhelpt .AssertIs (t , w , S {"D" })
disposeTest (t , c , s , true )
}
func TemplateTestRemoveRelationCrossBlocking (
t *testing .T , newTest NewTestFactory ,
) {
tests := []struct {
name string
fn func (t *testing .T , w *arpc .NetworkMachine )
}{
{
"using Set should de-activate the old one" ,
func (t *testing .T , w *arpc .NetworkMachine ) {
w .Set (S {"C" }, nil )
amhelpt .AssertIs (t , w , S {"C" })
},
},
{
"using Set should work both ways" ,
func (t *testing .T , w *arpc .NetworkMachine ) {
w .Set (S {"C" }, nil )
amhelpt .AssertIs (t , w , S {"C" })
w .Set (S {"D" }, nil )
amhelpt .AssertIs (t , w , S {"D" })
},
},
{
"using Add should de-activate the old one" ,
func (t *testing .T , w *arpc .NetworkMachine ) {
w .Add (S {"C" }, nil )
amhelpt .AssertIs (t , w , S {"C" })
},
},
{
"using Add should work both ways" ,
func (t *testing .T , w *arpc .NetworkMachine ) {
w .Add (S {"C" }, nil )
amhelpt .AssertIs (t , w , S {"C" })
w .Add (S {"D" }, nil )
amhelpt .AssertIs (t , w , S {"D" })
},
},
}
for i := range tests {
test := tests [i ]
t .Run (test .name , func (t *testing .T ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
m := utils .NewCustomNetSrc (t , am .Schema {
sst .A : {},
sst .B : {},
sst .C : {Remove : S {sst .D }},
sst .D : {Remove : S {sst .C }},
})
m .Add1 (sst .D , nil )
_ , _ , s , c := newTest (t , ctx , m , nil , 0 , false , nil , nil )
w := c .NetMach
test .fn (t , w )
disposeTest (t , c , s , true )
})
}
}
func TemplateTestAddRelation (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
m := utils .NewCustomNetSrc (t , am .Schema {
sst .A : {Remove : S {sst .D }},
sst .B : {},
sst .C : {Add : S {sst .D }},
sst .D : {},
})
_ , _ , s , c := newTest (t , ctx , m , nil , 0 , false , nil , nil )
w := c .NetMach
w .Set (S {"C" }, nil )
amhelpt .AssertIs (t , w , S {"C" , "D" }, "state should be activated" )
w .Set (S {"A" , "C" }, nil )
amhelpt .AssertIs (t , w , S {"A" , "C" }, "state D should be skipped if " +
"blocked at the same time" )
disposeTest (t , c , s , true )
}
func TemplateTestRequireRelation (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewCustomNetSrc (t , am .Schema {
sst .A : {Require : S {sst .D }},
sst .B : {},
sst .C : {},
sst .D : {},
})
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
w .Set (S {"C" , "D" }, nil )
amhelpt .AssertIs (t , w , S {"C" , "D" })
disposeTest (t , c , s , true )
}
func TemplateTestRequireRelationWhenRequiredIsntActive (
t *testing .T , newTest NewTestFactory ,
) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewCustomNetSrc (t , am .Schema {
sst .A : {},
sst .B : {},
sst .C : {Require : S {sst .D }},
sst .D : {},
})
mach .Add1 (sst .A , nil )
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
w .Set (S {"C" , "A" }, nil )
amhelpt .AssertIs (t , w , S {"A" }, "target state shouldnt be activated" )
disposeTest (t , c , s , true )
}
func TemplateTestAutoStates (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewCustomNetSrc (t , am .Schema {
sst .A : {},
sst .B : {
Auto : true ,
Require : S {sst .A },
},
sst .C : {Require : S {sst .D }},
sst .D : {},
})
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
result := w .Add (S {"A" }, nil )
assert .Equal (t , am .Executed , result , "transition should be executed" )
amhelpt .AssertIs (t , w , S {"A" , "B" }, "dependant auto state should be set" )
disposeTest (t , c , s , true )
}
func TemplateTestSwitch (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewCustomNetSrc (t , am .Schema {
sst .A : {},
sst .B : {},
sst .C : {Require : S {sst .D }},
sst .D : {},
})
mach .Add1 (sst .A , nil )
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
caseA := false
switch w .Switch (S {"A" , "B" }) {
case "A" :
caseA = true
case "B" :
}
assert .Equal (t , true , caseA )
caseDef := false
switch w .Switch (S {"C" , "B" }) {
case "B" :
default :
caseDef = true
}
assert .Equal (t , true , caseDef )
disposeTest (t , c , s , true )
}
func TemplateTestRegressionRemoveCrossBlockedByImplied (
t *testing .T , newTest NewTestFactory ,
) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewCustomNetSrc (t , Schema {
"A" : {Remove : S {"B" }},
"B" : {Remove : S {"A" }},
"Z" : {Add : S {"B" }},
})
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
w .Set (S {"Z" }, nil )
amhelpt .AssertIs (t , w , S {"Z" , "B" })
disposeTest (t , c , s , true )
}
func TemplateTestRegressionImpliedBlockByBeingRemoved (
t *testing .T , newTest NewTestFactory ,
) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewCustomNetSrc (t , Schema {
"Wet" : {Require : S {"Water" }},
"Dry" : {Remove : S {"Wet" }},
"Water" : {Add : S {"Wet" }, Remove : S {"Dry" }},
})
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
w .Set (S {"Dry" }, nil )
w .Set (S {"Water" }, nil )
amhelpt .AssertIs (t , w , S {"Water" , "Wet" })
disposeTest (t , c , s , true )
}
func TemplateTestWhen2 (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewNoRelsNetSrc (t , nil , "" )
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
ready1 := make (chan struct {})
pass1 := make (chan struct {})
go func () {
close (ready1 )
<-w .When (S {"A" , "B" }, nil )
close (pass1 )
}()
ready2 := make (chan struct {})
pass2 := make (chan struct {})
go func () {
close (ready2 )
<-w .When (S {"A" , "B" }, nil )
close (pass2 )
}()
<-ready1
<-ready2
w .Add (S {"A" , "B" }, nil )
<-pass1
<-pass2
disposeTest (t , c , s , true )
}
func TemplateTestWhenActive (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewNoRelsNetSrc (t , S {"A" }, "" )
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
<-w .When (S {"A" }, nil )
amhelpt .AssertIs (t , w , S {"A" })
disposeTest (t , c , s , true )
}
func TemplateTestWhenNot2 (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewNoRelsNetSrc (t , S {"A" , "B" }, "" )
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
ready1 := make (chan struct {})
pass1 := make (chan struct {})
go func () {
close (ready1 )
<-w .WhenNot (S {"A" , "B" }, nil )
close (pass1 )
}()
ready2 := make (chan struct {})
pass2 := make (chan struct {})
go func () {
close (ready2 )
<-w .WhenNot (S {"A" , "B" }, nil )
close (pass2 )
}()
<-ready1
<-ready2
w .Remove (S {"A" , "B" }, nil )
<-pass1
<-pass2
disposeTest (t , c , s , true )
}
func TemplateTestWhenNotActive (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewNoRelsNetSrc (t , S {"A" }, "" )
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
<-w .WhenNot (S {"B" }, nil )
amhelpt .AssertIs (t , w , S {"A" })
disposeTest (t , c , s , true )
}
func TemplateTestPartialAuto (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewCustomNetSrc (t , am .Schema {
sst .A : {},
sst .B : {},
sst .C : {
Auto : true ,
Require : S {sst .B },
},
sst .D : {
Auto : true ,
Require : S {sst .B },
},
})
mach .Add1 (sst .A , nil )
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
w .Add (S {"A" }, nil )
amhelpt .AssertIs (t , w , S {"A" })
disposeTest (t , c , s , true )
}
func TemplateTestTime (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewCustomNetSrc (t , am .Schema {
sst .A : {},
sst .B : {Multi : true },
sst .C : {},
sst .D : {},
})
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
w .Add (S {"A" , "B" }, nil )
amhelpt .AssertIs (t , w , S {"A" , "B" })
amhelpt .AssertTime (t , w , S {"A" , "B" , "C" , "D" }, am .Time {1 , 1 , 0 , 0 })
w .Add (S {"A" , "B" }, nil )
amhelpt .AssertIs (t , w , S {"A" , "B" })
amhelpt .AssertTime (t , w , S {"A" , "B" , "C" , "D" }, am .Time {1 , 3 , 0 , 0 })
w .Add (S {"A" , "B" , "C" }, nil )
amhelpt .AssertIs (t , w , S {"A" , "B" , "C" })
amhelpt .AssertTime (t , w , S {"A" , "B" , "C" , "D" }, am .Time {1 , 5 , 1 , 0 })
w .Set (S {"D" }, nil )
amhelpt .AssertIs (t , w , S {"D" })
amhelpt .AssertTime (t , w , S {"A" , "B" , "C" , "D" }, am .Time {2 , 6 , 2 , 1 })
w .Add (S {"D" , "C" }, nil )
amhelpt .AssertIs (t , w , S {"D" , "C" })
amhelpt .AssertTime (t , w , S {"A" , "B" , "C" , "D" }, am .Time {2 , 6 , 3 , 1 })
w .Remove (S {"B" , "C" }, nil )
amhelpt .AssertIs (t , w , S {"D" })
amhelpt .AssertTime (t , w , S {"A" , "B" , "C" , "D" }, am .Time {2 , 6 , 4 , 1 })
w .Add (S {"A" , "B" }, nil )
amhelpt .AssertIs (t , w , S {"D" , "A" , "B" })
amhelpt .AssertTime (t , w , S {"A" , "B" , "C" , "D" }, am .Time {3 , 7 , 4 , 1 })
order := S {"A" , "B" , "C" , "D" }
before := w .Time (order )
w .Add (S {"C" }, nil )
now := w .Time (order )
amhelpt .AssertIs (t , w , S {"A" , "B" , "D" , "C" })
amhelpt .AssertTime (t , w , S {"A" , "B" , "C" , "D" }, am .Time {3 , 7 , 5 , 1 })
assert .True (t , now .After (true , before ))
assert .False (t , before .After (true , now ))
disposeTest (t , c , s , true )
}
func TemplateTestWhenTime (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewNoRelsNetSrc (t , S {"A" , "B" }, "" )
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
whenCh := w .WhenTime (S {"A" , "B" }, am .Time {5 , 2 }, nil )
w .Remove (S {"A" , "B" }, nil )
w .Add (S {"A" , "B" }, nil )
select {
case <- whenCh :
t .Fatal ("when shouldnt be resolved" )
default :
}
w .Remove1 ("A" , nil )
w .Add1 ("A" , nil )
select {
default :
t .Fatal ("when should be resolved" )
case <- whenCh :
}
disposeTest (t , c , s , true )
}
func TemplateTestIs (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewCustomNetSrc (t , am .Schema {
sst .A : {},
sst .B : {
Auto : true ,
Require : S {sst .A },
},
sst .C : {},
sst .D : {},
})
mach .Add (S {sst .A , sst .B }, nil )
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
assert .True (t , w .Is (S {"A" , "B" }), "A B should be active" )
assert .False (t , w .Is (S {"A" , "B" , "C" }), "A B C shouldnt be active" )
disposeTest (t , c , s , true )
}
func TemplateTestNot (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewCustomNetSrc (t , am .Schema {
sst .A : {},
sst .B : {
Auto : true ,
Require : S {sst .A },
},
sst .C : {},
sst .D : {},
})
mach .Add (S {sst .A , sst .B }, nil )
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
assert .False (t , w .Not (S {"A" , "B" }), "A B should be active" )
assert .False (t , w .Not (S {"A" , "B" , "C" }), "A B C is partially active" )
assert .True (t , w .Not1 ("D" ), "D is inactive" )
disposeTest (t , c , s , true )
}
func TemplateTestAny (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewCustomNetSrc (t , am .Schema {
sst .A : {},
sst .B : {
Auto : true ,
Require : S {sst .A },
},
sst .C : {},
sst .D : {},
})
mach .Add (S {sst .A , sst .B }, nil )
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
assert .True (t , w .Any (S {"A" , "B" }, S {"C" }), "A B should be active" )
assert .True (t , w .Any (S {"A" , "B" , "C" }, S {"A" }),
"A B C is partially active" )
disposeTest (t , c , s , true )
}
func TemplateTestClock (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewCustomNetSrc (t , am .Schema {
sst .A : {},
sst .B : {Multi : true },
sst .C : {},
sst .D : {},
})
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
w .Add (S {"A" , "B" }, nil )
amhelpt .AssertIs (t , w , S {"A" , "B" })
amhelpt .AssertTime (t , w , S {"A" , "B" , "C" , "D" }, am .Time {1 , 1 , 0 , 0 })
w .Add (S {"A" , "B" }, nil )
amhelpt .AssertIs (t , w , S {"A" , "B" })
amhelpt .AssertTime (t , w , S {"A" , "B" , "C" , "D" }, am .Time {1 , 3 , 0 , 0 })
w .Add (S {"A" , "B" , "C" }, nil )
amhelpt .AssertIs (t , w , S {"A" , "B" , "C" })
amhelpt .AssertTime (t , w , S {"A" , "B" , "C" , "D" }, am .Time {1 , 5 , 1 , 0 })
w .Set (S {"D" }, nil )
amhelpt .AssertIs (t , w , S {"D" })
amhelpt .AssertTime (t , w , S {"A" , "B" , "C" , "D" }, am .Time {2 , 6 , 2 , 1 })
w .Add (S {"D" , "C" }, nil )
amhelpt .AssertIs (t , w , S {"D" , "C" })
amhelpt .AssertTime (t , w , S {"A" , "B" , "C" , "D" }, am .Time {2 , 6 , 3 , 1 })
w .Remove (S {"B" , "C" }, nil )
amhelpt .AssertIs (t , w , S {"D" })
amhelpt .AssertTime (t , w , S {"A" , "B" , "C" , "D" }, am .Time {2 , 6 , 4 , 1 })
w .Add (S {"A" , "B" }, nil )
amhelpt .AssertIs (t , w , S {"D" , "A" , "B" })
amhelpt .AssertTime (t , w , S {"A" , "B" , "C" , "D" }, am .Time {3 , 7 , 4 , 1 })
assert .Subset (t , w .Clock (nil ), am .Clock {
"A" : 3 , "B" : 7 , "C" : 4 , "D" : 1 , "Exception" : 0 ,
})
assert .Equal (t , am .Clock {
"A" : 3 , "B" : 7 ,
}, w .Clock (S {"A" , "B" }))
assert .Equal (t , uint64 (3 ), w .Tick ("A" ))
disposeTest (t , c , s , true )
}
func TemplateTestInspect (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewRelsNetSrc (t , S {"A" , "C" })
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
names := S {"A" , "B" , "C" , "D" , "Exception" }
expected := `
1 A
|Tick 1
|Auto true
|Require C
0 B
|Tick 0
|Multi true
|Add C
1 C
|Tick 1
|After D
0 D
|Tick 0
|Add C B
0 Exception
|Tick 0
|Multi true
`
amhelpt .AssertString (t , w , expected , names )
w .Remove (S {"C" }, nil )
w .Add (S {"B" }, nil )
w .Add (S {"D" }, nil )
expected = `
0 Exception
|Tick 0
|Multi true
1 A
|Tick 3
|Auto true
|Require C
1 B
|Tick 1
|Multi true
|Add C
1 C
|Tick 3
|After D
1 D
|Tick 1
|Add C B
0 ErrOnClient
|Tick 0
|Require Exception
`
amhelpt .AssertString (t , w , expected , nil )
disposeTest (t , c , s , true )
}
func TemplateTestString (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewNoRelsNetSrc (t , S {"A" , "B" }, "" )
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
assert .Equal (t , "(A:1 B:1)" , w .String ())
assert .Equal (t , "(A:1 B:1) [Exception:0 C:0 D:0 ErrOnClient:0]" ,
w .StringAll ())
disposeTest (t , c , s , true )
}
type TestNestedMutationHandlers struct {
*am .ExceptionHandler
}
func (h *TestNestedMutationHandlers ) AState (e *am .Event ) {
e .Machine ().Add1 ("B" , nil )
e .Machine ().Add1 ("B" , nil )
e .Machine ().Add1 ("B" , nil )
e .Machine ().Remove1 ("B" , nil )
e .Machine ().Remove1 ("B" , nil )
}
func TemplateTestNestedMutation (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewNoRelsNetSrc (t , nil , "" )
_ , err := mach .HandlersBind (&TestNestedMutationHandlers {})
assert .NoError (t , err )
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
w .Add1 ("A" , nil )
amhelpt .AssertIs (t , w , S {"A" })
disposeTest (t , c , s , true )
}
func TemplateTestIsClock (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
m := utils .NewNoRelsNetSrc (t , nil , "" )
_ , _ , s , c := newTest (t , ctx , m , nil , 0 , false , nil , nil )
w := c .NetMach
cA := w .Clock (S {"A" })
cAll := w .Clock (nil )
w .Add (S {"A" , "B" }, nil )
assert .False (t , w .IsClock (cAll ))
assert .False (t , w .IsClock (cA ))
disposeTest (t , c , s , true )
}
func TemplateTestIsTime (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
m := utils .NewNoRelsNetSrc (t , nil , "" )
_ , _ , s , c := newTest (t , ctx , m , nil , 0 , false , nil , nil )
w := c .NetMach
tA := w .Time (S {"A" })
tAll := w .Time (nil )
w .Add (S {"A" , "B" }, nil )
assert .False (t , w .IsTime (tA , S {"A" }))
assert .False (t , w .IsTime (tAll , nil ))
disposeTest (t , c , s , true )
}
type TestWhenQueueTracer struct {
*am .TracerNoOp
done chan struct {}
t *testing .T
}
func (tr *TestWhenQueueTracer ) TransitionEnd (tx *am .Transition ) {
go func () {
m := tx .MachApi
if tx .TimeBefore .Is1 (m .Index1 ("A" )) {
return
}
m .Add1 ("B" , nil )
m .Add1 ("C" , nil )
res := am .Result (5 )
m .Add1 ("D" , nil )
<-m .WhenQueue (res )
amhelpt .AssertIs (tr .t , m , S {"A" , "B" , "C" , "D" })
close (tr .done )
}()
}
func TemplateTestWhenQueue (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewNoRelsNetSrc (t , nil , "" )
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
nm := c .NetMach
tr := &TestWhenQueueTracer {
TracerNoOp : &am .TracerNoOp {
Id : t .Name (),
},
t : t ,
done : make (chan struct {}),
}
_ , err := nm .BindTracer (tr )
require .NoError (t , err )
nm .Add1 ("A" , nil )
select {
case <- tr .done :
case <- time .After (time .Second ):
<-tr .done
}
disposeTest (t , c , s , true )
}
func TemplateTestWhenQuery (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx , cancel := context .WithCancel (context .Background ())
defer cancel ()
mach := utils .NewNoRelsNetSrc (t , S {"A" }, "" )
_ , _ , s , c := newTest (t , ctx , mach , nil , 0 , false , nil , nil )
w := c .NetMach
query1 := func (c am .Clock ) bool {
return c ["A" ] > c ["B" ]*4
}
query2 := func (c am .Clock ) bool {
return c ["A" ] < c ["B" ]
}
when1 := w .WhenQuery (query1 , nil )
when2 := w .WhenQuery (query2 , nil )
w .Add1 ("B" , nil )
w .Remove1 ("A" , nil )
w .Add1 ("A" , nil )
w .Remove1 ("A" , nil )
select {
case <- when2 :
assert .Fail (t , "should NOT match" )
case <- when1 :
assert .Fail (t , "should NOT match" )
default :
}
w .Add1 ("A" , nil )
select {
case <- when1 :
case <- when2 :
assert .Fail (t , "should NOT match" )
default :
assert .Fail (t , "should match" )
}
disposeTest (t , c , s , true )
}
func TemplateTestPipes (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
ctx := context .Background ()
netSrc := utils .NewNoRelsNetSrc (t , S {"A" }, "" )
local := utils .NewNoRelsNetSrc (t , nil , "-local" )
_ , _ , s , c := newTest (t , ctx , netSrc , nil , 0 , false , nil , nil )
local .AddBreakpoint1 ("A" , "" , false )
local .AddBreakpoint1 ("B" , "" , false )
local .Set (c .NetMach .ActiveStates (nil ), nil )
_ , err := ampipe .BindAny (c .NetMach , local )
require .NoError (t , err )
netSrc .Add (S {"A" , "B" }, nil )
amhelpt .WaitForAll (t , t .Name (), ctx , time .Second ,
local .When (am .S {"A" , "B" }, nil ))
t .Log ("OK" )
local .Dispose ()
disposeTest (t , c , s , true )
}
func TemplateTestStateCtxBasic (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
m := utils .NewNoRelsNetSrc (t , nil , "" )
m .Add1 ("A" , nil )
ctx1 := m .NewStateCtx ("A" )
assert .Nil (t , ctx1 .Err ())
m .Remove1 ("A" , nil )
assert .Error (t , ctx1 .Err ())
ctx2 := m .NewStateCtx ("B" )
assert .Nil (t , ctx2 .Err ())
m .Add1 ("B" , nil )
assert .Error (t , ctx2 .Err ())
m .Dispose ()
<-m .WhenDisposed ()
}
func TemplateTestWhenTimeSum (t *testing .T , newTest NewTestFactory ) {
if os .Getenv (am .EnvAmTestDbgAddr ) == "" {
t .Parallel ()
}
m := utils .NewNoRelsNetSrc (t , S {"A" , "B" }, "" )
sum0 := m .Time (nil ).Sum (nil )
require .Equal (t , uint64 (2 ), sum0 )
whenCh := m .WhenTimeSum (8 , nil )
m .Remove (S {"A" , "B" }, nil )
m .Add (S {"A" , "B" }, nil )
sum1 := m .Time (nil ).Sum (nil )
require .Equal (t , uint64 (6 ), sum1 )
select {
case <- whenCh :
t .Fatal ("when shouldnt be resolved" )
default :
}
m .Remove1 ("A" , nil )
m .Add1 ("A" , nil )
sum2 := m .Time (nil ).Sum (nil )
require .Equal (t , uint64 (8 ), sum2 )
select {
default :
t .Fatal ("when should be resolved" )
case <- whenCh :
}
m .Dispose ()
<-m .WhenDisposed ()
}
The pages are generated with Golds v0.8.4 . (GOOS=linux GOARCH=amd64)
Golds is a Go 101 project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds .