From a3717e4bcb5de9a8cd63890774ebf7b10d3cc818 Mon Sep 17 00:00:00 2001 From: Jared Fine Date: Thu, 7 Nov 2024 21:58:38 +0000 Subject: [PATCH 01/13] Add --git-archive-file-path and --metadata-archive-file-path options --- .../MigrateRepoCommandArgsTests.cs | 79 +++++++++++++++++++ .../MigrateRepo/MigrateRepoCommandTests.cs | 4 +- .../MigrateRepo/MigrateRepoCommand.cs | 16 +++- .../MigrateRepo/MigrateRepoCommandArgs.cs | 17 ++++ 4 files changed, 111 insertions(+), 5 deletions(-) diff --git a/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandArgsTests.cs b/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandArgsTests.cs index 6104bd4c2..94f4b1186 100644 --- a/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandArgsTests.cs +++ b/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandArgsTests.cs @@ -16,6 +16,10 @@ public class MigrateRepoCommandArgsTests private const string GITHUB_TARGET_PAT = "github-target-pat"; private const string AWS_BUCKET_NAME = "aws-bucket-name"; private const string GHES_API_URL = "foo-ghes-api.com"; + private const string GIT_ARCHIVE_URL = "http://host/git-archive.tar.gz"; + private const string METADATA_ARCHIVE_URL = "http://host/metadata-archive.tar.gz"; + private const string GIT_ARCHIVE_FILE_PATH = "./git-archive.tar.gz"; + private const string METADATA_ARCHIVE_FILE_PATH = "./metadata-archive.tar.gz"; [Fact] public void Defaults_TargetRepo_To_SourceRepo() @@ -124,6 +128,7 @@ public void It_Throws_When_Aws_Bucket_Name_Provided_With_AzureStorageConnectionS .ThrowExactly() .WithMessage("*--use-github-storage flag*"); } + [Fact] public void No_Ssl_Verify_Without_Ghes_Api_Url_Throws() { @@ -159,5 +164,79 @@ public void Keep_Archive_Without_Ghes_Api_Url_Throws() .ThrowExactly() .WithMessage("*--keep-archive*"); } + + [Fact] + public void GitArchiveFilePath_Without_MetadataArchiveFilePath_Throws() + { + var args = new MigrateRepoCommandArgs + { + SourceRepo = SOURCE_REPO, + GithubSourceOrg = SOURCE_ORG, + GithubTargetOrg = TARGET_ORG, + TargetRepo = TARGET_REPO, + GitArchiveFilePath = GIT_ARCHIVE_FILE_PATH + }; + + FluentActions.Invoking(() => args.Validate(_mockOctoLogger.Object)) + .Should() + .ThrowExactly() + .WithMessage("*you must provide both --git-archive-file-path --metadata-archive-file-path*"); + } + + [Fact] + public void MetadataArchiveFilePath_Without_GitArchiveFilePath_Throws() + { + var args = new MigrateRepoCommandArgs + { + SourceRepo = SOURCE_REPO, + GithubSourceOrg = SOURCE_ORG, + GithubTargetOrg = TARGET_ORG, + TargetRepo = TARGET_REPO, + MetadataArchiveFilePath = METADATA_ARCHIVE_FILE_PATH + }; + + FluentActions.Invoking(() => args.Validate(_mockOctoLogger.Object)) + .Should() + .ThrowExactly() + .WithMessage("*you must provide both --git-archive-file-path --metadata-archive-file-path*"); + } + + [Fact] + public void GitArchiveUrl_With_GitArchiveFilePath_Throws() + { + var args = new MigrateRepoCommandArgs + { + SourceRepo = SOURCE_REPO, + GithubSourceOrg = SOURCE_ORG, + GithubTargetOrg = TARGET_ORG, + TargetRepo = TARGET_REPO, + GitArchiveUrl = GIT_ARCHIVE_URL, + GitArchiveFilePath = GIT_ARCHIVE_FILE_PATH + }; + + FluentActions.Invoking(() => args.Validate(_mockOctoLogger.Object)) + .Should() + .ThrowExactly() + .WithMessage("*--git-archive-url and --git-archive-file-path may not be used together*"); + } + + [Fact] + public void MetadataArchiveUrl_With_MetadataArchiveFilePath_Throws() + { + var args = new MigrateRepoCommandArgs + { + SourceRepo = SOURCE_REPO, + GithubSourceOrg = SOURCE_ORG, + GithubTargetOrg = TARGET_ORG, + TargetRepo = TARGET_REPO, + MetadataArchiveUrl = METADATA_ARCHIVE_URL, + MetadataArchiveFilePath = METADATA_ARCHIVE_FILE_PATH + }; + + FluentActions.Invoking(() => args.Validate(_mockOctoLogger.Object)) + .Should() + .ThrowExactly() + .WithMessage("*--metadata-archive-url and --metadata-archive-file-path may not be used together*"); + } } } diff --git a/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandTests.cs b/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandTests.cs index df42dc8b9..c3b70f914 100644 --- a/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandTests.cs +++ b/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandTests.cs @@ -13,7 +13,7 @@ public void Should_Have_Options() command.Should().NotBeNull(); command.Name.Should().Be("migrate-repo"); - command.Options.Count.Should().Be(24); + command.Options.Count.Should().Be(26); TestHelpers.VerifyCommandOption(command.Options, "github-source-org", true); TestHelpers.VerifyCommandOption(command.Options, "source-repo", true); @@ -31,6 +31,8 @@ public void Should_Have_Options() TestHelpers.VerifyCommandOption(command.Options, "skip-releases", false); TestHelpers.VerifyCommandOption(command.Options, "git-archive-url", false, true); TestHelpers.VerifyCommandOption(command.Options, "metadata-archive-url", false, true); + TestHelpers.VerifyCommandOption(command.Options, "git-archive-file-path", false, true); + TestHelpers.VerifyCommandOption(command.Options, "metadata-archive-file-path", false, true); TestHelpers.VerifyCommandOption(command.Options, "queue-only", false); TestHelpers.VerifyCommandOption(command.Options, "target-repo-visibility", false); TestHelpers.VerifyCommandOption(command.Options, "github-source-pat", false); diff --git a/src/gei/Commands/MigrateRepo/MigrateRepoCommand.cs b/src/gei/Commands/MigrateRepo/MigrateRepoCommand.cs index 1009c37b7..ddb3271cf 100644 --- a/src/gei/Commands/MigrateRepo/MigrateRepoCommand.cs +++ b/src/gei/Commands/MigrateRepo/MigrateRepoCommand.cs @@ -21,7 +21,6 @@ public MigrateRepoCommand() : base( AddOption(GithubTargetOrg); AddOption(TargetRepo); AddOption(TargetApiUrl); - AddOption(GhesApiUrl); AddOption(AzureStorageConnectionString); AddOption(AwsBucketName); @@ -30,13 +29,12 @@ public MigrateRepoCommand() : base( AddOption(AwsSessionToken); AddOption(AwsRegion); AddOption(NoSslVerify); - AddOption(GitArchiveUrl); AddOption(MetadataArchiveUrl); - + AddOption(GitArchiveFilePath); + AddOption(MetadataArchiveFilePath); AddOption(SkipReleases); AddOption(LockSourceRepo); - AddOption(QueueOnly); AddOption(TargetRepoVisibility.FromAmong("public", "private", "internal")); AddOption(GithubSourcePat); @@ -120,6 +118,16 @@ public MigrateRepoCommand() : base( IsHidden = true, Description = "An authenticated SAS URL to an Azure Blob Storage container with a pre-generated metadata archive. Only used when an archive has been generated and uploaded prior to running a migration (not common). Must be passed in when also using --git-archive-url" }; + public Option GitArchiveFilePath { get; } = new("--git-archive-file-path") + { + IsHidden = true, + Description = "Used to migrate an archive that is on disk, must be used with --metadata-archive-file-path" + }; + public Option MetadataArchiveFilePath { get; } = new("--metadata-archive-file-path") + { + IsHidden = true, + Description = "Used to migrate an archive that is on disk, must be used with --git-archive-file-path" + }; public Option SkipReleases { get; } = new("--skip-releases") { Description = "Skip releases when migrating." diff --git a/src/gei/Commands/MigrateRepo/MigrateRepoCommandArgs.cs b/src/gei/Commands/MigrateRepo/MigrateRepoCommandArgs.cs index 73d02c8e3..56e736577 100644 --- a/src/gei/Commands/MigrateRepo/MigrateRepoCommandArgs.cs +++ b/src/gei/Commands/MigrateRepo/MigrateRepoCommandArgs.cs @@ -25,6 +25,8 @@ public class MigrateRepoCommandArgs : CommandArgs public bool NoSslVerify { get; set; } public string GitArchiveUrl { get; set; } public string MetadataArchiveUrl { get; set; } + public string GitArchiveFilePath { get; set; } + public string MetadataArchiveFilePath { get; set; } public bool SkipReleases { get; set; } public bool LockSourceRepo { get; set; } public bool QueueOnly { get; set; } @@ -41,11 +43,26 @@ public override void Validate(OctoLogger log) DefaultSourcePat(log); DefaultTargetRepo(log); + if (GitArchiveUrl.HasValue() && GitArchiveFilePath.HasValue()) + { + throw new OctoshiftCliException("The options --git-archive-url and --git-archive-file-path may not be used together"); + } + + if (MetadataArchiveUrl.HasValue() && MetadataArchiveFilePath.HasValue()) + { + throw new OctoshiftCliException("The options --metadata-archive-url and --metadata-archive-file-path may not be used together"); + } + if (string.IsNullOrWhiteSpace(GitArchiveUrl) != string.IsNullOrWhiteSpace(MetadataArchiveUrl)) { throw new OctoshiftCliException("When using archive urls, you must provide both --git-archive-url --metadata-archive-url"); } + if (string.IsNullOrWhiteSpace(GitArchiveFilePath) != string.IsNullOrWhiteSpace(MetadataArchiveFilePath)) + { + throw new OctoshiftCliException("When using archive files, you must provide both --git-archive-file-path --metadata-archive-file-path"); + } + if (GhesApiUrl.IsNullOrWhiteSpace()) { if (AwsBucketName.HasValue()) From 1f328da4b48687841cfb9edf4a557d83454f0c74 Mon Sep 17 00:00:00 2001 From: Jared Fine Date: Fri, 8 Nov 2024 17:28:00 +0000 Subject: [PATCH 02/13] Just path instead of file path --- .../MigrateRepoCommandArgsTests.cs | 28 +++++++++---------- .../MigrateRepo/MigrateRepoCommandTests.cs | 4 +-- .../MigrateRepo/MigrateRepoCommand.cs | 12 ++++---- .../MigrateRepo/MigrateRepoCommandArgs.cs | 16 +++++------ 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandArgsTests.cs b/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandArgsTests.cs index 94f4b1186..c1da1e2fa 100644 --- a/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandArgsTests.cs +++ b/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandArgsTests.cs @@ -18,8 +18,8 @@ public class MigrateRepoCommandArgsTests private const string GHES_API_URL = "foo-ghes-api.com"; private const string GIT_ARCHIVE_URL = "http://host/git-archive.tar.gz"; private const string METADATA_ARCHIVE_URL = "http://host/metadata-archive.tar.gz"; - private const string GIT_ARCHIVE_FILE_PATH = "./git-archive.tar.gz"; - private const string METADATA_ARCHIVE_FILE_PATH = "./metadata-archive.tar.gz"; + private const string GIT_ARCHIVE_PATH = "./git-archive.tar.gz"; + private const string METADATA_ARCHIVE_PATH = "./metadata-archive.tar.gz"; [Fact] public void Defaults_TargetRepo_To_SourceRepo() @@ -166,7 +166,7 @@ public void Keep_Archive_Without_Ghes_Api_Url_Throws() } [Fact] - public void GitArchiveFilePath_Without_MetadataArchiveFilePath_Throws() + public void GitArchivePath_Without_MetadataArchivePath_Throws() { var args = new MigrateRepoCommandArgs { @@ -174,17 +174,17 @@ public void GitArchiveFilePath_Without_MetadataArchiveFilePath_Throws() GithubSourceOrg = SOURCE_ORG, GithubTargetOrg = TARGET_ORG, TargetRepo = TARGET_REPO, - GitArchiveFilePath = GIT_ARCHIVE_FILE_PATH + GitArchivePath = GIT_ARCHIVE_PATH }; FluentActions.Invoking(() => args.Validate(_mockOctoLogger.Object)) .Should() .ThrowExactly() - .WithMessage("*you must provide both --git-archive-file-path --metadata-archive-file-path*"); + .WithMessage("*you must provide both --git-archive-path --metadata-archive-path*"); } [Fact] - public void MetadataArchiveFilePath_Without_GitArchiveFilePath_Throws() + public void MetadataArchivePath_Without_GitArchivePath_Throws() { var args = new MigrateRepoCommandArgs { @@ -192,17 +192,17 @@ public void MetadataArchiveFilePath_Without_GitArchiveFilePath_Throws() GithubSourceOrg = SOURCE_ORG, GithubTargetOrg = TARGET_ORG, TargetRepo = TARGET_REPO, - MetadataArchiveFilePath = METADATA_ARCHIVE_FILE_PATH + MetadataArchivePath = METADATA_ARCHIVE_PATH }; FluentActions.Invoking(() => args.Validate(_mockOctoLogger.Object)) .Should() .ThrowExactly() - .WithMessage("*you must provide both --git-archive-file-path --metadata-archive-file-path*"); + .WithMessage("*you must provide both --git-archive-path --metadata-archive-path*"); } [Fact] - public void GitArchiveUrl_With_GitArchiveFilePath_Throws() + public void GitArchiveUrl_With_GitArchivePath_Throws() { var args = new MigrateRepoCommandArgs { @@ -211,17 +211,17 @@ public void GitArchiveUrl_With_GitArchiveFilePath_Throws() GithubTargetOrg = TARGET_ORG, TargetRepo = TARGET_REPO, GitArchiveUrl = GIT_ARCHIVE_URL, - GitArchiveFilePath = GIT_ARCHIVE_FILE_PATH + GitArchivePath = GIT_ARCHIVE_PATH }; FluentActions.Invoking(() => args.Validate(_mockOctoLogger.Object)) .Should() .ThrowExactly() - .WithMessage("*--git-archive-url and --git-archive-file-path may not be used together*"); + .WithMessage("*--git-archive-url and --git-archive-path may not be used together*"); } [Fact] - public void MetadataArchiveUrl_With_MetadataArchiveFilePath_Throws() + public void MetadataArchiveUrl_With_MetadataArchivePath_Throws() { var args = new MigrateRepoCommandArgs { @@ -230,13 +230,13 @@ public void MetadataArchiveUrl_With_MetadataArchiveFilePath_Throws() GithubTargetOrg = TARGET_ORG, TargetRepo = TARGET_REPO, MetadataArchiveUrl = METADATA_ARCHIVE_URL, - MetadataArchiveFilePath = METADATA_ARCHIVE_FILE_PATH + MetadataArchivePath = METADATA_ARCHIVE_PATH }; FluentActions.Invoking(() => args.Validate(_mockOctoLogger.Object)) .Should() .ThrowExactly() - .WithMessage("*--metadata-archive-url and --metadata-archive-file-path may not be used together*"); + .WithMessage("*--metadata-archive-url and --metadata-archive-path may not be used together*"); } } } diff --git a/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandTests.cs b/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandTests.cs index c3b70f914..be0fc095c 100644 --- a/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandTests.cs +++ b/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandTests.cs @@ -31,8 +31,8 @@ public void Should_Have_Options() TestHelpers.VerifyCommandOption(command.Options, "skip-releases", false); TestHelpers.VerifyCommandOption(command.Options, "git-archive-url", false, true); TestHelpers.VerifyCommandOption(command.Options, "metadata-archive-url", false, true); - TestHelpers.VerifyCommandOption(command.Options, "git-archive-file-path", false, true); - TestHelpers.VerifyCommandOption(command.Options, "metadata-archive-file-path", false, true); + TestHelpers.VerifyCommandOption(command.Options, "git-archive-path", false, true); + TestHelpers.VerifyCommandOption(command.Options, "metadata-archive-path", false, true); TestHelpers.VerifyCommandOption(command.Options, "queue-only", false); TestHelpers.VerifyCommandOption(command.Options, "target-repo-visibility", false); TestHelpers.VerifyCommandOption(command.Options, "github-source-pat", false); diff --git a/src/gei/Commands/MigrateRepo/MigrateRepoCommand.cs b/src/gei/Commands/MigrateRepo/MigrateRepoCommand.cs index ddb3271cf..af5b29c5c 100644 --- a/src/gei/Commands/MigrateRepo/MigrateRepoCommand.cs +++ b/src/gei/Commands/MigrateRepo/MigrateRepoCommand.cs @@ -31,8 +31,8 @@ public MigrateRepoCommand() : base( AddOption(NoSslVerify); AddOption(GitArchiveUrl); AddOption(MetadataArchiveUrl); - AddOption(GitArchiveFilePath); - AddOption(MetadataArchiveFilePath); + AddOption(GitArchivePath); + AddOption(MetadataArchivePath); AddOption(SkipReleases); AddOption(LockSourceRepo); AddOption(QueueOnly); @@ -118,15 +118,15 @@ public MigrateRepoCommand() : base( IsHidden = true, Description = "An authenticated SAS URL to an Azure Blob Storage container with a pre-generated metadata archive. Only used when an archive has been generated and uploaded prior to running a migration (not common). Must be passed in when also using --git-archive-url" }; - public Option GitArchiveFilePath { get; } = new("--git-archive-file-path") + public Option GitArchivePath { get; } = new("--git-archive-path") { IsHidden = true, - Description = "Used to migrate an archive that is on disk, must be used with --metadata-archive-file-path" + Description = "Used to migrate an archive that is on disk, must be used with --metadata-archive-path" }; - public Option MetadataArchiveFilePath { get; } = new("--metadata-archive-file-path") + public Option MetadataArchivePath { get; } = new("--metadata-archive-path") { IsHidden = true, - Description = "Used to migrate an archive that is on disk, must be used with --git-archive-file-path" + Description = "Used to migrate an archive that is on disk, must be used with --git-archive-path" }; public Option SkipReleases { get; } = new("--skip-releases") { diff --git a/src/gei/Commands/MigrateRepo/MigrateRepoCommandArgs.cs b/src/gei/Commands/MigrateRepo/MigrateRepoCommandArgs.cs index 56e736577..2287af0fb 100644 --- a/src/gei/Commands/MigrateRepo/MigrateRepoCommandArgs.cs +++ b/src/gei/Commands/MigrateRepo/MigrateRepoCommandArgs.cs @@ -25,8 +25,8 @@ public class MigrateRepoCommandArgs : CommandArgs public bool NoSslVerify { get; set; } public string GitArchiveUrl { get; set; } public string MetadataArchiveUrl { get; set; } - public string GitArchiveFilePath { get; set; } - public string MetadataArchiveFilePath { get; set; } + public string GitArchivePath { get; set; } + public string MetadataArchivePath { get; set; } public bool SkipReleases { get; set; } public bool LockSourceRepo { get; set; } public bool QueueOnly { get; set; } @@ -43,14 +43,14 @@ public override void Validate(OctoLogger log) DefaultSourcePat(log); DefaultTargetRepo(log); - if (GitArchiveUrl.HasValue() && GitArchiveFilePath.HasValue()) + if (GitArchiveUrl.HasValue() && GitArchivePath.HasValue()) { - throw new OctoshiftCliException("The options --git-archive-url and --git-archive-file-path may not be used together"); + throw new OctoshiftCliException("The options --git-archive-url and --git-archive-path may not be used together"); } - if (MetadataArchiveUrl.HasValue() && MetadataArchiveFilePath.HasValue()) + if (MetadataArchiveUrl.HasValue() && MetadataArchivePath.HasValue()) { - throw new OctoshiftCliException("The options --metadata-archive-url and --metadata-archive-file-path may not be used together"); + throw new OctoshiftCliException("The options --metadata-archive-url and --metadata-archive-path may not be used together"); } if (string.IsNullOrWhiteSpace(GitArchiveUrl) != string.IsNullOrWhiteSpace(MetadataArchiveUrl)) @@ -58,9 +58,9 @@ public override void Validate(OctoLogger log) throw new OctoshiftCliException("When using archive urls, you must provide both --git-archive-url --metadata-archive-url"); } - if (string.IsNullOrWhiteSpace(GitArchiveFilePath) != string.IsNullOrWhiteSpace(MetadataArchiveFilePath)) + if (string.IsNullOrWhiteSpace(GitArchivePath) != string.IsNullOrWhiteSpace(MetadataArchivePath)) { - throw new OctoshiftCliException("When using archive files, you must provide both --git-archive-file-path --metadata-archive-file-path"); + throw new OctoshiftCliException("When using archive files, you must provide both --git-archive-path --metadata-archive-path"); } if (GhesApiUrl.IsNullOrWhiteSpace()) From 24dd5d496b2dc79fd73fc0a785082715680fef38 Mon Sep 17 00:00:00 2001 From: Jared Fine Date: Mon, 18 Nov 2024 22:09:43 +0000 Subject: [PATCH 03/13] Break out archive upload and utilize for archive path options --- .../MigrateRepo/MigrateRepoCommand.cs | 2 +- .../MigrateRepo/MigrateRepoCommandHandler.cs | 119 ++++++++++++------ 2 files changed, 81 insertions(+), 40 deletions(-) diff --git a/src/gei/Commands/MigrateRepo/MigrateRepoCommand.cs b/src/gei/Commands/MigrateRepo/MigrateRepoCommand.cs index af5b29c5c..a0ce2d47e 100644 --- a/src/gei/Commands/MigrateRepo/MigrateRepoCommand.cs +++ b/src/gei/Commands/MigrateRepo/MigrateRepoCommand.cs @@ -179,7 +179,7 @@ public override MigrateRepoCommandHandler BuildHandler(MigrateRepoCommandArgs ar AwsApi awsApi = null; HttpDownloadService httpDownloadService = null; - if (args.GhesApiUrl.HasValue()) + if (args.GhesApiUrl.HasValue() || (args.GitArchivePath.HasValue() && args.MetadataArchivePath.HasValue())) { var sourceGithubApiFactory = sp.GetRequiredService(); var awsApiFactory = sp.GetRequiredService(); diff --git a/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs b/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs index 0eb1acc2d..f28215ef4 100644 --- a/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs +++ b/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs @@ -121,6 +121,27 @@ public async Task Handle(MigrateRepoCommandArgs args) _log.LogInformation("Archives uploaded to blob storage, now starting migration..."); } } + else if (args.GitArchivePath.HasValue() && args.MetadataArchivePath.HasValue()) + { + var timeNow = $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}"; + var gitArchiveUploadFileName = $"{timeNow}-{GIT_ARCHIVE_FILE_NAME}"; + var metadataArchiveUploadFileName = $"{timeNow}-{METADATA_ARCHIVE_FILE_NAME}"; + + (args.GitArchiveUrl, args.MetadataArchiveUrl) = await UploadArchive( + args.GithubSourceOrg, + args.AwsBucketName, + args.UseGithubStorage, + args.GitArchivePath, + args.MetadataArchivePath, + gitArchiveUploadFileName, + metadataArchiveUploadFileName + ); + + if (args.UseGithubStorage || blobCredentialsRequired) + { + _log.LogInformation("Archives uploaded to blob storage, now starting migration..."); + } + } var sourceRepoUrl = GetSourceRepoUrl(args); var sourceToken = GetSourceToken(args); @@ -192,8 +213,8 @@ public async Task Handle(MigrateRepoCommandArgs args) private string ExtractGhesBaseUrl(string ghesApiUrl) { // We expect the GHES url template to be either http(s)://hostname/api/v3 or http(s)://api.hostname.com. - // We are either going to be able to extract and return the base url based on the above templates or - // will fallback to ghesApiUrl and return it as the base url. + // We are either going to be able to extract and return the base url based on the above templates or + // will fallback to ghesApiUrl and return it as the base url. ghesApiUrl = ghesApiUrl.Trim().TrimEnd('/'); @@ -239,43 +260,15 @@ private string ExtractGhesBaseUrl(string ghesApiUrl) _log.LogInformation($"Downloading archive from {metadataArchiveUrl}"); await _httpDownloadService.DownloadToFile(metadataArchiveUrl, metadataArchiveDownloadFilePath); -#pragma warning disable IDE0063 - await using (var gitArchiveContent = _fileSystemProvider.OpenRead(gitArchiveDownloadFilePath)) - await using (var metadataArchiveContent = _fileSystemProvider.OpenRead(metadataArchiveDownloadFilePath)) -#pragma warning restore IDE0063 - { - if (useGithubStorage) - { - return await UploadArchivesToGithub( - githubTargetOrg, - gitArchiveUploadFileName, - gitArchiveContent, - metadataArchiveUploadFileName, - metadataArchiveContent - ); - } -#pragma warning disable IDE0046 - else if (_awsApi.HasValue()) -#pragma warning restore IDE0046 - { - return await UploadArchivesToAws( - awsBucketName, - gitArchiveUploadFileName, - gitArchiveContent, - metadataArchiveUploadFileName, - metadataArchiveContent - ); - } - else - { - return await UploadArchivesToAzure( - gitArchiveUploadFileName, - gitArchiveContent, - metadataArchiveUploadFileName, - metadataArchiveContent - ); - } - } + return await UploadArchive( + githubTargetOrg, + awsBucketName, + useGithubStorage, + gitArchiveDownloadFilePath, + metadataArchiveDownloadFilePath, + gitArchiveUploadFileName, + metadataArchiveUploadFileName + ); } finally { @@ -287,6 +280,54 @@ private string ExtractGhesBaseUrl(string ghesApiUrl) } } + private async Task<(string GitArchiveUrl, string MetadataArchiveUrl)> UploadArchive( + string githubTargetOrg, + string awsBucketName, + bool useGithubStorage, + string gitArchiveDownloadFilePath, + string metadataArchiveDownloadFilePath, + string gitArchiveUploadFileName, + string metadataArchiveUploadFileName) + { +#pragma warning disable IDE0063 + await using (var gitArchiveContent = _fileSystemProvider.OpenRead(gitArchiveDownloadFilePath)) + await using (var metadataArchiveContent = _fileSystemProvider.OpenRead(metadataArchiveDownloadFilePath)) +#pragma warning restore IDE0063 + { + if (useGithubStorage) + { + return await UploadArchivesToGithub( + githubTargetOrg, + gitArchiveUploadFileName, + gitArchiveContent, + metadataArchiveUploadFileName, + metadataArchiveContent + ); + } +#pragma warning disable IDE0046 + else if (_awsApi.HasValue()) +#pragma warning restore IDE0046 + { + return await UploadArchivesToAws( + awsBucketName, + gitArchiveUploadFileName, + gitArchiveContent, + metadataArchiveUploadFileName, + metadataArchiveContent + ); + } + else + { + return await UploadArchivesToAzure( + gitArchiveUploadFileName, + gitArchiveContent, + metadataArchiveUploadFileName, + metadataArchiveContent + ); + } + } + } + private async Task<(string GitArchiveUrl, string MetadataArchiveUrl, int GitArchiveId, int MetadataArchiveId)> GenerateArchive( string githubSourceOrg, string sourceRepo, From bca29c860caaf91826b3a3eb656c27e0b9edf682 Mon Sep 17 00:00:00 2001 From: Jared Fine Date: Wed, 20 Nov 2024 00:04:36 +0000 Subject: [PATCH 04/13] Refactor uploading logic --- .../MigrateRepo/MigrateRepoCommandHandler.cs | 116 ++++++++---------- 1 file changed, 50 insertions(+), 66 deletions(-) diff --git a/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs b/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs index f28215ef4..f50dd57ce 100644 --- a/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs +++ b/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs @@ -127,13 +127,18 @@ public async Task Handle(MigrateRepoCommandArgs args) var gitArchiveUploadFileName = $"{timeNow}-{GIT_ARCHIVE_FILE_NAME}"; var metadataArchiveUploadFileName = $"{timeNow}-{METADATA_ARCHIVE_FILE_NAME}"; - (args.GitArchiveUrl, args.MetadataArchiveUrl) = await UploadArchive( + args.GitArchiveUrl = await UploadArchive( args.GithubSourceOrg, args.AwsBucketName, args.UseGithubStorage, args.GitArchivePath, + gitArchiveUploadFileName + ); + args.MetadataArchiveUrl = await UploadArchive( + args.GithubSourceOrg, + args.AwsBucketName, + args.UseGithubStorage, args.MetadataArchivePath, - gitArchiveUploadFileName, metadataArchiveUploadFileName ); @@ -240,7 +245,7 @@ private string ExtractGhesBaseUrl(string ghesApiUrl) bool useGithubStorage) { var (gitArchiveUrl, metadataArchiveUrl, gitArchiveId, metadataArchiveId) = await _retryPolicy.Retry( - async () => await GenerateArchive(githubSourceOrg, sourceRepo, skipReleases, lockSourceRepo)); + async () => await GenerateArchives(githubSourceOrg, sourceRepo, skipReleases, lockSourceRepo)); if (!useGithubStorage && !blobCredentialsRequired) { @@ -260,14 +265,21 @@ private string ExtractGhesBaseUrl(string ghesApiUrl) _log.LogInformation($"Downloading archive from {metadataArchiveUrl}"); await _httpDownloadService.DownloadToFile(metadataArchiveUrl, metadataArchiveDownloadFilePath); - return await UploadArchive( - githubTargetOrg, - awsBucketName, - useGithubStorage, - gitArchiveDownloadFilePath, - metadataArchiveDownloadFilePath, - gitArchiveUploadFileName, - metadataArchiveUploadFileName + return ( + await UploadArchive( + githubTargetOrg, + awsBucketName, + useGithubStorage, + gitArchiveDownloadFilePath, + gitArchiveUploadFileName + ), + await UploadArchive( + githubTargetOrg, + awsBucketName, + useGithubStorage, + metadataArchiveDownloadFilePath, + metadataArchiveUploadFileName + ) ); } finally @@ -280,55 +292,34 @@ private string ExtractGhesBaseUrl(string ghesApiUrl) } } - private async Task<(string GitArchiveUrl, string MetadataArchiveUrl)> UploadArchive( + private async Task UploadArchive( string githubTargetOrg, string awsBucketName, bool useGithubStorage, - string gitArchiveDownloadFilePath, - string metadataArchiveDownloadFilePath, - string gitArchiveUploadFileName, - string metadataArchiveUploadFileName) + string archiveDownloadFilePath, + string archiveUploadFileName) { #pragma warning disable IDE0063 - await using (var gitArchiveContent = _fileSystemProvider.OpenRead(gitArchiveDownloadFilePath)) - await using (var metadataArchiveContent = _fileSystemProvider.OpenRead(metadataArchiveDownloadFilePath)) + await using (var archiveContent = _fileSystemProvider.OpenRead(archiveDownloadFilePath)) #pragma warning restore IDE0063 + + if (useGithubStorage) { - if (useGithubStorage) - { - return await UploadArchivesToGithub( - githubTargetOrg, - gitArchiveUploadFileName, - gitArchiveContent, - metadataArchiveUploadFileName, - metadataArchiveContent - ); - } + return await UploadArchiveToGithub(githubTargetOrg, archiveUploadFileName, archiveContent); + } #pragma warning disable IDE0046 - else if (_awsApi.HasValue()) + else if (_awsApi.HasValue()) #pragma warning restore IDE0046 - { - return await UploadArchivesToAws( - awsBucketName, - gitArchiveUploadFileName, - gitArchiveContent, - metadataArchiveUploadFileName, - metadataArchiveContent - ); - } - else - { - return await UploadArchivesToAzure( - gitArchiveUploadFileName, - gitArchiveContent, - metadataArchiveUploadFileName, - metadataArchiveContent - ); - } + { + return await UploadArchiveToAws(awsBucketName, archiveUploadFileName, archiveContent); + } + else + { + return await UploadArchiveToAzure(archiveUploadFileName, archiveContent); } } - private async Task<(string GitArchiveUrl, string MetadataArchiveUrl, int GitArchiveId, int MetadataArchiveId)> GenerateArchive( + private async Task<(string GitArchiveUrl, string MetadataArchiveUrl, int GitArchiveId, int MetadataArchiveId)> GenerateArchives( string githubSourceOrg, string sourceRepo, bool skipReleases, @@ -363,37 +354,30 @@ private void DeleteArchive(string path) } } - private async Task<(string, string)> UploadArchivesToAzure(string gitArchiveFileName, Stream gitArchiveContent, string metadataArchiveFileName, Stream metadataArchiveContent) + private async Task UploadArchiveToAzure(string archiveFileName, Stream archiveContent) { - _log.LogInformation($"Uploading archive {gitArchiveFileName} to Azure Blob Storage"); - var authenticatedGitArchiveUri = await _azureApi.UploadToBlob(gitArchiveFileName, gitArchiveContent); - _log.LogInformation($"Uploading archive {metadataArchiveFileName} to Azure Blob Storage"); - var authenticatedMetadataArchiveUri = await _azureApi.UploadToBlob(metadataArchiveFileName, metadataArchiveContent); + _log.LogInformation($"Uploading archive {archiveFileName} to Azure Blob Storage"); + var authenticatedArchiveUri = await _azureApi.UploadToBlob(archiveFileName, archiveContent); - return (authenticatedGitArchiveUri.ToString(), authenticatedMetadataArchiveUri.ToString()); + return authenticatedArchiveUri.ToString(); } - private async Task<(string, string)> UploadArchivesToAws(string bucketName, string gitArchiveFileName, Stream gitArchiveContent, string metadataArchiveFileName, Stream metadataArchiveContent) + private async Task UploadArchiveToAws(string bucketName, string archiveFileName, Stream archiveContent) { - _log.LogInformation($"Uploading archive {gitArchiveFileName} to AWS S3"); - var authenticatedGitArchiveUri = await _awsApi.UploadToBucket(bucketName, gitArchiveContent, gitArchiveFileName); - _log.LogInformation($"Uploading archive {metadataArchiveFileName} to AWS S3"); - var authenticatedMetadataArchiveUri = await _awsApi.UploadToBucket(bucketName, metadataArchiveContent, metadataArchiveFileName); + _log.LogInformation($"Uploading archive {archiveFileName} to AWS S3"); + var authenticatedArchiveUri = await _awsApi.UploadToBucket(bucketName, archiveContent, archiveFileName); - return (authenticatedGitArchiveUri.ToString(), authenticatedMetadataArchiveUri.ToString()); + return authenticatedArchiveUri.ToString(); } - private async Task<(string, string)> UploadArchivesToGithub(string org, string gitArchiveUploadFileName, Stream gitArchiveContent, string metadataArchiveUploadFileName, Stream metadataArchiveContent) + private async Task UploadArchiveToGithub(string org, string archiveFileName, Stream archiveContent) { var githubOrgDatabaseId = await _targetGithubApi.GetOrganizationDatabaseId(org); _log.LogInformation($"Uploading git archive to GitHub Storage"); - var uploadedGitArchiveUrl = await _targetGithubApi.UploadArchiveToGithubStorage(githubOrgDatabaseId, gitArchiveUploadFileName, gitArchiveContent); - - _log.LogInformation($"Uploading metadata archive to GitHub Storage"); - var uploadedMetadataArchiveUrl = await _targetGithubApi.UploadArchiveToGithubStorage(githubOrgDatabaseId, metadataArchiveUploadFileName, metadataArchiveContent); + var uploadedArchiveUrl = await _targetGithubApi.UploadArchiveToGithubStorage(githubOrgDatabaseId, archiveFileName, archiveContent); - return (uploadedGitArchiveUrl, uploadedMetadataArchiveUrl); + return uploadedArchiveUrl; } private async Task WaitForArchiveGeneration(GithubApi githubApi, string githubSourceOrg, int archiveId) From cc299f3f7cf1af4cfb00f9e85782c39d38f3ab6b Mon Sep 17 00:00:00 2001 From: Jared Fine Date: Wed, 20 Nov 2024 08:37:22 -0500 Subject: [PATCH 05/13] Update src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs Co-authored-by: Arin Ghazarian --- .../MigrateRepo/MigrateRepoCommandHandler.cs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs b/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs index f50dd57ce..e25ce19f8 100644 --- a/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs +++ b/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs @@ -299,24 +299,21 @@ private async Task UploadArchive( string archiveDownloadFilePath, string archiveUploadFileName) { -#pragma warning disable IDE0063 - await using (var archiveContent = _fileSystemProvider.OpenRead(archiveDownloadFilePath)) -#pragma warning restore IDE0063 + await using var archiveContent = _fileSystemProvider.OpenRead(archiveDownloadFilePath); if (useGithubStorage) { return await UploadArchiveToGithub(githubTargetOrg, archiveUploadFileName, archiveContent); } + #pragma warning disable IDE0046 - else if (_awsApi.HasValue()) + if (_awsApi.HasValue()) #pragma warning restore IDE0046 { return await UploadArchiveToAws(awsBucketName, archiveUploadFileName, archiveContent); } - else - { - return await UploadArchiveToAzure(archiveUploadFileName, archiveContent); - } + + return await UploadArchiveToAzure(archiveUploadFileName, archiveContent); } private async Task<(string GitArchiveUrl, string MetadataArchiveUrl, int GitArchiveId, int MetadataArchiveId)> GenerateArchives( From 860aeb052891cf32c69c97565a8ccd963e9fe770 Mon Sep 17 00:00:00 2001 From: Jared Fine Date: Wed, 20 Nov 2024 17:19:31 +0000 Subject: [PATCH 06/13] Add additional logging --- src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs b/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs index e25ce19f8..49144675b 100644 --- a/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs +++ b/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs @@ -261,9 +261,11 @@ private string ExtractGhesBaseUrl(string ghesApiUrl) { _log.LogInformation($"Downloading archive from {gitArchiveUrl}"); await _httpDownloadService.DownloadToFile(gitArchiveUrl, gitArchiveDownloadFilePath); + _log.LogInformation("Download complete"); _log.LogInformation($"Downloading archive from {metadataArchiveUrl}"); await _httpDownloadService.DownloadToFile(metadataArchiveUrl, metadataArchiveDownloadFilePath); + _log.LogInformation("Download complete"); return ( await UploadArchive( @@ -355,6 +357,7 @@ private async Task UploadArchiveToAzure(string archiveFileName, Stream a { _log.LogInformation($"Uploading archive {archiveFileName} to Azure Blob Storage"); var authenticatedArchiveUri = await _azureApi.UploadToBlob(archiveFileName, archiveContent); + _log.LogInformation("Upload complete"); return authenticatedArchiveUri.ToString(); } @@ -363,6 +366,7 @@ private async Task UploadArchiveToAws(string bucketName, string archiveF { _log.LogInformation($"Uploading archive {archiveFileName} to AWS S3"); var authenticatedArchiveUri = await _awsApi.UploadToBucket(bucketName, archiveContent, archiveFileName); + _log.LogInformation("Upload complete"); return authenticatedArchiveUri.ToString(); } @@ -371,8 +375,9 @@ private async Task UploadArchiveToGithub(string org, string archiveFileN { var githubOrgDatabaseId = await _targetGithubApi.GetOrganizationDatabaseId(org); - _log.LogInformation($"Uploading git archive to GitHub Storage"); + _log.LogInformation($"Uploading archive {archiveFileName} to GitHub Storage"); var uploadedArchiveUrl = await _targetGithubApi.UploadArchiveToGithubStorage(githubOrgDatabaseId, archiveFileName, archiveContent); + _log.LogInformation("Upload complete"); return uploadedArchiveUrl; } From 3499dc3ab5b31f2f83e24d95151cb3424855f936 Mon Sep 17 00:00:00 2001 From: Jared Fine Date: Wed, 20 Nov 2024 17:48:30 +0000 Subject: [PATCH 07/13] Only upload once if same archive is specified --- .../MigrateRepo/MigrateRepoCommandHandler.cs | 46 +++++++++++++------ 1 file changed, 31 insertions(+), 15 deletions(-) diff --git a/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs b/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs index 49144675b..72f6d1ca9 100644 --- a/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs +++ b/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs @@ -27,6 +27,7 @@ public class MigrateRepoCommandHandler : ICommandHandler private const int CHECK_STATUS_DELAY_IN_MILLISECONDS = 10000; // 10 seconds private const string GIT_ARCHIVE_FILE_NAME = "git_archive.tar.gz"; private const string METADATA_ARCHIVE_FILE_NAME = "metadata_archive.tar.gz"; + private const string DUPLICATE_ARCHIVE_FILE_NAME = "archive.tar.gz"; private const string DEFAULT_GITHUB_BASE_URL = "https://github.com"; public MigrateRepoCommandHandler( @@ -126,25 +127,40 @@ public async Task Handle(MigrateRepoCommandArgs args) var timeNow = $"{DateTime.Now:yyyy-MM-dd_HH-mm-ss}"; var gitArchiveUploadFileName = $"{timeNow}-{GIT_ARCHIVE_FILE_NAME}"; var metadataArchiveUploadFileName = $"{timeNow}-{METADATA_ARCHIVE_FILE_NAME}"; + var duplicateArchiveUploadFileName = $"{timeNow}-{DUPLICATE_ARCHIVE_FILE_NAME}"; - args.GitArchiveUrl = await UploadArchive( - args.GithubSourceOrg, - args.AwsBucketName, - args.UseGithubStorage, - args.GitArchivePath, - gitArchiveUploadFileName - ); - args.MetadataArchiveUrl = await UploadArchive( - args.GithubSourceOrg, - args.AwsBucketName, - args.UseGithubStorage, - args.MetadataArchivePath, - metadataArchiveUploadFileName - ); + if (args.GitArchivePath == args.MetadataArchivePath) + { + args.GitArchiveUrl = await UploadArchive( + args.GithubSourceOrg, + args.AwsBucketName, + args.UseGithubStorage, + args.GitArchivePath, + duplicateArchiveUploadFileName + ); + args.MetadataArchiveUrl = args.GitArchiveUrl; + } + else + { + args.GitArchiveUrl = await UploadArchive( + args.GithubSourceOrg, + args.AwsBucketName, + args.UseGithubStorage, + args.GitArchivePath, + gitArchiveUploadFileName + ); + args.MetadataArchiveUrl = await UploadArchive( + args.GithubSourceOrg, + args.AwsBucketName, + args.UseGithubStorage, + args.MetadataArchivePath, + metadataArchiveUploadFileName + ); + } if (args.UseGithubStorage || blobCredentialsRequired) { - _log.LogInformation("Archives uploaded to blob storage, now starting migration..."); + _log.LogInformation("Archive(s) uploaded to blob storage, now starting migration..."); } } From 854d2f02420b44c93b045f578e2c06a598cd2bef Mon Sep 17 00:00:00 2001 From: Arin Ghazarian Date: Wed, 20 Nov 2024 18:49:28 -0800 Subject: [PATCH 08/13] Add test coverage for when archive paths are provided --- .../MigrateRepoCommandHandlerTests.cs | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs b/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs index 5f208f754..de05d30ba 100644 --- a/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs +++ b/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs @@ -42,6 +42,8 @@ public class MigrateRepoCommandHandlerTests private const string AWS_SECRET_ACCESS_KEY = "aws-secret-access-key"; private const string AWS_SESSION_TOKEN = "aws-session-token"; private const string AWS_REGION = "aws-region"; + private const string GIT_ARCHIVE_FILE_NAME = "git_archive.tar.gz"; + private const string METADATA_ARCHIVE_FILE_NAME = "metadata_archive.tar.gz"; public MigrateRepoCommandHandlerTests() { @@ -552,6 +554,64 @@ public async Task Github_With_Archive_Urls() _mockTargetGithubApi.Verify(x => x.GetMigration(migrationId)); } + [Fact] + public async Task With_Archive_Paths() + { + var githubOrgId = Guid.NewGuid().ToString(); + var migrationSourceId = Guid.NewGuid().ToString(); + var sourceGithubPat = Guid.NewGuid().ToString(); + var targetGithubPat = Guid.NewGuid().ToString(); + var githubRepoUrl = $"https://github.com/{SOURCE_ORG}/{SOURCE_REPO}"; + var gitArchiveUrl = $"https://example.com/{GIT_ARCHIVE_FILE_NAME}"; + var metadataArchiveUrl = $"https://example.com/{METADATA_ARCHIVE_FILE_NAME}"; + var gitArchivePath = $"/path/{GIT_ARCHIVE_FILE_NAME}"; + var metadataArchivePath = $"/path/{METADATA_ARCHIVE_FILE_NAME}"; + var migrationId = Guid.NewGuid().ToString(); + + _mockAzureApi + .Setup(x => x.UploadToBlob(It.Is(s => s.EndsWith(GIT_ARCHIVE_FILE_NAME)), It.IsAny()).Result) + .Returns(new Uri(gitArchiveUrl)); + _mockAzureApi + .Setup(x => x.UploadToBlob(It.Is(s => s.EndsWith(METADATA_ARCHIVE_FILE_NAME)), It.IsAny()).Result) + .Returns(new Uri(metadataArchiveUrl)); + + _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId); + _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result).Returns(migrationSourceId); + _mockTargetGithubApi + .Setup(x => x.StartMigration( + migrationSourceId, + githubRepoUrl, + githubOrgId, + TARGET_REPO, + sourceGithubPat, + targetGithubPat, + gitArchiveUrl, + metadataArchiveUrl, + false, + null, + false).Result) + .Returns(migrationId); + _mockTargetGithubApi.Setup(x => x.GetMigration(migrationId).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); + + _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(sourceGithubPat); + _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(targetGithubPat); + + var args = new MigrateRepoCommandArgs + { + GithubSourceOrg = SOURCE_ORG, + SourceRepo = SOURCE_REPO, + GithubTargetOrg = TARGET_ORG, + TargetRepo = TARGET_REPO, + TargetApiUrl = TARGET_API_URL, + GitArchivePath = gitArchivePath, + MetadataArchivePath = metadataArchivePath, + AzureStorageConnectionString = AZURE_CONNECTION_STRING + }; + await _handler.Handle(args); + + _mockTargetGithubApi.Verify(x => x.GetMigration(migrationId)); + } + [Fact] public async Task Github_Only_One_Archive_Url_Throws_Error() { From 69c288c5458694356ef20d9d3fda20fa30a97931 Mon Sep 17 00:00:00 2001 From: Arin Ghazarian Date: Wed, 20 Nov 2024 19:20:32 -0800 Subject: [PATCH 09/13] Make duplicate upload logic a bit simpler --- .../MigrateRepoCommandHandlerTests.cs | 2 +- .../MigrateRepo/MigrateRepoCommandHandler.cs | 50 ++++++------------- 2 files changed, 17 insertions(+), 35 deletions(-) diff --git a/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs b/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs index de05d30ba..b0484af09 100644 --- a/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs +++ b/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs @@ -574,7 +574,7 @@ public async Task With_Archive_Paths() _mockAzureApi .Setup(x => x.UploadToBlob(It.Is(s => s.EndsWith(METADATA_ARCHIVE_FILE_NAME)), It.IsAny()).Result) .Returns(new Uri(metadataArchiveUrl)); - + _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId); _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result).Returns(migrationSourceId); _mockTargetGithubApi diff --git a/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs b/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs index 72f6d1ca9..875c4f94f 100644 --- a/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs +++ b/src/gei/Commands/MigrateRepo/MigrateRepoCommandHandler.cs @@ -128,40 +128,25 @@ public async Task Handle(MigrateRepoCommandArgs args) var gitArchiveUploadFileName = $"{timeNow}-{GIT_ARCHIVE_FILE_NAME}"; var metadataArchiveUploadFileName = $"{timeNow}-{METADATA_ARCHIVE_FILE_NAME}"; var duplicateArchiveUploadFileName = $"{timeNow}-{DUPLICATE_ARCHIVE_FILE_NAME}"; - - if (args.GitArchivePath == args.MetadataArchivePath) - { - args.GitArchiveUrl = await UploadArchive( - args.GithubSourceOrg, - args.AwsBucketName, - args.UseGithubStorage, - args.GitArchivePath, - duplicateArchiveUploadFileName - ); - args.MetadataArchiveUrl = args.GitArchiveUrl; - } - else - { - args.GitArchiveUrl = await UploadArchive( - args.GithubSourceOrg, - args.AwsBucketName, - args.UseGithubStorage, - args.GitArchivePath, - gitArchiveUploadFileName - ); - args.MetadataArchiveUrl = await UploadArchive( + var shouldUploadOnce = args.GitArchivePath == args.MetadataArchivePath; + + args.GitArchiveUrl = await UploadArchive( + args.GithubSourceOrg, + args.AwsBucketName, + args.UseGithubStorage, + args.GitArchivePath, + shouldUploadOnce ? duplicateArchiveUploadFileName : gitArchiveUploadFileName); + + args.MetadataArchiveUrl = shouldUploadOnce + ? args.GitArchiveUrl + : await UploadArchive( args.GithubSourceOrg, args.AwsBucketName, args.UseGithubStorage, args.MetadataArchivePath, - metadataArchiveUploadFileName - ); - } + metadataArchiveUploadFileName); - if (args.UseGithubStorage || blobCredentialsRequired) - { - _log.LogInformation("Archive(s) uploaded to blob storage, now starting migration..."); - } + _log.LogInformation("Archive(s) uploaded to blob storage, now starting migration..."); } var sourceRepoUrl = GetSourceRepoUrl(args); @@ -289,16 +274,13 @@ await UploadArchive( awsBucketName, useGithubStorage, gitArchiveDownloadFilePath, - gitArchiveUploadFileName - ), + gitArchiveUploadFileName), await UploadArchive( githubTargetOrg, awsBucketName, useGithubStorage, metadataArchiveDownloadFilePath, - metadataArchiveUploadFileName - ) - ); + metadataArchiveUploadFileName)); } finally { From ac7ae2f73ed28de703897dd780131ffbc15dc149 Mon Sep 17 00:00:00 2001 From: Arin Ghazarian Date: Wed, 20 Nov 2024 19:26:34 -0800 Subject: [PATCH 10/13] Remove unnecessary console out --- .../gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs b/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs index b0484af09..5e4c398c9 100644 --- a/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs +++ b/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs @@ -409,8 +409,6 @@ public async Task Happy_Path_UseGithubStorage(bool useGhesBlobCredentials) .Setup(x => x.UploadArchiveToGithubStorage(githubOrgDatabaseId, It.Is(a => a.EndsWith("metadata_archive.tar.gz")), metaContentStream).Result) .Returns(uploadedMetadataArchiveUrl); - Console.WriteLine($"MigrationSourceId: {migrationSourceId}, MigrationId: {migrationId}"); - var args = new MigrateRepoCommandArgs { GithubSourceOrg = SOURCE_ORG, From ede7b847e8004c143d0c5a43eab1be61a24de44f Mon Sep 17 00:00:00 2001 From: Arin Ghazarian Date: Wed, 20 Nov 2024 21:13:34 -0800 Subject: [PATCH 11/13] Fix flaky tests by removing the need to create physical files and doing everything in memory --- .../Extensions/EnumerableExtensions.cs | 3 +++ src/Octoshift/Extensions/StringExtensions.cs | 2 ++ src/Octoshift/Services/FileSystemProvider.cs | 2 +- .../MigrateRepoCommandHandlerTests.cs | 10 +++++--- .../MigrateRepoCommandHandlerTests.cs | 23 +++++++++++-------- 5 files changed, 26 insertions(+), 14 deletions(-) diff --git a/src/Octoshift/Extensions/EnumerableExtensions.cs b/src/Octoshift/Extensions/EnumerableExtensions.cs index 0d448bc6f..b6bde1c41 100644 --- a/src/Octoshift/Extensions/EnumerableExtensions.cs +++ b/src/Octoshift/Extensions/EnumerableExtensions.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text; using System.Threading.Tasks; namespace OctoshiftCLI.Extensions @@ -23,5 +24,7 @@ public static async Task Sum(this IEnumerable list, Func } public static IEnumerable ToEmptyEnumerableIfNull(this IEnumerable enumerable) => enumerable ?? Enumerable.Empty(); + + public static string GetString(this byte[] bytes) => Encoding.UTF8.GetString(bytes.ToArray()); } } diff --git a/src/Octoshift/Extensions/StringExtensions.cs b/src/Octoshift/Extensions/StringExtensions.cs index 73173acb6..8d323ff92 100644 --- a/src/Octoshift/Extensions/StringExtensions.cs +++ b/src/Octoshift/Extensions/StringExtensions.cs @@ -24,5 +24,7 @@ public static class StringExtensions public static string ToUnixPath(this string path) => path?.Replace("\\", "/"); public static string EscapeDataString(this string value) => Uri.EscapeDataString(value); + + public static byte[] ToBytes(this string s) => Encoding.UTF8.GetBytes(s); } } diff --git a/src/Octoshift/Services/FileSystemProvider.cs b/src/Octoshift/Services/FileSystemProvider.cs index 83369e667..de80bde9a 100644 --- a/src/Octoshift/Services/FileSystemProvider.cs +++ b/src/Octoshift/Services/FileSystemProvider.cs @@ -15,7 +15,7 @@ public class FileSystemProvider public virtual FileStream Open(string path, FileMode mode) => File.Open(path, mode); - public virtual FileStream OpenRead(string path) => File.OpenRead(path); + public virtual Stream OpenRead(string path) => File.OpenRead(path); public virtual async Task WriteAllTextAsync(string path, string contents) => await File.WriteAllTextAsync(path, contents); diff --git a/src/OctoshiftCLI.Tests/bbs2gh/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs b/src/OctoshiftCLI.Tests/bbs2gh/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs index a44ea8558..2a5831db2 100644 --- a/src/OctoshiftCLI.Tests/bbs2gh/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs +++ b/src/OctoshiftCLI.Tests/bbs2gh/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs @@ -6,6 +6,7 @@ using Moq; using OctoshiftCLI.BbsToGithub.Commands.MigrateRepo; using OctoshiftCLI.BbsToGithub.Services; +using OctoshiftCLI.Extensions; using OctoshiftCLI.Services; using Xunit; @@ -350,9 +351,9 @@ public async Task Happy_Path_Uploads_To_Github_Storage() var githubOrgDatabaseId = Guid.NewGuid().ToString(); const string gitArchiveFilePath = "./gitdata_archive"; const string gitArchiveUrl = "gei://archive/1"; + const string gitArchiveContents = "I am git archive"; - await File.WriteAllTextAsync(gitArchiveFilePath, "I am git archive"); - await using var gitContentStream = File.OpenRead(gitArchiveFilePath); + await using var gitContentStream = new MemoryStream(gitArchiveContents.ToBytes()); _mockFileSystemProvider.Setup(m => m.OpenRead(gitArchiveFilePath)).Returns(gitContentStream); @@ -360,7 +361,10 @@ public async Task Happy_Path_Uploads_To_Github_Storage() _mockGithubApi.Setup(x => x.CreateBbsMigrationSource(GITHUB_ORG_ID).Result).Returns(MIGRATION_SOURCE_ID); _mockGithubApi.Setup(x => x.GetOrganizationDatabaseId(GITHUB_ORG).Result).Returns(githubOrgDatabaseId); _mockGithubApi - .Setup(x => x.UploadArchiveToGithubStorage(githubOrgDatabaseId, It.IsAny(), gitContentStream).Result) + .Setup(x => x.UploadArchiveToGithubStorage( + githubOrgDatabaseId, + It.IsAny(), + It.Is(s => (s as MemoryStream).ToArray().GetString() == gitArchiveContents)).Result) .Returns(gitArchiveUrl); // Act diff --git a/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs b/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs index 5e4c398c9..c87bdb974 100644 --- a/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs +++ b/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs @@ -5,6 +5,7 @@ using System.Threading.Tasks; using FluentAssertions; using Moq; +using OctoshiftCLI.Extensions; using OctoshiftCLI.GithubEnterpriseImporter.Commands.MigrateRepo; using OctoshiftCLI.GithubEnterpriseImporter.Services; using OctoshiftCLI.Services; @@ -345,16 +346,13 @@ public async Task Happy_Path_UseGithubStorage(bool useGhesBlobCredentials) var metadataArchiveUrl = $"https://example.com/{metadataArchiveId}"; var uploadedGitArchiveUrl = "gei://archive/1"; var uploadedMetadataArchiveUrl = "gei://archive/2"; - var gitArchiveFilePath = "./gitdata_archive"; - var metadataArchiveFilePath = "./metadata_archive"; var gitArchiveDownloadFilePath = "git_archive_downaloded.tmp"; var metadataArchiveDownloadFilePath = "metadata_archive_downloaded.tmp"; + var gitArchiveContents = "I am git archive"; + var metadataArchiveContents = "I am metadata archive"; - File.WriteAllText(gitArchiveFilePath, "I am git archive"); - File.WriteAllText(metadataArchiveFilePath, "I am metadata archive"); - - using var gitContentStream = File.OpenRead(gitArchiveFilePath); - using var metaContentStream = File.OpenRead(metadataArchiveFilePath); + using var gitContentStream = new MemoryStream(gitArchiveContents.ToBytes()); + using var metaContentStream = new MemoryStream(metadataArchiveContents.ToBytes()); _mockFileSystemProvider .SetupSequence(m => m.GetTempFileName()) @@ -372,7 +370,6 @@ public async Task Happy_Path_UseGithubStorage(bool useGhesBlobCredentials) _mockGhesVersionChecker.Setup(m => m.AreBlobCredentialsRequired(GHES_API_URL)).ReturnsAsync(useGhesBlobCredentials); _mockTargetGithubApi.Setup(x => x.DoesOrgExist(TARGET_ORG).Result).Returns(true); - _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId); _mockTargetGithubApi.Setup(x => x.GetOrganizationDatabaseId(TARGET_ORG).Result).Returns(githubOrgDatabaseId); _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result).Returns(migrationSourceId); @@ -402,11 +399,17 @@ public async Task Happy_Path_UseGithubStorage(bool useGhesBlobCredentials) _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, metadataArchiveId).Result).Returns(metadataArchiveUrl); _mockTargetGithubApi - .Setup(x => x.UploadArchiveToGithubStorage(githubOrgDatabaseId, It.Is(a => a.EndsWith("git_archive.tar.gz")), gitContentStream).Result) + .Setup(x => x.UploadArchiveToGithubStorage( + githubOrgDatabaseId, + It.Is(a => a.EndsWith("git_archive.tar.gz")), + It.Is(s => (s as MemoryStream).ToArray().GetString() == gitArchiveContents)).Result) .Returns(uploadedGitArchiveUrl); _mockTargetGithubApi - .Setup(x => x.UploadArchiveToGithubStorage(githubOrgDatabaseId, It.Is(a => a.EndsWith("metadata_archive.tar.gz")), metaContentStream).Result) + .Setup(x => x.UploadArchiveToGithubStorage( + githubOrgDatabaseId, + It.Is(a => a.EndsWith("metadata_archive.tar.gz")), + It.Is(s => (s as MemoryStream).ToArray().GetString() == metadataArchiveContents)).Result) .Returns(uploadedMetadataArchiveUrl); var args = new MigrateRepoCommandArgs From fa6b65fbb05d0425a6818c786d1427b2831823d5 Mon Sep 17 00:00:00 2001 From: Arin Ghazarian Date: Wed, 20 Nov 2024 23:21:59 -0800 Subject: [PATCH 12/13] Simplify testes --- .../MigrateRepoCommandHandlerTests.cs | 816 ++++++++---------- 1 file changed, 362 insertions(+), 454 deletions(-) diff --git a/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs b/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs index c87bdb974..d9c5c2b9d 100644 --- a/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs +++ b/src/OctoshiftCLI.Tests/gei/Commands/MigrateRepo/MigrateRepoCommandHandlerTests.cs @@ -45,6 +45,19 @@ public class MigrateRepoCommandHandlerTests private const string AWS_REGION = "aws-region"; private const string GIT_ARCHIVE_FILE_NAME = "git_archive.tar.gz"; private const string METADATA_ARCHIVE_FILE_NAME = "metadata_archive.tar.gz"; + private const string GITHUB_ORG_ID = "9b1b5862-6a8b-4fe1-8cef-0f4e67e975e8"; + private const string MIGRATION_SOURCE_ID = "b6ec2c17-c4d7-4552-83f6-b5407153c324"; + private const string GITHUB_REPO_URL = $"https://github.com/{SOURCE_ORG}/{SOURCE_REPO}"; + private const string GHES_REPO_URL = $"https://myghes/{SOURCE_ORG}/{SOURCE_REPO}"; + private const string MIGRATION_ID = "069f660d-9201-47c5-95d4-f9b743cb89d9"; + private const int GIT_ARCHIVE_ID = 1; + private const int METADATA_ARCHIVE_ID = 2; + private const string GIT_ARCHIVE_URL = "https://example.com/1"; + private const string METADATA_ARCHIVE_URL = "https://example.com/2"; + private const string AUTHENTICATED_GIT_ARCHIVE_URL = $"https://example.com/1/authenticated"; + private const string AUTHENTICATED_METADATA_ARCHIVE_URL = $"https://example.com/2/authenticated"; + private const string GIT_ARCHIVE_FILE_PATH = "path/to/git_archive"; + private const string METADATA_ARCHIVE_FILE_PATH = "path/to/metadata_archive"; public MigrateRepoCommandHandlerTests() { @@ -92,19 +105,12 @@ await FluentActions public async Task Happy_Path_Without_Wait() { // Arrange - var githubOrgId = Guid.NewGuid().ToString(); - var migrationSourceId = Guid.NewGuid().ToString(); - var sourceGithubPat = Guid.NewGuid().ToString(); - var targetGithubPat = Guid.NewGuid().ToString(); - var githubRepoUrl = $"https://github.com/{SOURCE_ORG}/{SOURCE_REPO}"; - var migrationId = Guid.NewGuid().ToString(); + _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(GITHUB_ORG_ID); + _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(GITHUB_ORG_ID).Result).Returns(MIGRATION_SOURCE_ID); + _mockTargetGithubApi.Setup(x => x.StartMigration(MIGRATION_SOURCE_ID, GITHUB_REPO_URL, GITHUB_ORG_ID, TARGET_REPO, GITHUB_SOURCE_PAT, GITHUB_TARGET_PAT, null, null, false, null, false).Result).Returns(MIGRATION_ID); - _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId); - _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result).Returns(migrationSourceId); - _mockTargetGithubApi.Setup(x => x.StartMigration(migrationSourceId, githubRepoUrl, githubOrgId, TARGET_REPO, sourceGithubPat, targetGithubPat, null, null, false, null, false).Result).Returns(migrationId); - - _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(sourceGithubPat); - _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(targetGithubPat); + _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_SOURCE_PAT); + _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_TARGET_PAT); var actualLogOutput = new List(); _mockOctoLogger.Setup(m => m.LogInformation(It.IsAny())).Callback(s => actualLogOutput.Add(s)); @@ -112,7 +118,7 @@ public async Task Happy_Path_Without_Wait() var expectedLogOutput = new List() { "Migrating Repo...", - $"A repository migration (ID: {migrationId}) was successfully queued." + $"A repository migration (ID: {MIGRATION_ID}) was successfully queued." }; // Act @@ -129,8 +135,8 @@ public async Task Happy_Path_Without_Wait() // Assert _mockTargetGithubApi.Verify(m => m.GetOrganizationId(TARGET_ORG)); - _mockTargetGithubApi.Verify(m => m.CreateGhecMigrationSource(githubOrgId)); - _mockTargetGithubApi.Verify(m => m.StartMigration(migrationSourceId, githubRepoUrl, githubOrgId, TARGET_REPO, sourceGithubPat, targetGithubPat, null, null, false, null, false)); + _mockTargetGithubApi.Verify(m => m.CreateGhecMigrationSource(GITHUB_ORG_ID)); + _mockTargetGithubApi.Verify(m => m.StartMigration(MIGRATION_SOURCE_ID, GITHUB_REPO_URL, GITHUB_ORG_ID, TARGET_REPO, GITHUB_SOURCE_PAT, GITHUB_TARGET_PAT, null, null, false, null, false)); _mockOctoLogger.Verify(m => m.LogInformation(It.IsAny()), Times.Exactly(2)); actualLogOutput.Should().Equal(expectedLogOutput); @@ -142,20 +148,14 @@ public async Task Happy_Path_Without_Wait() public async Task Skip_Migration_If_Target_Repo_Exists() { // Arrange - var githubOrgId = Guid.NewGuid().ToString(); - var migrationSourceId = Guid.NewGuid().ToString(); - var sourceGithubPat = Guid.NewGuid().ToString(); - var targetGithubPat = Guid.NewGuid().ToString(); - var githubRepoUrl = $"https://github.com/{SOURCE_ORG}/{SOURCE_REPO}"; - - _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId); - _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result).Returns(migrationSourceId); + _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(GITHUB_ORG_ID); + _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(GITHUB_ORG_ID).Result).Returns(MIGRATION_SOURCE_ID); _mockTargetGithubApi - .Setup(x => x.StartMigration(migrationSourceId, githubRepoUrl, githubOrgId, TARGET_REPO, sourceGithubPat, targetGithubPat, null, null, false, null, false).Result) + .Setup(x => x.StartMigration(MIGRATION_SOURCE_ID, GITHUB_REPO_URL, GITHUB_ORG_ID, TARGET_REPO, GITHUB_SOURCE_PAT, GITHUB_TARGET_PAT, null, null, false, null, false).Result) .Throws(new OctoshiftCliException($"A repository called {TARGET_ORG}/{TARGET_REPO} already exists")); - _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(sourceGithubPat); - _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(targetGithubPat); + _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_SOURCE_PAT); + _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_TARGET_PAT); var actualLogOutput = new List(); _mockOctoLogger.Setup(m => m.LogInformation(It.IsAny())).Callback(s => actualLogOutput.Add(s)); @@ -183,33 +183,26 @@ public async Task Skip_Migration_If_Target_Repo_Exists() [Fact] public async Task Happy_Path_GithubSource() { - var githubOrgId = Guid.NewGuid().ToString(); - var migrationSourceId = Guid.NewGuid().ToString(); - var sourceGithubPat = Guid.NewGuid().ToString(); - var targetGithubPat = Guid.NewGuid().ToString(); - var githubRepoUrl = $"https://github.com/{SOURCE_ORG}/{SOURCE_REPO}"; - var migrationId = Guid.NewGuid().ToString(); - - _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId); - _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result).Returns(migrationSourceId); + _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(GITHUB_ORG_ID); + _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(GITHUB_ORG_ID).Result).Returns(MIGRATION_SOURCE_ID); _mockTargetGithubApi .Setup(x => x.StartMigration( - migrationSourceId, - githubRepoUrl, - githubOrgId, + MIGRATION_SOURCE_ID, + GITHUB_REPO_URL, + GITHUB_ORG_ID, TARGET_REPO, - sourceGithubPat, - targetGithubPat, + GITHUB_SOURCE_PAT, + GITHUB_TARGET_PAT, null, null, false, null, false).Result) - .Returns(migrationId); - _mockTargetGithubApi.Setup(x => x.GetMigration(migrationId).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); + .Returns(MIGRATION_ID); + _mockTargetGithubApi.Setup(x => x.GetMigration(MIGRATION_ID).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); - _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(sourceGithubPat); - _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(targetGithubPat); + _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_SOURCE_PAT); + _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_TARGET_PAT); var args = new MigrateRepoCommandArgs { @@ -221,24 +214,20 @@ public async Task Happy_Path_GithubSource() }; await _handler.Handle(args); - _mockTargetGithubApi.Verify(x => x.GetMigration(migrationId)); + _mockTargetGithubApi.Verify(x => x.GetMigration(MIGRATION_ID)); } [Fact] public async Task Throws_Decorated_Error_When_Create_Migration_Source_Fails_With_Permissions_Error() { // Arrange - var githubOrgId = Guid.NewGuid().ToString(); - var sourceGithubPat = Guid.NewGuid().ToString(); - var targetGithubPat = Guid.NewGuid().ToString(); - - _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId); + _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(GITHUB_ORG_ID); _mockTargetGithubApi - .Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result) + .Setup(x => x.CreateGhecMigrationSource(GITHUB_ORG_ID).Result) .Throws(new OctoshiftCliException("monalisa does not have the correct permissions to execute `CreateMigrationSource`")); - _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(sourceGithubPat); - _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(targetGithubPat); + _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_SOURCE_PAT); + _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_TARGET_PAT); // Act await _handler.Invoking(async x => await x.Handle(new MigrateRepoCommandArgs @@ -258,56 +247,44 @@ await _handler.Invoking(async x => await x.Handle(new MigrateRepoCommandArgs [Fact] public async Task Happy_Path_GithubSource_Ghes() { - var githubOrgId = Guid.NewGuid().ToString(); - var migrationSourceId = Guid.NewGuid().ToString(); - var sourceGithubPat = Guid.NewGuid().ToString(); - var targetGithubPat = Guid.NewGuid().ToString(); - var githubRepoUrl = $"https://myghes/{SOURCE_ORG}/{SOURCE_REPO}"; - var migrationId = Guid.NewGuid().ToString(); - var gitArchiveId = 1; - var metadataArchiveId = 2; - var gitArchiveUrl = $"https://example.com/{gitArchiveId}"; - var metadataArchiveUrl = $"https://example.com/{metadataArchiveId}"; - var authenticatedGitArchiveUrl = new Uri($"https://example.com/{gitArchiveId}/authenticated"); - var authenticatedMetadataArchiveUrl = new Uri($"https://example.com/{metadataArchiveId}/authenticated"); - var gitArchiveFilePath = "path/to/git_archive"; - var metadataArchiveFilePath = "path/to/metadata_archive"; - - _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId); - _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result).Returns(migrationSourceId); + _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(GITHUB_ORG_ID); + _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(GITHUB_ORG_ID).Result).Returns(MIGRATION_SOURCE_ID); _mockTargetGithubApi .Setup(x => x.StartMigration( - migrationSourceId, - githubRepoUrl, - githubOrgId, + MIGRATION_SOURCE_ID, + GHES_REPO_URL, + GITHUB_ORG_ID, TARGET_REPO, - sourceGithubPat, - targetGithubPat, - authenticatedGitArchiveUrl.ToString(), - authenticatedMetadataArchiveUrl.ToString(), + GITHUB_SOURCE_PAT, + GITHUB_TARGET_PAT, + AUTHENTICATED_GIT_ARCHIVE_URL, + AUTHENTICATED_METADATA_ARCHIVE_URL, false, null, false).Result) - .Returns(migrationId); - _mockTargetGithubApi.Setup(x => x.GetMigration(migrationId).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); + .Returns(MIGRATION_ID); + _mockTargetGithubApi.Setup(x => x.GetMigration(MIGRATION_ID).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); _mockTargetGithubApi.Setup(x => x.DoesOrgExist(TARGET_ORG).Result).Returns(true); - _mockSourceGithubApi.Setup(x => x.StartGitArchiveGeneration(SOURCE_ORG, SOURCE_REPO).Result).Returns(gitArchiveId); - _mockSourceGithubApi.Setup(x => x.StartMetadataArchiveGeneration(SOURCE_ORG, SOURCE_REPO, false, false).Result).Returns(metadataArchiveId); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, gitArchiveId).Result).Returns(ArchiveMigrationStatus.Exported); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, metadataArchiveId).Result).Returns(ArchiveMigrationStatus.Exported); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, gitArchiveId).Result).Returns(gitArchiveUrl); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, metadataArchiveId).Result).Returns(metadataArchiveUrl); + _mockSourceGithubApi.Setup(x => x.StartGitArchiveGeneration(SOURCE_ORG, SOURCE_REPO).Result).Returns(GIT_ARCHIVE_ID); + _mockSourceGithubApi.Setup(x => x.StartMetadataArchiveGeneration(SOURCE_ORG, SOURCE_REPO, false, false).Result).Returns(METADATA_ARCHIVE_ID); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, GIT_ARCHIVE_ID).Result).Returns(ArchiveMigrationStatus.Exported); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, METADATA_ARCHIVE_ID).Result).Returns(ArchiveMigrationStatus.Exported); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, GIT_ARCHIVE_ID).Result).Returns(GIT_ARCHIVE_URL); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, METADATA_ARCHIVE_ID).Result).Returns(METADATA_ARCHIVE_URL); - _mockAzureApi.SetupSequence(x => x.UploadToBlob(It.IsAny(), It.IsAny()).Result).Returns(authenticatedGitArchiveUrl).Returns(authenticatedMetadataArchiveUrl); + _mockAzureApi + .SetupSequence(x => x.UploadToBlob(It.IsAny(), It.IsAny()).Result) + .Returns(new Uri(AUTHENTICATED_GIT_ARCHIVE_URL)) + .Returns(new Uri(AUTHENTICATED_METADATA_ARCHIVE_URL)); _mockFileSystemProvider .SetupSequence(m => m.GetTempFileName()) - .Returns(gitArchiveFilePath) - .Returns(metadataArchiveFilePath); + .Returns(GIT_ARCHIVE_FILE_PATH) + .Returns(METADATA_ARCHIVE_FILE_PATH); - _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(sourceGithubPat); - _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(targetGithubPat); + _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_SOURCE_PAT); + _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_TARGET_PAT); _mockGhesVersionChecker.Setup(m => m.AreBlobCredentialsRequired(GHES_API_URL)).ReturnsAsync(true); @@ -323,9 +300,9 @@ public async Task Happy_Path_GithubSource_Ghes() }; await _handler.Handle(args); - _mockTargetGithubApi.Verify(x => x.GetMigration(migrationId)); - _mockFileSystemProvider.Verify(x => x.DeleteIfExists(gitArchiveFilePath), Times.Once); - _mockFileSystemProvider.Verify(x => x.DeleteIfExists(metadataArchiveFilePath), Times.Once); + _mockTargetGithubApi.Verify(x => x.GetMigration(MIGRATION_ID)); + _mockFileSystemProvider.Verify(x => x.DeleteIfExists(GIT_ARCHIVE_FILE_PATH), Times.Once); + _mockFileSystemProvider.Verify(x => x.DeleteIfExists(METADATA_ARCHIVE_FILE_PATH), Times.Once); } [Theory] @@ -333,17 +310,7 @@ public async Task Happy_Path_GithubSource_Ghes() [InlineData(true)] public async Task Happy_Path_UseGithubStorage(bool useGhesBlobCredentials) { - var githubOrgId = Guid.NewGuid().ToString(); var githubOrgDatabaseId = Guid.NewGuid().ToString(); - var migrationSourceId = Guid.NewGuid().ToString(); - var sourceGithubPat = Guid.NewGuid().ToString(); - var targetGithubPat = Guid.NewGuid().ToString(); - var githubRepoUrl = $"https://myghes/{SOURCE_ORG}/{SOURCE_REPO}"; - var migrationId = "valid-migration-id"; // Ensure a valid migration ID is returned - var gitArchiveId = 1; - var metadataArchiveId = 2; - var gitArchiveUrl = $"https://example.com/{gitArchiveId}"; - var metadataArchiveUrl = $"https://example.com/{metadataArchiveId}"; var uploadedGitArchiveUrl = "gei://archive/1"; var uploadedMetadataArchiveUrl = "gei://archive/2"; var gitArchiveDownloadFilePath = "git_archive_downaloded.tmp"; @@ -370,33 +337,33 @@ public async Task Happy_Path_UseGithubStorage(bool useGhesBlobCredentials) _mockGhesVersionChecker.Setup(m => m.AreBlobCredentialsRequired(GHES_API_URL)).ReturnsAsync(useGhesBlobCredentials); _mockTargetGithubApi.Setup(x => x.DoesOrgExist(TARGET_ORG).Result).Returns(true); - _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId); + _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(GITHUB_ORG_ID); _mockTargetGithubApi.Setup(x => x.GetOrganizationDatabaseId(TARGET_ORG).Result).Returns(githubOrgDatabaseId); - _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result).Returns(migrationSourceId); + _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(GITHUB_ORG_ID).Result).Returns(MIGRATION_SOURCE_ID); _mockTargetGithubApi.Setup(x => x.StartMigration( - migrationSourceId, - githubRepoUrl, - githubOrgId, + MIGRATION_SOURCE_ID, + GHES_REPO_URL, + GITHUB_ORG_ID, TARGET_REPO, - sourceGithubPat, - targetGithubPat, + GITHUB_SOURCE_PAT, + GITHUB_TARGET_PAT, uploadedGitArchiveUrl, uploadedMetadataArchiveUrl, false, null, false).Result) - .Returns(migrationId); + .Returns(MIGRATION_ID); - _mockTargetGithubApi.Setup(x => x.GetMigration(migrationId).Result) + _mockTargetGithubApi.Setup(x => x.GetMigration(MIGRATION_ID).Result) .Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); - _mockSourceGithubApi.Setup(x => x.StartGitArchiveGeneration(SOURCE_ORG, SOURCE_REPO).Result).Returns(gitArchiveId); - _mockSourceGithubApi.Setup(x => x.StartMetadataArchiveGeneration(SOURCE_ORG, SOURCE_REPO, false, false).Result).Returns(metadataArchiveId); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, gitArchiveId).Result).Returns(ArchiveMigrationStatus.Exported); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, metadataArchiveId).Result).Returns(ArchiveMigrationStatus.Exported); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, gitArchiveId).Result).Returns(gitArchiveUrl); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, metadataArchiveId).Result).Returns(metadataArchiveUrl); + _mockSourceGithubApi.Setup(x => x.StartGitArchiveGeneration(SOURCE_ORG, SOURCE_REPO).Result).Returns(GIT_ARCHIVE_ID); + _mockSourceGithubApi.Setup(x => x.StartMetadataArchiveGeneration(SOURCE_ORG, SOURCE_REPO, false, false).Result).Returns(METADATA_ARCHIVE_ID); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, GIT_ARCHIVE_ID).Result).Returns(ArchiveMigrationStatus.Exported); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, METADATA_ARCHIVE_ID).Result).Returns(ArchiveMigrationStatus.Exported); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, GIT_ARCHIVE_ID).Result).Returns(GIT_ARCHIVE_URL); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, METADATA_ARCHIVE_ID).Result).Returns(METADATA_ARCHIVE_URL); _mockTargetGithubApi .Setup(x => x.UploadArchiveToGithubStorage( @@ -418,8 +385,8 @@ public async Task Happy_Path_UseGithubStorage(bool useGhesBlobCredentials) SourceRepo = SOURCE_REPO, GithubTargetOrg = TARGET_ORG, TargetRepo = TARGET_REPO, - GithubSourcePat = sourceGithubPat, - GithubTargetPat = targetGithubPat, + GithubSourcePat = GITHUB_SOURCE_PAT, + GithubTargetPat = GITHUB_TARGET_PAT, TargetApiUrl = TARGET_API_URL, GhesApiUrl = GHES_API_URL, UseGithubStorage = true, @@ -427,65 +394,52 @@ public async Task Happy_Path_UseGithubStorage(bool useGhesBlobCredentials) await _handler.Handle(args); - _mockTargetGithubApi.Verify(x => x.GetMigration(migrationId)); + _mockTargetGithubApi.Verify(x => x.GetMigration(MIGRATION_ID)); _mockFileSystemProvider.Verify(x => x.DeleteIfExists(gitArchiveDownloadFilePath), Times.Once); _mockFileSystemProvider.Verify(x => x.DeleteIfExists(metadataArchiveDownloadFilePath), Times.Once); } - [Fact] public async Task Happy_Path_GithubSource_Ghes_Repo_Renamed() { - var githubOrgId = Guid.NewGuid().ToString(); - var migrationSourceId = Guid.NewGuid().ToString(); - var sourceGithubPat = Guid.NewGuid().ToString(); - var targetGithubPat = Guid.NewGuid().ToString(); - var githubRepoUrl = $"https://myghes/{SOURCE_ORG}/{SOURCE_REPO}"; - var migrationId = Guid.NewGuid().ToString(); - var gitArchiveId = 1; - var metadataArchiveId = 2; - var gitArchiveUrl = $"https://example.com/{gitArchiveId}"; - var metadataArchiveUrl = $"https://example.com/{metadataArchiveId}"; - var authenticatedGitArchiveUrl = new Uri($"https://example.com/{gitArchiveId}/authenticated"); - var authenticatedMetadataArchiveUrl = new Uri($"https://example.com/{metadataArchiveId}/authenticated"); - var gitArchiveFilePath = "path/to/git_archive"; - var metadataArchiveFilePath = "path/to/metadata_archive"; - - _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId); - _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result).Returns(migrationSourceId); + _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(GITHUB_ORG_ID); + _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(GITHUB_ORG_ID).Result).Returns(MIGRATION_SOURCE_ID); _mockTargetGithubApi .Setup(x => x.StartMigration( - migrationSourceId, - githubRepoUrl, - githubOrgId, + MIGRATION_SOURCE_ID, + GHES_REPO_URL, + GITHUB_ORG_ID, TARGET_REPO, - sourceGithubPat, - targetGithubPat, - authenticatedGitArchiveUrl.ToString(), - authenticatedMetadataArchiveUrl.ToString(), + GITHUB_SOURCE_PAT, + GITHUB_TARGET_PAT, + AUTHENTICATED_GIT_ARCHIVE_URL, + AUTHENTICATED_METADATA_ARCHIVE_URL, false, null, false).Result) - .Returns(migrationId); - _mockTargetGithubApi.Setup(x => x.GetMigration(migrationId).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); + .Returns(MIGRATION_ID); + _mockTargetGithubApi.Setup(x => x.GetMigration(MIGRATION_ID).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); _mockTargetGithubApi.Setup(x => x.DoesOrgExist(TARGET_ORG).Result).Returns(true); - _mockSourceGithubApi.Setup(x => x.StartGitArchiveGeneration(SOURCE_ORG, SOURCE_REPO).Result).Returns(gitArchiveId); - _mockSourceGithubApi.Setup(x => x.StartMetadataArchiveGeneration(SOURCE_ORG, SOURCE_REPO, false, false).Result).Returns(metadataArchiveId); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, gitArchiveId).Result).Returns(ArchiveMigrationStatus.Exported); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, metadataArchiveId).Result).Returns(ArchiveMigrationStatus.Exported); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, gitArchiveId).Result).Returns(gitArchiveUrl); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, metadataArchiveId).Result).Returns(metadataArchiveUrl); + _mockSourceGithubApi.Setup(x => x.StartGitArchiveGeneration(SOURCE_ORG, SOURCE_REPO).Result).Returns(GIT_ARCHIVE_ID); + _mockSourceGithubApi.Setup(x => x.StartMetadataArchiveGeneration(SOURCE_ORG, SOURCE_REPO, false, false).Result).Returns(METADATA_ARCHIVE_ID); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, GIT_ARCHIVE_ID).Result).Returns(ArchiveMigrationStatus.Exported); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, METADATA_ARCHIVE_ID).Result).Returns(ArchiveMigrationStatus.Exported); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, GIT_ARCHIVE_ID).Result).Returns(GIT_ARCHIVE_URL); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, METADATA_ARCHIVE_ID).Result).Returns(METADATA_ARCHIVE_URL); - _mockAzureApi.SetupSequence(x => x.UploadToBlob(It.IsAny(), It.IsAny()).Result).Returns(authenticatedGitArchiveUrl).Returns(authenticatedMetadataArchiveUrl); + _mockAzureApi + .SetupSequence(x => x.UploadToBlob(It.IsAny(), It.IsAny()).Result) + .Returns(new Uri(AUTHENTICATED_GIT_ARCHIVE_URL)) + .Returns(new Uri(AUTHENTICATED_METADATA_ARCHIVE_URL)); _mockFileSystemProvider .SetupSequence(m => m.GetTempFileName()) - .Returns(gitArchiveFilePath) - .Returns(metadataArchiveFilePath); + .Returns(GIT_ARCHIVE_FILE_PATH) + .Returns(METADATA_ARCHIVE_FILE_PATH); - _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(sourceGithubPat); - _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(targetGithubPat); + _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_SOURCE_PAT); + _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_TARGET_PAT); _mockGhesVersionChecker.Setup(m => m.AreBlobCredentialsRequired(GHES_API_URL)).ReturnsAsync(true); @@ -501,44 +455,34 @@ public async Task Happy_Path_GithubSource_Ghes_Repo_Renamed() }; await _handler.Handle(args); - _mockTargetGithubApi.Verify(x => x.GetMigration(migrationId)); - _mockFileSystemProvider.Verify(x => x.DeleteIfExists(gitArchiveFilePath), Times.Once); - _mockFileSystemProvider.Verify(x => x.DeleteIfExists(metadataArchiveFilePath), Times.Once); + _mockTargetGithubApi.Verify(x => x.GetMigration(MIGRATION_ID)); + _mockFileSystemProvider.Verify(x => x.DeleteIfExists(GIT_ARCHIVE_FILE_PATH), Times.Once); + _mockFileSystemProvider.Verify(x => x.DeleteIfExists(METADATA_ARCHIVE_FILE_PATH), Times.Once); } [Fact] public async Task Github_With_Archive_Urls() { - var githubOrgId = Guid.NewGuid().ToString(); - var migrationSourceId = Guid.NewGuid().ToString(); - var sourceGithubPat = Guid.NewGuid().ToString(); - var targetGithubPat = Guid.NewGuid().ToString(); - var githubRepoUrl = $"https://github.com/{SOURCE_ORG}/{SOURCE_REPO}"; - var migrationId = Guid.NewGuid().ToString(); - - var gitArchiveUrl = "https://example.com/git_archive.tar.gz"; - var metadataArchiveUrl = "https://example.com/metadata_archive.tar.gz"; - - _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId); - _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result).Returns(migrationSourceId); + _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(GITHUB_ORG_ID); + _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(GITHUB_ORG_ID).Result).Returns(MIGRATION_SOURCE_ID); _mockTargetGithubApi .Setup(x => x.StartMigration( - migrationSourceId, - githubRepoUrl, - githubOrgId, + MIGRATION_SOURCE_ID, + GITHUB_REPO_URL, + GITHUB_ORG_ID, TARGET_REPO, - sourceGithubPat, - targetGithubPat, - gitArchiveUrl, - metadataArchiveUrl, + GITHUB_SOURCE_PAT, + GITHUB_TARGET_PAT, + GIT_ARCHIVE_URL, + METADATA_ARCHIVE_URL, false, null, false).Result) - .Returns(migrationId); - _mockTargetGithubApi.Setup(x => x.GetMigration(migrationId).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); + .Returns(MIGRATION_ID); + _mockTargetGithubApi.Setup(x => x.GetMigration(MIGRATION_ID).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); - _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(sourceGithubPat); - _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(targetGithubPat); + _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_SOURCE_PAT); + _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_TARGET_PAT); var args = new MigrateRepoCommandArgs { @@ -547,55 +491,47 @@ public async Task Github_With_Archive_Urls() GithubTargetOrg = TARGET_ORG, TargetRepo = TARGET_REPO, TargetApiUrl = TARGET_API_URL, - GitArchiveUrl = gitArchiveUrl, - MetadataArchiveUrl = metadataArchiveUrl, + GitArchiveUrl = GIT_ARCHIVE_URL, + MetadataArchiveUrl = METADATA_ARCHIVE_URL }; await _handler.Handle(args); - _mockTargetGithubApi.Verify(x => x.GetMigration(migrationId)); + _mockTargetGithubApi.Verify(x => x.GetMigration(MIGRATION_ID)); } [Fact] public async Task With_Archive_Paths() { - var githubOrgId = Guid.NewGuid().ToString(); - var migrationSourceId = Guid.NewGuid().ToString(); - var sourceGithubPat = Guid.NewGuid().ToString(); - var targetGithubPat = Guid.NewGuid().ToString(); - var githubRepoUrl = $"https://github.com/{SOURCE_ORG}/{SOURCE_REPO}"; - var gitArchiveUrl = $"https://example.com/{GIT_ARCHIVE_FILE_NAME}"; - var metadataArchiveUrl = $"https://example.com/{METADATA_ARCHIVE_FILE_NAME}"; var gitArchivePath = $"/path/{GIT_ARCHIVE_FILE_NAME}"; var metadataArchivePath = $"/path/{METADATA_ARCHIVE_FILE_NAME}"; - var migrationId = Guid.NewGuid().ToString(); _mockAzureApi .Setup(x => x.UploadToBlob(It.Is(s => s.EndsWith(GIT_ARCHIVE_FILE_NAME)), It.IsAny()).Result) - .Returns(new Uri(gitArchiveUrl)); + .Returns(new Uri(GIT_ARCHIVE_URL)); _mockAzureApi .Setup(x => x.UploadToBlob(It.Is(s => s.EndsWith(METADATA_ARCHIVE_FILE_NAME)), It.IsAny()).Result) - .Returns(new Uri(metadataArchiveUrl)); + .Returns(new Uri(METADATA_ARCHIVE_URL)); - _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId); - _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result).Returns(migrationSourceId); + _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(GITHUB_ORG_ID); + _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(GITHUB_ORG_ID).Result).Returns(MIGRATION_SOURCE_ID); _mockTargetGithubApi .Setup(x => x.StartMigration( - migrationSourceId, - githubRepoUrl, - githubOrgId, + MIGRATION_SOURCE_ID, + GITHUB_REPO_URL, + GITHUB_ORG_ID, TARGET_REPO, - sourceGithubPat, - targetGithubPat, - gitArchiveUrl, - metadataArchiveUrl, + GITHUB_SOURCE_PAT, + GITHUB_TARGET_PAT, + GIT_ARCHIVE_URL, + METADATA_ARCHIVE_URL, false, null, false).Result) - .Returns(migrationId); - _mockTargetGithubApi.Setup(x => x.GetMigration(migrationId).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); + .Returns(MIGRATION_ID); + _mockTargetGithubApi.Setup(x => x.GetMigration(MIGRATION_ID).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); - _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(sourceGithubPat); - _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(targetGithubPat); + _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_SOURCE_PAT); + _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_TARGET_PAT); var args = new MigrateRepoCommandArgs { @@ -610,14 +546,67 @@ public async Task With_Archive_Paths() }; await _handler.Handle(args); - _mockTargetGithubApi.Verify(x => x.GetMigration(migrationId)); + _mockTargetGithubApi.Verify(x => x.GetMigration(MIGRATION_ID)); + + _mockAzureApi.Verify(x => x.UploadToBlob(It.Is(s => s.EndsWith(GIT_ARCHIVE_FILE_NAME)), It.IsAny()), Times.Once()); + _mockAzureApi.Verify(x => x.UploadToBlob(It.Is(s => s.EndsWith(METADATA_ARCHIVE_FILE_NAME)), It.IsAny()), Times.Once()); + _mockAzureApi.VerifyNoOtherCalls(); } [Fact] - public async Task Github_Only_One_Archive_Url_Throws_Error() + public async Task With_Duplicate_Archive_Paths() { - var gitArchiveUrl = "https://example.com/git_archive.tar.gz"; + var gitArchivePath = $"/path/{GIT_ARCHIVE_FILE_NAME}"; + var metadataArchivePath = $"/path/{GIT_ARCHIVE_FILE_NAME}"; + var duplicateArchiveFileName = "archive.tar.gz"; + + _mockAzureApi + .Setup(x => x.UploadToBlob(It.Is(s => s.EndsWith(duplicateArchiveFileName)), It.IsAny()).Result) + .Returns(new Uri(GIT_ARCHIVE_URL)); + _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(GITHUB_ORG_ID); + _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(GITHUB_ORG_ID).Result).Returns(MIGRATION_SOURCE_ID); + _mockTargetGithubApi + .Setup(x => x.StartMigration( + MIGRATION_SOURCE_ID, + GITHUB_REPO_URL, + GITHUB_ORG_ID, + TARGET_REPO, + GITHUB_SOURCE_PAT, + GITHUB_TARGET_PAT, + GIT_ARCHIVE_URL, + GIT_ARCHIVE_URL, + false, + null, + false).Result) + .Returns(MIGRATION_ID); + _mockTargetGithubApi.Setup(x => x.GetMigration(MIGRATION_ID).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); + + _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_SOURCE_PAT); + _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_TARGET_PAT); + + var args = new MigrateRepoCommandArgs + { + GithubSourceOrg = SOURCE_ORG, + SourceRepo = SOURCE_REPO, + GithubTargetOrg = TARGET_ORG, + TargetRepo = TARGET_REPO, + TargetApiUrl = TARGET_API_URL, + GitArchivePath = gitArchivePath, + MetadataArchivePath = metadataArchivePath, + AzureStorageConnectionString = AZURE_CONNECTION_STRING + }; + await _handler.Handle(args); + + _mockTargetGithubApi.Verify(x => x.GetMigration(MIGRATION_ID)); + + _mockAzureApi.Verify(x => x.UploadToBlob(It.Is(s => s.EndsWith(duplicateArchiveFileName)), It.IsAny()), Times.Once()); + _mockAzureApi.VerifyNoOtherCalls(); + } + + [Fact] + public async Task Github_Only_One_Archive_Url_Throws_Error() + { await FluentActions .Invoking(async () => await _handler.Handle(new MigrateRepoCommandArgs { @@ -626,7 +615,7 @@ await FluentActions GithubTargetOrg = TARGET_ORG, TargetRepo = TARGET_REPO, TargetApiUrl = TARGET_API_URL, - GitArchiveUrl = gitArchiveUrl, + GitArchiveUrl = GIT_ARCHIVE_URL, })) .Should().ThrowAsync(); } @@ -650,53 +639,40 @@ await FluentActions [Fact] public async Task Ghes_AzureConnectionString_Uses_Env_When_Option_Empty() { - var azureConnectionStringEnv = Guid.NewGuid().ToString(); - - var githubOrgId = Guid.NewGuid().ToString(); - var migrationSourceId = Guid.NewGuid().ToString(); - var sourceGithubPat = Guid.NewGuid().ToString(); - var targetGithubPat = Guid.NewGuid().ToString(); - var githubRepoUrl = $"https://myghes/{SOURCE_ORG}/{SOURCE_REPO}"; - var migrationId = Guid.NewGuid().ToString(); - var gitArchiveId = 1; - var metadataArchiveId = 2; - - var gitArchiveUrl = $"https://example.com/{gitArchiveId}"; - var metadataArchiveUrl = $"https://example.com/{metadataArchiveId}"; - var authenticatedGitArchiveUrl = new Uri($"https://example.com/{gitArchiveId}/authenticated"); - var authenticatedMetadataArchiveUrl = new Uri($"https://example.com/{metadataArchiveId}/authenticated"); - - _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId); - _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result).Returns(migrationSourceId); + _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(GITHUB_ORG_ID); + _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(GITHUB_ORG_ID).Result).Returns(MIGRATION_SOURCE_ID); _mockTargetGithubApi .Setup(x => x.StartMigration( - migrationSourceId, - githubRepoUrl, - githubOrgId, + MIGRATION_SOURCE_ID, + GHES_REPO_URL, + GITHUB_ORG_ID, TARGET_REPO, - sourceGithubPat, - targetGithubPat, - authenticatedGitArchiveUrl.ToString(), - authenticatedMetadataArchiveUrl.ToString(), + GITHUB_SOURCE_PAT, + GITHUB_TARGET_PAT, + AUTHENTICATED_GIT_ARCHIVE_URL, + AUTHENTICATED_METADATA_ARCHIVE_URL, false, null, false).Result) - .Returns(migrationId); - _mockTargetGithubApi.Setup(x => x.GetMigration(migrationId).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); + .Returns(MIGRATION_ID); + _mockTargetGithubApi.Setup(x => x.GetMigration(MIGRATION_ID).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); _mockTargetGithubApi.Setup(x => x.DoesOrgExist(TARGET_ORG).Result).Returns(true); - _mockSourceGithubApi.Setup(x => x.StartGitArchiveGeneration(SOURCE_ORG, SOURCE_REPO).Result).Returns(gitArchiveId); - _mockSourceGithubApi.Setup(x => x.StartMetadataArchiveGeneration(SOURCE_ORG, SOURCE_REPO, false, false).Result).Returns(metadataArchiveId); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, gitArchiveId).Result).Returns(ArchiveMigrationStatus.Exported); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, metadataArchiveId).Result).Returns(ArchiveMigrationStatus.Exported); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, gitArchiveId).Result).Returns(gitArchiveUrl); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, metadataArchiveId).Result).Returns(metadataArchiveUrl); + _mockSourceGithubApi.Setup(x => x.StartGitArchiveGeneration(SOURCE_ORG, SOURCE_REPO).Result).Returns(GIT_ARCHIVE_ID); + _mockSourceGithubApi.Setup(x => x.StartMetadataArchiveGeneration(SOURCE_ORG, SOURCE_REPO, false, false).Result).Returns(METADATA_ARCHIVE_ID); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, GIT_ARCHIVE_ID).Result).Returns(ArchiveMigrationStatus.Exported); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, METADATA_ARCHIVE_ID).Result).Returns(ArchiveMigrationStatus.Exported); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, GIT_ARCHIVE_ID).Result).Returns(GIT_ARCHIVE_URL); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, METADATA_ARCHIVE_ID).Result).Returns(METADATA_ARCHIVE_URL); - _mockAzureApi.SetupSequence(x => x.UploadToBlob(It.IsAny(), It.IsAny()).Result).Returns(authenticatedGitArchiveUrl).Returns(authenticatedMetadataArchiveUrl); + _mockAzureApi + .SetupSequence(x => x.UploadToBlob(It.IsAny(), It.IsAny()).Result) + .Returns(new Uri(AUTHENTICATED_GIT_ARCHIVE_URL)) + .Returns(new Uri(AUTHENTICATED_METADATA_ARCHIVE_URL)); - _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(sourceGithubPat); - _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(targetGithubPat); - _mockEnvironmentVariableProvider.Setup(m => m.AzureStorageConnectionString(It.IsAny())).Returns(azureConnectionStringEnv); + _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_SOURCE_PAT); + _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_TARGET_PAT); + _mockEnvironmentVariableProvider.Setup(m => m.AzureStorageConnectionString(It.IsAny())).Returns(AZURE_CONNECTION_STRING); _mockGhesVersionChecker.Setup(m => m.AreBlobCredentialsRequired(GHES_API_URL)).ReturnsAsync(true); @@ -711,56 +687,45 @@ public async Task Ghes_AzureConnectionString_Uses_Env_When_Option_Empty() }; await _handler.Handle(args); - _mockTargetGithubApi.Verify(x => x.GetMigration(migrationId)); + _mockTargetGithubApi.Verify(x => x.GetMigration(MIGRATION_ID)); } [Fact] public async Task Ghes_With_NoSslVerify_Uses_NoSsl_Client() { - var githubOrgId = Guid.NewGuid().ToString(); - var migrationSourceId = Guid.NewGuid().ToString(); - var sourceGithubPat = Guid.NewGuid().ToString(); - var targetGithubPat = Guid.NewGuid().ToString(); - var githubRepoUrl = $"https://myghes/{SOURCE_ORG}/{SOURCE_REPO}"; - var migrationId = Guid.NewGuid().ToString(); - var gitArchiveId = 1; - var metadataArchiveId = 2; - - var gitArchiveUrl = $"https://example.com/{gitArchiveId}"; - var metadataArchiveUrl = $"https://example.com/{metadataArchiveId}"; - var authenticatedGitArchiveUrl = new Uri($"https://example.com/{gitArchiveId}/authenticated"); - var authenticatedMetadataArchiveUrl = new Uri($"https://example.com/{metadataArchiveId}/authenticated"); - - _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId); - _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result).Returns(migrationSourceId); + _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(GITHUB_ORG_ID); + _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(GITHUB_ORG_ID).Result).Returns(MIGRATION_SOURCE_ID); _mockTargetGithubApi .Setup(x => x.StartMigration( - migrationSourceId, - githubRepoUrl, - githubOrgId, + MIGRATION_SOURCE_ID, + GHES_REPO_URL, + GITHUB_ORG_ID, TARGET_REPO, - sourceGithubPat, - targetGithubPat, - authenticatedGitArchiveUrl.ToString(), - authenticatedMetadataArchiveUrl.ToString(), + GITHUB_SOURCE_PAT, + GITHUB_TARGET_PAT, + AUTHENTICATED_GIT_ARCHIVE_URL, + AUTHENTICATED_METADATA_ARCHIVE_URL, false, null, false).Result) - .Returns(migrationId); - _mockTargetGithubApi.Setup(x => x.GetMigration(migrationId).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); + .Returns(MIGRATION_ID); + _mockTargetGithubApi.Setup(x => x.GetMigration(MIGRATION_ID).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); _mockTargetGithubApi.Setup(x => x.DoesOrgExist(TARGET_ORG).Result).Returns(true); - _mockSourceGithubApi.Setup(x => x.StartGitArchiveGeneration(SOURCE_ORG, SOURCE_REPO).Result).Returns(gitArchiveId); - _mockSourceGithubApi.Setup(x => x.StartMetadataArchiveGeneration(SOURCE_ORG, SOURCE_REPO, false, false).Result).Returns(metadataArchiveId); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, gitArchiveId).Result).Returns(ArchiveMigrationStatus.Exported); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, metadataArchiveId).Result).Returns(ArchiveMigrationStatus.Exported); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, gitArchiveId).Result).Returns(gitArchiveUrl); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, metadataArchiveId).Result).Returns(metadataArchiveUrl); + _mockSourceGithubApi.Setup(x => x.StartGitArchiveGeneration(SOURCE_ORG, SOURCE_REPO).Result).Returns(GIT_ARCHIVE_ID); + _mockSourceGithubApi.Setup(x => x.StartMetadataArchiveGeneration(SOURCE_ORG, SOURCE_REPO, false, false).Result).Returns(METADATA_ARCHIVE_ID); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, GIT_ARCHIVE_ID).Result).Returns(ArchiveMigrationStatus.Exported); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, METADATA_ARCHIVE_ID).Result).Returns(ArchiveMigrationStatus.Exported); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, GIT_ARCHIVE_ID).Result).Returns(GIT_ARCHIVE_URL); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, METADATA_ARCHIVE_ID).Result).Returns(METADATA_ARCHIVE_URL); - _mockAzureApi.SetupSequence(x => x.UploadToBlob(It.IsAny(), It.IsAny()).Result).Returns(authenticatedGitArchiveUrl).Returns(authenticatedMetadataArchiveUrl); + _mockAzureApi + .SetupSequence(x => x.UploadToBlob(It.IsAny(), It.IsAny()).Result) + .Returns(new Uri(AUTHENTICATED_GIT_ARCHIVE_URL)) + .Returns(new Uri(AUTHENTICATED_METADATA_ARCHIVE_URL)); - _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(sourceGithubPat); - _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(targetGithubPat); + _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_SOURCE_PAT); + _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_TARGET_PAT); _mockGhesVersionChecker.Setup(m => m.AreBlobCredentialsRequired(GHES_API_URL)).ReturnsAsync(true); @@ -777,53 +742,41 @@ public async Task Ghes_With_NoSslVerify_Uses_NoSsl_Client() }; await _handler.Handle(args); - _mockTargetGithubApi.Verify(x => x.GetMigration(migrationId)); + _mockTargetGithubApi.Verify(x => x.GetMigration(MIGRATION_ID)); } [Fact] public async Task Ghes_With_3_8_0_Version_Returns_Archive_Urls_Directly() { - var githubOrgId = Guid.NewGuid().ToString(); - var migrationSourceId = Guid.NewGuid().ToString(); - var sourceGithubPat = Guid.NewGuid().ToString(); - var targetGithubPat = Guid.NewGuid().ToString(); - var githubRepoUrl = $"https://myghes/{SOURCE_ORG}/{SOURCE_REPO}"; - var migrationId = Guid.NewGuid().ToString(); - var gitArchiveId = 1; - var metadataArchiveId = 2; - - var gitArchiveUrl = $"https://example.com/{gitArchiveId}"; - var metadataArchiveUrl = $"https://example.com/{metadataArchiveId}"; - - _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId); - _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result).Returns(migrationSourceId); + _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(GITHUB_ORG_ID); + _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(GITHUB_ORG_ID).Result).Returns(MIGRATION_SOURCE_ID); _mockTargetGithubApi .Setup(x => x.StartMigration( - migrationSourceId, - githubRepoUrl, - githubOrgId, + MIGRATION_SOURCE_ID, + GHES_REPO_URL, + GITHUB_ORG_ID, TARGET_REPO, - sourceGithubPat, - targetGithubPat, - gitArchiveUrl, - metadataArchiveUrl, + GITHUB_SOURCE_PAT, + GITHUB_TARGET_PAT, + GIT_ARCHIVE_URL, + METADATA_ARCHIVE_URL, false, null, false).Result) - .Returns(migrationId); - _mockTargetGithubApi.Setup(x => x.GetMigration(migrationId).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); + .Returns(MIGRATION_ID); + _mockTargetGithubApi.Setup(x => x.GetMigration(MIGRATION_ID).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); _mockTargetGithubApi.Setup(x => x.DoesOrgExist(TARGET_ORG).Result).Returns(true); - _mockSourceGithubApi.Setup(x => x.StartGitArchiveGeneration(SOURCE_ORG, SOURCE_REPO).Result).Returns(gitArchiveId); - _mockSourceGithubApi.Setup(x => x.StartMetadataArchiveGeneration(SOURCE_ORG, SOURCE_REPO, false, false).Result).Returns(metadataArchiveId); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, gitArchiveId).Result).Returns(ArchiveMigrationStatus.Exported); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, metadataArchiveId).Result).Returns(ArchiveMigrationStatus.Exported); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, gitArchiveId).Result).Returns(gitArchiveUrl); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, metadataArchiveId).Result).Returns(metadataArchiveUrl); + _mockSourceGithubApi.Setup(x => x.StartGitArchiveGeneration(SOURCE_ORG, SOURCE_REPO).Result).Returns(GIT_ARCHIVE_ID); + _mockSourceGithubApi.Setup(x => x.StartMetadataArchiveGeneration(SOURCE_ORG, SOURCE_REPO, false, false).Result).Returns(METADATA_ARCHIVE_ID); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, GIT_ARCHIVE_ID).Result).Returns(ArchiveMigrationStatus.Exported); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, METADATA_ARCHIVE_ID).Result).Returns(ArchiveMigrationStatus.Exported); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, GIT_ARCHIVE_ID).Result).Returns(GIT_ARCHIVE_URL); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, METADATA_ARCHIVE_ID).Result).Returns(METADATA_ARCHIVE_URL); - _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(sourceGithubPat); - _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(targetGithubPat); + _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_SOURCE_PAT); + _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_TARGET_PAT); _mockGhesVersionChecker.Setup(m => m.AreBlobCredentialsRequired(GHES_API_URL)).ReturnsAsync(false); @@ -839,18 +792,15 @@ public async Task Ghes_With_3_8_0_Version_Returns_Archive_Urls_Directly() }; await _handler.Handle(args); - _mockTargetGithubApi.Verify(x => x.GetMigration(migrationId)); + _mockTargetGithubApi.Verify(x => x.GetMigration(MIGRATION_ID)); } [Fact] public async Task Ghes_Failed_Archive_Generation_Throws_Error() { - var gitArchiveId = 1; - var metadataArchiveId = 2; - - _mockSourceGithubApi.Setup(x => x.StartGitArchiveGeneration(SOURCE_ORG, SOURCE_REPO).Result).Returns(gitArchiveId); - _mockSourceGithubApi.Setup(x => x.StartMetadataArchiveGeneration(SOURCE_ORG, SOURCE_REPO, false, false).Result).Returns(metadataArchiveId); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, gitArchiveId).Result).Returns(ArchiveMigrationStatus.Failed); + _mockSourceGithubApi.Setup(x => x.StartGitArchiveGeneration(SOURCE_ORG, SOURCE_REPO).Result).Returns(GIT_ARCHIVE_ID); + _mockSourceGithubApi.Setup(x => x.StartMetadataArchiveGeneration(SOURCE_ORG, SOURCE_REPO, false, false).Result).Returns(METADATA_ARCHIVE_ID); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, GIT_ARCHIVE_ID).Result).Returns(ArchiveMigrationStatus.Failed); _mockGhesVersionChecker.Setup(m => m.AreBlobCredentialsRequired(GHES_API_URL)).ReturnsAsync(true); @@ -872,77 +822,65 @@ await FluentActions [Fact] public async Task Ghes_Retries_Archive_Generation_On_Any_Error() { - var githubOrgId = Guid.NewGuid().ToString(); - var migrationSourceId = Guid.NewGuid().ToString(); - var sourceGithubPat = Guid.NewGuid().ToString(); - var targetGithubPat = Guid.NewGuid().ToString(); - var githubRepoUrl = $"https://myghes/{SOURCE_ORG}/{SOURCE_REPO}"; - var migrationId = Guid.NewGuid().ToString(); - var gitArchiveId = 1; - var metadataArchiveId = 2; - var gitArchiveUrl = $"https://example.com/{gitArchiveId}"; - var metadataArchiveUrl = $"https://example.com/{metadataArchiveId}"; - var authenticatedGitArchiveUrl = new Uri($"https://example.com/{gitArchiveId}/authenticated"); - var authenticatedMetadataArchiveUrl = new Uri($"https://example.com/{metadataArchiveId}/authenticated"); - var gitArchiveFilePath = "path/to/git_archive"; - var metadataArchiveFilePath = "path/to/metadata_archive"; - _mockSourceGithubApi.Setup(x => x.GetEnterpriseServerVersion()).ReturnsAsync("3.7.1"); - _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId); - _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result).Returns(migrationSourceId); + _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(GITHUB_ORG_ID); + _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(GITHUB_ORG_ID).Result).Returns(MIGRATION_SOURCE_ID); _mockTargetGithubApi .Setup(x => x.StartMigration( - migrationSourceId, - githubRepoUrl, - githubOrgId, + MIGRATION_SOURCE_ID, + GHES_REPO_URL, + GITHUB_ORG_ID, TARGET_REPO, - sourceGithubPat, - targetGithubPat, - authenticatedGitArchiveUrl.ToString(), - authenticatedMetadataArchiveUrl.ToString(), + GITHUB_SOURCE_PAT, + GITHUB_TARGET_PAT, + AUTHENTICATED_GIT_ARCHIVE_URL, + AUTHENTICATED_METADATA_ARCHIVE_URL, false, null, false).Result) - .Returns(migrationId); - _mockTargetGithubApi.Setup(x => x.GetMigration(migrationId).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); + .Returns(MIGRATION_ID); + _mockTargetGithubApi.Setup(x => x.GetMigration(MIGRATION_ID).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); _mockTargetGithubApi.Setup(x => x.DoesOrgExist(TARGET_ORG).Result).Returns(true); _mockSourceGithubApi .SetupSequence(x => x.StartGitArchiveGeneration(SOURCE_ORG, SOURCE_REPO).Result) .Throws() - .Returns(gitArchiveId) - .Returns(gitArchiveId) // for first StartMetadataArchiveGeneration throw - .Returns(gitArchiveId) // for second StartMetadataArchiveGeneration throw - .Returns(gitArchiveId) // for GetArchiveMigrationStatus Failed - .Returns(gitArchiveId); // for GetArchiveMigrationStatus TimeoutException + .Returns(GIT_ARCHIVE_ID) + .Returns(GIT_ARCHIVE_ID) // for first StartMetadataArchiveGeneration throw + .Returns(GIT_ARCHIVE_ID) // for second StartMetadataArchiveGeneration throw + .Returns(GIT_ARCHIVE_ID) // for GetArchiveMigrationStatus Failed + .Returns(GIT_ARCHIVE_ID); // for GetArchiveMigrationStatus TimeoutException _mockSourceGithubApi .SetupSequence(x => x.StartMetadataArchiveGeneration(SOURCE_ORG, SOURCE_REPO, false, false).Result) .Throws() .Throws() - .Returns(metadataArchiveId) - .Returns(metadataArchiveId) // for GetArchiveMigrationStatus Failed - .Returns(metadataArchiveId); // for GetArchiveMigrationStatus TimeoutException + .Returns(METADATA_ARCHIVE_ID) + .Returns(METADATA_ARCHIVE_ID) // for GetArchiveMigrationStatus Failed + .Returns(METADATA_ARCHIVE_ID); // for GetArchiveMigrationStatus TimeoutException _mockSourceGithubApi - .SetupSequence(x => x.GetArchiveMigrationStatus(SOURCE_ORG, gitArchiveId).Result) + .SetupSequence(x => x.GetArchiveMigrationStatus(SOURCE_ORG, GIT_ARCHIVE_ID).Result) .Returns(ArchiveMigrationStatus.Failed) .Returns(ArchiveMigrationStatus.Exported) .Returns(ArchiveMigrationStatus.Exported); // for GetArchiveMigrationStatus TimeoutException _mockSourceGithubApi - .SetupSequence(x => x.GetArchiveMigrationStatus(SOURCE_ORG, metadataArchiveId).Result) + .SetupSequence(x => x.GetArchiveMigrationStatus(SOURCE_ORG, METADATA_ARCHIVE_ID).Result) .Throws() .Returns(ArchiveMigrationStatus.Exported); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, gitArchiveId).Result).Returns(gitArchiveUrl); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, metadataArchiveId).Result).Returns(metadataArchiveUrl); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, GIT_ARCHIVE_ID).Result).Returns(GIT_ARCHIVE_URL); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, METADATA_ARCHIVE_ID).Result).Returns(METADATA_ARCHIVE_URL); - _mockAzureApi.SetupSequence(x => x.UploadToBlob(It.IsAny(), It.IsAny()).Result).Returns(authenticatedGitArchiveUrl).Returns(authenticatedMetadataArchiveUrl); + _mockAzureApi + .SetupSequence(x => x.UploadToBlob(It.IsAny(), It.IsAny()).Result) + .Returns(new Uri(AUTHENTICATED_GIT_ARCHIVE_URL)) + .Returns(new Uri(AUTHENTICATED_METADATA_ARCHIVE_URL)); _mockFileSystemProvider .SetupSequence(m => m.GetTempFileName()) - .Returns(gitArchiveFilePath) - .Returns(metadataArchiveFilePath); + .Returns(GIT_ARCHIVE_FILE_PATH) + .Returns(METADATA_ARCHIVE_FILE_PATH); - _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(sourceGithubPat); - _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(targetGithubPat); + _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_SOURCE_PAT); + _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_TARGET_PAT); _mockGhesVersionChecker.Setup(m => m.AreBlobCredentialsRequired(GHES_API_URL)).ReturnsAsync(true); @@ -958,7 +896,7 @@ public async Task Ghes_Retries_Archive_Generation_On_Any_Error() }; await _handler.Handle(args); - _mockTargetGithubApi.Verify(x => x.GetMigration(migrationId)); + _mockTargetGithubApi.Verify(x => x.GetMigration(MIGRATION_ID)); } [Fact] @@ -1052,10 +990,6 @@ public async Task It_Uses_Github_Source_Pat_When_Provided() [Fact] public async Task It_Skips_Releases_When_Option_Is_True() { - // Arrange - var actualLogOutput = new List(); - _mockOctoLogger.Setup(m => m.LogInformation(It.IsAny())).Callback(s => actualLogOutput.Add(s)); - // Act var args = new MigrateRepoCommandArgs { @@ -1087,8 +1021,6 @@ public async Task It_Skips_Releases_When_Option_Is_True() public async Task It_Locks_Source_Repo_When_Option_Is_True() { // Arrange - var actualLogOutput = new List(); - _mockOctoLogger.Setup(m => m.LogInformation(It.IsAny())).Callback(s => actualLogOutput.Add(s)); _mockTargetGithubApi.Setup(x => x.DoesOrgExist(TARGET_ORG).Result).Returns(true); // Act @@ -1226,12 +1158,12 @@ public async Task It_Extracts_Base_Ghes_Url_From_Ghes_Api_Url_Using_Alternate_Te { // Arrange const string ghesApiUrl = "https://api.myghes.com"; - var expectedGithubRepoUrl = $"https://myghes.com/{SOURCE_ORG}/{SOURCE_REPO}"; + var expectedGITHUB_REPO_URL = $"https://myghes.com/{SOURCE_ORG}/{SOURCE_REPO}"; _mockSourceGithubApi .Setup(x => x.StartMigration( It.IsAny(), - expectedGithubRepoUrl, + expectedGITHUB_REPO_URL, It.IsAny(), It.IsAny(), It.IsAny(), @@ -1241,7 +1173,7 @@ public async Task It_Extracts_Base_Ghes_Url_From_Ghes_Api_Url_Using_Alternate_Te false, It.IsAny(), false).Result) - .Returns("migrationId"); + .Returns("MIGRATION_ID"); _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(It.IsAny(), It.IsAny()).Result).Returns(ArchiveMigrationStatus.Exported); @@ -1266,7 +1198,7 @@ public async Task It_Extracts_Base_Ghes_Url_From_Ghes_Api_Url_Using_Alternate_Te // Assert _mockTargetGithubApi.Verify(m => m.StartMigration( It.IsAny(), - expectedGithubRepoUrl, + expectedGITHUB_REPO_URL, It.IsAny(), It.IsAny(), It.IsAny(), @@ -1283,12 +1215,12 @@ public async Task It_Falls_Back_To_The_Ghes_Api_Url_If_Could_Not_Extract_Base_Gh { // Arrange const string ghesApiUrl = "https://non-conforming-ghes-api-url"; - var expectedGithubRepoUrl = $"{ghesApiUrl}/{SOURCE_ORG}/{SOURCE_REPO}"; + var expectedGITHUB_REPO_URL = $"{ghesApiUrl}/{SOURCE_ORG}/{SOURCE_REPO}"; _mockTargetGithubApi .Setup(x => x.StartMigration( It.IsAny(), - expectedGithubRepoUrl, + expectedGITHUB_REPO_URL, It.IsAny(), It.IsAny(), It.IsAny(), @@ -1298,7 +1230,7 @@ public async Task It_Falls_Back_To_The_Ghes_Api_Url_If_Could_Not_Extract_Base_Gh false, It.IsAny(), false).Result) - .Returns("migrationId"); + .Returns("MIGRATION_ID"); _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(It.IsAny(), It.IsAny()).Result).Returns(ArchiveMigrationStatus.Exported); @@ -1323,7 +1255,7 @@ public async Task It_Falls_Back_To_The_Ghes_Api_Url_If_Could_Not_Extract_Base_Gh // Assert _mockTargetGithubApi.Verify(m => m.StartMigration( It.IsAny(), - expectedGithubRepoUrl, + expectedGITHUB_REPO_URL, It.IsAny(), It.IsAny(), It.IsAny(), @@ -1338,17 +1270,6 @@ public async Task It_Falls_Back_To_The_Ghes_Api_Url_If_Could_Not_Extract_Base_Gh [Fact] public async Task It_Uses_Aws_If_Arguments_Are_Included() { - var githubOrgId = Guid.NewGuid().ToString(); - var migrationSourceId = Guid.NewGuid().ToString(); - var sourceGithubPat = Guid.NewGuid().ToString(); - var targetGithubPat = Guid.NewGuid().ToString(); - var githubRepoUrl = $"https://myghes/{SOURCE_ORG}/{SOURCE_REPO}"; - var migrationId = Guid.NewGuid().ToString(); - var gitArchiveId = 1; - var metadataArchiveId = 2; - - var gitArchiveUrl = $"https://example.com/{gitArchiveId}"; - var metadataArchiveUrl = $"https://example.com/{metadataArchiveId}"; var gitArchiveContent = new byte[] { 1, 2, 3, 4, 5 }; var metadataArchiveContent = new byte[] { 6, 7, 8, 9, 10 }; @@ -1358,37 +1279,37 @@ public async Task It_Uses_Aws_If_Arguments_Are_Included() var awsRegion = "eu-west-1"; var archiveUrl = $"https://s3.amazonaws.com/{awsBucketName}/archive.tar"; - _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId); - _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result).Returns(migrationSourceId); + _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(GITHUB_ORG_ID); + _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(GITHUB_ORG_ID).Result).Returns(MIGRATION_SOURCE_ID); _mockTargetGithubApi .Setup(x => x.StartMigration( - migrationSourceId, - githubRepoUrl, - githubOrgId, + MIGRATION_SOURCE_ID, + GHES_REPO_URL, + GITHUB_ORG_ID, TARGET_REPO, - sourceGithubPat, - targetGithubPat, + GITHUB_SOURCE_PAT, + GITHUB_TARGET_PAT, archiveUrl, archiveUrl, false, null, false).Result) - .Returns(migrationId); - _mockTargetGithubApi.Setup(x => x.GetMigration(migrationId).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); + .Returns(MIGRATION_ID); + _mockTargetGithubApi.Setup(x => x.GetMigration(MIGRATION_ID).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, null, null)); _mockTargetGithubApi.Setup(x => x.DoesOrgExist(TARGET_ORG).Result).Returns(true); - _mockSourceGithubApi.Setup(x => x.StartGitArchiveGeneration(SOURCE_ORG, SOURCE_REPO).Result).Returns(gitArchiveId); - _mockSourceGithubApi.Setup(x => x.StartMetadataArchiveGeneration(SOURCE_ORG, SOURCE_REPO, false, false).Result).Returns(metadataArchiveId); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, gitArchiveId).Result).Returns(ArchiveMigrationStatus.Exported); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, metadataArchiveId).Result).Returns(ArchiveMigrationStatus.Exported); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, gitArchiveId).Result).Returns(gitArchiveUrl); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, metadataArchiveId).Result).Returns(metadataArchiveUrl); + _mockSourceGithubApi.Setup(x => x.StartGitArchiveGeneration(SOURCE_ORG, SOURCE_REPO).Result).Returns(GIT_ARCHIVE_ID); + _mockSourceGithubApi.Setup(x => x.StartMetadataArchiveGeneration(SOURCE_ORG, SOURCE_REPO, false, false).Result).Returns(METADATA_ARCHIVE_ID); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, GIT_ARCHIVE_ID).Result).Returns(ArchiveMigrationStatus.Exported); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, METADATA_ARCHIVE_ID).Result).Returns(ArchiveMigrationStatus.Exported); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, GIT_ARCHIVE_ID).Result).Returns(GIT_ARCHIVE_URL); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, METADATA_ARCHIVE_ID).Result).Returns(METADATA_ARCHIVE_URL); - _mockHttpDownloadService.Setup(x => x.DownloadToBytes(gitArchiveUrl).Result).Returns(gitArchiveContent); - _mockHttpDownloadService.Setup(x => x.DownloadToBytes(metadataArchiveUrl).Result).Returns(metadataArchiveContent); + _mockHttpDownloadService.Setup(x => x.DownloadToBytes(GIT_ARCHIVE_URL).Result).Returns(gitArchiveContent); + _mockHttpDownloadService.Setup(x => x.DownloadToBytes(METADATA_ARCHIVE_URL).Result).Returns(metadataArchiveContent); - _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(sourceGithubPat); - _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(targetGithubPat); + _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_SOURCE_PAT); + _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_TARGET_PAT); _mockAwsApi.Setup(m => m.UploadToBucket(awsBucketName, It.IsAny(), It.IsAny())).ReturnsAsync(archiveUrl); @@ -1592,57 +1513,44 @@ await _handler.Invoking(async x => await x.Handle(new MigrateRepoCommandArgs [Fact] public async Task Keep_Archive_Does_Not_Call_DeleteIfExists() { - var githubOrgId = Guid.NewGuid().ToString(); - var migrationSourceId = Guid.NewGuid().ToString(); - var sourceGithubPat = Guid.NewGuid().ToString(); - var targetGithubPat = Guid.NewGuid().ToString(); - var githubRepoUrl = $"https://myghes/{SOURCE_ORG}/{SOURCE_REPO}"; - var migrationId = Guid.NewGuid().ToString(); - var gitArchiveId = 1; - var metadataArchiveId = 2; - var gitArchiveFilePath = "path/to/git_archive"; - var metadataArchiveFilePath = "path/to/metadata_archive"; - - var gitArchiveUrl = $"https://example.com/{gitArchiveId}"; - var metadataArchiveUrl = $"https://example.com/{metadataArchiveId}"; - var authenticatedGitArchiveUrl = new Uri($"https://example.com/{gitArchiveId}/authenticated"); - var authenticatedMetadataArchiveUrl = new Uri($"https://example.com/{metadataArchiveId}/authenticated"); - - _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(githubOrgId); - _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(githubOrgId).Result).Returns(migrationSourceId); + _mockTargetGithubApi.Setup(x => x.GetOrganizationId(TARGET_ORG).Result).Returns(GITHUB_ORG_ID); + _mockTargetGithubApi.Setup(x => x.CreateGhecMigrationSource(GITHUB_ORG_ID).Result).Returns(MIGRATION_SOURCE_ID); _mockTargetGithubApi .Setup(x => x.StartMigration( - migrationSourceId, - githubRepoUrl, - githubOrgId, + MIGRATION_SOURCE_ID, + GHES_REPO_URL, + GITHUB_ORG_ID, TARGET_REPO, - sourceGithubPat, - targetGithubPat, - authenticatedGitArchiveUrl.ToString(), - authenticatedMetadataArchiveUrl.ToString(), + GITHUB_SOURCE_PAT, + GITHUB_TARGET_PAT, + AUTHENTICATED_GIT_ARCHIVE_URL, + AUTHENTICATED_METADATA_ARCHIVE_URL, false, null, false).Result) - .Returns(migrationId); - _mockTargetGithubApi.Setup(x => x.GetMigration(migrationId).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, "", "")); + .Returns(MIGRATION_ID); + _mockTargetGithubApi.Setup(x => x.GetMigration(MIGRATION_ID).Result).Returns((State: RepositoryMigrationStatus.Succeeded, TARGET_REPO, 0, "", "")); _mockTargetGithubApi.Setup(x => x.DoesOrgExist(TARGET_ORG).Result).Returns(true); - _mockSourceGithubApi.Setup(x => x.StartGitArchiveGeneration(SOURCE_ORG, SOURCE_REPO).Result).Returns(gitArchiveId); - _mockSourceGithubApi.Setup(x => x.StartMetadataArchiveGeneration(SOURCE_ORG, SOURCE_REPO, false, false).Result).Returns(metadataArchiveId); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, gitArchiveId).Result).Returns(ArchiveMigrationStatus.Exported); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, metadataArchiveId).Result).Returns(ArchiveMigrationStatus.Exported); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, gitArchiveId).Result).Returns(gitArchiveUrl); - _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, metadataArchiveId).Result).Returns(metadataArchiveUrl); + _mockSourceGithubApi.Setup(x => x.StartGitArchiveGeneration(SOURCE_ORG, SOURCE_REPO).Result).Returns(GIT_ARCHIVE_ID); + _mockSourceGithubApi.Setup(x => x.StartMetadataArchiveGeneration(SOURCE_ORG, SOURCE_REPO, false, false).Result).Returns(METADATA_ARCHIVE_ID); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, GIT_ARCHIVE_ID).Result).Returns(ArchiveMigrationStatus.Exported); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationStatus(SOURCE_ORG, METADATA_ARCHIVE_ID).Result).Returns(ArchiveMigrationStatus.Exported); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, GIT_ARCHIVE_ID).Result).Returns(GIT_ARCHIVE_URL); + _mockSourceGithubApi.Setup(x => x.GetArchiveMigrationUrl(SOURCE_ORG, METADATA_ARCHIVE_ID).Result).Returns(METADATA_ARCHIVE_URL); - _mockAzureApi.SetupSequence(x => x.UploadToBlob(It.IsAny(), It.IsAny()).Result).Returns(authenticatedGitArchiveUrl).Returns(authenticatedMetadataArchiveUrl); + _mockAzureApi + .SetupSequence(x => x.UploadToBlob(It.IsAny(), It.IsAny()).Result) + .Returns(new Uri(AUTHENTICATED_GIT_ARCHIVE_URL)) + .Returns(new Uri(AUTHENTICATED_METADATA_ARCHIVE_URL)); _mockFileSystemProvider .SetupSequence(m => m.GetTempFileName()) - .Returns(gitArchiveFilePath) - .Returns(metadataArchiveFilePath); + .Returns(GIT_ARCHIVE_FILE_PATH) + .Returns(METADATA_ARCHIVE_FILE_PATH); - _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(sourceGithubPat); - _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(targetGithubPat); + _mockEnvironmentVariableProvider.Setup(m => m.SourceGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_SOURCE_PAT); + _mockEnvironmentVariableProvider.Setup(m => m.TargetGithubPersonalAccessToken(It.IsAny())).Returns(GITHUB_TARGET_PAT); _mockGhesVersionChecker.Setup(m => m.AreBlobCredentialsRequired(GHES_API_URL)).ReturnsAsync(true); @@ -1658,8 +1566,8 @@ public async Task Keep_Archive_Does_Not_Call_DeleteIfExists() }; await _handler.Handle(args); - _mockFileSystemProvider.Verify(x => x.DeleteIfExists(gitArchiveFilePath), Times.Never); - _mockFileSystemProvider.Verify(x => x.DeleteIfExists(metadataArchiveFilePath), Times.Never); + _mockFileSystemProvider.Verify(x => x.DeleteIfExists(GIT_ARCHIVE_FILE_PATH), Times.Never); + _mockFileSystemProvider.Verify(x => x.DeleteIfExists(METADATA_ARCHIVE_FILE_PATH), Times.Never); } [Fact] From c6d693a69f35d545ddc89d18734e5b4655553ee5 Mon Sep 17 00:00:00 2001 From: Jared Fine Date: Thu, 21 Nov 2024 17:50:46 +0000 Subject: [PATCH 13/13] Add release notes for the local archive migration support --- RELEASENOTES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 8b1378917..a3289459e 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -1 +1 @@ - +- Adds `--git-archive-path` and `--metadata-archive-path` options to `gh gei migrate-repo` for uploading (to selected storage) and migrating