diff --git a/src/Foundatio.AWS/Foundatio.AWS.csproj b/src/Foundatio.AWS/Foundatio.AWS.csproj index 28addd7..1f098d4 100644 --- a/src/Foundatio.AWS/Foundatio.AWS.csproj +++ b/src/Foundatio.AWS/Foundatio.AWS.csproj @@ -4,11 +4,11 @@ $(PackageTags);Amazon;AWS;S3 - - - + + + - + diff --git a/src/Foundatio.AWS/Metrics/CloudWatchMetricsClient.cs b/src/Foundatio.AWS/Metrics/CloudWatchMetricsClient.cs deleted file mode 100644 index e86b57b..0000000 --- a/src/Foundatio.AWS/Metrics/CloudWatchMetricsClient.cs +++ /dev/null @@ -1,284 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Amazon.CloudWatch; -using Amazon.CloudWatch.Model; -using Amazon.Runtime; -using Foundatio.Extensions; -using Foundatio.Utility; -using Microsoft.Extensions.Logging; - -namespace Foundatio.Metrics; - -public class CloudWatchMetricsClient : BufferedMetricsClientBase, IMetricsClientStats -{ - private readonly Lazy _client; - private readonly CloudWatchMetricsClientOptions _options; - private readonly string _namespace; - private readonly List _dimensions; - - public CloudWatchMetricsClient(CloudWatchMetricsClientOptions options) : base(options) - { - _options = options; - _namespace = options.Namespace; - _dimensions = options.Dimensions; - _client = new Lazy(() => new AmazonCloudWatchClient( - options.Credentials ?? FallbackCredentialsFactory.GetCredentials(), - new AmazonCloudWatchConfig - { - LogResponse = false, - DisableLogging = true, - RegionEndpoint = options.Region ?? FallbackRegionFactory.GetRegionEndpoint() - })); - } - - public CloudWatchMetricsClient(Builder builder) - : this(builder(new CloudWatchMetricsClientOptionsBuilder()).Build()) { } - - public AmazonCloudWatchClient Client => _client.Value; - - protected override async Task StoreAggregatedMetricsAsync(TimeBucket timeBucket, ICollection counters, ICollection gauges, ICollection timings) - { - var metrics = new List(); - metrics.AddRange(ConvertToDatums(counters)); - metrics.AddRange(ConvertToDatums(gauges)); - metrics.AddRange(ConvertToDatums(timings)); - - int page = 1; - int pageSize = 20; // CloudWatch only allows max 20 metrics at once. - - do - { - var metricsPage = metrics.Skip((page - 1) * pageSize).Take(pageSize).ToList(); - if (metricsPage.Count == 0) - break; - - if (_logger.IsEnabled(LogLevel.Trace)) _logger.LogTrace("Sending PutMetricData to AWS for {Count} metric(s)", metricsPage.Count); - // do retries - var response = await _client.Value.PutMetricDataAsync(new PutMetricDataRequest - { - Namespace = _namespace, - MetricData = metricsPage - }).AnyContext(); - - if (response.HttpStatusCode != System.Net.HttpStatusCode.OK) - throw new AmazonCloudWatchException("Unable to post metrics."); - - page++; - } while (true); - } - - private IEnumerable ConvertToDatums(ICollection counters) - { - foreach (var counter in counters) - { - yield return new MetricDatum - { - TimestampUtc = counter.Key.StartTimeUtc, - MetricName = GetMetricName(MetricType.Counter, counter.Key.Name), - Value = counter.Value - }; - - yield return new MetricDatum - { - Dimensions = _dimensions, - TimestampUtc = counter.Key.StartTimeUtc, - MetricName = GetMetricName(MetricType.Counter, counter.Key.Name), - Value = counter.Value - }; - } - } - - private IEnumerable ConvertToDatums(ICollection gauges) - { - foreach (var gauge in gauges) - { - yield return new MetricDatum - { - TimestampUtc = gauge.Key.StartTimeUtc, - MetricName = GetMetricName(MetricType.Gauge, gauge.Key.Name), - StatisticValues = new StatisticSet - { - SampleCount = gauge.Count, - Sum = gauge.Total, - Minimum = gauge.Min, - Maximum = gauge.Max - } - }; - - yield return new MetricDatum - { - Dimensions = _dimensions, - TimestampUtc = gauge.Key.StartTimeUtc, - MetricName = GetMetricName(MetricType.Gauge, gauge.Key.Name), - StatisticValues = new StatisticSet - { - SampleCount = gauge.Count, - Sum = gauge.Total, - Minimum = gauge.Min, - Maximum = gauge.Max - } - }; - } - } - - private IEnumerable ConvertToDatums(ICollection timings) - { - foreach (var timing in timings) - { - yield return new MetricDatum - { - TimestampUtc = timing.Key.StartTimeUtc, - MetricName = GetMetricName(MetricType.Timing, timing.Key.Name), - StatisticValues = new StatisticSet - { - SampleCount = timing.Count, - Sum = timing.TotalDuration, - Minimum = timing.MinDuration, - Maximum = timing.MaxDuration - }, - Unit = StandardUnit.Milliseconds - }; - - yield return new MetricDatum - { - Dimensions = _dimensions, - TimestampUtc = timing.Key.StartTimeUtc, - MetricName = GetMetricName(MetricType.Timing, timing.Key.Name), - StatisticValues = new StatisticSet - { - SampleCount = timing.Count, - Sum = timing.TotalDuration, - Minimum = timing.MinDuration, - Maximum = timing.MaxDuration - }, - Unit = StandardUnit.Milliseconds - }; - } - } - - private string GetMetricName(MetricType metricType, string name) - { - return String.Concat(_options.Prefix, name); - } - - private int GetStatsPeriod(DateTime start, DateTime end) - { - double totalMinutes = end.Subtract(start).TotalMinutes; - var interval = TimeSpan.FromMinutes(1); - if (totalMinutes >= 60 * 24 * 7) - interval = TimeSpan.FromDays(1); - else if (totalMinutes >= 60 * 2) - interval = TimeSpan.FromMinutes(5); - - return (int)interval.TotalSeconds; - } - - public async Task GetCounterStatsAsync(string name, DateTime? start = default(DateTime?), DateTime? end = default(DateTime?), int dataPoints = 20) - { - if (!start.HasValue) - start = SystemClock.UtcNow.AddHours(-4); - - if (!end.HasValue) - end = SystemClock.UtcNow; - - var request = new GetMetricStatisticsRequest - { - Namespace = _namespace, - MetricName = GetMetricName(MetricType.Counter, name), - Period = GetStatsPeriod(start.Value, end.Value), - StartTimeUtc = start.Value, - EndTimeUtc = end.Value, - Statistics = new List { "Sum" } - }; - - var response = await _client.Value.GetMetricStatisticsAsync(request).AnyContext(); - if (response.HttpStatusCode != System.Net.HttpStatusCode.OK) - throw new AmazonCloudWatchException("Unable to retrieve metrics."); - - return new CounterStatSummary( - name, - response.Datapoints.Select(dp => new CounterStat - { - Count = (long)dp.Sum, - Time = dp.Timestamp - }).ToList(), - start.Value, - end.Value); - } - - public async Task GetGaugeStatsAsync(string name, DateTime? start = default(DateTime?), DateTime? end = default(DateTime?), int dataPoints = 20) - { - if (!start.HasValue) - start = SystemClock.UtcNow.AddHours(-4); - - if (!end.HasValue) - end = SystemClock.UtcNow; - - var request = new GetMetricStatisticsRequest - { - Namespace = _namespace, - MetricName = GetMetricName(MetricType.Counter, name), - Period = GetStatsPeriod(start.Value, end.Value), - StartTimeUtc = start.Value, - EndTimeUtc = end.Value, - Statistics = new List { "Sum", "Minimum", "Maximum", "SampleCount", "Average" } - }; - - var response = await _client.Value.GetMetricStatisticsAsync(request).AnyContext(); - if (response.HttpStatusCode != System.Net.HttpStatusCode.OK) - throw new AmazonCloudWatchException("Unable to retrieve metrics."); - - return new GaugeStatSummary( - name, - response.Datapoints.Select(dp => new GaugeStat - { - Max = dp.Maximum, - Min = dp.Minimum, - Total = dp.Sum, - Time = dp.Timestamp, - Count = (int)dp.SampleCount, - Last = dp.Average - }).ToList(), - start.Value, - end.Value); - } - - public async Task GetTimerStatsAsync(string name, DateTime? start = default(DateTime?), DateTime? end = default(DateTime?), int dataPoints = 20) - { - if (!start.HasValue) - start = SystemClock.UtcNow.AddHours(-4); - - if (!end.HasValue) - end = SystemClock.UtcNow; - - var request = new GetMetricStatisticsRequest - { - Namespace = _namespace, - MetricName = GetMetricName(MetricType.Counter, name), - Period = GetStatsPeriod(start.Value, end.Value), - StartTimeUtc = start.Value, - EndTimeUtc = end.Value, - Unit = StandardUnit.Milliseconds, - Statistics = new List { "Sum", "Minimum", "Maximum", "SampleCount" } - }; - - var response = await _client.Value.GetMetricStatisticsAsync(request).AnyContext(); - if (response.HttpStatusCode != System.Net.HttpStatusCode.OK) - throw new AmazonCloudWatchException("Unable to retrieve metrics."); - - return new TimingStatSummary( - name, - response.Datapoints.Select(dp => new TimingStat - { - MinDuration = (int)dp.Minimum, - MaxDuration = (int)dp.Maximum, - TotalDuration = (long)dp.Sum, - Count = (int)dp.SampleCount, - Time = dp.Timestamp - }).ToList(), - start.Value, - end.Value); - } -} diff --git a/src/Foundatio.AWS/Metrics/CloudWatchMetricsClientOptions.cs b/src/Foundatio.AWS/Metrics/CloudWatchMetricsClientOptions.cs deleted file mode 100644 index 80a5de7..0000000 --- a/src/Foundatio.AWS/Metrics/CloudWatchMetricsClientOptions.cs +++ /dev/null @@ -1,126 +0,0 @@ -using System; -using System.Collections.Generic; -using Amazon; -using Amazon.CloudWatch.Model; -using Amazon.Runtime; - -namespace Foundatio.Metrics; - -public class CloudWatchMetricsClientOptions : SharedMetricsClientOptions -{ - public string ConnectionString { get; set; } - public AWSCredentials Credentials { get; set; } - public RegionEndpoint Region { get; set; } - public string ServiceUrl { get; set; } - public string Namespace { get; set; } - public List Dimensions { get; set; } = new List(); -} - -public class CloudWatchMetricsClientOptionsBuilder : SharedMetricsClientOptionsBuilder -{ - public CloudWatchMetricsClientOptionsBuilder ConnectionString(string connectionString) - { - if (String.IsNullOrEmpty(connectionString)) - throw new ArgumentNullException(nameof(connectionString)); - Target.ConnectionString = connectionString; - return this; - } - - public CloudWatchMetricsClientOptionsBuilder Credentials(AWSCredentials credentials) - { - if (credentials == null) - throw new ArgumentNullException(nameof(credentials)); - Target.Credentials = credentials; - return this; - } - - public CloudWatchMetricsClientOptionsBuilder Credentials(string accessKey, string secretKey) - { - if (String.IsNullOrEmpty(accessKey)) - throw new ArgumentNullException(nameof(accessKey)); - if (String.IsNullOrEmpty(secretKey)) - throw new ArgumentNullException(nameof(secretKey)); - - Target.Credentials = new BasicAWSCredentials(accessKey, secretKey); - return this; - } - - public CloudWatchMetricsClientOptionsBuilder Region(RegionEndpoint region) - { - if (region == null) - throw new ArgumentNullException(nameof(region)); - Target.Region = region; - return this; - } - - public CloudWatchMetricsClientOptionsBuilder Region(string region) - { - if (String.IsNullOrEmpty(region)) - throw new ArgumentNullException(nameof(region)); - Target.Region = RegionEndpoint.GetBySystemName(region); - return this; - } - - public CloudWatchMetricsClientOptionsBuilder Namespace(string value) - { - if (String.IsNullOrEmpty(value)) - throw new ArgumentNullException(nameof(value)); - Target.Namespace = value; - return this; - } - - public CloudWatchMetricsClientOptionsBuilder Dimensions(params Dimension[] dimensions) - { - if (dimensions == null) - throw new ArgumentNullException(nameof(dimensions)); - Target.Dimensions = new List(dimensions); - return this; - } - - public CloudWatchMetricsClientOptionsBuilder AddDimension(Dimension dimension) - { - if (dimension == null) - throw new ArgumentNullException(nameof(dimension)); - Target.Dimensions.Add(dimension); - return this; - } - - public CloudWatchMetricsClientOptionsBuilder AddDimension(string key, string value) - { - if (String.IsNullOrEmpty(key)) - throw new ArgumentNullException(nameof(key)); - if (String.IsNullOrEmpty(value)) - throw new ArgumentNullException(nameof(value)); - - Target.Dimensions.Add(new Dimension - { - Name = key, - Value = value - }); - return this; - } - - public override CloudWatchMetricsClientOptions Build() - { - if (String.IsNullOrEmpty(Target.ConnectionString)) - return Target; - - var connectionString = new CloudWatchMetricsConnectionStringBuilder(Target.ConnectionString); - if (Target.Credentials == null) - Target.Credentials = connectionString.GetCredentials(); - - if (Target.Region == null) - Target.Region = connectionString.GetRegion(); - - if (String.IsNullOrEmpty(Target.ServiceUrl) && !String.IsNullOrEmpty(connectionString.ServiceUrl)) - Target.ServiceUrl = connectionString.ServiceUrl; - - if (String.IsNullOrEmpty(Target.Namespace) && !String.IsNullOrEmpty(connectionString.Namespace)) - Target.Namespace = connectionString.Namespace; - - if (connectionString.Dimensions.Count > 0) - Target.Dimensions.AddRange(connectionString.Dimensions); - - return Target; - } -} diff --git a/src/Foundatio.AWS/Metrics/CloudWatchMetricsConnectionStringBuilder.cs b/src/Foundatio.AWS/Metrics/CloudWatchMetricsConnectionStringBuilder.cs deleted file mode 100644 index edbfcf3..0000000 --- a/src/Foundatio.AWS/Metrics/CloudWatchMetricsConnectionStringBuilder.cs +++ /dev/null @@ -1,49 +0,0 @@ -using System; -using System.Collections.Generic; -using Amazon.CloudWatch.Model; - -namespace Foundatio.Metrics; - -public class CloudWatchMetricsConnectionStringBuilder : AmazonConnectionStringBuilder -{ - private string _namespace; - - public CloudWatchMetricsConnectionStringBuilder() - { - } - - public CloudWatchMetricsConnectionStringBuilder(string connectionString) : base(connectionString) - { - } - - public string Namespace - { - get => string.IsNullOrEmpty(_namespace) ? "app/metrics" : _namespace; - set => _namespace = value; - } - - public List Dimensions { get; set; } = new List(); - - protected override bool ParseItem(string key, string value) - { - if (String.Equals(key, "Namespace", StringComparison.OrdinalIgnoreCase)) - Namespace = value; - else if (!base.ParseItem(key, value)) - Dimensions.Add(new Dimension - { - Name = key, - Value = value - }); - return true; - } - - public override string ToString() - { - var connectionString = base.ToString(); - if (!string.IsNullOrEmpty(_namespace)) - connectionString += "Namespace=" + _namespace + ";"; - foreach (var dimension in Dimensions) - connectionString += dimension.Name + "=" + dimension.Value + ";"; - return connectionString; - } -} diff --git a/src/Foundatio.AWS/Queues/SQSQueue.cs b/src/Foundatio.AWS/Queues/SQSQueue.cs index e07d976..7e02dbe 100644 --- a/src/Foundatio.AWS/Queues/SQSQueue.cs +++ b/src/Foundatio.AWS/Queues/SQSQueue.cs @@ -10,7 +10,6 @@ using Foundatio.AsyncEx; using Foundatio.Extensions; using Foundatio.Serializer; -using Foundatio.Utility; using Microsoft.Extensions.Logging; using ThirdParty.Json.LitJson; @@ -128,7 +127,7 @@ protected override async Task EnqueueImplAsync(T data, QueueEntryOptions _logger.LogTrace("Enqueued SQS message {MessageId}", response.MessageId); Interlocked.Increment(ref _enqueuedCount); - var entry = new QueueEntry(response.MessageId, options?.CorrelationId, data, this, SystemClock.UtcNow, 0); + var entry = new QueueEntry(response.MessageId, options?.CorrelationId, data, this, _timeProvider.GetUtcNow().UtcDateTime, 0); await OnEnqueuedAsync(entry).AnyContext(); return response.MessageId; @@ -156,7 +155,7 @@ Task ReceiveMessageAsync() _logger.LogTrace("Checking for SQS message... Cancel Requested: {IsCancellationRequested}", linkedCancellationToken.IsCancellationRequested); // The aws sdk will not abort an http long pull operation when the cancellation token is cancelled. - // The aws sdk will throw the OperationCanceledException after the long poll http call is returned and + // The aws sdk will throw the OperationCanceledException after the long poll http call is returned and // the message will be marked as in-flight but not returned from this call: https://github.com/aws/aws-sdk-net/issues/1680 return _client.Value.ReceiveMessageAsync(request, CancellationToken.None); } @@ -170,7 +169,7 @@ Task ReceiveMessageAsync() { try { - await SystemClock.SleepAsync(_options.DequeueInterval, linkedCancellationToken).AnyContext(); + await _timeProvider.Delay(_options.DequeueInterval, linkedCancellationToken).AnyContext(); } catch (OperationCanceledException) { diff --git a/tests/Directory.Build.props b/tests/Directory.Build.props index 7ce35d7..4f770db 100644 --- a/tests/Directory.Build.props +++ b/tests/Directory.Build.props @@ -12,7 +12,7 @@ - + diff --git a/tests/Foundatio.AWS.Tests/Foundatio.AWS.Tests.csproj b/tests/Foundatio.AWS.Tests/Foundatio.AWS.Tests.csproj index e8811e7..bf51b1f 100644 --- a/tests/Foundatio.AWS.Tests/Foundatio.AWS.Tests.csproj +++ b/tests/Foundatio.AWS.Tests/Foundatio.AWS.Tests.csproj @@ -7,4 +7,9 @@ Always + + + docker-compose.yml + + \ No newline at end of file diff --git a/tests/Foundatio.AWS.Tests/Metrics/CloudWatchMetricsConnectionStringBuilderTests.cs b/tests/Foundatio.AWS.Tests/Metrics/CloudWatchMetricsConnectionStringBuilderTests.cs deleted file mode 100644 index 74dfed3..0000000 --- a/tests/Foundatio.AWS.Tests/Metrics/CloudWatchMetricsConnectionStringBuilderTests.cs +++ /dev/null @@ -1,110 +0,0 @@ -using Amazon.CloudWatch.Model; -using Foundatio.Metrics; -using Xunit; - -namespace Foundatio.AWS.Tests.Metrics; - -public class CloudWatchMetricsConnectionStringBuilderTests : ConnectionStringBuilderTests -{ - protected override AmazonConnectionStringBuilder CreateConnectionStringBuilder(string connectionString) - { - return new CloudWatchMetricsConnectionStringBuilder(connectionString); - } - - protected override AmazonConnectionStringBuilder CreateConnectionStringBuilder() - { - return new CloudWatchMetricsConnectionStringBuilder(); - } - - [Fact] - public override void CanParseAccessKey() - { - base.CanParseAccessKey(); - } - - [Fact] - public override void CanParseSecretKey() - { - base.CanParseSecretKey(); - } - - [Fact] - public override void CanParseRegion() - { - base.CanParseRegion(); - } - - [Fact] - public override void CanGenerateConnectionString() - { - base.CanGenerateConnectionString(); - } - - [Fact] - public void CanParseNamespace() - { - foreach (var key in new[] { "Namespace", "namespace" }) - { - var connectionStringBuilder = CreateConnectionStringBuilder($"AccessKey=TestAccessKey;SecretKey=TestSecretKey;{key}=TestNamespace"); - Assert.Equal("TestAccessKey", connectionStringBuilder.AccessKey); - Assert.Equal("TestSecretKey", connectionStringBuilder.SecretKey); - Assert.Null(connectionStringBuilder.Region); - var cloudWatchMetricsConnectionStringBuilder = Assert.IsType(connectionStringBuilder); - Assert.Equal("TestNamespace", cloudWatchMetricsConnectionStringBuilder.Namespace); - } - } - - [Fact] - public void UnknownKeyWillBeDimensions() - { - var connectionStringBuilder = CreateConnectionStringBuilder("AccessKey=TestAccessKey;SecretKey=TestSecretKey;Namespace=TestNamespace;key1=value1;key2=value2"); - Assert.Equal("TestAccessKey", connectionStringBuilder.AccessKey); - Assert.Equal("TestSecretKey", connectionStringBuilder.SecretKey); - var cloudWatchMetricsConnectionStringBuilder = Assert.IsType(connectionStringBuilder); - Assert.Equal("TestNamespace", cloudWatchMetricsConnectionStringBuilder.Namespace); - Assert.Equal(2, cloudWatchMetricsConnectionStringBuilder.Dimensions.Count); - Assert.Equal("key1", cloudWatchMetricsConnectionStringBuilder.Dimensions[0].Name); - Assert.Equal("key2", cloudWatchMetricsConnectionStringBuilder.Dimensions[1].Name); - Assert.Equal("value1", cloudWatchMetricsConnectionStringBuilder.Dimensions[0].Value); - Assert.Equal("value2", cloudWatchMetricsConnectionStringBuilder.Dimensions[1].Value); - } - - [Fact] - public void CanGenerateConnectionStringWithNamespace() - { - var connectionStringBuilder = (CloudWatchMetricsConnectionStringBuilder)CreateConnectionStringBuilder(); - connectionStringBuilder.AccessKey = "TestAccessKey"; - connectionStringBuilder.SecretKey = "TestSecretKey"; - connectionStringBuilder.Region = "TestRegion"; - connectionStringBuilder.Namespace = "TestNamespace"; - - Assert.Equal("AccessKey=TestAccessKey;SecretKey=TestSecretKey;Region=TestRegion;Namespace=TestNamespace;", connectionStringBuilder.ToString()); - } - - [Fact] - public void CanGenerateConnectionStringWithDimensions() - { - var connectionStringBuilder = (CloudWatchMetricsConnectionStringBuilder)CreateConnectionStringBuilder(); - connectionStringBuilder.AccessKey = "TestAccessKey"; - connectionStringBuilder.SecretKey = "TestSecretKey"; - connectionStringBuilder.Region = "TestRegion"; - connectionStringBuilder.Dimensions.Add(new Dimension { Name = "key1", Value = "value1" }); - connectionStringBuilder.Dimensions.Add(new Dimension { Name = "key2", Value = "value2" }); - - Assert.Equal("AccessKey=TestAccessKey;SecretKey=TestSecretKey;Region=TestRegion;key1=value1;key2=value2;", connectionStringBuilder.ToString()); - } - - [Fact] - public void CanGenerateConnectionStringWithAll() - { - var connectionStringBuilder = (CloudWatchMetricsConnectionStringBuilder)CreateConnectionStringBuilder(); - connectionStringBuilder.AccessKey = "TestAccessKey"; - connectionStringBuilder.SecretKey = "TestSecretKey"; - connectionStringBuilder.Region = "TestRegion"; - connectionStringBuilder.Namespace = "TestNamespace"; - connectionStringBuilder.Dimensions.Add(new Dimension { Name = "key1", Value = "value1" }); - connectionStringBuilder.Dimensions.Add(new Dimension { Name = "key2", Value = "value2" }); - - Assert.Equal("AccessKey=TestAccessKey;SecretKey=TestSecretKey;Region=TestRegion;Namespace=TestNamespace;key1=value1;key2=value2;", connectionStringBuilder.ToString()); - } -} diff --git a/tests/Foundatio.AWS.Tests/Metrics/CloudWatchMetricsTests.cs b/tests/Foundatio.AWS.Tests/Metrics/CloudWatchMetricsTests.cs deleted file mode 100644 index 0b134b3..0000000 --- a/tests/Foundatio.AWS.Tests/Metrics/CloudWatchMetricsTests.cs +++ /dev/null @@ -1,71 +0,0 @@ -using System; -using System.Threading.Tasks; -using Foundatio.Metrics; -using Foundatio.Tests.Metrics; -using Microsoft.Extensions.Logging; -using Xunit; -using Xunit.Abstractions; - -namespace Foundatio.AWS.Tests.Metrics; - -public class CloudWatchMetricsTests : MetricsClientTestBase -{ - public CloudWatchMetricsTests(ITestOutputHelper output) : base(output) - { - Log.DefaultMinimumLevel = LogLevel.Trace; - } - -#pragma warning disable CS0618 // Type or member is obsolete - public override IMetricsClient GetMetricsClient(bool buffered = false) - { - // Don't run this as part of the tests because it doesn't work reliably since CloudWatch can take a long time for the stats to show up. - // Also, you can't delete metrics so we have to use random ids and it creates a bunch of junk data. - return null; - -#pragma warning disable CS0162 // Unreachable code detected - string id = Guid.NewGuid().ToString("N").Substring(0, 10); - return new CloudWatchMetricsClient( - o => o.ConnectionString($"serviceurl=http://localhost:4566;Test Id={id}") - .Prefix("foundatio/tests/metrics") - .Buffered(buffered) - .LoggerFactory(Log)); -#pragma warning restore CS0162 // Unreachable code detected - } -#pragma warning restore CS0618 // Type or member is obsolete - - [Fact] - public override Task CanSetGaugesAsync() - { - return base.CanSetGaugesAsync(); - } - - [Fact] - public override Task CanIncrementCounterAsync() - { - return base.CanIncrementCounterAsync(); - } - - [Fact] - public override Task CanWaitForCounterAsync() - { - return base.CanWaitForCounterAsync(); - } - - [Fact] - public override Task CanGetBufferedQueueMetricsAsync() - { - return base.CanGetBufferedQueueMetricsAsync(); - } - - [Fact] - public override Task CanIncrementBufferedCounterAsync() - { - return base.CanIncrementBufferedCounterAsync(); - } - - [Fact] - public override Task CanSendBufferedMetricsAsync() - { - return base.CanSendBufferedMetricsAsync(); - } -} diff --git a/tests/Foundatio.AWS.Tests/Queues/SQSQueueTests.cs b/tests/Foundatio.AWS.Tests/Queues/SQSQueueTests.cs index fe05757..a8a94c1 100644 --- a/tests/Foundatio.AWS.Tests/Queues/SQSQueueTests.cs +++ b/tests/Foundatio.AWS.Tests/Queues/SQSQueueTests.cs @@ -2,7 +2,6 @@ using System.Threading.Tasks; using Foundatio.Queues; using Foundatio.Tests.Queue; -using Foundatio.Utility; using Microsoft.Extensions.Logging; using Xunit; using Xunit.Abstractions; @@ -19,7 +18,7 @@ public SQSQueueTests(ITestOutputHelper output) : base(output) _assertStats = false; } - protected override IQueue GetQueue(int retries = 1, TimeSpan? workItemTimeout = null, TimeSpan? retryDelay = null, int[] retryMultipliers = null, int deadLetterMaxItems = 100, bool runQueueMaintenance = true) + protected override IQueue GetQueue(int retries = 1, TimeSpan? workItemTimeout = null, TimeSpan? retryDelay = null, int[] retryMultipliers = null, int deadLetterMaxItems = 100, bool runQueueMaintenance = true, TimeProvider timeProvider = null) { var queue = new SQSQueue( o => o.ConnectionString("serviceurl=http://localhost:4566;AccessKey=xxx;SecretKey=xxx") @@ -29,6 +28,7 @@ protected override IQueue GetQueue(int retries = 1, TimeSpan? wo .WorkItemTimeout(workItemTimeout.GetValueOrDefault(TimeSpan.FromMinutes(5))) .DequeueInterval(TimeSpan.FromSeconds(1)) .ReadQueueTimeout(TimeSpan.FromSeconds(1)) + .TimeProvider(timeProvider) .LoggerFactory(Log)); _logger.LogDebug("Queue Id: {queueId}", queue.QueueId); @@ -211,7 +211,7 @@ public async Task CanGetQueueItemWithDeliveryDelayAndEnsureMessageNotMarkedWorki Assert.Equal(0, stats.Working); } - await SystemClock.SleepAsync(TimeSpan.FromSeconds(3)); + await Task.Delay(TimeSpan.FromSeconds(3)); if (_assertStats) {