-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add test for syncing complex forms twice (#1256)
* Add integration test for syncing sena-3 * prevent duplicating complex forms which are the same/already exist * catch and throw some exceptions with additional context to help debugging * change test project vernacular ws and change how ComplexFormComponent headwords get set so that they match what we get from fieldworks * ensure root service provider is cleaned up in fixtures to avoid issue where test host hangs once tests are done * ensure headword is stable * flatten Complex Form types from FW so we import all of them, not just the top level * ensure that all entries are created before complex forms during import to avoid issues where the complex form does not get created because it's referencing an entry which does not exist * don't try to download sena3 from lexbox, just download the zip from google drive * isolate sena3 sync tests rather than using the same project for each test * use HgRunner instead of trying to locate mercurial manually --------- Co-authored-by: Kevin Hahn <[email protected]>
- Loading branch information
Showing
27 changed files
with
818 additions
and
119 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
18 changes: 18 additions & 0 deletions
18
backend/FwLite/FwDataMiniLcmBridge/Api/PossibilityExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
using SIL.LCModel; | ||
|
||
namespace FwDataMiniLcmBridge.Api; | ||
|
||
public static class PossibilityExtensions | ||
{ | ||
public static IEnumerable<T> Flatten<T>(this IEnumerable<T> enumerable) where T : ICmPossibility | ||
{ | ||
foreach (var cmPossibility in enumerable) | ||
{ | ||
yield return cmPossibility; | ||
foreach (var child in Flatten(cmPossibility.SubPossibilitiesOS.Cast<T>())) | ||
{ | ||
yield return child; | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
backend/FwLite/FwLiteProjectSync.Tests/Fixtures/MercurialTestHelper.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
using Chorus.VcsDrivers.Mercurial; | ||
using SIL.CommandLineProcessing; | ||
using SIL.PlatformUtilities; | ||
using SIL.Progress; | ||
|
||
namespace FwLiteProjectSync.Tests.Fixtures; | ||
|
||
public static class MercurialTestHelper | ||
{ | ||
private static readonly NullProgress NullProgress = new NullProgress(); | ||
|
||
private static string RunHgCommand(string repoPath, string args) | ||
{ | ||
var result = HgRunner.Run(args, repoPath, 120, NullProgress); | ||
if (result.ExitCode == 0) return result.StandardOutput; | ||
throw new Exception( | ||
$"hg {args} failed.\nStdOut: {result.StandardOutput}\nStdErr: {result.StandardError}"); | ||
|
||
} | ||
|
||
public static void HgClean(string repoPath, string exclude) | ||
{ | ||
RunHgCommand(repoPath, $"purge --no-confirm --exclude {exclude}"); | ||
} | ||
|
||
public static void HgUpdate(string repoPath, string rev) | ||
{ | ||
RunHgCommand(repoPath, $"update \"{rev}\""); | ||
} | ||
} | ||
|
93 changes: 93 additions & 0 deletions
93
backend/FwLite/FwLiteProjectSync.Tests/Fixtures/Sena3SyncFixture.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
using System.IO.Compression; | ||
using FwDataMiniLcmBridge; | ||
using FwDataMiniLcmBridge.Api; | ||
using LcmCrdt; | ||
using LexCore.Utils; | ||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Extensions.Options; | ||
using SIL.IO; | ||
using SIL.Progress; | ||
|
||
namespace FwLiteProjectSync.Tests.Fixtures; | ||
|
||
public class Sena3Fixture : IAsyncLifetime | ||
{ | ||
private static readonly HttpClient http = new HttpClient(); | ||
|
||
public async Task InitializeAsync() | ||
{ | ||
var services = new ServiceCollection() | ||
.AddSyncServices(nameof(Sena3Fixture), false); | ||
var rootServiceProvider = services.BuildServiceProvider(); | ||
var fwProjectsFolder = rootServiceProvider.GetRequiredService<IOptions<FwDataBridgeConfig>>() | ||
.Value | ||
.ProjectsFolder; | ||
if (Path.Exists(fwProjectsFolder)) Directory.Delete(fwProjectsFolder, true); | ||
Directory.CreateDirectory(fwProjectsFolder); | ||
|
||
var crdtProjectsFolder = | ||
rootServiceProvider.GetRequiredService<IOptions<LcmCrdtConfig>>().Value.ProjectPath; | ||
if (Path.Exists(crdtProjectsFolder)) Directory.Delete(crdtProjectsFolder, true); | ||
rootServiceProvider.Dispose(); | ||
Check warning on line 31 in backend/FwLite/FwLiteProjectSync.Tests/Fixtures/Sena3SyncFixture.cs GitHub Actions / Build FW Lite and run tests
|
||
|
||
Directory.CreateDirectory(crdtProjectsFolder); | ||
await DownloadSena3(); | ||
} | ||
|
||
public async Task<(CrdtMiniLcmApi CrdtApi, FwDataMiniLcmApi FwDataApi, IServiceProvider services, IDisposable cleanup)> SetupProjects() | ||
{ | ||
var sena3MasterCopy = await DownloadSena3(); | ||
|
||
var rootServiceProvider = new ServiceCollection() | ||
.AddSyncServices(nameof(Sena3Fixture), false) | ||
.BuildServiceProvider(); | ||
var cleanup = Defer.Action(() => rootServiceProvider.Dispose()); | ||
var services = rootServiceProvider.CreateAsyncScope().ServiceProvider; | ||
var projectName = "sena-3_" + Guid.NewGuid().ToString("N"); | ||
|
||
var projectsFolder = services.GetRequiredService<IOptions<FwDataBridgeConfig>>() | ||
.Value | ||
.ProjectsFolder; | ||
var fwDataProject = new FwDataProject(projectName, projectsFolder); | ||
var fwDataProjectPath = Path.Combine(fwDataProject.ProjectsPath, fwDataProject.Name); | ||
DirectoryHelper.Copy(sena3MasterCopy, fwDataProjectPath); | ||
File.Move(Path.Combine(fwDataProjectPath, "sena-3.fwdata"), fwDataProject.FilePath); | ||
var fwDataMiniLcmApi = services.GetRequiredService<FwDataFactory>().GetFwDataMiniLcmApi(fwDataProject, false); | ||
|
||
var crdtProject = await services.GetRequiredService<ProjectsService>() | ||
.CreateProject(new(projectName, FwProjectId: fwDataMiniLcmApi.ProjectId, SeedNewProjectData: false)); | ||
var crdtMiniLcmApi = (CrdtMiniLcmApi)await services.OpenCrdtProject(crdtProject); | ||
return (crdtMiniLcmApi, fwDataMiniLcmApi, services, cleanup); | ||
} | ||
|
||
public Task DisposeAsync() | ||
{ | ||
return Task.CompletedTask; | ||
} | ||
|
||
private async Task<Stream> DownloadSena3ProjectBackupStream() | ||
{ | ||
var backupUrl = new Uri("https://drive.google.com/uc?export=download&id=1I-hwc0RHoQqW774gbS5qR-GHa1E7BlsS"); | ||
var result = await http.GetAsync(backupUrl, HttpCompletionOption.ResponseHeadersRead); | ||
return await result.Content.ReadAsStreamAsync(); | ||
} | ||
|
||
private async Task<string> DownloadSena3() | ||
{ | ||
var tempFolder = Path.Combine(Path.GetTempPath(), nameof(Sena3Fixture)); | ||
var sena3MasterCopy = Path.Combine(tempFolder, "sena-3"); | ||
if (!Directory.Exists(sena3MasterCopy) || !File.Exists(Path.Combine(sena3MasterCopy, "sena-3.fwdata"))) | ||
{ | ||
Directory.CreateDirectory(sena3MasterCopy); | ||
await using var zipStream = await DownloadSena3ProjectBackupStream(); | ||
//the zip file is structured like this: /sena-3/.hg | ||
//by extracting it to tempFolder it should merge with sena-3 | ||
ZipFile.ExtractToDirectory(zipStream, tempFolder); | ||
|
||
MercurialTestHelper.HgUpdate(sena3MasterCopy, "tip"); | ||
LfMergeBridge.LfMergeBridge.ReassembleFwdataFile(new NullProgress(), false, Path.Combine(sena3MasterCopy, "sena-3.fwdata")); | ||
MercurialTestHelper.HgClean(sena3MasterCopy, "sena-3.fwdata"); | ||
} | ||
return sena3MasterCopy; | ||
} | ||
} |
Oops, something went wrong.