mirror of
https://github.com/2dust/v2rayN.git
synced 2026-10-11 07:45:06 +03:00
Fix empty latency tests and Linux startup errors (#10335)
* Fix overflow when speed tests have no eligible profiles * Preserve core executable permissions in Debian packages * Avoid requesting an icon refresh before view initialization
This commit is contained in:
@@ -676,6 +676,15 @@ EOF
|
||||
find "$stage/opt/v2rayN" -type f -exec chmod 0644 {} +
|
||||
[[ -f "$stage/opt/v2rayN/v2rayN" ]] && chmod 0755 "$stage/opt/v2rayN/v2rayN" || true
|
||||
|
||||
# Core binaries must be executable before installation: ordinary users cannot
|
||||
# chmod the root-owned files installed by dpkg.
|
||||
local core
|
||||
for core in xray/xray sing_box/sing-box mihomo/mihomo; do
|
||||
if [[ -f "$stage/opt/v2rayN/bin/$core" ]]; then
|
||||
chmod 0755 "$stage/opt/v2rayN/bin/$core"
|
||||
fi
|
||||
done
|
||||
|
||||
deb_out="$OUTPUT_DIR/v2rayn_${VERSION}_${deb_arch}.deb"
|
||||
dpkg-deb --root-owner-group --build "$stage" "$deb_out"
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
namespace ServiceLib.Tests.Common;
|
||||
|
||||
public class UnixFileModeTests
|
||||
{
|
||||
[Test]
|
||||
public async Task AlreadyExecutableSystemBinary_ShouldNotRequireOwnership()
|
||||
{
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// /bin/sh is executable but owned by root on the Unix CI runners.
|
||||
// A regular user must not need chmod permission just to launch it.
|
||||
var mode = File.GetUnixFileMode("/bin/sh");
|
||||
await Utils.SetUnixFileMode("/bin/sh").Should().BeTrue();
|
||||
await File.GetUnixFileMode("/bin/sh").Should().BeEqualTo(mode);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task NonExecutableOwnedFile_ShouldGainExecuteBitsWithoutLosingOtherPermissions()
|
||||
{
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var path = Path.GetTempFileName();
|
||||
try
|
||||
{
|
||||
var mode = UnixFileMode.UserRead | UnixFileMode.UserWrite | UnixFileMode.GroupRead;
|
||||
File.SetUnixFileMode(path, mode);
|
||||
|
||||
await Utils.SetUnixFileMode(path).Should().BeTrue();
|
||||
await File.GetUnixFileMode(path).Should().BeEqualTo(mode | UnixFileMode.UserExecute | UnixFileMode.GroupExecute | UnixFileMode.OtherExecute);
|
||||
}
|
||||
finally
|
||||
{
|
||||
File.Delete(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
namespace ServiceLib.Tests.Services;
|
||||
|
||||
public class SpeedtestServiceBatchTests
|
||||
{
|
||||
[Test]
|
||||
[Arguments(0)]
|
||||
[Arguments(1000)]
|
||||
public async Task EmptySelection_ShouldReturnNoBatches(int pageSize)
|
||||
{
|
||||
await GetBatches([], pageSize).Count.Should().BeEqualTo(0);
|
||||
}
|
||||
|
||||
[Test]
|
||||
[Arguments(0)]
|
||||
[Arguments(-1)]
|
||||
public async Task NonPositivePageSize_ShouldKeepEveryEligibleProfile(int pageSize)
|
||||
{
|
||||
var profiles = CreateProfiles();
|
||||
var batches = GetBatches(profiles, pageSize);
|
||||
|
||||
await batches.Count.Should().BeEqualTo(profiles.Count);
|
||||
await batches.SelectMany(batch => batch).Count().Should().BeEqualTo(profiles.Count);
|
||||
foreach (var profile in profiles)
|
||||
{
|
||||
await batches.SelectMany(batch => batch).Count(item => ReferenceEquals(item, profile)).Should().BeEqualTo(1);
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public async Task NormalBatches_ShouldRespectPageSizeAndKeepCoreTypesSeparate()
|
||||
{
|
||||
var profiles = CreateProfiles();
|
||||
var batches = GetBatches(profiles, 2);
|
||||
|
||||
await batches.Count.Should().BeEqualTo(3);
|
||||
await batches.SelectMany(batch => batch).Count().Should().BeEqualTo(profiles.Count);
|
||||
foreach (var batch in batches)
|
||||
{
|
||||
await (batch.Count > 0 && batch.Count <= 2).Should().BeTrue();
|
||||
await batch.Select(item => item.CoreType).Distinct().Count().Should().BeEqualTo(1);
|
||||
}
|
||||
}
|
||||
|
||||
private static List<ServerTestItem> CreateProfiles() =>
|
||||
[
|
||||
new() { CoreType = ECoreType.Xray },
|
||||
new() { CoreType = ECoreType.Xray },
|
||||
new() { CoreType = ECoreType.Xray },
|
||||
new() { CoreType = ECoreType.sing_box },
|
||||
new() { CoreType = ECoreType.sing_box }
|
||||
];
|
||||
|
||||
private static List<List<ServerTestItem>> GetBatches(List<ServerTestItem> profiles, int pageSize)
|
||||
{
|
||||
var service = new SpeedtestService(new Config { SpeedTestItem = new() }, _ => Task.CompletedTask);
|
||||
var method = typeof(SpeedtestService).GetMethod("GetTestBatchItem", BindingFlags.Instance | BindingFlags.NonPublic)!;
|
||||
return (List<List<ServerTestItem>>)method.Invoke(service, [profiles, pageSize])!;
|
||||
}
|
||||
}
|
||||
@@ -1441,7 +1441,11 @@ public class Utils
|
||||
if (File.Exists(fileName))
|
||||
{
|
||||
var currentMode = File.GetUnixFileMode(fileName);
|
||||
File.SetUnixFileMode(fileName, currentMode | UnixFileMode.UserExecute | UnixFileMode.GroupExecute | UnixFileMode.OtherExecute);
|
||||
var executableMode = currentMode | UnixFileMode.UserExecute | UnixFileMode.GroupExecute | UnixFileMode.OtherExecute;
|
||||
if (currentMode != executableMode)
|
||||
{
|
||||
File.SetUnixFileMode(fileName, executableMode);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -587,6 +587,12 @@ public class SpeedtestService(Config config, Func<SpeedTestResult, Task> updateF
|
||||
private List<List<ServerTestItem>> GetTestBatchItem(List<ServerTestItem> lstSelected, int pageSize)
|
||||
{
|
||||
List<List<ServerTestItem>> lstTest = [];
|
||||
if (lstSelected.Count == 0)
|
||||
{
|
||||
return lstTest;
|
||||
}
|
||||
|
||||
pageSize = Math.Max(pageSize, 1);
|
||||
var lst1 = lstSelected.Where(t => t.CoreType == ECoreType.Xray).ToList();
|
||||
var lst2 = lstSelected.Where(t => t.CoreType == ECoreType.sing_box).ToList();
|
||||
|
||||
|
||||
@@ -219,7 +219,8 @@ public partial class StatusBarViewModel : MyReactiveObject
|
||||
await ConfigHandler.InitBuiltinRouting(_config);
|
||||
await RefreshRoutingsMenu();
|
||||
await InboundDisplayStatus();
|
||||
await ChangeSystemProxyAsync(_config.SystemProxyItem.SysProxyType, true);
|
||||
// The view refreshes its icon on initialization; interaction handlers are not registered yet.
|
||||
await ChangeSystemProxyAsync(_config.SystemProxyItem.SysProxyType, false);
|
||||
|
||||
BlRouting = true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user