1 using System.IO; 2 using Microsoft.Build.Framework; 3 using Microsoft.Build.Tasks; 4 using Microsoft.Build.Utilities; 5 using Xunit; 6 7 namespace Microsoft.Build.UnitTests.ResolveAssemblyReference_Tests 8 { 9 /// <summary> 10 /// Unit test the cases where we need to determine if the target framework is greater than the current target framework through the use of the target framework attribute 11 /// </summary> 12 public sealed class VerifyTargetFrameworkAttribute : ResolveAssemblyReferenceTestFixture 13 { 14 /// <summary> 15 /// Verify there are no warnings if the target framework identifier passed to rar and the target framework identifier in the dll do not match. 16 /// </summary> 17 [Fact] FrameworksDoNotMatch()18 public void FrameworksDoNotMatch() 19 { 20 MockEngine e = new MockEngine(); 21 22 ITaskItem[] items = new ITaskItem[] 23 { 24 new TaskItem("DependsOnFoo4Framework"), 25 }; 26 27 ResolveAssemblyReference t = new ResolveAssemblyReference(); 28 t.BuildEngine = e; 29 t.Assemblies = items; 30 t.TargetFrameworkMoniker = "BAR, Version=4.0"; 31 t.TargetFrameworkMonikerDisplayName = "BAR"; 32 t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar }; 33 Execute(t); 34 35 Assert.Equal(0, e.Warnings); // "No warnings expected in this scenario." 36 Assert.Equal(0, e.Errors); // "No errors expected in this scenario." 37 Assert.Equal(1, t.ResolvedFiles.Length); 38 Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "DependsOnFoo4Framework.dll"))); // "Expected to find assembly, but didn't." 39 } 40 41 /// <summary> 42 /// Verify there are no warnings if it is the same framework but we are a lower version. With a primary reference in the project. 43 /// </summary> 44 [Fact] LowerVersionSameFrameworkDirect()45 public void LowerVersionSameFrameworkDirect() 46 { 47 MockEngine e = new MockEngine(); 48 49 ITaskItem[] items = new ITaskItem[] 50 { 51 new TaskItem("DependsOnFoo35Framework"), 52 }; 53 54 ResolveAssemblyReference t = new ResolveAssemblyReference(); 55 t.BuildEngine = e; 56 t.Assemblies = items; 57 t.TargetFrameworkMoniker = "Foo, Version=v4.0"; 58 t.TargetFrameworkMonikerDisplayName = "Foo"; 59 t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar }; 60 Execute(t); 61 62 Assert.Equal(0, e.Warnings); // "No warnings expected in this scenario." 63 Assert.Equal(0, e.Errors); // "No errors expected in this scenario." 64 Assert.Equal(1, t.ResolvedFiles.Length); 65 Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "DependsOnFoo35Framework.dll"))); // "Expected to find assembly, but didn't." 66 } 67 68 /// <summary> 69 /// Verify there are no warnings if it is the same framework and the same version and a direct reference 70 /// </summary> 71 [Fact] SameVersionSameFrameworkDirect()72 public void SameVersionSameFrameworkDirect() 73 { 74 MockEngine e = new MockEngine(); 75 76 ITaskItem[] items = new ITaskItem[] 77 { 78 new TaskItem("DependsOnFoo4Framework"), 79 }; 80 81 ResolveAssemblyReference t = new ResolveAssemblyReference(); 82 t.BuildEngine = e; 83 t.Assemblies = items; 84 t.TargetFrameworkMoniker = "Foo, Version=4.0"; 85 t.TargetFrameworkMonikerDisplayName = "Foo"; 86 t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar }; 87 Execute(t); 88 89 Assert.Equal(0, e.Warnings); // "No warnings expected in this scenario." 90 Assert.Equal(0, e.Errors); // "No errors expected in this scenario." 91 Assert.Equal(1, t.ResolvedFiles.Length); 92 Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "DependsOnFoo4Framework.dll"))); // "Expected to find assembly, but didn't." 93 } 94 95 /// <summary> 96 /// Verify there are no warnings if the reference was built for a higher framework but specific version is true 97 /// </summary> 98 [Fact] HigherVersionButSpecificVersionDirect()99 public void HigherVersionButSpecificVersionDirect() 100 { 101 MockEngine e = new MockEngine(); 102 103 TaskItem item = new TaskItem("DependsOnFoo45Framework, Version=4.5.0.0, PublicKeyToken=null, Culture=Neutral"); 104 item.SetMetadata("SpecificVersion", "true"); 105 106 ITaskItem[] items = new ITaskItem[] 107 { 108 item 109 }; 110 111 ResolveAssemblyReference t = new ResolveAssemblyReference(); 112 t.BuildEngine = e; 113 t.Assemblies = items; 114 t.TargetFrameworkMoniker = "Foo, Version=4.0"; 115 t.TargetFrameworkMonikerDisplayName = "Foo"; 116 t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar }; 117 Execute(t); 118 119 Assert.Equal(0, e.Warnings); // "No warnings expected in this scenario." 120 Assert.Equal(0, e.Errors); // "No errors expected in this scenario." 121 Assert.Equal(1, t.ResolvedFiles.Length); 122 Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "DependsOnFoo45Framework.dll"))); // "Expected to find assembly, but didn't." 123 } 124 125 /// <summary> 126 /// Verify there are no warnings if it is the same framework but we are a lower version. 127 /// </summary> 128 [Fact] LowerVersionSameFrameworkInDirect()129 public void LowerVersionSameFrameworkInDirect() 130 { 131 MockEngine e = new MockEngine(); 132 133 ITaskItem[] items = new ITaskItem[] 134 { 135 new TaskItem("IndirectDependsOnFoo35Framework"), 136 }; 137 138 ResolveAssemblyReference t = new ResolveAssemblyReference(); 139 t.BuildEngine = e; 140 t.Assemblies = items; 141 t.TargetFrameworkMoniker = "Foo, Version=v4.0"; 142 t.TargetFrameworkMonikerDisplayName = "Foo"; 143 t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar }; 144 Execute(t); 145 146 Assert.Equal(0, e.Warnings); // "No warnings expected in this scenario." 147 Assert.Equal(0, e.Errors); // "No errors expected in this scenario." 148 Assert.Equal(1, t.ResolvedFiles.Length); 149 Assert.Equal(1, t.ResolvedDependencyFiles.Length); 150 Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "IndirectDependsOnFoo35Framework.dll"))); // "Expected to find assembly, but didn't." 151 Assert.True(ContainsItem(t.ResolvedDependencyFiles, Path.Combine(s_frameworksPath, "DependsOnFoo35Framework.dll"))); // "Expected to find assembly, but didn't." 152 } 153 154 /// <summary> 155 /// Verify there are no warnings if it is the same framework and the same version. 156 /// </summary> 157 [Fact] SameVersionSameFrameworkInDirect()158 public void SameVersionSameFrameworkInDirect() 159 { 160 MockEngine e = new MockEngine(); 161 162 ITaskItem[] items = new ITaskItem[] 163 { 164 new TaskItem("IndirectDependsOnFoo4Framework"), 165 }; 166 167 ResolveAssemblyReference t = new ResolveAssemblyReference(); 168 t.BuildEngine = e; 169 t.Assemblies = items; 170 t.TargetFrameworkMoniker = "Foo, Version=4.0"; 171 t.TargetFrameworkMonikerDisplayName = "Foo"; 172 t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar }; 173 Execute(t); 174 175 Assert.Equal(0, e.Warnings); // "No warnings expected in this scenario." 176 Assert.Equal(0, e.Errors); // "No errors expected in this scenario." 177 Assert.Equal(1, t.ResolvedFiles.Length); 178 Assert.Equal(1, t.ResolvedDependencyFiles.Length); 179 Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "IndirectDependsOnFoo4Framework.dll"))); // "Expected to find assembly, but didn't." 180 Assert.True(ContainsItem(t.ResolvedDependencyFiles, Path.Combine(s_frameworksPath, "DependsOnFoo4Framework.dll"))); // "Expected to find assembly, but didn't." 181 } 182 183 /// <summary> 184 /// Verify there are no warnings if it is the same framework and a higher version but specific version is true. 185 /// </summary> 186 [Fact] HigherVersionButSpecificVersionInDirect()187 public void HigherVersionButSpecificVersionInDirect() 188 { 189 MockEngine e = new MockEngine(); 190 191 TaskItem item = new TaskItem("IndirectDependsOnFoo45Framework, Version=0.0.0.0, PublicKeyToken=null, Culture=Neutral"); 192 item.SetMetadata("SpecificVersion", "true"); 193 194 ITaskItem[] items = new ITaskItem[] 195 { 196 item 197 }; 198 199 ResolveAssemblyReference t = new ResolveAssemblyReference(); 200 t.BuildEngine = e; 201 t.Assemblies = items; 202 t.TargetFrameworkMoniker = "Foo, Version=4.0"; 203 t.TargetFrameworkMonikerDisplayName = "Foo"; 204 t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar }; 205 Execute(t); 206 207 Assert.Equal(0, e.Warnings); // "No warnings expected in this scenario." 208 Assert.Equal(0, e.Errors); // "No errors expected in this scenario." 209 Assert.Equal(1, t.ResolvedFiles.Length); 210 Assert.Equal(1, t.ResolvedDependencyFiles.Length); 211 Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "IndirectDependsOnFoo45Framework.dll"))); // "Expected to find assembly, but didn't." 212 Assert.True(ContainsItem(t.ResolvedDependencyFiles, Path.Combine(s_frameworksPath, "DependsOnFoo45Framework.dll"))); // "Expected to find assembly, but didn't." 213 } 214 215 /// <summary> 216 /// Verify there are warnings if there is an indirect reference to a dll that is higher that what the current target framework is. 217 /// </summary> 218 [Fact] HigherVersionInDirect()219 public void HigherVersionInDirect() 220 { 221 MockEngine e = new MockEngine(); 222 223 TaskItem item = new TaskItem("IndirectDependsOnFoo45Framework, Version=0.0.0.0, PublicKeyToken=null, Culture=Neutral"); 224 225 ITaskItem[] items = new ITaskItem[] 226 { 227 item 228 }; 229 230 ResolveAssemblyReference t = new ResolveAssemblyReference(); 231 t.BuildEngine = e; 232 t.Assemblies = items; 233 t.TargetFrameworkMoniker = "Foo, Version=4.0"; 234 t.TargetFrameworkMonikerDisplayName = "Foo"; 235 t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar }; 236 Execute(t, false); 237 238 Assert.Equal(1, e.Warnings); // "One warning expected in this scenario." 239 e.AssertLogContains("MSB3275"); 240 Assert.Equal(0, e.Errors); // "No errors expected in this scenario." 241 Assert.Equal(0, t.ResolvedFiles.Length); 242 Assert.Equal(0, t.ResolvedDependencyFiles.Length); 243 } 244 245 /// <summary> 246 /// Verify there are no warnings if there is an indirect reference to a dll that is higher that what the current target framework is but IgnoreFrameworkAttributeVersionMismatch is true. 247 /// </summary> 248 [Fact] HigherVersionInDirectIgnoreMismatch()249 public void HigherVersionInDirectIgnoreMismatch() 250 { 251 MockEngine e = new MockEngine(); 252 253 TaskItem item = new TaskItem("IndirectDependsOnFoo45Framework, Version=0.0.0.0, PublicKeyToken=null, Culture=Neutral"); 254 255 ITaskItem[] items = new ITaskItem[] 256 { 257 item 258 }; 259 260 ResolveAssemblyReference t = new ResolveAssemblyReference(); 261 t.BuildEngine = e; 262 t.Assemblies = items; 263 t.TargetFrameworkMoniker = "Foo, Version=4.0"; 264 t.TargetFrameworkMonikerDisplayName = "Foo"; 265 t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar }; 266 t.IgnoreTargetFrameworkAttributeVersionMismatch = true; 267 Execute(t); 268 269 Assert.Equal(0, e.Warnings); // "No warnings expected in this scenario." 270 Assert.Equal(0, e.Errors); // "No errors expected in this scenario." 271 Assert.Equal(1, t.ResolvedFiles.Length); 272 Assert.Equal(1, t.ResolvedDependencyFiles.Length); 273 Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "IndirectDependsOnFoo45Framework.dll"))); // "Expected to find assembly, but didn't." 274 Assert.True(ContainsItem(t.ResolvedDependencyFiles, Path.Combine(s_frameworksPath, "DependsOnFoo45Framework.dll"))); // "Expected to find assembly, but didn't." 275 } 276 277 /// <summary> 278 /// Verify there are no warnings if there is a direct reference to a dll that is higher that what the current target framework is but the property IgnoreFrameworkAttributeVersionMismatch is true. 279 /// </summary> 280 [Fact] HigherVersionDirectIgnoreMismatch()281 public void HigherVersionDirectIgnoreMismatch() 282 { 283 MockEngine e = new MockEngine(); 284 285 TaskItem item = new TaskItem("DependsOnFoo45Framework"); 286 287 ITaskItem[] items = new ITaskItem[] 288 { 289 item 290 }; 291 292 ResolveAssemblyReference t = new ResolveAssemblyReference(); 293 t.BuildEngine = e; 294 t.Assemblies = items; 295 t.TargetFrameworkMoniker = "Foo, Version=4.0"; 296 t.TargetFrameworkMonikerDisplayName = "Foo"; 297 t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar }; 298 t.IgnoreTargetFrameworkAttributeVersionMismatch = true; 299 300 Execute(t); 301 302 Assert.Equal(0, e.Warnings); // "No warnings expected in this scenario." 303 Assert.Equal(0, e.Errors); // "No errors expected in this scenario." 304 Assert.Equal(1, t.ResolvedFiles.Length); 305 Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "DependsOnFoo45Framework.dll"))); // "Expected to find assembly, but didn't." 306 } 307 308 309 /// <summary> 310 /// Verify there are warnings if there is a direct reference to a dll that is higher that what the current target framework is. 311 /// </summary> 312 [Fact] HigherVersionDirect()313 public void HigherVersionDirect() 314 { 315 MockEngine e = new MockEngine(); 316 317 TaskItem item = new TaskItem("DependsOnFoo45Framework"); 318 319 ITaskItem[] items = new ITaskItem[] 320 { 321 item 322 }; 323 324 ResolveAssemblyReference t = new ResolveAssemblyReference(); 325 t.BuildEngine = e; 326 t.Assemblies = items; 327 t.TargetFrameworkMoniker = "Foo, Version=4.0"; 328 t.TargetFrameworkMonikerDisplayName = "Foo"; 329 t.SearchPaths = new string[] { s_frameworksPath + Path.DirectorySeparatorChar }; 330 Execute(t, false); 331 332 Assert.Equal(1, e.Warnings); // "One warning expected in this scenario." 333 e.AssertLogContains("MSB3274"); 334 Assert.Equal(0, e.Errors); // "No errors expected in this scenario." 335 Assert.Equal(0, t.ResolvedFiles.Length); 336 Assert.Equal(0, t.ResolvedDependencyFiles.Length); 337 } 338 339 /// <summary> 340 /// Verify there are no warnings if there is a direct reference to a dll that is higher that what the current target framework is but 341 /// find dependencies is false. This is because we do not want to add an extra read for this attribute during the project load phase. 342 /// which has dependencies set to false. A regular build or design time build has this set to true so we do the correct check. 343 /// </summary> 344 [Fact] 345 [Trait("Category", "mono-osx-failing")] HigherVersionDirectDependenciesFalse()346 public void HigherVersionDirectDependenciesFalse() 347 { 348 MockEngine e = new MockEngine(); 349 350 TaskItem item = new TaskItem("DependsOnFoo45Framework"); 351 352 ITaskItem[] items = new ITaskItem[] 353 { 354 item 355 }; 356 357 ResolveAssemblyReference t = new ResolveAssemblyReference(); 358 t.BuildEngine = e; 359 t.Assemblies = items; 360 t.FindDependencies = false; 361 t.TargetFrameworkMoniker = "Foo, Version=4.0"; 362 t.TargetFrameworkMonikerDisplayName = "Foo"; 363 t.SearchPaths = new string[] { @"c:\Frameworks\" }; 364 Assert.True( 365 t.Execute 366 ( 367 fileExists, 368 directoryExists, 369 getDirectories, 370 getAssemblyName, 371 getAssemblyMetadata, 372 #if FEATURE_WIN32_REGISTRY 373 getRegistrySubKeyNames, 374 getRegistrySubKeyDefaultValue, 375 #endif 376 getLastWriteTime, 377 getRuntimeVersion, 378 #if FEATURE_WIN32_REGISTRY 379 openBaseKey, 380 #endif 381 checkIfAssemblyIsInGac, 382 isWinMDFile, 383 readMachineTypeFromPEHeader 384 ) 385 ); 386 387 388 Assert.Equal(0, e.Warnings); // "No warning expected in this scenario." 389 Assert.Equal(0, e.Errors); // "No errors expected in this scenario." 390 Assert.Equal(1, t.ResolvedFiles.Length); 391 Assert.Equal(0, t.ResolvedDependencyFiles.Length); 392 Assert.True(ContainsItem(t.ResolvedFiles, Path.Combine(s_frameworksPath, "DependsOnFoo45Framework.dll"))); // "Expected to find assembly, but didn't." 393 } 394 } 395 }