- 将 StartNginxContainer 重命名为 StartMockBackend,明确其作为模拟后端的用途 - proxy_e2e_test.go: 所有测试使用 lolly 作为代理,nginx 作为后端 - ssl_e2e_test.go: 移除 nginx 容器测试,简化为 lolly SSL 功能测试 - static_e2e_test.go: 所有测试使用 lolly 作为静态文件服务器 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
154 lines
4.5 KiB
Go
154 lines
4.5 KiB
Go
//go:build e2e
|
||
|
||
// ssl_e2e_test.go - SSL/TLS E2E 测试(L3 层,需要 Docker)
|
||
//
|
||
// 测试 lolly SSL/TLS 功能。
|
||
// 所有测试都以 lolly 作为被测系统。
|
||
//
|
||
// 作者:xfy
|
||
package e2e
|
||
|
||
import (
|
||
"context"
|
||
"net/http"
|
||
"os"
|
||
"testing"
|
||
"time"
|
||
|
||
"github.com/stretchr/testify/assert"
|
||
"github.com/stretchr/testify/require"
|
||
|
||
"rua.plus/lolly/internal/e2e/testutil"
|
||
)
|
||
|
||
// TestE2ESSLHandshake 测试 SSL 握手环境。
|
||
func TestE2ESSLHandshake(t *testing.T) {
|
||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||
defer cancel()
|
||
|
||
if !testutil.DockerAvailable(ctx) {
|
||
t.Skip("Docker not available")
|
||
}
|
||
|
||
t.Log("Docker is available for E2E SSL tests")
|
||
}
|
||
|
||
// TestE2ESSLWithLolly 测试 lolly SSL/TLS 功能。
|
||
// 需要 lolly:latest 镜像和测试证书。
|
||
// 注意:当前测试仅验证证书生成功能,因为默认 lolly 镜像未配置 SSL。
|
||
// 完整的 SSL 测试需要自定义配置和证书挂载,这里仅测试 HTTP 连接。
|
||
func TestE2ESSLWithLolly(t *testing.T) {
|
||
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
|
||
defer cancel()
|
||
|
||
if !testutil.DockerAvailable(ctx) {
|
||
t.Skip("Docker not available")
|
||
}
|
||
|
||
if !testutil.LollyImageAvailable(ctx) {
|
||
t.Skip("lolly:latest image not available, run 'make docker-build' first")
|
||
}
|
||
|
||
// 生成自签名证书
|
||
certPath, keyPath, cleanup, err := testutil.GenerateSelfSignedCert(t.TempDir())
|
||
require.NoError(t, err, "Failed to generate self-signed certificate")
|
||
defer cleanup()
|
||
|
||
t.Logf("Generated certificate: %s", certPath)
|
||
t.Logf("Generated key: %s", keyPath)
|
||
|
||
// 启动 lolly 服务器(使用默认配置,无 SSL)
|
||
lolly, err := testutil.StartLollyContainer(ctx, "")
|
||
require.NoError(t, err, "Failed to start lolly container")
|
||
defer lolly.Terminate(ctx)
|
||
|
||
t.Logf("Lolly HTTP server: %s", lolly.HTTPBaseURL())
|
||
|
||
// 测试 HTTP 连接(默认配置未启用 HTTPS)
|
||
client := &http.Client{Timeout: 10 * time.Second}
|
||
resp, err := client.Get(lolly.HTTPBaseURL())
|
||
require.NoError(t, err, "Failed to reach lolly HTTP")
|
||
defer resp.Body.Close()
|
||
|
||
// lolly 默认配置没有静态文件,返回 404
|
||
assert.Equal(t, 404, resp.StatusCode, "Lolly HTTP should return 404 without static files")
|
||
}
|
||
|
||
// TestE2ESSLDockerAvailable 测试 Docker 是否可用。
|
||
func TestE2ESSLDockerAvailable(t *testing.T) {
|
||
ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
|
||
defer cancel()
|
||
|
||
if !testutil.DockerAvailable(ctx) {
|
||
t.Skip("Docker not available, skipping E2E SSL tests")
|
||
}
|
||
|
||
t.Log("Docker is available for E2E SSL tests")
|
||
}
|
||
|
||
// TestE2ESSLEnvironmentCheck 检查测试环境。
|
||
func TestE2ESSLEnvironmentCheck(t *testing.T) {
|
||
dockerHost := os.Getenv("DOCKER_HOST")
|
||
if dockerHost != "" {
|
||
t.Logf("DOCKER_HOST: %s", dockerHost)
|
||
}
|
||
|
||
if os.Getenv("CI") != "" {
|
||
t.Log("Running in CI environment")
|
||
}
|
||
|
||
if _, err := os.Stat("/.dockerenv"); err == nil {
|
||
t.Log("Running inside a Docker container")
|
||
}
|
||
}
|
||
|
||
// TestE2ESSLHTTP3Placeholder HTTP/3 测试占位符。
|
||
func TestE2ESSLHTTP3Placeholder(t *testing.T) {
|
||
if testing.Short() {
|
||
t.Skip("Skipping E2E test in short mode")
|
||
}
|
||
|
||
t.Log("HTTP/3 E2E test placeholder - requires UDP port configuration")
|
||
}
|
||
|
||
// TestE2ESSLCertificateGeneration 测试证书生成。
|
||
func TestE2ESSLCertificateGeneration(t *testing.T) {
|
||
tmpDir := t.TempDir()
|
||
|
||
certPath, keyPath, cleanup, err := testutil.GenerateSelfSignedCert(tmpDir)
|
||
require.NoError(t, err, "Failed to generate certificate")
|
||
defer cleanup()
|
||
|
||
assert.FileExists(t, certPath, "Certificate file should exist")
|
||
assert.FileExists(t, keyPath, "Key file should exist")
|
||
|
||
// 验证证书可以被加载
|
||
certPool, err := testutil.GenerateCertPool(certPath)
|
||
require.NoError(t, err, "Failed to create cert pool")
|
||
assert.NotNil(t, certPool)
|
||
}
|
||
|
||
// TestE2ESSLConcurrent 测试 lolly 并发 SSL 连接。
|
||
func TestE2ESSLConcurrent(t *testing.T) {
|
||
ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
|
||
defer cancel()
|
||
|
||
if !testutil.LollyImageAvailable(ctx) {
|
||
t.Skip("lolly:latest image not available, run 'make docker-build' first")
|
||
}
|
||
|
||
lolly, err := testutil.StartLollyContainer(ctx, "")
|
||
require.NoError(t, err, "Failed to start lolly container")
|
||
defer lolly.Terminate(ctx)
|
||
|
||
// 使用真正的并发测试
|
||
failures := testutil.RunAndVerifyConcurrentRequests(t, testutil.ConcurrentRequestConfig{
|
||
URL: lolly.HTTPBaseURL(),
|
||
Count: 10,
|
||
Timeout: 10 * time.Second,
|
||
ExpectCode: 404, // lolly 默认配置没有静态文件
|
||
})
|
||
|
||
assert.Empty(t, failures, "All concurrent requests should succeed")
|
||
}
|