report a peer's port change locally without rewriting it
Keep IConfigurationManager source-compatible for plugin implementers.
This commit is contained in:
+81
@@ -0,0 +1,81 @@
|
||||
using Emby.Server.Implementations;
|
||||
using Xunit;
|
||||
|
||||
namespace Jellyfin.Server.Implementations.Tests.Configuration;
|
||||
|
||||
/// <summary>
|
||||
/// The decision <c>ApplicationHost.OnConfigurationUpdated</c> makes about a port change. The ports this
|
||||
/// process bound are fixed for its lifetime and the pending-restart flag is per-process, so an instance
|
||||
/// applying another instance's port change still has to notice its own binding went stale - while leaving
|
||||
/// the authorization write, and the notice that follows it, to the instance that made the change.
|
||||
/// </summary>
|
||||
public static class ApplicationHostPortChangeTests
|
||||
{
|
||||
/// <summary>
|
||||
/// The local case, unchanged: clear the authorization flag and report the pending restart.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public static void LocalPortChange_ClearsAuthorizationAndRequiresRestart()
|
||||
{
|
||||
var outcome = ApplicationHost.EvaluatePortChange(8096, 8920, 9096, 8920, true, false);
|
||||
|
||||
Assert.True(outcome.RequiresRestart);
|
||||
Assert.True(outcome.ClearsPortAuthorization);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The cross-instance case: the peer wrote the new port and cleared the flag with it, so this
|
||||
/// instance must not write, but it is still listening on the old port and has to say so.
|
||||
/// </summary>
|
||||
[Theory]
|
||||
[InlineData(true)]
|
||||
[InlineData(false)]
|
||||
public static void RemotePortChange_RequiresRestartWithoutWriting(bool isPortAuthorized)
|
||||
{
|
||||
var outcome = ApplicationHost.EvaluatePortChange(8096, 8920, 9096, 8920, isPortAuthorized, true);
|
||||
|
||||
Assert.True(outcome.RequiresRestart);
|
||||
Assert.False(outcome.ClearsPortAuthorization);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A second update while a port change is already pending must not write the flag again, and the
|
||||
/// binding is still stale.
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public static void LocalPortChange_WithAuthorizationAlreadyCleared_RequiresRestartWithoutWriting()
|
||||
{
|
||||
var outcome = ApplicationHost.EvaluatePortChange(8096, 8920, 9096, 8920, false, false);
|
||||
|
||||
Assert.True(outcome.RequiresRestart);
|
||||
Assert.False(outcome.ClearsPortAuthorization);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An update that leaves the ports alone is not a port change, whoever wrote it.
|
||||
/// </summary>
|
||||
[Theory]
|
||||
[InlineData(false)]
|
||||
[InlineData(true)]
|
||||
public static void UnchangedPorts_DoNothing(bool isApplyingRemoteInvalidation)
|
||||
{
|
||||
var outcome = ApplicationHost.EvaluatePortChange(8096, 8920, 8096, 8920, true, isApplyingRemoteInvalidation);
|
||||
|
||||
Assert.False(outcome.RequiresRestart);
|
||||
Assert.False(outcome.ClearsPortAuthorization);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Nothing is decided before the ports have been bound.
|
||||
/// </summary>
|
||||
[Theory]
|
||||
[InlineData(0, 8920)]
|
||||
[InlineData(8096, 0)]
|
||||
public static void UnboundPorts_DoNothing(int boundHttpPort, int boundHttpsPort)
|
||||
{
|
||||
var outcome = ApplicationHost.EvaluatePortChange(boundHttpPort, boundHttpsPort, 9096, 9920, true, false);
|
||||
|
||||
Assert.False(outcome.RequiresRestart);
|
||||
Assert.False(outcome.ClearsPortAuthorization);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user