/// <summary>
 /// true iff the GroupAddress, IsSuppressRouterSideProcessing, QueryRobustnessVariable and SourceAddresses fields are equal
 /// and the QueryInterval is similar.
 /// </summary>
 private bool EqualFields(IgmpQueryVersion3Layer other)
 {
     return(other != null &&
            GroupAddress == other.GroupAddress &&
            IsSuppressRouterSideProcessing == other.IsSuppressRouterSideProcessing &&
            QueryRobustnessVariable == other.QueryRobustnessVariable &&
            QueryInterval.Divide(2) <= other.QueryInterval && QueryInterval.Multiply(2) >= other.QueryInterval &&
            SourceAddresses.SequenceEqual(other.SourceAddresses));
 }
Beispiel #2
0
 /// <summary>
 /// Run multiple types of analysis over the same data.
 /// Each item represents one interval.
 /// </summary>
 /// <param name="collection">Name of event collection to query.</param>
 /// <param name="analysisParams">Defines the multiple types of analyses to perform.</param>
 /// <param name="timeframe">Specifies window of time from which to select events for analysis. May be absolute or relative.</param>
 /// <param name="interval">The block size for partitioning the specified timeframe. Optional, may be null.</param>
 /// <param name="filters">Filters to narrow down the events used in analysis. Optional, may be null.</param>
 /// <param name="timezone">The timezone to use when specifying a relative timeframe. Optional, may be blank.</param>
 /// <returns></returns>
 public async Task <IEnumerable <QueryIntervalValue <IDictionary <string, string> > > > QueryMultiAnalysisIntervalAsync(
     string collection, IEnumerable <MultiAnalysisParam> analysisParams, QueryTimeframe timeframe = null,
     QueryInterval interval = null, IEnumerable <QueryFilter> filters = null, string timezone = "")
 {
     return
         (await
          Queries.MultiAnalysis(collection, analysisParams, timeframe, interval, filters, timezone)
          .ConfigureAwait(false));
 }
Beispiel #3
0
 QueryMultiAnalysisIntervalGroupAsync(string collection, IEnumerable <MultiAnalysisParam> analysisParams,
                                      QueryTimeframe timeframe = null, QueryInterval interval = null, IEnumerable <QueryFilter> filters = null,
                                      string groupBy           = "", string timezone = "")
 {
     return
         (await
          Queries.MultiAnalysis(collection, analysisParams, timeframe, interval, filters, groupBy, timezone)
          .ConfigureAwait(false));
 }
Beispiel #4
0
 /// <summary>
 /// Returns items collected by time interval and group.
 /// </summary>
 /// <param name="queryType">Type of query to run.</param>
 /// <param name="collection">Name of event collection to query.</param>
 /// <param name="targetProperty">Name of property to analyse.</param>
 /// <param name="groupBy">Name of field by which to group results.</param>
 /// <param name="timeframe">Specifies window of time from which to select events for analysis. May be absolute or relative.</param>
 /// <param name="interval">The block size for partitioning the specified timeframe. Optional, may be null.</param>
 /// <param name="filters">Filters to narrow down the events used in analysis. Optional, may be null.</param>
 /// <param name="timezone">The timezone to use when specifying a relative timeframe. Optional, may be blank.</param>
 /// <returns></returns>
 public async Task <IEnumerable <QueryIntervalValue <IEnumerable <QueryGroupValue <string> > > > > QueryIntervalGroupAsync
     (QueryType queryType, string collection, string targetProperty, string groupBy, QueryTimeframe timeframe,
     QueryInterval interval, IEnumerable <QueryFilter> filters = null, string timezone = "")
 {
     return
         (await
          Queries.Metric(queryType, collection, targetProperty, groupBy, timeframe, interval, filters,
                         timezone).ConfigureAwait(false));
 }
        public async Task Query_SimpleSelectUniqueInterval_Success()
        {
            var queryParameters = new QueryParameters()
            {
                Analysis       = QueryType.SelectUnique(),
                TargetProperty = "someProperty",
                Timeframe      = QueryRelativeTimeframe.ThisNHours(2),
                Interval       = QueryInterval.EveryNHours(1)
            };

            var expectedCounts = new List <string[]>()
            {
                new string[] { "10", "20" }, new string[] { "30", "40" }
            };
            var expectedTimeframes = new List <QueryAbsoluteTimeframe>()
            {
                new QueryAbsoluteTimeframe(DateTime.Now.AddHours(-2), DateTime.Now.AddHours(-1)),
                new QueryAbsoluteTimeframe(DateTime.Now.AddHours(-1), DateTime.Now)
            };
            var expectedResults = expectedCounts.Zip(
                expectedTimeframes,
                (count, time) => new { timeframe = time, value = count });

            var expectedResponse = new
            {
                result = expectedResults
            };

            var client = CreateQueryTestKeenClient(queryParameters, expectedResponse);

            var actualResults = await client.Queries.Metric(
                queryParameters.Analysis,
                queryParameters.EventCollection,
                queryParameters.TargetProperty,
                queryParameters.Timeframe,
                queryParameters.Interval);

            Assert.AreEqual(expectedResults.Count(), actualResults.Count());
            var expectedEnumerator = expectedResults.GetEnumerator();
            var actualEnumerator   = actualResults.GetEnumerator();

            while (expectedEnumerator.MoveNext() && actualEnumerator.MoveNext())
            {
                var expected = expectedEnumerator.Current;
                var actual   = actualEnumerator.Current;
                Assert.AreEqual(expected.timeframe.Start, actual.Start);
                Assert.AreEqual(expected.timeframe.End, actual.End);
                Assert.AreEqual(string.Join(",", expected.value), actual.Value);
            }
        }
Beispiel #6
0
 /// <summary>
 /// Run multiple types of analysis over the same data.
 /// Each item represents one interval.
 /// </summary>
 /// <param name="collection">Name of event collection to query.</param>
 /// <param name="analysisParams">Defines the multiple types of analyses to perform.</param>
 /// <param name="timeframe">Specifies window of time from which to select events for analysis. May be absolute or relative.</param>
 /// <param name="interval">The block size for partitioning the specified timeframe. Optional, may be null.</param>
 /// <param name="filters">Filters to narrow down the events used in analysis. Optional, may be null.</param>
 /// <param name="timezone">The timezone to use when specifying a relative timeframe. Optional, may be blank.</param>
 /// <returns></returns>
 public IEnumerable <QueryIntervalValue <IDictionary <string, string> > > QueryMultiAnalysisInterval(
     string collection, IEnumerable <MultiAnalysisParam> analysisParams, QueryTimeframe timeframe = null,
     QueryInterval interval = null, IEnumerable <QueryFilter> filters = null, string timezone = "")
 {
     try
     {
         return
             (QueryMultiAnalysisIntervalAsync(collection, analysisParams, timeframe, interval, filters, timezone)
              .Result);
     }
     catch (AggregateException ex)
     {
         throw ex.TryUnwrap();
     }
 }
Beispiel #7
0
 /// <summary>
 /// Returns items collected by time interval and group.
 /// </summary>
 /// <param name="queryType">Type of query to run.</param>
 /// <param name="collection">Name of event collection to query.</param>
 /// <param name="targetProperty">Name of property to analyse.</param>
 /// <param name="groupBy">Name of field by which to group results.</param>
 /// <param name="timeframe">Specifies window of time from which to select events for analysis. May be absolute or relative.</param>
 /// <param name="interval">The block size for partitioning the specified timeframe. Optional, may be null.</param>
 /// <param name="filters">Filters to narrow down the events used in analysis. Optional, may be null.</param>
 /// <param name="timezone">The timezone to use when specifying a relative timeframe. Optional, may be blank.</param>
 /// <returns></returns>
 public IEnumerable <QueryIntervalValue <IEnumerable <QueryGroupValue <string> > > > QueryIntervalGroup(
     QueryType queryType, string collection, string targetProperty, string groupBy, QueryTimeframe timeframe,
     QueryInterval interval, IEnumerable <QueryFilter> filters = null, string timezone = "")
 {
     try
     {
         return
             (QueryIntervalGroupAsync(queryType, collection, targetProperty, groupBy, timeframe, interval, filters,
                                      timezone).Result);
     }
     catch (AggregateException ex)
     {
         throw ex.TryUnwrap();
     }
 }
Beispiel #8
0
 QueryMultiAnalysisIntervalGroup(string collection, IEnumerable <MultiAnalysisParam> analysisParams,
                                 QueryTimeframe timeframe = null, QueryInterval interval = null, IEnumerable <QueryFilter> filters = null,
                                 string groupBy           = "", string timezone = "")
 {
     try
     {
         return
             (QueryMultiAnalysisIntervalGroupAsync(collection, analysisParams, timeframe, interval, filters,
                                                   groupBy, timezone).Result);
     }
     catch (AggregateException ex)
     {
         throw ex.TryUnwrap();
     }
 }
Beispiel #9
0
        public async Task Query_SimpleSelectUniqueInterval_Success()
        {
            var queryParameters = new QueryParameters()
            {
                Analysis       = QueryType.SelectUnique(),
                TargetProperty = "someProperty",
                Timeframe      = QueryRelativeTimeframe.ThisNHours(2),
                Interval       = QueryInterval.EveryNHours(1)
            };

            var expectedCounts = new List <string[]>()
            {
                new string[] { "10", "20" }, new string[] { "30", "40" }
            };
            var expectedTimeframes = new List <QueryAbsoluteTimeframe>()
            {
                new QueryAbsoluteTimeframe(DateTime.Now.AddHours(-2), DateTime.Now.AddHours(-1)),
                new QueryAbsoluteTimeframe(DateTime.Now.AddHours(-1), DateTime.Now)
            };
            var expectedResults = expectedCounts.Zip(
                expectedTimeframes,
                (count, time) => new { timeframe = time, value = count });
            var expectedResponse = new
            {
                result = expectedResults
            };

            var client = CreateQueryTestKeenClient(queryParameters, expectedResponse);

            var actualResult = await client.Queries.Metric(
                queryParameters.Analysis,
                queryParameters.EventCollection,
                queryParameters.TargetProperty,
                queryParameters.Timeframe,
                queryParameters.Interval);

            var expectedSdkResult = expectedResults.Select((result) =>
            {
                return(new QueryIntervalValue <string>(
                           string.Join(',', result.value),
                           result.timeframe.Start,
                           result.timeframe.End));
            });

            Assert.That(actualResult, Is.EquivalentTo(expectedSdkResult));
        }
Beispiel #10
0
 /// <summary>
 /// Create a new query object.
 /// </summary>
 /// <param name="output">A QueryOutput object containing information necessary to perform output operations.</param>
 /// <param name="interval">The interval at which to query</param>
 /// <param name="name">The name of the query in the database</param>
 /// <param name="database">The filepath of the database that contains this query</param>
 /// <param name="viewName">The data view (query or table) to reference to point to in the database.</param>
 /// <param name="transpose">Whether or not to transpose the contents of the query into the file. Default: false</param>
 /// <param name="time">The time in the Interval to write this query. For Hourly, Time represents the minute. For Daily, Time represents the hour. Default: -1</param>
 /// <param name="delimiter">The character(s) used to delimit values in this Query. Default: ","</param>
 /// <param name="printHeaders">Whether or not the headers of this query should be printed at the top of the file.</param>
 public Query(QueryOutput output, QueryInterval interval, string name, string database, string viewName = "", bool transpose = false, int time = -1, string delimiter = ",", bool printHeaders = false)
 {
     Output   = output;
     Interval = interval;
     Name     = name;
     if (viewName == "")
     {
         DataView = name;
     }
     else
     {
         DataView = viewName;
     }
     Database     = database;
     Transpose    = transpose;
     Time         = time;
     Delimiter    = delimiter;
     PrintHeaders = printHeaders;
     Paused       = false;
 }
Beispiel #11
0
        public async Task Query_SimpleMultiAnalysisInterval_Success()
        {
            var queryParameters = new MultiAnalysisParameters()
            {
                Labels = new string[]
                {
                    "first analysis",
                    "second analysis"
                },
                Analyses = new QueryParameters[]
                {
                    new QueryParameters(),
                    new QueryParameters()
                    {
                        Analysis       = QueryType.Average(),
                        TargetProperty = "targetProperty"
                    }
                },
                Interval = QueryInterval.Daily()
            };

            string responseJson = "{\"result\":[" +
                                  "{\"timeframe\":{\"start\":\"2017-10-14T00:00:00.000Z\",\"end\":\"2017-10-15T00:00:00.000Z\"}," +
                                  "\"value\":{" +
                                  $"\"{queryParameters.Labels[0]}\":12345,\"{queryParameters.Labels[1]}\":54321}}" +
                                  "}," +
                                  "{\"timeframe\":{\"start\":\"2017-10-15T00:00:00.000Z\",\"end\":\"2017-10-16T00:00:00.000Z\"}," +
                                  "\"value\":{" +
                                  $"\"{queryParameters.Labels[0]}\":123,\"{queryParameters.Labels[1]}\":321}}" +
                                  "}" +
                                  "]}";

            var expectedResponse = JObject.Parse(responseJson);

            var client = CreateQueryTestKeenClient(queryParameters, expectedResponse);

            var actualResults = await client.Queries.MultiAnalysis(
                queryParameters.EventCollection,
                queryParameters.GetMultiAnalysisParameters(),
                timeframe : null,
                interval : queryParameters.Interval,
                filters : null,
                timezone : null);

            var expectedResults = expectedResponse["result"];

            Assert.AreEqual(expectedResults.Count(), actualResults.Count());
            var results = expectedResults.Zip(actualResults, (expected, actual) => new { Expected = expected, Actual = actual });

            foreach (var result in results)
            {
                Assert.AreEqual(DateTime.Parse(result.Expected["timeframe"]["start"].Value <string>()), result.Actual.Start);
                Assert.AreEqual(DateTime.Parse(result.Expected["timeframe"]["end"].Value <string>()), result.Actual.End);

                foreach (var label in queryParameters.Labels)
                {
                    // Validate the result is correct
                    Assert.AreEqual(result.Expected["value"][label].Value <int>(), int.Parse(result.Actual.Value[label]));
                }
            }
        }
Beispiel #12
0
        public async Task Query_SimpleSelectUniqueGroupByInterval_Success()
        {
            var queryParameters = new QueryParameters()
            {
                Analysis       = QueryType.SelectUnique(),
                TargetProperty = "someProperty",
                Timeframe      = QueryRelativeTimeframe.ThisNHours(2),
                Interval       = QueryInterval.EveryNHours(1),
                GroupBy        = "someGroupProperty"
            };

            string resultsJson = @"[
                {
                    ""timeframe"": {
                        ""start"": ""2017-10-14T00:00:00.000Z"",
                        ""end"": ""2017-10-15T00:00:00.000Z""
                    },
                    ""value"": [
                        {
                            ""someGroupProperty"": ""group1"",
                            ""result"": [
                                ""10"",
                                ""20""
                            ]
                        },
                        {
                            ""someGroupProperty"": ""group2"",
                            ""result"": [
                                ""30"",
                                ""40""
                            ]
                        }
                    ]
                },
                {
                    ""timeframe"": {
                        ""start"": ""2017-10-15T00:00:00.000Z"",
                        ""end"": ""2017-10-16T00:00:00.000Z""
                    },
                    ""value"": [
                        {
                            ""someGroupProperty"": ""group1"",
                            ""result"": [
                                ""50"",
                                ""60""
                            ]
                        },
                        {
                            ""someGroupProperty"": ""group2"",
                            ""result"": [
                                ""70"",
                                ""80""
                            ]
                        }
                    ]
                }
            ]";

            var expectedResults = JArray.Parse(resultsJson);

            var expectedResponse = new
            {
                result = expectedResults
            };

            var client = CreateQueryTestKeenClient(queryParameters, expectedResponse);

            var actualResult = await client.Queries.Metric(
                queryParameters.Analysis,
                queryParameters.EventCollection,
                queryParameters.TargetProperty,
                queryParameters.GroupBy,
                queryParameters.Timeframe,
                queryParameters.Interval);

            var expectedSdkResult = expectedResults.Select((intervalToken) =>
            {
                return(new QueryIntervalValue <IEnumerable <QueryGroupValue <string> > >(
                           intervalToken["value"].Select((groupToken) =>
                {
                    return new QueryGroupValue <string>(
                        string.Join(',', groupToken["result"]),
                        groupToken[queryParameters.GroupBy].Value <string>());
                }),
                           intervalToken["timeframe"]["start"].Value <DateTime>(),
                           intervalToken["timeframe"]["end"].Value <DateTime>()));
            });

            // Use JArray objects as a way to normalize types here, since the
            // concrete types won't match for the QueryInternalValue IEnumerable implementation.
            Assert.That(JArray.FromObject(actualResult), Is.EquivalentTo(JArray.FromObject(expectedSdkResult)));
        }
Beispiel #13
0
        public async Task Query_SimpleCountGroupByInterval_Success()
        {
            var queryParameters = new QueryParameters()
            {
                TargetProperty = "someProperty",
                Timeframe      = QueryRelativeTimeframe.ThisNHours(2),
                Interval       = QueryInterval.EveryNHours(1),
                GroupBy        = "someGroupProperty"
            };

            var expectedResults = new[]
            {
                new
                {
                    timeframe = new QueryAbsoluteTimeframe(DateTime.Now.AddHours(-2), DateTime.Now.AddHours(-1)),
                    value     = new List <Dictionary <string, string> >
                    {
                        new Dictionary <string, string> {
                            { queryParameters.GroupBy, "group1" }, { "result", "10" }
                        },
                        new Dictionary <string, string> {
                            { queryParameters.GroupBy, "group2" }, { "result", "20" }
                        },
                    }
                },
                new
                {
                    timeframe = new QueryAbsoluteTimeframe(DateTime.Now.AddHours(-1), DateTime.Now),
                    value     = new List <Dictionary <string, string> >
                    {
                        new Dictionary <string, string> {
                            { queryParameters.GroupBy, "group1" }, { "result", "30" }
                        },
                        new Dictionary <string, string> {
                            { queryParameters.GroupBy, "group2" }, { "result", "40" }
                        },
                    }
                }
            };

            var expectedResponse = new
            {
                result = expectedResults
            };

            var client = CreateQueryTestKeenClient(queryParameters, expectedResponse);

            var actualResult = (await client.Queries.Metric(
                                    queryParameters.Analysis,
                                    queryParameters.EventCollection,
                                    queryParameters.TargetProperty,
                                    queryParameters.GroupBy,
                                    queryParameters.Timeframe,
                                    queryParameters.Interval));

            var expectedSdkResult = expectedResults.Select((intervals) =>
            {
                return(new QueryIntervalValue <IEnumerable <QueryGroupValue <string> > >(
                           intervals.value.Select((group) => new QueryGroupValue <string>(
                                                      group["result"],
                                                      group[queryParameters.GroupBy])),
                           intervals.timeframe.Start,
                           intervals.timeframe.End
                           ));
            });

            // Use JArray objects as a way to normalize types here, since the
            // concrete types won't match for the QueryInternalValue IEnumerable implementation.
            Assert.That(JArray.FromObject(actualResult), Is.EquivalentTo(JArray.FromObject(expectedSdkResult)));
        }
Beispiel #14
0
        public async Task Query_SimpleMultiAnalysisIntervalGroupBy_Success()
        {
            var queryParameters = new MultiAnalysisParameters()
            {
                Labels = new string[]
                {
                    "first analysis",
                    "second analysis"
                },
                Analyses = new QueryParameters[]
                {
                    new QueryParameters(),
                    new QueryParameters()
                    {
                        Analysis       = QueryType.Average(),
                        TargetProperty = "targetProperty"
                    }
                },
                GroupBy  = "groupByProperty",
                Interval = QueryInterval.Daily()
            };

            string responseJson = "{\"result\":[" +
                                  "{\"timeframe\":{\"start\":\"2017-10-14T00:00:00.000Z\",\"end\":\"2017-10-15T00:00:00.000Z\"}," +
                                  "\"value\":[" +
                                  $"{{\"{queryParameters.GroupBy}\":\"group1\",\"{queryParameters.Labels[0]}\":12345,\"{queryParameters.Labels[1]}\":54321}}," +
                                  $"{{\"{queryParameters.GroupBy}\":\"group2\",\"{queryParameters.Labels[0]}\":67890,\"{queryParameters.Labels[1]}\":9876}}" +
                                  "]}," +
                                  "{\"timeframe\":{\"start\":\"2017-10-15T00:00:00.000Z\",\"end\":\"2017-10-16T00:00:00.000Z\"}," +
                                  "\"value\":[" +
                                  $"{{\"{queryParameters.GroupBy}\":\"group1\",\"{queryParameters.Labels[0]}\":123,\"{queryParameters.Labels[1]}\":321}}," +
                                  $"{{\"{queryParameters.GroupBy}\":\"group2\",\"{queryParameters.Labels[0]}\":456,\"{queryParameters.Labels[1]}\":654}}" +
                                  "]}" +
                                  "]}";

            var expectedResponse = JObject.Parse(responseJson);

            var client = CreateQueryTestKeenClient(queryParameters, expectedResponse);

            var actualResults = await client.Queries.MultiAnalysis(
                queryParameters.EventCollection,
                queryParameters.GetMultiAnalysisParameters(),
                groupby : queryParameters.GroupBy,
                interval : queryParameters.Interval);

            var expectedResults = expectedResponse["result"];

            Assert.AreEqual(expectedResults.Count(), actualResults.Count());
            var results = expectedResults.Zip(actualResults, (expected, actual) => new { Expected = expected, Actual = actual });

            foreach (var result in results)
            {
                Assert.AreEqual(DateTime.Parse(result.Expected["timeframe"]["start"].Value <string>()), result.Actual.Start);
                Assert.AreEqual(DateTime.Parse(result.Expected["timeframe"]["end"].Value <string>()), result.Actual.End);

                foreach (var group in new string[] { "group1", "group2" })
                {
                    var expectedGroupResult = result.Expected["value"].Where((groupResult) => groupResult[queryParameters.GroupBy].Value <string>() == group).First();
                    var actualGroupResult   = result.Actual.Value.Where((groupResult) => groupResult.Group == group).First();

                    foreach (var label in queryParameters.Labels)
                    {
                        Assert.AreEqual(expectedGroupResult[label].Value <int>(), int.Parse(actualGroupResult.Value[label]));
                    }
                }
            }
        }
        public async Task Query_SimpleSelectUniqueGroupByInterval_Success()
        {
            var queryParameters = new QueryParameters()
            {
                Analysis       = QueryType.SelectUnique(),
                TargetProperty = "someProperty",
                Timeframe      = QueryRelativeTimeframe.ThisNHours(2),
                Interval       = QueryInterval.EveryNHours(1),
                GroupBy        = "someGroupProperty"
            };

            string resultsJson = @"[
                {
                    ""timeframe"": {
                        ""start"": ""2017-10-14T00:00:00.000Z"",
                        ""end"": ""2017-10-15T00:00:00.000Z""
                    },
                    ""value"": [
                        {
                            ""someGroupProperty"": ""group1"",
                            ""result"": [
                                ""10"",
                                ""20""
                            ]
                        },
                        {
                            ""someGroupProperty"": ""group2"",
                            ""result"": [
                                ""30"",
                                ""40""
                            ]
                        }
                    ]
                },
                {
                    ""timeframe"": {
                        ""start"": ""2017-10-15T00:00:00.000Z"",
                        ""end"": ""2017-10-16T00:00:00.000Z""
                    },
                    ""value"": [
                        {
                            ""someGroupProperty"": ""group1"",
                            ""result"": [
                                ""50"",
                                ""60""
                            ]
                        },
                        {
                            ""someGroupProperty"": ""group2"",
                            ""result"": [
                                ""70"",
                                ""80""
                            ]
                        }
                    ]
                }
            ]";

            var expectedResults = JArray.Parse(resultsJson);

            var expectedResponse = new
            {
                result = expectedResults
            };

            var client = CreateQueryTestKeenClient(queryParameters, expectedResponse);

            var actualResults = await client.Queries.Metric(
                queryParameters.Analysis,
                queryParameters.EventCollection,
                queryParameters.TargetProperty,
                queryParameters.GroupBy,
                queryParameters.Timeframe,
                queryParameters.Interval);

            Assert.AreEqual(expectedResults.Count(), actualResults.Count());
            var actualEnumerator = actualResults.GetEnumerator();

            foreach (var expected in expectedResults)
            {
                actualEnumerator.MoveNext();
                var actual = actualEnumerator.Current;
                // Validate the interval is correct
                Assert.AreEqual(DateTime.Parse(expected["timeframe"]["start"].Value <string>()), actual.Start);
                Assert.AreEqual(DateTime.Parse(expected["timeframe"]["end"].Value <string>()), actual.End);

                // Validate the results for the group within the time interval
                Assert.AreEqual(expected["value"].Count(), actual.Value.Count());
                var actualGroupResultEnumerator = actual.Value.GetEnumerator();
                foreach (var expectedGroupResult in expected["value"])
                {
                    actualGroupResultEnumerator.MoveNext();
                    var actualGroupResult = actualGroupResultEnumerator.Current;
                    Assert.AreEqual(expectedGroupResult[queryParameters.GroupBy].Value <string>(), actualGroupResult.Group);
                    Assert.AreEqual(string.Join(",", expectedGroupResult["result"].Values <string>()), actualGroupResult.Value);
                }
            }
        }
        public async Task Query_SimpleCountGroupByInterval_Success()
        {
            var queryParameters = new QueryParameters()
            {
                TargetProperty = "someProperty",
                Timeframe      = QueryRelativeTimeframe.ThisNHours(2),
                Interval       = QueryInterval.EveryNHours(1),
                GroupBy        = "someGroupProperty"
            };

            var expectedResults = new[]
            {
                new
                {
                    timeframe = new QueryAbsoluteTimeframe(DateTime.Now.AddHours(-2), DateTime.Now.AddHours(-1)),
                    value     = new List <Dictionary <string, string> >
                    {
                        new Dictionary <string, string> {
                            { queryParameters.GroupBy, "group1" }, { "result", "10" }
                        },
                        new Dictionary <string, string> {
                            { queryParameters.GroupBy, "group2" }, { "result", "20" }
                        },
                    }
                },
                new
                {
                    timeframe = new QueryAbsoluteTimeframe(DateTime.Now.AddHours(-1), DateTime.Now),
                    value     = new List <Dictionary <string, string> >
                    {
                        new Dictionary <string, string> {
                            { queryParameters.GroupBy, "group1" }, { "result", "30" }
                        },
                        new Dictionary <string, string> {
                            { queryParameters.GroupBy, "group2" }, { "result", "40" }
                        },
                    }
                }
            };

            var expectedResponse = new
            {
                result = expectedResults
            };

            var client = CreateQueryTestKeenClient(queryParameters, expectedResponse);

            var actualResults = await client.Queries.Metric(
                queryParameters.Analysis,
                queryParameters.EventCollection,
                queryParameters.TargetProperty,
                queryParameters.GroupBy,
                queryParameters.Timeframe,
                queryParameters.Interval);

            Assert.AreEqual(expectedResults.Count(), actualResults.Count());
            var actualEnumerator = actualResults.GetEnumerator();

            foreach (var expected in expectedResults)
            {
                actualEnumerator.MoveNext();
                var actual = actualEnumerator.Current;
                // Validate the interval is correct
                Assert.AreEqual(expected.timeframe.Start, actual.Start);
                Assert.AreEqual(expected.timeframe.End, actual.End);

                // Validate the results for the group within the time interval
                Assert.AreEqual(expected.value.Count, actual.Value.Count());
                var actualGroupResultEnumerator = actual.Value.GetEnumerator();
                foreach (var expectedGroupResult in expected.value)
                {
                    actualGroupResultEnumerator.MoveNext();
                    var actualGroupResult = actualGroupResultEnumerator.Current;
                    Assert.AreEqual(expectedGroupResult[queryParameters.GroupBy], actualGroupResult.Group);
                    Assert.AreEqual(expectedGroupResult["result"], actualGroupResult.Value);
                }
            }
        }