mirror of
https://github.com/costela/docker-etchosts.git
synced 2025-05-11 01:45:40 +02:00
skip "bridge" and "none" nets; add some tests
This commit is contained in:
parent
f6a14606f1
commit
5eb23ea821
2 changed files with 279 additions and 2 deletions
18
docker.go
18
docker.go
|
@ -18,6 +18,9 @@ type dockerClienter interface {
|
||||||
ContainerList(context.Context, types.ContainerListOptions) ([]types.Container, error)
|
ContainerList(context.Context, types.ContainerListOptions) ([]types.Container, error)
|
||||||
ContainerInspect(context.Context, string) (types.ContainerJSON, error)
|
ContainerInspect(context.Context, string) (types.ContainerJSON, error)
|
||||||
Events(context.Context, types.EventsOptions) (<-chan events.Message, <-chan error)
|
Events(context.Context, types.EventsOptions) (<-chan events.Message, <-chan error)
|
||||||
|
}
|
||||||
|
|
||||||
|
type dockerClientPinger interface {
|
||||||
Ping(context.Context) (types.Ping, error)
|
Ping(context.Context) (types.Ping, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -57,15 +60,26 @@ func getIPsToNames(client dockerClienter, id string) (ipsToNamesMap, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for netName, netInfo := range containerFull.NetworkSettings.Networks {
|
for netName, netInfo := range containerFull.NetworkSettings.Networks {
|
||||||
|
if netName == "none" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
names := make([]string, 0, 4) // 4 is worst-case size if container in a compose project (see below)
|
names := make([]string, 0, 4) // 4 is worst-case size if container in a compose project (see below)
|
||||||
|
|
||||||
|
maybeAppendNet := func(names []string, name string) []string {
|
||||||
|
if netName != "bridge" {
|
||||||
|
return append(names, fmt.Sprintf("%s.%s", name, netName))
|
||||||
|
}
|
||||||
|
return names
|
||||||
|
}
|
||||||
|
|
||||||
appendNames := func(names []string, name string) []string {
|
appendNames := func(names []string, name string) []string {
|
||||||
log.Debugf("found base name %s with IP %s", name, netInfo.IPAddress)
|
log.Debugf("found base name %s with IP %s", name, netInfo.IPAddress)
|
||||||
names = append(names, fmt.Sprintf("%s", name))
|
names = append(names, fmt.Sprintf("%s", name))
|
||||||
names = append(names, fmt.Sprintf("%s.%s", name, netName))
|
names = maybeAppendNet(names, name)
|
||||||
if proj, ok := containerFull.Config.Labels["com.docker.compose.project"]; ok {
|
if proj, ok := containerFull.Config.Labels["com.docker.compose.project"]; ok {
|
||||||
names = append(names, fmt.Sprintf("%s.%s", name, proj))
|
names = append(names, fmt.Sprintf("%s.%s", name, proj))
|
||||||
names = append(names, fmt.Sprintf("%s.%s.%s", name, proj, netName))
|
names = maybeAppendNet(names, fmt.Sprintf("%s.%s", name, proj))
|
||||||
}
|
}
|
||||||
return names
|
return names
|
||||||
}
|
}
|
||||||
|
|
263
docker_test.go
Normal file
263
docker_test.go
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"io/ioutil"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"docker.io/go-docker/api/types"
|
||||||
|
"docker.io/go-docker/api/types/container"
|
||||||
|
"docker.io/go-docker/api/types/events"
|
||||||
|
"docker.io/go-docker/api/types/network"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
)
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
log.SetOutput(ioutil.Discard)
|
||||||
|
}
|
||||||
|
|
||||||
|
type testClient struct{}
|
||||||
|
|
||||||
|
func (testClient) ContainerList(_ context.Context, _ types.ContainerListOptions) ([]types.Container, error) {
|
||||||
|
return []types.Container{
|
||||||
|
{
|
||||||
|
ID: "111",
|
||||||
|
Names: []string{
|
||||||
|
"/someservice",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "222",
|
||||||
|
Names: []string{
|
||||||
|
"/someproject_someservice_1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "333",
|
||||||
|
Names: []string{
|
||||||
|
"/someotherproject_someotherservice_1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ID: "444",
|
||||||
|
Names: []string{
|
||||||
|
"/some_nonnetworked_service",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (testClient) ContainerInspect(_ context.Context, ID string) (types.ContainerJSON, error) {
|
||||||
|
switch ID {
|
||||||
|
case "111":
|
||||||
|
return types.ContainerJSON{
|
||||||
|
ContainerJSONBase: &types.ContainerJSONBase{Name: "service1"},
|
||||||
|
Config: &container.Config{Labels: map[string]string{}},
|
||||||
|
NetworkSettings: &types.NetworkSettings{
|
||||||
|
Networks: map[string]*network.EndpointSettings{
|
||||||
|
"bridge": {
|
||||||
|
IPAddress: "1.2.3.4",
|
||||||
|
Aliases: []string{
|
||||||
|
"somealias",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
case "222":
|
||||||
|
return types.ContainerJSON{
|
||||||
|
ContainerJSONBase: &types.ContainerJSONBase{Name: "service2"},
|
||||||
|
Config: &container.Config{Labels: map[string]string{
|
||||||
|
"com.docker.compose.project": "someproject",
|
||||||
|
}},
|
||||||
|
NetworkSettings: &types.NetworkSettings{
|
||||||
|
Networks: map[string]*network.EndpointSettings{
|
||||||
|
"somenetwork": {
|
||||||
|
IPAddress: "2.3.4.5",
|
||||||
|
Aliases: []string{
|
||||||
|
"somealias1",
|
||||||
|
"nonuniquealias",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
case "333":
|
||||||
|
return types.ContainerJSON{
|
||||||
|
ContainerJSONBase: &types.ContainerJSONBase{Name: "service3"},
|
||||||
|
Config: &container.Config{Labels: map[string]string{
|
||||||
|
"com.docker.compose.project": "someotherproject",
|
||||||
|
}},
|
||||||
|
NetworkSettings: &types.NetworkSettings{
|
||||||
|
Networks: map[string]*network.EndpointSettings{
|
||||||
|
"someothernetwork": {
|
||||||
|
IPAddress: "3.4.5.6",
|
||||||
|
Aliases: []string{
|
||||||
|
"someotheralias1",
|
||||||
|
"nonuniquealias",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"somesecondarynetwork": {
|
||||||
|
IPAddress: "4.5.6.7",
|
||||||
|
Aliases: []string{
|
||||||
|
"somesecondaryalias1",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
case "444":
|
||||||
|
return types.ContainerJSON{
|
||||||
|
ContainerJSONBase: &types.ContainerJSONBase{Name: "service4"},
|
||||||
|
Config: &container.Config{Labels: map[string]string{}},
|
||||||
|
NetworkSettings: &types.NetworkSettings{
|
||||||
|
Networks: map[string]*network.EndpointSettings{
|
||||||
|
"none": {},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}, nil
|
||||||
|
default:
|
||||||
|
panic("whaaa?")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (testClient) Events(context.Context, types.EventsOptions) (<-chan events.Message, <-chan error) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (testClient) Ping(context.Context) (types.Ping, error) {
|
||||||
|
return types.Ping{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type workingPinger struct{}
|
||||||
|
|
||||||
|
func (workingPinger) Ping(_ context.Context) (types.Ping, error) {
|
||||||
|
return types.Ping{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// not safe to use same pinger in multiple parallel tests!
|
||||||
|
type delayedPinger struct{ counter, limit int }
|
||||||
|
|
||||||
|
func (wp *delayedPinger) Ping(_ context.Context) (types.Ping, error) {
|
||||||
|
// some arbitrary number of failures
|
||||||
|
if wp.counter >= wp.limit {
|
||||||
|
return types.Ping{}, nil
|
||||||
|
}
|
||||||
|
wp.counter++
|
||||||
|
return types.Ping{}, errors.New("not working yet")
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_getIPsToNames(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
client dockerClienter
|
||||||
|
id string
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want ipsToNamesMap
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{"simple query1", args{testClient{}, "111"}, ipsToNamesMap{
|
||||||
|
"1.2.3.4": []string{
|
||||||
|
"service1", "somealias",
|
||||||
|
},
|
||||||
|
}, false},
|
||||||
|
{"query with aliases and projects", args{testClient{}, "222"}, ipsToNamesMap{
|
||||||
|
"2.3.4.5": []string{
|
||||||
|
"service2", "service2.somenetwork", "service2.someproject", "service2.someproject.somenetwork",
|
||||||
|
"somealias1", "somealias1.somenetwork", "somealias1.someproject", "somealias1.someproject.somenetwork",
|
||||||
|
"nonuniquealias", "nonuniquealias.somenetwork", "nonuniquealias.someproject", "nonuniquealias.someproject.somenetwork",
|
||||||
|
},
|
||||||
|
}, false},
|
||||||
|
{"query with 2 networks", args{testClient{}, "333"}, ipsToNamesMap{
|
||||||
|
"3.4.5.6": []string{
|
||||||
|
"service3", "service3.someothernetwork", "service3.someotherproject", "service3.someotherproject.someothernetwork",
|
||||||
|
"someotheralias1", "someotheralias1.someothernetwork", "someotheralias1.someotherproject", "someotheralias1.someotherproject.someothernetwork",
|
||||||
|
"nonuniquealias", "nonuniquealias.someothernetwork", "nonuniquealias.someotherproject", "nonuniquealias.someotherproject.someothernetwork",
|
||||||
|
},
|
||||||
|
"4.5.6.7": []string{
|
||||||
|
"service3", "service3.somesecondarynetwork", "service3.someotherproject", "service3.someotherproject.somesecondarynetwork",
|
||||||
|
"somesecondaryalias1", "somesecondaryalias1.somesecondarynetwork", "somesecondaryalias1.someotherproject", "somesecondaryalias1.someotherproject.somesecondarynetwork",
|
||||||
|
},
|
||||||
|
}, false},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := getIPsToNames(tt.args.client, tt.args.id)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("getIPsToNames() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("getIPsToNames():\n%v\nwant:\n%v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_getAllIPsToNames(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
client dockerClienter
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
want ipsToNamesMap
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{"simple query1", args{testClient{}}, ipsToNamesMap{
|
||||||
|
"1.2.3.4": []string{"service1", "somealias"},
|
||||||
|
"2.3.4.5": []string{
|
||||||
|
"service2", "service2.somenetwork", "service2.someproject", "service2.someproject.somenetwork",
|
||||||
|
"somealias1", "somealias1.somenetwork", "somealias1.someproject", "somealias1.someproject.somenetwork",
|
||||||
|
"nonuniquealias", "nonuniquealias.somenetwork", "nonuniquealias.someproject", "nonuniquealias.someproject.somenetwork",
|
||||||
|
},
|
||||||
|
"3.4.5.6": []string{
|
||||||
|
"service3", "service3.someothernetwork", "service3.someotherproject", "service3.someotherproject.someothernetwork",
|
||||||
|
"someotheralias1", "someotheralias1.someothernetwork", "someotheralias1.someotherproject", "someotheralias1.someotherproject.someothernetwork",
|
||||||
|
"nonuniquealias", "nonuniquealias.someothernetwork", "nonuniquealias.someotherproject", "nonuniquealias.someotherproject.someothernetwork",
|
||||||
|
},
|
||||||
|
"4.5.6.7": []string{
|
||||||
|
"service3", "service3.somesecondarynetwork", "service3.someotherproject", "service3.someotherproject.somesecondarynetwork",
|
||||||
|
"somesecondaryalias1", "somesecondaryalias1.somesecondarynetwork", "somesecondaryalias1.someotherproject", "somesecondaryalias1.someotherproject.somesecondarynetwork",
|
||||||
|
},
|
||||||
|
}, false},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := getAllIPsToNames(tt.args.client)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("getAllIPsToNames() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if !reflect.DeepEqual(got, tt.want) {
|
||||||
|
t.Errorf("getAllIPsToNames() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func Test_waitForConnection(t *testing.T) {
|
||||||
|
type args struct {
|
||||||
|
client dockerClientPinger
|
||||||
|
}
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
long bool // whether this test is "long-running"
|
||||||
|
}{
|
||||||
|
{"connection working", args{workingPinger{}}, false},
|
||||||
|
{"delayed connection", args{&delayedPinger{limit: 5}}, true},
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
if tt.long && testing.Short() {
|
||||||
|
t.Skip()
|
||||||
|
}
|
||||||
|
waitForConnection(tt.args.client)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue