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

475 lines
14 KiB
C#

// 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.
using System.Text.Json;
using FluentAssertions;
using OpenSandbox.Models;
using Xunit;
namespace OpenSandbox.Tests;
public class ModelsTests
{
[Fact]
public void Execution_ShouldInitializeWithEmptyCollections()
{
// Arrange & Act
var execution = new Execution();
// Assert
execution.Id.Should().BeNull();
execution.ExecutionCount.Should().BeNull();
execution.Logs.Should().NotBeNull();
execution.Logs.Stdout.Should().BeEmpty();
execution.Logs.Stderr.Should().BeEmpty();
execution.Results.Should().BeEmpty();
execution.Error.Should().BeNull();
execution.Complete.Should().BeNull();
execution.ExitCode.Should().BeNull();
}
[Fact]
public void ExecutionLogs_ShouldAllowAddingMessages()
{
// Arrange
var logs = new ExecutionLogs();
var stdoutMsg = new OutputMessage { Text = "stdout", Timestamp = 1000, IsError = false };
var stderrMsg = new OutputMessage { Text = "stderr", Timestamp = 2000, IsError = true };
// Act
logs.Stdout.Add(stdoutMsg);
logs.Stderr.Add(stderrMsg);
// Assert
logs.Stdout.Should().HaveCount(1);
logs.Stdout[0].Text.Should().Be("stdout");
logs.Stderr.Should().HaveCount(1);
logs.Stderr[0].Text.Should().Be("stderr");
logs.Stderr[0].IsError.Should().BeTrue();
}
[Fact]
public void OutputMessage_ShouldStoreProperties()
{
// Arrange & Act
var msg = new OutputMessage
{
Text = "Hello World",
Timestamp = 1234567890,
IsError = false
};
// Assert
msg.Text.Should().Be("Hello World");
msg.Timestamp.Should().Be(1234567890);
msg.IsError.Should().BeFalse();
}
[Fact]
public void ExecutionResult_ShouldStoreProperties()
{
// Arrange & Act
var result = new ExecutionResult
{
Text = "Result text",
Timestamp = 1234567890,
Raw = new Dictionary<string, object> { ["text/plain"] = "Result text" }
};
// Assert
result.Text.Should().Be("Result text");
result.Timestamp.Should().Be(1234567890);
result.Raw.Should().ContainKey("text/plain");
}
[Fact]
public void ExecutionError_ShouldStoreProperties()
{
// Arrange & Act
var error = new ExecutionError
{
Name = "ValueError",
Value = "Invalid value",
Timestamp = 1234567890,
Traceback = new List<string> { "line 1", "line 2" }
};
// Assert
error.Name.Should().Be("ValueError");
error.Value.Should().Be("Invalid value");
error.Timestamp.Should().Be(1234567890);
error.Traceback.Should().HaveCount(2);
}
[Fact]
public void ExecutionComplete_ShouldStoreProperties()
{
// Arrange & Act
var complete = new ExecutionComplete
{
Timestamp = 1234567890,
ExecutionTimeMs = 500
};
// Assert
complete.Timestamp.Should().Be(1234567890);
complete.ExecutionTimeMs.Should().Be(500);
}
[Fact]
public void SandboxInfo_ShouldStoreProperties()
{
// Arrange & Act
var info = new SandboxInfo
{
Id = "sandbox-123",
Image = new ImageSpec { Uri = "ubuntu:latest" },
Platform = new PlatformSpec { Os = "linux", Arch = "amd64" },
Entrypoint = new List<string> { "tail", "-f", "/dev/null" },
Status = new SandboxStatus { State = "Running" },
CreatedAt = DateTime.UtcNow,
ExpiresAt = DateTime.UtcNow.AddMinutes(10),
Metadata = new Dictionary<string, string> { ["key"] = "value" }
};
// Assert
info.Id.Should().Be("sandbox-123");
info.Image.Uri.Should().Be("ubuntu:latest");
info.Platform.Should().NotBeNull();
info.Platform!.Os.Should().Be("linux");
info.Entrypoint.Should().HaveCount(3);
info.Status.State.Should().Be("Running");
info.Metadata.Should().ContainKey("key");
}
[Fact]
public void SandboxStatus_ShouldStoreProperties()
{
// Arrange & Act
var status = new SandboxStatus
{
State = "Error",
Reason = "ImagePullFailed",
Message = "Failed to pull image"
};
// Assert
status.State.Should().Be("Error");
status.Reason.Should().Be("ImagePullFailed");
status.Message.Should().Be("Failed to pull image");
}
[Fact]
public void ImageSpec_WithAuth_ShouldStoreCredentials()
{
// Arrange & Act
var image = new ImageSpec
{
Uri = "private-registry.com/image:tag",
Auth = new ImageAuth
{
Username = "user",
Password = "pass"
}
};
// Assert
image.Uri.Should().Be("private-registry.com/image:tag");
image.Auth.Should().NotBeNull();
image.Auth!.Username.Should().Be("user");
image.Auth.Password.Should().Be("pass");
}
[Fact]
public void NetworkPolicy_ShouldStoreRules()
{
// Arrange & Act
var policy = new NetworkPolicy
{
DefaultAction = NetworkRuleAction.Deny,
Egress = new List<NetworkRule>
{
new() { Action = NetworkRuleAction.Allow, Target = "example.com" },
new() { Action = NetworkRuleAction.Allow, Target = "*.trusted.com" }
}
};
// Assert
policy.DefaultAction.Should().Be(NetworkRuleAction.Deny);
policy.Egress.Should().HaveCount(2);
policy.Egress![0].Action.Should().Be(NetworkRuleAction.Allow);
policy.Egress[0].Target.Should().Be("example.com");
}
[Fact]
public void Volume_WithOssfs_ShouldSerializeExpectedPayload()
{
var request = new CreateSandboxRequest
{
Image = new ImageSpec { Uri = "python:3.11" },
ResourceLimits = new Dictionary<string, string>(),
Entrypoint = new List<string> { "python" },
Platform = new PlatformSpec { Os = "linux", Arch = "arm64" },
Volumes = new List<Volume>
{
new()
{
Name = "oss-data",
MountPath = "/mnt/oss",
SubPath = "prefix",
Ossfs = new OSSFS
{
Bucket = "bucket-a",
Endpoint = "oss-cn-hangzhou.aliyuncs.com",
AccessKeyId = "ak",
AccessKeySecret = "sk",
Options = new List<string> { "allow_other" }
}
}
}
};
string json = JsonSerializer.Serialize(request);
json.Should().Contain("\"ossfs\":");
json.Should().Contain("\"bucket\":\"bucket-a\"");
json.Should().Contain("\"endpoint\":\"oss-cn-hangzhou.aliyuncs.com\"");
json.Should().Contain("\"accessKeyId\":\"ak\"");
json.Should().Contain("\"accessKeySecret\":\"sk\"");
json.Should().Contain("\"version\":\"2.0\"");
json.Should().Contain("\"platform\":{\"os\":\"linux\",\"arch\":\"arm64\"}");
}
[Fact]
public void SandboxMetrics_ShouldStoreProperties()
{
// Arrange & Act
var metrics = new SandboxMetrics
{
CpuCount = 4,
CpuUsedPercentage = 25.5,
MemoryTotalMiB = 8192,
MemoryUsedMiB = 2048,
Timestamp = 1234567890
};
// Assert
metrics.CpuCount.Should().Be(4);
metrics.CpuUsedPercentage.Should().Be(25.5);
metrics.MemoryTotalMiB.Should().Be(8192);
metrics.MemoryUsedMiB.Should().Be(2048);
metrics.Timestamp.Should().Be(1234567890);
}
[Fact]
public void SandboxFileInfo_ShouldStoreProperties()
{
// Arrange & Act
var fileInfo = new SandboxFileInfo
{
Path = "/tmp/test.txt",
Size = 1024,
Mode = 644,
Owner = "root",
Group = "root",
CreatedAt = DateTime.UtcNow,
ModifiedAt = DateTime.UtcNow
};
// Assert
fileInfo.Path.Should().Be("/tmp/test.txt");
fileInfo.Size.Should().Be(1024);
fileInfo.Mode.Should().Be(644);
fileInfo.Owner.Should().Be("root");
}
[Fact]
public void WriteEntry_ShouldStoreProperties()
{
// Arrange & Act
var entry = new WriteEntry
{
Path = "/tmp/file.txt",
Data = "Hello World",
Mode = 644,
Owner = "user",
Group = "group"
};
// Assert
entry.Path.Should().Be("/tmp/file.txt");
entry.Data.Should().Be("Hello World");
entry.Mode.Should().Be(644);
}
[Fact]
public void SearchEntry_ShouldStoreProperties()
{
// Arrange & Act
var entry = new SearchEntry
{
Path = "/tmp",
Pattern = "*.txt"
};
// Assert
entry.Path.Should().Be("/tmp");
entry.Pattern.Should().Be("*.txt");
}
[Fact]
public void MoveEntry_ShouldStoreProperties()
{
// Arrange & Act
var entry = new MoveEntry
{
Src = "/tmp/old.txt",
Dest = "/tmp/new.txt"
};
// Assert
entry.Src.Should().Be("/tmp/old.txt");
entry.Dest.Should().Be("/tmp/new.txt");
}
[Fact]
public void RunCommandOptions_ShouldStoreProperties()
{
// Arrange & Act
var options = new RunCommandOptions
{
WorkingDirectory = "/home/user",
Background = true,
TimeoutSeconds = 30,
Uid = 1000,
Gid = 1000,
Envs = new Dictionary<string, string>
{
["APP_ENV"] = "test"
}
};
// Assert
options.WorkingDirectory.Should().Be("/home/user");
options.Background.Should().BeTrue();
options.TimeoutSeconds.Should().Be(30);
options.Uid.Should().Be(1000);
options.Gid.Should().Be(1000);
options.Envs.Should().ContainKey("APP_ENV");
}
[Fact]
public void CreateSessionOptions_ShouldStoreWorkingDirectory()
{
var options = new CreateSessionOptions
{
WorkingDirectory = "/workspace"
};
options.WorkingDirectory.Should().Be("/workspace");
}
[Fact]
public void RunInSessionOptions_ShouldStoreProperties()
{
var options = new RunInSessionOptions
{
WorkingDirectory = "/workspace",
TimeoutSeconds = 5
};
options.WorkingDirectory.Should().Be("/workspace");
options.TimeoutSeconds.Should().Be(5);
}
[Fact]
public void ServerStreamEvent_ShouldStoreProperties()
{
// Arrange & Act
var ev = new ServerStreamEvent
{
Type = "stdout",
Text = "output text",
Timestamp = 1234567890,
ExecutionCount = 1,
ExecutionTime = 100
};
// Assert
ev.Type.Should().Be("stdout");
ev.Text.Should().Be("output text");
ev.Timestamp.Should().Be(1234567890);
ev.ExecutionCount.Should().Be(1);
ev.ExecutionTime.Should().Be(100);
}
[Fact]
public void CommandStatus_ShouldStoreProperties()
{
var startedAt = DateTime.UtcNow.AddSeconds(-5);
var finishedAt = DateTime.UtcNow;
var status = new CommandStatus
{
Id = "cmd-1",
Content = "echo hello",
Running = false,
ExitCode = 0,
Error = null,
StartedAt = startedAt,
FinishedAt = finishedAt
};
status.Id.Should().Be("cmd-1");
status.Content.Should().Be("echo hello");
status.Running.Should().BeFalse();
status.ExitCode.Should().Be(0);
status.StartedAt.Should().Be(startedAt);
status.FinishedAt.Should().Be(finishedAt);
}
[Fact]
public void CommandLogs_ShouldStoreProperties()
{
var logs = new CommandLogs
{
Content = "line1\nline2\n",
Cursor = 12
};
logs.Content.Should().Contain("line1");
logs.Cursor.Should().Be(12);
}
[Fact]
public void PaginationInfo_ShouldStoreProperties()
{
// Arrange & Act
var pagination = new PaginationInfo
{
Page = 1,
PageSize = 10,
TotalItems = 100,
TotalPages = 10,
HasNextPage = true
};
// Assert
pagination.Page.Should().Be(1);
pagination.PageSize.Should().Be(10);
pagination.TotalItems.Should().Be(100);
pagination.TotalPages.Should().Be(10);
pagination.HasNextPage.Should().BeTrue();
}
}