github.com/qiniu/go-sdk/v7@v7.27.0/sandbox/envd_test.go (about)

     1  package sandbox
     2  
     3  import (
     4  	"bytes"
     5  	"context"
     6  	"crypto/sha256"
     7  	"fmt"
     8  	"io"
     9  	"mime"
    10  	"mime/multipart"
    11  	"testing"
    12  )
    13  
    14  func TestGetHost(t *testing.T) {
    15  	domain := "example.com"
    16  	sb := &Sandbox{sandboxID: "sb-123", domain: &domain}
    17  
    18  	got := sb.GetHost(8080)
    19  	want := "8080-sb-123.example.com"
    20  	if got != want {
    21  		t.Errorf("GetHost = %q, want %q", got, want)
    22  	}
    23  }
    24  
    25  func TestGetHostNilDomain(t *testing.T) {
    26  	sb := &Sandbox{sandboxID: "sb-456"}
    27  
    28  	got := sb.GetHost(3000)
    29  	if got != "" {
    30  		t.Errorf("GetHost with nil domain = %q, want empty string", got)
    31  	}
    32  }
    33  
    34  func TestGetHostEmptyDomain(t *testing.T) {
    35  	domain := ""
    36  	sb := &Sandbox{sandboxID: "sb-789", domain: &domain}
    37  
    38  	got := sb.GetHost(443)
    39  	if got != "" {
    40  		t.Errorf("GetHost with empty domain = %q, want empty string", got)
    41  	}
    42  }
    43  
    44  func TestEnvdURL(t *testing.T) {
    45  	domain := "test.dev"
    46  	sb := &Sandbox{sandboxID: "sb-100", domain: &domain, client: &Client{config: &Config{}}}
    47  
    48  	got := sb.envdURL()
    49  	want := "https://49983-sb-100.test.dev"
    50  	if got != want {
    51  		t.Errorf("envdURL = %q, want %q", got, want)
    52  	}
    53  }
    54  
    55  func TestEnvdBasicAuth(t *testing.T) {
    56  	auth := envdBasicAuth("testuser")
    57  	// base64("testuser:") = "dGVzdHVzZXI6"
    58  	want := "Basic dGVzdHVzZXI6"
    59  	if auth != want {
    60  		t.Errorf("envdBasicAuth = %q, want %q", auth, want)
    61  	}
    62  }
    63  
    64  func TestFileSignature(t *testing.T) {
    65  	sig := fileSignature("/test/file.txt", "read", "user", "token123", 300)
    66  	raw := "/test/file.txt:read:user:token123:300"
    67  	hash := sha256.Sum256([]byte(raw))
    68  	want := "v1_" + fmt.Sprintf("%x", hash)
    69  	if sig != want {
    70  		t.Errorf("fileSignature = %q, want %q", sig, want)
    71  	}
    72  }
    73  
    74  func TestDownloadURL(t *testing.T) {
    75  	domain := "test.dev"
    76  	token := "mytoken"
    77  	sb := &Sandbox{sandboxID: "sb-100", domain: &domain, envdAccessToken: &token, client: &Client{config: &Config{}}}
    78  
    79  	u := sb.DownloadURL("/home/user/file.txt")
    80  	// 验证 URL 包含必要的查询参数
    81  	if u == "" {
    82  		t.Fatal("DownloadURL returned empty string")
    83  	}
    84  	// 检查基础结构
    85  	if got := "https://49983-sb-100.test.dev/files?"; len(u) < len(got) || u[:len(got)] != got {
    86  		t.Errorf("DownloadURL prefix = %q, want prefix %q", u, got)
    87  	}
    88  }
    89  
    90  func TestUploadURL(t *testing.T) {
    91  	domain := "test.dev"
    92  	token := "mytoken"
    93  	sb := &Sandbox{sandboxID: "sb-100", domain: &domain, envdAccessToken: &token, client: &Client{config: &Config{}}}
    94  
    95  	u := sb.UploadURL("/home/user/file.txt")
    96  	if u == "" {
    97  		t.Fatal("UploadURL returned empty string")
    98  	}
    99  	if got := "https://49983-sb-100.test.dev/files?"; len(u) < len(got) || u[:len(got)] != got {
   100  		t.Errorf("UploadURL prefix = %q, want prefix %q", u, got)
   101  	}
   102  }
   103  
   104  func TestDownloadURLWithoutToken(t *testing.T) {
   105  	domain := "test.dev"
   106  	sb := &Sandbox{sandboxID: "sb-100", domain: &domain, client: &Client{config: &Config{}}}
   107  
   108  	u := sb.DownloadURL("/file.txt")
   109  	// 没有 token 时不应包含 signature 参数
   110  	if u == "" {
   111  		t.Fatal("DownloadURL returned empty string")
   112  	}
   113  }
   114  
   115  func TestFilesLazyInit(t *testing.T) {
   116  	domain := "test.dev"
   117  	sb := &Sandbox{sandboxID: "sb-100", domain: &domain, client: &Client{config: &Config{}}}
   118  
   119  	fs1 := sb.Files()
   120  	fs2 := sb.Files()
   121  	if fs1 != fs2 {
   122  		t.Error("Files() should return the same instance")
   123  	}
   124  }
   125  
   126  func TestCommandsLazyInit(t *testing.T) {
   127  	domain := "test.dev"
   128  	sb := &Sandbox{sandboxID: "sb-100", domain: &domain, client: &Client{config: &Config{}}}
   129  
   130  	cmd1 := sb.Commands()
   131  	cmd2 := sb.Commands()
   132  	if cmd1 != cmd2 {
   133  		t.Error("Commands() should return the same instance")
   134  	}
   135  }
   136  
   137  func TestPtyLazyInit(t *testing.T) {
   138  	domain := "test.dev"
   139  	sb := &Sandbox{sandboxID: "sb-100", domain: &domain, client: &Client{config: &Config{}}}
   140  
   141  	pty1 := sb.Pty()
   142  	pty2 := sb.Pty()
   143  	if pty1 != pty2 {
   144  		t.Error("Pty() should return the same instance")
   145  	}
   146  }
   147  
   148  func TestFileURLOptionWithUser(t *testing.T) {
   149  	domain := "test.dev"
   150  	token := "tok"
   151  	sb := &Sandbox{sandboxID: "sb-1", domain: &domain, envdAccessToken: &token, client: &Client{config: &Config{}}}
   152  
   153  	u := sb.DownloadURL("/file.txt", WithFileUser("admin"))
   154  	// 验证 URL 包含 username=admin
   155  	if u == "" {
   156  		t.Fatal("DownloadURL returned empty string")
   157  	}
   158  }
   159  
   160  func TestIsNotFoundError(t *testing.T) {
   161  	apiErr := &APIError{StatusCode: 404, Body: []byte("not found")}
   162  	if !isNotFoundError(apiErr) {
   163  		t.Error("expected isNotFoundError to return true for 404 APIError")
   164  	}
   165  
   166  	apiErr200 := &APIError{StatusCode: 200, Body: []byte("ok")}
   167  	if isNotFoundError(apiErr200) {
   168  		t.Error("expected isNotFoundError to return false for 200 APIError")
   169  	}
   170  }
   171  
   172  func TestEntryInfoFromProtoNil(t *testing.T) {
   173  	if entryInfoFromProto(nil) != nil {
   174  		t.Error("entryInfoFromProto(nil) should return nil")
   175  	}
   176  }
   177  
   178  func TestWriteFilesEmpty(t *testing.T) {
   179  	domain := "test.dev"
   180  	sb := &Sandbox{sandboxID: "sb-100", domain: &domain, client: &Client{config: &Config{}}}
   181  	fs := &Filesystem{sandbox: sb}
   182  
   183  	infos, err := fs.WriteFiles(context.Background(), nil)
   184  	if err != nil {
   185  		t.Fatalf("WriteFiles(nil) 应返回 nil error,得到: %v", err)
   186  	}
   187  	if infos != nil {
   188  		t.Fatalf("WriteFiles(nil) 应返回 nil,得到: %v", infos)
   189  	}
   190  }
   191  
   192  func TestBatchUploadURL(t *testing.T) {
   193  	domain := "test.dev"
   194  	sb := &Sandbox{sandboxID: "sb-100", domain: &domain, client: &Client{config: &Config{}}}
   195  
   196  	u := sb.batchUploadURL("user")
   197  	want := "https://49983-sb-100.test.dev/files?username=user"
   198  	if u != want {
   199  		t.Errorf("batchUploadURL = %q, want %q", u, want)
   200  	}
   201  }
   202  
   203  func TestWriteFileFullPath(t *testing.T) {
   204  	var buf bytes.Buffer
   205  	w := newMultipartWriter(&buf)
   206  
   207  	if err := w.writeFileFullPath("file_0", "/home/user/test.txt", []byte("hello")); err != nil {
   208  		t.Fatalf("writeFileFullPath 失败: %v", err)
   209  	}
   210  	if err := w.close(); err != nil {
   211  		t.Fatalf("close 失败: %v", err)
   212  	}
   213  
   214  	// 解析 multipart 内容,验证 Content-Disposition 中的 filename 是完整路径。
   215  	// 注意:Part.FileName() 会调用 filepath.Base(),所以直接解析 header。
   216  	r := multipart.NewReader(&buf, w.w.Boundary())
   217  	part, err := r.NextPart()
   218  	if err != nil {
   219  		t.Fatalf("NextPart 失败: %v", err)
   220  	}
   221  	_, params, err := mime.ParseMediaType(part.Header.Get("Content-Disposition"))
   222  	if err != nil {
   223  		t.Fatalf("ParseMediaType 失败: %v", err)
   224  	}
   225  	if got := params["filename"]; got != "/home/user/test.txt" {
   226  		t.Errorf("filename = %q, want %q", got, "/home/user/test.txt")
   227  	}
   228  	data, _ := io.ReadAll(part)
   229  	if string(data) != "hello" {
   230  		t.Errorf("data = %q, want %q", string(data), "hello")
   231  	}
   232  }
   233  
   234  func TestWriteFileBaseName(t *testing.T) {
   235  	var buf bytes.Buffer
   236  	w := newMultipartWriter(&buf)
   237  
   238  	if err := w.writeFile("file", "/home/user/test.txt", []byte("hello")); err != nil {
   239  		t.Fatalf("writeFile 失败: %v", err)
   240  	}
   241  	if err := w.close(); err != nil {
   242  		t.Fatalf("close 失败: %v", err)
   243  	}
   244  
   245  	// 解析 multipart 内容,验证 filename 是 basename
   246  	r := multipart.NewReader(&buf, w.w.Boundary())
   247  	part, err := r.NextPart()
   248  	if err != nil {
   249  		t.Fatalf("NextPart 失败: %v", err)
   250  	}
   251  	if got := part.FileName(); got != "test.txt" {
   252  		t.Errorf("filename = %q, want %q", got, "test.txt")
   253  	}
   254  }