252 lines
5.4 KiB
Go
252 lines
5.4 KiB
Go
|
|
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!")
|
|||
|
|
}
|