Apply modern Go patterns across the codebase:
- Replace `interface{}` with `any` (Go 1.18+)
- Use `for range n` instead of `for i := 0; i < n; i++` (Go 1.22+)
- Replace `sort.Slice` with `slices.Sort` from slices package
- Simplify sync.WaitGroup patterns with errgroup where appropriate
- Add Makefile targets for modernize analyzer
Total: 84 files updated, net reduction of 79 lines
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
698 lines
16 KiB
Go
698 lines
16 KiB
Go
// Package http3 提供 HTTP/3 服务器功能的测试。
|
||
//
|
||
// 该文件测试 HTTP/3 服务器模块的各项功能,包括:
|
||
// - 服务器创建和配置验证
|
||
// - Alt-Svc 头部生成
|
||
// - 服务器统计信息获取
|
||
// - 运行状态检查
|
||
// - 服务器停止和优雅停止
|
||
//
|
||
// 作者:xfy
|
||
package http3
|
||
|
||
import (
|
||
"crypto/rand"
|
||
"crypto/rsa"
|
||
"crypto/tls"
|
||
"crypto/x509"
|
||
"crypto/x509/pkix"
|
||
"encoding/pem"
|
||
"math/big"
|
||
"net"
|
||
"testing"
|
||
"time"
|
||
|
||
"github.com/valyala/fasthttp"
|
||
"rua.plus/lolly/internal/config"
|
||
)
|
||
|
||
// TestNewServer_NilConfig 测试空配置错误
|
||
func TestNewServer_NilConfig(t *testing.T) {
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
server, err := NewServer(nil, handler, &tls.Config{})
|
||
|
||
if err == nil {
|
||
t.Error("Expected error for nil config")
|
||
}
|
||
if server != nil {
|
||
t.Error("Expected nil server for nil config")
|
||
}
|
||
if err.Error() != "http3 config is nil" {
|
||
t.Errorf("Expected error message 'http3 config is nil', got: %v", err)
|
||
}
|
||
}
|
||
|
||
// TestNewServer_NilHandler 测试空 handler 错误
|
||
func TestNewServer_NilHandler(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: ":443",
|
||
Enable0RTT: true,
|
||
}
|
||
|
||
server, err := NewServer(cfg, nil, &tls.Config{})
|
||
|
||
if err == nil {
|
||
t.Error("Expected error for nil handler")
|
||
}
|
||
if server != nil {
|
||
t.Error("Expected nil server for nil handler")
|
||
}
|
||
if err.Error() != "handler is nil" {
|
||
t.Errorf("Expected error message 'handler is nil', got: %v", err)
|
||
}
|
||
}
|
||
|
||
// TestNewServer_NilTLS 测试空 TLS 配置错误
|
||
func TestNewServer_NilTLS(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: ":443",
|
||
Enable0RTT: true,
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
server, err := NewServer(cfg, handler, nil)
|
||
|
||
if err == nil {
|
||
t.Error("Expected error for nil TLS config")
|
||
}
|
||
if server != nil {
|
||
t.Error("Expected nil server for nil TLS config")
|
||
}
|
||
if err.Error() != "tls config is required for HTTP/3" {
|
||
t.Errorf("Expected error message 'tls config is required for HTTP/3', got: %v", err)
|
||
}
|
||
}
|
||
|
||
// TestNewServer_Success 测试成功创建服务器
|
||
func TestNewServer_Success(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: ":443",
|
||
Enable0RTT: true,
|
||
MaxStreams: 100,
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
tlsConfig := &tls.Config{
|
||
Certificates: []tls.Certificate{},
|
||
}
|
||
|
||
server, err := NewServer(cfg, handler, tlsConfig)
|
||
if err != nil {
|
||
t.Errorf("Unexpected error: %v", err)
|
||
}
|
||
if server == nil {
|
||
t.Fatal("Expected non-nil server")
|
||
}
|
||
|
||
if server.config != cfg {
|
||
t.Error("Config not set correctly")
|
||
}
|
||
|
||
if server.handler == nil {
|
||
t.Error("Handler not set correctly")
|
||
}
|
||
|
||
if server.adapter == nil {
|
||
t.Error("Adapter not initialized")
|
||
}
|
||
|
||
if server.tlsConfig != tlsConfig {
|
||
t.Error("TLS config not set correctly")
|
||
}
|
||
|
||
if server.running {
|
||
t.Error("Server should not be running initially")
|
||
}
|
||
}
|
||
|
||
// TestGetAltSvcHeader_DefaultPort 测试默认端口 Alt-Svc 头
|
||
func TestGetAltSvcHeader_DefaultPort(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: ":443",
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
server, _ := NewServer(cfg, handler, &tls.Config{})
|
||
|
||
header := server.GetAltSvcHeader()
|
||
|
||
expected := `h3=":443"; ma=86400`
|
||
if header != expected {
|
||
t.Errorf("Expected Alt-Svc header '%s', got '%s'", expected, header)
|
||
}
|
||
}
|
||
|
||
// TestGetAltSvcHeader_CustomPort 测试自定义端口 Alt-Svc 头
|
||
func TestGetAltSvcHeader_CustomPort(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: ":8443",
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
server, _ := NewServer(cfg, handler, &tls.Config{})
|
||
|
||
header := server.GetAltSvcHeader()
|
||
|
||
expected := `h3=":8443"; ma=86400`
|
||
if header != expected {
|
||
t.Errorf("Expected Alt-Svc header '%s', got '%s'", expected, header)
|
||
}
|
||
}
|
||
|
||
// TestGetAltSvcHeader_Disabled 测试禁用 HTTP/3 时返回空
|
||
func TestGetAltSvcHeader_Disabled(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: false,
|
||
Listen: ":443",
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
server, _ := NewServer(cfg, handler, &tls.Config{})
|
||
|
||
header := server.GetAltSvcHeader()
|
||
|
||
if header != "" {
|
||
t.Errorf("Expected empty Alt-Svc header when disabled, got '%s'", header)
|
||
}
|
||
}
|
||
|
||
// TestGetAltSvcHeader_EmptyListen 测试空监听地址时使用默认端口
|
||
func TestGetAltSvcHeader_EmptyListen(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: "", // 空,使用默认 :443
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
server, _ := NewServer(cfg, handler, &tls.Config{})
|
||
|
||
header := server.GetAltSvcHeader()
|
||
|
||
expected := `h3=":443"; ma=86400`
|
||
if header != expected {
|
||
t.Errorf("Expected Alt-Svc header '%s', got '%s'", expected, header)
|
||
}
|
||
}
|
||
|
||
// TestGetStats 测试获取统计信息
|
||
func TestGetStats(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: ":8443",
|
||
Enable0RTT: true,
|
||
MaxStreams: 200,
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
server, _ := NewServer(cfg, handler, &tls.Config{})
|
||
|
||
stats := server.GetStats()
|
||
|
||
if stats.Running {
|
||
t.Error("Expected Running to be false initially")
|
||
}
|
||
|
||
if stats.Listen != ":8443" {
|
||
t.Errorf("Expected Listen ':8443', got '%s'", stats.Listen)
|
||
}
|
||
|
||
if !stats.Enable0RTT {
|
||
t.Error("Expected Enable0RTT to be true")
|
||
}
|
||
|
||
if stats.MaxStreams != 200 {
|
||
t.Errorf("Expected MaxStreams 200, got %d", stats.MaxStreams)
|
||
}
|
||
}
|
||
|
||
// TestIsRunning 测试运行状态检查
|
||
func TestIsRunning(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: ":443",
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
server, _ := NewServer(cfg, handler, &tls.Config{})
|
||
|
||
// 初始状态应该是 false
|
||
if server.IsRunning() {
|
||
t.Error("Expected IsRunning to be false initially")
|
||
}
|
||
|
||
// 手动设置运行状态(不启动真实服务器)
|
||
server.mu.Lock()
|
||
server.running = true
|
||
server.mu.Unlock()
|
||
|
||
if !server.IsRunning() {
|
||
t.Error("Expected IsRunning to be true after setting")
|
||
}
|
||
|
||
// 再次设置为 false
|
||
server.mu.Lock()
|
||
server.running = false
|
||
server.mu.Unlock()
|
||
|
||
if server.IsRunning() {
|
||
t.Error("Expected IsRunning to be false after unsetting")
|
||
}
|
||
}
|
||
|
||
// TestStop_NotRunning 测试停止未运行的服务器
|
||
func TestStop_NotRunning(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: ":443",
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
server, _ := NewServer(cfg, handler, &tls.Config{})
|
||
|
||
// 服务器未启动,Stop 应该返回 nil
|
||
err := server.Stop()
|
||
if err != nil {
|
||
t.Errorf("Expected nil error when stopping non-running server, got: %v", err)
|
||
}
|
||
}
|
||
|
||
// TestGracefulStop_NotRunning 测试优雅停止未运行的服务器
|
||
func TestGracefulStop_NotRunning(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: ":443",
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
server, _ := NewServer(cfg, handler, &tls.Config{})
|
||
|
||
// 服务器未启动,GracefulStop 应该返回 nil
|
||
err := server.GracefulStop(5 * time.Second)
|
||
if err != nil {
|
||
t.Errorf("Expected nil error when graceful stopping non-running server, got: %v", err)
|
||
}
|
||
}
|
||
|
||
// TestGracefulStop_WithTimeout 测试优雅停止超时
|
||
func TestGracefulStop_WithTimeout(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: ":443",
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
server, _ := NewServer(cfg, handler, &tls.Config{})
|
||
|
||
// 测试不同超时值
|
||
tests := []struct {
|
||
name string
|
||
timeout time.Duration
|
||
}{
|
||
{"zero timeout", 0},
|
||
{"short timeout", 100 * time.Millisecond},
|
||
{"long timeout", 30 * time.Second},
|
||
}
|
||
|
||
for _, tt := range tests {
|
||
t.Run(tt.name, func(t *testing.T) {
|
||
err := server.GracefulStop(tt.timeout)
|
||
if err != nil {
|
||
t.Errorf("Unexpected error: %v", err)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
// TestServer_MultipleStop 测试多次调用 Stop
|
||
func TestServer_MultipleStop(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: ":443",
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
server, _ := NewServer(cfg, handler, &tls.Config{})
|
||
|
||
// 多次调用 Stop 应该都是安全的
|
||
for i := range 3 {
|
||
err := server.Stop()
|
||
if err != nil {
|
||
t.Errorf("Stop call %d returned error: %v", i+1, err)
|
||
}
|
||
}
|
||
}
|
||
|
||
// TestServer_MultipleGracefulStop 测试多次调用 GracefulStop
|
||
func TestServer_MultipleGracefulStop(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: ":443",
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
server, _ := NewServer(cfg, handler, &tls.Config{})
|
||
|
||
// 多次调用 GracefulStop 应该都是安全的
|
||
for i := range 3 {
|
||
err := server.GracefulStop(1 * time.Second)
|
||
if err != nil {
|
||
t.Errorf("GracefulStop call %d returned error: %v", i+1, err)
|
||
}
|
||
}
|
||
}
|
||
|
||
// TestGetAltSvcHeader_PortBoundaries 测试端口边界值
|
||
func TestGetAltSvcHeader_PortBoundaries(t *testing.T) {
|
||
tests := []struct {
|
||
name string
|
||
listen string
|
||
expected string
|
||
}{
|
||
{
|
||
name: "标准 HTTP 端口 80",
|
||
listen: ":80",
|
||
expected: `h3=":80"; ma=86400`,
|
||
},
|
||
{
|
||
name: "标准 HTTPS 端口 443",
|
||
listen: ":443",
|
||
expected: `h3=":443"; ma=86400`,
|
||
},
|
||
{
|
||
name: "高端口 65535",
|
||
listen: ":65535",
|
||
expected: `h3=":65535"; ma=86400`,
|
||
},
|
||
{
|
||
name: "低端口 1",
|
||
listen: ":1",
|
||
expected: `h3=":1"; ma=86400`,
|
||
},
|
||
{
|
||
name: "带 IP 地址的监听",
|
||
listen: "0.0.0.0:8443",
|
||
expected: `h3=":0.0.0.0:8443"; ma=86400`,
|
||
},
|
||
{
|
||
name: "带 IPv6 地址的监听",
|
||
listen: "[::]:8443",
|
||
expected: `h3=":[::]:8443"; ma=86400`,
|
||
},
|
||
}
|
||
|
||
for _, tt := range tests {
|
||
t.Run(tt.name, func(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: tt.listen,
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
server, _ := NewServer(cfg, handler, &tls.Config{})
|
||
|
||
header := server.GetAltSvcHeader()
|
||
if header != tt.expected {
|
||
t.Errorf("GetAltSvcHeader() = %q, want %q", header, tt.expected)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
// TestGetAltSvcHeader_DisabledServer 测试禁用状态下的服务器
|
||
func TestGetAltSvcHeader_DisabledServer(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: false,
|
||
Listen: ":443",
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
server, _ := NewServer(cfg, handler, &tls.Config{})
|
||
|
||
header := server.GetAltSvcHeader()
|
||
if header != "" {
|
||
t.Errorf("Expected empty Alt-Svc header when disabled, got %q", header)
|
||
}
|
||
}
|
||
|
||
// TestGetAltSvcHeader_NilConfig 测试 nil 配置情况
|
||
func TestGetAltSvcHeader_NilConfig(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: ":443",
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
server, _ := NewServer(cfg, handler, &tls.Config{})
|
||
|
||
// 正常情况下应该返回 header
|
||
header := server.GetAltSvcHeader()
|
||
if header == "" {
|
||
t.Error("Expected non-empty Alt-Svc header with valid config")
|
||
}
|
||
}
|
||
|
||
// TestStart_AlreadyRunning 测试启动已运行的服务器
|
||
func TestStart_AlreadyRunning(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: ":0", // 使用随机端口避免冲突
|
||
MaxStreams: 100,
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
cert := generateTestCertificate(t)
|
||
tlsConfig := &tls.Config{
|
||
Certificates: []tls.Certificate{cert},
|
||
}
|
||
|
||
server, err := NewServer(cfg, handler, tlsConfig)
|
||
if err != nil {
|
||
t.Fatalf("Failed to create server: %v", err)
|
||
}
|
||
|
||
// 启动服务器
|
||
err = server.Start()
|
||
if err != nil {
|
||
t.Fatalf("Failed to start server: %v", err)
|
||
}
|
||
defer server.Stop()
|
||
|
||
// 再次启动应该失败
|
||
err = server.Start()
|
||
if err == nil {
|
||
t.Error("Expected error when starting already running server")
|
||
}
|
||
if err.Error() != "server already running" {
|
||
t.Errorf("Expected 'server already running' error, got: %v", err)
|
||
}
|
||
}
|
||
|
||
// TestStart_InvalidListenAddress 测试无效监听地址
|
||
func TestStart_InvalidListenAddress(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: "invalid:address:format", // 无效地址
|
||
MaxStreams: 100,
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
tlsConfig := &tls.Config{
|
||
Certificates: []tls.Certificate{},
|
||
}
|
||
|
||
server, err := NewServer(cfg, handler, tlsConfig)
|
||
if err != nil {
|
||
t.Fatalf("Failed to create server: %v", err)
|
||
}
|
||
|
||
err = server.Start()
|
||
if err == nil {
|
||
t.Error("Expected error for invalid listen address")
|
||
server.Stop()
|
||
}
|
||
}
|
||
|
||
// TestStop_RunningServer 测试停止运行中的服务器
|
||
func TestStop_RunningServer(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: ":0",
|
||
MaxStreams: 100,
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
cert := generateTestCertificate(t)
|
||
tlsConfig := &tls.Config{
|
||
Certificates: []tls.Certificate{cert},
|
||
}
|
||
|
||
server, err := NewServer(cfg, handler, tlsConfig)
|
||
if err != nil {
|
||
t.Fatalf("Failed to create server: %v", err)
|
||
}
|
||
|
||
// 启动服务器
|
||
err = server.Start()
|
||
if err != nil {
|
||
t.Fatalf("Failed to start server: %v", err)
|
||
}
|
||
|
||
if !server.IsRunning() {
|
||
t.Error("Server should be running after Start()")
|
||
}
|
||
|
||
// 停止服务器
|
||
err = server.Stop()
|
||
if err != nil {
|
||
t.Errorf("Unexpected error stopping server: %v", err)
|
||
}
|
||
|
||
if server.IsRunning() {
|
||
t.Error("Server should not be running after Stop()")
|
||
}
|
||
}
|
||
|
||
// TestGracefulStop_RunningServer 测试优雅停止运行中的服务器
|
||
func TestGracefulStop_RunningServer(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: ":0",
|
||
MaxStreams: 100,
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
cert := generateTestCertificate(t)
|
||
tlsConfig := &tls.Config{
|
||
Certificates: []tls.Certificate{cert},
|
||
}
|
||
|
||
server, err := NewServer(cfg, handler, tlsConfig)
|
||
if err != nil {
|
||
t.Fatalf("Failed to create server: %v", err)
|
||
}
|
||
|
||
// 启动服务器
|
||
err = server.Start()
|
||
if err != nil {
|
||
t.Fatalf("Failed to start server: %v", err)
|
||
}
|
||
|
||
if !server.IsRunning() {
|
||
t.Error("Server should be running after Start()")
|
||
}
|
||
|
||
// 优雅停止服务器
|
||
err = server.GracefulStop(5 * time.Second)
|
||
if err != nil {
|
||
t.Errorf("Unexpected error graceful stopping server: %v", err)
|
||
}
|
||
|
||
if server.IsRunning() {
|
||
t.Error("Server should not be running after GracefulStop()")
|
||
}
|
||
}
|
||
|
||
// TestStart_Enable0RTT 测试启用 0-RTT 时的警告日志
|
||
func TestStart_Enable0RTT(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: ":0",
|
||
Enable0RTT: true,
|
||
MaxStreams: 100,
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
cert := generateTestCertificate(t)
|
||
tlsConfig := &tls.Config{
|
||
Certificates: []tls.Certificate{cert},
|
||
}
|
||
|
||
server, err := NewServer(cfg, handler, tlsConfig)
|
||
if err != nil {
|
||
t.Fatalf("Failed to create server: %v", err)
|
||
}
|
||
|
||
err = server.Start()
|
||
if err != nil {
|
||
t.Fatalf("Failed to start server: %v", err)
|
||
}
|
||
defer server.Stop()
|
||
|
||
// 验证服务器已启动
|
||
if !server.IsRunning() {
|
||
t.Error("Server should be running")
|
||
}
|
||
}
|
||
|
||
// TestStart_DefaultValues 测试默认值设置
|
||
func TestStart_DefaultValues(t *testing.T) {
|
||
cfg := &config.HTTP3Config{
|
||
Enabled: true,
|
||
Listen: ":0",
|
||
MaxStreams: 0, // 使用默认值
|
||
}
|
||
handler := func(_ *fasthttp.RequestCtx) {}
|
||
|
||
cert := generateTestCertificate(t)
|
||
tlsConfig := &tls.Config{
|
||
Certificates: []tls.Certificate{cert},
|
||
}
|
||
|
||
server, err := NewServer(cfg, handler, tlsConfig)
|
||
if err != nil {
|
||
t.Fatalf("Failed to create server: %v", err)
|
||
}
|
||
|
||
err = server.Start()
|
||
if err != nil {
|
||
t.Fatalf("Failed to start server: %v", err)
|
||
}
|
||
defer server.Stop()
|
||
|
||
if !server.IsRunning() {
|
||
t.Error("Server should be running")
|
||
}
|
||
}
|
||
|
||
// generateTestCertificate 生成用于测试的自签名证书
|
||
func generateTestCertificate(t *testing.T) tls.Certificate {
|
||
t.Helper()
|
||
|
||
// 使用 RSA 密钥生成自签名证书
|
||
tmpl := &x509.Certificate{
|
||
SerialNumber: big.NewInt(1),
|
||
Subject: pkix.Name{CommonName: "localhost"},
|
||
NotBefore: time.Now(),
|
||
NotAfter: time.Now().Add(time.Hour),
|
||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
|
||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
|
||
BasicConstraintsValid: true,
|
||
DNSNames: []string{"localhost"},
|
||
IPAddresses: []net.IP{net.ParseIP("127.0.0.1")},
|
||
}
|
||
|
||
priv, err := rsa.GenerateKey(rand.Reader, 2048)
|
||
if err != nil {
|
||
t.Fatalf("Failed to generate RSA key: %v", err)
|
||
}
|
||
|
||
certDER, err := x509.CreateCertificate(rand.Reader, tmpl, tmpl, &priv.PublicKey, priv)
|
||
if err != nil {
|
||
t.Fatalf("Failed to create certificate: %v", err)
|
||
}
|
||
|
||
certPEM := pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE", Bytes: certDER})
|
||
keyPEM := pem.EncodeToMemory(&pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)})
|
||
|
||
cert, err := tls.X509KeyPair(certPEM, keyPEM)
|
||
if err != nil {
|
||
t.Fatalf("Failed to load certificate: %v", err)
|
||
}
|
||
|
||
return cert
|
||
}
|