Files
wehub-resource-sync e0e362d700
SDK Tests / changes (push) Successful in 2m29s
Real E2E Tests / changes (push) Successful in 2m29s
Deploy Docs Pages / build (push) Has been cancelled
Deploy Docs Pages / deploy (push) Has been cancelled
Real E2E Tests / JavaScript E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Python E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Java E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / C# E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Go E2E (docker bridge) (push) Has been cancelled
Real E2E Tests / Real E2E CI (push) Has been cancelled
SDK Tests / SDK CI (push) Has been cancelled
SDK Tests / CLI Tests (push) Has been cancelled
SDK Tests / Python SDK Quality (code-interpreter) (push) Has been cancelled
SDK Tests / Python SDK Quality (sandbox) (push) Has been cancelled
SDK Tests / Python SDK Tests (code-interpreter) (push) Has been cancelled
SDK Tests / JavaScript SDK Quality And Tests (code-interpreter) (push) Has been cancelled
SDK Tests / JavaScript SDK Quality And Tests (sandbox) (push) Has been cancelled
SDK Tests / Python SDK Tests (sandbox) (push) Has been cancelled
SDK Tests / CLI Quality (push) Has been cancelled
SDK Tests / Kotlin SDK Quality And Tests (sandbox) (push) Has been cancelled
SDK Tests / Kotlin SDK Quality And Tests (code-interpreter) (push) Has been cancelled
SDK Tests / C# SDK Quality And Tests (code-interpreter) (push) Has been cancelled
SDK Tests / C# SDK Quality And Tests (sandbox) (push) Has been cancelled
SDK Tests / Go SDK Quality And Tests (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:39:33 +08:00

270 lines
8.9 KiB
Go

// Copyright 2026 Alibaba Group Holding Ltd.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package e2e
import (
"context"
"io"
"os"
"testing"
"github.com/alibaba/OpenSandbox/sdks/sandbox/go"
"github.com/stretchr/testify/require"
)
func TestFilesystem_GetFileInfo(t *testing.T) {
ctx, sb := createTestSandbox(t)
info, err := sb.GetFileInfo(ctx, "/etc/os-release")
require.NoError(t, err)
fi, ok := info["/etc/os-release"]
require.True(t, ok, "expected /etc/os-release in result")
require.NotZero(t, fi.Size, "expected non-zero file size")
t.Logf("File info: path=%s size=%d owner=%s", fi.Path, fi.Size, fi.Owner)
}
func TestFilesystem_WriteReadDelete(t *testing.T) {
ctx, sb := createTestSandbox(t)
exec, err := sb.RunCommand(ctx, `echo "go-e2e-content" > /tmp/test-rw.txt`, nil)
require.NoError(t, err)
if exec.ExitCode != nil {
require.Equal(t, 0, *exec.ExitCode, "write exit code")
}
exec, err = sb.RunCommand(ctx, "cat /tmp/test-rw.txt", nil)
require.NoError(t, err)
require.Contains(t, exec.Text(), "go-e2e-content")
info, err := sb.GetFileInfo(ctx, "/tmp/test-rw.txt")
require.NoError(t, err)
_, ok := info["/tmp/test-rw.txt"]
require.True(t, ok, "file not found via GetFileInfo")
err = sb.DeleteFiles(ctx, []string{"/tmp/test-rw.txt"})
require.NoError(t, err)
exec, err = sb.RunCommand(ctx, "test -f /tmp/test-rw.txt && echo exists || echo gone", nil)
require.NoError(t, err)
require.Contains(t, exec.Text(), "gone")
t.Log("Write/Read/Delete cycle passed")
}
func TestFilesystem_MoveFiles(t *testing.T) {
ctx, sb := createTestSandbox(t)
sb.RunCommand(ctx, `echo "move-me" > /tmp/move-src.txt`, nil)
err := sb.MoveFiles(ctx, opensandbox.MoveRequest{
{Src: "/tmp/move-src.txt", Dest: "/tmp/move-dst.txt"},
})
require.NoError(t, err)
exec, err := sb.RunCommand(ctx, "cat /tmp/move-dst.txt", nil)
require.NoError(t, err)
require.Contains(t, exec.Text(), "move-me")
t.Log("MoveFiles passed")
}
func TestFilesystem_Directories(t *testing.T) {
ctx, sb := createTestSandbox(t)
err := sb.CreateDirectory(ctx, "/tmp/test-dir-e2e", 755)
require.NoError(t, err)
exec, err := sb.RunCommand(ctx, "test -d /tmp/test-dir-e2e && echo yes || echo no", nil)
require.NoError(t, err)
require.Contains(t, exec.Text(), "yes")
err = sb.DeleteDirectory(ctx, "/tmp/test-dir-e2e")
require.NoError(t, err)
t.Log("Directory create/delete passed")
}
func TestFilesystem_SearchFiles(t *testing.T) {
ctx, sb := createTestSandbox(t)
results, err := sb.SearchFiles(ctx, "/etc", "*.conf")
require.NoError(t, err)
t.Logf("Found %d files matching *.conf in /etc", len(results))
}
func TestFilesystem_DownloadFile(t *testing.T) {
ctx, sb := createTestSandbox(t)
rc, err := sb.DownloadFile(ctx, "/etc/os-release", "")
require.NoError(t, err)
defer rc.Close()
data, err := io.ReadAll(rc)
require.NoError(t, err)
require.NotEmpty(t, data, "downloaded file is empty")
t.Logf("Downloaded %d bytes", len(data))
}
func TestFilesystem_UploadAndDownloadFile(t *testing.T) {
ctx, sb := createTestSandbox(t)
tmp, err := os.CreateTemp("", "opensandbox-upload-*")
require.NoError(t, err)
defer os.Remove(tmp.Name())
content := []byte("go-e2e-upload-download")
_, err = tmp.Write(content)
require.NoError(t, err)
require.NoError(t, tmp.Close())
remotePath := "/tmp/go-e2e-upload-download.txt"
up, err := os.Open(tmp.Name())
require.NoError(t, err)
defer up.Close()
require.NoError(t, sb.UploadFile(ctx, up, opensandbox.UploadFileOptions{
FileName: "go-e2e-upload-download.txt",
Metadata: opensandbox.FileMetadata{Path: remotePath},
}))
t.Cleanup(func() {
_ = sb.DeleteFiles(context.Background(), []string{remotePath})
})
rc, err := sb.DownloadFile(ctx, remotePath, "")
require.NoError(t, err)
defer rc.Close()
downloaded, err := io.ReadAll(rc)
require.NoError(t, err)
require.Equal(t, string(content), string(downloaded))
}
func TestFilesystem_SetPermissions(t *testing.T) {
ctx, sb := createTestSandbox(t)
_, err := sb.RunCommand(ctx, `echo "perm-test" > /tmp/perm-e2e.txt`, nil)
require.NoError(t, err)
t.Cleanup(func() { _ = sb.DeleteFiles(context.Background(), []string{"/tmp/perm-e2e.txt"}) })
err = sb.SetPermissions(ctx, opensandbox.PermissionsRequest{
"/tmp/perm-e2e.txt": {Mode: 644},
})
require.NoError(t, err)
exec, err := sb.RunCommand(ctx, `stat -c "%a" /tmp/perm-e2e.txt || stat -f "%Lp" /tmp/perm-e2e.txt`, nil)
require.NoError(t, err)
require.Contains(t, exec.Text(), "644")
}
func TestFilesystem_ReplaceInFiles(t *testing.T) {
ctx, sb := createTestSandbox(t)
_, err := sb.RunCommand(ctx, `echo "hello localhost" > /tmp/replace-e2e.txt`, nil)
require.NoError(t, err)
t.Cleanup(func() { _ = sb.DeleteFiles(context.Background(), []string{"/tmp/replace-e2e.txt"}) })
resp, err := sb.ReplaceInFilesDetailed(ctx, opensandbox.ReplaceRequest{
"/tmp/replace-e2e.txt": {Old: "localhost", New: "example.com"},
})
require.NoError(t, err)
require.NotNil(t, resp)
require.Equal(t, 1, resp["/tmp/replace-e2e.txt"].ReplacedCount)
exec, err := sb.RunCommand(ctx, "cat /tmp/replace-e2e.txt", nil)
require.NoError(t, err)
require.Contains(t, exec.Text(), "example.com")
// No match → replacedCount=0
resp, err = sb.ReplaceInFilesDetailed(ctx, opensandbox.ReplaceRequest{
"/tmp/replace-e2e.txt": {Old: "nonexistent", New: "irrelevant"},
})
require.NoError(t, err)
require.Equal(t, 0, resp["/tmp/replace-e2e.txt"].ReplacedCount)
// Multiple matches
_, err = sb.RunCommand(ctx, `echo "foo bar foo baz foo" > /tmp/replace-multi.txt`, nil)
require.NoError(t, err)
t.Cleanup(func() { _ = sb.DeleteFiles(context.Background(), []string{"/tmp/replace-multi.txt"}) })
resp, err = sb.ReplaceInFilesDetailed(ctx, opensandbox.ReplaceRequest{
"/tmp/replace-multi.txt": {Old: "foo", New: "qux"},
})
require.NoError(t, err)
require.Equal(t, 3, resp["/tmp/replace-multi.txt"].ReplacedCount)
// Batch replace across multiple files
_, err = sb.RunCommand(ctx, `echo "hello world" > /tmp/replace-batch-a.txt`, nil)
require.NoError(t, err)
t.Cleanup(func() { _ = sb.DeleteFiles(context.Background(), []string{"/tmp/replace-batch-a.txt"}) })
_, err = sb.RunCommand(ctx, `echo "hello hello" > /tmp/replace-batch-b.txt`, nil)
require.NoError(t, err)
t.Cleanup(func() { _ = sb.DeleteFiles(context.Background(), []string{"/tmp/replace-batch-b.txt"}) })
resp, err = sb.ReplaceInFilesDetailed(ctx, opensandbox.ReplaceRequest{
"/tmp/replace-batch-a.txt": {Old: "hello", New: "hi"},
"/tmp/replace-batch-b.txt": {Old: "hello", New: "hi"},
})
require.NoError(t, err)
require.Equal(t, 1, resp["/tmp/replace-batch-a.txt"].ReplacedCount)
require.Equal(t, 2, resp["/tmp/replace-batch-b.txt"].ReplacedCount)
execA, err := sb.RunCommand(ctx, "cat /tmp/replace-batch-a.txt", nil)
require.NoError(t, err)
require.Contains(t, execA.Text(), "hi world")
execB, err := sb.RunCommand(ctx, "cat /tmp/replace-batch-b.txt", nil)
require.NoError(t, err)
require.Contains(t, execB.Text(), "hi hi")
// Verify original ReplaceInFiles (verbose=false, error-only return) still works
err = sb.ReplaceInFiles(ctx, opensandbox.ReplaceRequest{
"/tmp/replace-multi.txt": {Old: "qux", New: "done"},
})
require.NoError(t, err)
execDone, err := sb.RunCommand(ctx, "cat /tmp/replace-multi.txt", nil)
require.NoError(t, err)
require.Contains(t, execDone.Text(), "done")
require.NotContains(t, execDone.Text(), "qux")
}
func TestFilesystem_DownloadFileLineReading(t *testing.T) {
ctx, sb := createTestSandbox(t)
remotePath := "/tmp/line-read-e2e.txt"
_, err := sb.RunCommand(ctx, `printf "line1\nline2\nline3\nline4\nline5" > `+remotePath, nil)
require.NoError(t, err)
t.Cleanup(func() { _ = sb.DeleteFiles(context.Background(), []string{remotePath}) })
// offset=2, limit=2 → lines 2-3
rc, err := sb.DownloadFile(ctx, remotePath, "", opensandbox.DownloadFileOptions{Offset: 2, Limit: 2})
require.NoError(t, err)
data, err := io.ReadAll(rc)
rc.Close()
require.NoError(t, err)
require.Equal(t, "line2\nline3", string(data))
// offset=4, no limit → lines 4-5
rc, err = sb.DownloadFile(ctx, remotePath, "", opensandbox.DownloadFileOptions{Offset: 4})
require.NoError(t, err)
data, err = io.ReadAll(rc)
rc.Close()
require.NoError(t, err)
require.Equal(t, "line4\nline5", string(data))
// limit=2, no offset → lines 1-2
rc, err = sb.DownloadFile(ctx, remotePath, "", opensandbox.DownloadFileOptions{Limit: 2})
require.NoError(t, err)
data, err = io.ReadAll(rc)
rc.Close()
require.NoError(t, err)
require.Equal(t, "line1\nline2", string(data))
}