diff --git a/NEW/src/JdeScoping.DataSync/Etl/Pipeline/EtlPipelineBuilder.cs b/NEW/src/JdeScoping.DataSync/Etl/Pipeline/EtlPipelineBuilder.cs index 41c94b5..13f5a1a 100644 --- a/NEW/src/JdeScoping.DataSync/Etl/Pipeline/EtlPipelineBuilder.cs +++ b/NEW/src/JdeScoping.DataSync/Etl/Pipeline/EtlPipelineBuilder.cs @@ -13,6 +13,7 @@ public class EtlPipelineBuilder private readonly List _preScripts = new(); private readonly List _postScripts = new(); private ILogger? _logger; + private int _defaultCommandTimeoutSeconds = 600; public EtlPipelineBuilder WithName(string name) { @@ -59,6 +60,15 @@ public class EtlPipelineBuilder return this; } + public EtlPipelineBuilder WithCommandTimeout(TimeSpan timeout) + { + if (timeout < TimeSpan.Zero || timeout > TimeSpan.FromHours(24)) + throw new ArgumentOutOfRangeException(nameof(timeout), + "Timeout must be between 0 and 24 hours."); + _defaultCommandTimeoutSeconds = (int)timeout.TotalSeconds; + return this; + } + public EtlPipeline Build() { if (_source == null) diff --git a/NEW/tests/JdeScoping.DataSync.Tests/Etl/Pipeline/EtlPipelineBuilderTests.cs b/NEW/tests/JdeScoping.DataSync.Tests/Etl/Pipeline/EtlPipelineBuilderTests.cs new file mode 100644 index 0000000..4ffa40b --- /dev/null +++ b/NEW/tests/JdeScoping.DataSync.Tests/Etl/Pipeline/EtlPipelineBuilderTests.cs @@ -0,0 +1,69 @@ +using JdeScoping.DataSync.Etl.Pipeline; + +namespace JdeScoping.DataSync.Tests.Etl.Pipeline; + +public class EtlPipelineBuilderTests +{ + [Fact] + public void WithCommandTimeout_ValidTimeout_SetsTimeoutAndReturnsBuilder() + { + // Arrange + var builder = new EtlPipelineBuilder(); + + // Act + var result = builder.WithCommandTimeout(TimeSpan.FromMinutes(30)); + + // Assert + Assert.Same(builder, result); + } + + [Fact] + public void WithCommandTimeout_NegativeTimeout_ThrowsArgumentOutOfRangeException() + { + // Arrange + var builder = new EtlPipelineBuilder(); + + // Act & Assert + var ex = Assert.Throws(() => + builder.WithCommandTimeout(TimeSpan.FromSeconds(-1))); + Assert.Equal("timeout", ex.ParamName); + } + + [Fact] + public void WithCommandTimeout_Over24Hours_ThrowsArgumentOutOfRangeException() + { + // Arrange + var builder = new EtlPipelineBuilder(); + + // Act & Assert + var ex = Assert.Throws(() => + builder.WithCommandTimeout(TimeSpan.FromHours(25))); + Assert.Equal("timeout", ex.ParamName); + } + + [Fact] + public void WithCommandTimeout_ExactlyZero_DoesNotThrow() + { + // Arrange + var builder = new EtlPipelineBuilder(); + + // Act + var result = builder.WithCommandTimeout(TimeSpan.Zero); + + // Assert + Assert.Same(builder, result); + } + + [Fact] + public void WithCommandTimeout_Exactly24Hours_DoesNotThrow() + { + // Arrange + var builder = new EtlPipelineBuilder(); + + // Act + var result = builder.WithCommandTimeout(TimeSpan.FromHours(24)); + + // Assert + Assert.Same(builder, result); + } +}