consul/test/integration/consul-container/upgrade/healthcheck_test.go

275 lines
8.0 KiB
Go

package consul_container
import (
"context"
"flag"
"fmt"
"testing"
"time"
"github.com/hashicorp/consul/api"
"github.com/hashicorp/consul/integration/consul-container/libs/cluster"
"github.com/hashicorp/consul/integration/consul-container/libs/node"
"github.com/hashicorp/consul/integration/consul-container/libs/utils"
"github.com/hashicorp/consul/sdk/testutil/retry"
"github.com/stretchr/testify/require"
)
var targetImage = flag.String("target-version", "local", "docker image to be used as UUT (unit under test)")
var latestImage = flag.String("latest-version", "latest", "docker image to be used as latest")
const retryTimeout = 10 * time.Second
const retryFrequency = 500 * time.Millisecond
// Test health check GRPC call using Current Servers and Latest GA Clients
func TestCurrentServersWithLatestGAClients(t *testing.T) {
t.Parallel()
numServers := 3
cluster, err := serversCluster(t, numServers, *targetImage)
require.NoError(t, err)
defer Terminate(t, cluster)
numClients := 1
clients, err := clientsCreate(numClients)
client := cluster.Nodes[0].GetClient()
err = cluster.AddNodes(clients)
retry.RunWith(&retry.Timer{Timeout: retryTimeout, Wait: retryFrequency}, t, func(r *retry.R) {
leader, err := cluster.Leader()
require.NoError(r, err)
require.NotEmpty(r, leader)
members, err := client.Agent().Members(false)
require.Len(r, members, 4)
})
serviceName := "api"
err, index := serviceCreate(t, client, serviceName)
ch := make(chan []*api.ServiceEntry)
errCh := make(chan error)
go func() {
service, q, err := client.Health().Service(serviceName, "", false, &api.QueryOptions{WaitIndex: index})
if q.QueryBackend != api.QueryBackendStreaming {
err = fmt.Errorf("invalid backend for this test %s", q.QueryBackend)
}
if err != nil {
errCh <- err
} else {
ch <- service
}
}()
err = client.Agent().ServiceRegister(&api.AgentServiceRegistration{Name: serviceName, Port: 9998})
timer := time.NewTimer(1 * time.Second)
select {
case err := <-errCh:
require.NoError(t, err)
case service := <-ch:
require.Len(t, service, 1)
require.Equal(t, serviceName, service[0].Service.Service)
require.Equal(t, 9998, service[0].Service.Port)
case <-timer.C:
t.Fatalf("test timeout")
}
}
// Test health check GRPC call using Mixed (majority latest) Servers and Latest GA Clients
func TestMixedServersMajorityLatestGAClient(t *testing.T) {
t.Parallel()
var configs []node.Config
configs = append(configs,
node.Config{
HCL: `node_name="` + utils.RandName("consul-server") + `"
log_level="TRACE"
server=true`,
Cmd: []string{"agent", "-client=0.0.0.0"},
Version: *targetImage,
})
for i := 1; i < 3; i++ {
configs = append(configs,
node.Config{
HCL: `node_name="` + utils.RandName("consul-server") + `"
log_level="TRACE"
bootstrap_expect=3
server=true`,
Cmd: []string{"agent", "-client=0.0.0.0"},
Version: *latestImage,
})
}
cluster, err := cluster.New(configs)
require.NoError(t, err)
defer Terminate(t, cluster)
numClients := 1
clients, err := clientsCreate(numClients)
client := clients[0].GetClient()
err = cluster.AddNodes(clients)
retry.RunWith(&retry.Timer{Timeout: retryTimeout, Wait: retryFrequency}, t, func(r *retry.R) {
leader, err := cluster.Leader()
require.NoError(r, err)
require.NotEmpty(r, leader)
members, err := client.Agent().Members(false)
require.Len(r, members, 4)
})
serviceName := "api"
err, index := serviceCreate(t, client, serviceName)
ch := make(chan []*api.ServiceEntry)
errCh := make(chan error)
go func() {
service, q, err := client.Health().Service(serviceName, "", false, &api.QueryOptions{WaitIndex: index})
if q.QueryBackend != api.QueryBackendStreaming {
err = fmt.Errorf("invalid backend for this test %s", q.QueryBackend)
}
if err != nil {
errCh <- err
} else {
ch <- service
}
}()
err = client.Agent().ServiceRegister(&api.AgentServiceRegistration{Name: serviceName, Port: 9998})
timer := time.NewTimer(1 * time.Second)
select {
case err := <-errCh:
require.NoError(t, err)
case service := <-ch:
require.Len(t, service, 1)
require.Equal(t, serviceName, service[0].Service.Service)
require.Equal(t, 9998, service[0].Service.Port)
case <-timer.C:
t.Fatalf("test timeout")
}
}
// Test health check GRPC call using Mixed (majority current) Servers and Latest GA Clients
func TestMixedServersMajorityCurrentGAClient(t *testing.T) {
t.Parallel()
var configs []node.Config
for i := 0; i < 2; i++ {
configs = append(configs,
node.Config{
HCL: `node_name="` + utils.RandName("consul-server") + `"
log_level="TRACE"
bootstrap_expect=3
server=true`,
Cmd: []string{"agent", "-client=0.0.0.0"},
Version: *targetImage,
})
}
configs = append(configs,
node.Config{
HCL: `node_name="` + utils.RandName("consul-server") + `"
log_level="TRACE"
server=true`,
Cmd: []string{"agent", "-client=0.0.0.0"},
Version: *latestImage,
})
cluster, err := cluster.New(configs)
require.NoError(t, err)
defer Terminate(t, cluster)
numClients := 1
clients, err := clientsCreate(numClients)
client := clients[0].GetClient()
err = cluster.AddNodes(clients)
retry.RunWith(&retry.Timer{Timeout: retryTimeout, Wait: retryFrequency}, t, func(r *retry.R) {
leader, err := cluster.Leader()
require.NoError(r, err)
require.NotEmpty(r, leader)
members, err := client.Agent().Members(false)
require.Len(r, members, 4)
})
serviceName := "api"
err, index := serviceCreate(t, client, serviceName)
ch := make(chan []*api.ServiceEntry)
errCh := make(chan error)
go func() {
service, q, err := client.Health().Service(serviceName, "", false, &api.QueryOptions{WaitIndex: index})
if q.QueryBackend != api.QueryBackendStreaming {
err = fmt.Errorf("invalid backend for this test %s", q.QueryBackend)
}
if err != nil {
errCh <- err
} else {
ch <- service
}
}()
err = client.Agent().ServiceRegister(&api.AgentServiceRegistration{Name: serviceName, Port: 9998})
timer := time.NewTimer(1 * time.Second)
select {
case err := <-errCh:
require.NoError(t, err)
case service := <-ch:
require.Len(t, service, 1)
require.Equal(t, serviceName, service[0].Service.Service)
require.Equal(t, 9998, service[0].Service.Port)
case <-timer.C:
t.Fatalf("test timeout")
}
}
func clientsCreate(numClients int) ([]node.Node, error) {
clients := make([]node.Node, numClients)
var err error
for i := 0; i < numClients; i++ {
clients[i], err = node.NewConsulContainer(context.Background(),
node.Config{
HCL: `node_name="` + utils.RandName("consul-client") + `"
log_level="TRACE"`,
Cmd: []string{"agent", "-client=0.0.0.0"},
Version: *targetImage,
})
}
return clients, err
}
func serviceCreate(t *testing.T, client *api.Client, serviceName string) (error, uint64) {
err := client.Agent().ServiceRegister(&api.AgentServiceRegistration{Name: serviceName, Port: 9999})
require.NoError(t, err)
service, meta, err := client.Catalog().Service(serviceName, "", &api.QueryOptions{})
require.NoError(t, err)
require.Len(t, service, 1)
require.Equal(t, serviceName, service[0].ServiceName)
require.Equal(t, 9999, service[0].ServicePort)
return err, meta.LastIndex
}
func serversCluster(t *testing.T, numServers int, image string) (*cluster.Cluster, error) {
var err error
var configs []node.Config
for i := 0; i < numServers; i++ {
configs = append(configs, node.Config{
HCL: `node_name="` + utils.RandName("consul-server") + `"
log_level="TRACE"
bootstrap_expect=3
server=true`,
Cmd: []string{"agent", "-client=0.0.0.0"},
Version: image,
})
}
cluster, err := cluster.New(configs)
require.NoError(t, err)
retry.RunWith(&retry.Timer{Timeout: retryTimeout, Wait: retryFrequency}, t, func(r *retry.R) {
leader, err := cluster.Leader()
require.NoError(r, err)
require.NotEmpty(r, leader)
members, err := cluster.Nodes[0].GetClient().Agent().Members(false)
require.Len(r, members, numServers)
})
return cluster, err
}
func Terminate(t *testing.T, cluster *cluster.Cluster) {
err := cluster.Terminate()
require.NoError(t, err)
}