public async Task <PropertyComparison> ExecuteAsync() { var typeToPackageProperties = new Dictionary <PackageSourceType, Dictionary <string, string> >(); foreach (var source in _packageSourceProvider.GetPackageSources()) { var result = await _client.PushPackageIfNotExistsAsync(source, _testData.PackageFullMetadata); if (result.PackageResult.Data == null) { throw new InvalidOperationException("The package was not pushed successfully."); } var metadata = await _client.GetMetadataAsync(source); typeToPackageProperties[source.Type] = GetPropertyDictionary(metadata, result.PackageResult.Data); } // Collect the data per property name across all sources. var actualValues = new Dictionary <string, Dictionary <string, HashSet <PackageSourceType> > >(); foreach (var type in typeToPackageProperties.Keys) { var packageProperties = typeToPackageProperties[type]; foreach (var pair in packageProperties) { Dictionary <string, HashSet <PackageSourceType> > valueToTypes; if (!actualValues.TryGetValue(pair.Key, out valueToTypes)) { valueToTypes = new Dictionary <string, HashSet <PackageSourceType> >(); actualValues[pair.Key] = valueToTypes; } HashSet <PackageSourceType> types; if (!valueToTypes.TryGetValue(pair.Value, out types)) { types = new HashSet <PackageSourceType>(); valueToTypes[pair.Value] = types; } types.Add(type); } } // Get the expected properties from the package itself. var originalPackage = await _packageReader.GetPackageAsync( _testData.PackageFullMetadata, listed : true, isAbsoluteLatestVersion : true, isLatestVersion : false); var originalPackageEntry = _mapper.GetPackageEntry(originalPackage); var expectedValues = GetPropertyDictionary(Metadata.Empty, originalPackageEntry); // Categorize the differences. var valuesSameAsSource = new Dictionary <string, KeyValuePair <string, HashSet <PackageSourceType> > >(); var valuesIntendedToBeDifferent = new Dictionary <string, Dictionary <string, HashSet <PackageSourceType> > >(); var valuesNotIntendedToBeDifferent = new Dictionary <string, Dictionary <string, HashSet <PackageSourceType> > >(); foreach (var propertyName in actualValues.Keys) { var propertyNameToValues = PropertiesIntendedToBeDifference.Contains(propertyName) ? valuesIntendedToBeDifferent : valuesNotIntendedToBeDifferent; string expectedValue; if (!expectedValues.TryGetValue(propertyName, out expectedValue)) { expectedValue = null; } var unsortedValueToTypes = actualValues[propertyName]; foreach (var actualValue in unsortedValueToTypes.Keys) { var types = unsortedValueToTypes[actualValue]; if (actualValue == expectedValue) { var pair = new KeyValuePair <string, HashSet <PackageSourceType> >(expectedValue, types); valuesSameAsSource[propertyName] = pair; } else { Dictionary <string, HashSet <PackageSourceType> > valueToTypes; if (!propertyNameToValues.TryGetValue(propertyName, out valueToTypes)) { valueToTypes = new Dictionary <string, HashSet <PackageSourceType> >(); propertyNameToValues[propertyName] = valueToTypes; } valueToTypes[actualValue] = types; } } } return(new PropertyComparison { ExpectedValues = expectedValues, ValuesSameAsSource = valuesSameAsSource, ValuesIntendedToBeDifferent = valuesIntendedToBeDifferent, ValuesNotIntendedToBeDifferent = valuesNotIntendedToBeDifferent, }); }