Beispiel #1
0
// TestChildSupervisor tests a supervisor as a child.
func TestChildSupervisor(t *testing.T) {
	assert := asserts.NewTestingAsserts(t, true)
	sup := supervisor.NewSupervisor("parent", supervisor.OneForAll, 3, time.Second)
	chsup, _ := sup.Supervisor("child", supervisor.OneForOne, 5, time.Second)
	st := newStarts()
	childA := func(h *supervisor.Handle) error { return methodChild(h, st) }
	childB := func(h *supervisor.Handle) error { return panicChild(h, st, shortWait) }

	sup.Go("alpha", childA)
	sup.Go("beta", childA)

	chsup.Go("gamma", childA)
	chsup.Go("delta", childA)
	chsup.Go("epsilon", childB)

	time.Sleep(2 * time.Second)

	err := sup.Stop()
	assert.Nil(err, "stopping parent of 'child-supervisor'")
	assert.Equal(st.count("alpha"), 4, "starts of 'alpha'")
	assert.Equal(st.count("beta"), 4, "starts of 'beta'")
	assert.Equal(st.count("gamma"), 4, "starts of 'gamma'")
	assert.Equal(st.count("delta"), 4, "starts of 'delta'")
	assert.True(st.count("epsilon") > 1, "starts of 'epsilon'")
}
Beispiel #2
0
// TestIllegalTerminate tests the termination of an illegal child.
func TestIllegalTerminate(t *testing.T) {
	assert := asserts.NewTestingAsserts(t, true)
	sup := supervisor.NewSupervisor("terminate", supervisor.OneForOne, 5, time.Second)

	err := sup.Terminate("non-existing")
	assert.ErrorMatch(err, `child id ".*" is not in use`, "termination of 'non-existing'")

	err = sup.Stop()
	assert.Nil(err, "stopping of 'terminate'")
}
Beispiel #3
0
// TestFuncMethod tests the termination of a method child on demand.
func TestFuncMethod(t *testing.T) {
	assert := asserts.NewTestingAsserts(t, true)
	sup := supervisor.NewSupervisor("method", supervisor.OneForOne, 5, time.Second)
	st := newStarts()
	child := func(h *supervisor.Handle) error { return methodChild(h, st) }

	sup.Go("alpha", child)

	time.Sleep(100 * time.Millisecond)

	err := sup.Terminate("alpha")
	assert.Nil(err, "termination of 'alpha'")
	assert.Equal(st.count("alpha"), 1, "starts of 'alpha'")

	err = sup.Stop()
	assert.Nil(err, "stopping of 'method'")
}
Beispiel #4
0
// TestFuncError tests the error of a child.
func TestFuncError(t *testing.T) {
	assert := asserts.NewTestingAsserts(t, true)
	sup := supervisor.NewSupervisor("error", supervisor.OneForOne, 5, time.Second)
	st := newStarts()
	child := func(h *supervisor.Handle) error { return errorChild(h, st, shortWait) }

	sup.Go("alpha", child)

	time.Sleep(325 * time.Millisecond)

	err := sup.Terminate("alpha")
	assert.Nil(err, "termination of 'alpha'")
	assert.Equal(st.count("alpha"), 4, "starts of 'alpha'")

	err = sup.Stop()
	assert.Nil(err, "stopping of 'error'")
}
Beispiel #5
0
// TestFuncsOneForAll tests multiple childs restarting one for all.
func TestFuncsOneForAll(t *testing.T) {
	assert := asserts.NewTestingAsserts(t, true)
	sup := supervisor.NewSupervisor("one4all", supervisor.OneForAll, 25, time.Second)
	st := newStarts()
	childA := func(h *supervisor.Handle) error { return selectChild(h, st) }
	childB := func(h *supervisor.Handle) error { return methodChild(h, st) }
	childC := func(h *supervisor.Handle) error { return panicChild(h, st, shortWait) }

	sup.Go("alpha", childA)
	sup.Go("beta", childB)
	sup.Go("gamma", childC)

	time.Sleep(time.Second)

	err := sup.Stop()
	assert.Nil(err, "stopping of 'one4all'")
	assert.Equal(st.count("alpha"), 10, "starts of 'alpha'")
	assert.Equal(st.count("beta"), 10, "starts of 'beta'")
	assert.Equal(st.count("gamma"), 10, "starts of 'gamma'")
}
Beispiel #6
0
// TestSupervisorTree tests a tree of supervisors.
func TestSupervisorTree(t *testing.T) {
	assert := asserts.NewTestingAsserts(t, true)
	sup := supervisor.NewSupervisor("parent", supervisor.OneForAll, 3, 5*time.Second)
	chsup, _ := sup.Supervisor("child", supervisor.OneForAll, 3, time.Second)
	gchsup, _ := chsup.Supervisor("grandchild", supervisor.OneForOne, 3, time.Second)
	st := newStarts()
	childA := func(h *supervisor.Handle) error { return methodChild(h, st) }
	childB := func(h *supervisor.Handle) error { return panicChild(h, st, shortWait) }

	sup.Go("alpha", childA)
	chsup.Go("beta", childA)
	gchsup.Go("gamma", childB)

	time.Sleep(10 * time.Second)

	err := sup.Stop()
	assert.ErrorMatch(err, `supervisor had .* restarts in .*`, "stopping of 'supervisor-tree'")
	assert.Equal(st.count("alpha"), 4, "starts of 'alpha'")
	assert.Equal(st.count("beta"), 16, "starts of 'beta'")
	assert.Equal(st.count("gamma"), 64, "starts of 'gamma'")
}
Beispiel #7
0
// TestChildren tests the retrieval of the children ids.
func TestChildren(t *testing.T) {
	assert := asserts.NewTestingAsserts(t, true)
	sup := supervisor.NewSupervisor("children", supervisor.OneForOne, 5, time.Second)
	st := newStarts()
	child := func(h *supervisor.Handle) error { return selectChild(h, st) }

	sup.Go("alpha", child)
	sup.Go("beta", child)
	sup.Go("gamma", child)

	children := sup.Children()
	sort.Strings(children)
	assert.Equal(children, []string{"alpha", "beta", "gamma"}, "all children")

	sup.Terminate("beta")
	children = sup.Children()
	sort.Strings(children)
	assert.Equal(children, []string{"alpha", "gamma"}, "children w/o 'beta'")

	err := sup.Stop()
	assert.Nil(err, "stopping of 'children'")
}
Beispiel #8
0
// TestStampede tests a panic with strategy one for all and a large number of children.
func TestStampede(t *testing.T) {
	assert := asserts.NewTestingAsserts(t, true)
	sup := supervisor.NewSupervisor("stampede", supervisor.OneForAll, 5, time.Second)
	st := newStarts()
	childA := func(h *supervisor.Handle) error { return methodChild(h, st) }
	childB := func(h *supervisor.Handle) error { return panicChild(h, st, shortWait) }
	count := 1000

	for i := 0; i < count; i++ {
		id := fmt.Sprintf("alpha-%d", i)
		sup.Go(id, childA)
	}
	sup.Go("beta", childB)

	time.Sleep(2 * time.Second)

	err := sup.Stop()
	assert.Nil(err, "stopping of 'stampede'")
	for i := 0; i < count; i++ {
		id := fmt.Sprintf("alpha-%d", i)
		assert.True(st.count(id) >= 1, "starts of child '"+id+"'")
	}
}