Repository: go-kratos/kratos
Pull request #2166 (2022-07-08 00:18:07)

test(contrib): add unit test for contrib/registry/k8s
Description (what this PR does / why we need it):
coverage: 90+% of statements

Which issue(s) this PR fixes (resolves / be part of):
part of https://github.com/go-kratos/kratos/issues/2135

codecov-commenter: # [Codecov](https://codecov.io/gh/go-kratos/kratos/pull/2166?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) Report
> Merging [#2166](https://codecov.io/gh/go-kratos/kratos/pull/2166?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) (3e204f1) into [main](https://codecov.io/gh/go-kratos/kratos/commit/e09d294388947e8e4063f8e87b681682fa040e53?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos) (e09d294) will **not change** coverage.
> The diff coverage is `n/a`.

```diff
@@           Coverage Diff           @@
##             main    #2166   +/-   ##
=======================================
  Coverage   79.16%   79.16%           
=======================================
  Files          84       84           
  Lines        3701     3701           
=======================================
  Hits         2930     2930           
  Misses        561      561           
  Partials      210      210           
```



------

[Continue to review full report at Codecov](https://codecov.io/gh/go-kratos/kratos/pull/2166?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/go-kratos/kratos/pull/2166?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos). Last update [e09d294...3e204f1](https://codecov.io/gh/go-kratos/kratos/pull/2166?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=go-kratos).

rogerogers: The random function triggers the error, 9000 times might little small🤓

Patch:
diff --git a/contrib/config/kubernetes/go.mod b/contrib/config/kubernetes/go.mod
index db846f9c..c4c0d82d 100644
--- a/contrib/config/kubernetes/go.mod
+++ b/contrib/config/kubernetes/go.mod
@@ -4,9 +4,9 @@ go 1.16
 
 require (
 	github.com/go-kratos/kratos/v2 v2.3.1
-	k8s.io/api v0.24.1
-	k8s.io/apimachinery v0.24.1
-	k8s.io/client-go v0.24.1
+	k8s.io/api v0.24.2
+	k8s.io/apimachinery v0.24.2
+	k8s.io/client-go v0.24.2
 )
 
 replace github.com/go-kratos/kratos/v2 => ../../../
diff --git a/contrib/config/kubernetes/go.sum b/contrib/config/kubernetes/go.sum
index ad234674..138314b9 100644
--- a/contrib/config/kubernetes/go.sum
+++ b/contrib/config/kubernetes/go.sum
@@ -652,12 +652,12 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
 honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
 honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
 honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
-k8s.io/api v0.24.1 h1:BjCMRDcyEYz03joa3K1+rbshwh1Ay6oB53+iUx2H8UY=
-k8s.io/api v0.24.1/go.mod h1:JhoOvNiLXKTPQ60zh2g0ewpA+bnEYf5q44Flhquh4vQ=
-k8s.io/apimachinery v0.24.1 h1:ShD4aDxTQKN5zNf8K1RQ2u98ELLdIW7jEnlO9uAMX/I=
-k8s.io/apimachinery v0.24.1/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM=
-k8s.io/client-go v0.24.1 h1:w1hNdI9PFrzu3OlovVeTnf4oHDt+FJLd9Ndluvnb42E=
-k8s.io/client-go v0.24.1/go.mod h1:f1kIDqcEYmwXS/vTbbhopMUbhKp2JhOeVTfxgaCIlF8=
+k8s.io/api v0.24.2 h1:g518dPU/L7VRLxWfcadQn2OnsiGWVOadTLpdnqgY2OI=
+k8s.io/api v0.24.2/go.mod h1:AHqbSkTm6YrQ0ObxjO3Pmp/ubFF/KuM7jU+3khoBsOg=
+k8s.io/apimachinery v0.24.2 h1:5QlH9SL2C8KMcrNJPor+LbXVTaZRReml7svPEh4OKDM=
+k8s.io/apimachinery v0.24.2/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM=
+k8s.io/client-go v0.24.2 h1:CoXFSf8if+bLEbinDqN9ePIDGzcLtqhfd6jpfnwGOFA=
+k8s.io/client-go v0.24.2/go.mod h1:zg4Xaoo+umDsfCWr4fCnmLEtQXyCNXCvJuSsglNcV30=
 k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
 k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
 k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=
diff --git a/contrib/registry/consul/go.mod b/contrib/registry/consul/go.mod
index f746247d..38f0f1aa 100644
--- a/contrib/registry/consul/go.mod
+++ b/contrib/registry/consul/go.mod
@@ -4,7 +4,7 @@ go 1.16
 
 require (
 	github.com/go-kratos/kratos/v2 v2.3.1
-	github.com/hashicorp/consul/api v1.12.0
+	github.com/hashicorp/consul/api v1.13.0
 )
 
 replace github.com/go-kratos/kratos/v2 => ../../../
diff --git a/contrib/registry/consul/go.sum b/contrib/registry/consul/go.sum
index 402ade80..b2e006cb 100644
--- a/contrib/registry/consul/go.sum
+++ b/contrib/registry/consul/go.sum
@@ -64,13 +64,14 @@ github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
 github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
 github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.7 h1:81/ik6ipDQS2aGcBfIN5dHDB36BwrStyeAQquSYCV4o=
 github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
 github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
 github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
 github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
-github.com/hashicorp/consul/api v1.12.0 h1:k3y1FYv6nuKyNTqj6w9gXOx5r5CfLj/k/euUeBXj1OY=
-github.com/hashicorp/consul/api v1.12.0/go.mod h1:6pVBMo0ebnYdt2S3H87XhekM/HHrUoTD2XXb/VrZVy0=
+github.com/hashicorp/consul/api v1.13.0 h1:2hnLQ0GjQvw7f3O61jMO8gbasZviZTrt9R8WzgiirHc=
+github.com/hashicorp/consul/api v1.13.0/go.mod h1:ZlVrynguJKcYr54zGaDbaL3fOvKC9m72FhPvA8T35KQ=
 github.com/hashicorp/consul/sdk v0.8.0 h1:OJtKBtEjboEZvG6AOUdh4Z1Zbyu0WcxQ0qatRrZHTVU=
 github.com/hashicorp/consul/sdk v0.8.0/go.mod h1:GBvyrGALthsZObzUGsfgHZQDXjg4lOjagTIwIR1vPms=
 github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
@@ -222,6 +223,7 @@ golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBn
 golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
+golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
diff --git a/contrib/registry/kubernetes/go.sum b/contrib/registry/kubernetes/go.sum
index 199d8157..559f0670 100644
--- a/contrib/registry/kubernetes/go.sum
+++ b/contrib/registry/kubernetes/go.sum
@@ -201,6 +201,7 @@ github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpO
 github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
 github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
+github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
 github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
 github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
 github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=


Test patch:
diff --git a/contrib/registry/kubernetes/registry_test.go b/contrib/registry/kubernetes/registry_test.go
new file mode 100644
index 00000000..2363b1c3
--- /dev/null
+++ b/contrib/registry/kubernetes/registry_test.go
@@ -0,0 +1,186 @@
+package kuberegistry
+
+import (
+	"context"
+	"os"
+	"path/filepath"
+	"testing"
+	"time"
+
+	"github.com/go-kratos/kratos/v2/registry"
+
+	appsv1 "k8s.io/api/apps/v1"
+	apiv1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	"k8s.io/client-go/kubernetes"
+	"k8s.io/client-go/rest"
+	"k8s.io/client-go/tools/clientcmd"
+	"k8s.io/client-go/util/homedir"
+)
+
+const (
+	namespace  = "default"
+	deployName = "hello-deployment"
+	podName    = "hello"
+)
+
+var deployment = appsv1.Deployment{
+	ObjectMeta: metav1.ObjectMeta{
+		Name: deployName,
+	},
+	Spec: appsv1.DeploymentSpec{
+		Replicas: int32Ptr(1),
+		Selector: &metav1.LabelSelector{
+			MatchLabels: map[string]string{
+				"app": podName,
+			},
+		},
+		Template: apiv1.PodTemplateSpec{
+			ObjectMeta: metav1.ObjectMeta{
+				Labels: map[string]string{
+					"app": podName,
+				},
+			},
+			Spec: apiv1.PodSpec{
+				Containers: []apiv1.Container{
+					{
+						Name:  "nginx",
+						Image: "nginx:alpine",
+						Ports: []apiv1.ContainerPort{
+							{
+								Name:          "http",
+								Protocol:      apiv1.ProtocolTCP,
+								ContainerPort: 80,
+							},
+						},
+						Command: []string{
+							"nginx",
+							"-g",
+							"daemon off;",
+						},
+					},
+				},
+			},
+		},
+	},
+}
+
+func getClientSet() (*kubernetes.Clientset, error) {
+	restConfig, err := rest.InClusterConfig()
+	home := homedir.HomeDir()
+
+	if err != nil {
+		kubeconfig := filepath.Join(home, ".kube", "config")
+		restConfig, err = clientcmd.BuildConfigFromFlags("", kubeconfig)
+		if err != nil {
+			return nil, err
+		}
+	}
+	clientSet, err := kubernetes.NewForConfig(restConfig)
+	if err != nil {
+		return nil, err
+	}
+	return clientSet, nil
+}
+
+func int32Ptr(i int32) *int32 { return &i }
+
+func TestSetEnv(t *testing.T) {
+	os.Setenv("HOSTNAME", podName)
+	if os.Getenv("HOSTNAME") != podName {
+		t.Fatal("error")
+	}
+}
+
+func TestRegistry(t *testing.T) {
+	currentNamespace = "default"
+
+	clientSet, err := getClientSet()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	r := NewRegistry(clientSet)
+	r.Start()
+
+	svrHello := &registry.ServiceInstance{
+		ID:        "1",
+		Name:      "hello",
+		Version:   "v1.0.0",
+		Endpoints: []string{"http://127.0.0.1:80"},
+	}
+	_, err = clientSet.AppsV1().Deployments(namespace).Create(context.Background(), &deployment, metav1.CreateOptions{})
+
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	watch, err := r.Watch(context.Background(), svrHello.Name)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	defer func() {
+		_ = watch.Stop()
+	}()
+
+	go func() {
+		for {
+			res, err1 := watch.Next()
+			if err1 != nil {
+				return
+			}
+			t.Logf("watch: %d", len(res))
+			for _, r := range res {
+				t.Logf("next: %+v", r)
+			}
+		}
+	}()
+	time.Sleep(time.Second)
+
+	pod, err := clientSet.CoreV1().Pods(namespace).List(context.Background(), metav1.ListOptions{
+		LabelSelector: "app=hello",
+	})
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(pod.Items) < 1 {
+		t.Fatal("fetch resource error")
+	}
+
+	os.Setenv("HOSTNAME", pod.Items[0].Name)
+
+	// Alway remember delete test resource
+	defer func() {
+		_ = clientSet.AppsV1().Deployments(namespace).Delete(context.Background(), deployName, metav1.DeleteOptions{})
+	}()
+
+	if err = r.Register(context.Background(), svrHello); err != nil {
+		t.Fatal(err)
+	}
+	time.Sleep(time.Second)
+
+	res, err := r.GetService(context.Background(), svrHello.Name)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	if len(res) != 1 && res[0].Name != svrHello.Name {
+		t.Fatal(err)
+	}
+
+	if err1 := r.Deregister(context.Background(), svrHello); err1 != nil {
+		t.Fatal(err1)
+	}
+
+	time.Sleep(time.Second)
+
+	res, err = r.GetService(context.Background(), svrHello.Name)
+	if err != nil {
+		t.Fatal(err)
+	}
+	if len(res) != 0 {
+		t.Fatal("not expected empty")
+	}
+}