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) } }