public void TestLocalEntityDeclarationDefinitionCopy()
        {
            var corpus = TestHelper.GetLocalCorpus("", nameof(TestLocalEntityDeclarationDefinitionCopy), noInputAndOutputFolder: true);
            var entity = new CdmLocalEntityDeclarationDefinition(corpus.Ctx, "name");

            var dataPartitionName               = "dataPartitionName";
            var dataPartitionPatternName        = "dataPartitionPatternName";
            var incrementalPartitionName        = "incrementalPartitionName";
            var incrementalPartitionPatternName = "incrementalPartitionPatternName";

            var dataPartition               = entity.DataPartitions.Add(dataPartitionName);
            var dataPartitionPattern        = entity.DataPartitionPatterns.Add(dataPartitionPatternName);
            var incrementalPartition        = entity.IncrementalPartitions.Add(incrementalPartitionName);
            var incrementalPartitionPattern = entity.IncrementalPartitionPatterns.Add(incrementalPartitionPatternName);

            var copy = entity.Copy() as CdmLocalEntityDeclarationDefinition;

            copy.DataPartitions[0].Name               = "newDataPartitionName";
            copy.DataPartitionPatterns[0].Name        = "newDataPartitionPatternName";
            copy.IncrementalPartitions[0].Name        = "newIncrementalPartition";
            copy.IncrementalPartitionPatterns[0].Name = "newIncrementalPartitionPatterns";

            Assert.AreEqual(dataPartitionName, dataPartition.Name);
            Assert.AreEqual(dataPartitionPatternName, dataPartitionPattern.Name);
            Assert.AreEqual(incrementalPartitionName, incrementalPartition.Name);
            Assert.AreEqual(incrementalPartitionPatternName, incrementalPartitionPattern.Name);
        }
Ejemplo n.º 2
0
        public async Task TestVariationsInRootLocation()
        {
            CdmCorpusDefinition   corpus   = TestHelper.GetLocalCorpus(testsSubpath, "TestVariationsInRootLocation");
            CdmManifestDefinition manifest = await corpus.FetchObjectAsync <CdmManifestDefinition>("pattern.manifest.cdm.json");

            await manifest.FileStatusCheckAsync();

            CdmLocalEntityDeclarationDefinition startsWithSlash = manifest.Entities[0] as CdmLocalEntityDeclarationDefinition;

            Assert.AreEqual(".*testfile.csv", startsWithSlash.DataPartitionPatterns[0].RegularExpression);
            Assert.AreEqual(1, startsWithSlash.DataPartitions.Count);
            Assert.AreEqual("/partitions/testfile.csv", startsWithSlash.DataPartitions[0].Location);

            CdmLocalEntityDeclarationDefinition endsWithSlash = manifest.Entities[1] as CdmLocalEntityDeclarationDefinition;

            Assert.AreEqual(".*testfile.csv", endsWithSlash.DataPartitionPatterns[0].RegularExpression);
            Assert.AreEqual(1, endsWithSlash.DataPartitions.Count);
            Assert.AreEqual("partitions/testfile.csv", endsWithSlash.DataPartitions[0].Location);

            CdmLocalEntityDeclarationDefinition noSlash = manifest.Entities[2] as CdmLocalEntityDeclarationDefinition;

            Assert.AreEqual(".*testfile.csv", noSlash.DataPartitionPatterns[0].RegularExpression);
            Assert.AreEqual(1, noSlash.DataPartitions.Count);
            Assert.AreEqual("partitions/testfile.csv", noSlash.DataPartitions[0].Location);
        }
Ejemplo n.º 3
0
        public static async Task <TableEntity> ToDataAsync(CdmLocalEntityDeclarationDefinition instance, CdmManifestDefinition manifest, string symsRootPath,
                                                           ResolveOptions resOpt, CopyOptions options)
        {
            TableEntity tableEntity = await DocumentPersistence.ToDataAsync(instance.EntityPath, manifest, instance.Ctx, resOpt, options);

            if (tableEntity != null)
            {
                TableProperties teProperties = (TableProperties)tableEntity.Properties;
                var             properties   = CreateTablePropertyBags(instance, resOpt, options, teProperties.Properties);

                if (instance.DataPartitions != null && instance.DataPartitions.Count > 0)
                {
                    List <string> paths = new List <string>();
                    foreach (var element in instance.DataPartitions)
                    {
                        if (element.Location != null)
                        {
                            var    adlsPath = instance.Ctx.Corpus.Storage.CorpusPathToAdapterPath(element.Location);
                            string location = element.Location;
                            if (adlsPath == null)
                            {
                                Logger.Error((ResolveContext)instance.Ctx, Tag, nameof(ToDataAsync), instance.AtCorpusPath, CdmLogCode.ErrPersistSymsAdlsAdapterMissing, element.Location);
                                return(null);
                            }
                            var symsPath = Utils.AdlsAdapterPathToSymsPath(adlsPath);
                            if (symsPath != null)
                            {
                                location = symsPath;
                            }
                            else
                            {
                                var pathTuple = StorageUtils.SplitNamespacePath(element.Location);
                                location = Utils.CreateSymsAbsolutePath(symsRootPath, pathTuple.Item2);
                            }

                            paths.Add(location);
                        }

                        teProperties.StorageDescriptor = DataPartitionPersistence.ToData(element, teProperties.StorageDescriptor, resOpt, options);
                    }

                    // Logic to find common root folder.
                    IEnumerable <string> samples = paths.ToArray();
                    teProperties.StorageDescriptor.Source.Location = new string(samples.First().Substring(0, samples.Min(s => s.Length))
                                                                                .TakeWhile((c, i) => samples.All(s => s[i] == c)).ToArray());
                }
                else
                {
                    // location and format is mandatory for syms.
                    teProperties.StorageDescriptor.Source.Location = Utils.CreateSymsAbsolutePath(symsRootPath, instance.EntityName);
                }

                teProperties.Properties = properties;
            }

            return(tableEntity);
        }
Ejemplo n.º 4
0
        public async Task TestGlobPathVariation()
        {
            CdmCorpusDefinition corpus = TestHelper.GetLocalCorpus(testsSubpath, "TestGlobPathVariation");

            CdmManifestDefinition manifest = await corpus.FetchObjectAsync <CdmManifestDefinition>("pattern.manifest.cdm.json");

            await manifest.FileStatusCheckAsync();

            int index = 0;
            CdmLocalEntityDeclarationDefinition noSlash = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(noSlash.DataPartitionPatterns[0].RootLocation, "/partitions");
            Assert.AreEqual(noSlash.DataPartitionPatterns[0].GlobPattern, "*.csv");
            Assert.AreEqual(noSlash.DataPartitions.Count, 1);
            Assert.AreEqual(noSlash.DataPartitions[0].Location, "/partitions/testfile.csv");
            index++;

            CdmLocalEntityDeclarationDefinition rootLocationSlash = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(rootLocationSlash.DataPartitionPatterns[0].RootLocation, "/partitions/");
            Assert.AreEqual(rootLocationSlash.DataPartitionPatterns[0].GlobPattern, "*.csv");
            Assert.AreEqual(rootLocationSlash.DataPartitions.Count, 1);
            Assert.AreEqual(rootLocationSlash.DataPartitions[0].Location, "/partitions/testfile.csv");
            index++;

            CdmLocalEntityDeclarationDefinition globPatternSlash = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(globPatternSlash.DataPartitionPatterns[0].RootLocation, "/partitions");
            Assert.AreEqual(globPatternSlash.DataPartitionPatterns[0].GlobPattern, "/*.csv");
            Assert.AreEqual(globPatternSlash.DataPartitions.Count, 1);
            Assert.AreEqual(globPatternSlash.DataPartitions[0].Location, "/partitions/testfile.csv");
            index++;

            CdmLocalEntityDeclarationDefinition bothSlash = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(bothSlash.DataPartitionPatterns[0].RootLocation, "/partitions/");
            Assert.AreEqual(bothSlash.DataPartitionPatterns[0].GlobPattern, "/*.csv");
            Assert.AreEqual(bothSlash.DataPartitions.Count, 1);
            Assert.AreEqual(bothSlash.DataPartitions[0].Location, "/partitions/testfile.csv");
            index++;

            CdmLocalEntityDeclarationDefinition noSlashOrStarAtStart = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(noSlashOrStarAtStart.DataPartitionPatterns[0].RootLocation, "/partitions/");
            Assert.AreEqual(noSlashOrStarAtStart.DataPartitionPatterns[0].GlobPattern, "t*.csv");
            Assert.AreEqual(noSlashOrStarAtStart.DataPartitions.Count, 1);
            Assert.AreEqual(noSlashOrStarAtStart.DataPartitions[0].Location, "/partitions/testfile.csv");
            index++;

            CdmLocalEntityDeclarationDefinition noSlashOrStarAndRootLocation = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(noSlashOrStarAndRootLocation.DataPartitionPatterns[0].RootLocation, "/partitions");
            Assert.AreEqual(noSlashOrStarAndRootLocation.DataPartitionPatterns[0].GlobPattern, "t*.csv");
            Assert.AreEqual(noSlashOrStarAndRootLocation.DataPartitions.Count, 1);
            Assert.AreEqual(noSlashOrStarAndRootLocation.DataPartitions[0].Location, "/partitions/testfile.csv");
        }
Ejemplo n.º 5
0
        private static IDictionary <string, JToken> CreateTablePropertyBags(CdmLocalEntityDeclarationDefinition instance, ResolveOptions resOpt, CopyOptions options, IDictionary <string, JToken> properties)
        {
            if (properties == null)
            {
                properties = new Dictionary <string, JToken>();
            }

            if (instance.EntityPath != null)
            {
                Tuple <string, string> pathTuple = StorageUtils.SplitNamespacePath(instance.EntityPath);
                if (pathTuple == null)
                {
                    Logger.Error((ResolveContext)instance.Ctx, Tag, nameof(ToDataAsync), instance.AtCorpusPath, CdmLogCode.ErrPersistSymsEntityPathNull, instance.EntityName);
                    return(null);
                }
                properties["cdm:entityPath"] = JToken.FromObject(pathTuple.Item2);
            }

            var t2pm          = new TraitToPropertyMap(instance);
            var isHiddenTrait = t2pm.FetchTraitReference("is.hidden");

            if (!properties.ContainsKey("cdm:description"))
            {
                properties["cdm:description"] = instance.Explanation;
            }

            if (instance.LastChildFileModifiedTime != null)
            {
                properties["cdm:lastChildFileModifiedTime"] = instance.LastChildFileModifiedTime;
            }

            if (instance.LastFileModifiedTime != null)
            {
                properties["cdm:lastFileModifiedTime"] = instance.LastFileModifiedTime;
            }

            if (instance.LastFileStatusCheckTime != null)
            {
                properties["cdm:lastFileStatusCheckTime"] = instance.LastFileStatusCheckTime;
            }

            if (isHiddenTrait != null)
            {
                properties["cdm:isHidden"] = true;
            }

            if (instance.ExhibitsTraits != null && instance.ExhibitsTraits.Count > 0)
            {
                properties["cdm:entityDecTraits"] = JToken.FromObject(Utils.ListCopyData <TraitReferenceDefinition>(resOpt, instance.ExhibitsTraits, options),
                                                                      new JsonSerializer {
                    NullValueHandling = NullValueHandling.Ignore, ContractResolver = new CamelCasePropertyNamesContractResolver()
                });
            }

            return(properties);
        }
Ejemplo n.º 6
0
 /// <summary>
 /// Check if entity added or modified.
 /// </summary>
 internal static bool IsEntityAddedOrModified(CdmLocalEntityDeclarationDefinition entity, IDictionary <string, TableEntity> existingSymsTables)
 {
     if (existingSymsTables == null || existingSymsTables.Count == 0 || !existingSymsTables.ContainsKey(entity.EntityName))
     {
         return(true);
     }
     if (entity.LastFileModifiedTime != null && (entity.LastFileModifiedOldTime != null && entity.LastFileModifiedOldTime < entity.LastFileModifiedTime))
     {
         return(true);
     }
     return(false);
 }
Ejemplo n.º 7
0
        public static async Task <LocalEntity> ToData(CdmLocalEntityDeclarationDefinition instance, CdmManifestDefinition manifest, ResolveOptions resOpt, CopyOptions options)
        {
            var localEntity = await DocumentPersistence.ToData(instance.EntityPath, manifest, resOpt, options, instance.Ctx);

            if (localEntity != null)
            {
                var t2pm          = new TraitToPropertyMap(instance);
                var isHiddenTrait = t2pm.FetchTraitReference("is.hidden");

                if (localEntity.Description == null)
                {
                    localEntity.Description = instance.Explanation;
                }
                localEntity.LastChildFileModifiedTime = instance.LastChildFileModifiedTime;
                localEntity.LastFileModifiedTime      = instance.LastFileModifiedTime;
                localEntity.LastFileStatusCheckTime   = instance.LastFileStatusCheckTime;

                if (isHiddenTrait != null)
                {
                    localEntity.IsHidden = true;
                }

                if (t2pm.FetchPropertyValue("cdmSchemas") is List <string> schemas)
                {
                    localEntity.Schemas = schemas;
                }

                if (instance.DataPartitions != null && instance.DataPartitions.Count > 0)
                {
                    localEntity.Partitions = new List <Partition>();

                    foreach (var element in instance.DataPartitions)
                    {
                        var partition = await DataPartitionPersistence.ToData(element, resOpt, options);

                        if (partition != null)
                        {
                            localEntity.Partitions.Add(partition);
                        }
                        else
                        {
                            Logger.Error((ResolveContext)instance.Ctx, Tag, nameof(ToData), instance.AtCorpusPath, CdmLogCode.ErrPersistModelJsonEntityPartitionConversionError);
                            return(null);
                        }
                    }
                }
            }

            return(localEntity);
        }
        private static Func <dynamic, bool> ensureIncremental(CdmLocalEntityDeclarationDefinition instance)
        {
            bool compare(dynamic obj)
            {
                if ((obj is CdmDataPartitionDefinition && !(obj as CdmDataPartitionDefinition).IsIncremental) ||
                    (obj is CdmDataPartitionPatternDefinition && !(obj as CdmDataPartitionPatternDefinition).IsIncremental))
                {
                    ErrorMessage(instance.Ctx, nameof(ToData), instance.AtCorpusPath, obj, false);
                    return(false);
                }
                return(true);
            }

            return(compare);
        }
        public static async Task <LocalEntity> ToData(CdmLocalEntityDeclarationDefinition instance, ResolveOptions resOpt, CopyOptions options)
        {
            var localEntity = await DocumentPersistence.ToData(instance.EntityPath, resOpt, options, instance.Ctx);

            if (localEntity != null)
            {
                var t2pm          = new TraitToPropertyMap(instance);
                var isHiddenTrait = t2pm.FetchTraitReference("is.hidden");

                localEntity.Description = instance.Explanation;
                localEntity.LastChildFileModifiedTime = instance.LastChildFileModifiedTime;
                localEntity.LastFileModifiedTime      = instance.LastFileModifiedTime;
                localEntity.LastFileStatusCheckTime   = instance.LastFileStatusCheckTime;

                if (isHiddenTrait != null)
                {
                    localEntity.IsHidden = true;
                }

                if (t2pm.FetchPropertyValue("cdmSchemas") is List <string> schemas)
                {
                    localEntity.Schemas = schemas;
                }

                if (instance.DataPartitions != null && instance.DataPartitions.Count > 0)
                {
                    localEntity.Partitions = new List <Partition>();

                    foreach (var element in instance.DataPartitions)
                    {
                        var partition = await DataPartitionPersistence.ToData(element, resOpt, options);

                        if (partition != null)
                        {
                            localEntity.Partitions.Add(partition);
                        }
                        else
                        {
                            Logger.Error(nameof(LocalEntityDeclarationPersistence), instance.Ctx, "There was an error while trying to convert cdm data partition to model.json partition.");
                            return(null);
                        }
                    }
                }
            }

            return(localEntity);
        }
Ejemplo n.º 10
0
        public void TestCdmCollectionAddPopulatesInDocumentWithVisit()
        {
            var manifest = CdmCollectionHelperFunctions.GenerateManifest("C:\\Nothing");

            var entityReference = new CdmLocalEntityDeclarationDefinition(manifest.Ctx, "entityName");

            var trait = entityReference.ExhibitsTraits.Add("theTrait");

            var argument = trait.Arguments.Add("GreatArgumentName", "GreatValue");

            manifest.Entities.Add(entityReference);

            Assert.AreEqual(manifest, manifest.InDocument);
            Assert.AreEqual(manifest, entityReference.InDocument);
            Assert.AreEqual(manifest, trait.InDocument);
            Assert.AreEqual(manifest, argument.InDocument);
        }
Ejemplo n.º 11
0
        public static EntityDeclarationDefinition ToData(CdmLocalEntityDeclarationDefinition instance, ResolveOptions resOpt, CopyOptions options)
        {
            var result = new EntityDeclarationDefinition
            {
                Type                      = EntityDeclarationDefinitionType.LocalEntity,
                EntityName                = instance.EntityName,
                Explanation               = instance.Explanation,
                ExhibitsTraits            = Utils.ListCopyData(resOpt, instance.ExhibitsTraits, options),
                LastFileStatusCheckTime   = TimeUtils.GetFormattedDateString(instance.LastFileStatusCheckTime),
                LastFileModifiedTime      = TimeUtils.GetFormattedDateString(instance.LastFileModifiedTime),
                LastChildFileModifiedTime = TimeUtils.GetFormattedDateString(instance.LastChildFileModifiedTime),
                EntityPath                = instance.EntityPath,
                DataPartitions            = Utils.ListCopyData <DataPartition>(resOpt, instance.DataPartitions, options),
                DataPartitionPatterns     = Utils.ListCopyData <DataPartitionPattern>(resOpt, instance.DataPartitionPatterns, options)
            };

            return(result);
        }
Ejemplo n.º 12
0
        public async Task TestPartitionPatternWithGlob()
        {
            CdmCorpusDefinition corpus = TestHelper.GetLocalCorpus(testsSubpath, "TestPartitionPatternWithGlob");

            int patternWithGlobAndRegex = 0;

            corpus.SetEventCallback(new EventCallback
            {
                Invoke = (CdmStatusLevel statusLevel, string message) =>
                {
                    if (message.Contains("CdmDataPartitionPatternDefinition | The Data Partition Pattern contains both a glob pattern (/testfile.csv) and a regular expression (/subFolder/testSubFile.csv) set, the glob pattern will be used. | FileStatusCheckAsync"))
                    {
                        patternWithGlobAndRegex++;
                    }
                }
            }, CdmStatusLevel.Warning);

            CdmManifestDefinition manifest = await corpus.FetchObjectAsync <CdmManifestDefinition>("pattern.manifest.cdm.json");

            await manifest.FileStatusCheckAsync();

            // one pattern object contains both glob and regex
            Assert.AreEqual(1, patternWithGlobAndRegex);

            int index = 0;
            // make sure '.' in glob is not converted to '.' in regex
            CdmLocalEntityDeclarationDefinition dotIsEscaped = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(dotIsEscaped.DataPartitionPatterns[0].GlobPattern, "test.ile.csv");
            Assert.AreEqual(dotIsEscaped.DataPartitions.Count, 0);
            index++;

            // star pattern should match anything in the root folder
            CdmLocalEntityDeclarationDefinition onlyStar = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(onlyStar.DataPartitionPatterns[0].GlobPattern, "*");
            Assert.AreEqual(onlyStar.DataPartitions.Count, 1);
            Assert.AreEqual(onlyStar.DataPartitions[0].Location, "/partitions/testfile.csv");
            index++;

            // star can match nothing
            CdmLocalEntityDeclarationDefinition starNoMatch = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(starNoMatch.DataPartitionPatterns[0].GlobPattern, "/testfile*.csv");
            Assert.AreEqual(starNoMatch.DataPartitions.Count, 1);
            Assert.AreEqual(starNoMatch.DataPartitions[0].Location, "/partitions/testfile.csv");
            index++;

            // star at root level
            // this should match any files at root level, none in subfolders
            CdmLocalEntityDeclarationDefinition starAtRoot = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(starAtRoot.DataPartitionPatterns[0].GlobPattern, "/*.csv");
            Assert.AreEqual(starAtRoot.DataPartitions.Count, 1);
            Assert.AreEqual(starAtRoot.DataPartitions[0].Location, "/partitions/testfile.csv");
            index++;

            // star at deeper level
            CdmLocalEntityDeclarationDefinition starAtDeeperLevel = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(starAtDeeperLevel.DataPartitionPatterns[0].GlobPattern, "/*/*.csv");
            Assert.AreEqual(starAtDeeperLevel.DataPartitions.Count, 1);
            Assert.AreEqual(starAtDeeperLevel.DataPartitions[0].Location, "/partitions/subFolder/testSubFile.csv");
            index++;

            // pattern that ends with star
            CdmLocalEntityDeclarationDefinition endsWithStar = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(endsWithStar.DataPartitionPatterns[0].GlobPattern, "/testfile*");
            Assert.AreEqual(endsWithStar.DataPartitions.Count, 1);
            Assert.AreEqual(endsWithStar.DataPartitions[0].Location, "/partitions/testfile.csv");
            index++;

            // globstar (**) on its own matches
            CdmLocalEntityDeclarationDefinition globStar = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(globStar.DataPartitionPatterns[0].GlobPattern, "**");
            Assert.AreEqual(2, globStar.DataPartitions.Count);
            Assert.AreEqual(1, globStar.DataPartitions.Where(x =>
                                                             x.Location == "/partitions/testfile.csv"
                                                             ).ToList().Count);
            Assert.AreEqual(1, globStar.DataPartitions.Where(x =>
                                                             x.Location == "/partitions/subFolder/testSubFile.csv"
                                                             ).ToList().Count);
            index++;

            // globstar at the beginning of the pattern
            CdmLocalEntityDeclarationDefinition beginsWithGlobstar = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(beginsWithGlobstar.DataPartitionPatterns[0].GlobPattern, "/**.csv");
            Assert.AreEqual(1, beginsWithGlobstar.DataPartitions.Count);
            Assert.AreEqual(beginsWithGlobstar.DataPartitions[0].Location, "/partitions/testfile.csv");
            index++;

            // globstar at the end of the pattern
            CdmLocalEntityDeclarationDefinition endsWithGlobstar = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(endsWithGlobstar.DataPartitionPatterns[0].GlobPattern, "/**");
            Assert.AreEqual(endsWithGlobstar.DataPartitions.Count, 2);
            Assert.AreEqual(1, endsWithGlobstar.DataPartitions.Where(x =>
                                                                     x.Location == "/partitions/testfile.csv"
                                                                     ).ToList().Count);
            Assert.AreEqual(1, endsWithGlobstar.DataPartitions.Where(x =>
                                                                     x.Location == "/partitions/subFolder/testSubFile.csv"
                                                                     ).ToList().Count);
            index++;

            // globstar matches zero or more folders
            CdmLocalEntityDeclarationDefinition zeroOrMoreFolders = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(zeroOrMoreFolders.DataPartitionPatterns[0].GlobPattern, "/**/*.csv");
            Assert.AreEqual(2, zeroOrMoreFolders.DataPartitions.Count);
            Assert.AreEqual(1, zeroOrMoreFolders.DataPartitions.Where(x =>
                                                                      x.Location == "/partitions/testfile.csv"
                                                                      ).ToList().Count);
            Assert.AreEqual(1, zeroOrMoreFolders.DataPartitions.Where(x =>
                                                                      x.Location == "/partitions/subFolder/testSubFile.csv"
                                                                      ).ToList().Count);
            index++;

            // globstar matches zero or more folders without starting slash
            CdmLocalEntityDeclarationDefinition zeroOrMoreNoStartingSlash = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(zeroOrMoreNoStartingSlash.DataPartitionPatterns[0].GlobPattern, "/**/*.csv");
            Assert.AreEqual(2, zeroOrMoreNoStartingSlash.DataPartitions.Count);
            Assert.AreEqual(1, zeroOrMoreNoStartingSlash.DataPartitions.Where(x =>
                                                                              x.Location == "/partitions/testfile.csv"
                                                                              ).ToList().Count);
            Assert.AreEqual(1, zeroOrMoreNoStartingSlash.DataPartitions.Where(x =>
                                                                              x.Location == "/partitions/subFolder/testSubFile.csv"
                                                                              ).ToList().Count);
            index++;

            // question mark in the middle of a pattern
            CdmLocalEntityDeclarationDefinition questionMark = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(questionMark.DataPartitionPatterns[0].GlobPattern, "/test?ile.csv");
            Assert.AreEqual(1, questionMark.DataPartitions.Count);
            Assert.AreEqual(questionMark.DataPartitions[0].Location, "/partitions/testfile.csv");
            index++;

            // question mark at the beginning of a pattern
            CdmLocalEntityDeclarationDefinition beginsWithQuestionMark = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(beginsWithQuestionMark.DataPartitionPatterns[0].GlobPattern, "/?estfile.csv");
            Assert.AreEqual(1, beginsWithQuestionMark.DataPartitions.Count);
            Assert.AreEqual(beginsWithQuestionMark.DataPartitions[0].Location, "/partitions/testfile.csv");
            index++;

            // question mark at the end of a pattern
            CdmLocalEntityDeclarationDefinition endsWithQuestionMark = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(endsWithQuestionMark.DataPartitionPatterns[0].GlobPattern, "/testfile.cs?");
            Assert.AreEqual(1, endsWithQuestionMark.DataPartitions.Count);
            Assert.AreEqual(endsWithQuestionMark.DataPartitions[0].Location, "/partitions/testfile.csv");
            index++;

            // backslash in glob can match slash
            CdmLocalEntityDeclarationDefinition backslashInPattern = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(backslashInPattern.DataPartitionPatterns[0].GlobPattern, "\\testfile.csv");
            Assert.AreEqual(1, backslashInPattern.DataPartitions.Count);
            Assert.AreEqual(backslashInPattern.DataPartitions[0].Location, "/partitions/testfile.csv");
            index++;

            // pattern object includes glob pattern and regular expression
            CdmLocalEntityDeclarationDefinition globAndRegex = (CdmLocalEntityDeclarationDefinition)manifest.Entities[index];

            Assert.AreEqual(globAndRegex.DataPartitionPatterns[0].GlobPattern, "/testfile.csv");
            Assert.AreEqual(globAndRegex.DataPartitionPatterns[0].RegularExpression, "/subFolder/testSubFile.csv");
            Assert.AreEqual(1, globAndRegex.DataPartitions.Count);
            // matching this file means the glob pattern was (correctly) used
            Assert.AreEqual(globAndRegex.DataPartitions[0].Location, "/partitions/testfile.csv");
        }