Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

manage C#-only experiments with ExperimentsManager #10868

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using System.IO;
using System.Text;

using NuGetUpdater.Core;
Expand All @@ -18,6 +19,8 @@ public async Task WithSolution()
await Run(path =>
[
"update",
"--job-path",
Path.Combine(path, "job.json"),
"--repo-root",
path,
"--solution-or-project",
Expand Down Expand Up @@ -119,6 +122,8 @@ public async Task WithProject()
await Run(path =>
[
"update",
"--job-path",
Path.Combine(path, "job.json"),
"--repo-root",
path,
"--solution-or-project",
Expand Down Expand Up @@ -197,6 +202,8 @@ public async Task WithDirsProjAndDirectoryBuildPropsThatIsOutOfDirectoryButStill
await Run(path =>
[
"update",
"--job-path",
Path.Combine(path, "job.json"),
"--repo-root",
path,
"--solution-or-project",
Expand Down Expand Up @@ -325,6 +332,7 @@ public async Task UpdaterDoesNotUseRepoGlobalJsonForMSBuildTasks(string? working
MockNuGetPackage.CreateSimplePackage("Some.Package", "13.0.1", "net8.0"),
];
await MockNuGetPackagesInDirectory(testPackages, tempDir.DirectoryPath);
await MockJobFileInDirectory(tempDir.DirectoryPath);

var globalJsonPath = Path.Join(tempDir.DirectoryPath, "global.json");
var srcGlobalJsonPath = Path.Join(tempDir.DirectoryPath, "src", "global.json");
Expand Down Expand Up @@ -353,6 +361,8 @@ await File.WriteAllTextAsync(projectPath, """
IEnumerable<string> executableArgs = [
executableName,
"update",
"--job-path",
Path.Combine(tempDir.DirectoryPath, "job.json"),
"--repo-root",
tempDir.DirectoryPath,
"--solution-or-project",
Expand Down Expand Up @@ -402,6 +412,7 @@ private static async Task Run(Func<string, string[]> getArgs, (string Path, stri

try
{
await MockJobFileInDirectory(path);
await MockNuGetPackagesInDirectory(packages, path);

var args = getArgs(path);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace NuGetUpdater.Cli.Commands;

internal static class UpdateCommand
{
internal static readonly Option<FileInfo> JobPathOption = new("--job-path") { IsRequired = true };
internal static readonly Option<DirectoryInfo> RepoRootOption = new("--repo-root", () => new DirectoryInfo(Environment.CurrentDirectory)) { IsRequired = false };
internal static readonly Option<FileInfo> SolutionOrProjectFileOption = new("--solution-or-project") { IsRequired = true };
internal static readonly Option<string> DependencyNameOption = new("--dependency") { IsRequired = true };
Expand All @@ -18,6 +19,7 @@ internal static Command GetCommand(Action<int> setExitCode)
{
Command command = new("update", "Applies the changes from an analysis report to update a dependency.")
{
JobPathOption,
RepoRootOption,
SolutionOrProjectFileOption,
DependencyNameOption,
Expand All @@ -29,12 +31,13 @@ internal static Command GetCommand(Action<int> setExitCode)

command.TreatUnmatchedTokensAsErrors = true;

command.SetHandler(async (repoRoot, solutionOrProjectFile, dependencyName, newVersion, previousVersion, isTransitive, resultOutputPath) =>
command.SetHandler(async (jobPath, repoRoot, solutionOrProjectFile, dependencyName, newVersion, previousVersion, isTransitive, resultOutputPath) =>
{
var worker = new UpdaterWorker(new ConsoleLogger());
var experimentsManager = await ExperimentsManager.FromJobFileAsync(jobPath.FullName);
var worker = new UpdaterWorker(experimentsManager, new ConsoleLogger());
await worker.RunAsync(repoRoot.FullName, solutionOrProjectFile.FullName, dependencyName, previousVersion, newVersion, isTransitive, resultOutputPath);
setExitCode(0);
}, RepoRootOption, SolutionOrProjectFileOption, DependencyNameOption, NewVersionOption, PreviousVersionOption, IsTransitiveOption, ResultOutputPathOption);
}, JobPathOption, RepoRootOption, SolutionOrProjectFileOption, DependencyNameOption, NewVersionOption, PreviousVersionOption, IsTransitiveOption, ResultOutputPathOption);

return command;
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,92 @@ public void DeserializeJob()
Assert.Equal("specific-sdk", jobWrapper.Job.Source.Directory);
}

[Fact]
public void DeserializeExperimentsManager()
{
var jobWrapper = RunWorker.Deserialize("""
{
"job": {
"package-manager": "nuget",
"allowed-updates": [
{
"update-type": "all"
}
],
"source": {
"provider": "github",
"repo": "some-org/some-repo",
"directory": "some-dir"
},
"experiments": {
"nuget_legacy_dependency_solver": true,
"unexpected_bool": true,
"unexpected_number": 42,
"unexpected_null": null,
"unexpected_string": "abc",
"unexpected_array": [1, "two", 3.0],
"unexpected_object": {
"a": 1,
"b": "two"
}
}
}
}
""");
var experimentsManager = ExperimentsManager.GetExperimentsManager(jobWrapper.Job.Experiments);
Assert.True(experimentsManager.UseLegacyDependencySolver);
}

[Fact]
public void DeserializeExperimentsManager_EmptyExperiments()
{
var jobWrapper = RunWorker.Deserialize("""
{
"job": {
"package-manager": "nuget",
"allowed-updates": [
{
"update-type": "all"
}
],
"source": {
"provider": "github",
"repo": "some-org/some-repo",
"directory": "some-dir"
},
"experiments": {
}
}
}
""");
var experimentsManager = ExperimentsManager.GetExperimentsManager(jobWrapper.Job.Experiments);
Assert.False(experimentsManager.UseLegacyDependencySolver);
}

[Fact]
public void DeserializeExperimentsManager_NoExperiments()
{
var jobWrapper = RunWorker.Deserialize("""
{
"job": {
"package-manager": "nuget",
"allowed-updates": [
{
"update-type": "all"
}
],
"source": {
"provider": "github",
"repo": "some-org/some-repo",
"directory": "some-dir"
}
}
}
""");
var experimentsManager = ExperimentsManager.GetExperimentsManager(jobWrapper.Job.Experiments);
Assert.False(experimentsManager.UseLegacyDependencySolver);
}

[Fact]
public void SerializeError()
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
using System.Text.Json;

using NuGetUpdater.Core.Run;
using NuGetUpdater.Core.Run.ApiModel;
using NuGetUpdater.Core.Test.Updater;
using NuGetUpdater.Core.Updater;

Expand All @@ -19,11 +23,12 @@ protected static Task TestNoChange(
bool isTransitive = false,
TestFile[]? additionalFiles = null,
MockNuGetPackage[]? packages = null,
ExperimentsManager? experimentsManager = null,
string projectFilePath = "test-project.csproj")
{
return useSolution
? TestNoChangeforSolution(dependencyName, oldVersion, newVersion, projectFiles: [(projectFilePath, projectContents)], isTransitive, additionalFiles, packages)
: TestNoChangeforProject(dependencyName, oldVersion, newVersion, projectContents, isTransitive, additionalFiles, packages, projectFilePath);
? TestNoChangeforSolution(dependencyName, oldVersion, newVersion, projectFiles: [(projectFilePath, projectContents)], isTransitive, additionalFiles, packages, experimentsManager)
: TestNoChangeforProject(dependencyName, oldVersion, newVersion, projectContents, isTransitive, additionalFiles, packages, experimentsManager, projectFilePath);
}

protected static Task TestUpdate(
Expand All @@ -37,11 +42,12 @@ protected static Task TestUpdate(
TestFile[]? additionalFiles = null,
TestFile[]? additionalFilesExpected = null,
MockNuGetPackage[]? packages = null,
ExperimentsManager? experimentsManager = null,
string projectFilePath = "test-project.csproj")
{
return useSolution
? TestUpdateForSolution(dependencyName, oldVersion, newVersion, projectFiles: [(projectFilePath, projectContents)], projectFilesExpected: [(projectFilePath, expectedProjectContents)], isTransitive, additionalFiles, additionalFilesExpected, packages)
: TestUpdateForProject(dependencyName, oldVersion, newVersion, projectFile: (projectFilePath, projectContents), expectedProjectContents, isTransitive, additionalFiles, additionalFilesExpected, packages);
? TestUpdateForSolution(dependencyName, oldVersion, newVersion, projectFiles: [(projectFilePath, projectContents)], projectFilesExpected: [(projectFilePath, expectedProjectContents)], isTransitive, additionalFiles, additionalFilesExpected, packages, experimentsManager)
: TestUpdateForProject(dependencyName, oldVersion, newVersion, projectFile: (projectFilePath, projectContents), expectedProjectContents, isTransitive, additionalFiles, additionalFilesExpected, packages, experimentsManager);
}

protected static Task TestUpdate(
Expand All @@ -54,11 +60,12 @@ protected static Task TestUpdate(
bool isTransitive = false,
TestFile[]? additionalFiles = null,
TestFile[]? additionalFilesExpected = null,
MockNuGetPackage[]? packages = null)
MockNuGetPackage[]? packages = null,
ExperimentsManager? experimentsManager = null)
{
return useSolution
? TestUpdateForSolution(dependencyName, oldVersion, newVersion, projectFiles: [projectFile], projectFilesExpected: [(projectFile.Path, expectedProjectContents)], isTransitive, additionalFiles, additionalFilesExpected, packages)
: TestUpdateForProject(dependencyName, oldVersion, newVersion, projectFile, expectedProjectContents, isTransitive, additionalFiles, additionalFilesExpected, packages);
? TestUpdateForSolution(dependencyName, oldVersion, newVersion, projectFiles: [projectFile], projectFilesExpected: [(projectFile.Path, expectedProjectContents)], isTransitive, additionalFiles, additionalFilesExpected, packages, experimentsManager)
: TestUpdateForProject(dependencyName, oldVersion, newVersion, projectFile, expectedProjectContents, isTransitive, additionalFiles, additionalFilesExpected, packages, experimentsManager);
}

protected static Task TestNoChangeforProject(
Expand All @@ -69,6 +76,7 @@ protected static Task TestNoChangeforProject(
bool isTransitive = false,
TestFile[]? additionalFiles = null,
MockNuGetPackage[]? packages = null,
ExperimentsManager? experimentsManager = null,
string projectFilePath = "test-project.csproj")
=> TestUpdateForProject(
dependencyName,
Expand All @@ -79,7 +87,8 @@ protected static Task TestNoChangeforProject(
isTransitive,
additionalFiles,
additionalFilesExpected: additionalFiles,
packages: packages);
packages: packages,
experimentsManager: experimentsManager);

protected static Task TestUpdateForProject(
string dependencyName,
Expand All @@ -91,6 +100,7 @@ protected static Task TestUpdateForProject(
TestFile[]? additionalFiles = null,
TestFile[]? additionalFilesExpected = null,
MockNuGetPackage[]? packages = null,
ExperimentsManager? experimentsManager = null,
string projectFilePath = "test-project.csproj",
ExpectedUpdateOperationResult? expectedResult = null)
=> TestUpdateForProject(
Expand All @@ -103,6 +113,7 @@ protected static Task TestUpdateForProject(
additionalFiles,
additionalFilesExpected,
packages,
experimentsManager,
expectedResult);

protected static async Task TestUpdateForProject(
Expand All @@ -115,6 +126,7 @@ protected static async Task TestUpdateForProject(
TestFile[]? additionalFiles = null,
TestFile[]? additionalFilesExpected = null,
MockNuGetPackage[]? packages = null,
ExperimentsManager? experimentsManager = null,
ExpectedUpdateOperationResult? expectedResult = null)
{
additionalFiles ??= [];
Expand All @@ -134,7 +146,8 @@ protected static async Task TestUpdateForProject(
await MockNuGetPackagesInDirectory(packages, temporaryDirectory);

// run update
var worker = new UpdaterWorker(new TestLogger());
experimentsManager ??= new ExperimentsManager();
var worker = new UpdaterWorker(experimentsManager, new TestLogger());
var projectPath = placeFilesInSrc ? $"src/{projectFilePath}" : projectFilePath;
var actualResult = await worker.RunWithErrorHandlingAsync(temporaryDirectory, projectPath, dependencyName, oldVersion, newVersion, isTransitive);
if (expectedResult is { })
Expand Down Expand Up @@ -172,7 +185,8 @@ protected static Task TestNoChangeforSolution(
TestFile[] projectFiles,
bool isTransitive = false,
TestFile[]? additionalFiles = null,
MockNuGetPackage[]? packages = null)
MockNuGetPackage[]? packages = null,
ExperimentsManager? experimentsManager = null)
=> TestUpdateForSolution(
dependencyName,
oldVersion,
Expand All @@ -182,7 +196,8 @@ protected static Task TestNoChangeforSolution(
isTransitive,
additionalFiles,
additionalFilesExpected: additionalFiles,
packages: packages);
packages: packages,
experimentsManager: experimentsManager);

protected static async Task TestUpdateForSolution(
string dependencyName,
Expand All @@ -193,7 +208,8 @@ protected static async Task TestUpdateForSolution(
bool isTransitive = false,
TestFile[]? additionalFiles = null,
TestFile[]? additionalFilesExpected = null,
MockNuGetPackage[]? packages = null)
MockNuGetPackage[]? packages = null,
ExperimentsManager? experimentsManager = null)
{
additionalFiles ??= [];
additionalFilesExpected ??= [];
Expand Down Expand Up @@ -236,8 +252,9 @@ protected static async Task TestUpdateForSolution(
{
await MockNuGetPackagesInDirectory(packages, temporaryDirectory);

experimentsManager ??= new ExperimentsManager();
var slnPath = Path.Combine(temporaryDirectory, slnName);
var worker = new UpdaterWorker(new TestLogger());
var worker = new UpdaterWorker(experimentsManager, new TestLogger());
await worker.RunAsync(temporaryDirectory, slnPath, dependencyName, oldVersion, newVersion, isTransitive);
});

Expand All @@ -246,6 +263,27 @@ protected static async Task TestUpdateForSolution(
AssertContainsFiles(expectedResult, actualResult);
}

public static async Task MockJobFileInDirectory(string temporaryDirectory)
{
var jobFile = new JobFile()
{
Job = new()
{
AllowedUpdates =
[
new() { UpdateType = "all" }
],
Source = new()
{
Provider = "github",
Repo = "test/repo",
Directory = "/",
}
}
};
await File.WriteAllTextAsync(Path.Join(temporaryDirectory, "job.json"), JsonSerializer.Serialize(jobFile, RunWorker.SerializerOptions));
}

public static async Task MockNuGetPackagesInDirectory(MockNuGetPackage[]? packages, string temporaryDirectory)
{
if (packages is not null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,8 @@ static async Task TestUpdateForDirsProj(
bool isTransitive = false,
(string Path, string Content)[]? additionalFiles = null,
(string Path, string Content)[]? additionalFilesExpected = null,
MockNuGetPackage[]? packages = null)
MockNuGetPackage[]? packages = null,
ExperimentsManager? experimentsManager = null)
{
additionalFiles ??= [];
additionalFilesExpected ??= [];
Expand All @@ -363,8 +364,9 @@ static async Task TestUpdateForDirsProj(
{
await MockNuGetPackagesInDirectory(packages, temporaryDirectory);

experimentsManager ??= new ExperimentsManager();
var projectPath = Path.Combine(temporaryDirectory, projectFileName);
var worker = new UpdaterWorker(new TestLogger());
var worker = new UpdaterWorker(experimentsManager, new TestLogger());
await worker.RunAsync(temporaryDirectory, projectPath, dependencyName, oldVersion, newVersion, isTransitive);
});

Expand Down
Loading
Loading