func startEchoServerContainer(t *testing.T, proto string) (*daemon.Daemon, *daemon.Container, string) { var ( err error id string outputBuffer = bytes.NewBuffer(nil) strPort string eng = NewTestEngine(t) daemon = mkDaemonFromEngine(eng, t) port = 5554 p nat.Port ) defer func() { if err != nil { daemon.Nuke() } }() for { port += 1 strPort = strconv.Itoa(port) var cmd string if proto == "tcp" { cmd = "socat TCP-LISTEN:" + strPort + ",reuseaddr,fork EXEC:/bin/cat" } else if proto == "udp" { cmd = "socat UDP-RECVFROM:" + strPort + ",fork EXEC:/bin/cat" } else { t.Fatal(fmt.Errorf("Unknown protocol %v", proto)) } ep := make(map[nat.Port]struct{}, 1) p = nat.Port(fmt.Sprintf("%s/%s", strPort, proto)) ep[p] = struct{}{} jobCreate := eng.Job("create") jobCreate.Setenv("Image", unitTestImageID) jobCreate.SetenvList("Cmd", []string{"sh", "-c", cmd}) jobCreate.SetenvList("PortSpecs", []string{fmt.Sprintf("%s/%s", strPort, proto)}) jobCreate.SetenvJson("ExposedPorts", ep) jobCreate.Stdout.Add(outputBuffer) if err := jobCreate.Run(); err != nil { t.Fatal(err) } id = engine.Tail(outputBuffer, 1) // FIXME: this relies on the undocumented behavior of daemon.Create // which will return a nil error AND container if the exposed ports // are invalid. That behavior should be fixed! if id != "" { break } t.Logf("Port %v already in use, trying another one", strPort) } jobStart := eng.Job("start", id) portBindings := make(map[nat.Port][]nat.PortBinding) portBindings[p] = []nat.PortBinding{ {}, } if err := jobStart.SetenvJson("PortsBindings", portBindings); err != nil { t.Fatal(err) } if err := jobStart.Run(); err != nil { t.Fatal(err) } container := daemon.Get(id) if container == nil { t.Fatalf("Couldn't fetch test container %s", id) } setTimeout(t, "Waiting for the container to be started timed out", 2*time.Second, func() { for !container.IsRunning() { time.Sleep(10 * time.Millisecond) } }) // Even if the state is running, lets give some time to lxc to spawn the process container.WaitStop(500 * time.Millisecond) strPort = container.NetworkSettings.Ports[p][0].HostPort return daemon, container, strPort }
func startEchoServerContainer(t *testing.T, proto string) (*daemon.Daemon, *daemon.Container, string) { var ( err error id string strPort string eng = NewTestEngine(t) daemon = mkDaemonFromEngine(eng, t) port = 5554 p nat.Port ) defer func() { if err != nil { daemon.Nuke() } }() for { port += 1 strPort = strconv.Itoa(port) var cmd string if proto == "tcp" { cmd = "socat TCP-LISTEN:" + strPort + ",reuseaddr,fork EXEC:/bin/cat" } else if proto == "udp" { cmd = "socat UDP-RECVFROM:" + strPort + ",fork EXEC:/bin/cat" } else { t.Fatal(fmt.Errorf("Unknown protocol %v", proto)) } ep := make(map[nat.Port]struct{}, 1) p = nat.Port(fmt.Sprintf("%s/%s", strPort, proto)) ep[p] = struct{}{} c := &runconfig.Config{ Image: unitTestImageID, Cmd: runconfig.NewCommand("sh", "-c", cmd), PortSpecs: []string{fmt.Sprintf("%s/%s", strPort, proto)}, ExposedPorts: ep, } id, _, err = daemon.ContainerCreate(unitTestImageID, c, &runconfig.HostConfig{}) // FIXME: this relies on the undocumented behavior of daemon.Create // which will return a nil error AND container if the exposed ports // are invalid. That behavior should be fixed! if id != "" { break } t.Logf("Port %v already in use, trying another one", strPort) } if err := daemon.ContainerStart(id, &runconfig.HostConfig{}); err != nil { t.Fatal(err) } container, err := daemon.Get(id) if err != nil { t.Fatal(err) } setTimeout(t, "Waiting for the container to be started timed out", 2*time.Second, func() { for !container.IsRunning() { time.Sleep(10 * time.Millisecond) } }) // Even if the state is running, lets give some time to lxc to spawn the process container.WaitStop(500 * time.Millisecond) strPort = container.NetworkSettings.Ports[p][0].HostPort return daemon, container, strPort }