xamarin-macios/tests/msbuild/Xamarin.MacDev.Tasks.Tests/FrameworkListTest.cs

191 строка
7.0 KiB
C#

using System;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Text;
using System.Xml;
using NUnit.Framework;
using Xamarin.Tests;
using System.Linq;
namespace Xamarin.iOS.Tasks
{
[TestFixture]
public class FrameworkListTests
{
[TestCase ("Xamarin.iOS-FrameworkList.xml.in")]
[TestCase ("Xamarin.TVOS-FrameworkList.xml.in")]
[TestCase ("Xamarin.WatchOS-FrameworkList.xml.in")]
[TestCase ("Xamarin.Mac-Full-FrameworkList.xml.in")]
[TestCase ("Xamarin.Mac-Mobile-FrameworkList.xml.in")]
public void CheckFrameworkListFile (string frameworkListFile)
{
var fameworkListFileParts = frameworkListFile.Split ('-');
string frameworkName = fameworkListFileParts[0];
switch (frameworkName) {
case "Xamarin.iOS":
if (!Configuration.include_ios)
Assert.Inconclusive ("include_ios is disabled");
break;
case "Xamarin.TVOS":
if (!Configuration.include_tvos)
Assert.Inconclusive ("include_tvos is disabled");
break;
case "Xamarin.WatchOS":
if (!Configuration.include_watchos)
Assert.Inconclusive ("include_watchos is disabled");
break;
case "Xamarin.Mac":
if (!Configuration.include_mac)
Assert.Inconclusive ("include_mac is disabled");
break;
}
var isMac = frameworkName == "Xamarin.Mac";
var isFull = fameworkListFileParts[1] == "Full";
var frameworkListAssemblies = ScanFrameworkListXml (frameworkListFile, isMac);
var installedAssemblies = ScanAssemblyDirectory (frameworkName, isMac, isFull);
foreach (var assembly in frameworkListAssemblies) {
if (!installedAssemblies.Any (a => a.Name == assembly.Name))
ReportAssemblies (assembly, $"One or more assemblies listed in '{frameworkListFile}' were not found in the final SDK root folder. Update the list if an assembly was intentionally removed.");
}
foreach (var assembly in installedAssemblies) {
if (!frameworkListAssemblies.Any (a => a.Name == assembly.Name))
ReportAssemblies (assembly, $"One or more assemblies in the the SDK root folder are not listed in '{frameworkListFile}'. Update the list if an assembly was intentionally added.");
else if (!frameworkListAssemblies.Single (a => a.Name == assembly.Name).Equals (assembly))
ReportAssemblies (assembly, $"One or more assemblies in the the SDK root folder do not match the entry in '{frameworkListFile}'. Update the list if an assembly was intentionally modified.");
}
}
void ReportAssemblies (AssemblyInfo assembly, string message)
{
var errorCount = 0;
using (var sw = new StringWriter ()) {
using (var writer = XmlWriter.Create (sw, new XmlWriterSettings { Encoding = Encoding.UTF8, ConformanceLevel = ConformanceLevel.Fragment, Indent = true })) {
writer.WriteStartElement ("File");
writer.WriteAttributeString ("AssemblyName", assembly.Name);
WriteNonEmptyAttribute ("Version", assembly.Version);
WriteNonEmptyAttribute ("PublicKeyToken", assembly.PublicKeyToken);
WriteNonEmptyAttribute ("Culture", assembly.Culture);
if (assembly.ProcessorArchitecture != ProcessorArchitecture.None)
writer.WriteAttributeString ("ProcessorArchitecture", assembly.ProcessorArchitecture.ToString ());
if (assembly.InGac)
writer.WriteAttributeString ("InGac", "true");
writer.WriteEndElement ();
errorCount++;
void WriteNonEmptyAttribute (string name, string val)
{
if (!string.IsNullOrEmpty (val))
writer.WriteAttributeString (name, val);
}
}
Assert.AreEqual (0, errorCount, $"{message}\n{sw.ToString ()}");
}
}
List<AssemblyInfo> ScanFrameworkListXml (string frameworkListFile, bool isMac)
{
var assemblies = new List<AssemblyInfo> ();
var path = Path.GetFullPath (Path.Combine (Configuration.SourceRoot, "msbuild", isMac ? "Xamarin.Mac.Tasks" : "Xamarin.iOS.Tasks.Core", frameworkListFile));
using (var reader = XmlReader.Create (path)) {
while (reader.Read ()) {
if (reader.IsStartElement ()) {
switch (reader.LocalName) {
case "File":
assemblies.Add (ReadFileElement (reader));
break;
}
}
}
}
return assemblies;
}
List<AssemblyInfo> ScanAssemblyDirectory (string frameworkName, bool isMac, bool isFull)
{
var assemblies = new List<AssemblyInfo> ();
var assembliesPath = Path.GetFullPath (Path.Combine (isMac ? Configuration.SdkRootXM : Configuration.MonoTouchRootDirectory, "lib", "mono", isFull ? "4.5" : frameworkName));
AddAssemblies (assembliesPath);
AddAssemblies (Path.Combine (assembliesPath, "Facades"));
void AddAssemblies (string path)
{
foreach (var f in Directory.EnumerateFiles (path, "*.dll")) {
try {
var an = AssemblyName.GetAssemblyName (f);
assemblies.Add (new AssemblyInfo (an));
} catch (Exception ex) {
Assert.Fail ("Error reading assembly '{0}' in framework '{1}':{2}{3}", f, frameworkName, Environment.NewLine, ex);
}
}
}
return assemblies;
}
static AssemblyInfo ReadFileElement (XmlReader reader)
{
var ainfo = new AssemblyInfo ();
if (reader.MoveToAttribute ("AssemblyName") && reader.ReadAttributeValue ())
ainfo.Name = reader.ReadContentAsString ();
if (string.IsNullOrEmpty (ainfo.Name))
throw new Exception ("Missing AssemblyName attribute");
if (reader.MoveToAttribute ("Version") && reader.ReadAttributeValue ())
ainfo.Version = reader.ReadContentAsString ();
if (reader.MoveToAttribute ("PublicKeyToken") && reader.ReadAttributeValue ())
ainfo.PublicKeyToken = reader.ReadContentAsString ();
if (reader.MoveToAttribute ("Culture") && reader.ReadAttributeValue ())
ainfo.Culture = reader.ReadContentAsString ();
if (reader.MoveToAttribute ("ProcessorArchitecture") && reader.ReadAttributeValue ())
ainfo.ProcessorArchitecture = (ProcessorArchitecture)
Enum.Parse (typeof (ProcessorArchitecture), reader.ReadContentAsString (), true);
if (reader.MoveToAttribute ("InGac") && reader.ReadAttributeValue ())
ainfo.InGac = reader.ReadContentAsBoolean ();
return ainfo;
}
}
class AssemblyInfo
{
public string Name;
public string Version;
public string PublicKeyToken;
public string Culture;
public ProcessorArchitecture ProcessorArchitecture = ProcessorArchitecture.MSIL;
public bool InGac;
public AssemblyInfo ()
{
}
public AssemblyInfo (AssemblyName aname)
{
Name = aname.Name;
Version = aname.Version.ToString ();
ProcessorArchitecture = aname.ProcessorArchitecture;
Culture = aname.CultureInfo.Name;
string fn = aname.ToString ();
string key = "publickeytoken=";
int i = fn.IndexOf (key, StringComparison.OrdinalIgnoreCase) + key.Length;
int j = fn.IndexOf (',', i);
if (j == -1) j = fn.Length;
PublicKeyToken = fn.Substring (i, j - i);
}
public bool Equals (AssemblyInfo other) {
// ignore Culture and InGac for equality since those are not mentioned in the FrameworkList.xml
return other.Name == this.Name &&
other.Version == this.Version &&
other.PublicKeyToken == this.PublicKeyToken &&
other.ProcessorArchitecture == this.ProcessorArchitecture;
}
}
}