mirror of
https://github.com/kubenetworks/kubevpn.git
synced 2025-10-27 01:10:39 +08:00
feat: sync mode modify api server & add ut for mode run and mode sync (#704)
* feat: mode sync modify kubeconfig apiserver to in cluster apiserver * feat: add ut for sync mode and run mode * fix: bugs
This commit is contained in:
304
pkg/handler/mode_sync_test.go
Normal file
304
pkg/handler/mode_sync_test.go
Normal file
@@ -0,0 +1,304 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/apimachinery/pkg/fields"
|
||||
"k8s.io/apimachinery/pkg/util/wait"
|
||||
"k8s.io/client-go/util/retry"
|
||||
|
||||
"github.com/wencaiwulue/kubevpn/v2/pkg/util"
|
||||
)
|
||||
|
||||
var content = `package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"log"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func main() {
|
||||
http.HandleFunc("/health", health)
|
||||
|
||||
log.Println("Start listening http port 9080 ...")
|
||||
if err := http.ListenAndServe(":9080", nil); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func health(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != http.MethodGet {
|
||||
w.WriteHeader(http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
resp, err := json.Marshal(map[string]string{
|
||||
"status": "Authors is healthy in pod",
|
||||
})
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
log.Println(err)
|
||||
return
|
||||
}
|
||||
w.Write(resp)
|
||||
}`
|
||||
|
||||
func (u *ut) kubevpnSyncWithFullProxy(t *testing.T) {
|
||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||
defer cancelFunc()
|
||||
|
||||
endpoint := u.kubevpnSync(t, ctx, false)
|
||||
u.healthChecker(t, endpoint, nil, remoteSyncPod)
|
||||
u.healthChecker(t, endpoint, map[string]string{"env": "test"}, remoteSyncPod)
|
||||
}
|
||||
|
||||
func (u *ut) kubevpnSync(t *testing.T, ctx context.Context, isServiceMesh bool) string {
|
||||
path := u.writeTempFile(t)
|
||||
name := filepath.Base(path)
|
||||
dir := filepath.Dir(path)
|
||||
remoteDir := "/app/test"
|
||||
|
||||
args := []string{"sync",
|
||||
"deploy/authors",
|
||||
"--debug",
|
||||
"--sync", fmt.Sprintf("%s:%s", dir, remoteDir),
|
||||
"-c", "authors",
|
||||
"--target-image", "ghcr.io/kubenetworks/authors:latest",
|
||||
}
|
||||
if isServiceMesh {
|
||||
args = append(args, "--headers", "env=test")
|
||||
}
|
||||
cmd := exec.Command("kubevpn", args...)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
list, err := util.GetRunningPodList(ctx, u.clientset, u.namespace, fields.OneTermEqualSelector("origin-workload", "authors").String())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if len(list) == 0 {
|
||||
t.Fatal("expect at least one pod")
|
||||
}
|
||||
|
||||
remotePath := fmt.Sprintf("%s/%s", remoteDir, name)
|
||||
containerName := "authors"
|
||||
u.checkContent(ctx, t, list[0].Name, containerName, remotePath)
|
||||
go u.execServer(ctx, t, list[0].Name, containerName, remotePath)
|
||||
|
||||
endpoint := fmt.Sprintf("http://%s:%v/health", list[0].Status.PodIP, 9080)
|
||||
u.healthChecker(t, endpoint, nil, remoteSyncPod)
|
||||
app := "authors"
|
||||
ip, err := u.getServiceIP(app)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
endpoint = fmt.Sprintf("http://%s:%v/health", ip, 9080)
|
||||
return endpoint
|
||||
}
|
||||
|
||||
func (u *ut) execServer(ctx context.Context, t *testing.T, podName string, containerName string, remoteDir string) {
|
||||
for ctx.Err() == nil {
|
||||
output, err := util.Shell(
|
||||
ctx,
|
||||
u.clientset,
|
||||
u.restconfig,
|
||||
podName,
|
||||
containerName,
|
||||
u.namespace,
|
||||
[]string{"go", "run", remoteDir},
|
||||
)
|
||||
if err != nil {
|
||||
t.Log(err, output)
|
||||
}
|
||||
time.Sleep(time.Second * 1)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *ut) kubevpnSyncWithServiceMesh(t *testing.T) {
|
||||
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||
defer cancelFunc()
|
||||
|
||||
endpoint := u.kubevpnSync(t, ctx, true)
|
||||
u.healthChecker(t, endpoint, nil, remoteSyncOrigin)
|
||||
u.healthChecker(t, endpoint, map[string]string{"env": "test"}, remoteSyncPod)
|
||||
}
|
||||
|
||||
func (u *ut) checkContent(ctx context.Context, t *testing.T, podName string, containerName string, remotePath string) {
|
||||
err := retry.OnError(
|
||||
wait.Backoff{Duration: time.Second, Factor: 1, Jitter: 0, Steps: 120},
|
||||
func(err error) bool { return err != nil },
|
||||
func() error {
|
||||
shell, err := util.Shell(
|
||||
ctx,
|
||||
u.clientset,
|
||||
u.restconfig,
|
||||
podName,
|
||||
containerName,
|
||||
u.namespace,
|
||||
[]string{"cat", remotePath},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if strings.TrimSpace(shell) != strings.TrimSpace(content) {
|
||||
t.Logf("expect: %s, but was: %s", content, shell)
|
||||
return fmt.Errorf("expect: %s, but was: %s", content, shell)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *ut) TestCompile(t *testing.T) {
|
||||
u.writeTempFile(t)
|
||||
}
|
||||
|
||||
func (u *ut) writeTempFile(t *testing.T) string {
|
||||
dir := t.TempDir()
|
||||
file := filepath.Join(dir, "main.go")
|
||||
temp, err := os.Create(file)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
_, err = temp.WriteString(content)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = temp.Chmod(0755)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
err = temp.Close()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
return temp.Name()
|
||||
}
|
||||
|
||||
func (u *ut) checkSyncWithFullProxyStatus(t *testing.T) {
|
||||
cmd := exec.Command("kubevpn", "status", "-o", "json")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
t.Fatal(err, string(output))
|
||||
}
|
||||
|
||||
expect := status{List: []*connection{{
|
||||
Namespace: u.namespace,
|
||||
Status: "connected",
|
||||
ProxyList: []*proxyItem{{
|
||||
Namespace: u.namespace,
|
||||
Workload: "deployments.apps/authors",
|
||||
RuleList: []*proxyRule{{
|
||||
Headers: nil,
|
||||
CurrentDevice: false,
|
||||
PortMap: map[int32]int32{9080: 9080, 80: 80},
|
||||
}},
|
||||
}},
|
||||
SyncList: []*syncItem{{
|
||||
Namespace: u.namespace,
|
||||
Workload: "deploy/authors",
|
||||
RuleList: []*syncRule{{}},
|
||||
}},
|
||||
}}}
|
||||
|
||||
var statuses status
|
||||
if err = json.Unmarshal(output, &statuses); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(expect.List) == 0 || len(expect.List[0].SyncList) == 0 || len(expect.List[0].SyncList[0].RuleList) == 0 {
|
||||
t.Fatal("expect List[0].SyncList[0].RuleList[0] not found", string(output))
|
||||
}
|
||||
|
||||
expect.List[0].SyncList[0].RuleList[0].DstWorkload = statuses.List[0].SyncList[0].RuleList[0].DstWorkload
|
||||
|
||||
if !reflect.DeepEqual(statuses, expect) {
|
||||
marshal, _ := json.Marshal(expect)
|
||||
marshalB, _ := json.Marshal(statuses)
|
||||
t.Fatalf("expect: %s, but was: %s", string(marshal), string(marshalB))
|
||||
}
|
||||
}
|
||||
|
||||
func (u *ut) kubevpnUnSync(t *testing.T) {
|
||||
cmd := exec.Command("kubevpn", "status", "-o", "json")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
t.Fatal(err, string(output))
|
||||
}
|
||||
|
||||
var statuses status
|
||||
if err = json.Unmarshal(output, &statuses); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(statuses.List) == 0 || len(statuses.List[0].SyncList) == 0 || len(statuses.List[0].SyncList[0].RuleList) == 0 {
|
||||
t.Fatal("expect List[0].SyncList[0].RuleList[0] not found", string(output))
|
||||
}
|
||||
|
||||
cmd = exec.Command("kubevpn", "unsync", statuses.List[0].SyncList[0].RuleList[0].DstWorkload)
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
err = cmd.Run()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
func (u *ut) checkSyncWithServiceMeshStatus(t *testing.T) {
|
||||
cmd := exec.Command("kubevpn", "status", "-o", "json")
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
t.Fatal(err, string(output))
|
||||
}
|
||||
|
||||
expect := status{List: []*connection{{
|
||||
Namespace: u.namespace,
|
||||
Status: "connected",
|
||||
ProxyList: []*proxyItem{{
|
||||
Namespace: u.namespace,
|
||||
Workload: "deployments.apps/authors",
|
||||
RuleList: []*proxyRule{{
|
||||
Headers: map[string]string{"env": "test"},
|
||||
CurrentDevice: false,
|
||||
PortMap: map[int32]int32{9080: 9080, 80: 80},
|
||||
}},
|
||||
}},
|
||||
SyncList: []*syncItem{{
|
||||
Namespace: u.namespace,
|
||||
Workload: "deploy/authors",
|
||||
RuleList: []*syncRule{{}},
|
||||
}},
|
||||
}}}
|
||||
|
||||
var statuses status
|
||||
if err = json.Unmarshal(output, &statuses); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
if len(expect.List) == 0 || len(expect.List[0].SyncList) == 0 || len(expect.List[0].SyncList[0].RuleList) == 0 {
|
||||
t.Fatal("expect List[0].SyncList[0].RuleList[0] not found", string(output))
|
||||
}
|
||||
|
||||
expect.List[0].SyncList[0].RuleList[0].DstWorkload = statuses.List[0].SyncList[0].RuleList[0].DstWorkload
|
||||
|
||||
if !reflect.DeepEqual(statuses, expect) {
|
||||
marshal, _ := json.Marshal(expect)
|
||||
marshalB, _ := json.Marshal(statuses)
|
||||
t.Fatalf("expect: %s, but was: %s", string(marshal), string(marshalB))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user