Files

78 lines
2.5 KiB
Go

package dns
import (
"reflect"
"testing"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/network"
"github.com/psviderski/uncloud/internal/machine/store"
"github.com/psviderski/uncloud/pkg/api"
"github.com/stretchr/testify/assert"
)
func TestClusterResolver_UpdateServiceIPs(t *testing.T) {
t.Parallel()
containers := []store.ContainerRecord{
newRecord("svc-id-1", "web", "10.210.0.2", "mach-1"),
newRecord("svc-id-1", "web", "10.210.0.3", "mach-2"),
newRecord("svc-id-2", "api", "10.210.1.2", "mach-1"),
}
r := NewClusterResolver(nil)
r.updateServiceIPs(containers)
firstMapPtr := reflect.ValueOf(r.serviceIPs).Pointer()
assert.NotZero(t, firstMapPtr, "first call should populate the map")
assert.NotEmpty(t, r.Resolve("web"))
assert.NotEmpty(t, r.Resolve("api"))
// Second call with the same input must not swap the map.
r.updateServiceIPs(containers)
assert.Equal(t, firstMapPtr, reflect.ValueOf(r.serviceIPs).Pointer(),
"second call with identical input must not rewrite the map")
// Reordering the input also must not rewrite the map.
reordered := []store.ContainerRecord{containers[2], containers[0], containers[1]}
r.updateServiceIPs(reordered)
assert.Equal(t, firstMapPtr, reflect.ValueOf(r.serviceIPs).Pointer(),
"reordered input with same containers must not rewrite the map")
// A real change must rewrite the map.
changed := append([]store.ContainerRecord{}, containers...)
changed = append(changed, newRecord("svc-id-3", "db", "10.210.2.2", "mach-1"))
r.updateServiceIPs(changed)
assert.NotEqual(t, firstMapPtr, reflect.ValueOf(r.serviceIPs).Pointer(),
"adding a new service should rewrite the map")
assert.NotEmpty(t, r.Resolve("db"))
}
func newRecord(serviceID, serviceName, ip, machineID string) store.ContainerRecord {
return store.ContainerRecord{
Container: api.ServiceContainer{
Container: api.Container{
InspectResponse: container.InspectResponse{
ContainerJSONBase: &container.ContainerJSONBase{
ID: serviceName + "-" + ip,
State: &container.State{Running: true},
},
NetworkSettings: &container.NetworkSettings{
Networks: map[string]*network.EndpointSettings{
// Hardcoded to avoid an import cycle via internal/machine/docker.
"uncloud": {IPAddress: ip},
},
},
Config: &container.Config{
Labels: map[string]string{
api.LabelServiceID: serviceID,
api.LabelServiceName: serviceName,
},
},
},
},
},
MachineID: machineID,
}
}