public void AppConfigFileNotSavedWhenIdentical()
        {
            string appConfigFile       = WriteAppConfigRuntimeSection(string.Empty);
            string outputAppConfigFile = _env.ExpectFile(".config").Path;

            TaskItemMock redirect = new TaskItemMock("System, Version=10.0.0.0, Culture=Neutral, PublicKeyToken='b77a5c561934e089'", "40.0.0.0");

            var redirectResults = GenerateBindingRedirects(appConfigFile, outputAppConfigFile, redirect);

            // Verify it ran correctly
            redirectResults.ExecuteResult.ShouldBeTrue();
            redirectResults.TargetAppConfigContent.ShouldContain("<assemblyIdentity name=\"System\" publicKeyToken=\"b77a5c561934e089\" culture=\"neutral\" />");
            redirectResults.TargetAppConfigContent.ShouldContain("newVersion=\"40.0.0.0\"");

            var oldTimestamp = DateTime.Now.Subtract(TimeSpan.FromDays(30));

            File.SetCreationTime(outputAppConfigFile, oldTimestamp);
            File.SetLastWriteTime(outputAppConfigFile, oldTimestamp);

            // Make sure it's old
            File.GetCreationTime(outputAppConfigFile).ShouldBe(oldTimestamp, TimeSpan.FromSeconds(5));
            File.GetLastWriteTime(outputAppConfigFile).ShouldBe(oldTimestamp, TimeSpan.FromSeconds(5));

            // Re-run the task
            var redirectResults2 = GenerateBindingRedirects(appConfigFile, outputAppConfigFile, redirect);

            // Verify it ran correctly and that it's still old
            redirectResults2.ExecuteResult.ShouldBeTrue();
            redirectResults2.TargetAppConfigContent.ShouldContain("<assemblyIdentity name=\"System\" publicKeyToken=\"b77a5c561934e089\" culture=\"neutral\" />");
            redirectResults.TargetAppConfigContent.ShouldContain("newVersion=\"40.0.0.0\"");

            File.GetCreationTime(outputAppConfigFile).ShouldBe(oldTimestamp, TimeSpan.FromSeconds(5));
            File.GetLastWriteTime(outputAppConfigFile).ShouldBe(oldTimestamp, TimeSpan.FromSeconds(5));
        }
        public void TargetAppConfigShouldContainsBindingRedirects()
        {
            // Arrange
            // Current appConfig is empty
            string       appConfigFile = WriteAppConfigRuntimeSection(string.Empty);
            TaskItemMock redirect      = new TaskItemMock("System, Version=10.0.0.0, Culture=Neutral, PublicKeyToken='b77a5c561934e089'", "40.0.0.0");

            // Act
            var redirectResults = GenerateBindingRedirects(appConfigFile, null, redirect);

            // Assert
            redirectResults.ExecuteResult.ShouldBeTrue();
            redirectResults.TargetAppConfigContent.ShouldContain("<assemblyIdentity name=\"System\" publicKeyToken=\"b77a5c561934e089\" culture=\"neutral\" />");
            redirectResults.TargetAppConfigContent.ShouldContain("newVersion=\"40.0.0.0\"");
        }
        public void AppConfigWithEmptyAssemblyBindingShouldNotProduceWarnings()
        {
            // Arrange
            string appConfigFile = WriteAppConfigRuntimeSection(
                @"<assemblyBinding xmlns=""urn:schemas-microsoft-com:asm.v1"" appliesTo=""v1.0.3705""> 
</assemblyBinding>");
            TaskItemMock redirect = new TaskItemMock("System, Version=10.0.0.0, Culture=Neutral, PublicKeyToken='b77a5c561934e089'", "40.0.0.0");

            // Act
            var redirectResults = GenerateBindingRedirects(appConfigFile, null, redirect);

            // Assert
            redirectResults.Engine.Errors.ShouldBe(0);
            redirectResults.Engine.Warnings.ShouldBe(0);
        }
        public void TargetAppConfigShouldContainsBindingRedirects()
        {
            // Arrange
            // Current appConfig is empty
            string appConfigFile = WriteAppConfigRuntimeSection(string.Empty);
            TaskItemMock redirect = new TaskItemMock("System, Version=10.0.0.0, Culture=Neutral, PublicKeyToken='b77a5c561934e089'", "40.0.0.0");

            // Act
            var redirectResults = GenerateBindingRedirects(appConfigFile, redirect);

            // Assert
            Assert.True(redirectResults.ExecuteResult);
            Assert.Contains("<assemblyIdentity name=\"System\" publicKeyToken=\"b77a5c561934e089\" culture=\"neutral\" />", redirectResults.TargetAppConfigContent);
            Assert.Contains("newVersion=\"40.0.0.0\"", redirectResults.TargetAppConfigContent);
        }
        public void GenerateBindingRedirectsFromTwoDependentAssemblySections()
        {
            // Arrange
            string appConfigFile = WriteAppConfigRuntimeSection(
                @"<loadFromRemoteSources enabled=""true""/>
  <assemblyBinding xmlns=""urn:schemas-microsoft-com:asm.v1"" >
    <dependentAssembly>
      <assemblyIdentity name=""Microsoft.ServiceBus"" publicKeyToken =""31bf3856ad364e35"" culture =""neutral"" />
      <bindingRedirect oldVersion=""2.0.0.0-3.0.0.0"" newVersion =""2.2.0.0"" />
    </dependentAssembly>
    <probing privatePath=""VSO14"" />
    <dependentAssembly>
      <assemblyIdentity name=""System.Web.Http"" publicKeyToken =""31bf3856ad364e35"" culture =""neutral"" />
      <bindingRedirect oldVersion=""4.0.0.0-6.0.0.0"" newVersion =""4.0.0.0"" />
    </dependentAssembly>
    <dependentAssembly>
      <assemblyIdentity name=""Microsoft.TeamFoundation.Common"" publicKeyToken =""b03f5f7f11d50a3a"" culture =""neutral"" />
      <codeBase version=""11.0.0.0"" href =""Microsoft.TeamFoundation.Common.dll"" />
      <codeBase version=""14.0.0.0"" href =""VSO14\Microsoft.TeamFoundation.Common.dll"" />
    </dependentAssembly>
  </assemblyBinding>");

            TaskItemMock serviceBusRedirect = new TaskItemMock("Microsoft.ServiceBus, Version=2.0.0.0, Culture=Neutral, PublicKeyToken='31bf3856ad364e35'", "41.0.0.0");
            TaskItemMock webHttpRedirect    = new TaskItemMock("System.Web.Http, Version=4.0.0.0, Culture=Neutral, PublicKeyToken='31bf3856ad364e35'", "40.0.0.0");

            // Act
            var redirectResults = GenerateBindingRedirects(appConfigFile, null, serviceBusRedirect, webHttpRedirect);

            // Assert
            redirectResults.ExecuteResult.ShouldBeTrue();
            // Naive check that target app.config contains custom redirects.
            // Output config should have max versions for both serviceBus and webhttp assemblies.
            redirectResults.TargetAppConfigContent.ShouldContain($"oldVersion=\"0.0.0.0-{serviceBusRedirect.MaxVersion}\"");
            redirectResults.TargetAppConfigContent.ShouldContain($"newVersion=\"{serviceBusRedirect.MaxVersion}\"");

            redirectResults.TargetAppConfigContent.ShouldContain($"oldVersion=\"0.0.0.0-{webHttpRedirect.MaxVersion}\"");
            redirectResults.TargetAppConfigContent.ShouldContain($"newVersion=\"{webHttpRedirect.MaxVersion}\"");

            XElement targetAppConfig = XElement.Parse(redirectResults.TargetAppConfigContent);

            targetAppConfig.Descendants()
            .Count(e => e.Name.LocalName.Equals("assemblyBinding", StringComparison.OrdinalIgnoreCase))
            .ShouldBe(1);
            // "Binding redirects should not add additional assemblyBinding sections into the target app.config: " + targetAppConfig

            // Log file should contains a warning when GenerateBindingRedirects updates existing app.config entries
            redirectResults.Engine.AssertLogContains("MSB3836");
        }
        public void AppConfigInvalidIfDependentAssemblyNodeIsEmpty()
        {
            // Construct the app.config.
            string appConfigFile = WriteAppConfigRuntimeSection(
                @"<assemblyBinding xmlns=""urn:schemas-microsoft-com:asm.v1"">
  <dependentAssembly>
  </dependentAssembly>
</assemblyBinding>");
            TaskItemMock redirect = new TaskItemMock("System, Version=10.0.0.0, Culture=Neutral, PublicKeyToken='b77a5c561934e089'", "40.0.0.0");

            // Act
            var redirectResults = GenerateBindingRedirects(appConfigFile, null, redirect);

            // Assert
            redirectResults.Engine.AssertLogContains("MSB3835");
        }
        public void AppConfigWithProbingPathAndWithoutDependentAssemblyShouldNotProduceWarningsBug1161241()
        {
            // Arrange
            string appConfigFile = WriteAppConfigRuntimeSection(
                @"<assemblyBinding xmlns=""urn:schemas-microsoft-com:asm.v1"">
   <probing privatePath = 'bin;bin2\subbin;bin3'/>  
</assemblyBinding>");
            TaskItemMock redirect = new TaskItemMock("System, Version=10.0.0.0, Culture=Neutral, PublicKeyToken='b77a5c561934e089'", "40.0.0.0");

            // Act
            var redirectResults = GenerateBindingRedirects(appConfigFile, null, redirect);

            // Assert
            redirectResults.Engine.Errors.ShouldBe(0);   // "Unexpected errors. Engine log: " + redirectResults.Engine.Log
            redirectResults.Engine.Warnings.ShouldBe(0); // "Unexpected errors. Engine log: " + redirectResults.Engine.Log
        }
        public void DependentAssemblySectionWithoutBindingRedirectShouldNotProduceWarnings()
        {
            // Arrange
            string appConfigFile = WriteAppConfigRuntimeSection(
                @"<assemblyBinding xmlns=""urn:schemas-microsoft-com:asm.v1"" appliesTo=""v1.0.3705"">
      <dependentAssembly>
        <assemblyIdentity name=""Microsoft.TeamFoundation.Common"" publicKeyToken =""b03f5f7f11d50a3a"" culture =""neutral"" />
        <codeBase version=""11.0.0.0"" href =""Microsoft.TeamFoundation.Common.dll"" />
        <codeBase version=""14.0.0.0"" href =""VSO14\Microsoft.TeamFoundation.Common.dll"" />
      </dependentAssembly>
 </assemblyBinding>");
            TaskItemMock redirect = new TaskItemMock("System, Version=10.0.0.0, Culture=Neutral, PublicKeyToken='b77a5c561934e089'", "40.0.0.0");

            // Act
            var redirectResults = GenerateBindingRedirects(appConfigFile, null, redirect);

            // Assert
            redirectResults.Engine.Errors.ShouldBe(0);
            redirectResults.Engine.Warnings.ShouldBe(0);
        }
        public void TargetAppConfigShouldContainsBindingRedirectsFromAppConfig()
        {
            // Arrange
            string appConfigFile = WriteAppConfigRuntimeSection(
                @"<assemblyBinding xmlns=""urn:schemas-microsoft-com:asm.v1"">
  <dependentAssembly>
    <assemblyIdentity name=""MyAssembly""
                  publicKeyToken = ""14a739be0244c389""
                  culture = ""Neutral""/>
    <bindingRedirect oldVersion= ""1.0.0.0""
                  newVersion = ""5.0.0.0"" />
  </dependentAssembly>
</assemblyBinding>");

            TaskItemMock redirect = new TaskItemMock("MyAssembly, Version=10.0.0.0, Culture=Neutral, PublicKeyToken='14a739be0244c389'", "40.0.0.0");

            // Act
            var redirectResults = GenerateBindingRedirects(appConfigFile, null, redirect);

            // Assert
            redirectResults.TargetAppConfigContent.ShouldContain("MyAssembly");
            redirectResults.TargetAppConfigContent.ShouldContain("<bindingRedirect oldVersion=\"0.0.0.0-40.0.0.0\" newVersion=\"40.0.0.0\"");
        }
        public void TargetAppConfigShouldContainsBindingRedirectsFromAppConfig()
        {
            // Arrange
            string appConfigFile = WriteAppConfigRuntimeSection(
@"<assemblyBinding xmlns=""urn:schemas-microsoft-com:asm.v1"">
  <dependentAssembly>
    <assemblyIdentity name=""MyAssembly""
                  publicKeyToken = ""14a739be0244c389""
                  culture = ""Neutral""/>
    <bindingRedirect oldVersion= ""1.0.0.0""
                  newVersion = ""5.0.0.0"" />
  </dependentAssembly>
</assemblyBinding>");

            TaskItemMock redirect = new TaskItemMock("MyAssembly, Version=10.0.0.0, Culture=Neutral, PublicKeyToken='14a739be0244c389'", "40.0.0.0");

            // Act
            var redirectResults = GenerateBindingRedirects(appConfigFile, redirect);

            // Assert
            Assert.Contains("MyAssembly", redirectResults.TargetAppConfigContent);
            Assert.Contains("<bindingRedirect oldVersion=\"0.0.0.0-40.0.0.0\" newVersion=\"40.0.0.0\"", redirectResults.TargetAppConfigContent);
        }
        public void GenerateBindingRedirectsFromTwoDependentAssemblySections()
        {
            // Arrange
            string appConfigFile = WriteAppConfigRuntimeSection(
@"<loadFromRemoteSources enabled=""true""/>
  <assemblyBinding xmlns=""urn:schemas-microsoft-com:asm.v1"" >
    <dependentAssembly>
      <assemblyIdentity name=""Microsoft.ServiceBus"" publicKeyToken =""31bf3856ad364e35"" culture =""neutral"" />
      <bindingRedirect oldVersion=""2.0.0.0-3.0.0.0"" newVersion =""2.2.0.0"" />
    </dependentAssembly>
    <probing privatePath=""VSO14"" />
    <dependentAssembly>
      <assemblyIdentity name=""System.Web.Http"" publicKeyToken =""31bf3856ad364e35"" culture =""neutral"" />
      <bindingRedirect oldVersion=""4.0.0.0-6.0.0.0"" newVersion =""4.0.0.0"" />
    </dependentAssembly>
    <dependentAssembly>
      <assemblyIdentity name=""Microsoft.TeamFoundation.Common"" publicKeyToken =""b03f5f7f11d50a3a"" culture =""neutral"" />
      <codeBase version=""11.0.0.0"" href =""Microsoft.TeamFoundation.Common.dll"" />
      <codeBase version=""14.0.0.0"" href =""VSO14\Microsoft.TeamFoundation.Common.dll"" />
    </dependentAssembly>
  </assemblyBinding>");

            TaskItemMock serviceBusRedirect = new TaskItemMock("Microsoft.ServiceBus, Version=2.0.0.0, Culture=Neutral, PublicKeyToken='31bf3856ad364e35'", "41.0.0.0");
            TaskItemMock webHttpRedirect = new TaskItemMock("System.Web.Http, Version=4.0.0.0, Culture=Neutral, PublicKeyToken='31bf3856ad364e35'", "40.0.0.0");

            // Act
            var redirectResults = GenerateBindingRedirects(appConfigFile, serviceBusRedirect, webHttpRedirect);

            // Assert
            Assert.True(redirectResults.ExecuteResult);
            // Naive check that target app.config contains custom redirects.
            // Output config should have max versions for both serviceBus and webhttp assemblies.
            Assert.Contains(string.Format(CultureInfo.InvariantCulture, "oldVersion=\"0.0.0.0-{0}\"", serviceBusRedirect.MaxVersion), redirectResults.TargetAppConfigContent);
            Assert.Contains(string.Format(CultureInfo.InvariantCulture, "newVersion=\"{0}\"", serviceBusRedirect.MaxVersion), redirectResults.TargetAppConfigContent);

            Assert.Contains(string.Format(CultureInfo.InvariantCulture, "oldVersion=\"0.0.0.0-{0}\"", webHttpRedirect.MaxVersion), redirectResults.TargetAppConfigContent);
            Assert.Contains(string.Format(CultureInfo.InvariantCulture, "newVersion=\"{0}\"", webHttpRedirect.MaxVersion), redirectResults.TargetAppConfigContent);

            XElement targetAppConfig = XElement.Parse(redirectResults.TargetAppConfigContent);
            Assert.Equal(1,
                targetAppConfig.Descendants()
                    .Count(e => e.Name.LocalName.Equals("assemblyBinding", StringComparison.InvariantCultureIgnoreCase)));
            // "Binding redirects should not add additional assemblyBinding sections into the target app.config: " + targetAppConfig

            // Log file should contains a warning when GenerateBindingRedirects updates existing app.config entries
            redirectResults.Engine.AssertLogContains("MSB3836");
        }
        public void AppConfigInvalidIfDependentAssemblyNodeIsEmpty()
        {
            // Construct the app.config.
            string appConfigFile = WriteAppConfigRuntimeSection(
@"<assemblyBinding xmlns=""urn:schemas-microsoft-com:asm.v1"">
  <dependentAssembly>
  </dependentAssembly>
</assemblyBinding>");
            TaskItemMock redirect = new TaskItemMock("System, Version=10.0.0.0, Culture=Neutral, PublicKeyToken='b77a5c561934e089'", "40.0.0.0");

            // Act
            var redirectResults = GenerateBindingRedirects(appConfigFile, redirect);

            // Assert
            redirectResults.Engine.AssertLogContains("MSB3835");
        }
        public void DependentAssemblySectionWithoutBindingRedirectShouldNotProduceWarnings()
        {
            // Arrange
            string appConfigFile = WriteAppConfigRuntimeSection(
@"<assemblyBinding xmlns=""urn:schemas-microsoft-com:asm.v1"" appliesTo=""v1.0.3705"">
      <dependentAssembly>
        <assemblyIdentity name=""Microsoft.TeamFoundation.Common"" publicKeyToken =""b03f5f7f11d50a3a"" culture =""neutral"" />
        <codeBase version=""11.0.0.0"" href =""Microsoft.TeamFoundation.Common.dll"" />
        <codeBase version=""14.0.0.0"" href =""VSO14\Microsoft.TeamFoundation.Common.dll"" />
      </dependentAssembly>
 </assemblyBinding>");
            TaskItemMock redirect = new TaskItemMock("System, Version=10.0.0.0, Culture=Neutral, PublicKeyToken='b77a5c561934e089'", "40.0.0.0");

            // Act
            var redirectResults = GenerateBindingRedirects(appConfigFile, redirect);

            // Assert
            Assert.Equal(0, redirectResults.Engine.Errors); // "Unexpected errors. Engine log: " + redirectResults.Engine.Log);
            Assert.Equal(0, redirectResults.Engine.Warnings); // "Unexpected errors. Engine log: " + redirectResults.Engine.Log);
        }
        public void AppConfigWithEmptyAssemblyBindingShouldNotProduceWarnings()
        {
            // Arrange
            string appConfigFile = WriteAppConfigRuntimeSection(
@"<assemblyBinding xmlns=""urn:schemas-microsoft-com:asm.v1"" appliesTo=""v1.0.3705""> 
</assemblyBinding>");
            TaskItemMock redirect = new TaskItemMock("System, Version=10.0.0.0, Culture=Neutral, PublicKeyToken='b77a5c561934e089'", "40.0.0.0");

            // Act
            var redirectResults = GenerateBindingRedirects(appConfigFile, redirect);

            // Assert
            Assert.Equal(0, redirectResults.Engine.Errors); // "Unexpected errors. Engine log: " + redirectResults.Engine.Log);
            Assert.Equal(0, redirectResults.Engine.Warnings); // "Unexpected errors. Engine log: " + redirectResults.Engine.Log
        }
        public void AppConfigWithProbingPathAndWithoutDependentAssemblyShouldNotProduceWarningsBug1161241()
        {
            // Arrange
            string appConfigFile = WriteAppConfigRuntimeSection(
@"<assemblyBinding xmlns=""urn:schemas-microsoft-com:asm.v1"">
   <probing privatePath = 'bin;bin2\subbin;bin3'/>  
</assemblyBinding>");
            TaskItemMock redirect = new TaskItemMock("System, Version=10.0.0.0, Culture=Neutral, PublicKeyToken='b77a5c561934e089'", "40.0.0.0");

            // Act
            var redirectResults = GenerateBindingRedirects(appConfigFile, redirect);

            // Assert
            Assert.Equal(0, redirectResults.Engine.Errors); // "Unexpected errors. Engine log: " + redirectResults.Engine.Log
            Assert.Equal(0, redirectResults.Engine.Warnings); // "Unexpected errors. Engine log: " + redirectResults.Engine.Log
        }