mirror of https://github.com/hashicorp/consul
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
231 lines
6.6 KiB
231 lines
6.6 KiB
// Copyright (c) HashiCorp, Inc. |
|
// SPDX-License-Identifier: BUSL-1.1 |
|
|
|
package xds |
|
|
|
import ( |
|
"testing" |
|
|
|
envoy_core_v3 "github.com/envoyproxy/go-control-plane/envoy/config/core/v3" |
|
envoy_endpoint_v3 "github.com/envoyproxy/go-control-plane/envoy/config/endpoint/v3" |
|
"github.com/hashicorp/consul/agent/proxycfg" |
|
"github.com/hashicorp/consul/agent/structs" |
|
"github.com/hashicorp/consul/agent/xds/response" |
|
"github.com/hashicorp/go-hclog" |
|
"github.com/mitchellh/copystructure" |
|
"github.com/stretchr/testify/require" |
|
) |
|
|
|
func Test_makeLoadAssignment(t *testing.T) { |
|
|
|
testCheckServiceNodes := structs.CheckServiceNodes{ |
|
structs.CheckServiceNode{ |
|
Node: &structs.Node{ |
|
ID: "node1-id", |
|
Node: "node1", |
|
Address: "10.10.10.10", |
|
Datacenter: "dc1", |
|
}, |
|
Service: &structs.NodeService{ |
|
Service: "web", |
|
Port: 1234, |
|
}, |
|
Checks: structs.HealthChecks{ |
|
&structs.HealthCheck{ |
|
Node: "node1", |
|
CheckID: "serfHealth", |
|
Status: "passing", |
|
}, |
|
&structs.HealthCheck{ |
|
Node: "node1", |
|
ServiceID: "web", |
|
CheckID: "web:check", |
|
Status: "passing", |
|
}, |
|
}, |
|
}, |
|
structs.CheckServiceNode{ |
|
Node: &structs.Node{ |
|
ID: "node2-id", |
|
Node: "node2", |
|
Address: "10.10.10.20", |
|
Datacenter: "dc1", |
|
}, |
|
Service: &structs.NodeService{ |
|
Service: "web", |
|
Port: 1234, |
|
}, |
|
Checks: structs.HealthChecks{ |
|
&structs.HealthCheck{ |
|
Node: "node2", |
|
CheckID: "serfHealth", |
|
Status: "passing", |
|
}, |
|
&structs.HealthCheck{ |
|
Node: "node2", |
|
ServiceID: "web", |
|
CheckID: "web:check", |
|
Status: "passing", |
|
}, |
|
}, |
|
}, |
|
} |
|
|
|
testWeightedCheckServiceNodesRaw, err := copystructure.Copy(testCheckServiceNodes) |
|
require.NoError(t, err) |
|
testWeightedCheckServiceNodes := testWeightedCheckServiceNodesRaw.(structs.CheckServiceNodes) |
|
|
|
testWeightedCheckServiceNodes[0].Service.Weights = &structs.Weights{ |
|
Passing: 10, |
|
Warning: 1, |
|
} |
|
testWeightedCheckServiceNodes[1].Service.Weights = &structs.Weights{ |
|
Passing: 5, |
|
Warning: 0, |
|
} |
|
|
|
testWarningCheckServiceNodesRaw, err := copystructure.Copy(testWeightedCheckServiceNodes) |
|
require.NoError(t, err) |
|
testWarningCheckServiceNodes := testWarningCheckServiceNodesRaw.(structs.CheckServiceNodes) |
|
|
|
testWarningCheckServiceNodes[0].Checks[0].Status = "warning" |
|
testWarningCheckServiceNodes[1].Checks[0].Status = "warning" |
|
|
|
// TODO(rb): test onlypassing |
|
tests := []struct { |
|
name string |
|
clusterName string |
|
locality *structs.Locality |
|
endpoints []loadAssignmentEndpointGroup |
|
want *envoy_endpoint_v3.ClusterLoadAssignment |
|
}{ |
|
{ |
|
name: "no instances", |
|
clusterName: "service:test", |
|
endpoints: []loadAssignmentEndpointGroup{ |
|
{Endpoints: nil}, |
|
}, |
|
want: &envoy_endpoint_v3.ClusterLoadAssignment{ |
|
ClusterName: "service:test", |
|
Endpoints: []*envoy_endpoint_v3.LocalityLbEndpoints{{ |
|
LbEndpoints: []*envoy_endpoint_v3.LbEndpoint{}, |
|
}}, |
|
}, |
|
}, |
|
{ |
|
name: "instances, no weights", |
|
clusterName: "service:test", |
|
endpoints: []loadAssignmentEndpointGroup{ |
|
{Endpoints: testCheckServiceNodes}, |
|
}, |
|
want: &envoy_endpoint_v3.ClusterLoadAssignment{ |
|
ClusterName: "service:test", |
|
Endpoints: []*envoy_endpoint_v3.LocalityLbEndpoints{{ |
|
LbEndpoints: []*envoy_endpoint_v3.LbEndpoint{ |
|
{ |
|
HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ |
|
Endpoint: &envoy_endpoint_v3.Endpoint{ |
|
Address: response.MakeAddress("10.10.10.10", 1234), |
|
}}, |
|
HealthStatus: envoy_core_v3.HealthStatus_HEALTHY, |
|
LoadBalancingWeight: response.MakeUint32Value(1), |
|
}, |
|
{ |
|
HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ |
|
Endpoint: &envoy_endpoint_v3.Endpoint{ |
|
Address: response.MakeAddress("10.10.10.20", 1234), |
|
}}, |
|
HealthStatus: envoy_core_v3.HealthStatus_HEALTHY, |
|
LoadBalancingWeight: response.MakeUint32Value(1), |
|
}, |
|
}, |
|
}}, |
|
}, |
|
}, |
|
{ |
|
name: "instances, healthy weights", |
|
clusterName: "service:test", |
|
endpoints: []loadAssignmentEndpointGroup{ |
|
{Endpoints: testWeightedCheckServiceNodes}, |
|
}, |
|
want: &envoy_endpoint_v3.ClusterLoadAssignment{ |
|
ClusterName: "service:test", |
|
Endpoints: []*envoy_endpoint_v3.LocalityLbEndpoints{{ |
|
LbEndpoints: []*envoy_endpoint_v3.LbEndpoint{ |
|
{ |
|
HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ |
|
Endpoint: &envoy_endpoint_v3.Endpoint{ |
|
Address: response.MakeAddress("10.10.10.10", 1234), |
|
}}, |
|
HealthStatus: envoy_core_v3.HealthStatus_HEALTHY, |
|
LoadBalancingWeight: response.MakeUint32Value(10), |
|
}, |
|
{ |
|
HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ |
|
Endpoint: &envoy_endpoint_v3.Endpoint{ |
|
Address: response.MakeAddress("10.10.10.20", 1234), |
|
}}, |
|
HealthStatus: envoy_core_v3.HealthStatus_HEALTHY, |
|
LoadBalancingWeight: response.MakeUint32Value(5), |
|
}, |
|
}, |
|
}}, |
|
}, |
|
}, |
|
{ |
|
name: "instances, warning weights", |
|
clusterName: "service:test", |
|
endpoints: []loadAssignmentEndpointGroup{ |
|
{Endpoints: testWarningCheckServiceNodes}, |
|
}, |
|
want: &envoy_endpoint_v3.ClusterLoadAssignment{ |
|
ClusterName: "service:test", |
|
Endpoints: []*envoy_endpoint_v3.LocalityLbEndpoints{{ |
|
LbEndpoints: []*envoy_endpoint_v3.LbEndpoint{ |
|
{ |
|
HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ |
|
Endpoint: &envoy_endpoint_v3.Endpoint{ |
|
Address: response.MakeAddress("10.10.10.10", 1234), |
|
}}, |
|
HealthStatus: envoy_core_v3.HealthStatus_HEALTHY, |
|
LoadBalancingWeight: response.MakeUint32Value(1), |
|
}, |
|
{ |
|
HostIdentifier: &envoy_endpoint_v3.LbEndpoint_Endpoint{ |
|
Endpoint: &envoy_endpoint_v3.Endpoint{ |
|
Address: response.MakeAddress("10.10.10.20", 1234), |
|
}}, |
|
HealthStatus: envoy_core_v3.HealthStatus_UNHEALTHY, |
|
LoadBalancingWeight: response.MakeUint32Value(1), |
|
}, |
|
}, |
|
}}, |
|
}, |
|
}, |
|
} |
|
for _, tt := range tests { |
|
t.Run(tt.name, func(t *testing.T) { |
|
got := makeLoadAssignment( |
|
hclog.NewNullLogger(), |
|
&proxycfg.ConfigSnapshot{ServiceLocality: tt.locality}, |
|
tt.clusterName, |
|
nil, |
|
tt.endpoints, |
|
proxycfg.GatewayKey{Datacenter: "dc1"}, |
|
) |
|
require.Equal(t, tt.want, got) |
|
|
|
if tt.locality == nil { |
|
got := makeLoadAssignment( |
|
hclog.NewNullLogger(), |
|
&proxycfg.ConfigSnapshot{ServiceLocality: &structs.Locality{Region: "us-west-1", Zone: "us-west-1a"}}, |
|
tt.clusterName, |
|
nil, |
|
tt.endpoints, |
|
proxycfg.GatewayKey{Datacenter: "dc1"}, |
|
) |
|
require.Equal(t, tt.want, got) |
|
} |
|
}) |
|
} |
|
}
|
|
|