Skip to content
This repository was archived by the owner on Apr 27, 2026. It is now read-only.
Merged
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
Expand Up @@ -256,7 +256,7 @@ public class FileSystemDirectoryAccessorTests : DirectoryAccessorTests
{
public override IDirectoryAccessor CreateDirectory([CallerMemberName]string testName = null)
{
var directory = PackageUtilities.CreateDirectory(testName);
var directory = PrebuildUtilities.CreateDirectory(testName);

return new FileSystemDirectoryAccessor(directory);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,38 +15,38 @@

namespace Microsoft.DotNet.Interactive.CSharpProject.Tests;

public class PackageTests : IDisposable
public class PrebuildTests : IDisposable
{
private readonly CompositeDisposable _disposables = new();

public PackageTests(ITestOutputHelper output)
public PrebuildTests(ITestOutputHelper output)
{
_disposables.Add(output.SubscribeToPocketLogger());
}

public void Dispose() => _disposables.Dispose();

[Fact]
public async Task A_package_is_not_initialized_more_than_once()
public async Task A_prebuild_is_not_initialized_more_than_once()
{
var initializer = new TestPackageInitializer(
var initializer = new TestPrebuildInitializer(
"console",
"MyProject");

var package = PackageUtilities.CreateEmptyBuildablePackage(initializer: initializer);
var prebuild = PrebuildUtilities.CreateEmptyBuildablePrebuild(initializer: initializer);

await package.GetOrCreateWorkspaceAsync();
await package.GetOrCreateWorkspaceAsync();
await prebuild.GetOrCreateWorkspaceAsync();
await prebuild.GetOrCreateWorkspaceAsync();

initializer.InitializeCount.Should().Be(1);
}

[Fact]
public async Task Package_after_create_actions_are_not_run_more_than_once()
public async Task Prebuild_after_create_actions_are_not_run_more_than_once()
{
var afterCreateCallCount = 0;

var initializer = new PackageInitializer(
var initializer = new PrebuildInitializer(
"console",
"test",
afterCreate: async _ =>
Expand All @@ -55,22 +55,22 @@ public async Task Package_after_create_actions_are_not_run_more_than_once()
afterCreateCallCount++;
});

var package = PackageUtilities.CreateEmptyBuildablePackage(initializer: initializer);
var prebuild = PrebuildUtilities.CreateEmptyBuildablePrebuild(initializer: initializer);

await package.GetOrCreateWorkspaceAsync();
await package.GetOrCreateWorkspaceAsync();
await prebuild.GetOrCreateWorkspaceAsync();
await prebuild.GetOrCreateWorkspaceAsync();

afterCreateCallCount.Should().Be(1);
}

[Fact]
public async Task A_package_copy_is_not_reinitialized_if_the_source_was_already_initialized()
public async Task A_prebuild_copy_is_not_reinitialized_if_the_source_was_already_initialized()
{
var initializer = new TestPackageInitializer(
var initializer = new TestPrebuildInitializer(
"console",
"MyProject");

var original = PackageUtilities.CreateEmptyBuildablePackage(initializer: initializer);
var original = PrebuildUtilities.CreateEmptyBuildablePrebuild(initializer: initializer);

await original.GetOrCreateWorkspaceAsync();

Expand All @@ -82,22 +82,22 @@ public async Task A_package_copy_is_not_reinitialized_if_the_source_was_already_
}

[Fact]
public async Task When_package_contains_simple_console_app_then_entry_point_dll_is_in_the_build_directory()
public async Task When_prebuild_contains_simple_console_app_then_entry_point_dll_is_in_the_build_directory()
{
var package = PackageUtilities.CreateEmptyBuildablePackage(initializer: new PackageInitializer("console", "empty"));
var prebuild = PrebuildUtilities.CreateEmptyBuildablePrebuild(initializer: new PrebuildInitializer("console", "empty"));

await package.GetOrCreateWorkspaceAsync();
await prebuild.GetOrCreateWorkspaceAsync();

package.EntryPointAssemblyPath.Exists.Should().BeTrue();
prebuild.EntryPointAssemblyPath.Exists.Should().BeTrue();

package.EntryPointAssemblyPath
prebuild.EntryPointAssemblyPath
.FullName
.Should()
.Be(Path.Combine(
package.Directory.FullName,
prebuild.Directory.FullName,
"bin",
"Debug",
package.TargetFramework,
prebuild.TargetFramework,
"empty.dll"));
}

Expand All @@ -106,14 +106,14 @@ public async Task If_a_build_is_in_flight_then_the_second_one_will_wait_on_it_to
{
var buildEvents = new LogEntryList();
var buildEventsMessages = new List<string>();
var package = await PackageUtilities.CreateBuildableConsolePackageCopy();
var prebuild = await PrebuildUtilities.CreateBuildableConsolePrebuildCopy();
var barrier = new Barrier(2);
LogEvents.Subscribe(
e =>
{
buildEvents.Add(e);
buildEventsMessages.Add(e.Evaluate().Message);
if (e.Evaluate().Message.StartsWith("Building package "))
if (e.Evaluate().Message.StartsWith("Building prebuild "))
{
barrier.SignalAndWait(30.Seconds());
}
Expand All @@ -125,23 +125,23 @@ public async Task If_a_build_is_in_flight_then_the_second_one_will_wait_on_it_to
});

await Task.WhenAll(
Task.Run(() => package.BuildAsync()),
Task.Run(() => package.BuildAsync()));
Task.Run(() => prebuild.BuildAsync()),
Task.Run(() => prebuild.BuildAsync()));

buildEventsMessages.Should()
.Contain(e => e.StartsWith("Building package " + package.Name))
.Contain(e => e.StartsWith($"Building prebuild '{prebuild.Name}'"))
.And
.Contain(e => e.StartsWith("Skipping build for package " + package.Name));
.Contain(e => e.StartsWith($"Skipping build for prebuild '{prebuild.Name}'"));
}

[Fact]
public async Task Directory_is_created_on_demand_during_build()
{
DirectoryInfo directory = new(Path.Combine(Package.DefaultPackagesDirectory.FullName, Guid.NewGuid().ToString("N")));
DirectoryInfo directory = new(Path.Combine(Prebuild.DefaultPrebuildsDirectory.FullName, Guid.NewGuid().ToString("N")));

var package = new Package("console", enableBuild: true, directory: directory);
var prebuild = new Prebuild("console", enableBuild: true, directory: directory);

await package.BuildAsync();
await prebuild.BuildAsync();

directory.Exists.Should().BeTrue();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,99 +1,99 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
using System;
using System.IO;
using System.Reactive.Concurrency;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.DotNet.Interactive.CSharpProject.Build;
namespace Microsoft.DotNet.Interactive.CSharpProject.Tests;
public static class PackageUtilities
{
private static readonly object CreateDirectoryLock = new();
public static async Task<Package> CreateBuildableCopy(
this Package fromPackage,
string folderNameStartsWith = null,
IScheduler buildThrottleScheduler = null,
DirectoryInfo parentDirectory = null)
{
if (fromPackage is null)
{
throw new ArgumentNullException(nameof(fromPackage));
}
await fromPackage.EnsureReadyAsync();
folderNameStartsWith ??= fromPackage.Name;
parentDirectory ??= fromPackage.Directory.Parent;
var destination =
CreateDirectory(folderNameStartsWith,
parentDirectory);
fromPackage.Directory.CopyTo(destination, info =>
{
switch (info)
{
case FileInfo fileInfo:
return FileLock.IsLockFile(fileInfo) || fileInfo.Extension.EndsWith("binlog");
default:
return false;
}
});
var copy = new Package(directory: destination, name: destination.Name, enableBuild: true);
return copy;
}
public static DirectoryInfo CreateDirectory(
string folderNameStartsWith,
DirectoryInfo parentDirectory = null)
{
if (string.IsNullOrWhiteSpace(folderNameStartsWith))
{
throw new ArgumentException("Value cannot be null or whitespace.", nameof(folderNameStartsWith));
}
parentDirectory ??= Package.DefaultPackagesDirectory;
DirectoryInfo created;
lock (CreateDirectoryLock)
{
if (!parentDirectory.Exists)
{
parentDirectory.Create();
}
var existingFolders = parentDirectory.GetDirectories($"{folderNameStartsWith}.*");
created = parentDirectory.CreateSubdirectory($"{folderNameStartsWith}.{existingFolders.Length + 1}");
}
return created;
}
public static async Task<Package> CreateBuildableConsolePackageCopy(
[CallerMemberName] string testName = null,
IScheduler buildThrottleScheduler = null)
{
var consolePackage = await Package.GetOrCreateConsolePackageAsync(true);
return await consolePackage.CreateBuildableCopy(testName, buildThrottleScheduler);
}
public static Package CreateEmptyBuildablePackage(
[CallerMemberName] string testName = null,
IPackageInitializer initializer = null)
{
return new Package(
name: testName,
directory: CreateDirectory(testName),
initializer: initializer,
enableBuild: true);
}
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.IO;
using System.Reactive.Concurrency;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using Microsoft.DotNet.Interactive.CSharpProject.Build;

namespace Microsoft.DotNet.Interactive.CSharpProject.Tests;

public static class PrebuildUtilities
{
private static readonly object CreateDirectoryLock = new();

public static async Task<Prebuild> CreateBuildableCopy(
this Prebuild fromPrebuild,
string folderNameStartsWith = null,
IScheduler buildThrottleScheduler = null,
DirectoryInfo parentDirectory = null)
{
if (fromPrebuild is null)
{
throw new ArgumentNullException(nameof(fromPrebuild));
}

await fromPrebuild.EnsureReadyAsync();

folderNameStartsWith ??= fromPrebuild.Name;
parentDirectory ??= fromPrebuild.Directory.Parent;

var destination =
CreateDirectory(folderNameStartsWith,
parentDirectory);

fromPrebuild.Directory.CopyTo(destination, info =>
{
switch (info)
{
case FileInfo fileInfo:
return FileLock.IsLockFile(fileInfo) || fileInfo.Extension.EndsWith("binlog");
default:
return false;
}
});

var copy = new Prebuild(directory: destination, name: destination.Name, enableBuild: true);

return copy;
}

public static DirectoryInfo CreateDirectory(
string folderNameStartsWith,
DirectoryInfo parentDirectory = null)
{
if (string.IsNullOrWhiteSpace(folderNameStartsWith))
{
throw new ArgumentException("Value cannot be null or whitespace.", nameof(folderNameStartsWith));
}

parentDirectory ??= Prebuild.DefaultPrebuildsDirectory;

DirectoryInfo created;

lock (CreateDirectoryLock)
{
if (!parentDirectory.Exists)
{
parentDirectory.Create();
}

var existingFolders = parentDirectory.GetDirectories($"{folderNameStartsWith}.*");

created = parentDirectory.CreateSubdirectory($"{folderNameStartsWith}.{existingFolders.Length + 1}");
}

return created;
}

public static async Task<Prebuild> CreateBuildableConsolePrebuildCopy(
[CallerMemberName] string testName = null,
IScheduler buildThrottleScheduler = null)
{
var prebuild = await Prebuild.GetOrCreateConsolePrebuildAsync(true);
return await prebuild.CreateBuildableCopy(testName, buildThrottleScheduler);
}

public static Prebuild CreateEmptyBuildablePrebuild(
[CallerMemberName] string testName = null,
IPrebuildInitializer initializer = null)
{
return new Prebuild(
name: testName,
directory: CreateDirectory(testName),
initializer: initializer,
enableBuild: true);
}
}
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -689,8 +689,8 @@ public static IEnumerable<int> Fibonacci()
#endregion

var (processed, position) = CodeManipulation.ProcessMarkup(generator);
var package = await PackageUtilities.CreateBuildableCopy(await Package.GetOrCreateConsolePackageAsync(false));
var workspace = new Workspace(workspaceType: package.Name, buffers: new[]
var prebuild = await PrebuildUtilities.CreateBuildableCopy(await Prebuild.GetOrCreateConsolePrebuildAsync(false));
var workspace = new Workspace(workspaceType: prebuild.Name, buffers: new[]
{
new Buffer("Program.cs", program),
new Buffer("generators/FibonacciGenerator.cs", processed, position)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ protected RoslynWorkspaceServerTestsCore(ITestOutputHelper output) : base(output
{
}

protected override ILanguageService GetLanguageService() => new RoslynWorkspaceServer(PackageFinder.Create(() => Package.GetOrCreateConsolePackageAsync(false)));
protected override ILanguageService GetLanguageService() => new RoslynWorkspaceServer(PrebuildFinder.Create(() => Prebuild.GetOrCreateConsolePrebuildAsync(false)));

protected override ICodeCompiler GetCodeCompiler() => new RoslynWorkspaceServer(PackageFinder.Create(() => Package.GetOrCreateConsolePackageAsync(false)));
protected override ICodeCompiler GetCodeCompiler() => new RoslynWorkspaceServer(PrebuildFinder.Create(() => Prebuild.GetOrCreateConsolePrebuildAsync(false)));

protected override ICodeRunner GetCodeRunner() => new RoslynWorkspaceServer(PackageFinder.Create(() => Package.GetOrCreateConsolePackageAsync(false)));
protected override ICodeRunner GetCodeRunner() => new RoslynWorkspaceServer(PrebuildFinder.Create(() => Prebuild.GetOrCreateConsolePrebuildAsync(false)));
}
Loading