mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
Implement tests for List validation
This commit is contained in:
parent
32d0752e3f
commit
7cf817853c
@ -7,6 +7,7 @@ using Microsoft.Extensions.Hosting;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.Http;
|
||||
using Wabbajack.Common.StatusFeed;
|
||||
using Wabbajack.Lib.FileUploader;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
@ -22,6 +23,8 @@ namespace Wabbajack.BuildServer.Test
|
||||
private bool _disposed = false;
|
||||
public AbsolutePath ServerTempFolder => _severTempFolder.Dir;
|
||||
|
||||
public AbsolutePath ServerPublicFolder => "public".RelativeTo(AbsolutePath.EntryPoint);
|
||||
|
||||
|
||||
public BuildServerFixture()
|
||||
{
|
||||
@ -42,6 +45,9 @@ namespace Wabbajack.BuildServer.Test
|
||||
_token = new CancellationTokenSource();
|
||||
_task = _host.RunAsync(_token.Token);
|
||||
Consts.WabbajackBuildServerUri = new Uri("http://localhost:8080");
|
||||
|
||||
"ServerWhitelist.yaml".RelativeTo(ServerPublicFolder).WriteAllText(
|
||||
"GoogleIDs:\nAllowedPrefixes:\n - http://localhost");
|
||||
}
|
||||
|
||||
~BuildServerFixture()
|
||||
@ -125,8 +131,11 @@ namespace Wabbajack.BuildServer.Test
|
||||
_authedClient = new Client();
|
||||
Fixture = fixture.Deref();
|
||||
_authedClient.Headers.Add(("x-api-key", Fixture.APIKey));
|
||||
AuthorAPI.ApiKeyOverride = Fixture.APIKey;
|
||||
_queue = new WorkQueue();
|
||||
Queue = new WorkQueue();
|
||||
Consts.ModlistSummaryURL = MakeURL("lists/status.json");
|
||||
Consts.ServerWhitelistURL = MakeURL("ServerWhitelist.yaml");
|
||||
}
|
||||
|
||||
public WorkQueue Queue { get; set; }
|
||||
|
126
Wabbajack.BuildServer.Test/ModListValidationTests.cs
Normal file
126
Wabbajack.BuildServer.Test/ModListValidationTests.cs
Normal file
@ -0,0 +1,126 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Security.Policy;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Wabbajack.BuildServer.Model.Models;
|
||||
using Wabbajack.BuildServer.Models.JobQueue;
|
||||
using Wabbajack.BuildServer.Models.Jobs;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Lib;
|
||||
using Wabbajack.Lib.Downloaders;
|
||||
using Wabbajack.Lib.FileUploader;
|
||||
using Wabbajack.Lib.ModListRegistry;
|
||||
using Xunit;
|
||||
using Xunit.Abstractions;
|
||||
|
||||
namespace Wabbajack.BuildServer.Test
|
||||
{
|
||||
public class ModListValidationTests : ABuildServerSystemTest
|
||||
{
|
||||
public ModListValidationTests(ITestOutputHelper output, SingletonAdaptor<BuildServerFixture> fixture) : base(output, fixture)
|
||||
{
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CanLoadMetadataFromTestServer()
|
||||
{
|
||||
var modlist = await MakeModList();
|
||||
Consts.ModlistMetadataURL = modlist.ToString();
|
||||
var data = await ModlistMetadata.LoadFromGithub();
|
||||
Assert.Single(data);
|
||||
Assert.Equal("test_list", data.First().Links.MachineURL);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task CanValidateModLists()
|
||||
{
|
||||
var modlists = await MakeModList();
|
||||
Consts.ModlistMetadataURL = modlists.ToString();
|
||||
Utils.Log("Updating modlists");
|
||||
var result = await AuthorAPI.UpdateServerModLists();
|
||||
Assert.NotNull(result);
|
||||
|
||||
var sql = Fixture.GetService<SqlService>();
|
||||
var settings = Fixture.GetService<AppSettings>();
|
||||
var job = await sql.GetJob();
|
||||
|
||||
Assert.NotNull(job);
|
||||
Assert.IsType<UpdateModLists>(job.Payload);
|
||||
|
||||
|
||||
var jobResult = await job.Payload.Execute(sql, settings);
|
||||
Assert.Equal(JobResultType.Success, jobResult.ResultType);
|
||||
|
||||
Utils.Log("Checking validated results");
|
||||
var data = await ModlistMetadata.LoadFromGithub();
|
||||
|
||||
Assert.Single(data);
|
||||
Assert.Equal(0, data.First().ValidationSummary.Failed);
|
||||
Assert.Equal(1, data.First().ValidationSummary.Passed);
|
||||
|
||||
}
|
||||
|
||||
|
||||
private async Task<Uri> MakeModList()
|
||||
{
|
||||
var archive_data = Encoding.UTF8.GetBytes("Cheese for Everyone!");
|
||||
var test_archive_path = "test_archive.txt".RelativeTo(Fixture.ServerPublicFolder);
|
||||
await test_archive_path.WriteAllBytesAsync(archive_data);
|
||||
|
||||
|
||||
|
||||
var modListData = new ModList
|
||||
{
|
||||
Archives = new List<Archive>
|
||||
{
|
||||
new Archive
|
||||
{
|
||||
Hash = await test_archive_path.FileHashAsync(),
|
||||
Name = "test_archive",
|
||||
Size = test_archive_path.Size,
|
||||
State = new HTTPDownloader.State {Url = MakeURL("test_archive.txt")}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var modListPath = "test_modlist.wabbajack".RelativeTo(Fixture.ServerPublicFolder);
|
||||
|
||||
await using (var fs = modListPath.Create())
|
||||
{
|
||||
using var za = new ZipArchive(fs, ZipArchiveMode.Create);
|
||||
var entry = za.CreateEntry("modlist.json");
|
||||
await using var es = entry.Open();
|
||||
modListData.ToJson(es);
|
||||
}
|
||||
|
||||
var modListMetaData = new List<ModlistMetadata>
|
||||
{
|
||||
new ModlistMetadata
|
||||
{
|
||||
Official = false,
|
||||
Author = "Test Suite",
|
||||
Description = "A test",
|
||||
DownloadMetadata = new DownloadMetadata
|
||||
{
|
||||
Hash = await modListPath.FileHashAsync(),
|
||||
Size = modListPath.Size
|
||||
},
|
||||
Links = new ModlistMetadata.LinksObject
|
||||
{
|
||||
MachineURL = "test_list",
|
||||
Download = MakeURL("test_modlist.wabbajack")
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var metadataPath = "test_mod_list_metadata.json".RelativeTo(Fixture.ServerPublicFolder);
|
||||
|
||||
modListMetaData.ToJson(metadataPath);
|
||||
|
||||
return new Uri(MakeURL("test_mod_list_metadata.json"));
|
||||
}
|
||||
}
|
||||
}
|
@ -22,7 +22,7 @@ namespace Wabbajack.BuildServer.Controllers
|
||||
|
||||
[HttpGet]
|
||||
[Route("status.json")]
|
||||
public async Task<IEnumerable<ModlistSummary>> HandleGetLists()
|
||||
public async Task<IEnumerable<ModListSummary>> HandleGetLists()
|
||||
{
|
||||
return await SQL.GetModListSummaries();
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ namespace Wabbajack.BuildServer.Models.Jobs
|
||||
var dto = new ModListStatus
|
||||
{
|
||||
Id = list.Links.MachineURL,
|
||||
Summary = new ModlistSummary
|
||||
Summary = new ModListSummary
|
||||
{
|
||||
Name = status.Name,
|
||||
MachineURL = list.Links?.MachineURL ?? status.Name,
|
||||
|
@ -2,6 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Wabbajack.Common.Serialization.Json;
|
||||
using Wabbajack.Lib;
|
||||
using Wabbajack.Lib.ModListRegistry;
|
||||
|
||||
@ -10,7 +11,7 @@ namespace Wabbajack.BuildServer.Models
|
||||
public class ModListStatus
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public ModlistSummary Summary { get; set; }
|
||||
public ModListSummary Summary { get; set; }
|
||||
|
||||
public ModlistMetadata Metadata { get; set; }
|
||||
public DetailedStatus DetailedStatus { get; set; }
|
||||
@ -24,6 +25,7 @@ namespace Wabbajack.BuildServer.Models
|
||||
}
|
||||
}
|
||||
|
||||
[JsonName("DetailedStatus")]
|
||||
public class DetailedStatus
|
||||
{
|
||||
public string Name { get; set; }
|
||||
@ -34,6 +36,7 @@ namespace Wabbajack.BuildServer.Models
|
||||
public string MachineName { get; set; }
|
||||
}
|
||||
|
||||
[JsonName("DetailedStatusItem")]
|
||||
public class DetailedStatusItem
|
||||
{
|
||||
public bool IsFailing { get; set; }
|
||||
|
@ -447,11 +447,11 @@ namespace Wabbajack.BuildServer.Model.Models
|
||||
}
|
||||
|
||||
#region ModLists
|
||||
public async Task<IEnumerable<ModlistSummary>> GetModListSummaries()
|
||||
public async Task<IEnumerable<ModListSummary>> GetModListSummaries()
|
||||
{
|
||||
await using var conn = await Open();
|
||||
var results = await conn.QueryAsync<string>("SELECT Summary from dbo.ModLists");
|
||||
return results.Select(s => s.FromJsonString<ModlistSummary>()).ToList();
|
||||
return results.Select(s => s.FromJsonString<ModListSummary>()).ToList();
|
||||
}
|
||||
|
||||
public async Task<DetailedStatus> GetDetailedModlistStatus(string machineUrl)
|
||||
@ -599,8 +599,8 @@ namespace Wabbajack.BuildServer.Model.Models
|
||||
await conn.ExecuteAsync(@"MERGE dbo.ModLists AS Target
|
||||
USING (SELECT @MachineUrl MachineUrl, @Metadata Metadata, @Summary Summary, @DetailedStatus DetailedStatus) AS Source
|
||||
ON Target.MachineUrl = Source.MachineUrl
|
||||
WHEN MATCHED THEN UPDATE SET Target.Summary = Source.Summary, Target.Metadata = Source.Metadata, Target.DetailedStatus = Source.DetailedStats
|
||||
WHEN NOT MATCHED THEN INSERT (MachineUrl, Summary, Metadata, DetailedStatus) VALUES (@MachineUrl, @Summary, @Metadata, @DetailedStatus)",
|
||||
WHEN MATCHED THEN UPDATE SET Target.Summary = Source.Summary, Target.Metadata = Source.Metadata, Target.DetailedStatus = Source.DetailedStatus
|
||||
WHEN NOT MATCHED THEN INSERT (MachineUrl, Summary, Metadata, DetailedStatus) VALUES (@MachineUrl, @Summary, @Metadata, @DetailedStatus);",
|
||||
new
|
||||
{
|
||||
MachineUrl = dto.Metadata.Links.MachineURL,
|
||||
|
@ -81,7 +81,6 @@ namespace Wabbajack.Common
|
||||
|
||||
}.Select(s => (RelativePath)s).ToHashSet();
|
||||
|
||||
public static string ModPermissionsURL = "https://raw.githubusercontent.com/wabbajack-tools/opt-out-lists/master/NexusModPermissions.yml";
|
||||
public static string ServerWhitelistURL = "https://raw.githubusercontent.com/wabbajack-tools/opt-out-lists/master/ServerWhitelist.yml";
|
||||
public static string ModlistMetadataURL = "https://raw.githubusercontent.com/wabbajack-tools/mod-lists/master/modlists.json";
|
||||
public static string ModlistSummaryURL = "http://build.wabbajack.org/lists/status.json";
|
||||
|
@ -47,6 +47,12 @@ namespace Wabbajack.Common
|
||||
var ser = JsonSerializer.Create(JsonSettings);
|
||||
ser.Serialize(writer, obj);
|
||||
}
|
||||
|
||||
public static void ToJson<T>(this T obj, AbsolutePath path)
|
||||
{
|
||||
using var fs = path.Create();
|
||||
obj.ToJson(fs);
|
||||
}
|
||||
|
||||
public static string ToJson<T>(this T obj)
|
||||
{
|
||||
|
@ -21,8 +21,11 @@ namespace Wabbajack.Lib.FileUploader
|
||||
{
|
||||
public static IObservable<bool> HaveAuthorAPIKey => Utils.HaveEncryptedJsonObservable(Consts.AuthorAPIKeyFile);
|
||||
|
||||
public static string ApiKeyOverride = null;
|
||||
|
||||
public static async Task<string> GetAPIKey(string apiKey = null)
|
||||
{
|
||||
if (ApiKeyOverride != null) return ApiKeyOverride;
|
||||
return apiKey ?? (await Consts.LocalAppDataPath.Combine(Consts.AuthorAPIKeyFile).ReadAllTextAsync()).Trim();
|
||||
}
|
||||
|
||||
@ -130,7 +133,7 @@ namespace Wabbajack.Lib.FileUploader
|
||||
public static async Task<string> RunJob(string jobtype)
|
||||
{
|
||||
var client = await GetAuthorizedClient();
|
||||
return await client.GetStringAsync($"https://{Consts.WabbajackCacheHostname}/jobs/enqueue_job/{jobtype}");
|
||||
return await client.GetStringAsync($"{Consts.WabbajackBuildServerUri}jobs/enqueue_job/{jobtype}");
|
||||
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@ using Game = Wabbajack.Common.Game;
|
||||
|
||||
namespace Wabbajack.Lib.ModListRegistry
|
||||
{
|
||||
[JsonName("ModListMetadata")]
|
||||
public class ModlistMetadata
|
||||
{
|
||||
[JsonProperty("title")]
|
||||
@ -35,8 +36,9 @@ namespace Wabbajack.Lib.ModListRegistry
|
||||
public DownloadMetadata DownloadMetadata { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public ModlistSummary ValidationSummary { get; set; } = new ModlistSummary();
|
||||
public ModListSummary ValidationSummary { get; set; } = new ModListSummary();
|
||||
|
||||
[JsonName("Links")]
|
||||
public class LinksObject
|
||||
{
|
||||
[JsonProperty("image")]
|
||||
@ -66,10 +68,10 @@ namespace Wabbajack.Lib.ModListRegistry
|
||||
var metadata = (await metadataResult).FromJsonString<List<ModlistMetadata>>();
|
||||
try
|
||||
{
|
||||
var summaries = (await summaryResult).FromJsonString<List<ModlistSummary>>().ToDictionary(d => d.Name);
|
||||
var summaries = (await summaryResult).FromJsonString<List<ModListSummary>>().ToDictionary(d => d.MachineURL);
|
||||
|
||||
foreach (var data in metadata)
|
||||
if (summaries.TryGetValue(data.Title, out var summary))
|
||||
if (summaries.TryGetValue(data.Links.MachineURL, out var summary))
|
||||
data.ValidationSummary = summary;
|
||||
}
|
||||
catch (Exception)
|
||||
@ -104,7 +106,8 @@ namespace Wabbajack.Lib.ModListRegistry
|
||||
|
||||
}
|
||||
|
||||
public class ModlistSummary
|
||||
[JsonName("ModListSummary")]
|
||||
public class ModListSummary
|
||||
{
|
||||
[JsonProperty("name")]
|
||||
public string Name { get; set; }
|
||||
|
@ -31,7 +31,7 @@ namespace Wabbajack.Lib.Validation
|
||||
using (var result = await response.Content.ReadAsStreamAsync())
|
||||
{
|
||||
ServerWhitelist = result.FromYaml<ServerWhitelist>();
|
||||
Utils.Log($"Loaded permissions for {ServerWhitelist.AllowedPrefixes.Count} servers and {ServerWhitelist.GoogleIDs.Count} Google Drive files");
|
||||
Utils.Log($"Loaded permissions for {ServerWhitelist.AllowedPrefixes?.Count ?? 0} servers and {ServerWhitelist.GoogleIDs?.Count ?? 0} Google Drive files");
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -44,23 +44,6 @@ steps:
|
||||
command: 'test'
|
||||
projects: '**/*.Test.csproj'
|
||||
arguments: '/p:Platform=x64 /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput=$(Build.SourcesDirectory)/CodeCoverage'
|
||||
|
||||
# Generate the report using ReportGenerator (https://github.com/danielpalme/ReportGenerator)
|
||||
# First install the tool on the machine, then run it
|
||||
- script: |
|
||||
dotnet tool install -g dotnet-reportgenerator-globaltool
|
||||
reportgenerator -reports:$(Build.SourcesDirectory)/tests/**/coverage.cobertura.xml -targetdir:$(Build.SourcesDirectory)/CodeCoverage -reporttypes:HtmlInline_AzurePipelines;Cobertura
|
||||
displayName: Create Code coverage report
|
||||
|
||||
# Publish the code coverage result (summary and web site)
|
||||
# The summary allows to view the coverage percentage in the summary tab
|
||||
# The web site allows to view which lines are covered directly in Azure Pipeline
|
||||
- task: PublishCodeCoverageResults@1
|
||||
displayName: 'Publish code coverage'
|
||||
inputs:
|
||||
codeCoverageTool: Cobertura
|
||||
summaryFileLocation: '$(Build.SourcesDirectory)/CodeCoverage/Cobertura.xml'
|
||||
reportDirectory: '$(Build.SourcesDirectory)/CodeCoverage'
|
||||
|
||||
- task: DotNetCoreCLI@2
|
||||
inputs:
|
||||
|
Loading…
Reference in New Issue
Block a user