feat(backend): 实现Go后端API并添加测试脚本
This commit is contained in:
166
background/test_scripts/concurrent_load.go
Normal file
166
background/test_scripts/concurrent_load.go
Normal file
@@ -0,0 +1,166 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
baseURL = "http://localhost:6902/api"
|
||||
concurrency = 10 // 并发数
|
||||
)
|
||||
|
||||
// 并发上传文件
|
||||
func concurrentUploads(wg *sync.WaitGroup, filePaths []string, results chan<- string) {
|
||||
defer wg.Done()
|
||||
|
||||
for _, filePath := range filePaths {
|
||||
// 打开文件
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("Error opening file %s: %v", filePath, err)
|
||||
continue
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 创建multipart表单
|
||||
body := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(body)
|
||||
|
||||
// 添加name字段
|
||||
appName := filepath.Base(filePath)
|
||||
writer.WriteField("name", appName)
|
||||
|
||||
// 添加file字段
|
||||
part, err := writer.CreateFormFile("file", filepath.Base(filePath))
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("Error creating form file %s: %v", filePath, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// 复制文件内容
|
||||
_, err = io.Copy(part, file)
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("Error copying file content %s: %v", filePath, err)
|
||||
continue
|
||||
}
|
||||
|
||||
writer.Close()
|
||||
|
||||
// 创建请求
|
||||
req, err := http.NewRequest("POST", baseURL+"/apps", body)
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("Error creating request for %s: %v", filePath, err)
|
||||
continue
|
||||
}
|
||||
req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||
|
||||
// 发送请求
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("Error sending request for %s: %v", filePath, err)
|
||||
continue
|
||||
}
|
||||
resp.Body.Close()
|
||||
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
results <- fmt.Sprintf("Successfully uploaded %s", filePath)
|
||||
} else {
|
||||
results <- fmt.Sprintf("Failed to upload %s, status: %d", filePath, resp.StatusCode)
|
||||
}
|
||||
|
||||
// 等待一下,避免请求过于密集
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
// 并发获取App列表
|
||||
func concurrentGetApps(wg *sync.WaitGroup, results chan<- string) {
|
||||
defer wg.Done()
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
resp, err := http.Get(baseURL + "/apps")
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("Error getting apps: %v", err)
|
||||
continue
|
||||
}
|
||||
resp.Body.Close()
|
||||
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
results <- "Successfully got apps list"
|
||||
} else {
|
||||
results <- fmt.Sprintf("Failed to get apps list, status: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
// 等待一下,避免请求过于密集
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("Starting concurrent test...")
|
||||
startTime := time.Now()
|
||||
|
||||
// 获取测试文件列表
|
||||
testFiles := []string{
|
||||
"fake_files/empty.txt",
|
||||
"fake_files/fake_file_0_4.txt",
|
||||
}
|
||||
|
||||
// 创建结果通道
|
||||
results := make(chan string, 100)
|
||||
|
||||
// 创建WaitGroup
|
||||
var wg sync.WaitGroup
|
||||
|
||||
// 启动并发上传协程
|
||||
for i := 0; i < concurrency; i++ {
|
||||
wg.Add(1)
|
||||
go concurrentUploads(&wg, testFiles, results)
|
||||
}
|
||||
|
||||
// 启动并发获取App列表协程
|
||||
for i := 0; i < concurrency/2; i++ {
|
||||
wg.Add(1)
|
||||
go concurrentGetApps(&wg, results)
|
||||
}
|
||||
|
||||
// 等待所有协程完成
|
||||
wg.Wait()
|
||||
close(results)
|
||||
|
||||
// 打印结果
|
||||
fmt.Println("\nTest Results:")
|
||||
successCount := 0
|
||||
errorCount := 0
|
||||
for result := range results {
|
||||
fmt.Println(result)
|
||||
if len(result) > 8 && result[:8] == "Successfully" {
|
||||
successCount++
|
||||
} else {
|
||||
errorCount++
|
||||
}
|
||||
}
|
||||
|
||||
// 打印统计信息
|
||||
totalTime := time.Since(startTime)
|
||||
fmt.Printf("\nTest Statistics:")
|
||||
fmt.Printf("\n- Total requests: %d", successCount+errorCount)
|
||||
fmt.Printf("\n- Successful requests: %d", successCount)
|
||||
fmt.Printf("\n- Failed requests: %d", errorCount)
|
||||
fmt.Printf("\n- Total time: %v", totalTime)
|
||||
fmt.Printf("\n- Requests per second: %.2f\n", float64(successCount+errorCount)/totalTime.Seconds())
|
||||
|
||||
if errorCount == 0 {
|
||||
fmt.Println("\n✅ All concurrent requests succeeded! System is stable.")
|
||||
} else {
|
||||
fmt.Printf("\n❌ %d concurrent requests failed. System may have stability issues.", errorCount)
|
||||
}
|
||||
}
|
||||
166
background/test_scripts/concurrent_load_test.go
Normal file
166
background/test_scripts/concurrent_load_test.go
Normal file
@@ -0,0 +1,166 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
baseURL = "http://localhost:6902/api"
|
||||
concurrency = 10 // 并发数
|
||||
)
|
||||
|
||||
// 并发上传文件
|
||||
func concurrentUploads(wg *sync.WaitGroup, filePaths []string, results chan<- string) {
|
||||
defer wg.Done()
|
||||
|
||||
for _, filePath := range filePaths {
|
||||
// 打开文件
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("Error opening file %s: %v", filePath, err)
|
||||
continue
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 创建multipart表单
|
||||
body := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(body)
|
||||
|
||||
// 添加name字段
|
||||
appName := filepath.Base(filePath)
|
||||
writer.WriteField("name", appName)
|
||||
|
||||
// 添加file字段
|
||||
part, err := writer.CreateFormFile("file", filepath.Base(filePath))
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("Error creating form file %s: %v", filePath, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// 复制文件内容
|
||||
_, err = io.Copy(part, file)
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("Error copying file content %s: %v", filePath, err)
|
||||
continue
|
||||
}
|
||||
|
||||
writer.Close()
|
||||
|
||||
// 创建请求
|
||||
req, err := http.NewRequest("POST", baseURL+"/apps", body)
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("Error creating request for %s: %v", filePath, err)
|
||||
continue
|
||||
}
|
||||
req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||
|
||||
// 发送请求
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("Error sending request for %s: %v", filePath, err)
|
||||
continue
|
||||
}
|
||||
resp.Body.Close()
|
||||
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
results <- fmt.Sprintf("Successfully uploaded %s", filePath)
|
||||
} else {
|
||||
results <- fmt.Sprintf("Failed to upload %s, status: %d", filePath, resp.StatusCode)
|
||||
}
|
||||
|
||||
// 等待一下,避免请求过于密集
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
// 并发获取App列表
|
||||
func concurrentGetApps(wg *sync.WaitGroup, results chan<- string) {
|
||||
defer wg.Done()
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
resp, err := http.Get(baseURL + "/apps")
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("Error getting apps: %v", err)
|
||||
continue
|
||||
}
|
||||
resp.Body.Close()
|
||||
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
results <- "Successfully got apps list"
|
||||
} else {
|
||||
results <- fmt.Sprintf("Failed to get apps list, status: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
// 等待一下,避免请求过于密集
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("Starting concurrent test...")
|
||||
startTime := time.Now()
|
||||
|
||||
// 获取测试文件列表
|
||||
testFiles := []string{
|
||||
"fake_files/empty.txt",
|
||||
"fake_files/fake_file_0_4.txt",
|
||||
}
|
||||
|
||||
// 创建结果通道
|
||||
results := make(chan string, 100)
|
||||
|
||||
// 创建WaitGroup
|
||||
var wg sync.WaitGroup
|
||||
|
||||
// 启动并发上传协程
|
||||
for i := 0; i < concurrency; i++ {
|
||||
wg.Add(1)
|
||||
go concurrentUploads(&wg, testFiles, results)
|
||||
}
|
||||
|
||||
// 启动并发获取App列表协程
|
||||
for i := 0; i < concurrency/2; i++ {
|
||||
wg.Add(1)
|
||||
go concurrentGetApps(&wg, results)
|
||||
}
|
||||
|
||||
// 等待所有协程完成
|
||||
wg.Wait()
|
||||
close(results)
|
||||
|
||||
// 打印结果
|
||||
fmt.Println("\nTest Results:")
|
||||
successCount := 0
|
||||
errorCount := 0
|
||||
for result := range results {
|
||||
fmt.Println(result)
|
||||
if len(result) > 8 && result[:8] == "Successfully" {
|
||||
successCount++
|
||||
} else {
|
||||
errorCount++
|
||||
}
|
||||
}
|
||||
|
||||
// 打印统计信息
|
||||
totalTime := time.Since(startTime)
|
||||
fmt.Printf("\nTest Statistics:")
|
||||
fmt.Printf("\n- Total requests: %d", successCount+errorCount)
|
||||
fmt.Printf("\n- Successful requests: %d", successCount)
|
||||
fmt.Printf("\n- Failed requests: %d", errorCount)
|
||||
fmt.Printf("\n- Total time: %v", totalTime)
|
||||
fmt.Printf("\n- Requests per second: %.2f\n", float64(successCount+errorCount)/totalTime.Seconds())
|
||||
|
||||
if errorCount == 0 {
|
||||
fmt.Println("\n✅ All concurrent requests succeeded! System is stable.")
|
||||
} else {
|
||||
fmt.Printf("\n❌ %d concurrent requests failed. System may have stability issues.", errorCount)
|
||||
}
|
||||
}
|
||||
166
background/test_scripts/concurrent_test.go
Normal file
166
background/test_scripts/concurrent_test.go
Normal file
@@ -0,0 +1,166 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
baseURL = "http://localhost:6902/api"
|
||||
concurrency = 10 // 并发数
|
||||
)
|
||||
|
||||
// 并发上传文件
|
||||
func concurrentUploads(wg *sync.WaitGroup, filePaths []string, results chan<- string) {
|
||||
defer wg.Done()
|
||||
|
||||
for _, filePath := range filePaths {
|
||||
// 打开文件
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("Error opening file %s: %v", filePath, err)
|
||||
continue
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 创建multipart表单
|
||||
body := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(body)
|
||||
|
||||
// 添加name字段
|
||||
appName := filepath.Base(filePath)
|
||||
writer.WriteField("name", appName)
|
||||
|
||||
// 添加file字段
|
||||
part, err := writer.CreateFormFile("file", filepath.Base(filePath))
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("Error creating form file %s: %v", filePath, err)
|
||||
continue
|
||||
}
|
||||
|
||||
// 复制文件内容
|
||||
_, err = io.Copy(part, file)
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("Error copying file content %s: %v", filePath, err)
|
||||
continue
|
||||
}
|
||||
|
||||
writer.Close()
|
||||
|
||||
// 创建请求
|
||||
req, err := http.NewRequest("POST", baseURL+"/apps", body)
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("Error creating request for %s: %v", filePath, err)
|
||||
continue
|
||||
}
|
||||
req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||
|
||||
// 发送请求
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("Error sending request for %s: %v", filePath, err)
|
||||
continue
|
||||
}
|
||||
resp.Body.Close()
|
||||
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
results <- fmt.Sprintf("Successfully uploaded %s", filePath)
|
||||
} else {
|
||||
results <- fmt.Sprintf("Failed to upload %s, status: %d", filePath, resp.StatusCode)
|
||||
}
|
||||
|
||||
// 等待一下,避免请求过于密集
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
// 并发获取App列表
|
||||
func concurrentGetApps(wg *sync.WaitGroup, results chan<- string) {
|
||||
defer wg.Done()
|
||||
|
||||
for i := 0; i < 5; i++ {
|
||||
resp, err := http.Get(baseURL + "/apps")
|
||||
if err != nil {
|
||||
results <- fmt.Sprintf("Error getting apps: %v", err)
|
||||
continue
|
||||
}
|
||||
resp.Body.Close()
|
||||
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
results <- "Successfully got apps list"
|
||||
} else {
|
||||
results <- fmt.Sprintf("Failed to get apps list, status: %d", resp.StatusCode)
|
||||
}
|
||||
|
||||
// 等待一下,避免请求过于密集
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("Starting concurrent test...")
|
||||
startTime := time.Now()
|
||||
|
||||
// 获取测试文件列表
|
||||
testFiles := []string{
|
||||
"fake_files/empty.txt",
|
||||
"fake_files/fake_file_0_4.txt",
|
||||
}
|
||||
|
||||
// 创建结果通道
|
||||
results := make(chan string, 100)
|
||||
|
||||
// 创建WaitGroup
|
||||
var wg sync.WaitGroup
|
||||
|
||||
// 启动并发上传协程
|
||||
for i := 0; i < concurrency; i++ {
|
||||
wg.Add(1)
|
||||
go concurrentUploads(&wg, testFiles, results)
|
||||
}
|
||||
|
||||
// 启动并发获取App列表协程
|
||||
for i := 0; i < concurrency/2; i++ {
|
||||
wg.Add(1)
|
||||
go concurrentGetApps(&wg, results)
|
||||
}
|
||||
|
||||
// 等待所有协程完成
|
||||
wg.Wait()
|
||||
close(results)
|
||||
|
||||
// 打印结果
|
||||
fmt.Println("\nTest Results:")
|
||||
successCount := 0
|
||||
errorCount := 0
|
||||
for result := range results {
|
||||
fmt.Println(result)
|
||||
if len(result) > 8 && result[:8] == "Successfully" {
|
||||
successCount++
|
||||
} else {
|
||||
errorCount++
|
||||
}
|
||||
}
|
||||
|
||||
// 打印统计信息
|
||||
totalTime := time.Since(startTime)
|
||||
fmt.Printf("\nTest Statistics:")
|
||||
fmt.Printf("\n- Total requests: %d", successCount+errorCount)
|
||||
fmt.Printf("\n- Successful requests: %d", successCount)
|
||||
fmt.Printf("\n- Failed requests: %d", errorCount)
|
||||
fmt.Printf("\n- Total time: %v", totalTime)
|
||||
fmt.Printf("\n- Requests per second: %.2f\n", float64(successCount+errorCount)/totalTime.Seconds())
|
||||
|
||||
if errorCount == 0 {
|
||||
fmt.Println("\n✅ All concurrent requests succeeded! System is stable.")
|
||||
} else {
|
||||
fmt.Printf("\n❌ %d concurrent requests failed. System may have stability issues.", errorCount)
|
||||
}
|
||||
}
|
||||
68
background/test_scripts/generate_fake_files.go
Normal file
68
background/test_scripts/generate_fake_files.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 生成指定大小的随机字节数据
|
||||
func generateRandomData(size int64) []byte {
|
||||
data := make([]byte, size)
|
||||
_, err := rand.Read(data)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
// 生成假文件
|
||||
func generateFakeFiles() {
|
||||
// 确保输出目录存在
|
||||
outputDir := "fake_files"
|
||||
err := os.MkdirAll(outputDir, 0755)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 定义要生成的文件类型和大小
|
||||
fileTypes := []string{".apk", ".ipa", ".zip", ".txt", ".pdf"}
|
||||
fileSizes := []int64{
|
||||
1024, // 1KB
|
||||
1024 * 1024, // 1MB
|
||||
5 * 1024 * 1024, // 5MB
|
||||
}
|
||||
|
||||
// 生成文件
|
||||
for i, size := range fileSizes {
|
||||
for _, ext := range fileTypes {
|
||||
filename := fmt.Sprintf("fake_file_%d_%d%s", i, len(ext), ext)
|
||||
filepath := filepath.Join(outputDir, filename)
|
||||
data := generateRandomData(size)
|
||||
err := os.WriteFile(filepath, data, 0644)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("Generated %s (%d bytes)\n", filepath, size)
|
||||
}
|
||||
}
|
||||
|
||||
// 生成一个空文件
|
||||
emptyFile := filepath.Join(outputDir, "empty.txt")
|
||||
err = os.WriteFile(emptyFile, []byte{}, 0644)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
fmt.Printf("Generated %s (0 bytes)\n", emptyFile)
|
||||
}
|
||||
|
||||
func main() {
|
||||
// 初始化随机数生成器
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
fmt.Println("Generating fake files...")
|
||||
generateFakeFiles()
|
||||
fmt.Println("Fake files generated successfully!")
|
||||
}
|
||||
252
background/test_scripts/test_backend.go
Normal file
252
background/test_scripts/test_backend.go
Normal file
@@ -0,0 +1,252 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime/multipart"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
baseURL = "http://localhost:6902/api"
|
||||
)
|
||||
|
||||
// App 结构体定义
|
||||
type App struct {
|
||||
ID string `json:"id"`
|
||||
Name string `json:"name"`
|
||||
FileName string `json:"fileName"`
|
||||
Date string `json:"date"`
|
||||
}
|
||||
|
||||
// 获取App列表
|
||||
func getApps() ([]App, error) {
|
||||
resp, err := http.Get(baseURL + "/apps")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var apps []App
|
||||
if err := json.Unmarshal(body, &apps); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return apps, nil
|
||||
}
|
||||
|
||||
// 上传App
|
||||
func uploadApp(name, filePath string) (bool, error) {
|
||||
// 打开文件
|
||||
file, err := os.Open(filePath)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
// 创建multipart表单
|
||||
body := &bytes.Buffer{}
|
||||
writer := multipart.NewWriter(body)
|
||||
|
||||
// 添加name字段
|
||||
writer.WriteField("name", name)
|
||||
|
||||
// 添加file字段
|
||||
part, err := writer.CreateFormFile("file", filepath.Base(filePath))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
// 复制文件内容到表单
|
||||
if _, err := io.Copy(part, file); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
writer.Close()
|
||||
|
||||
// 创建请求
|
||||
req, err := http.NewRequest("POST", baseURL+"/apps", body)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
req.Header.Set("Content-Type", writer.FormDataContentType())
|
||||
|
||||
// 发送请求
|
||||
resp, err := http.DefaultClient.Do(req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// 解析响应
|
||||
respBody, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
var response map[string]bool
|
||||
if err := json.Unmarshal(respBody, &response); err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return response["success"], nil
|
||||
}
|
||||
|
||||
// 下载App
|
||||
func downloadApp(id string) ([]byte, error) {
|
||||
resp, err := http.Get(baseURL + "/apps/" + id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
body, _ := ioutil.ReadAll(resp.Body)
|
||||
return nil, fmt.Errorf("download failed: %s, %s", resp.Status, string(body))
|
||||
}
|
||||
|
||||
return ioutil.ReadAll(resp.Body)
|
||||
}
|
||||
|
||||
// 测试上传和下载功能
|
||||
func testUploadDownload() error {
|
||||
// 获取当前目录下的fake_files目录
|
||||
fakeFilesDir := "fake_files"
|
||||
|
||||
// 读取fake_files目录下的所有文件
|
||||
files, err := ioutil.ReadDir(fakeFilesDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 上传每个文件
|
||||
for _, file := range files {
|
||||
if file.IsDir() {
|
||||
continue
|
||||
}
|
||||
|
||||
filePath := filepath.Join(fakeFilesDir, file.Name())
|
||||
appName := strings.TrimSuffix(file.Name(), filepath.Ext(file.Name()))
|
||||
|
||||
fmt.Printf("Uploading %s...\n", file.Name())
|
||||
success, err := uploadApp(appName, filePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to upload %s: %v", file.Name(), err)
|
||||
}
|
||||
if !success {
|
||||
return fmt.Errorf("upload %s failed", file.Name())
|
||||
}
|
||||
fmt.Printf("Uploaded %s successfully\n", file.Name())
|
||||
|
||||
// 等待一下,避免并发问题
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
|
||||
// 获取App列表
|
||||
apps, err := getApps()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get apps: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("\nTotal %d apps uploaded:\n", len(apps))
|
||||
for _, app := range apps {
|
||||
fmt.Printf("- %s (%s)\n", app.Name, app.FileName)
|
||||
}
|
||||
|
||||
// 测试下载第一个App
|
||||
if len(apps) > 0 {
|
||||
fmt.Printf("\nDownloading %s...\n", apps[0].FileName)
|
||||
data, err := downloadApp(apps[0].ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to download %s: %v", apps[0].FileName, err)
|
||||
}
|
||||
fmt.Printf("Downloaded %s successfully, size: %d bytes\n", apps[0].FileName, len(data))
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// 测试文件覆盖情况
|
||||
func testFileOverwrite() error {
|
||||
// 上传同一个文件两次,测试是否会覆盖
|
||||
filePath := "fake_files/empty.txt"
|
||||
appName := "Test Overwrite"
|
||||
|
||||
fmt.Printf("\nTesting file overwrite...\n")
|
||||
|
||||
// 第一次上传
|
||||
fmt.Printf("First upload of %s...\n", filePath)
|
||||
success, err := uploadApp(appName, filePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("first upload failed: %v", err)
|
||||
}
|
||||
if !success {
|
||||
return fmt.Errorf("first upload returned false")
|
||||
}
|
||||
|
||||
// 第二次上传
|
||||
fmt.Printf("Second upload of %s...\n", filePath)
|
||||
success, err = uploadApp(appName+" 2", filePath)
|
||||
if err != nil {
|
||||
return fmt.Errorf("second upload failed: %v", err)
|
||||
}
|
||||
if !success {
|
||||
return fmt.Errorf("second upload returned false")
|
||||
}
|
||||
|
||||
// 获取App列表,应该有两个不同ID的App,但文件名相同
|
||||
apps, err := getApps()
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get apps: %v", err)
|
||||
}
|
||||
|
||||
fmt.Printf("\nAfter two uploads, total %d apps:\n", len(apps))
|
||||
emptyTxtApps := 0
|
||||
for _, app := range apps {
|
||||
if app.FileName == "empty.txt" {
|
||||
emptyTxtApps++
|
||||
fmt.Printf("- %s (%s) [ID: %s]\n", app.Name, app.FileName, app.ID)
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("\nFound %d apps with filename 'empty.txt'\n", emptyTxtApps)
|
||||
if emptyTxtApps != 2 {
|
||||
return fmt.Errorf("expected 2 apps with filename 'empty.txt', got %d", emptyTxtApps)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
fmt.Println("Testing app distribution backend...")
|
||||
|
||||
// 等待服务启动
|
||||
fmt.Println("\nWaiting for server to start...")
|
||||
time.Sleep(2 * time.Second)
|
||||
|
||||
// 测试上传下载功能
|
||||
if err := testUploadDownload(); err != nil {
|
||||
fmt.Printf("Error in testUploadDownload: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
// 测试文件覆盖情况
|
||||
if err := testFileOverwrite(); err != nil {
|
||||
fmt.Printf("Error in testFileOverwrite: %v\n", err)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println("\nAll tests passed successfully!")
|
||||
}
|
||||
Reference in New Issue
Block a user