lolly/internal/stream/ssl_test.go
xfy 2734b04d8f refactor: remove 16.8k lines of dead code across all internal packages
- Delete unused files: tempfile subsystem, matcher variants, server/internal
- Remove 200+ unused functions across proxy, ssl, lua, http2/3, stream, variable
- Fix proxy test type errors (backgroundRefresh ctx→Request)
- Move bench/tools mock backend into internal/testutil
- Remove corresponding test functions for all deleted code
2026-06-03 16:15:43 +08:00

196 lines
4.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Package stream 提供 TCP/UDP Stream 代理功能。
//
// 该文件包含 Stream SSL/TLS 支持的单元测试。
//
// 作者xfy
package stream
import (
"crypto/rand"
"crypto/rsa"
"crypto/tls"
"crypto/x509"
"encoding/pem"
"math/big"
"os"
"path/filepath"
"testing"
"time"
"rua.plus/lolly/internal/sslutil"
)
// generateTestCertificate 生成测试用的自签名证书
func generateTestCertificate(t *testing.T, certFile, keyFile string) {
t.Helper()
// 创建证书模板
template := &x509.Certificate{
SerialNumber: big.NewInt(1),
NotBefore: time.Now(),
NotAfter: time.Now().Add(24 * time.Hour),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
BasicConstraintsValid: true,
DNSNames: []string{"localhost"},
}
// 生成私钥和证书
key, err := rsa.GenerateKey(rand.Reader, 2048)
if err != nil {
t.Fatalf("Failed to generate key: %v", err)
}
certDER, err := x509.CreateCertificate(rand.Reader, template, template, &key.PublicKey, key)
if err != nil {
t.Fatalf("Failed to create certificate: %v", err)
}
// 写入证书文件
certOut, err := os.Create(certFile)
if err != nil {
t.Fatalf("Failed to create cert file: %v", err)
}
defer func() { _ = certOut.Close() }()
if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: certDER}); err != nil {
t.Fatalf("Failed to encode certificate: %v", err)
}
// 写入私钥文件
keyOut, err := os.Create(keyFile)
if err != nil {
t.Fatalf("Failed to create key file: %v", err)
}
defer func() { _ = keyOut.Close() }()
if err := pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(key)}); err != nil {
t.Fatalf("Failed to encode key: %v", err)
}
}
func TestParseMinTLSVersion(t *testing.T) {
tests := []struct {
protocols []string
wantVersion uint16
}{
{[]string{"TLSv1.3"}, tls.VersionTLS13},
{[]string{"TLSv1.2"}, tls.VersionTLS12},
{[]string{"TLSv1.2", "TLSv1.3"}, tls.VersionTLS12},
{[]string{}, tls.VersionTLS12},
{[]string{"Unknown"}, tls.VersionTLS12},
}
for _, tt := range tests {
got := sslutil.ParseMinTLSVersion(tt.protocols)
if got != tt.wantVersion {
t.Errorf("parseMinTLSVersion(%v) = %v, want %v", tt.protocols, got, tt.wantVersion)
}
}
}
func TestParseCipherSuites(t *testing.T) {
tests := []struct {
name string
ciphers []string
wantLen int
}{
{
name: "valid ciphers",
ciphers: []string{"ECDHE-RSA-AES128-GCM-SHA256", "ECDHE-RSA-AES256-GCM-SHA384"},
wantLen: 2,
},
{
name: "empty ciphers",
ciphers: []string{},
wantLen: 0, // returns nil for empty
},
{
name: "unknown ciphers",
ciphers: []string{"UNKNOWN-CIPHER"},
wantLen: 0, // returns nil for no valid ciphers
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := sslutil.ParseCipherSuitesLenient(tt.ciphers)
if tt.wantLen == 0 && got != nil {
t.Errorf("Expected nil, got %v", got)
} else if tt.wantLen > 0 && len(got) != tt.wantLen {
t.Errorf("Expected %d ciphers, got %d", tt.wantLen, len(got))
}
})
}
}
func TestLoadCertPool(t *testing.T) {
t.Run("valid cert", func(t *testing.T) {
tempDir := t.TempDir()
certFile := filepath.Join(tempDir, "ca.crt")
// 创建证书
template := &x509.Certificate{
SerialNumber: big.NewInt(1),
NotBefore: time.Now(),
NotAfter: time.Now().Add(24 * time.Hour),
IsCA: true,
KeyUsage: x509.KeyUsageCertSign,
}
key, _ := rsa.GenerateKey(rand.Reader, 2048)
certDER, _ := x509.CreateCertificate(rand.Reader, template, template, &key.PublicKey, key)
certOut, err := os.Create(certFile)
if err != nil {
t.Fatalf("Failed to create cert file: %v", err)
}
defer func() { _ = certOut.Close() }()
if err := pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: certDER}); err != nil {
t.Fatalf("Failed to encode certificate: %v", err)
}
pool, err := sslutil.LoadCertPool(certFile, "test")
if err != nil {
t.Fatalf("loadCertPool failed: %v", err)
}
if pool == nil {
t.Error("Expected non-nil pool")
}
})
t.Run("invalid path", func(t *testing.T) {
_, err := sslutil.LoadCertPool("/nonexistent/cert.pem", "test")
if err == nil {
t.Error("Expected error for nonexistent file")
}
})
t.Run("invalid content", func(t *testing.T) {
tempDir := t.TempDir()
certFile := filepath.Join(tempDir, "invalid.crt")
if err := os.WriteFile(certFile, []byte("not a certificate"), 0o644); err != nil {
t.Fatalf("写入无效证书文件失败: %v", err)
}
_, err := sslutil.LoadCertPool(certFile, "test")
if err == nil {
t.Error("Expected error for invalid certificate content")
}
})
}