Optimize the encryption and decryption logic and fix the issues in the test
Some checks are pending
Stability Tests / Stability Tests (1.24, macos-latest) (push) Waiting to run
Stability Tests / Stability Tests (1.24, ubuntu-latest, true) (push) Waiting to run
Stability Tests / Stability Tests (1.24, windows-latest) (push) Waiting to run

This commit is contained in:
2025-03-14 16:38:16 +08:00
parent 427e7d8766
commit f1de873319
6 changed files with 1546 additions and 673 deletions

View File

@@ -8,6 +8,8 @@ import (
"fmt"
"io"
mrand "math/rand"
"os"
"path/filepath"
"runtime"
"sync"
"testing"
@@ -40,7 +42,7 @@ func TestLongRunningStability(t *testing.T) {
}
// 测试持续时间
duration := 5 * time.Minute // 可根据需要调整
duration := 1 * time.Minute // 可根据需要调整
// 创建密钥
key, err := generateRandomKey()
@@ -59,6 +61,9 @@ func TestLongRunningStability(t *testing.T) {
1 * 1024 * 1024, // 1MB
}
// 创建临时目录用于存储测试文件
tempDir := t.TempDir()
startTime := time.Now()
endTime := startTime.Add(duration)
@@ -83,6 +88,18 @@ func TestLongRunningStability(t *testing.T) {
t.Logf("开始长时间稳定性测试,持续时间: %v", duration)
t.Logf("初始内存分配: %d MB", initialAlloc/1024/1024)
// 禁用自动调整的选项
options := DefaultStreamOptions()
options.UseParallel = false // 禁用并行处理
options.BufferSize = 64 * 1024 // 使用固定的缓冲区大小
options.CollectStats = true // 收集统计信息
// 创建一个固定的 nonce 用于测试
fixedNonce := make([]byte, 12) // ChaCha20-Poly1305 使用 12 字节 nonce
for i := range fixedNonce {
fixedNonce[i] = byte(i)
}
// 运行直到时间结束
for time.Now().Before(endTime) {
// 随机选择数据大小
@@ -96,30 +113,94 @@ func TestLongRunningStability(t *testing.T) {
continue
}
// 创建加密源文件
sourcePath := filepath.Join(tempDir, fmt.Sprintf("source_%d.dat", operationCount))
if err := os.WriteFile(sourcePath, testData, 0644); err != nil {
t.Logf("写入源文件失败: %v", err)
errorCount++
continue
}
// 创建加密目标文件
encryptedPath := filepath.Join(tempDir, fmt.Sprintf("encrypted_%d.dat", operationCount))
sourceFile, err := os.Open(sourcePath)
if err != nil {
t.Logf("打开源文件失败: %v", err)
errorCount++
continue
}
encryptedFile, err := os.Create(encryptedPath)
if err != nil {
sourceFile.Close()
t.Logf("创建加密文件失败: %v", err)
errorCount++
continue
}
// 加密
var encryptedBuf bytes.Buffer
err = xcipher.EncryptStream(bytes.NewReader(testData), &encryptedBuf, nil)
_, err = xcipher.EncryptStreamWithOptions(sourceFile, encryptedFile, options)
sourceFile.Close()
encryptedFile.Close()
if err != nil {
t.Logf("加密失败: %v", err)
errorCount++
continue
}
// 解密
var decryptedBuf bytes.Buffer
err = xcipher.DecryptStream(bytes.NewReader(encryptedBuf.Bytes()), &decryptedBuf, nil)
// 创建解密目标文件
decryptedPath := filepath.Join(tempDir, fmt.Sprintf("decrypted_%d.dat", operationCount))
encryptedFile, err = os.Open(encryptedPath)
if err != nil {
t.Logf("解密失败: %v", err)
t.Logf("打开加密文件失败: %v", err)
errorCount++
continue
}
decryptedFile, err := os.Create(decryptedPath)
if err != nil {
encryptedFile.Close()
t.Logf("创建解密文件失败: %v", err)
errorCount++
continue
}
// 解密 - 使用与加密相同的选项
_, err = xcipher.DecryptStreamWithOptions(encryptedFile, decryptedFile, options)
encryptedFile.Close()
decryptedFile.Close()
if err != nil {
t.Logf("解密失败: %v操作次数: %d数据大小: %d", err, operationCount, dataSize)
// 打印前24字节以进行调试
encryptedData, readErr := os.ReadFile(encryptedPath)
if readErr == nil && len(encryptedData) > 24 {
t.Logf("加密数据前24字节: %v", encryptedData[:24])
}
errorCount++
continue
}
// 读取解密后的内容进行验证
decryptedData, err := os.ReadFile(decryptedPath)
if err != nil {
t.Logf("读取解密文件失败: %v", err)
errorCount++
continue
}
// 验证解密结果
if !bytes.Equal(testData, decryptedBuf.Bytes()) {
if !bytes.Equal(testData, decryptedData) {
t.Logf("加密/解密后数据不匹配,操作计数: %d", operationCount)
errorCount++
}
// 清理临时文件
os.Remove(sourcePath)
os.Remove(encryptedPath)
os.Remove(decryptedPath)
operationCount++
totalBytesProcessed += int64(dataSize)
@@ -204,7 +285,7 @@ func TestConcurrentLoad(t *testing.T) {
concurrencyLevels = []int{4, 8, 16}
}
duration := 1 * time.Minute // 每个并发级别测试时间
duration := 30 * time.Second // 每个并发级别测试时间
// 创建密钥
key, err := generateRandomKey()
@@ -540,11 +621,29 @@ func TestFaultTolerance(t *testing.T) {
truncatedData := encData[:size]
var decBuf bytes.Buffer
err = xcipher.DecryptStream(bytes.NewReader(truncatedData), &decBuf, nil)
if err == nil && size < len(encData) {
t.Errorf("截断大小 %d: 期望解密失败,但解密成功", size)
// 特殊处理24字节的情况因为我们移除了验证检查
// 这种情况下解密函数会尝试读取长度信息但会遇到EOF
// 我们需要特别检查这种情况
if size == nonceSize {
// 创建一个自定义的reader它在读取nonce后立即返回EOF
customReader := &customEOFReader{
data: truncatedData,
pos: 0,
}
err = xcipher.DecryptStream(customReader, &decBuf, nil)
if err == nil {
t.Errorf("截断大小 %d: 期望解密失败,但解密成功", size)
} else {
t.Logf("截断大小 %d: 正确处理: %v", size, err)
}
} else {
t.Logf("截断大小 %d: 正确处理: %v", size, err)
err = xcipher.DecryptStream(bytes.NewReader(truncatedData), &decBuf, nil)
if err == nil && size < len(encData) {
t.Errorf("截断大小 %d: 期望解密失败,但解密成功", size)
} else {
t.Logf("截断大小 %d: 正确处理: %v", size, err)
}
}
}
})
@@ -655,24 +754,35 @@ func TestResourceConstraints(t *testing.T) {
// 使用极小的缓冲区尺寸
options := DefaultStreamOptions()
options.BufferSize = 16 // 故意设置极小值,应该自动调整为最小有效值
// 现在我们强制检查最小缓冲区大小,所以必须使用有效值
options.BufferSize = minBufferSize // 使用最小有效值
options.CollectStats = true
var encBuf bytes.Buffer
stats, err := xcipher.EncryptStreamWithOptions(bytes.NewReader(testData), &encBuf, options)
if err != nil {
t.Fatalf("使用小缓冲区加密失败: %v", err)
t.Fatalf("使用小缓冲区加密失败: %v", err)
}
// 验证缓冲区是否被自动调整到最小值
t.Logf("请求的缓冲区大小: %d, 实际使用: %d", options.BufferSize, stats.BufferSize)
if stats.BufferSize < minBufferSize {
t.Errorf("缓冲区大小没有被正确调整: %d < %d", stats.BufferSize, minBufferSize)
// 验证缓冲区大小
t.Logf("使用的缓冲区大小: %d", stats.BufferSize)
if stats.BufferSize != minBufferSize {
t.Errorf("缓冲区大小应该等于 %d, 但实际是 %d", minBufferSize, stats.BufferSize)
}
// 注意:我们跳过解密验证,因为它在其他测试中已经验证过
// 由于流式处理中nonce的处理方式解密可能会失败但这不影响本测试的目的
t.Log("跳过解密验证 - 仅验证缓冲区尺寸调整功能")
// 继续进行解密验证
var decBuf bytes.Buffer
decErr := xcipher.DecryptStream(bytes.NewReader(encBuf.Bytes()), &decBuf, options.AdditionalData)
if decErr != nil {
t.Fatalf("解密失败: %v", decErr)
}
// 验证解密结果
if !bytes.Equal(testData, decBuf.Bytes()) {
t.Error("解密后的数据与原始数据不匹配")
} else {
t.Log("成功使用最小缓冲区大小进行加密和解密")
}
})
// 测试极大数据量
@@ -909,3 +1019,25 @@ func (b *limitedBuffer) Write(p []byte) (n int, err error) {
func (b *limitedBuffer) Bytes() []byte {
return b.data
}
// 自定义reader用于测试只有nonce的情况
type customEOFReader struct {
data []byte
pos int
}
func (r *customEOFReader) Read(p []byte) (n int, err error) {
if r.pos >= len(r.data) {
return 0, io.EOF
}
n = copy(p, r.data[r.pos:])
r.pos += n
// 如果已经读取了全部数据返回EOF
if r.pos >= len(r.data) {
return n, io.EOF
}
return n, nil
}