Fixes #505 - Make sure all output is send on the network before closing

This commit is contained in:
Guillaume J. Charmes 2013-07-24 15:48:18 -07:00
Родитель 6ae3305040
Коммит fd9ad1a194
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B33E4642CB6E3FF3
4 изменённых файлов: 34 добавлений и 15 удалений

Просмотреть файл

@ -895,6 +895,12 @@ func TestPostContainersAttach(t *testing.T) {
stdin, stdinPipe := io.Pipe()
stdout, stdoutPipe := io.Pipe()
// Try to avoid the timeoout in destroy. Best effort, don't check error
defer func() {
closeWrap(stdin, stdinPipe, stdout, stdoutPipe)
container.Kill()
}()
// Attach to it
c1 := make(chan struct{})
go func() {
@ -934,7 +940,7 @@ func TestPostContainersAttach(t *testing.T) {
}
// Wait for attach to finish, the client disconnected, therefore, Attach finished his job
setTimeout(t, "Waiting for CmdAttach timed out", 2*time.Second, func() {
setTimeout(t, "Waiting for CmdAttach timed out", 10*time.Second, func() {
<-c1
})

Просмотреть файл

@ -379,14 +379,15 @@ func (container *Container) Attach(stdin io.ReadCloser, stdinCloser io.Closer, s
utils.Debugf("[start] attach stdin\n")
defer utils.Debugf("[end] attach stdin\n")
// No matter what, when stdin is closed (io.Copy unblock), close stdout and stderr
if cStdout != nil {
defer cStdout.Close()
}
if cStderr != nil {
defer cStderr.Close()
}
if container.Config.StdinOnce && !container.Config.Tty {
defer cStdin.Close()
} else {
if cStdout != nil {
defer cStdout.Close()
}
if cStderr != nil {
defer cStderr.Close()
}
}
if container.Config.Tty {
_, err = utils.CopyEscapable(cStdin, stdin)

Просмотреть файл

@ -8,6 +8,7 @@ import (
"log"
"net"
"os"
"runtime"
"strconv"
"strings"
"sync"
@ -25,7 +26,11 @@ const (
testDaemonProto = "tcp"
)
var globalRuntime *Runtime
var (
globalRuntime *Runtime
startFds int
startGoroutines int
)
func nuke(runtime *Runtime) error {
var wg sync.WaitGroup
@ -80,21 +85,21 @@ func init() {
NetworkBridgeIface = unitTestNetworkBridge
// Make it our Store root
runtime, err := NewRuntimeFromDirectory(unitTestStoreBase, false)
if err != nil {
if runtime, err := NewRuntimeFromDirectory(unitTestStoreBase, false); err != nil {
panic(err)
} else {
globalRuntime = runtime
}
globalRuntime = runtime
// Create the "Server"
srv := &Server{
runtime: runtime,
runtime: globalRuntime,
enableCors: false,
pullingPool: make(map[string]struct{}),
pushingPool: make(map[string]struct{}),
}
// If the unit test is not found, try to download it.
if img, err := runtime.repositories.LookupImage(unitTestImageName); err != nil || img.ID != unitTestImageID {
if img, err := globalRuntime.repositories.LookupImage(unitTestImageName); err != nil || img.ID != unitTestImageID {
// Retrieve the Image
if err := srv.ImagePull(unitTestImageName, "", os.Stdout, utils.NewStreamFormatter(false), nil); err != nil {
panic(err)
@ -109,6 +114,8 @@ func init() {
// Give some time to ListenAndServer to actually start
time.Sleep(time.Second)
startFds, startGoroutines = utils.GetTotalUsedFds(), runtime.NumGoroutine()
}
// FIXME: test that ImagePull(json=true) send correct json output

Просмотреть файл

@ -6,7 +6,12 @@ import (
"testing"
)
func TestFinal(t *testing.T) {
cleanup(globalRuntime)
func displayFdGoroutines(t *testing.T) {
t.Logf("Fds: %d, Goroutines: %d", utils.GetTotalUsedFds(), runtime.NumGoroutine())
}
func TestFinal(t *testing.T) {
cleanup(globalRuntime)
t.Logf("Start Fds: %d, Start Goroutines: %d", startFds, startGoroutines)
displayFdGoroutines(t)
}