216 lines
8.5 KiB
C#
216 lines
8.5 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.IO.Compression;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Xml.Linq;
|
|
using BizTalkApplicationCatalog.Models;
|
|
using BizTalkApplicationCatalog.Persistence;
|
|
using BizTalkApplicationCatalog.Reporting;
|
|
|
|
namespace BizTalkApplicationCatalog.Infrastructure
|
|
{
|
|
/// <summary>
|
|
/// Prüft Snapshot, Merge und Excel-Ausgabe ohne BizTalk-Zugriff.
|
|
/// </summary>
|
|
internal static class SelfTestRunner
|
|
{
|
|
public static void Run(string outputPath = null)
|
|
{
|
|
var keepOutput = !string.IsNullOrWhiteSpace(outputPath);
|
|
var directory = keepOutput
|
|
? Path.GetDirectoryName(Path.GetFullPath(outputPath))
|
|
: Path.Combine(
|
|
Path.GetTempPath(),
|
|
"BizTalkApplicationCatalogTests-" + Guid.NewGuid().ToString("N"));
|
|
Directory.CreateDirectory(directory);
|
|
var path = keepOutput
|
|
? Path.GetFullPath(outputPath)
|
|
: Path.Combine(directory, "phase1-test.xlsx");
|
|
var jsonPath = Path.Combine(
|
|
directory,
|
|
"phase1-test-" + Guid.NewGuid().ToString("N") + ".json");
|
|
|
|
try
|
|
{
|
|
var acc = AccSnapshot();
|
|
SnapshotStore.Save(acc, jsonPath);
|
|
var loadedAcc = SnapshotStore.Load(jsonPath);
|
|
SnapshotStore.ValidateForMerge(loadedAcc, "ACC");
|
|
Assert(
|
|
loadedAcc.Applications.Count == 2,
|
|
"JSON-Roundtrip hat Anwendungen verloren.");
|
|
|
|
var prod = ProdSnapshot();
|
|
SnapshotStore.ValidateForMerge(prod, "PROD");
|
|
new XlsxReportWriter().Write(new[] { loadedAcc, prod }, path);
|
|
Assert(File.Exists(path), "XLSX-Datei wurde nicht erzeugt.");
|
|
|
|
using (var archive = ZipFile.OpenRead(path))
|
|
{
|
|
var required = new[]
|
|
{
|
|
"[Content_Types].xml",
|
|
"_rels/.rels",
|
|
"docProps/core.xml",
|
|
"docProps/app.xml",
|
|
"xl/workbook.xml",
|
|
"xl/_rels/workbook.xml.rels",
|
|
"xl/styles.xml",
|
|
"xl/worksheets/sheet1.xml"
|
|
};
|
|
foreach (var name in required)
|
|
{
|
|
Assert(
|
|
archive.GetEntry(name) != null,
|
|
"XLSX-Part fehlt: " + name);
|
|
}
|
|
Assert(
|
|
archive.GetEntry("xl/worksheets/sheet2.xml") == null,
|
|
"Die Arbeitsmappe enthält mehr als ein Datenblatt.");
|
|
|
|
foreach (var entry in archive.Entries.Where(item =>
|
|
item.FullName.EndsWith(".xml", StringComparison.OrdinalIgnoreCase)
|
|
|| item.FullName.EndsWith(".rels", StringComparison.OrdinalIgnoreCase)))
|
|
{
|
|
using (var stream = entry.Open())
|
|
{
|
|
XDocument.Load(stream);
|
|
}
|
|
}
|
|
|
|
var workbook = LoadXml(archive, "xl/workbook.xml");
|
|
XNamespace spreadsheet =
|
|
"http://schemas.openxmlformats.org/spreadsheetml/2006/main";
|
|
var names = workbook.Descendants(spreadsheet + "sheet")
|
|
.Select(item => (string)item.Attribute("name"))
|
|
.ToList();
|
|
Assert(
|
|
names.SequenceEqual(new[] { "Phase 1" }),
|
|
"Es wird nicht exakt das Blatt 'Phase 1' erzeugt.");
|
|
|
|
var contentTypes = LoadXml(archive, "[Content_Types].xml");
|
|
XNamespace contentTypeNamespace =
|
|
"http://schemas.openxmlformats.org/package/2006/content-types";
|
|
Assert(
|
|
contentTypes.Root
|
|
.Elements(contentTypeNamespace + "Override")
|
|
.Count() == 5,
|
|
"Content-Type-Overrides sind unvollständig.");
|
|
|
|
var worksheet = LoadXml(
|
|
archive,
|
|
"xl/worksheets/sheet1.xml");
|
|
Assert(
|
|
worksheet.Descendants(spreadsheet + "mergeCell")
|
|
.Select(item => (string)item.Attribute("ref"))
|
|
.Contains("A1:G1"),
|
|
"Titelzeile ist nicht zusammengeführt.");
|
|
Assert(
|
|
(string)worksheet
|
|
.Descendants(spreadsheet + "autoFilter")
|
|
.Single()
|
|
.Attribute("ref") == "A2:G5",
|
|
"Filterbereich ist falsch.");
|
|
|
|
string text;
|
|
using (var reader = new StreamReader(
|
|
archive.GetEntry("xl/worksheets/sheet1.xml").Open(),
|
|
Encoding.UTF8))
|
|
{
|
|
text = reader.ReadToEnd();
|
|
}
|
|
Assert(text.Contains("BizTalk-Anwendung in ACC"), "ACC-Spalte fehlt.");
|
|
Assert(text.Contains("BizTalk-Anwendung in PRD"), "PRD-Spalte fehlt.");
|
|
Assert(text.Contains("FILE (1x) / SFTP (1x)"), "Adapteraggregation ist falsch.");
|
|
Assert(text.Contains("Nur in ACC vorhanden"), "ACC-Hinweis fehlt.");
|
|
Assert(text.Contains("Nur in PRD vorhanden"), "PRD-Hinweis fehlt.");
|
|
Assert(text.Contains("Gesamt: 3 BizTalk-Anwendungen"), "Summenzeile ist falsch.");
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
try
|
|
{
|
|
if (File.Exists(jsonPath)) File.Delete(jsonPath);
|
|
if (!keepOutput && Directory.Exists(directory))
|
|
{
|
|
Directory.Delete(directory, true);
|
|
}
|
|
}
|
|
catch (IOException)
|
|
{
|
|
}
|
|
catch (UnauthorizedAccessException)
|
|
{
|
|
}
|
|
}
|
|
}
|
|
|
|
private static CatalogSnapshot AccSnapshot()
|
|
{
|
|
var snapshot = Snapshot("ACC", "BIZTALK-ACC");
|
|
snapshot.Applications.Add(Application(
|
|
"OrderProcessing",
|
|
new AdapterCount { AdapterType = "FILE", Count = 1 },
|
|
new AdapterCount { AdapterType = "SFTP", Count = 1 }));
|
|
snapshot.Applications.Add(Application(
|
|
"AccOnly",
|
|
new AdapterCount { AdapterType = "FILE", Count = 1 }));
|
|
return snapshot;
|
|
}
|
|
|
|
private static CatalogSnapshot ProdSnapshot()
|
|
{
|
|
var snapshot = Snapshot("PROD", "BIZTALK-PROD");
|
|
snapshot.Applications.Add(Application(
|
|
"OrderProcessing",
|
|
new AdapterCount { AdapterType = "FILE", Count = 1 },
|
|
new AdapterCount { AdapterType = "SFTP", Count = 1 }));
|
|
snapshot.Applications.Add(Application(
|
|
"ProdOnly",
|
|
new AdapterCount { AdapterType = "SFTP", Count = 1 }));
|
|
return snapshot;
|
|
}
|
|
|
|
private static CatalogSnapshot Snapshot(
|
|
string environment,
|
|
string computer)
|
|
{
|
|
return new CatalogSnapshot
|
|
{
|
|
EnvironmentName = environment,
|
|
ComputerName = computer,
|
|
CreatedUtc = DateTime.UtcNow.ToString("o"),
|
|
IsComplete = true
|
|
};
|
|
}
|
|
|
|
private static CatalogApplication Application(
|
|
string name,
|
|
params AdapterCount[] adapters)
|
|
{
|
|
var result = new CatalogApplication
|
|
{
|
|
Name = name,
|
|
EndpointCount = adapters.Sum(item => item.Count)
|
|
};
|
|
result.AdapterCounts.AddRange(adapters);
|
|
return result;
|
|
}
|
|
|
|
private static XDocument LoadXml(ZipArchive archive, string name)
|
|
{
|
|
using (var stream = archive.GetEntry(name).Open())
|
|
{
|
|
return XDocument.Load(stream);
|
|
}
|
|
}
|
|
|
|
private static void Assert(bool condition, string message)
|
|
{
|
|
if (!condition) throw new InvalidOperationException(message);
|
|
}
|
|
}
|
|
}
|