(t *testing.T)
| 111 | } |
| 112 | |
| 113 | func TestUnified_HotReloadSwitchesMode(t *testing.T) { |
| 114 | // 先配成透明,再热切到终止 |
| 115 | transparentBackend := startEchoTLS(t, "x.example.com") |
| 116 | terminatingBackend := startEchoPlaintext(t) |
| 117 | |
| 118 | cert := genSelfSigned(t) |
| 119 | proxy := &UnifiedProxy{Addr: "127.0.0.1:0"} |
| 120 | proxy.SetTLSConfig(&tls.Config{Certificates: []tls.Certificate{cert}}) |
| 121 | proxy.SetRoutes([]Route{ |
| 122 | {SNI: "x.example.com", Backend: transparentBackend, Mode: ModeTransparent}, |
| 123 | }) |
| 124 | |
| 125 | ln, _ := net.Listen("tcp", "127.0.0.1:0") |
| 126 | addr := ln.Addr().String() |
| 127 | _ = ln.Close() |
| 128 | proxy.Addr = addr |
| 129 | |
| 130 | ctx, cancel := context.WithCancel(context.Background()) |
| 131 | defer cancel() |
| 132 | var wg sync.WaitGroup |
| 133 | wg.Add(1) |
| 134 | go func() { defer wg.Done(); _ = proxy.Serve(ctx) }() |
| 135 | t.Cleanup(func() { cancel(); wg.Wait() }) |
| 136 | |
| 137 | waitForListen(t, addr) |
| 138 | |
| 139 | // 切到终止模式 |
| 140 | proxy.SetRoutes([]Route{ |
| 141 | {SNI: "x.example.com", Backend: terminatingBackend, Mode: ModeTerminating}, |
| 142 | }) |
| 143 | |
| 144 | conn, err := net.Dial("tcp", addr) |
| 145 | if err != nil { |
| 146 | t.Fatal(err) |
| 147 | } |
| 148 | defer conn.Close() |
| 149 | tc := tls.Client(conn, &tls.Config{ServerName: "x.example.com", InsecureSkipVerify: true}) |
| 150 | _ = tc.SetDeadline(time.Now().Add(3 * time.Second)) |
| 151 | if err := tc.Handshake(); err != nil { |
| 152 | t.Fatalf("handshake after hot reload: %v", err) |
| 153 | } |
| 154 | if _, err := tc.Write([]byte("hi")); err != nil { |
| 155 | t.Fatal(err) |
| 156 | } |
| 157 | got := make([]byte, 2) |
| 158 | if _, err := io.ReadFull(tc, got); err != nil { |
| 159 | t.Fatal(err) |
| 160 | } |
| 161 | if string(got) != "hi" { |
| 162 | t.Errorf("got %q, want 'hi'", got) |
| 163 | } |
| 164 | } |
nothing calls this directly
no test coverage detected