public bool?Ping( string instrumentationKey, DateTimeOffset timestamp, string configurationETag, string authApiKey, out CollectionConfigurationInfo configurationInfo) { lock (this.ResponseLock) { if (this.CountersEnabled) { lock (this.countersLock) { this.PingCount++; this.LastPingTimestamp = timestamp; this.LastAuthApiKey = authApiKey; } } if (this.AlwaysThrow) { throw new InvalidOperationException("Mock is set to always throw"); } configurationInfo = this.CollectionConfigurationInfo?.ETag == configurationETag ? null : this.CollectionConfigurationInfo; return(this.ReturnValueFromPing); } }
public void CollectionConfigurationAccumulatorPreparesMetricAccumulatorsTest() { // ARRANGE CollectionConfigurationError[] error; var metricInfo = new CalculatedMetricInfo() { Id = "Metric1", TelemetryType = TelemetryType.Request, Projection = "Name", Aggregation = AggregationType.Min, FilterGroups = new FilterConjunctionGroupInfo[0] }; var collectionConfigurationInfo = new CollectionConfigurationInfo() { Metrics = new[] { metricInfo } }; var collectionConfiguration = new CollectionConfiguration(collectionConfigurationInfo, out error, new ClockMock()); // ACT var accumulator = new CollectionConfigurationAccumulator(collectionConfiguration); // ASSERT Assert.AreSame(collectionConfiguration, accumulator.CollectionConfiguration); Assert.AreEqual("Metric1", accumulator.MetricAccumulators.Single().Key); }
public bool?SubmitSamples( IEnumerable <QuickPulseDataSample> samples, string instrumentationKey, string configurationETag, string authApiKey, out CollectionConfigurationInfo configurationInfo, CollectionConfigurationError[] collectionConfigurationErrors) { lock (this.ResponseLock) { if (this.CountersEnabled) { lock (this.countersLock) { this.batches.Add(samples.Count()); this.LastSampleBatchSize = samples.Count(); this.samples.AddRange(samples); this.LastAuthApiKey = authApiKey; } } if (this.AlwaysThrow) { throw new InvalidOperationException("Mock is set to always throw"); } configurationInfo = this.CollectionConfigurationInfo?.ETag == configurationETag ? null : this.CollectionConfigurationInfo; this.CollectionConfigurationErrors = collectionConfigurationErrors; return(this.ReturnValueFromSubmitSample); } }
private void UpdateConfiguration(CollectionConfigurationInfo configurationInfo) { // we only get here if Etag in the header is different from the current one, but we still want to check if Etag in the body is also different if (configurationInfo != null && !string.Equals(configurationInfo.ETag, this.currentConfigurationETag, StringComparison.Ordinal)) { QuickPulseEventSource.Log.CollectionConfigurationUpdating(this.currentConfigurationETag, configurationInfo.ETag, string.Empty); this.collectionConfigurationErrors.Clear(); CollectionConfigurationError[] errors = null; try { errors = this.onUpdatedConfiguration?.Invoke(configurationInfo); } catch (Exception e) { QuickPulseEventSource.Log.CollectionConfigurationUpdateFailed(this.currentConfigurationETag, configurationInfo.ETag, e.ToInvariantString(), string.Empty); this.collectionConfigurationErrors.Add( CollectionConfigurationError.CreateError( CollectionConfigurationErrorType.CollectionConfigurationFailureToCreateUnexpected, string.Format(CultureInfo.InvariantCulture, "Unexpected error applying configuration. ETag: {0}", configurationInfo.ETag ?? string.Empty), e, Tuple.Create("ETag", configurationInfo.ETag))); } if (errors != null) { this.collectionConfigurationErrors.AddRange(errors); } this.currentConfigurationETag = configurationInfo.ETag; } }
private CollectionConfigurationError[] OnUpdatedConfiguration(CollectionConfigurationInfo configurationInfo) { // we need to preserve the current quota for each document stream that still exists in the new configuration CollectionConfigurationError[] errorsConfig; var newCollectionConfiguration = new CollectionConfiguration(configurationInfo, out errorsConfig, this.timeProvider, this.collectionConfiguration?.DocumentStreams); // the next accumulator that gets swapped in on the collection thread will be initialized with the new collection configuration Interlocked.Exchange(ref this.collectionConfiguration, newCollectionConfiguration); CollectionConfigurationError[] errorsPerformanceCounters; this.UpdatePerformanceCollector(newCollectionConfiguration.PerformanceCounters, out errorsPerformanceCounters); return(errorsConfig.Concat(errorsPerformanceCounters).ToArray()); }
public void CollectionConfigurationReportsInvalidFilterForDocumentStreams() { // ARRANGE CollectionConfigurationError[] errors; var documentStreamInfos = new[] { new DocumentStreamInfo() { Id = "Stream1", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Request, Filters = new FilterConjunctionGroupInfo() { Filters = new[] { new FilterInfo() { FieldName = "NonExistentFieldName" } } } } } } }; var collectionConfigurationInfo = new CollectionConfigurationInfo() { DocumentStreams = documentStreamInfos, ETag = "ETag1" }; // ACT var collectionConfiguration = new CollectionConfiguration(collectionConfigurationInfo, out errors, new ClockMock()); // ASSERT Assert.AreEqual(1, collectionConfiguration.DocumentStreams.Count()); Assert.AreEqual(CollectionConfigurationErrorType.FilterFailureToCreateUnexpected, errors.Single().ErrorType); Assert.AreEqual("Failed to create a filter NonExistentFieldName Equal .", errors.Single().Message); Assert.IsTrue(errors.Single().FullException.Contains("Comparand")); Assert.AreEqual(5, errors.Single().Data.Count); Assert.AreEqual("Stream1", errors.Single().Data["DocumentStreamId"]); Assert.AreEqual("ETag1", errors.Single().Data["ETag"]); Assert.AreEqual("NonExistentFieldName", errors.Single().Data["FilterFieldName"]); Assert.AreEqual(Predicate.Equal.ToString(), errors.Single().Data["FilterPredicate"]); Assert.AreEqual(null, errors.Single().Data["FilterComparand"]); }
private bool?SendRequest( string requestUri, bool includeIdentityHeaders, string configurationETag, string authApiKey, out CollectionConfigurationInfo configurationInfo, Action <Stream> onWriteRequestBody) { try { using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, requestUri)) { this.AddHeaders(request, includeIdentityHeaders, configurationETag, authApiKey); using (MemoryStream stream = new MemoryStream()) { onWriteRequestBody(stream); stream.Flush(); ArraySegment <byte> buffer = stream.TryGetBuffer(out buffer) ? buffer : new ArraySegment <byte>(); request.Content = new ByteArrayContent(buffer.Array, buffer.Offset, buffer.Count); using (var cancellationToken = new CancellationTokenSource(this.timeout)) { HttpResponseMessage response = this.httpClient.SendAsync(request, cancellationToken.Token).GetAwaiter().GetResult(); if (response == null) { configurationInfo = null; return(null); } return(this.ProcessResponse(response, configurationETag, out configurationInfo)); } } } } catch (Exception e) { QuickPulseEventSource.Log.ServiceCommunicationFailedEvent(e.ToInvariantString()); } configurationInfo = null; return(null); }
public void CollectionConfigurationReportsInvalidFilterGroupForDocumentStreams() { // ARRANGE CollectionConfigurationError[] errors; var documentStreamInfos = new[] { new DocumentStreamInfo() { Id = "Stream1", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = (TelemetryType)505, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } } } } }; var collectionConfigurationInfo = new CollectionConfigurationInfo() { DocumentStreams = documentStreamInfos, ETag = "ETag1" }; // ACT var collectionConfiguration = new CollectionConfiguration(collectionConfigurationInfo, out errors, new ClockMock()); // ASSERT Assert.AreEqual(1, collectionConfiguration.DocumentStreams.Count()); Assert.AreEqual(CollectionConfigurationErrorType.DocumentStreamFailureToCreateFilterUnexpected, errors.Single().ErrorType); Assert.AreEqual("Failed to create a document stream filter TelemetryType: '505', filters: ''.", errors.Single().Message); Assert.IsTrue(errors.Single().FullException.Contains("Unsupported TelemetryType: '505'")); Assert.AreEqual(2, errors.Single().Data.Count); Assert.AreEqual("Stream1", errors.Single().Data["DocumentStreamId"]); Assert.AreEqual("ETag1", errors.Single().Data["ETag"]); }
public bool?Ping( string instrumentationKey, DateTimeOffset timestamp, string configurationETag, string authApiKey, out CollectionConfigurationInfo configurationInfo) { var requestUri = string.Format( CultureInfo.InvariantCulture, "{0}/ping?ikey={1}", this.ServiceUri.AbsoluteUri.TrimEnd('/'), Uri.EscapeUriString(instrumentationKey)); return(this.SendRequest( requestUri, true, configurationETag, authApiKey, out configurationInfo, requestStream => this.WritePingData(timestamp, requestStream))); }
private bool?SendRequest( string requestUri, bool includeIdentityHeaders, string configurationETag, string authApiKey, out CollectionConfigurationInfo configurationInfo, Action <Stream> onWriteRequestBody) { try { HttpWebRequest request = WebRequest.Create(new Uri(requestUri)) as HttpWebRequest; request.Method = "POST"; request.Timeout = (int)this.timeout.TotalMilliseconds; this.AddHeaders(request, includeIdentityHeaders, configurationETag, authApiKey); using (Stream requestStream = request.GetRequestStream()) { onWriteRequestBody(requestStream); using (HttpWebResponse response = request.GetResponse() as HttpWebResponse) { if (response == null) { configurationInfo = null; return(null); } return(this.ProcessResponse(response, configurationETag, out configurationInfo)); } } } catch (Exception e) { QuickPulseEventSource.Log.ServiceCommunicationFailedEvent(e.ToInvariantString()); } configurationInfo = null; return(null); }
public bool?SubmitSamples( IEnumerable <QuickPulseDataSample> samples, string instrumentationKey, string configurationETag, string authApiKey, out CollectionConfigurationInfo configurationInfo, CollectionConfigurationError[] collectionConfigurationErrors) { var requestUri = string.Format( CultureInfo.InvariantCulture, "{0}/post?ikey={1}", this.ServiceUri.AbsoluteUri.TrimEnd('/'), Uri.EscapeUriString(instrumentationKey)); return(this.SendRequest( requestUri, false, configurationETag, authApiKey, out configurationInfo, requestStream => this.WriteSamples(samples, instrumentationKey, requestStream, collectionConfigurationErrors))); }
public void CollectionConfigurationReportsDocumentStreamsWithDuplicateIds() { // ARRANGE CollectionConfigurationError[] errors; var documentStreamInfos = new[] { new DocumentStreamInfo() { Id = "Stream1", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Request, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } } } }, new DocumentStreamInfo() { Id = "Stream1", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Dependency, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } } } }, new DocumentStreamInfo() { Id = "Stream2", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Dependency, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } } } } }; var collectionConfigurationInfo = new CollectionConfigurationInfo() { DocumentStreams = documentStreamInfos, ETag = "ETag1" }; // ACT var collectionConfiguration = new CollectionConfiguration(collectionConfigurationInfo, out errors, new ClockMock()); // ASSERT Assert.AreEqual(2, collectionConfiguration.DocumentStreams.Count()); Assert.AreEqual("Stream1", collectionConfiguration.DocumentStreams.First().Id); Assert.AreEqual("Stream2", collectionConfiguration.DocumentStreams.Last().Id); Assert.AreEqual(CollectionConfigurationErrorType.DocumentStreamDuplicateIds, errors.Single().ErrorType); Assert.AreEqual("Document stream with a duplicate id ignored: Stream1", errors.Single().Message); Assert.AreEqual(string.Empty, errors.Single().FullException); Assert.AreEqual(2, errors.Single().Data.Count); Assert.AreEqual("Stream1", errors.Single().Data["DocumentStreamId"]); Assert.AreEqual("ETag1", errors.Single().Data["ETag"]); }
public void CollectionConfigurationCarriesOverQuotaWhenCreatingDocumentStreams() { // ARRANGE var timeProvider = new ClockMock(); CollectionConfigurationError[] errors; var oldDocumentStreamInfos = new[] { new DocumentStreamInfo() { Id = "Stream1", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Request, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } } } }, new DocumentStreamInfo() { Id = "Stream2", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Dependency, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } } } }, new DocumentStreamInfo() { Id = "Stream3", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Exception, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } } } } }; var newDocumentStreamInfos = new[] { new DocumentStreamInfo() { Id = "Stream1", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Request, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } } } }, new DocumentStreamInfo() { Id = "Stream2", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Dependency, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } } } }, new DocumentStreamInfo() { Id = "Stream3", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Exception, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } } } }, new DocumentStreamInfo() { Id = "Stream4", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Event, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } } } }, new DocumentStreamInfo() { Id = "Stream5", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Trace, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } } } } }; var oldCollectionConfigurationInfo = new CollectionConfigurationInfo() { DocumentStreams = oldDocumentStreamInfos, ETag = "ETag1" }; var oldCollectionConfiguration = new CollectionConfiguration(oldCollectionConfigurationInfo, out errors, timeProvider); // spend some quota on the old configuration var accumulatorManager = new QuickPulseDataAccumulatorManager(oldCollectionConfiguration); var telemetryProcessor = new QuickPulseTelemetryProcessor(new SimpleTelemetryProcessorSpy()); ((IQuickPulseTelemetryProcessor)telemetryProcessor).StartCollection( accumulatorManager, new Uri("http://microsoft.com"), new TelemetryConfiguration() { InstrumentationKey = "some ikey" }); // ACT // the initial quota is 3 telemetryProcessor.Process(new RequestTelemetry() { Context = { InstrumentationKey = "some ikey" } }); telemetryProcessor.Process(new DependencyTelemetry() { Context = { InstrumentationKey = "some ikey" } }); telemetryProcessor.Process(new DependencyTelemetry() { Context = { InstrumentationKey = "some ikey" } }); telemetryProcessor.Process(new ExceptionTelemetry() { Context = { InstrumentationKey = "some ikey" } }); telemetryProcessor.Process(new ExceptionTelemetry() { Context = { InstrumentationKey = "some ikey" } }); telemetryProcessor.Process(new ExceptionTelemetry() { Context = { InstrumentationKey = "some ikey" } }); // ACT // the new configuration must carry the quotas over from the old one (only for those document streams that already existed) var newCollectionConfigurationInfo = new CollectionConfigurationInfo() { DocumentStreams = newDocumentStreamInfos, ETag = "ETag1" }; var newCollectionConfiguration = new CollectionConfiguration( newCollectionConfigurationInfo, out errors, timeProvider, oldCollectionConfiguration.DocumentStreams); // ASSERT DocumentStream[] documentStreams = newCollectionConfiguration.DocumentStreams.ToArray(); Assert.AreEqual(5, documentStreams.Length); Assert.AreEqual("Stream1", documentStreams[0].Id); Assert.AreEqual(2, documentStreams[0].RequestQuotaTracker.CurrentQuota); Assert.AreEqual(3, documentStreams[0].DependencyQuotaTracker.CurrentQuota); Assert.AreEqual(3, documentStreams[0].ExceptionQuotaTracker.CurrentQuota); Assert.AreEqual(3, documentStreams[0].EventQuotaTracker.CurrentQuota); Assert.AreEqual(3, documentStreams[0].EventQuotaTracker.CurrentQuota); Assert.AreEqual("Stream2", documentStreams[1].Id); Assert.AreEqual(3, documentStreams[1].RequestQuotaTracker.CurrentQuota); Assert.AreEqual(1, documentStreams[1].DependencyQuotaTracker.CurrentQuota); Assert.AreEqual(3, documentStreams[1].ExceptionQuotaTracker.CurrentQuota); Assert.AreEqual(3, documentStreams[1].EventQuotaTracker.CurrentQuota); Assert.AreEqual(3, documentStreams[1].EventQuotaTracker.CurrentQuota); Assert.AreEqual("Stream3", documentStreams[2].Id); Assert.AreEqual(3, documentStreams[2].RequestQuotaTracker.CurrentQuota); Assert.AreEqual(3, documentStreams[2].DependencyQuotaTracker.CurrentQuota); Assert.AreEqual(0, documentStreams[2].ExceptionQuotaTracker.CurrentQuota); Assert.AreEqual(3, documentStreams[2].EventQuotaTracker.CurrentQuota); Assert.AreEqual(3, documentStreams[2].EventQuotaTracker.CurrentQuota); Assert.AreEqual("Stream4", documentStreams[3].Id); Assert.AreEqual(3, documentStreams[3].RequestQuotaTracker.CurrentQuota); Assert.AreEqual(3, documentStreams[3].DependencyQuotaTracker.CurrentQuota); Assert.AreEqual(3, documentStreams[3].ExceptionQuotaTracker.CurrentQuota); Assert.AreEqual(3, documentStreams[3].EventQuotaTracker.CurrentQuota); Assert.AreEqual(3, documentStreams[3].EventQuotaTracker.CurrentQuota); }
public void CollectionConfigurationCreatesDocumentStreams() { // ARRANGE CollectionConfigurationError[] errors; var documentStreamInfos = new[] { new DocumentStreamInfo() { Id = "Stream1", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Request, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } } } }, new DocumentStreamInfo() { Id = "Stream2", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Dependency, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } } } }, new DocumentStreamInfo() { Id = "Stream3", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Exception, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } } } }, new DocumentStreamInfo() { Id = "Stream4", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Event, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } } } } }; var collectionConfigurationInfo = new CollectionConfigurationInfo() { DocumentStreams = documentStreamInfos, ETag = "ETag1" }; // ACT var collectionConfiguration = new CollectionConfiguration(collectionConfigurationInfo, out errors, new ClockMock()); // ASSERT DocumentStream[] documentStreams = collectionConfiguration.DocumentStreams.ToArray(); Assert.AreEqual(4, documentStreams.Length); Assert.AreEqual("Stream1", documentStreams[0].Id); Assert.AreEqual("Stream2", documentStreams[1].Id); Assert.AreEqual("Stream3", documentStreams[2].Id); Assert.AreEqual("Stream4", documentStreams[3].Id); }
private bool?ProcessResponse(HttpResponseMessage response, string configurationETag, out CollectionConfigurationInfo configurationInfo) { configurationInfo = null; bool isSubscribed; if (!bool.TryParse(response.Headers.GetValuesSafe(QuickPulseConstants.XMsQpsSubscribedHeaderName).FirstOrDefault(), out isSubscribed)) { // could not parse the isSubscribed value // read the response out to avoid issues with TCP connections not being freed up try { response.Content.LoadIntoBufferAsync().GetAwaiter().GetResult(); } catch (Exception) { // we did our best, we don't care about the outcome anyway } return(null); } foreach (string headerName in QuickPulseConstants.XMsQpsAuthOpaqueHeaderNames) { this.authOpaqueHeaderValues[headerName] = response.Headers.GetValuesSafe(headerName).FirstOrDefault(); } string configurationETagHeaderValue = response.Headers.GetValuesSafe(QuickPulseConstants.XMsQpsConfigurationETagHeaderName).FirstOrDefault(); try { using (Stream responseStream = response.Content.ReadAsStreamAsync().GetAwaiter().GetResult()) { if (isSubscribed && !string.IsNullOrEmpty(configurationETagHeaderValue) && !string.Equals(configurationETagHeaderValue, configurationETag, StringComparison.Ordinal) && responseStream != null) { configurationInfo = this.deserializerServerResponse.ReadObject(responseStream) as CollectionConfigurationInfo; } } } catch (Exception e) { // couldn't read or deserialize the response QuickPulseEventSource.Log.ServiceCommunicationFailedEvent(e.ToInvariantString()); } return(isSubscribed); }
private void WriteCollectionConfiguration(Stream stream) { var collectionConfigurationInfo = new CollectionConfigurationInfo() { ETag = "Etag1", Metrics = new[] { new CalculatedMetricInfo() { Id = "Metric1", Aggregation = AggregationType.Sum, Projection = "Count()", FilterGroups = new[] { new FilterConjunctionGroupInfo() { Filters = new[] { new FilterInfo() { FieldName = "Success", Predicate = Predicate.Equal, Comparand = "True" } } } } } }, DocumentStreams = new[] { new DocumentStreamInfo() { Id = "Stream1", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Request, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } }, new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Dependency, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } }, new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Exception, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } }, new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Event, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } }, new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Trace, Filters = new FilterConjunctionGroupInfo() { Filters = new FilterInfo[0] } } } } } }; var serializerCollectionConfigurationInfo = new DataContractJsonSerializer(typeof(CollectionConfigurationInfo)); serializerCollectionConfigurationInfo.WriteObject(stream, collectionConfigurationInfo); }
public void CollectionConfigurationReportsMultipleInvalidFiltersAndDocumentStreams() { // ARRANGE CollectionConfigurationError[] errors; var documentStreamInfos = new[] { new DocumentStreamInfo() { Id = "Stream1", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = (TelemetryType)505, Filters = new FilterConjunctionGroupInfo() { Filters = new[] { new FilterInfo() { FieldName = "NonExistentFilterFieldName1" }, new FilterInfo() { FieldName = "NonExistentFilterFieldName2" } } } } } }, new DocumentStreamInfo() { Id = "Stream2", DocumentFilterGroups = new[] { new DocumentFilterConjunctionGroupInfo() { TelemetryType = TelemetryType.Request, Filters = new FilterConjunctionGroupInfo() { Filters = new[] { new FilterInfo() { FieldName = "NonExistentFilterFieldName3" }, new FilterInfo() { FieldName = "NonExistentFilterFieldName4" } } } } } } }; var collectionConfigurationInfo = new CollectionConfigurationInfo() { DocumentStreams = documentStreamInfos, ETag = "ETag1" }; // ACT var collectionConfiguration = new CollectionConfiguration(collectionConfigurationInfo, out errors, new ClockMock()); // ASSERT Assert.AreEqual(2, collectionConfiguration.DocumentStreams.Count()); Assert.AreEqual("Stream1", collectionConfiguration.DocumentStreams.First().Id); Assert.AreEqual("Stream2", collectionConfiguration.DocumentStreams.Last().Id); Assert.AreEqual(3, errors.Length); Assert.AreEqual(CollectionConfigurationErrorType.DocumentStreamFailureToCreateFilterUnexpected, errors[0].ErrorType); Assert.AreEqual( "Failed to create a document stream filter TelemetryType: '505', filters: 'NonExistentFilterFieldName1 Equal , NonExistentFilterFieldName2 Equal '.", errors[0].Message); Assert.IsTrue(errors[0].FullException.Contains("Unsupported TelemetryType: '505'")); Assert.AreEqual(2, errors[0].Data.Count); Assert.AreEqual("Stream1", errors[0].Data["DocumentStreamId"]); Assert.AreEqual("ETag1", errors[0].Data["ETag"]); Assert.AreEqual(CollectionConfigurationErrorType.FilterFailureToCreateUnexpected, errors[1].ErrorType); Assert.AreEqual("Failed to create a filter NonExistentFilterFieldName3 Equal .", errors[1].Message); Assert.IsTrue(errors[1].FullException.Contains("Comparand")); Assert.AreEqual(5, errors[1].Data.Count); Assert.AreEqual("Stream2", errors[1].Data["DocumentStreamId"]); Assert.AreEqual("ETag1", errors[1].Data["ETag"]); Assert.AreEqual("NonExistentFilterFieldName3", errors[1].Data["FilterFieldName"]); Assert.AreEqual(Predicate.Equal.ToString(), errors[1].Data["FilterPredicate"]); Assert.AreEqual(null, errors[1].Data["FilterComparand"]); Assert.AreEqual(CollectionConfigurationErrorType.FilterFailureToCreateUnexpected, errors[2].ErrorType); Assert.AreEqual("Failed to create a filter NonExistentFilterFieldName4 Equal .", errors[2].Message); Assert.IsTrue(errors[2].FullException.Contains("Comparand")); Assert.AreEqual(5, errors[2].Data.Count); Assert.AreEqual("Stream2", errors[2].Data["DocumentStreamId"]); Assert.AreEqual("ETag1", errors[2].Data["ETag"]); Assert.AreEqual("NonExistentFilterFieldName4", errors[2].Data["FilterFieldName"]); Assert.AreEqual(Predicate.Equal.ToString(), errors[2].Data["FilterPredicate"]); Assert.AreEqual(null, errors[2].Data["FilterComparand"]); }
public void QuickPulseCollectionStateManagerUpdatesCollectionConfigurationWhenETagChanges() { // ARRANGE var serviceClient = new QuickPulseServiceClientMock { ReturnValueFromPing = true, ReturnValueFromSubmitSample = true }; var actions = new List <string>(); var collectionConfigurationInfos = new List <CollectionConfigurationInfo>(); var manager = CreateManager(serviceClient, new Clock(), actions, collectionConfigurationInfos: collectionConfigurationInfos); var filters = new[] { new FilterConjunctionGroupInfo() { Filters = new[] { new FilterInfo() { FieldName = "Name", Predicate = Predicate.Equal, Comparand = "Request1" } } } }; var metrics = new[] { new CalculatedMetricInfo() { Id = "Metric0", TelemetryType = TelemetryType.Request, Projection = "Name", Aggregation = AggregationType.Avg, FilterGroups = filters }, new CalculatedMetricInfo() { Id = "Metric1", TelemetryType = TelemetryType.Request, Projection = "Id", Aggregation = AggregationType.Sum, FilterGroups = filters } }; serviceClient.CollectionConfigurationInfo = new CollectionConfigurationInfo() { ETag = "1", Metrics = metrics }; manager.UpdateState("empty iKey", string.Empty); collectionConfigurationInfos.Clear(); // ACT serviceClient.CollectionConfigurationInfo = new CollectionConfigurationInfo() { ETag = "2", Metrics = metrics }; manager.UpdateState("empty iKey", string.Empty); // ASSERT CollectionConfigurationInfo receivedCollectionConfigurationInfo = collectionConfigurationInfos.Single(); Assert.AreEqual("2", receivedCollectionConfigurationInfo.ETag); Assert.AreEqual(2, receivedCollectionConfigurationInfo.Metrics.Length); Assert.AreEqual(metrics[0].ToString(), receivedCollectionConfigurationInfo.Metrics[0].ToString()); Assert.AreEqual(metrics[0].Id, receivedCollectionConfigurationInfo.Metrics[0].Id); Assert.AreEqual(metrics[1].ToString(), receivedCollectionConfigurationInfo.Metrics[1].ToString()); Assert.AreEqual(metrics[1].Id, receivedCollectionConfigurationInfo.Metrics[1].Id); }