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