aboutsummaryrefslogtreecommitdiffstats
path: root/kill_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'kill_test.go')
-rw-r--r--kill_test.go112
1 files changed, 112 insertions, 0 deletions
diff --git a/kill_test.go b/kill_test.go
new file mode 100644
index 0000000..d11e54c
--- /dev/null
+++ b/kill_test.go
@@ -0,0 +1,112 @@
+package gui
+
+import (
+ "fmt"
+ "testing"
+)
+
+// Kill the attachHandler with no victim attached.
+func TestAttachHandlerKill(t *testing.T) {
+ handler := newAttachHandler()
+ if !trySend(handler.kill, true, timeout) {
+ t.Errorf("kill attachHandler timed out after %v", timeout)
+ }
+ if _, ok := tryRecv(handler.dead, timeout); !ok {
+ t.Errorf("no dead signal from attachHandler after %v", timeout)
+ }
+}
+
+// Kill the attachHandler with a victim attached.
+func TestAttachHandlerAttachKill(t *testing.T) {
+ handler := newAttachHandler()
+ victim, err := newDummyAttachable(handler)
+ if err != nil {
+ t.Error(err)
+ }
+
+ // Kill attachHandler.
+ if !trySend(handler.kill, true, timeout) {
+ t.Errorf("failed to kill attachHandler after %v", timeout)
+ }
+ if _, ok := tryRecv(handler.dead, timeout); !ok {
+ t.Errorf("attachHandler not dead after %v", timeout)
+ }
+
+ // victim.Dead() should now be closed.
+ if _, notClosed := <-victim.Dead(); notClosed {
+ t.Errorf("victim not dead after killing attachHandler")
+ }
+}
+
+// Detach the victim and attach another in its place.
+func TestAttachHandlerReattach(t *testing.T) {
+ handler := newAttachHandler()
+
+ // Attach first victim.
+ victim1, err := newDummyAttachable(handler)
+ if err != nil {
+ t.Error(err)
+ }
+
+ // Try to attach second victim while first still attached—should fail.
+ if _, err := newDummyAttachable(handler); err == nil {
+ t.Errorf("attachHandler accepted another victim while the first was still attached.")
+ }
+
+ // Detach first victim.
+ if !trySend(victim1.Kill(), true, timeout) {
+ t.Errorf("failed to kill first victim after %v", timeout)
+ }
+ if _, ok := tryRecv(victim1.Dead(), timeout); !ok {
+ t.Errorf("first victim failed to die after %v", timeout)
+ }
+
+ // Attach second victim.
+ if _, err := newDummyAttachable(handler); err != nil {
+ t.Error(err)
+ }
+
+ handler.kill <- true
+ <-handler.dead
+}
+
+type dummyAttachable struct {
+ kill chan<- bool
+ dead <-chan bool
+ detachChan <-chan bool
+}
+
+// newDummyAttachable returns a dummyAttachable that is attached to parent,
+// or error if the parent does not accept the attach.
+func newDummyAttachable(parent killer) (attachable, error) {
+ kill := make(chan bool)
+ dead := make(chan bool)
+ detachChan := make(chan bool)
+
+ go func() {
+ <-kill
+ close(kill)
+ detachChan <- true
+ close(detachChan)
+ dead <- true
+ close(dead)
+ }()
+
+ da := dummyAttachable{kill, dead, detachChan}
+ if !trySend(parent.attach(), attachable(da), timeout) {
+ return da, fmt.Errorf("failed to attach after %v", timeout)
+ }
+ return da, nil
+}
+
+func (da dummyAttachable) Kill() chan<- bool {
+ return da.kill
+}
+
+func (da dummyAttachable) Dead() <-chan bool {
+ return da.dead
+}
+
+func (da dummyAttachable) detach() <-chan bool {
+ return da.detachChan
+}