mirror of
https://github.com/fnproject/fn.git
synced 2022-10-28 21:29:17 +03:00
* fn: experimental prefork recycle and other improvements
*) Recycle and do not use same pool container again option.
*) Two state processing: initializing versus ready (start-kill).
*) Ready state is exempt from rate limiter.
* fn: experimental prefork pool multiple network support
In order to exceed 1023 container (bridge port) limit, add
multiple networks:
for i in fn-net1 fn-net2 fn-net3 fn-net4
do
docker network create $i
done
to Docker startup, (eg. dind preentry.sh), then provide this
to prefork pool using:
export FN_EXPERIMENTAL_PREFORK_NETWORKS="fn-net1 fn-net2 fn-net3 fn-net4"
which should be able to spawn 1023 * 4 containers.
* fn: fixup tests for cfg move
* fn: add ipc and pid namespaces into prefork pooling
* fn: revert ipc and pid namespaces for now
Pid/Ipc opens up the function container to pause container.
149 lines
3.0 KiB
Go
149 lines
3.0 KiB
Go
package docker
|
|
|
|
import (
|
|
"runtime"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/fnproject/fn/api/agent/drivers"
|
|
)
|
|
|
|
func getDefaultCfg() *drivers.Config {
|
|
cfg := &drivers.Config{
|
|
PreForkImage: "busybox",
|
|
PreForkCmd: "tail -f /dev/null",
|
|
}
|
|
return cfg
|
|
}
|
|
|
|
func TestRunnerDockerPool(t *testing.T) {
|
|
if runtime.GOOS != "linux" {
|
|
t.Skip("prefork only supported on Linux")
|
|
return
|
|
}
|
|
|
|
cfg := getDefaultCfg()
|
|
|
|
// shouldn't spin up a pool since cfg is empty
|
|
drv := NewDocker(*cfg)
|
|
|
|
cfg.PreForkPoolSize = 2
|
|
pool := NewDockerPool(*cfg, drv)
|
|
|
|
// primitive wait here
|
|
i := 0
|
|
for ; i < 10; i++ {
|
|
stats := pool.Usage()
|
|
if stats.free == 2 {
|
|
break
|
|
}
|
|
|
|
<-time.After(time.Duration(500) * time.Millisecond)
|
|
}
|
|
if i == 10 {
|
|
t.Fatalf("pool initialize timeout stats=%+v", pool.Usage())
|
|
}
|
|
|
|
id1, err := pool.AllocPoolId()
|
|
if err != nil {
|
|
t.Fatalf("pool AllocPoolId id1 err=%s", err.Error())
|
|
}
|
|
t.Logf("pool AllocPoolId id1=%s", id1)
|
|
|
|
id2, err := pool.AllocPoolId()
|
|
if err != nil {
|
|
t.Fatalf("pool AllocPoolId id2 err=%s", err.Error())
|
|
}
|
|
t.Logf("pool AllocPoolId id2=%s", id2)
|
|
|
|
id3, err := pool.AllocPoolId()
|
|
if err == nil {
|
|
t.Fatalf("pool AllocPoolId id3 should be err, but got id=%s", id3)
|
|
}
|
|
t.Logf("pool AllocPoolId id3=%s", id3)
|
|
|
|
pool.FreePoolId("nonsense")
|
|
|
|
id4, err := pool.AllocPoolId()
|
|
if err == nil {
|
|
t.Fatalf("pool AllocPoolId id4 should be err, but got id=%s", id3)
|
|
}
|
|
t.Logf("pool AllocPoolId id4=%s", id4)
|
|
|
|
pool.FreePoolId(id1)
|
|
|
|
id5, err := pool.AllocPoolId()
|
|
if err != nil {
|
|
t.Fatalf("pool AllocPoolId id5 err=%s", err.Error())
|
|
}
|
|
t.Logf("pool AllocPoolId id5=%s", id5)
|
|
if id5 != id1 {
|
|
t.Fatalf("pool AllocPoolId id5 != id1 (%s != %s)", id5, id1)
|
|
}
|
|
|
|
err = pool.Close()
|
|
if err != nil {
|
|
t.Fatalf("pool close err=%s", err.Error())
|
|
}
|
|
|
|
err = drv.Close()
|
|
if err != nil {
|
|
t.Fatalf("drv close err=%s", err.Error())
|
|
}
|
|
|
|
stats := pool.Usage()
|
|
if stats.free != 0 && stats.inuse != 0 {
|
|
t.Fatalf("pool shutdown timeout stats=%+v", stats)
|
|
}
|
|
}
|
|
|
|
func TestRunnerDockerPoolFaulty(t *testing.T) {
|
|
if runtime.GOOS != "linux" {
|
|
t.Skip("prefork only supported on Linux")
|
|
return
|
|
}
|
|
|
|
cfg := getDefaultCfg()
|
|
|
|
// shouldn't spin up a pool since cfg is empty
|
|
drv := NewDocker(*cfg)
|
|
|
|
cfg.PreForkPoolSize = 2
|
|
cfg.PreForkCmd = "sleep 0"
|
|
|
|
pool := NewDockerPool(*cfg, drv)
|
|
|
|
<-time.After(time.Duration(500) * time.Millisecond)
|
|
|
|
// Not much to see if pre-fork has exited, but let's close
|
|
// and wait at least to make sure we don't crash and burn.
|
|
id1, err := pool.AllocPoolId()
|
|
t.Logf("pool AllocPoolId id=%s err=%v", id1, err)
|
|
if id1 != "" {
|
|
pool.FreePoolId(id1)
|
|
}
|
|
|
|
<-time.After(time.Duration(500) * time.Millisecond)
|
|
|
|
id2, err := pool.AllocPoolId()
|
|
t.Logf("pool AllocPoolId id=%s err=%v", id2, err)
|
|
if id2 != "" {
|
|
pool.FreePoolId(id2)
|
|
}
|
|
|
|
err = pool.Close()
|
|
if err != nil {
|
|
t.Fatalf("pool close err=%s", err.Error())
|
|
}
|
|
|
|
err = drv.Close()
|
|
if err != nil {
|
|
t.Fatalf("drv close err=%s", err.Error())
|
|
}
|
|
|
|
stats := pool.Usage()
|
|
if stats.free != 0 && stats.inuse != 0 {
|
|
t.Fatalf("pool shutdown timeout stats=%+v", stats)
|
|
}
|
|
}
|