public void GetToolsetDataFromConfiguration_SectionNotRegisteredInConfigFile() { ToolsetConfigurationReaderTestHelper.WriteConfigFile(@" <configuration> <configSections> </configSections> <msbuildToolsets> <toolset toolsVersion=""2.0""> <property name=""MSBuildBinPath"" value=""D:\windows\Microsoft.NET\Framework\v2.0.x86ret\""/> </toolset> </msbuildToolsets> </configuration>"); ToolsetReader reader = new ToolsetConfigurationReader(new ReadApplicationConfiguration( ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest)); ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None)); string defaultToolsVersion = reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), true); Assertion.AssertEquals(null, defaultToolsVersion); Assertion.AssertEquals(0, values.Count); }
public void GetToolsetDataFromConfiguration_Basic() { ToolsetConfigurationReaderTestHelper.WriteConfigFile(@" <configuration> <configSections> <section name=""msbuildToolsets"" type=""Microsoft.Build.BuildEngine.ToolsetConfigurationSection, Microsoft.Build.Engine"" /> </configSections> <msbuildToolsets default=""2.0""> <toolset toolsVersion=""2.0""> <property name=""MSBuildBinPath"" value=""D:\windows\Microsoft.NET\Framework\v2.0.x86ret\""/> </toolset> <toolset toolsVersion=""3.5""> <property name=""MSBuildBinPath"" value=""D:\windows\Microsoft.NET\Framework\v3.5.x86ret\""/> </toolset> </msbuildToolsets> </configuration>"); ToolsetReader reader = new ToolsetConfigurationReader(new ReadApplicationConfiguration( ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest)); ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None)); string defaultToolsVersion = reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), true); Assertion.AssertEquals("2.0", defaultToolsVersion); Assertion.AssertEquals(2, values.Count); Assertion.AssertEquals(0, values["2.0"].BuildProperties.Count); Assertion.AssertEquals(@"D:\windows\Microsoft.NET\Framework\v2.0.x86ret", values["2.0"].ToolsPath); Assertion.AssertEquals(0, values["3.5"].BuildProperties.Count); Assertion.AssertEquals(@"D:\windows\Microsoft.NET\Framework\v3.5.x86ret", values["3.5"].ToolsPath); }
public void GetToolsetDataFromConfiguration_XmlEscapedCharacters() { ToolsetConfigurationReaderTestHelper.WriteConfigFile(@" <configuration> <configSections> <section name=""msbuildToolsets"" type=""Microsoft.Build.BuildEngine.ToolsetConfigurationSection, Microsoft.Build.Engine"" /> </configSections> <msbuildToolsets default=""2>.0""> <toolset toolsVersion=""2>.0""> <property name=""MSBuildBinPath"" value=""x""/> <property name=""foo"" value=""some>value""/> </toolset> </msbuildToolsets> </configuration>"); ToolsetReader reader = new ToolsetConfigurationReader(new ReadApplicationConfiguration( ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest)); ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None)); string defaultToolsVersion = reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), true); Assertion.AssertEquals("2>.0", defaultToolsVersion); Assertion.AssertEquals(1, values.Count); Assertion.AssertEquals(@"some>value", values["2>.0"].BuildProperties["foo"].Value); }
public void GetToolsetDataFromConfiguration_PropertyValueIsEmptyString1() { ToolsetConfigurationReaderTestHelper.WriteConfigFile(@" <configuration> <configSections> <section name=""msbuildToolsets"" type=""Microsoft.Build.BuildEngine.ToolsetConfigurationSection, Microsoft.Build.Engine"" /> </configSections> <msbuildToolsets default=""2.0""> <toolset toolsVersion=""2.0""> <property name=""MSBuildBinPath"" value=""""/> </toolset> </msbuildToolsets> </configuration>"); ToolsetReader reader = new ToolsetConfigurationReader(new ReadApplicationConfiguration( ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest)); ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None)); string defaultToolsVersion = reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), true); Assertion.AssertEquals(1, values.Count); Assertion.AssertEquals(0, values["2.0"].BuildProperties.Count); Assertion.AssertEquals(String.Empty, values["2.0"].ToolsPath); }
public void GetToolsetDataFromConfiguration_ToolsPathAndBinPathDiffer() { ToolsetConfigurationReaderTestHelper.WriteConfigFile(@" <configuration> <configSections> <section name=""msbuildToolsets"" type=""Microsoft.Build.BuildEngine.ToolsetConfigurationSection, Microsoft.Build.Engine"" /> </configSections> <msbuildToolsets default=""2.0""> <toolset toolsVersion=""2.0""> <property name=""MSBuildBinPath"" value=""D:\windows\Microsoft.NET\Framework\v2.0.x86ret\""/> <property name=""MSBuildToolsPath"" value=""D:\windows\Microsoft.NET\Framework\v3.5.x86ret\""/> </toolset> </msbuildToolsets> </configuration>"); ToolsetReader reader = new ToolsetConfigurationReader(new ReadApplicationConfiguration( ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest)); ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None)); //this should throw ... bool caught = false; try { reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), true); } catch (InvalidToolsetDefinitionException) { caught = true; } Assertion.Assert(caught); }
public void InvalidPropertyNameInConfigFile() { ToolsetConfigurationReaderTestHelper.WriteConfigFile(@" <configuration> <configSections> <section name=""msbuildToolsets"" type=""Microsoft.Build.BuildEngine.ToolsetConfigurationSection, Microsoft.Build.Engine"" /> </configSections> <msbuildToolsets default=""2.0""> <toolset toolsVersion=""2.0""> <property name=""MSBuildBinPath"" value=""D:\windows\Microsoft.NET\Framework\v2.0.x86ret\""/> <property name=""&"" value=""foo""/> </toolset> </msbuildToolsets> </configuration>"); ToolsetReader reader = new ToolsetConfigurationReader(new ReadApplicationConfiguration( ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest)); ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None)); //this should throw ... reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), true); }
public void GetToolsetDataFromConfiguration_EmptyMSBuildToolsetsNode() { ToolsetConfigurationReaderTestHelper.WriteConfigFile(@" <configuration> <configSections> <section name=""msbuildToolsets"" type=""Microsoft.Build.BuildEngine.ToolsetConfigurationSection, Microsoft.Build.Engine"" /> </configSections> <msbuildToolsets/> </configuration>"); ToolsetReader reader = new ToolsetConfigurationReader(new ReadApplicationConfiguration( ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest)); ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None)); string defaultToolsVersion = reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), true); Assertion.AssertEquals(null, defaultToolsVersion); Assertion.AssertEquals(0, values.Count); }
public void GetToolsetDataFromConfiguration_OnlyDefaultSpecified() { ToolsetConfigurationReaderTestHelper.WriteConfigFile(@" <configuration> <configSections> <section name=""msbuildToolsets"" type=""Microsoft.Build.BuildEngine.ToolsetConfigurationSection, Microsoft.Build.Engine"" /> </configSections> <msbuildToolsets default=""2.0""/> </configuration>"); ToolsetReader reader = new ToolsetConfigurationReader(new ReadApplicationConfiguration( ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest)); ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None)); reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), true); }
public void GetToolsetDataFromConfiguration_ConfigurationErrorsExceptionThrown() { ToolsetConfigurationReaderTestHelper.WriteConfigFile(@"", new ConfigurationErrorsException()); ToolsetReader reader = new ToolsetConfigurationReader(new ReadApplicationConfiguration( ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest)); ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None)); // this should throw ... reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), true); }
public void GetToolsetDataFromConfiguration_DefaultToolsetUndefined() { ToolsetConfigurationReaderTestHelper.WriteConfigFile(@" <configuration> <configSections> <section name=""msbuildToolsets"" type=""Microsoft.Build.BuildEngine.ToolsetConfigurationSection, Microsoft.Build.Engine"" /> </configSections> <msbuildToolsets default=""nonexistent""> <toolset toolsVersion=""2.0""> <property name=""MSBuildBinPath"" value=""D:\windows\Microsoft.NET\Framework\v2.0.x86ret\""/> </toolset> </msbuildToolsets> </configuration>"); ToolsetReader reader = new ToolsetConfigurationReader(new ReadApplicationConfiguration( ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest)); ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None)); // Does not throw reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), true); }
public void GetToolsetDataFromConfiguration_FileEmpty() { ToolsetConfigurationReaderTestHelper.WriteConfigFile(@""); ToolsetReader reader = new ToolsetConfigurationReader(new ReadApplicationConfiguration( ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest)); ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None)); reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), true); }
public void InvalidRelativePath() { string invalidRelativePath = @"..\|invalid|"; ToolsetConfigurationReaderTestHelper.WriteConfigFile(@" <configuration> <configSections> <section name=""msbuildToolsets"" type=""Microsoft.Build.BuildEngine.ToolsetConfigurationSection, Microsoft.Build.Engine"" /> </configSections> <msbuildToolsets default=""2.0""> <toolset toolsVersion=""2.0""> <property name=""MSBuildBinPath"" value=""" + invalidRelativePath + @"""/> </toolset> </msbuildToolsets> </configuration>"); ToolsetReader reader = new ToolsetConfigurationReader(new ReadApplicationConfiguration( ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest)); ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None)); reader.ReadToolsets(values, new BuildPropertyGroup(), new BuildPropertyGroup(), true); // Don't crash (consistent with invalid absolute path) Assertion.AssertEquals(invalidRelativePath, values["2.0"].ToolsPath); }
public void RelativePathInValue() { ToolsetConfigurationReaderTestHelper.WriteConfigFile(@" <configuration> <configSections> <section name=""msbuildToolsets"" type=""Microsoft.Build.BuildEngine.ToolsetConfigurationSection, Microsoft.Build.Engine"" /> </configSections> <msbuildToolsets default=""2.0""> <toolset toolsVersion=""2.0""> <property name=""MSBuildToolsPath"" value=""..\foo""/> <!-- derelativization occurs before comparing toolspath and binpath --> <property name=""MSBuildBinPath"" value=""..\.\foo""/> </toolset> <toolset toolsVersion=""3.0""> <!-- properties are expanded before derelativization--> <property name=""MSBuildBinPath"" value=""$(DotDotSlash)bar""/> </toolset> </msbuildToolsets> </configuration>"); ToolsetReader reader = new ToolsetConfigurationReader(new ReadApplicationConfiguration( ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest)); ToolsetCollection values = new ToolsetCollection(new Engine(ToolsetDefinitionLocations.None)); BuildPropertyGroup pg = new BuildPropertyGroup(); pg.SetProperty("DotDotSlash", @"..\"); reader.ReadToolsets(values, new BuildPropertyGroup(), pg, true); string expected1 = Path.GetFullPath(Path.Combine(FileUtilities.CurrentExecutableDirectory, @"..\foo")); string expected2 = Path.GetFullPath(Path.Combine(FileUtilities.CurrentExecutableDirectory, @"..\bar")); Console.WriteLine(values["2.0"].ToolsPath); Assertion.AssertEquals(expected1, values["2.0"].ToolsPath); Assertion.AssertEquals(expected2, values["3.0"].ToolsPath); }
/// <summary> /// Gathers toolset data from the registry and configuration file, if any. /// NOTE: this method is internal for unit testing purposes only. /// </summary> /// <param name="toolsets"></param> /// <param name="registryReader"></param> /// <param name="configurationReader"></param> /// <param name="globalProperties"></param> /// <param name="initialProperties"></param> /// <param name="locations"></param> /// <returns></returns> internal static string ReadAllToolsets(ToolsetCollection toolsets, ToolsetRegistryReader registryReader, ToolsetConfigurationReader configurationReader, BuildPropertyGroup globalProperties, BuildPropertyGroup initialProperties, ToolsetDefinitionLocations locations) { // The 2.0 .NET Framework installer did not write a ToolsVersion key for itself in the registry. // The 3.5 installer writes one for 2.0, but 3.5 might not be installed. // The 4.0 and subsequent installers can't keep writing the 2.0 one, because (a) it causes SxS issues and (b) we // don't want it unless 2.0 is installed. // So if the 2.0 framework is actually installed, and we're reading the registry, create a toolset for it. // The registry and config file can overwrite it. if ( ((locations & ToolsetDefinitionLocations.Registry) != 0) && !toolsets.Contains("2.0") && FrameworkLocationHelper.PathToDotNetFrameworkV20 != null ) { Toolset synthetic20Toolset = new Toolset("2.0", FrameworkLocationHelper.PathToDotNetFrameworkV20, initialProperties); toolsets.Add(synthetic20Toolset); } // The ordering here is important because the configuration file should have greater precedence // than the registry string defaultToolsVersionFromRegistry = null; ToolsetRegistryReader registryReaderToUse = null; if ((locations & ToolsetDefinitionLocations.Registry) == ToolsetDefinitionLocations.Registry) { registryReaderToUse = registryReader ?? new ToolsetRegistryReader(); // We do not accumulate properties when reading them from the registry, because the order // in which values are returned to us is essentially random: so we disallow one property // in the registry to refer to another also in the registry defaultToolsVersionFromRegistry = registryReaderToUse.ReadToolsets(toolsets, globalProperties, initialProperties, false /* do not accumulate properties */); } string defaultToolsVersionFromConfiguration = null; ToolsetConfigurationReader configurationReaderToUse = null; if ((locations & ToolsetDefinitionLocations.ConfigurationFile) == ToolsetDefinitionLocations.ConfigurationFile) { if (configurationReader == null && ConfigurationFileMayHaveToolsets()) { // We haven't been passed in a fake configuration reader by a unit test, // and it looks like we have a .config file to read, so create a real // configuration reader configurationReader = new ToolsetConfigurationReader(); } if (configurationReader != null) { configurationReaderToUse = configurationReader ?? new ToolsetConfigurationReader(); // Accumulation of properties is okay in the config file because it's deterministically ordered defaultToolsVersionFromConfiguration = configurationReaderToUse.ReadToolsets(toolsets, globalProperties, initialProperties, true /* accumulate properties */); } } // We'll use the default from the configuration file if it was specified, otherwise we'll try // the one from the registry. It's possible (and valid) that neither the configuration file // nor the registry specify a default, in which case we'll just return null. string defaultToolsVersion = defaultToolsVersionFromConfiguration ?? defaultToolsVersionFromRegistry; // If we got a default version from the registry or config file, and it // actually exists, fine. // Otherwise we have to come up with one. if (defaultToolsVersion == null || !toolsets.Contains(defaultToolsVersion)) { // We're going to choose a hard coded default tools version of 2.0. defaultToolsVersion = Constants.defaultToolsVersion; // But don't overwrite any existing tools path for this default we're choosing. if (!toolsets.Contains(Constants.defaultToolsVersion)) { // There's no tools path already for 2.0, so use the path to the v2.0 .NET Framework. // If an old-fashioned caller sets BinPath property, or passed a BinPath to the constructor, // that will overwrite what we're setting here. ErrorUtilities.VerifyThrow(Constants.defaultToolsVersion == "2.0", "Getting 2.0 FX path so default should be 2.0"); string pathToFramework = FrameworkLocationHelper.PathToDotNetFrameworkV20; // We could not find the default toolsversion because it was not installed on the machine. Fallback to the // one we expect to always be there when running msbuild 4.0. if (pathToFramework == null) { pathToFramework = FrameworkLocationHelper.PathToDotNetFrameworkV40; defaultToolsVersion = Constants.defaultFallbackToolsVersion; } // Again don't overwrite any existing tools path for this default we're choosing. if (!toolsets.Contains(defaultToolsVersion)) { Toolset defaultToolset = new Toolset(defaultToolsVersion, pathToFramework, initialProperties); toolsets.Add(defaultToolset); } } } return(defaultToolsVersion); }
/// <summary> /// Gathers toolset data from the registry and configuration file, if any. /// NOTE: this method is internal for unit testing purposes only. /// </summary> /// <param name="toolsets"></param> /// <param name="registryReader"></param> /// <param name="configurationReader"></param> /// <param name="globalProperties"></param> /// <param name="initialProperties"></param> /// <param name="locations"></param> /// <returns></returns> internal static string ReadAllToolsets(ToolsetCollection toolsets, ToolsetRegistryReader registryReader, ToolsetConfigurationReader configurationReader, BuildPropertyGroup globalProperties, BuildPropertyGroup initialProperties, ToolsetDefinitionLocations locations) { // The 2.0 .NET Framework installer did not write a ToolsVersion key for itself in the registry. // The 3.5 installer writes one for 2.0, but 3.5 might not be installed. // The 4.0 and subsequent installers can't keep writing the 2.0 one, because (a) it causes SxS issues and (b) we // don't want it unless 2.0 is installed. // So if the 2.0 framework is actually installed, and we're reading the registry, create a toolset for it. // The registry and config file can overwrite it. if ( ((locations & ToolsetDefinitionLocations.Registry) != 0) && !toolsets.Contains("2.0") && FrameworkLocationHelper.PathToDotNetFrameworkV20 != null ) { Toolset synthetic20Toolset = new Toolset("2.0", FrameworkLocationHelper.PathToDotNetFrameworkV20, initialProperties); toolsets.Add(synthetic20Toolset); } // The ordering here is important because the configuration file should have greater precedence // than the registry string defaultToolsVersionFromRegistry = null; ToolsetRegistryReader registryReaderToUse = null; if ((locations & ToolsetDefinitionLocations.Registry) == ToolsetDefinitionLocations.Registry) { registryReaderToUse = registryReader == null ? new ToolsetRegistryReader() : registryReader; // We do not accumulate properties when reading them from the registry, because the order // in which values are returned to us is essentially random: so we disallow one property // in the registry to refer to another also in the registry defaultToolsVersionFromRegistry = registryReaderToUse.ReadToolsets(toolsets, globalProperties, initialProperties, false /* do not accumulate properties */); } string defaultToolsVersionFromConfiguration = null; ToolsetConfigurationReader configurationReaderToUse = null; if ((locations & ToolsetDefinitionLocations.ConfigurationFile) == ToolsetDefinitionLocations.ConfigurationFile) { if (configurationReader == null && ConfigurationFileMayHaveToolsets()) { // We haven't been passed in a fake configuration reader by a unit test, // and it looks like we have a .config file to read, so create a real // configuration reader configurationReader = new ToolsetConfigurationReader(); } if (configurationReader != null) { configurationReaderToUse = configurationReader == null ? new ToolsetConfigurationReader() : configurationReader; // Accumulation of properties is okay in the config file because it's deterministically ordered defaultToolsVersionFromConfiguration = configurationReaderToUse.ReadToolsets(toolsets, globalProperties, initialProperties, true /* accumulate properties */); } } // We'll use the default from the configuration file if it was specified, otherwise we'll try // the one from the registry. It's possible (and valid) that neither the configuration file // nor the registry specify a default, in which case we'll just return null. string defaultToolsVersion = defaultToolsVersionFromConfiguration ?? defaultToolsVersionFromRegistry; // If we got a default version from the registry or config file, and it // actually exists, fine. // Otherwise we have to come up with one. if (defaultToolsVersion == null || !toolsets.Contains(defaultToolsVersion)) { // We're going to choose a hard coded default tools version of 2.0. defaultToolsVersion = Constants.defaultToolsVersion; // But don't overwrite any existing tools path for this default we're choosing. if (!toolsets.Contains(Constants.defaultToolsVersion)) { // There's no tools path already for 2.0, so use the path to the v2.0 .NET Framework. // If an old-fashioned caller sets BinPath property, or passed a BinPath to the constructor, // that will overwrite what we're setting here. ErrorUtilities.VerifyThrow(Constants.defaultToolsVersion == "2.0", "Getting 2.0 FX path so default should be 2.0"); string pathToFramework = FrameworkLocationHelper.PathToDotNetFrameworkV20; // We could not find the default toolsversion because it was not installed on the machine. Fallback to the // one we expect to always be there when running msbuild 4.0. if (pathToFramework == null) { pathToFramework = FrameworkLocationHelper.PathToDotNetFrameworkV40; defaultToolsVersion = Constants.defaultFallbackToolsVersion; } // Again don't overwrite any existing tools path for this default we're choosing. if (!toolsets.Contains(defaultToolsVersion)) { Toolset defaultToolset = new Toolset(defaultToolsVersion, pathToFramework, initialProperties); toolsets.Add(defaultToolset); } } } return defaultToolsVersion; }