mirror of
https://github.com/go-micro/go-micro.git
synced 2025-06-12 22:07:47 +02:00
add all the plugins
This commit is contained in:
497
plugins/registry/kubernetes/kubernetes_test.go
Normal file
497
plugins/registry/kubernetes/kubernetes_test.go
Normal file
@ -0,0 +1,497 @@
|
||||
package kubernetes
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
log "github.com/micro/go-micro/v2/logger"
|
||||
"github.com/micro/go-micro/v2/registry"
|
||||
"github.com/micro/go-micro/v2/router"
|
||||
"github.com/micro/go-micro/plugins/registry/kubernetes/v2/client"
|
||||
"github.com/micro/go-micro/plugins/registry/kubernetes/v2/client/mock"
|
||||
)
|
||||
|
||||
var (
|
||||
mockClient = mock.NewClient()
|
||||
podIP = 1
|
||||
)
|
||||
|
||||
func setupPod(name string) *client.Pod {
|
||||
p, ok := mockClient.Pods[name]
|
||||
if ok || p != nil {
|
||||
return p
|
||||
}
|
||||
|
||||
// inc pod
|
||||
podIP++
|
||||
|
||||
p = &client.Pod{
|
||||
Metadata: &client.Meta{
|
||||
Name: name,
|
||||
Labels: make(map[string]*string),
|
||||
Annotations: make(map[string]*string),
|
||||
},
|
||||
Status: &client.Status{
|
||||
PodIP: "10.0.0." + strconv.Itoa(podIP),
|
||||
Phase: podRunning,
|
||||
},
|
||||
}
|
||||
|
||||
mockClient.Pods[name] = p
|
||||
return p
|
||||
}
|
||||
|
||||
// registers a service against a given pod
|
||||
func register(r registry.Registry, podName string, svc *registry.Service) {
|
||||
os.Setenv("HOSTNAME", podName)
|
||||
|
||||
pod := setupPod(podName)
|
||||
|
||||
svc.Nodes = append(svc.Nodes, ®istry.Node{
|
||||
Id: svc.Name + ":" + pod.Metadata.Name,
|
||||
Address: fmt.Sprintf("%s:%d", pod.Status.PodIP, 80),
|
||||
Metadata: map[string]string{},
|
||||
})
|
||||
|
||||
if err := r.Register(svc); err != nil {
|
||||
log.Fatalf("did not expect Register() to fail: %v", err)
|
||||
}
|
||||
|
||||
os.Setenv("HOSTNAME", "")
|
||||
}
|
||||
|
||||
func teardownRegistry() {
|
||||
mock.Teardown(mockClient)
|
||||
}
|
||||
|
||||
func setupRegistry(opts ...registry.Option) registry.Registry {
|
||||
return &kregistry{
|
||||
client: mockClient,
|
||||
timeout: time.Second * 1,
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// Tests start here
|
||||
//
|
||||
//
|
||||
|
||||
func TestRegister(t *testing.T) {
|
||||
r := setupRegistry()
|
||||
defer teardownRegistry()
|
||||
|
||||
svc := ®istry.Service{Name: "foo.service", Version: "1"}
|
||||
register(r, "pod-1", svc)
|
||||
|
||||
// check pod has correct labels/annotations
|
||||
p := mockClient.Pods["pod-1"]
|
||||
svcLabel, ok := p.Metadata.Labels[svcSelectorPrefix+"foo.service"]
|
||||
if !ok || *svcLabel != svcSelectorValue {
|
||||
t.Fatalf("expected to have pod selector label")
|
||||
}
|
||||
|
||||
svcData, ok := p.Metadata.Annotations[annotationServiceKeyPrefix+"foo.service"]
|
||||
if !ok || len(*svcData) == 0 {
|
||||
t.Fatalf("expected to have annotation")
|
||||
}
|
||||
|
||||
// unmarshal service data from annotation and compare
|
||||
// service passed in to .Register()
|
||||
var service *registry.Service
|
||||
if err := json.Unmarshal([]byte(*svcData), &service); err != nil {
|
||||
t.Fatalf("did not expect register unmarshal to fail %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(svc, service) {
|
||||
t.Fatal("services did not match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegisterTwoDifferentServicesOnePod(t *testing.T) {
|
||||
r := setupRegistry()
|
||||
defer teardownRegistry()
|
||||
|
||||
svc1 := ®istry.Service{Name: "foo.service"}
|
||||
svc2 := ®istry.Service{Name: "bar.service"}
|
||||
|
||||
register(r, "pod-1", svc1)
|
||||
register(r, "pod-1", svc2)
|
||||
|
||||
// check pod has correct labels/annotations
|
||||
p := mockClient.Pods["pod-1"]
|
||||
if svcLabel1, ok := p.Metadata.Labels[svcSelectorPrefix+"foo.service"]; !ok || *svcLabel1 != svcSelectorValue {
|
||||
t.Fatalf("expected to have pod selector label for service one")
|
||||
}
|
||||
if svcLabel2, ok := p.Metadata.Labels[svcSelectorPrefix+"bar.service"]; !ok || *svcLabel2 != svcSelectorValue {
|
||||
t.Fatalf("expected to have pod selector label for service two")
|
||||
}
|
||||
svcData1, ok := p.Metadata.Annotations[annotationServiceKeyPrefix+"foo.service"]
|
||||
if !ok || len(*svcData1) == 0 {
|
||||
t.Fatalf("expected to have annotation")
|
||||
}
|
||||
svcData2, ok := p.Metadata.Annotations[annotationServiceKeyPrefix+"bar.service"]
|
||||
if !ok || len(*svcData1) == 0 {
|
||||
t.Fatalf("expected to have annotation")
|
||||
}
|
||||
|
||||
// unmarshal service data from annotation and compare
|
||||
// service passed in to .Register()
|
||||
var service1 *registry.Service
|
||||
if err := json.Unmarshal([]byte(*svcData1), &service1); err != nil {
|
||||
t.Fatalf("did not expect register unmarshal to fail %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(svc1, service1) {
|
||||
t.Fatal("services did not match")
|
||||
}
|
||||
|
||||
var service2 *registry.Service
|
||||
if err := json.Unmarshal([]byte(*svcData2), &service2); err != nil {
|
||||
t.Fatalf("did not expect register unmarshal to fail %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(svc2, service2) {
|
||||
t.Fatal("services did not match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegisterTwoDifferentServicesTwoPods(t *testing.T) {
|
||||
r := setupRegistry()
|
||||
defer teardownRegistry()
|
||||
|
||||
svc1 := ®istry.Service{Name: "foo.service"}
|
||||
svc2 := ®istry.Service{Name: "bar.service"}
|
||||
register(r, "pod-1", svc1)
|
||||
register(r, "pod-2", svc2)
|
||||
|
||||
// check pod-1 has correct labels/annotations
|
||||
p1 := mockClient.Pods["pod-1"]
|
||||
if svcLabel1, ok := p1.Metadata.Labels[svcSelectorPrefix+"foo.service"]; !ok || *svcLabel1 != svcSelectorValue {
|
||||
t.Fatalf("expected to have pod selector label for foo.service")
|
||||
}
|
||||
if _, ok := p1.Metadata.Labels[svcSelectorPrefix+"bar.service"]; ok {
|
||||
t.Fatal("pod 1 shouldnt have label for bar.service")
|
||||
}
|
||||
|
||||
// check pod-2 has correct labels/annotations
|
||||
p2 := mockClient.Pods["pod-2"]
|
||||
if svcLabel2, ok := p2.Metadata.Labels[svcSelectorPrefix+"bar.service"]; !ok || *svcLabel2 != svcSelectorValue {
|
||||
t.Fatalf("expected to have pod selector label for bar.service")
|
||||
}
|
||||
if _, ok := p2.Metadata.Labels[svcSelectorPrefix+"foo.service"]; ok {
|
||||
t.Fatal("pod 2 shouldnt have label for foo.service")
|
||||
}
|
||||
|
||||
svcData1, ok := p1.Metadata.Annotations[annotationServiceKeyPrefix+"foo.service"]
|
||||
if !ok || len(*svcData1) == 0 {
|
||||
t.Fatalf("expected to have annotation")
|
||||
}
|
||||
if _, okp2 := p1.Metadata.Annotations[annotationServiceKeyPrefix+"bar.service"]; okp2 {
|
||||
t.Fatal("bar.service shouldnt have annotation for pod2")
|
||||
}
|
||||
|
||||
svcData2, ok := p2.Metadata.Annotations[annotationServiceKeyPrefix+"bar.service"]
|
||||
if !ok || len(*svcData2) == 0 {
|
||||
t.Fatalf("expected to have annotation")
|
||||
}
|
||||
if _, okp1 := p2.Metadata.Annotations[annotationServiceKeyPrefix+"foo.service"]; okp1 {
|
||||
t.Fatal("bar.service shouldnt have annotation for pod1")
|
||||
}
|
||||
|
||||
// unmarshal service data from annotation and compare
|
||||
// service passed in to .Register()
|
||||
var service1 *registry.Service
|
||||
if err := json.Unmarshal([]byte(*svcData1), &service1); err != nil {
|
||||
t.Fatalf("did not expect register unmarshal to fail %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(svc1, service1) {
|
||||
t.Fatal("services did not match")
|
||||
}
|
||||
|
||||
var service2 *registry.Service
|
||||
if err := json.Unmarshal([]byte(*svcData2), &service2); err != nil {
|
||||
t.Fatalf("did not expect register unmarshal to fail %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(svc2, service2) {
|
||||
t.Fatal("services did not match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestRegisterSingleVersionedServiceTwoPods(t *testing.T) {
|
||||
r := setupRegistry()
|
||||
defer teardownRegistry()
|
||||
|
||||
svc1 := ®istry.Service{Name: "foo.service"}
|
||||
svc2 := ®istry.Service{Name: "foo.service"}
|
||||
register(r, "pod-1", svc1)
|
||||
register(r, "pod-2", svc2)
|
||||
|
||||
// check pod-1 has correct labels/annotations
|
||||
p1 := mockClient.Pods["pod-1"]
|
||||
if svcLabel1, ok := p1.Metadata.Labels[svcSelectorPrefix+"foo.service"]; !ok || *svcLabel1 != svcSelectorValue {
|
||||
t.Fatalf("expected to have pod selector label for foo.service")
|
||||
}
|
||||
|
||||
// check pod-2 has correct labels/annotations
|
||||
p2 := mockClient.Pods["pod-2"]
|
||||
if svcLabel2, ok := p2.Metadata.Labels[svcSelectorPrefix+"foo.service"]; !ok || *svcLabel2 != svcSelectorValue {
|
||||
t.Fatalf("expected to have pod selector label for foo.service")
|
||||
}
|
||||
|
||||
svcData1, ok := p1.Metadata.Annotations[annotationServiceKeyPrefix+"foo.service"]
|
||||
if !ok || len(*svcData1) == 0 {
|
||||
t.Fatalf("expected to have annotation")
|
||||
}
|
||||
svcData2, ok := p2.Metadata.Annotations[annotationServiceKeyPrefix+"foo.service"]
|
||||
if !ok || len(*svcData2) == 0 {
|
||||
t.Fatalf("expected to have annotation")
|
||||
}
|
||||
|
||||
// unmarshal service data from annotation and compare
|
||||
// service passed in to .Register()
|
||||
var service1 *registry.Service
|
||||
if err := json.Unmarshal([]byte(*svcData1), &service1); err != nil {
|
||||
t.Fatalf("did not expect register unmarshal to fail %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(svc1, service1) {
|
||||
t.Fatal("services did not match")
|
||||
}
|
||||
|
||||
var service2 *registry.Service
|
||||
if err := json.Unmarshal([]byte(*svcData2), &service2); err != nil {
|
||||
t.Fatalf("did not expect register unmarshal to fail %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(svc2, service2) {
|
||||
t.Fatal("services did not match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeregister(t *testing.T) {
|
||||
r := setupRegistry()
|
||||
defer teardownRegistry()
|
||||
|
||||
svc1 := ®istry.Service{Name: "foo.service"}
|
||||
svc2 := ®istry.Service{Name: "foo.service"}
|
||||
register(r, "pod-1", svc1)
|
||||
register(r, "pod-2", svc2)
|
||||
|
||||
// deregister one service
|
||||
os.Setenv("HOSTNAME", "pod-1")
|
||||
if err := r.Deregister(svc1); err != nil {
|
||||
t.Fatalf("did not expect Deregister to fail %v", err)
|
||||
}
|
||||
|
||||
// check pod-1 has correct labels/annotations
|
||||
p1 := mockClient.Pods["pod-1"]
|
||||
if svcLabel1, ok := p1.Metadata.Labels[svcSelectorPrefix+"foo.service"]; ok && *svcLabel1 == svcSelectorValue {
|
||||
t.Fatalf("expected to NOT have pod selector label for foo.service")
|
||||
}
|
||||
|
||||
// check pod-2 has correct labels/annotations
|
||||
p2 := mockClient.Pods["pod-2"]
|
||||
if svcLabel2, ok := p2.Metadata.Labels[svcSelectorPrefix+"foo.service"]; !ok || *svcLabel2 != svcSelectorValue {
|
||||
t.Fatalf("expected to have pod selector label for foo.service")
|
||||
}
|
||||
|
||||
svcData1, ok := p1.Metadata.Annotations[annotationServiceKeyPrefix+"foo.service"]
|
||||
if ok && len(*svcData1) != 0 {
|
||||
t.Fatalf("expected to NOT have annotation")
|
||||
}
|
||||
svcData2, ok := p2.Metadata.Annotations[annotationServiceKeyPrefix+"foo.service"]
|
||||
if !ok || len(*svcData2) == 0 {
|
||||
t.Fatalf("expected to have annotation")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestGetService(t *testing.T) {
|
||||
r := setupRegistry()
|
||||
defer teardownRegistry()
|
||||
|
||||
svc1 := ®istry.Service{Name: "foo.service"}
|
||||
register(r, "pod-1", svc1)
|
||||
|
||||
service, err := r.GetService("foo.service")
|
||||
if err != nil {
|
||||
t.Fatalf("did not expect GetService to fail %v", err)
|
||||
}
|
||||
|
||||
// compare services
|
||||
if !hasServices(service, []*registry.Service{svc1}) {
|
||||
t.Fatal("expected service to match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetServiceSameServiceTwoPods(t *testing.T) {
|
||||
r := setupRegistry()
|
||||
defer teardownRegistry()
|
||||
|
||||
svc1 := ®istry.Service{Name: "foo.service", Version: "1"}
|
||||
svc2 := ®istry.Service{Name: "foo.service", Version: "1"}
|
||||
register(r, "pod-1", svc1)
|
||||
register(r, "pod-2", svc2)
|
||||
|
||||
service, err := r.GetService("foo.service")
|
||||
if err != nil {
|
||||
t.Fatalf("did not expect GetService to fail %v", err)
|
||||
}
|
||||
|
||||
if len(service) != 1 {
|
||||
t.Fatal("expected there to be only 1 service")
|
||||
}
|
||||
|
||||
if len(service[0].Nodes) != 2 {
|
||||
t.Fatal("expected there to be 2 nodes")
|
||||
}
|
||||
if !hasNodes(service[0].Nodes, []*registry.Node{svc1.Nodes[0], svc2.Nodes[0]}) {
|
||||
t.Fatal("nodes dont match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetServiceTwoVersionsTwoPods(t *testing.T) {
|
||||
r := setupRegistry()
|
||||
defer teardownRegistry()
|
||||
|
||||
svc1 := ®istry.Service{Name: "foo.service", Version: "1"}
|
||||
svc2 := ®istry.Service{Name: "foo.service", Version: "2"}
|
||||
|
||||
register(r, "pod-1", svc1)
|
||||
register(r, "pod-2", svc2)
|
||||
|
||||
service, err := r.GetService("foo.service")
|
||||
if err != nil {
|
||||
t.Fatalf("did not expect GetService to fail %v", err)
|
||||
}
|
||||
|
||||
if len(service) != 2 {
|
||||
t.Fatal("expected there to be 2 services")
|
||||
}
|
||||
|
||||
// compare services
|
||||
if !hasServices(service, []*registry.Service{svc1, svc2}) {
|
||||
t.Fatal("expected service to match")
|
||||
}
|
||||
}
|
||||
|
||||
func TestListServices(t *testing.T) {
|
||||
r := setupRegistry()
|
||||
defer teardownRegistry()
|
||||
|
||||
svc1 := ®istry.Service{Name: "foo.service"}
|
||||
svc2 := ®istry.Service{Name: "bar.service"}
|
||||
|
||||
register(r, "pod-1", svc1)
|
||||
register(r, "pod-2", svc2)
|
||||
|
||||
services, err := r.ListServices()
|
||||
if err != nil {
|
||||
t.Fatalf("did not expect ListServices to fail %v", err)
|
||||
}
|
||||
if !hasServices(services, []*registry.Service{
|
||||
{Name: "foo.service"},
|
||||
{Name: "bar.service"},
|
||||
}) {
|
||||
t.Fatal("expected services to equal")
|
||||
}
|
||||
|
||||
os.Setenv("HOSTNAME", "pod-1")
|
||||
r.Deregister(svc1)
|
||||
services2, err := r.ListServices()
|
||||
if err != nil {
|
||||
t.Fatalf("did not expect ListServices to fail %v", err)
|
||||
}
|
||||
if !hasServices(services2, []*registry.Service{
|
||||
{Name: "bar.service"},
|
||||
}) {
|
||||
t.Fatal("expected services to equal")
|
||||
}
|
||||
|
||||
// kill pod without deregistering.
|
||||
delete(mockClient.Pods, "pod-2")
|
||||
|
||||
// shoudnt return old data
|
||||
services3, err := r.ListServices()
|
||||
if err != nil {
|
||||
t.Fatalf("did not expect ListServices to fail %v", err)
|
||||
}
|
||||
if len(services3) != 0 {
|
||||
t.Fatal("expected there to be no services")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestWatcher(t *testing.T) {
|
||||
r := setupRegistry()
|
||||
rtr := router.NewRouter(router.Registry(r))
|
||||
|
||||
// check that service is blank
|
||||
if _, err := rtr.Lookup(router.QueryService("foo.service")); err != router.ErrRouteNotFound {
|
||||
log.Fatal("expected selector.ErrNotFound")
|
||||
}
|
||||
|
||||
// setup svc
|
||||
svc1 := ®istry.Service{Name: "foo.service", Version: "1"}
|
||||
register(r, "pod-1", svc1)
|
||||
|
||||
if routes, err := rtr.Lookup(router.QueryService("foo.service")); err != nil {
|
||||
t.Fatalf("Querying service returned an error: %v", err)
|
||||
} else if len(routes) != 1 {
|
||||
t.Fatalf("Expected one route, found %v", len(routes))
|
||||
}
|
||||
|
||||
// setup svc
|
||||
svc2 := ®istry.Service{Name: "foo.service", Version: "1"}
|
||||
register(r, "pod-2", svc2)
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
|
||||
if routes, err := rtr.Lookup(router.QueryService("foo.service")); err != nil {
|
||||
t.Fatalf("Querying service returned an error: %v", err)
|
||||
} else if len(routes) != 2 {
|
||||
t.Fatalf("Expected two routes, found %v", len(routes))
|
||||
}
|
||||
|
||||
// remove pods
|
||||
teardownRegistry()
|
||||
time.Sleep(time.Millisecond * 100)
|
||||
|
||||
if _, err := rtr.Lookup(router.QueryService("foo.service")); err != router.ErrRouteNotFound {
|
||||
log.Fatal("expected selector.ErrNotFound")
|
||||
}
|
||||
}
|
||||
|
||||
func hasNodes(a, b []*registry.Node) bool {
|
||||
found := 0
|
||||
for _, nodeA := range a {
|
||||
for _, nodeB := range b {
|
||||
if nodeA.Id == nodeB.Id {
|
||||
found++
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return found == len(b)
|
||||
}
|
||||
|
||||
func hasServices(a, b []*registry.Service) bool {
|
||||
found := 0
|
||||
|
||||
for _, aV := range a {
|
||||
for _, bV := range b {
|
||||
if aV.Name != bV.Name {
|
||||
continue
|
||||
}
|
||||
if aV.Version != bV.Version {
|
||||
continue
|
||||
}
|
||||
if !hasNodes(aV.Nodes, bV.Nodes) {
|
||||
continue
|
||||
}
|
||||
found++
|
||||
break
|
||||
}
|
||||
}
|
||||
return found == len(b)
|
||||
}
|
Reference in New Issue
Block a user