2023-07-27 16:21:27 -06:00
|
|
|
package graphvent
|
|
|
|
|
|
|
|
import (
|
|
|
|
"testing"
|
2023-07-27 18:08:43 -06:00
|
|
|
"time"
|
2023-07-27 16:21:27 -06:00
|
|
|
)
|
|
|
|
|
2023-07-27 16:48:39 -06:00
|
|
|
const TestLockableType = NodeType("TEST_LOCKABLE")
|
2023-07-27 18:37:06 -06:00
|
|
|
func lockableTestContext(t *testing.T, logs []string) *Context {
|
|
|
|
ctx := logTestContext(t, logs)
|
2023-07-27 16:48:39 -06:00
|
|
|
|
2023-08-07 20:26:02 -06:00
|
|
|
err := ctx.RegisterNodeType(TestLockableType, []ExtType{LockableExtType})
|
2023-07-27 16:21:27 -06:00
|
|
|
fatalErr(t, err)
|
2023-07-27 16:48:39 -06:00
|
|
|
|
|
|
|
return ctx
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2023-07-28 10:04:31 -06:00
|
|
|
//TODO: add new finer grained signals, and probably add wildcards to not have to deal with annoying acl policies
|
|
|
|
var link_policy = NewAllNodesPolicy(Actions{MakeAction(LinkSignalType, "*"), MakeAction(StatusSignalType, "+")})
|
|
|
|
var lock_policy = NewAllNodesPolicy(Actions{MakeAction(LockSignalType, "*")})
|
2023-07-27 16:48:39 -06:00
|
|
|
|
2023-07-27 18:37:06 -06:00
|
|
|
func TestLink(t *testing.T) {
|
2023-07-30 10:09:04 -06:00
|
|
|
ctx := lockableTestContext(t, []string{"lockable"})
|
2023-07-27 16:48:39 -06:00
|
|
|
|
|
|
|
l1_listener := NewListenerExt(10)
|
2023-07-28 15:07:38 -06:00
|
|
|
l1 := NewNode(ctx, nil, TestLockableType, 10, nil,
|
2023-07-27 16:48:39 -06:00
|
|
|
l1_listener,
|
2023-07-27 18:37:06 -06:00
|
|
|
NewLockableExt(),
|
2023-07-27 16:48:39 -06:00
|
|
|
)
|
|
|
|
l2_listener := NewListenerExt(10)
|
2023-07-28 15:07:38 -06:00
|
|
|
l2 := NewNode(ctx, nil, TestLockableType, 10, nil,
|
2023-07-27 16:48:39 -06:00
|
|
|
l2_listener,
|
2023-07-27 18:37:06 -06:00
|
|
|
NewLockableExt(),
|
2023-07-27 16:48:39 -06:00
|
|
|
)
|
|
|
|
|
2023-07-27 18:08:43 -06:00
|
|
|
// Link l2 as a requirement of l1
|
2023-07-28 12:46:06 -06:00
|
|
|
err := LinkRequirement(ctx, l1.ID, l2.ID)
|
2023-07-27 18:08:43 -06:00
|
|
|
fatalErr(t, err)
|
2023-07-27 16:21:27 -06:00
|
|
|
|
2023-08-07 20:26:02 -06:00
|
|
|
_, err = WaitForSignal(ctx, l1_listener, time.Millisecond*10, LinkSignalType, func(sig *StringSignal) bool {
|
|
|
|
return sig.Str == "dep_done"
|
2023-07-28 19:32:27 -06:00
|
|
|
})
|
|
|
|
fatalErr(t, err)
|
2023-07-27 18:16:37 -06:00
|
|
|
|
2023-08-01 20:55:15 -06:00
|
|
|
sig1 := NewStatusSignal("TEST", l2.ID)
|
2023-08-07 20:26:02 -06:00
|
|
|
err = ctx.Send(l2.ID, []Message{{l2.ID, sig1}})
|
2023-07-27 18:16:37 -06:00
|
|
|
fatalErr(t, err)
|
|
|
|
|
2023-08-01 20:55:15 -06:00
|
|
|
_, err = WaitForSignal(ctx, l1_listener, time.Millisecond*10, StatusSignalType, func(sig *IDStringSignal) bool {
|
2023-07-30 23:42:47 -06:00
|
|
|
return sig.Str == "TEST"
|
2023-07-28 19:32:27 -06:00
|
|
|
})
|
|
|
|
fatalErr(t, err)
|
|
|
|
|
2023-08-01 20:55:15 -06:00
|
|
|
_, err = WaitForSignal(ctx, l2_listener, time.Millisecond*10, StatusSignalType, func(sig *IDStringSignal) bool {
|
2023-07-30 23:42:47 -06:00
|
|
|
return sig.Str == "TEST"
|
2023-07-28 19:32:27 -06:00
|
|
|
})
|
|
|
|
fatalErr(t, err)
|
2023-07-27 18:37:06 -06:00
|
|
|
}
|
|
|
|
|
2023-07-28 12:46:06 -06:00
|
|
|
func TestLink10K(t *testing.T) {
|
2023-07-28 19:32:27 -06:00
|
|
|
ctx := lockableTestContext(t, []string{})
|
2023-07-28 12:46:06 -06:00
|
|
|
|
2023-07-28 13:12:17 -06:00
|
|
|
NewLockable := func()(*Node) {
|
2023-07-28 15:07:38 -06:00
|
|
|
l := NewNode(ctx, nil, TestLockableType, 10, nil,
|
2023-07-28 13:12:17 -06:00
|
|
|
NewLockableExt(),
|
|
|
|
)
|
|
|
|
return l
|
|
|
|
}
|
|
|
|
|
|
|
|
NewListener := func()(*Node, *ListenerExt) {
|
2023-07-28 12:46:06 -06:00
|
|
|
listener := NewListenerExt(100000)
|
2023-07-28 15:07:38 -06:00
|
|
|
l := NewNode(ctx, nil, TestLockableType, 256, nil,
|
2023-07-28 12:46:06 -06:00
|
|
|
listener,
|
|
|
|
NewLockableExt(),
|
|
|
|
)
|
|
|
|
return l, listener
|
|
|
|
}
|
2023-07-28 13:12:17 -06:00
|
|
|
|
|
|
|
l0, l0_listener := NewListener()
|
2023-07-29 19:16:33 -06:00
|
|
|
lockables := make([]*Node, 10)
|
2023-07-28 12:46:06 -06:00
|
|
|
for i, _ := range(lockables) {
|
2023-07-28 13:12:17 -06:00
|
|
|
lockables[i] = NewLockable()
|
2023-07-28 12:46:06 -06:00
|
|
|
LinkRequirement(ctx, l0.ID, lockables[i].ID)
|
|
|
|
}
|
|
|
|
|
2023-07-28 13:12:17 -06:00
|
|
|
ctx.Log.Logf("test", "CREATED_10K")
|
2023-07-28 12:46:06 -06:00
|
|
|
|
|
|
|
|
2023-07-28 19:32:27 -06:00
|
|
|
for range(lockables) {
|
2023-08-07 20:26:02 -06:00
|
|
|
_, err := WaitForSignal(ctx, l0_listener, time.Millisecond*10, LinkSignalType, func(sig *StringSignal) bool {
|
|
|
|
return sig.Str == "dep_done"
|
2023-07-28 19:32:27 -06:00
|
|
|
})
|
|
|
|
fatalErr(t, err)
|
2023-07-28 12:46:06 -06:00
|
|
|
}
|
|
|
|
|
2023-07-28 13:12:17 -06:00
|
|
|
ctx.Log.Logf("test", "LINKED_10K")
|
2023-07-28 12:46:06 -06:00
|
|
|
}
|
|
|
|
|
2023-07-27 18:37:06 -06:00
|
|
|
func TestLock(t *testing.T) {
|
2023-08-07 20:26:02 -06:00
|
|
|
ctx := lockableTestContext(t, []string{"lockable", "listener"})
|
2023-07-27 19:53:43 -06:00
|
|
|
|
|
|
|
NewLockable := func()(*Node, *ListenerExt) {
|
2023-07-28 12:46:06 -06:00
|
|
|
listener := NewListenerExt(100)
|
2023-07-28 15:07:38 -06:00
|
|
|
l := NewNode(ctx, nil, TestLockableType, 10, nil,
|
2023-07-27 19:53:43 -06:00
|
|
|
listener,
|
|
|
|
NewLockableExt(),
|
|
|
|
)
|
|
|
|
return l, listener
|
|
|
|
}
|
|
|
|
|
|
|
|
l0, l0_listener := NewLockable()
|
|
|
|
l1, l1_listener := NewLockable()
|
|
|
|
l2, _ := NewLockable()
|
|
|
|
l3, _ := NewLockable()
|
|
|
|
l4, _ := NewLockable()
|
|
|
|
l5, _ := NewLockable()
|
|
|
|
|
|
|
|
|
|
|
|
var err error
|
2023-07-28 12:46:06 -06:00
|
|
|
err = LinkRequirement(ctx, l1.ID, l2.ID)
|
2023-07-27 19:53:43 -06:00
|
|
|
fatalErr(t, err)
|
2023-07-28 12:46:06 -06:00
|
|
|
err = LinkRequirement(ctx, l1.ID, l3.ID)
|
2023-07-27 19:53:43 -06:00
|
|
|
fatalErr(t, err)
|
2023-07-28 12:46:06 -06:00
|
|
|
err = LinkRequirement(ctx, l1.ID, l4.ID)
|
2023-07-27 19:53:43 -06:00
|
|
|
fatalErr(t, err)
|
2023-07-28 12:46:06 -06:00
|
|
|
err = LinkRequirement(ctx, l1.ID, l5.ID)
|
2023-07-27 19:53:43 -06:00
|
|
|
fatalErr(t, err)
|
2023-07-27 18:37:06 -06:00
|
|
|
|
2023-07-28 12:46:06 -06:00
|
|
|
err = LinkRequirement(ctx, l0.ID, l2.ID)
|
2023-07-27 19:53:43 -06:00
|
|
|
fatalErr(t, err)
|
2023-07-28 12:46:06 -06:00
|
|
|
err = LinkRequirement(ctx, l0.ID, l3.ID)
|
2023-07-27 18:37:06 -06:00
|
|
|
fatalErr(t, err)
|
2023-07-28 12:46:06 -06:00
|
|
|
err = LinkRequirement(ctx, l0.ID, l4.ID)
|
2023-07-27 19:53:43 -06:00
|
|
|
fatalErr(t, err)
|
2023-07-28 12:46:06 -06:00
|
|
|
err = LinkRequirement(ctx, l0.ID, l5.ID)
|
2023-07-27 19:53:43 -06:00
|
|
|
fatalErr(t, err)
|
|
|
|
|
2023-08-07 20:26:02 -06:00
|
|
|
linked_as_req := func(sig *StringSignal) bool {
|
|
|
|
return sig.Str == "dep_done"
|
2023-07-28 19:32:27 -06:00
|
|
|
}
|
|
|
|
|
2023-08-01 20:55:15 -06:00
|
|
|
locked := func(sig *StringSignal) bool {
|
2023-07-30 23:42:47 -06:00
|
|
|
return sig.Str == "locked"
|
2023-07-28 19:32:27 -06:00
|
|
|
}
|
|
|
|
|
2023-08-07 20:26:02 -06:00
|
|
|
_, err = WaitForSignal(ctx, l1_listener, time.Millisecond*10, LinkSignalType, linked_as_req)
|
2023-07-28 19:32:27 -06:00
|
|
|
fatalErr(t, err)
|
2023-08-07 20:26:02 -06:00
|
|
|
_, err = WaitForSignal(ctx, l1_listener, time.Millisecond*10, LinkSignalType, linked_as_req)
|
2023-07-28 19:32:27 -06:00
|
|
|
fatalErr(t, err)
|
2023-08-07 20:26:02 -06:00
|
|
|
_, err = WaitForSignal(ctx, l1_listener, time.Millisecond*10, LinkSignalType, linked_as_req)
|
2023-07-28 19:32:27 -06:00
|
|
|
fatalErr(t, err)
|
2023-08-07 20:26:02 -06:00
|
|
|
_, err = WaitForSignal(ctx, l1_listener, time.Millisecond*10, LinkSignalType, linked_as_req)
|
2023-07-28 19:32:27 -06:00
|
|
|
fatalErr(t, err)
|
2023-07-27 19:53:43 -06:00
|
|
|
|
2023-08-07 20:26:02 -06:00
|
|
|
_, err = WaitForSignal(ctx, l0_listener, time.Millisecond*10, LinkSignalType, linked_as_req)
|
2023-07-28 19:32:27 -06:00
|
|
|
fatalErr(t, err)
|
2023-08-07 20:26:02 -06:00
|
|
|
_, err = WaitForSignal(ctx, l0_listener, time.Millisecond*10, LinkSignalType, linked_as_req)
|
2023-07-28 19:32:27 -06:00
|
|
|
fatalErr(t, err)
|
2023-08-07 20:26:02 -06:00
|
|
|
_, err = WaitForSignal(ctx, l0_listener, time.Millisecond*10, LinkSignalType, linked_as_req)
|
2023-07-28 19:32:27 -06:00
|
|
|
fatalErr(t, err)
|
2023-08-07 20:26:02 -06:00
|
|
|
_, err = WaitForSignal(ctx, l0_listener, time.Millisecond*10, LinkSignalType, linked_as_req)
|
2023-07-28 19:32:27 -06:00
|
|
|
fatalErr(t, err)
|
2023-07-27 18:37:06 -06:00
|
|
|
|
|
|
|
err = LockLockable(ctx, l1)
|
|
|
|
fatalErr(t, err)
|
2023-07-28 19:32:27 -06:00
|
|
|
_, err = WaitForSignal(ctx, l1_listener, time.Millisecond*10, LockSignalType, locked)
|
|
|
|
fatalErr(t, err)
|
|
|
|
_, err = WaitForSignal(ctx, l1_listener, time.Millisecond*10, LockSignalType, locked)
|
|
|
|
fatalErr(t, err)
|
|
|
|
_, err = WaitForSignal(ctx, l1_listener, time.Millisecond*10, LockSignalType, locked)
|
|
|
|
fatalErr(t, err)
|
|
|
|
_, err = WaitForSignal(ctx, l1_listener, time.Millisecond*10, LockSignalType, locked)
|
|
|
|
fatalErr(t, err)
|
|
|
|
_, err = WaitForSignal(ctx, l1_listener, time.Millisecond*10, LockSignalType, locked)
|
|
|
|
fatalErr(t, err)
|
2023-07-27 22:25:00 -06:00
|
|
|
|
|
|
|
err = UnlockLockable(ctx, l1)
|
|
|
|
fatalErr(t, err)
|
2023-07-27 18:08:43 -06:00
|
|
|
}
|