public async Task IgnoresIfExistingMessageTypeDifferent(MessageType existingType) { var type = (MessageType)99; var component = new TestComponent("component"); var existingMessage = new MessageEntity(EventEntity, Time, "existing", existingType); Table .Setup(x => x.RetrieveAsync <MessageEntity>(MessageEntity.GetRowKey(EventEntity, Time))) .ReturnsAsync(existingMessage) .Verifiable(); await Factory.UpdateMessageAsync(EventEntity, Time, type, component); Table.Verify(); Table .Verify( x => x.ReplaceAsync(It.IsAny <MessageEntity>()), Times.Never()); Builder .Verify( x => x.Build(It.IsAny <MessageType>(), It.IsAny <IComponent>(), It.IsAny <ComponentStatus>()), Times.Never()); }
public async Task UpdateMessageAsync(EventEntity eventEntity, DateTime time, MessageType type, IComponent component) { using (_logger.Scope("Updating existing message of type {Type} for event {EventRowKey} at {Timestamp} affecting {ComponentPath}.", type, eventEntity.RowKey, time, component.Path)) { var existingMessage = await _table.RetrieveAsync <MessageEntity>(MessageEntity.GetRowKey(eventEntity, time)); if (existingMessage == null) { _logger.LogWarning("Cannot update message that doesn't exist."); return; } var existingMessageType = (MessageType)existingMessage.Type; if (existingMessageType != type) { if (existingMessageType == MessageType.Manual) { _logger.LogInformation("Message was changed manually, cannot update."); } else { _logger.LogWarning("Cannot update message, has unexpected type {UnexpectedType}.", existingMessageType); } return; } var newContents = _builder.Build(type, component); _logger.LogInformation("Replacing contents of message with time {MessageTimestamp} and contents {OldMessageContents} with {NewMessageContents}.", existingMessage.Time, existingMessage.Contents, newContents); existingMessage.Contents = newContents; await _table.ReplaceAsync(existingMessage); } }
public async Task ReplacesMessage(MessageType type) { var component = new TestComponent("component"); var contents = "new message"; Builder .Setup(x => x.Build(type, component)) .Returns(contents); var message = new MessageEntity(EventEntity, Time, "existing", type); Table .Setup(x => x.RetrieveAsync <MessageEntity>(MessageEntity.GetRowKey(EventEntity, Time))) .ReturnsAsync(message) .Verifiable(); Table .Setup(x => x.ReplaceAsync(message)) .Returns(Task.CompletedTask) .Verifiable(); await Factory.UpdateMessageAsync(EventEntity, Time, type, component); Assert.Equal(EventEntity.RowKey, message.ParentRowKey); Assert.Equal(Time, message.Time); Assert.Equal(contents, message.Contents); Table.Verify(); }
public async Task SavesNewMessageAndUpdatesEventIfNecessary(bool eventIsActive, bool shouldEventBeActive) { var eventStartTime = new DateTime(2018, 8, 19); var entity = new AddStatusMessageManualChangeEntity("path", eventStartTime, "message", shouldEventBeActive) { Timestamp = new DateTimeOffset(2018, 8, 21, 0, 0, 0, TimeSpan.Zero) }; var time = entity.Timestamp.UtcDateTime; var existingEntity = new EventEntity( entity.EventAffectedComponentPath, eventStartTime, ComponentStatus.Up, eventIsActive ? (DateTime?)null : new DateTime(2018, 8, 20)); var eventRowKey = existingEntity.RowKey; _table .Setup(x => x.RetrieveAsync <EventEntity>(eventRowKey)) .Returns(Task.FromResult(existingEntity)); _table .Setup(x => x.InsertAsync(It.IsAny <MessageEntity>())) .Returns(Task.CompletedTask); _table .Setup(x => x.ReplaceAsync(It.IsAny <EventEntity>())) .Returns(Task.CompletedTask); await _handler.Handle(entity); _table .Verify( x => x.InsertAsync( It.Is <MessageEntity>(message => message.PartitionKey == MessageEntity.DefaultPartitionKey && message.RowKey == MessageEntity.GetRowKey(eventRowKey, time) && message.ParentRowKey == eventRowKey && message.Time == time && message.Contents == entity.MessageContents )), Times.Once()); var shouldEventBeUpdated = ManualStatusChangeUtility.ShouldEventBeActive(existingEntity, shouldEventBeActive, time); _table .Verify( x => x.InsertAsync( It.Is <EventEntity>(eventEntity => eventEntity.PartitionKey == EventEntity.DefaultPartitionKey && eventEntity.RowKey == eventRowKey && eventEntity.AffectedComponentPath == existingEntity.AffectedComponentPath && eventEntity.AffectedComponentStatus == existingEntity.AffectedComponentStatus && eventEntity.StartTime == time )), shouldEventBeUpdated ? Times.Once() : Times.Never()); }
public async Task Handle(DeleteStatusMessageManualChangeEntity entity) { var eventRowKey = EventEntity.GetRowKey(entity.EventAffectedComponentPath, entity.EventStartTime); var messageEntity = await _table.RetrieveAsync <MessageEntity>(MessageEntity.GetRowKey(eventRowKey, entity.MessageTimestamp)); if (messageEntity == null) { throw new ArgumentException("Cannot delete a message that does not exist."); } messageEntity.Contents = ""; messageEntity.Type = (int)MessageType.Manual; await _table.ReplaceAsync(messageEntity); }
public async Task CreatesNewMessage() { var type = (MessageType)99; var status = (ComponentStatus)100; var componentStatus = (ComponentStatus)101; var component = new TestComponent("component") { Status = componentStatus }; var expectedStatus = GetExpectedStatus(component, status); var contents = "new message"; Builder .Setup(x => x.Build(type, component, expectedStatus)) .Returns(contents); Table .Setup(x => x.RetrieveAsync <MessageEntity>(MessageEntity.GetRowKey(EventEntity, Time))) .ReturnsAsync((MessageEntity)null) .Verifiable(); Table .Setup(x => x.InsertAsync(It.IsAny <MessageEntity>())) .Callback <ITableEntity>(entity => { var message = entity as MessageEntity; Assert.NotNull(message); Assert.Equal(EventEntity.RowKey, message.ParentRowKey); Assert.Equal(Time, message.Time); Assert.Equal(contents, message.Contents); }) .Returns(Task.CompletedTask) .Verifiable(); await InvokeMethod( EventEntity, Time, type, component, status); Table.Verify(); }
public async Task EditsMessage(MessageType type) { var entity = new EditStatusMessageManualChangeEntity("path", new DateTime(2018, 8, 20), new DateTime(2018, 8, 21), "message"); var eventRowKey = EventEntity.GetRowKey(entity.EventAffectedComponentPath, entity.EventStartTime); var messageRowKey = MessageEntity.GetRowKey(eventRowKey, entity.MessageTimestamp); var existingEntity = new EventEntity( entity.EventAffectedComponentPath, entity.EventStartTime, ComponentStatus.Up, null); _table .Setup(x => x.RetrieveAsync <EventEntity>(eventRowKey)) .Returns(Task.FromResult(existingEntity)); var existingMessage = new MessageEntity( existingEntity, entity.MessageTimestamp, "old message", type); _table .Setup(x => x.RetrieveAsync <MessageEntity>(messageRowKey)) .Returns(Task.FromResult(existingMessage)); _table .Setup(x => x.ReplaceAsync( It.Is <MessageEntity>(messageEntity => messageEntity.PartitionKey == MessageEntity.DefaultPartitionKey && messageEntity.RowKey == messageRowKey && messageEntity.ParentRowKey == eventRowKey && messageEntity.Time == existingMessage.Time && messageEntity.Contents == entity.MessageContents && messageEntity.Type == (int)MessageType.Manual ))) .Returns(Task.CompletedTask) .Verifiable(); await _handler.Handle(entity); _table.Verify(); }
public async Task CreateMessageAsync(EventEntity eventEntity, DateTime time, MessageType type, IComponent component, ComponentStatus status) { using (_logger.Scope("Creating new message of type {Type} for event {EventRowKey} at {Timestamp} affecting {ComponentPath} with status {ComponentStatus}.", type, eventEntity.RowKey, time, component.Path, status)) { var existingMessage = await _table.RetrieveAsync <MessageEntity>(MessageEntity.GetRowKey(eventEntity, time)); if (existingMessage != null) { _logger.LogInformation("Message already exists, will not recreate."); return; } var contents = _builder.Build(type, component, status); var messageEntity = new MessageEntity(eventEntity, time, contents, type); _logger.LogInformation("Creating message with time {MessageTimestamp} and contents {MessageContents}.", messageEntity.Time, messageEntity.Contents); await _table.InsertAsync(messageEntity); } }
public async Task IgnoresIfMessageDoesNotExist() { var type = (MessageType)99; var component = new TestComponent("component"); Table .Setup(x => x.RetrieveAsync <MessageEntity>(MessageEntity.GetRowKey(EventEntity, Time))) .ReturnsAsync((MessageEntity)null); await Factory.UpdateMessageAsync(EventEntity, Time, type, component); Table .Verify( x => x.ReplaceAsync(It.IsAny <MessageEntity>()), Times.Never()); Builder .Verify( x => x.Build(It.IsAny <MessageType>(), It.IsAny <IComponent>(), It.IsAny <ComponentStatus>()), Times.Never()); }
public async Task SavesMessageAndEvent(bool eventIsActive) { var entity = new AddStatusEventManualChangeEntity("path", ComponentStatus.Up, "message", eventIsActive) { Timestamp = new DateTimeOffset(2018, 8, 21, 0, 0, 0, TimeSpan.Zero) }; var time = entity.Timestamp.UtcDateTime; var eventRowKey = EventEntity.GetRowKey(entity.EventAffectedComponentPath, time); _table.Setup(x => x.InsertAsync( It.Is <MessageEntity>(messageEntity => messageEntity.PartitionKey == MessageEntity.DefaultPartitionKey && messageEntity.RowKey == MessageEntity.GetRowKey(eventRowKey, time) && messageEntity.ParentRowKey == eventRowKey && messageEntity.Time == time && messageEntity.Contents == entity.MessageContents ))) .Returns(Task.CompletedTask) .Verifiable(); _table.Setup(x => x.InsertAsync( It.Is <EventEntity>(eventEntity => eventEntity.PartitionKey == EventEntity.DefaultPartitionKey && eventEntity.RowKey == eventRowKey && eventEntity.AffectedComponentPath == entity.EventAffectedComponentPath && eventEntity.AffectedComponentStatus == entity.EventAffectedComponentStatus && eventEntity.StartTime == time && eventEntity.EndTime == (entity.EventIsActive ? (DateTime?)null : time) ))) .Returns(Task.CompletedTask) .Verifiable(); await _handler.Handle(entity); _table.Verify(); }
public async Task ReturnsExistingMessage() { var type = (MessageType)99; var status = (ComponentStatus)100; var componentStatus = (ComponentStatus)101; var component = new TestComponent("component") { Status = componentStatus }; var existingMessage = new MessageEntity(EventEntity, Time, "existing", (MessageType)98); Table .Setup(x => x.RetrieveAsync <MessageEntity>(MessageEntity.GetRowKey(EventEntity, Time))) .ReturnsAsync(existingMessage) .Verifiable(); await InvokeMethod( EventEntity, Time, type, component, status); Table.Verify(); Table .Verify( x => x.InsertAsync(It.IsAny <MessageEntity>()), Times.Never()); Builder .Verify( x => x.Build(It.IsAny <MessageType>(), It.IsAny <IComponent>(), It.IsAny <ComponentStatus>()), Times.Never()); }
public async Task ThrowsArgumentExceptionIfMissingMessage() { var entity = new EditStatusMessageManualChangeEntity("path", new DateTime(2018, 8, 20), new DateTime(2018, 8, 21), "message"); var eventRowKey = EventEntity.GetRowKey(entity.EventAffectedComponentPath, entity.EventStartTime); var messageRowKey = MessageEntity.GetRowKey(eventRowKey, entity.MessageTimestamp); var existingEntity = new EventEntity( entity.EventAffectedComponentPath, entity.EventStartTime, ComponentStatus.Up, null); _table .Setup(x => x.RetrieveAsync <EventEntity>(eventRowKey)) .Returns(Task.FromResult(existingEntity)); _table .Setup(x => x.RetrieveAsync <MessageEntity>(messageRowKey)) .Returns(Task.FromResult <MessageEntity>(null)); await Assert.ThrowsAsync <ArgumentException>(() => _handler.Handle(entity)); }