public static LinqTestOutput ExecuteTest(LinqTestInput input) { string querySqlStr = string.Empty; try { Func <bool, IQueryable> compiledQuery = input.Expression.Compile(); IQueryable queryResults = compiledQuery(true); querySqlStr = JObject.Parse(queryResults.ToString()).GetValue("query", StringComparison.Ordinal).ToString(); // we skip unordered query because the LinQ results vs actual query results are non-deterministic if (!input.skipVerification) { IQueryable dataResults = compiledQuery(false); LinqTestsCommon.ValidateResults(queryResults, dataResults); } return(new LinqTestOutput(querySqlStr)); } catch (Exception e) { return(new LinqTestOutput(querySqlStr, LinqTestsCommon.BuildExceptionMessageForTest(e))); } }
/// <summary> /// Compare 2 IEnumerable which may contain IEnumerable themselves. /// </summary> /// <param name="queryResults">The query results from Cosmos DB</param> /// <param name="dataResults">The query results from actual data</param> /// <returns>True if the two IEbumerable equal</returns> private static bool NestedListsSequenceEqual(IEnumerable queryResults, IEnumerable dataResults) { IEnumerator queryIter, dataIter; for (queryIter = queryResults.GetEnumerator(), dataIter = dataResults.GetEnumerator(); queryIter.MoveNext() && dataIter.MoveNext();) { IEnumerable queryEnumerable = queryIter.Current as IEnumerable; IEnumerable dataEnumerable = dataIter.Current as IEnumerable; if (queryEnumerable == null && dataEnumerable == null) { if (!(queryIter.Current.Equals(dataIter.Current))) { return(false); } } else if (queryEnumerable == null || dataEnumerable == null) { return(false); } else { if (!(LinqTestsCommon.NestedListsSequenceEqual(queryEnumerable, dataEnumerable))) { return(false); } } } return(!(queryIter.MoveNext() || dataIter.MoveNext())); }
public void ValidateSQLTranslationComplexData() { string constString = "s"; int[] array = { 1, 2, 3 }; var paramx = Expression.Parameter(typeof(int), "x"); const int Records = 100; const int MaxArraySize = 10; const int MaxStringLength = 50; Func <Random, complex> createDataObj = (random) => { var obj = new complex(); obj.b = random.NextDouble() < 0.5; obj.dbl = random.NextDouble(); obj.dblArray = new double[random.Next(MaxArraySize)]; for (int i = 0; i < obj.dblArray.Length; ++i) { obj.dblArray[i] = random.NextDouble() < 0.1 ? 3 : random.NextDouble(); } obj.inside = new simple() { x = random.Next(), y = random.Next() }; obj.str = random.NextDouble() < 0.1 ? "5" : LinqTestsCommon.RandomString(random, random.Next(MaxStringLength)); obj.id = Guid.NewGuid().ToString(); obj.pk = "Test"; return(obj); }; var getQuery = LinqTestsCommon.GenerateTestCosmosData <complex>(createDataObj, Records, testContainer); var inputs = new List <LinqTestInput>(); inputs.Add(new LinqTestInput("Select equality", b => getQuery(b).Select(s => s.str == "5"))); inputs.Add(new LinqTestInput("Select string concat", b => getQuery(b).Select(d => "x" + d.str))); inputs.Add(new LinqTestInput("Select string concat w const", b => getQuery(b).Select(d => "x" + constString + d.str))); inputs.Add(new LinqTestInput("SelectMany array", b => getQuery(b).SelectMany(d => d.dblArray))); inputs.Add(new LinqTestInput("SelectMany array property -> Filter x -> Select x expr", b => getQuery(b).SelectMany(z => z.dblArray).Where(x => x > 2).Select(x => x + 2))); inputs.Add(new LinqTestInput("SelectMany array property -> Filter x equality -> Select x expr", b => getQuery(b).SelectMany(z => z.dblArray.Where(x => x == 3).Select(x => x + 1)))); inputs.Add(new LinqTestInput("SelectMany array property -> Select identity", b => getQuery(b).SelectMany(d => d.dblArray.Select(x => x)))); inputs.Add(new LinqTestInput("SelectMany array property", b => getQuery(b).SelectMany(d => d.dblArray))); inputs.Add(new LinqTestInput("SelectMany array property -> Select x expr", b => getQuery(b).SelectMany(z => z.dblArray.Select(x => z.dbl + x)))); inputs.Add(new LinqTestInput("SelectMany array property -> Select new", b => getQuery(b).SelectMany(z => z.dblArray.Select(x => new { z.b, x = Math.Truncate(x * 100) })))); inputs.Add(new LinqTestInput("SelectMany identity", b => getQuery(b).SelectMany(x => x.dblArray))); inputs.Add(new LinqTestInput("SelectMany x -> Select y", b => getQuery(b).SelectMany(x => x.dblArray.Select(y => y)))); inputs.Add(new LinqTestInput("SelectMany x -> Select x.y", b => getQuery(b).SelectMany(x => x.dblArray.Select(y => y)))); inputs.Add(new LinqTestInput("SelectMany array", b => getQuery(b).SelectMany(x => x.dblArray))); this.ExecuteTestSuite(inputs); }
public static LinqTestOutput ExecuteTest(LinqTestInput input) { var querySqlStr = string.Empty; try { var compiledQuery = input.Expression.Compile(); var queryResults = compiledQuery(true); querySqlStr = JObject.Parse(queryResults.ToString()).GetValue("query", StringComparison.Ordinal).ToString(); // we skip unordered query because the LinQ results vs actual query results are non-deterministic if (!input.skipVerification) { var dataResults = compiledQuery(false); LinqTestsCommon.ValidateResults(queryResults, dataResults); } string errorMsg = null; if (input.errorMessage != null) { errorMsg = $"Expecting error containing message [[{input.errorMessage}]]. Actual: <No error>"; } return(new LinqTestOutput(querySqlStr, errorMsg, errorMsg != null)); } catch (Exception e) { while (!(e is DocumentClientException) && e.InnerException != null) { e = e.InnerException; } string message = null; bool hasFailed = false; if (input.errorMessage != null && !e.Message.Contains(input.errorMessage)) { message = $"Expecting error containing message [[{input.errorMessage}]]. Actual: [[{e.Message}]]"; hasFailed = true; } else if (input.errorMessage == null) { message = e.Message; hasFailed = true; } return(new LinqTestOutput(querySqlStr, message, hasFailed)); } }
public static LinqTestOutput ExecuteTest(LinqTestInput input) { string querySqlStr = string.Empty; try { Func <bool, IQueryable> compiledQuery = input.Expression.Compile(); IQueryable queryResults = compiledQuery(true); querySqlStr = JObject.Parse(queryResults.ToString()).GetValue("query", StringComparison.Ordinal).ToString(); // we skip unordered query because the LinQ results vs actual query results are non-deterministic if (!input.skipVerification) { IQueryable dataResults = compiledQuery(false); LinqTestsCommon.ValidateResults(queryResults, dataResults); } return(new LinqTestOutput(querySqlStr)); } catch (Exception e) { while (e.InnerException != null) { e = e.InnerException; } string message; if (e is CosmosException cosmosException) { message = $"Status Code: {cosmosException.StatusCode}"; } else if (e is DocumentClientException documentClientException) { message = documentClientException.RawErrorMessage; } else { message = e.Message; } return(new LinqTestOutput(querySqlStr, message)); } }
public static LinqTestOutput ExecuteTest(LinqTestInput input) { var querySqlStr = string.Empty; try { var compiledQuery = input.Expression.Compile(); var queryResults = compiledQuery(true); querySqlStr = JObject.Parse(queryResults.ToString()).GetValue("query", StringComparison.Ordinal).ToString(); // we skip unordered query because the LinQ results vs actual query results are non-deterministic if (!input.skipVerification) { var dataResults = compiledQuery(false); LinqTestsCommon.ValidateResults(queryResults, dataResults); } return(new LinqTestOutput(querySqlStr)); } catch (Exception e) { while (!(e is DocumentClientException) && e.InnerException != null) { e = e.InnerException; } string message = null; DocumentClientException dce = e as DocumentClientException; if (dce != null) { message = dce.RawErrorMessage; } else { message = e.Message; } return(new LinqTestOutput(querySqlStr, message)); } }
public override LinqTestOutput ExecuteTest(LinqTestInput input) { return(LinqTestsCommon.ExecuteTest(input)); }
public void ValidateSQLTranslation() { int constInt = 2; int[] array = { 1, 2, 3 }; var paramx = Expression.Parameter(typeof(int), "x"); float floatValue = 5.23f; const int Records = 100; Func <Random, simple> createDataObj = (random) => { var obj = new simple(); obj.x = random.Next(); obj.y = random.Next(); return(obj); }; var dataQuery = LinqTestsCommon.GenerateTestData <simple>(createDataObj, Records, client, testCollection); var inputs = new List <LinqTestInput>(); inputs.Add(new LinqTestInput("Select cast float", b => dataQuery(b).Select(x => (int)(floatValue)))); inputs.Add(new LinqTestInput("Select identity", b => dataQuery(b).Select(x => x))); inputs.Add(new LinqTestInput("Select int expr", b => dataQuery(b).Select(x => x.x % 10 + 2 + x.x % 5))); inputs.Add(new LinqTestInput("Select int expr w const", b => dataQuery(b).Select(x => x.x + constInt))); inputs.Add(new LinqTestInput("Select w new array", b => dataQuery(b).Select(d => new int[2] { d.x, d.x + 1 }))); inputs.Add(new LinqTestInput("Select new", b => dataQuery(b).Select(d => new { first = d.x, second = d.x }))); inputs.Add(new LinqTestInput("Select nested new", b => dataQuery(b).Select(d => new { first = d.x, second = new { third = d.x } }))); inputs.Add(new LinqTestInput("Filter int >", b => dataQuery(b).Where(x => x.x > 2))); inputs.Add(new LinqTestInput("Filter method >", b => dataQuery(b).Where(x => x.x > id(3)))); inputs.Add(new LinqTestInput("Filter int > -> Select int expr", b => dataQuery(b).Where(x => x.x > 2).Select(x => x.x + 2))); inputs.Add(new LinqTestInput("Select int expr -> Filter int >", b => dataQuery(b).Select(x => x.x + 2).Where(x => x > 2))); inputs.Add(new LinqTestInput("Filter int > -> Filter another field", b => dataQuery(b).Where(x => x.x > 2).Where(y => y.x < 4))); inputs.Add(new LinqTestInput("Filter x -> Filter y -> Select y expr", b => dataQuery(b).Where(x => x.x > 2).Where(y => y.x < 4).Select(y => y.x + y.x))); inputs.Add(new LinqTestInput("Select expr w const array", b => dataQuery(b).Select(x => x.x + array[2]))); inputs.Add(new LinqTestInput("Select const array index", b => dataQuery(b) .Where(x => x.x >= 0 && x.x < 3) .Select(x => new int[] { 1, 2, 3 }[x.x]), "The specified query includes 'member indexer' which is currently not supported.")); inputs.Add(new LinqTestInput("Select new simple", b => dataQuery(b).Select(x => new simple { x = x.x, y = x.x }))); inputs.Add(new LinqTestInput("Select new nested", b => dataQuery(b).Select(x => new nested { s = new simple { x = x.x, y = x.x }, x = 2 }))); inputs.Add(new LinqTestInput("Select new complex", b => dataQuery(b).Select(d => new complex { dbl = 1.0, str = "", b = false, dblArray = new double[] { 1.0, 2.0, }, inside = new simple { x = d.x, y = d.x } }))); inputs.Add(new LinqTestInput("Select cast double x", b => dataQuery(b).Select(x => (double)x.x))); inputs.Add(new LinqTestInput("Select indexer x", b => dataQuery(b) .Where(x => x.x >= 0 && x.x < array.Length) .Select(x => array[x.x]), "The specified query includes 'member indexer' which is currently not supported.")); inputs.Add(new LinqTestInput("Select new constructor", b => dataQuery(b).Select(x => new TimeSpan(x.x)), "Constructor invocation is not supported.")); inputs.Add(new LinqTestInput("Select method id", b => dataQuery(b).Select(x => id(x)), "Method 'id' is not supported.")); inputs.Add(new LinqTestInput("Select identity", b => dataQuery(b).Select(x => x))); inputs.Add(new LinqTestInput("Select simple property", b => dataQuery(b).Select(x => x.x))); this.ExecuteTestSuite(inputs); }
public static Func <bool, IQueryable <Family> > GenerateFamilyCosmosData( Cosmos.Database cosmosDatabase, out Container container) { // The test collection should have range index on string properties // for the orderby tests PartitionKeyDefinition partitionKeyDefinition = new PartitionKeyDefinition { Paths = new System.Collections.ObjectModel.Collection <string>(new[] { "/Pk" }), Kind = PartitionKind.Hash }; var newCol = new ContainerProperties() { Id = Guid.NewGuid().ToString(), PartitionKey = partitionKeyDefinition, IndexingPolicy = new Microsoft.Azure.Cosmos.IndexingPolicy() { IncludedPaths = new Collection <Cosmos.IncludedPath>() { new Cosmos.IncludedPath() { Path = "/*", Indexes = new System.Collections.ObjectModel.Collection <Microsoft.Azure.Cosmos.Index>() { Microsoft.Azure.Cosmos.Index.Range(Microsoft.Azure.Cosmos.DataType.Number, -1), Microsoft.Azure.Cosmos.Index.Range(Microsoft.Azure.Cosmos.DataType.String, -1) } } }, CompositeIndexes = new Collection <Collection <Cosmos.CompositePath> >() { new Collection <Cosmos.CompositePath>() { new Cosmos.CompositePath() { Path = "/FamilyId", Order = Cosmos.CompositePathSortOrder.Ascending }, new Cosmos.CompositePath() { Path = "/Int", Order = Cosmos.CompositePathSortOrder.Ascending } }, new Collection <Cosmos.CompositePath>() { new Cosmos.CompositePath() { Path = "/FamilyId", Order = Cosmos.CompositePathSortOrder.Ascending }, new Cosmos.CompositePath() { Path = "/Int", Order = Cosmos.CompositePathSortOrder.Descending } }, new Collection <Cosmos.CompositePath>() { new Cosmos.CompositePath() { Path = "/FamilyId", Order = Cosmos.CompositePathSortOrder.Ascending }, new Cosmos.CompositePath() { Path = "/Int", Order = Cosmos.CompositePathSortOrder.Ascending }, new Cosmos.CompositePath() { Path = "/IsRegistered", Order = Cosmos.CompositePathSortOrder.Descending } }, new Collection <Cosmos.CompositePath>() { new Cosmos.CompositePath() { Path = "/Int", Order = Cosmos.CompositePathSortOrder.Ascending }, new Cosmos.CompositePath() { Path = "/IsRegistered", Order = Cosmos.CompositePathSortOrder.Descending } }, new Collection <Cosmos.CompositePath>() { new Cosmos.CompositePath() { Path = "/IsRegistered", Order = Cosmos.CompositePathSortOrder.Ascending }, new Cosmos.CompositePath() { Path = "/Int", Order = Cosmos.CompositePathSortOrder.Descending } } } } }; container = cosmosDatabase.CreateContainerAsync(newCol).Result; const int Records = 100; const int MaxNameLength = 100; const int MaxThingStringLength = 50; const int MaxChild = 5; const int MaxPets = MaxChild; const int MaxThings = MaxChild; const int MaxGrade = 101; const int MaxTransaction = 20; const int MaxTransactionMinuteRange = 200; int MaxTransactionType = Enum.GetValues(typeof(TransactionType)).Length; Family createDataObj(Random random) { var obj = new Family { FamilyId = random.NextDouble() < 0.05 ? "some id" : Guid.NewGuid().ToString(), IsRegistered = random.NextDouble() < 0.5, NullableInt = random.NextDouble() < 0.5 ? (int?)random.Next() : null, Int = random.NextDouble() < 0.5 ? 5 : random.Next(), Id = Guid.NewGuid().ToString(), Pk = "Test", Parents = new Parent[random.Next(2) + 1] }; for (int i = 0; i < obj.Parents.Length; ++i) { obj.Parents[i] = new Parent() { FamilyName = LinqTestsCommon.RandomString(random, random.Next(MaxNameLength)), GivenName = LinqTestsCommon.RandomString(random, random.Next(MaxNameLength)) }; } obj.Tags = new string[random.Next(MaxChild)]; for (int i = 0; i < obj.Tags.Length; ++i) { obj.Tags[i] = (i + random.Next(30, 36)).ToString(); } obj.Children = new Child[random.Next(MaxChild)]; for (int i = 0; i < obj.Children.Length; ++i) { obj.Children[i] = new Child() { Gender = random.NextDouble() < 0.5 ? "male" : "female", FamilyName = obj.Parents[random.Next(obj.Parents.Length)].FamilyName, GivenName = LinqTestsCommon.RandomString(random, random.Next(MaxNameLength)), Grade = random.Next(MaxGrade) }; obj.Children[i].Pets = new List <Pet>(); for (int j = 0; j < random.Next(MaxPets); ++j) { obj.Children[i].Pets.Add(new Pet() { GivenName = random.NextDouble() < 0.5 ? LinqTestsCommon.RandomString(random, random.Next(MaxNameLength)) : "Fluffy" }); } obj.Children[i].Things = new Dictionary <string, string>(); for (int j = 0; j < random.Next(MaxThings) + 1; ++j) { obj.Children[i].Things.Add( j == 0 ? "A" : $"{j}-{random.Next().ToString()}", LinqTestsCommon.RandomString(random, random.Next(MaxThingStringLength))); } } obj.Records = new Logs { LogId = LinqTestsCommon.RandomString(random, random.Next(MaxNameLength)), Transactions = new Transaction[random.Next(MaxTransaction)] }; for (int i = 0; i < obj.Records.Transactions.Length; ++i) { var transaction = new Transaction() { Amount = random.Next(), Date = DateTime.Now.AddMinutes(random.Next(MaxTransactionMinuteRange)), Type = (TransactionType)(random.Next(MaxTransactionType)) }; obj.Records.Transactions[i] = transaction; } return(obj); } Func <bool, IQueryable <Family> > getQuery = LinqTestsCommon.GenerateTestCosmosData(createDataObj, Records, container); return(getQuery); }
/// <summary> /// Validate the results of CosmosDB query and the results of LinQ query on the original data /// Using Assert, will fail the unit test if the two results list are not SequenceEqual /// </summary> /// <param name="queryResults"></param> /// <param name="dataResults"></param> public static void ValidateResults(IQueryable queryResults, IQueryable dataResults) { // execution validation IEnumerator queryEnumerator = queryResults.GetEnumerator(); List <object> queryResultsList = new List <object>(); while (queryEnumerator.MoveNext()) { queryResultsList.Add(queryEnumerator.Current); } List <dynamic> dataResultsList = dataResults.Cast <dynamic>().ToList(); bool resultMatched = true; string actualStr = null; string expectedStr = null; if (dataResultsList.Count == 0 || queryResultsList.Count == 0) { resultMatched &= dataResultsList.Count == queryResultsList.Count; } else { dynamic firstElem = dataResultsList.FirstOrDefault(); if (firstElem is IEnumerable) { resultMatched &= CompareListOfArrays(queryResultsList, dataResultsList); } else if (LinqTestsCommon.IsAnonymousType(firstElem.GetType())) { resultMatched &= CompareListOfAnonymousType(queryResultsList, dataResultsList); } else if (LinqTestsCommon.IsNumber(firstElem)) { const double Epsilon = 1E-6; Type dataType = firstElem.GetType(); List <dynamic> dataSortedList = dataResultsList.OrderBy(x => x).ToList(); List <object> querySortedList = queryResultsList.OrderBy(x => x).ToList(); if (dataSortedList.Count != querySortedList.Count) { resultMatched = false; } else { for (int i = 0; i < dataSortedList.Count; ++i) { if (Math.Abs(dataSortedList[i] - (dynamic)querySortedList[i]) > (dynamic)Convert.ChangeType(Epsilon, dataType)) { resultMatched = false; break; } } } if (!resultMatched) { actualStr = JsonConvert.SerializeObject(querySortedList); expectedStr = JsonConvert.SerializeObject(dataSortedList); } } else { var dataNotQuery = dataResultsList.Except(queryResultsList).ToList(); var queryNotData = queryResultsList.Except(dataResultsList).ToList(); resultMatched &= !dataNotQuery.Any() && !queryNotData.Any(); } } string assertMsg = string.Empty; if (!resultMatched) { if (actualStr == null) { actualStr = JsonConvert.SerializeObject(queryResultsList); } if (expectedStr == null) { expectedStr = JsonConvert.SerializeObject(dataResultsList); } resultMatched |= actualStr.Equals(expectedStr); if (!resultMatched) { assertMsg = $"Expected: {expectedStr}, Actual: {actualStr}, RandomSeed: {LinqTestInput.RandomSeed}"; } } Assert.IsTrue(resultMatched, assertMsg); }
public void ValidateSQLTranslation() { int constInt = 2; int[] array = { 1, 2, 3 }; ParameterExpression paramx = Expression.Parameter(typeof(int), "x"); float floatValue = 5.23f; const int Records = 100; Func <Random, simple> createDataObj = (random) => { simple obj = new simple(); obj.x = random.Next(); obj.y = random.Next(); obj.id = Guid.NewGuid().ToString(); obj.pk = "Test"; return(obj); }; Func <bool, IQueryable <simple> > dataQuery = LinqTestsCommon.GenerateTestCosmosData <simple>(createDataObj, Records, testContainer); List <LinqTestInput> inputs = new List <LinqTestInput>(); inputs.Add(new LinqTestInput("Select cast float", b => dataQuery(b).Select(x => (int)floatValue))); inputs.Add(new LinqTestInput("Select identity", b => dataQuery(b).Select(x => x))); inputs.Add(new LinqTestInput("Select int expr", b => dataQuery(b).Select(x => (x.x % 10) + 2 + (x.x % 5)))); inputs.Add(new LinqTestInput("Select int expr w const", b => dataQuery(b).Select(x => x.x + constInt))); inputs.Add(new LinqTestInput("Select w new array", b => dataQuery(b).Select(d => new int[2] { d.x, d.x + 1 }))); inputs.Add(new LinqTestInput("Select new", b => dataQuery(b).Select(d => new { first = d.x, second = d.x }))); inputs.Add(new LinqTestInput("Select nested new", b => dataQuery(b).Select(d => new { first = d.x, second = new { third = d.x } }))); inputs.Add(new LinqTestInput("Filter int >", b => dataQuery(b).Where(x => x.x > 2))); inputs.Add(new LinqTestInput("Filter method >", b => dataQuery(b).Where(x => x.x > id(3)))); inputs.Add(new LinqTestInput("Filter int > -> Select int expr", b => dataQuery(b).Where(x => x.x > 2).Select(x => x.x + 2))); inputs.Add(new LinqTestInput("Select int expr -> Filter int >", b => dataQuery(b).Select(x => x.x + 2).Where(x => x > 2))); inputs.Add(new LinqTestInput("Filter int > -> Filter another field", b => dataQuery(b).Where(x => x.x > 2).Where(y => y.x < 4))); inputs.Add(new LinqTestInput("Filter x -> Filter y -> Select y expr", b => dataQuery(b).Where(x => x.x > 2).Where(y => y.x < 4).Select(y => y.x + y.x))); inputs.Add(new LinqTestInput("Select expr w const array", b => dataQuery(b).Select(x => x.x + array[2]))); inputs.Add(new LinqTestInput("Select const array index", b => dataQuery(b) .Where(x => x.x >= 0 && x.x < 3) .Select(x => new int[] { 1, 2, 3 }[x.x]))); inputs.Add(new LinqTestInput("Select new simple", b => dataQuery(b).Select(x => new simple { x = x.x, y = x.x }))); inputs.Add(new LinqTestInput("Select new nested", b => dataQuery(b).Select(x => new nested { s = new simple { x = x.x, y = x.x }, x = 2 }))); inputs.Add(new LinqTestInput("Select new complex", b => dataQuery(b).Select(d => new complex { dbl = 1.0, str = "", b = false, dblArray = new double[] { 1.0, 2.0, }, inside = new simple { x = d.x, y = d.x } }))); inputs.Add(new LinqTestInput("Select cast double x", b => dataQuery(b).Select(x => (double)x.x))); inputs.Add(new LinqTestInput("Select indexer x", b => dataQuery(b) .Where(x => x.x >= 0 && x.x < array.Length) .Select(x => array[x.x]))); inputs.Add(new LinqTestInput("Select new constructor", b => dataQuery(b).Select(x => new TimeSpan(x.x)))); inputs.Add(new LinqTestInput("Select method id", b => dataQuery(b).Select(x => id(x)))); inputs.Add(new LinqTestInput("Select identity", b => dataQuery(b).Select(x => x))); inputs.Add(new LinqTestInput("Select simple property", b => dataQuery(b).Select(x => x.x))); this.ExecuteTestSuite(inputs); }
internal static Func <bool, IQueryable <Family> > GenerateFamilyData( DocumentClient client, CosmosDatabaseSettings testDb, out CosmosContainerSettings testCollection) { // The test collection should have range index on string properties // for the orderby tests var newCol = new CosmosContainerSettings() { Id = Guid.NewGuid().ToString(), IndexingPolicy = new IndexingPolicy() { IncludedPaths = new System.Collections.ObjectModel.Collection <IncludedPath>() { new IncludedPath() { Path = "/*", Indexes = new System.Collections.ObjectModel.Collection <Index>() { Index.Range(DataType.Number, -1), Index.Range(DataType.String, -1) } } } } }; testCollection = client.CreateDocumentCollectionAsync(testDb, newCol).Result; const int Records = 100; const int MaxNameLength = 100; const int MaxThingStringLength = 50; const int MaxChild = 5; const int MaxPets = MaxChild; const int MaxThings = MaxChild; const int MaxGrade = 101; Func <Random, Family> createDataObj = random => { var obj = new Family(); obj.FamilyId = random.NextDouble() < 0.05 ? "some id" : Guid.NewGuid().ToString(); obj.IsRegistered = random.NextDouble() < 0.5; obj.NullableInt = random.NextDouble() < 0.5 ? (int?)random.Next() : null; obj.Int = random.NextDouble() < 0.5 ? 5 : random.Next(); obj.Parents = new Parent[random.Next(2) + 1]; for (int i = 0; i < obj.Parents.Length; ++i) { obj.Parents[i] = new Parent() { FamilyName = LinqTestsCommon.RandomString(random, random.Next(MaxNameLength)), GivenName = LinqTestsCommon.RandomString(random, random.Next(MaxNameLength)) }; } obj.Children = new Child[random.Next(MaxChild)]; for (int i = 0; i < obj.Children.Length; ++i) { obj.Children[i] = new Child() { Gender = random.NextDouble() < 0.5 ? "male" : "female", FamilyName = obj.Parents[random.Next(obj.Parents.Length)].FamilyName, GivenName = LinqTestsCommon.RandomString(random, random.Next(MaxNameLength)), Grade = random.Next(MaxGrade) }; obj.Children[i].Pets = new List <Pet>(); for (int j = 0; j < random.Next(MaxPets); ++j) { obj.Children[i].Pets.Add(new Pet() { GivenName = random.NextDouble() < 0.5 ? LinqTestsCommon.RandomString(random, random.Next(MaxNameLength)) : "Fluffy" }); } obj.Children[i].Things = new Dictionary <string, string>(); for (int j = 0; j < random.Next(MaxThings) + 1; ++j) { obj.Children[i].Things.Add( j == 0 ? "A" : $"{j}-{random.Next().ToString()}", LinqTestsCommon.RandomString(random, random.Next(MaxThingStringLength))); } } return(obj); }; Func <bool, IQueryable <Family> > getQuery = LinqTestsCommon.GenerateTestData(createDataObj, Records, client, testCollection); return(getQuery); }