public async Task TimelineIsPreservedAndRetryIsIncrementedOnAbandonTest() { // given - a message with a handler that fails var mockMessage = CreateMockMessage(CreateValidTestVstsMessage()); mockMessage.SetProperty(VstsMessageConstants.TaskLogIdPropertyName, 456); var maxRetryAttempts = 10; var currRetry = 5; mockMessage.SetProperty(VstsMessageConstants.RetryAttemptPropertyName, currRetry); var mockTaskClient = new MockTaskClient(); var executeCount = 0; var mockVstsHandler = new MockVstsHandler() { MockExecuteFunc = msg => { executeCount++; throw new NotImplementedException("handler throws expected ex"); }, }; var mockMessageListener = new MockServiceBusQueueMessageListener(); // when await ProcessTestMessage(mockMessage, mockMessageListener, mockTaskClient, mockVstsHandler, maxRetryAttempts : maxRetryAttempts); // then - logs are written to existing timeline Assert.IsTrue(mockMessageListener.IsAbandoned); Assert.AreEqual(0, mockTaskClient.TimelineRecordsUpdated.Count); // Assert.AreEqual("456", mockMessage.UpdatedProperties[VstsMessageConstants.TaskLogIdPropertyName]); // Assert.AreEqual((currRetry + 1).ToString(), mockMessage.UpdatedProperties[VstsMessageConstants.RetryAttemptPropertyName]); Assert.AreEqual(1, executeCount); }
public async Task ExecuteGoldenPathTestForBuild() { // given var testVstsMessage = CreateValidTestVstsMessage(); testVstsMessage.BuildProperties.BuildName = "tacos"; testVstsMessage.TestProperty = "burrito"; testVstsMessage.CompleteSychronously = false; var mockMessage = CreateMockMessage(testVstsMessage); var mockTaskClient = new MockTaskClient(); var executeCalled = false; var handler = new MockVstsHandler { MockExecuteFunc = (vstsMessage) => { Assert.IsNotNull(vstsMessage); Assert.AreEqual("tacos", vstsMessage.BuildProperties.BuildName); Assert.AreEqual("burrito", vstsMessage.TestProperty); executeCalled = true; return(Task.FromResult(new VstsScheduleResult() { Message = "(test) execution started", ScheduledId = "someId", ScheduleFailed = false })); } }; var mockMessageListener = new MockServiceBusQueueMessageListener(); // when await ProcessTestMessage(mockMessage, mockMessageListener, mockTaskClient, handler); // then - executed successfully Assert.IsTrue(executeCalled); Assert.IsTrue(mockMessageListener.IsCompleted); // then - job assigned was called Assert.AreEqual(1, mockTaskClient.EventsReceived.Count); var assignedEvent = mockTaskClient.EventsReceived[0] as JobAssignedEvent; Assert.IsNotNull(assignedEvent); Assert.AreEqual(testVstsMessage.JobId, assignedEvent.JobId); // then - timeline was created Assert.AreEqual(1, mockTaskClient.TimelineRecordsUpdated.Count); Assert.AreEqual(string.Format("someTimeline_{0}", testVstsMessage.JobId), mockTaskClient.TimelineRecordsUpdated[0].Name); // then - logs were written Assert.AreEqual(2, mockTaskClient.LogLines.Count); }
private static async Task TestReportJobStarted(ReleaseStatus releaseStatus, bool returnNullRelease, int expectedEventCount) { // given VstsMessage vstsContext = new TestVstsMessage { VstsHub = HubType.Release, VstsUri = new Uri("http://vstsUri"), VstsPlanUri = new Uri("http://vstsPlanUri"), ReleaseProperties = new VstsReleaseProperties(), }; var mockBuildClient = new MockBuildClient() { MockBuild = new Build() { Status = BuildStatus.None }, ReturnNullBuild = false, }; var mockReleaseClient = new MockReleaseClient() { MockRelease = new Release() { Status = releaseStatus }, ReturnNullRelease = returnNullRelease, }; var mockTaskClient = new MockTaskClient(); var reportingHelper = new VstsReportingHelper(vstsContext, new TraceBrokerInstrumentation(), new Dictionary <string, string>()) { CreateReleaseClient = (uri, s) => ReturnMockReleaseClientIfUrlValid(uri, vstsContext, mockReleaseClient), CreateBuildClient = (uri, s) => mockBuildClient, CreateTaskHttpClient = (uri, s, i, r) => mockTaskClient }; // when await reportingHelper.ReportJobStarted(DateTime.UtcNow, "test message", default(CancellationToken)); // then Assert.AreEqual(expectedEventCount, mockTaskClient.EventsReceived.Count); if (expectedEventCount != 0) { var taskEvent = mockTaskClient.EventsReceived[0] as JobStartedEvent; Assert.IsNotNull(taskEvent); } }
public async Task MessageIsDeadLetteredAndAbandonsBuildOnMaxRetryTest() { // given - a message with a handler that fails var mockMessage = CreateMockMessage(CreateValidTestVstsMessage()); mockMessage.SetProperty(VstsMessageConstants.TaskLogIdPropertyName, 456); var maxRetryAttempts = 10; var currRetry = 10; mockMessage.SetProperty(VstsMessageConstants.RetryAttemptPropertyName, currRetry); var mockTaskClient = new MockTaskClient(); var executeCount = 0; var mockVstsHandler = new MockVstsHandler() { MockExecuteFunc = msg => { executeCount++; throw new NotImplementedException("handler throws expected ex"); }, }; var mockMessageListener = new MockServiceBusQueueMessageListener(); // when await ProcessTestMessage(mockMessage, mockMessageListener, mockTaskClient, mockVstsHandler, maxRetryAttempts : maxRetryAttempts); // then - logs are written to existing timeline Assert.IsTrue(mockMessageListener.IsDeadLettered); Assert.AreEqual(0, mockTaskClient.TimelineRecordsUpdated.Count); // Assert.AreEqual("456", mockMessage.UpdatedProperties[VstsMessageConstants.TaskLogIdPropertyName]); // Assert.AreEqual((currRetry + 1).ToString(), mockMessage.UpdatedProperties[VstsMessageConstants.RetryAttemptPropertyName]); // Assert.AreEqual("NotImplementedException", mockMessage.UpdatedProperties[VstsMessageConstants.ErrorTypePropertyName]); Assert.AreEqual(1, executeCount); // then - build was failed Assert.AreEqual(2, mockTaskClient.EventsReceived.Count); var assignedEvent = mockTaskClient.EventsReceived[0] as JobAssignedEvent; Assert.IsNotNull(assignedEvent); var completedEvent = mockTaskClient.EventsReceived[1] as JobCompletedEvent; Assert.IsNotNull(completedEvent); Assert.AreEqual(TaskResult.Abandoned, completedEvent.Result); }
public async Task TimelineIsNotCreatedOnRetryTest() { // given - a message with a logId var mockMessage = CreateMockMessage(CreateValidTestVstsMessage()); mockMessage.SetProperty(VstsMessageConstants.TaskLogIdPropertyName, 456); mockMessage.SetProperty(VstsMessageConstants.RetryAttemptPropertyName, 10); var mockTaskClient = new MockTaskClient(); var mockMessageListener = new MockServiceBusQueueMessageListener(); // when await ProcessTestMessage(mockMessage, mockMessageListener, mockTaskClient); // then - logs are written to existing timeline Assert.IsTrue(mockMessageListener.IsCompleted); Assert.AreEqual(0, mockTaskClient.TimelineRecordsUpdated.Count); Assert.AreEqual(2, mockTaskClient.LogLines.Count); }
public async Task ExecuteScheduleFailedGoldenPathTest() { // given var testVstsMessage = CreateValidTestVstsMessage(); testVstsMessage.CompleteSychronously = true; var mockMessage = CreateMockMessage(testVstsMessage); var mockTaskClient = new MockTaskClient(); var mockReportingHelper = new MockVstsReportingHelper(testVstsMessage); var executeCalled = false; var handler = new MockVstsHandler { MockExecuteFunc = (vstsMessage) => { executeCalled = true; return(Task.FromResult(new VstsScheduleResult() { Message = "some error message", ScheduleFailed = true })); } }; // when await ProcessTestMessage(mockMessage, null, mockTaskClient, handler, mockReportingHelper); // then - executed successfully Assert.IsTrue(executeCalled); // then - job assigned & job completed was called Assert.AreEqual(1, mockTaskClient.EventsReceived.Count); var assignedEvent = mockTaskClient.EventsReceived[0] as JobAssignedEvent; Assert.IsNotNull(assignedEvent); Assert.AreEqual(2, mockReportingHelper.JobStatusReceived.Count); var startedMessage = mockReportingHelper.JobStatusReceived[0]; Assert.AreEqual(MockVstsReportingHelper.JobStatusEnum.Started, startedMessage); var completedMessage = mockReportingHelper.JobStatusReceived[1]; Assert.AreEqual(MockVstsReportingHelper.JobStatusEnum.Completed, completedMessage); Assert.AreEqual(testVstsMessage.JobId, mockReportingHelper.VstsMessage.JobId); Assert.IsFalse(mockReportingHelper.JobStatusSuccess); }
private static async Task TestReportJobStarted(ReleaseStatus releaseStatus, bool returnNullRelease, int expectedEventCount) { // given VstsMessage vstsContext = new TestVstsMessage { VstsHub = HubType.Release, VstsUri = new Uri("http://vstsUri"), VstsPlanUri = new Uri("http://vstsPlanUri"), ReleaseProperties = new VstsReleaseProperties(), }; var mockBuildClient = new MockBuildClient() { MockBuild = new Build() { Status = BuildStatus.None }, ReturnNullBuild = false, }; var mockReleaseClient = new MockReleaseClient() { MockRelease = new Release() { Status = releaseStatus }, ReturnNullRelease = returnNullRelease, }; var mockTaskClient = new MockTaskClient(); Assert.AreNotEqual(vstsContext.VstsUri, vstsContext.VstsPlanUri, "need to be different to ensure we can test correct one is used"); var reportingHelper = new TestableJobStatusReportingHelper(vstsContext, new TraceLogger(), mockTaskClient, mockReleaseClient, mockBuildClient); // when await reportingHelper.ReportJobStarted(DateTime.UtcNow, "test message", default(CancellationToken)); // then Assert.AreEqual(expectedEventCount, mockTaskClient.EventsReceived.Count); if (expectedEventCount != 0) { var taskEvent = mockTaskClient.EventsReceived[0] as JobStartedEvent; Assert.IsNotNull(taskEvent); } }
public async Task CancelGoldenPathTest() { // given - a cancel message var testVstsMessage = CreateValidTestVstsMessage(); testVstsMessage.RequestType = RequestType.Cancel; var mockMessage = CreateMockMessage(testVstsMessage); var mockTaskClient = new MockTaskClient(); var cancelCalled = false; var handler = new MockVstsHandler { MockCancelFunc = (vstsMessage) => { Assert.IsNotNull(vstsMessage); cancelCalled = true; return(Task.FromResult("(test) cancel reqeusted!")); } }; var mockMessageListener = new MockServiceBusQueueMessageListener(); // when await ProcessTestMessage(mockMessage, mockMessageListener, mockTaskClient, handler); // then - cancelled successfully Assert.IsTrue(cancelCalled); Assert.IsTrue(mockMessageListener.IsCompleted); // then - job assigned is not called Assert.AreEqual(0, mockTaskClient.EventsReceived.Count); // then - timeline was created Assert.AreEqual(1, mockTaskClient.TimelineRecordsUpdated.Count); Assert.AreEqual(string.Format("someTimeline_{0}", testVstsMessage.JobId), mockTaskClient.TimelineRecordsUpdated[0].Name); // then - logs were written Assert.AreEqual(2, mockTaskClient.LogLines.Count); }
private static async Task TestReportJobStarted(BuildStatus buildStatus, bool returnNullBuild, int expectedEventCount) { // given VstsMessage vstsContext = new TestVstsMessage { VstsHub = HubType.Build, VstsUri = new Uri("http://vstsUri"), VstsPlanUri = new Uri("http://vstsPlanUri"), BuildProperties = new VstsBuildProperties(), }; var mockBuildClient = new MockBuildClient() { MockBuild = new Build() { Status = buildStatus }, ReturnNullBuild = returnNullBuild, }; var mockTaskClient = new MockTaskClient(); var mockReleaseClient = new MockReleaseClient(); var reportingHelper = new TestableJobStatusReportingHelper(vstsContext, new TraceLogger(), mockTaskClient, mockReleaseClient, mockBuildClient) { //CreateBuildClient = (uri, s) => ReportingBrokerJobCompletedTests.ReturnMockBuildClientIfUrlValid(uri, vstsContext, mockBuildClient), //CreateReleaseClient = (uri, t) => mockReleaseClient }; // when await reportingHelper.ReportJobStarted(DateTime.UtcNow, "test message", default(CancellationToken)); // then Assert.AreEqual(expectedEventCount, mockTaskClient.EventsReceived.Count); if (expectedEventCount != 0) { var taskEvent = mockTaskClient.EventsReceived[0] as JobStartedEvent; Assert.IsNotNull(taskEvent); } }
private async Task TestReportJobCompleted(BuildStatus buildStatus, bool returnNullBuild, bool isPassed, int expectedEventCount, TaskResult expectedResult, int expectedRecordCount = 0, string timeLineRecordName = null) { // given Guid parentId = Guid.NewGuid(); Guid childId = Guid.NewGuid(); VstsMessage vstsContext = new TestVstsMessage { JobId = parentId, VstsHub = HubType.Build, VstsUri = new Uri("http://vstsUri"), VstsPlanUri = new Uri("http://vstsPlanUri"), BuildProperties = new VstsBuildProperties(), }; var mockBuildClient = new MockBuildClient() { MockBuild = new Build() { Status = buildStatus }, ReturnNullBuild = returnNullBuild, }; var mockReleaseClient = new MockReleaseClient() { MockRelease = new Release() { Status = ReleaseStatus.Undefined }, ReturnNullRelease = false, }; var timelineRecords = new List <Microsoft.TeamFoundation.DistributedTask.WebApi.TimelineRecord> { new Microsoft.TeamFoundation.DistributedTask.WebApi.TimelineRecord() { Id = parentId }, new Microsoft.TeamFoundation.DistributedTask.WebApi.TimelineRecord() { Id = childId, ParentId = parentId }, new Microsoft.TeamFoundation.DistributedTask.WebApi.TimelineRecord() { // Should be ignored Id = Guid.NewGuid() } }; if (!string.IsNullOrEmpty(timeLineRecordName)) { timelineRecords.Add(new Microsoft.TeamFoundation.DistributedTask.WebApi.TimelineRecord() { Id = Guid.NewGuid(), Name = timeLineRecordName }); } var mockTaskHttpClient = new MockTaskClient() { GetRecordsReturnCollection = timelineRecords }; var reportingHelper = new VstsReportingHelper(vstsContext, new TraceBrokerInstrumentation(), new Dictionary <string, string>(), timeLineRecordName) { CreateBuildClient = (uri, s) => ReturnMockBuildClientIfUrlValid(uri, vstsContext, mockBuildClient), CreateReleaseClient = (uri, s) => mockReleaseClient, CreateTaskHttpClient = (uri, s, i, r) => mockTaskHttpClient }; // when await reportingHelper.ReportJobCompleted(DateTime.UtcNow, "test message", isPassed, default(CancellationToken)); // then Assert.AreEqual(expectedEventCount, mockTaskHttpClient.EventsReceived.Count); if (expectedEventCount != 0) { var taskEvent = mockTaskHttpClient.EventsReceived[0] as JobCompletedEvent; Assert.IsNotNull(taskEvent); Assert.AreEqual(taskEvent.Result, expectedResult); } Assert.AreEqual(expectedRecordCount, mockTaskHttpClient.TimelineRecordsUpdated.Count); if (expectedRecordCount != 0) { var records = string.IsNullOrEmpty(timeLineRecordName) ? mockTaskHttpClient.TimelineRecordsUpdated.Where(rec => rec.Id == parentId || rec.Id == childId).ToList() : mockTaskHttpClient.TimelineRecordsUpdated.Where(rec => rec.Name != null && rec.Name.Equals(timeLineRecordName, StringComparison.OrdinalIgnoreCase)).ToList(); Assert.AreEqual(expectedRecordCount, records.Count); foreach (var record in records) { Assert.IsNotNull(record); Assert.AreEqual(expectedResult, record.Result); } } }
private static async Task ProcessTestMessage(MockServiceBusMessage mockServiceBusMessage = null, MockServiceBusQueueMessageListener mockMessageListener = null, MockTaskClient mockTaskClient = null, MockVstsHandler handler = null, MockVstsReportingHelper mockReportingHelper = null, IBrokerInstrumentation instrumentation = null, int maxRetryAttempts = 1, IBuildClient mockBuildClient = null, IGitClient mockGitClient = null) { mockServiceBusMessage = mockServiceBusMessage ?? CreateMockMessage(CreateValidTestVstsMessage()); mockTaskClient = mockTaskClient ?? new MockTaskClient(); mockBuildClient = mockBuildClient ?? new MockBuildClient() { MockBuild = new Build() { Status = BuildStatus.InProgress } }; mockReportingHelper = mockReportingHelper ?? new MockVstsReportingHelper(new TestVstsMessage()); var mockReleaseClient = new MockReleaseClient() { MockRelease = new Release() { Status = ReleaseStatus.Active } }; handler = handler ?? new MockVstsHandler { MockExecuteFunc = (vstsMessage) => Task.FromResult(new VstsScheduleResult() { Message = "(test) mock execute requested", ScheduledId = "someId", ScheduleFailed = false }) }; instrumentation = instrumentation ?? new TraceBrokerInstrumentation(); var settings = new ServiceBusQueueMessageHandlerSettings { MaxRetryAttempts = maxRetryAttempts, TimeLineNamePrefix = "someTimeline", WorkerName = "someWorker" }; mockMessageListener = mockMessageListener ?? new MockServiceBusQueueMessageListener(); var schedulingBroker = new ServiceBusQueueMessageHandler <TestVstsMessage>(queueClient: mockMessageListener, baseInstrumentation: instrumentation, scheduleHandler: handler, settings: settings); schedulingBroker.CreateTaskClient = (uri, creds, instrumentationHandler, skipRaisePlanEvents) => mockTaskClient; schedulingBroker.CreateBuildClient = (uri, creds) => mockBuildClient; schedulingBroker.CreateReleaseClient = (uri, creds) => mockReleaseClient; schedulingBroker.CreateVstsReportingHelper = (vstsMessage, inst, props) => mockReportingHelper; var cancelSource = new CancellationTokenSource(); await schedulingBroker.ReceiveAsync(mockServiceBusMessage, cancelSource.Token); }
private static async Task ProcessTestMessage(MockServiceBusMessage mockServiceBusMessage = null, MockServiceBusQueueMessageListener mockMessageListener = null, MockTaskClient mockTaskClient = null, MockVstsHandler handler = null, MockJobStatusReportingHelper mockReportingHelper = null, ILogger logger = null, int maxRetryAttempts = 1, IBuildClient mockBuildClient = null) { mockServiceBusMessage = mockServiceBusMessage ?? CreateMockMessage(CreateValidTestVstsMessage()); mockTaskClient = mockTaskClient ?? new MockTaskClient(); mockBuildClient = mockBuildClient ?? new MockBuildClient() { MockBuild = new Build() { Status = BuildStatus.InProgress } }; mockReportingHelper = mockReportingHelper ?? new MockJobStatusReportingHelper(new TestVstsMessage()); var mockReleaseClient = new MockReleaseClient() { MockRelease = new Release() { Status = ReleaseStatus.Active } }; handler = handler ?? new MockVstsHandler { MockExecuteFunc = (vstsMessage) => Task.FromResult(new VstsScheduleResult() { Message = "(test) mock execute requested", ScheduledId = "someId", ScheduleFailed = false }) }; logger = logger ?? new TraceLogger(); var settings = new ServiceBusQueueMessageHandlerSettings { MaxRetryAttempts = maxRetryAttempts, TimeLineNamePrefix = "someTimeline", WorkerName = "someWorker" }; mockMessageListener = mockMessageListener ?? new MockServiceBusQueueMessageListener(); var schedulingBroker = new TestableServiceBusQueueMessageHandler(mockMessageListener, handler, settings, logger, mockTaskClient, mockBuildClient, mockReportingHelper, mockReleaseClient); var cancelSource = new CancellationTokenSource(); await schedulingBroker.ReceiveAsync(mockServiceBusMessage, cancelSource.Token); }