/ tests / go / filesystem_e2e_test.go
filesystem_e2e_test.go
  1  // Copyright 2026 Alibaba Group Holding Ltd.
  2  //
  3  // Licensed under the Apache License, Version 2.0 (the "License");
  4  // you may not use this file except in compliance with the License.
  5  // You may obtain a copy of the License at
  6  //
  7  //     http://www.apache.org/licenses/LICENSE-2.0
  8  //
  9  // Unless required by applicable law or agreed to in writing, software
 10  // distributed under the License is distributed on an "AS IS" BASIS,
 11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12  // See the License for the specific language governing permissions and
 13  // limitations under the License.
 14  
 15  package e2e
 16  
 17  import (
 18  	"context"
 19  	"io"
 20  	"os"
 21  	"testing"
 22  
 23  	"github.com/alibaba/OpenSandbox/sdks/sandbox/go"
 24  	"github.com/stretchr/testify/require"
 25  )
 26  
 27  func TestFilesystem_GetFileInfo(t *testing.T) {
 28  	ctx, sb := createTestSandbox(t)
 29  
 30  	info, err := sb.GetFileInfo(ctx, "/etc/os-release")
 31  	require.NoError(t, err)
 32  
 33  	fi, ok := info["/etc/os-release"]
 34  	require.True(t, ok, "expected /etc/os-release in result")
 35  	require.NotZero(t, fi.Size, "expected non-zero file size")
 36  	t.Logf("File info: path=%s size=%d owner=%s", fi.Path, fi.Size, fi.Owner)
 37  }
 38  
 39  func TestFilesystem_WriteReadDelete(t *testing.T) {
 40  	ctx, sb := createTestSandbox(t)
 41  
 42  	exec, err := sb.RunCommand(ctx, `echo "go-e2e-content" > /tmp/test-rw.txt`, nil)
 43  	require.NoError(t, err)
 44  	if exec.ExitCode != nil {
 45  		require.Equal(t, 0, *exec.ExitCode, "write exit code")
 46  	}
 47  
 48  	exec, err = sb.RunCommand(ctx, "cat /tmp/test-rw.txt", nil)
 49  	require.NoError(t, err)
 50  	require.Contains(t, exec.Text(), "go-e2e-content")
 51  
 52  	info, err := sb.GetFileInfo(ctx, "/tmp/test-rw.txt")
 53  	require.NoError(t, err)
 54  	_, ok := info["/tmp/test-rw.txt"]
 55  	require.True(t, ok, "file not found via GetFileInfo")
 56  
 57  	err = sb.DeleteFiles(ctx, []string{"/tmp/test-rw.txt"})
 58  	require.NoError(t, err)
 59  
 60  	exec, err = sb.RunCommand(ctx, "test -f /tmp/test-rw.txt && echo exists || echo gone", nil)
 61  	require.NoError(t, err)
 62  	require.Contains(t, exec.Text(), "gone")
 63  	t.Log("Write/Read/Delete cycle passed")
 64  }
 65  
 66  func TestFilesystem_MoveFiles(t *testing.T) {
 67  	ctx, sb := createTestSandbox(t)
 68  
 69  	sb.RunCommand(ctx, `echo "move-me" > /tmp/move-src.txt`, nil)
 70  
 71  	err := sb.MoveFiles(ctx, opensandbox.MoveRequest{
 72  		{Src: "/tmp/move-src.txt", Dest: "/tmp/move-dst.txt"},
 73  	})
 74  	require.NoError(t, err)
 75  
 76  	exec, err := sb.RunCommand(ctx, "cat /tmp/move-dst.txt", nil)
 77  	require.NoError(t, err)
 78  	require.Contains(t, exec.Text(), "move-me")
 79  	t.Log("MoveFiles passed")
 80  }
 81  
 82  func TestFilesystem_Directories(t *testing.T) {
 83  	ctx, sb := createTestSandbox(t)
 84  
 85  	err := sb.CreateDirectory(ctx, "/tmp/test-dir-e2e", 755)
 86  	require.NoError(t, err)
 87  
 88  	exec, err := sb.RunCommand(ctx, "test -d /tmp/test-dir-e2e && echo yes || echo no", nil)
 89  	require.NoError(t, err)
 90  	require.Contains(t, exec.Text(), "yes")
 91  
 92  	err = sb.DeleteDirectory(ctx, "/tmp/test-dir-e2e")
 93  	require.NoError(t, err)
 94  	t.Log("Directory create/delete passed")
 95  }
 96  
 97  func TestFilesystem_SearchFiles(t *testing.T) {
 98  	ctx, sb := createTestSandbox(t)
 99  
100  	results, err := sb.SearchFiles(ctx, "/etc", "*.conf")
101  	require.NoError(t, err)
102  	t.Logf("Found %d files matching *.conf in /etc", len(results))
103  }
104  
105  func TestFilesystem_DownloadFile(t *testing.T) {
106  	ctx, sb := createTestSandbox(t)
107  
108  	rc, err := sb.DownloadFile(ctx, "/etc/os-release", "")
109  	require.NoError(t, err)
110  	defer rc.Close()
111  
112  	data, err := io.ReadAll(rc)
113  	require.NoError(t, err)
114  	require.NotEmpty(t, data, "downloaded file is empty")
115  	t.Logf("Downloaded %d bytes", len(data))
116  }
117  
118  func TestFilesystem_UploadAndDownloadFile(t *testing.T) {
119  	ctx, sb := createTestSandbox(t)
120  
121  	tmp, err := os.CreateTemp("", "opensandbox-upload-*")
122  	require.NoError(t, err)
123  	defer os.Remove(tmp.Name())
124  
125  	content := []byte("go-e2e-upload-download")
126  	_, err = tmp.Write(content)
127  	require.NoError(t, err)
128  	require.NoError(t, tmp.Close())
129  
130  	remotePath := "/tmp/go-e2e-upload-download.txt"
131  	up, err := os.Open(tmp.Name())
132  	require.NoError(t, err)
133  	defer up.Close()
134  	require.NoError(t, sb.UploadFile(ctx, up, opensandbox.UploadFileOptions{
135  		FileName: "go-e2e-upload-download.txt",
136  		Metadata: opensandbox.FileMetadata{Path: remotePath},
137  	}))
138  	t.Cleanup(func() {
139  		_ = sb.DeleteFiles(context.Background(), []string{remotePath})
140  	})
141  
142  	rc, err := sb.DownloadFile(ctx, remotePath, "")
143  	require.NoError(t, err)
144  	defer rc.Close()
145  
146  	downloaded, err := io.ReadAll(rc)
147  	require.NoError(t, err)
148  	require.Equal(t, string(content), string(downloaded))
149  }
150  
151  func TestFilesystem_SetPermissions(t *testing.T) {
152  	ctx, sb := createTestSandbox(t)
153  
154  	_, err := sb.RunCommand(ctx, `echo "perm-test" > /tmp/perm-e2e.txt`, nil)
155  	require.NoError(t, err)
156  	t.Cleanup(func() { _ = sb.DeleteFiles(context.Background(), []string{"/tmp/perm-e2e.txt"}) })
157  
158  	err = sb.SetPermissions(ctx, opensandbox.PermissionsRequest{
159  		"/tmp/perm-e2e.txt": {Mode: 644},
160  	})
161  	require.NoError(t, err)
162  
163  	exec, err := sb.RunCommand(ctx, `stat -c "%a" /tmp/perm-e2e.txt || stat -f "%Lp" /tmp/perm-e2e.txt`, nil)
164  	require.NoError(t, err)
165  	require.Contains(t, exec.Text(), "644")
166  }
167  
168  func TestFilesystem_ReplaceInFiles(t *testing.T) {
169  	ctx, sb := createTestSandbox(t)
170  
171  	_, err := sb.RunCommand(ctx, `echo "hello localhost" > /tmp/replace-e2e.txt`, nil)
172  	require.NoError(t, err)
173  	t.Cleanup(func() { _ = sb.DeleteFiles(context.Background(), []string{"/tmp/replace-e2e.txt"}) })
174  
175  	err = sb.ReplaceInFiles(ctx, opensandbox.ReplaceRequest{
176  		"/tmp/replace-e2e.txt": {Old: "localhost", New: "example.com"},
177  	})
178  	require.NoError(t, err)
179  
180  	exec, err := sb.RunCommand(ctx, "cat /tmp/replace-e2e.txt", nil)
181  	require.NoError(t, err)
182  	require.Contains(t, exec.Text(), "example.com")
183  }