1// +build !windows
2// Copyright 2016 go-dockerclient authors. All rights reserved.
3// Use of this source code is governed by a BSD-style
4// license that can be found in the LICENSE file.
5
6package docker
7
8import (
9	"bufio"
10	"bytes"
11	"io/ioutil"
12	"net"
13	"net/http"
14	"os"
15	"path/filepath"
16	"testing"
17	"time"
18)
19
20func TestExportContainerViaUnixSocket(t *testing.T) {
21	t.Parallel()
22	content := "exported container tar content"
23	var buf []byte
24	out := bytes.NewBuffer(buf)
25	tempSocket := tempfile("export_socket")
26	defer os.Remove(tempSocket)
27	endpoint := "unix://" + tempSocket
28	u, _ := parseEndpoint(endpoint, false)
29	client := Client{
30		HTTPClient:             defaultClient(),
31		Dialer:                 &net.Dialer{},
32		endpoint:               endpoint,
33		endpointURL:            u,
34		SkipServerVersionCheck: true,
35	}
36	listening := make(chan string)
37	done := make(chan int)
38	containerID := "4fa6e0f0c678"
39	go runStreamConnServer(t, "unix", tempSocket, listening, done, containerID)
40	<-listening // wait for server to start
41	opts := ExportContainerOptions{ID: containerID, OutputStream: out}
42	err := client.ExportContainer(opts)
43	<-done // make sure server stopped
44	if err != nil {
45		t.Errorf("ExportContainer: caugh error %#v while exporting container, expected nil", err.Error())
46	}
47	if out.String() != content {
48		t.Errorf("ExportContainer: wrong stdout. Want %#v. Got %#v.", content, out.String())
49	}
50}
51
52func TestStatsTimeoutUnixSocket(t *testing.T) {
53	t.Parallel()
54	tmpdir, err := ioutil.TempDir("", "socket")
55	if err != nil {
56		t.Fatal(err)
57	}
58	defer os.RemoveAll(tmpdir)
59	socketPath := filepath.Join(tmpdir, "docker_test.sock")
60	t.Logf("socketPath=%s", socketPath)
61	l, err := net.Listen("unix", socketPath)
62	if err != nil {
63		t.Fatal(err)
64	}
65	received := make(chan bool)
66	defer l.Close()
67	go func() {
68		conn, connErr := l.Accept()
69		if connErr != nil {
70			t.Logf("Failed to accept connection: %s", connErr)
71			return
72		}
73		breader := bufio.NewReader(conn)
74		req, connErr := http.ReadRequest(breader)
75		if connErr != nil {
76			t.Logf("Failed to read request: %s", connErr)
77			return
78		}
79		if req.URL.Path != "/containers/c/stats" {
80			t.Logf("Wrong URL path for stats: %q", req.URL.Path)
81			return
82		}
83		received <- true
84		time.Sleep(2 * time.Second)
85	}()
86	client, _ := NewClient("unix://" + socketPath)
87	client.SkipServerVersionCheck = true
88	errC := make(chan error, 1)
89	statsC := make(chan *Stats)
90	done := make(chan bool)
91	defer close(done)
92	go func() {
93		errC <- client.Stats(StatsOptions{ID: "c", Stats: statsC, Stream: true, Done: done, Timeout: time.Millisecond})
94		close(errC)
95	}()
96	err = <-errC
97	e, ok := err.(net.Error)
98	if !ok || !e.Timeout() {
99		t.Errorf("Failed to receive timeout error, got %#v", err)
100	}
101	recvTimeout := 2 * time.Second
102	select {
103	case <-received:
104		return
105	case <-time.After(recvTimeout):
106		t.Fatalf("Timeout waiting to receive message after %v", recvTimeout)
107	}
108}
109