Tests are working again
This commit is contained in:
@@ -4,27 +4,23 @@ import (
|
||||
"archive/tar"
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/distribution/reference"
|
||||
"github.com/docker/docker/api"
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/docker/docker/api/types/container"
|
||||
"github.com/docker/docker/api/types/network"
|
||||
"github.com/docker/docker/api/types/swarm"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/docker/pkg/jsonmessage"
|
||||
"github.com/docker/go-connections/tlsconfig"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -49,7 +45,6 @@ type DockerApi interface {
|
||||
DisconnectNetwork(containerId, networkId string) error
|
||||
DeleteNetwork(id string) error
|
||||
Exec(instanceName string, command []string) (int, error)
|
||||
New(ip string, cert, key []byte) (DockerApi, error)
|
||||
SwarmInit() (*SwarmTokens, error)
|
||||
SwarmJoin(addr, token string) error
|
||||
}
|
||||
@@ -411,6 +406,7 @@ func (d *docker) DeleteNetwork(id string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
func (d *docker) New(ip string, cert, key []byte) (DockerApi, error) {
|
||||
// We check if the client needs to use TLS
|
||||
var tlsConfig *tls.Config
|
||||
@@ -454,7 +450,7 @@ func (d *docker) New(ip string, cert, key []byte) (DockerApi, error) {
|
||||
}
|
||||
return NewDocker(c), nil
|
||||
}
|
||||
|
||||
*/
|
||||
func (d *docker) SwarmInit() (*SwarmTokens, error) {
|
||||
req := swarm.InitRequest{AdvertiseAddr: "eth0", ListenAddr: "0.0.0.0:2377"}
|
||||
_, err := d.c.SwarmInit(context.Background(), req)
|
||||
|
||||
6
docker/factory.go
Normal file
6
docker/factory.go
Normal file
@@ -0,0 +1,6 @@
|
||||
package docker
|
||||
|
||||
type FactoryApi interface {
|
||||
GetForSession(sessionId string) (DockerApi, error)
|
||||
GetForInstance(sessionId, instanceName string) (DockerApi, error)
|
||||
}
|
||||
17
docker/factory_mock.go
Normal file
17
docker/factory_mock.go
Normal file
@@ -0,0 +1,17 @@
|
||||
package docker
|
||||
|
||||
import "github.com/stretchr/testify/mock"
|
||||
|
||||
type FactoryMock struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (m *FactoryMock) GetForSession(sessionId string) (DockerApi, error) {
|
||||
args := m.Called(sessionId)
|
||||
return args.Get(0).(DockerApi), args.Error(1)
|
||||
}
|
||||
|
||||
func (m *FactoryMock) GetForInstance(sessionId, instanceName string) (DockerApi, error) {
|
||||
args := m.Called(sessionId, instanceName)
|
||||
return args.Get(0).(DockerApi), args.Error(1)
|
||||
}
|
||||
120
docker/local_cached_factory.go
Normal file
120
docker/local_cached_factory.go
Normal file
@@ -0,0 +1,120 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"log"
|
||||
"net"
|
||||
"net/http"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api"
|
||||
"github.com/docker/docker/client"
|
||||
"github.com/docker/go-connections/tlsconfig"
|
||||
"github.com/play-with-docker/play-with-docker/router"
|
||||
"github.com/play-with-docker/play-with-docker/storage"
|
||||
)
|
||||
|
||||
type localCachedFactory struct {
|
||||
rw sync.Mutex
|
||||
sessionClient DockerApi
|
||||
instanceClients map[string]DockerApi
|
||||
storage storage.StorageApi
|
||||
}
|
||||
|
||||
func (f *localCachedFactory) GetForSession(sessionId string) (DockerApi, error) {
|
||||
f.rw.Lock()
|
||||
defer f.rw.Unlock()
|
||||
|
||||
if f.sessionClient != nil {
|
||||
return f.sessionClient, nil
|
||||
}
|
||||
|
||||
c, err := client.NewEnvClient()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = f.check(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
d := NewDocker(c)
|
||||
f.sessionClient = d
|
||||
return f.sessionClient, nil
|
||||
}
|
||||
|
||||
func (f *localCachedFactory) GetForInstance(sessionId, instanceName string) (DockerApi, error) {
|
||||
f.rw.Lock()
|
||||
defer f.rw.Unlock()
|
||||
|
||||
c, found := f.instanceClients[sessionId+instanceName]
|
||||
if found {
|
||||
return c, nil
|
||||
}
|
||||
|
||||
instance, err := f.storage.InstanceFind(sessionId, instanceName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// Need to create client to the DinD docker daemon
|
||||
// We check if the client needs to use TLS
|
||||
var tlsConfig *tls.Config
|
||||
if len(instance.Cert) > 0 && len(instance.Key) > 0 {
|
||||
tlsConfig = tlsconfig.ClientDefault()
|
||||
tlsConfig.InsecureSkipVerify = true
|
||||
tlsCert, err := tls.X509KeyPair(instance.Cert, instance.Key)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not load X509 key pair: %v. Make sure the key is not encrypted", err)
|
||||
}
|
||||
tlsConfig.Certificates = []tls.Certificate{tlsCert}
|
||||
}
|
||||
|
||||
transport := &http.Transport{
|
||||
DialContext: (&net.Dialer{
|
||||
Timeout: 1 * time.Second,
|
||||
KeepAlive: 30 * time.Second,
|
||||
}).DialContext}
|
||||
if tlsConfig != nil {
|
||||
transport.TLSClientConfig = tlsConfig
|
||||
}
|
||||
cli := &http.Client{
|
||||
Transport: transport,
|
||||
}
|
||||
dc, err := client.NewClient(fmt.Sprintf("http://%s:443", instance.Session.Host), api.DefaultVersion, cli, map[string]string{"Host": router.EncodeHost(instance.SessionId, instance.IP, router.HostOpts{EncodedPort: 2375})})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Could not connect to DinD docker daemon", err)
|
||||
}
|
||||
err = f.check(dc)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
f.instanceClients[sessionId+instance.Name] = NewDocker(dc)
|
||||
|
||||
return f.instanceClients[instance.Name], nil
|
||||
}
|
||||
|
||||
func (f *localCachedFactory) check(c *client.Client) error {
|
||||
for i := 0; i < 5; i++ {
|
||||
_, err := c.Ping(context.Background())
|
||||
if err != nil {
|
||||
if client.IsErrConnectionFailed(err) {
|
||||
// connection has failed, maybe instance is not ready yet, sleep and retry
|
||||
log.Printf("Connection to [%s] has failed, maybe instance is not ready yet, sleeping and retrying in 1 second. Try #%d\n", c.DaemonHost(), i+1)
|
||||
time.Sleep(time.Second)
|
||||
continue
|
||||
}
|
||||
return err
|
||||
}
|
||||
break
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func NewLocalCachedFactory(s storage.StorageApi) *localCachedFactory {
|
||||
return &localCachedFactory{
|
||||
instanceClients: make(map[string]DockerApi),
|
||||
storage: s,
|
||||
}
|
||||
}
|
||||
122
docker/mock.go
Normal file
122
docker/mock.go
Normal file
@@ -0,0 +1,122 @@
|
||||
package docker
|
||||
|
||||
import (
|
||||
"io"
|
||||
"net"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/api/types"
|
||||
"github.com/stretchr/testify/mock"
|
||||
)
|
||||
|
||||
type Mock struct {
|
||||
mock.Mock
|
||||
}
|
||||
|
||||
func (m *Mock) CreateNetwork(id string) error {
|
||||
args := m.Called(id)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
func (m *Mock) ConnectNetwork(container, network, ip string) (string, error) {
|
||||
args := m.Called(container, network, ip)
|
||||
return args.String(0), args.Error(1)
|
||||
}
|
||||
|
||||
func (m *Mock) GetDaemonInfo() (types.Info, error) {
|
||||
args := m.Called()
|
||||
return args.Get(0).(types.Info), args.Error(1)
|
||||
}
|
||||
|
||||
func (m *Mock) GetSwarmPorts() ([]string, []uint16, error) {
|
||||
args := m.Called()
|
||||
return args.Get(0).([]string), args.Get(1).([]uint16), args.Error(2)
|
||||
}
|
||||
|
||||
func (m *Mock) GetPorts() ([]uint16, error) {
|
||||
args := m.Called()
|
||||
return args.Get(0).([]uint16), args.Error(1)
|
||||
}
|
||||
func (m *Mock) GetContainerStats(name string) (io.ReadCloser, error) {
|
||||
args := m.Called(name)
|
||||
return args.Get(0).(io.ReadCloser), args.Error(1)
|
||||
}
|
||||
func (m *Mock) ContainerResize(name string, rows, cols uint) error {
|
||||
args := m.Called(name, rows, cols)
|
||||
return args.Error(0)
|
||||
}
|
||||
func (m *Mock) CreateAttachConnection(name string) (net.Conn, error) {
|
||||
args := m.Called(name)
|
||||
return args.Get(0).(net.Conn), args.Error(1)
|
||||
}
|
||||
func (m *Mock) CopyToContainer(containerName, destination, fileName string, content io.Reader) error {
|
||||
args := m.Called(containerName, destination, fileName, content)
|
||||
return args.Error(0)
|
||||
}
|
||||
func (m *Mock) DeleteContainer(id string) error {
|
||||
args := m.Called(id)
|
||||
return args.Error(0)
|
||||
}
|
||||
func (m *Mock) CreateContainer(opts CreateContainerOpts) (string, error) {
|
||||
args := m.Called(opts)
|
||||
return args.String(0), args.Error(1)
|
||||
}
|
||||
func (m *Mock) ExecAttach(instanceName string, command []string, out io.Writer) (int, error) {
|
||||
args := m.Called(instanceName, command, out)
|
||||
return args.Int(0), args.Error(1)
|
||||
}
|
||||
func (m *Mock) DisconnectNetwork(containerId, networkId string) error {
|
||||
args := m.Called(containerId, networkId)
|
||||
return args.Error(0)
|
||||
}
|
||||
func (m *Mock) DeleteNetwork(id string) error {
|
||||
args := m.Called(id)
|
||||
return args.Error(0)
|
||||
}
|
||||
func (m *Mock) Exec(instanceName string, command []string) (int, error) {
|
||||
args := m.Called(instanceName, command)
|
||||
return args.Int(0), args.Error(1)
|
||||
}
|
||||
func (m *Mock) SwarmInit() (*SwarmTokens, error) {
|
||||
args := m.Called()
|
||||
return args.Get(0).(*SwarmTokens), args.Error(1)
|
||||
}
|
||||
func (m *Mock) SwarmJoin(addr, token string) error {
|
||||
args := m.Called(addr, token)
|
||||
return args.Error(0)
|
||||
}
|
||||
|
||||
type MockConn struct {
|
||||
}
|
||||
|
||||
func (m *MockConn) Read(b []byte) (n int, err error) {
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
func (m *MockConn) Write(b []byte) (n int, err error) {
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
func (m *MockConn) Close() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MockConn) LocalAddr() net.Addr {
|
||||
return &net.IPAddr{}
|
||||
}
|
||||
|
||||
func (m *MockConn) RemoteAddr() net.Addr {
|
||||
return &net.IPAddr{}
|
||||
}
|
||||
|
||||
func (m *MockConn) SetDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MockConn) SetReadDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (m *MockConn) SetWriteDeadline(t time.Time) error {
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user