Files
PSProxmoxVE/tests/PSProxmoxVE.Core.Tests/Client/PveHttpClientTimeoutTests.cs
T
Clint Branham f3b06171b2 fix: add -TimeoutSeconds for long-running HTTP calls
PveHttpClient was constructed without setting HttpClient.Timeout, so
.NET's 100s default applied to every request. Multi-GB ISO uploads via
Send-PveFile on a real LAN reliably tripped this with TaskCanceledException
after 100 seconds, and there was no way to override it.

- PveSession gains a Timeout (TimeSpan) property, defaulting to 100s.
- PveHttpClient accepts an optional per-instance timeout override that
  takes precedence over the session timeout.
- Connect-PveServer exposes -TimeoutSeconds to set the session default.
- Send-PveFile and Invoke-PveStorageDownload expose -TimeoutSeconds with
  a 30-minute implicit default so large uploads/downloads do not trip
  the 100s default. -TimeoutSeconds 0 means Timeout.InfiniteTimeSpan.

Tracked as F087. Closes #59.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 18:08:26 -05:00

69 lines
2.0 KiB
C#

using System;
using System.Net.Http;
using System.Reflection;
using System.Threading;
using PSProxmoxVE.Core.Authentication;
using PSProxmoxVE.Core.Client;
using Xunit;
namespace PSProxmoxVE.Core.Tests.Client
{
public class PveHttpClientTimeoutTests
{
private static HttpClient GetInnerHttpClient(PveHttpClient client)
{
var field = typeof(PveHttpClient).GetField("_httpClient",
BindingFlags.Instance | BindingFlags.NonPublic)!;
return (HttpClient)field.GetValue(client)!;
}
private static PveSession NewSession()
{
return new PveSession("pve.example.com", 8006, false,
"root@pam!token=aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee");
}
[Fact]
public void Constructor_UsesSessionTimeoutByDefault()
{
var session = NewSession();
session.Timeout = TimeSpan.FromSeconds(42);
using var client = new PveHttpClient(session);
Assert.Equal(TimeSpan.FromSeconds(42), GetInnerHttpClient(client).Timeout);
}
[Fact]
public void Constructor_OverrideTakesPrecedenceOverSessionTimeout()
{
var session = NewSession();
session.Timeout = TimeSpan.FromSeconds(42);
using var client = new PveHttpClient(session, TimeSpan.FromMinutes(30));
Assert.Equal(TimeSpan.FromMinutes(30), GetInnerHttpClient(client).Timeout);
}
[Fact]
public void Constructor_InfiniteTimeSpanIsAccepted()
{
var session = NewSession();
using var client = new PveHttpClient(session, Timeout.InfiniteTimeSpan);
Assert.Equal(Timeout.InfiniteTimeSpan, GetInnerHttpClient(client).Timeout);
}
[Fact]
public void DefaultSessionTimeoutIs100Seconds()
{
var session = NewSession();
using var client = new PveHttpClient(session);
Assert.Equal(TimeSpan.FromSeconds(100), GetInnerHttpClient(client).Timeout);
}
}
}