Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
23 changes: 10 additions & 13 deletions azure-pipelines.yml
Original file line number Diff line number Diff line change
Expand Up @@ -156,10 +156,9 @@ stages:
-ci
-restore
-test
-projects $(Build.SourcesDirectory)\tests\UnitTests.XHarness.Android.Device.proj
/bl:$(Build.SourcesDirectory)\artifacts\log\$(_BuildConfig)\Helix.XHarness.Android.Device.binlog
-projects $(Build.SourcesDirectory)\tests\XHarness.Android.DeviceTests.proj
/bl:$(Build.SourcesDirectory)\artifacts\log\$(_BuildConfig)\Helix.XHarness.Android.Device.Tests.binlog
/p:RestoreUsingNuGetTargets=false
/p:XHarnessTestARM64_V8A=true
displayName: XHarness Android Helix Testing (Windows)
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
Expand Down Expand Up @@ -198,10 +197,10 @@ stages:
-ci
-restore
-test
-projects $(Build.SourcesDirectory)/tests/UnitTests.XHarness.iOS.Simulator.proj
/bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/UnitTests.XHarness.iOS.Simulator.binlog
-projects $(Build.SourcesDirectory)/tests/XHarness.Apple.SimulatorTests.proj
/bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/XHarness.Apple.Simulator.Tests.binlog
/p:RestoreUsingNuGetTargets=false
displayName: XHarness iOS Simulator Helix Testing
displayName: XHarness Apple Simulator Helix Testing
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
HelixAccessToken: ''
Expand All @@ -211,10 +210,10 @@ stages:
-ci
-restore
-test
-projects $(Build.SourcesDirectory)/tests/UnitTests.XHarness.iOS.Device.proj
/bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/Helix.XHarness.iOS.Device.binlog
-projects $(Build.SourcesDirectory)/tests/XHarness.Apple.DeviceTests.proj
/bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/Helix.XHarness.Apple.Device.Tests.binlog
/p:RestoreUsingNuGetTargets=false
displayName: XHarness iOS Device Helix Testing
displayName: XHarness Apple Device Helix Testing
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
HelixAccessToken: ''
Expand All @@ -224,11 +223,9 @@ stages:
-ci
-restore
-test
-projects $(Build.SourcesDirectory)/tests/UnitTests.XHarness.Android.Simulator.proj
/bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/Helix.XHarness.Android.Simulator.binlog
-projects $(Build.SourcesDirectory)/tests/XHarness.Android.SimulatorTests.proj
/bl:$(Build.SourcesDirectory)/artifacts/log/$(_BuildConfig)/Helix.XHarness.Android.Simulator.Tests.binlog
/p:RestoreUsingNuGetTargets=false
/p:XHarnessTestX86=true
/p:XHarnessTestX86_64=true
displayName: XHarness Android Helix Testing (Linux)
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
Expand Down
4 changes: 3 additions & 1 deletion src/Common/Microsoft.Arcade.Common/FileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ public void WriteToFile(string path, string content)
File.WriteAllText(path, content);
}

public void FileCopy(string sourceFileName, string destFileName) => File.Copy(sourceFileName, destFileName);
public void CopyFile(string sourceFileName, string destFileName, bool overwrite = false) => File.Copy(sourceFileName, destFileName, overwrite);

public Stream GetFileStream(string path, FileMode mode, FileAccess access) => new FileStream(path, mode, access);

public FileAttributes GetAttributes(string path) => File.GetAttributes(path);
}
}
6 changes: 4 additions & 2 deletions src/Common/Microsoft.Arcade.Common/IFileSystem.cs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable enable
using System.IO;

#nullable enable
namespace Microsoft.Arcade.Common
{
public interface IFileSystem
Expand All @@ -28,8 +28,10 @@ public interface IFileSystem

void DeleteFile(string path);

void FileCopy(string sourceFileName, string destFileName);
void CopyFile(string sourceFileName, string destFileName, bool overwrite = false);

Stream GetFileStream(string path, FileMode mode, FileAccess access);

FileAttributes GetAttributes(string path);
}
}
8 changes: 8 additions & 0 deletions src/Common/Microsoft.Arcade.Common/IZipArchiveManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,20 @@
// The .NET Foundation licenses this file to you under the MIT license.

using System.IO;
using System.IO.Compression;
using System.Threading.Tasks;

namespace Microsoft.Arcade.Common
{
public interface IZipArchiveManager
{
/// <summary>
/// Opens a given archive.
/// </summary>
/// <param name="archivePath">Path to the zip archive</param>
/// <param name="mode">Access mode</param>
ZipArchive OpenArchive(string archivePath, ZipArchiveMode mode);

/// <summary>
/// Loads an embedded resource and adds it to a target archive.
/// </summary>
Expand Down
7 changes: 5 additions & 2 deletions src/Common/Microsoft.Arcade.Common/ZipArchiveManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ namespace Microsoft.Arcade.Common
{
public class ZipArchiveManager : IZipArchiveManager
{
public ZipArchive OpenArchive(string archivePath, ZipArchiveMode mode)
=> ZipFile.Open(archivePath, mode);

public async Task AddResourceFileToArchive<TAssembly>(string archivePath, string resourceName, string targetFileName = null)
{
using Stream fileStream = GetResourceFileContent<TAssembly>(resourceName);
Expand All @@ -28,7 +31,7 @@ public void ArchiveFile(string filePath, string archivePath)

using FileStream fs = File.OpenWrite(archivePath);
using ZipArchive zip = new(fs, archiveExists ? ZipArchiveMode.Update : ZipArchiveMode.Create, false);

// Overwrite previous file, if any (otherwise dual records were created)
if (archiveExists)
{
Expand All @@ -54,7 +57,7 @@ public async Task AddContentToArchive(string archivePath, string targetFilename,
await content.CopyToAsync(targetStream);
}

private static Stream GetResourceFileContent<TAssembly>(string resourceFileName)
public static Stream GetResourceFileContent<TAssembly>(string resourceFileName)
{
Assembly assembly = typeof(TAssembly).Assembly;
return assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{resourceFileName}");
Expand Down
18 changes: 15 additions & 3 deletions src/Common/Microsoft.Arcade.Test.Common/MockFileSystem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ public class MockFileSystem : IFileSystem
{
#region File system state

public HashSet<string> Directories { get; }
public HashSet<string> Directories { get; }

public Dictionary<string, string> Files { get; }

public List<string> RemovedFiles { get; } = new();
Expand Down Expand Up @@ -54,11 +54,23 @@ public void DeleteFile(string path)

public void WriteToFile(string path, string content) => Files[path] = content;

public void FileCopy(string sourceFileName, string destFileName) => Files[destFileName] = Files[sourceFileName];
public void CopyFile(string sourceFileName, string destFileName, bool overwrite = false) => Files[destFileName] = Files[sourceFileName];

public Stream GetFileStream(string path, FileMode mode, FileAccess access)
=> FileExists(path) ? new MemoryStream() : new MockFileStream(this, path);

public FileAttributes GetAttributes(string path)
{
var attributes = FileAttributes.Normal;

if (Directories.Contains(path))
{
attributes |= FileAttributes.Directory;
}

return attributes;
}

#endregion

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public CreateXHarnessAndroidWorkItemsTests()
});

_task = new CreateXHarnessAndroidWorkItems()
{
{
BuildEngine = new MockBuildEngine(),
};
}
Expand Down Expand Up @@ -76,7 +76,7 @@ public void AndroidXHarnessWorkItemIsCreated()

var workItem = _task.WorkItems.First();
workItem.GetMetadata("Identity").Should().Be("System.Foo");
workItem.GetMetadata("Timeout").Should().Be("00:15:42");
workItem.GetMetadata("Timeout").Should().Be("00:16:02");

var payloadArchive = workItem.GetMetadata("PayloadArchive");
payloadArchive.Should().NotBeNullOrEmpty();
Expand All @@ -88,9 +88,9 @@ public void AndroidXHarnessWorkItemIsCreated()
_zipArchiveManager
.Verify(x => x.ArchiveFile("/apks/System.Foo.apk", payloadArchive), Times.Once);
_zipArchiveManager
.Verify(x => x.AddResourceFileToArchive<CreateXHarnessAndroidWorkItems>(payloadArchive, It.Is<string>(s => s.Contains("xharness-helix-job.android.sh")), "xharness-helix-job.android.sh"), Times.AtLeastOnce);
.Verify(x => x.AddResourceFileToArchive<XHarnessTaskBase>(payloadArchive, It.Is<string>(s => s.Contains("xharness-helix-job.android.sh")), "xharness-helix-job.android.sh"), Times.AtLeastOnce);
_zipArchiveManager
.Verify(x => x.AddResourceFileToArchive<CreateXHarnessAndroidWorkItems>(payloadArchive, It.Is<string>(s => s.Contains("xharness-helix-job.android.ps1")), "xharness-helix-job.android.ps1"), Times.AtLeastOnce);
.Verify(x => x.AddResourceFileToArchive<XHarnessTaskBase>(payloadArchive, It.Is<string>(s => s.Contains("xharness-helix-job.android.ps1")), "xharness-helix-job.android.ps1"), Times.AtLeastOnce);
}

[Fact]
Expand All @@ -104,7 +104,7 @@ public void ArchivePayloadIsOverwritten()
CreateApk("apks/System.Bar.apk", "System.Bar"),
};

_fileSystem.Files.Add("apks/xharness-apk-payload-system.foo.zip", "archive");
_fileSystem.Files.Add("apks/xharness-payload-system.foo.zip", "archive");

// Act
using var provider = collection.BuildServiceProvider();
Expand All @@ -115,7 +115,7 @@ public void ArchivePayloadIsOverwritten()

var workItem = _task.WorkItems.Last();
workItem.GetMetadata("Identity").Should().Be("System.Bar");

workItem = _task.WorkItems.First();
workItem.GetMetadata("Identity").Should().Be("System.Foo");

Expand Down Expand Up @@ -178,7 +178,7 @@ public void ZippedApkIsProvided()

var workItem = _task.WorkItems.First();
workItem.GetMetadata("Identity").Should().Be("System.Foo");
workItem.GetMetadata("Timeout").Should().Be("00:15:42");
workItem.GetMetadata("Timeout").Should().Be("00:16:02");

var payloadArchive = workItem.GetMetadata("PayloadArchive");
payloadArchive.Should().NotBeNullOrEmpty();
Expand All @@ -190,9 +190,9 @@ public void ZippedApkIsProvided()
_zipArchiveManager
.Verify(x => x.ArchiveFile(It.IsAny<string>(), It.IsAny<string>()), Times.Never);
_zipArchiveManager
.Verify(x => x.AddResourceFileToArchive<CreateXHarnessAndroidWorkItems>(payloadArchive, It.Is<string>(s => s.Contains("xharness-helix-job.android.sh")), "xharness-helix-job.android.sh"), Times.AtLeastOnce);
.Verify(x => x.AddResourceFileToArchive<XHarnessTaskBase>(payloadArchive, It.Is<string>(s => s.Contains("xharness-helix-job.android.sh")), "xharness-helix-job.android.sh"), Times.AtLeastOnce);
_zipArchiveManager
.Verify(x => x.AddResourceFileToArchive<CreateXHarnessAndroidWorkItems>(payloadArchive, It.Is<string>(s => s.Contains("xharness-helix-job.android.ps1")), "xharness-helix-job.android.ps1"), Times.AtLeastOnce);
.Verify(x => x.AddResourceFileToArchive<XHarnessTaskBase>(payloadArchive, It.Is<string>(s => s.Contains("xharness-helix-job.android.ps1")), "xharness-helix-job.android.ps1"), Times.AtLeastOnce);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ public void AppleXHarnessWorkItemIsCreated()

var workItem = _task.WorkItems.First();
workItem.GetMetadata("Identity").Should().Be("System.Foo");
workItem.GetMetadata("Timeout").Should().Be("00:15:42");
workItem.GetMetadata("Timeout").Should().Be("00:16:02");

var payloadArchive = workItem.GetMetadata("PayloadArchive");
payloadArchive.Should().NotBeNullOrEmpty();
Expand All @@ -92,13 +92,13 @@ public void AppleXHarnessWorkItemIsCreated()
command.Should().Contain("--launch-timeout \"00:02:33\"");

_profileProvider
.Verify(x => x.AddProfilesToBundles(It.Is<ITaskItem[]>(bundles => bundles.Any(b => b.ItemSpec == "/apps/System.Foo.app"))), Times.Once);
.Verify(x => x.AddProfileToPayload(payloadArchive, "ios-device_13.5"), Times.Once);
_zipArchiveManager
.Verify(x => x.ArchiveDirectory("/apps/System.Foo.app", payloadArchive, true), Times.Once);
_zipArchiveManager
.Verify(x => x.AddResourceFileToArchive<CreateXHarnessAppleWorkItems>(payloadArchive, It.Is<string>(s => s.Contains("xharness-helix-job.apple.sh")), "xharness-helix-job.apple.sh"), Times.Once);
.Verify(x => x.AddResourceFileToArchive<XHarnessTaskBase>(payloadArchive, It.Is<string>(s => s.Contains("xharness-helix-job.apple.sh")), "xharness-helix-job.apple.sh"), Times.Once);
_zipArchiveManager
.Verify(x => x.AddResourceFileToArchive<CreateXHarnessAppleWorkItems>(payloadArchive, It.Is<string>(s => s.Contains("xharness-runner.apple.sh")), "xharness-runner.apple.sh"), Times.Once);
.Verify(x => x.AddResourceFileToArchive<XHarnessTaskBase>(payloadArchive, It.Is<string>(s => s.Contains("xharness-runner.apple.sh")), "xharness-runner.apple.sh"), Times.Once);
_zipArchiveManager
.Verify(x => x.AddContentToArchive(payloadArchive, "command.sh", It.Is<string>(s => s.Contains("xharness apple test"))), Times.Once);
}
Expand All @@ -114,7 +114,7 @@ public void ArchivePayloadIsOverwritten()
CreateAppBundle("apps/System.Bar.app", "ios-simulator-64_13.5"),
};

_fileSystem.Files.Add("apps/xharness-app-payload-system.foo.zip", "archive");
_fileSystem.Files.Add("apps/xharness-payload-system.foo.zip", "archive");

// Act
using var provider = collection.BuildServiceProvider();
Expand All @@ -133,6 +133,9 @@ public void ArchivePayloadIsOverwritten()
payloadArchive.Should().NotBeNullOrEmpty();
_fileSystem.FileExists(payloadArchive).Should().BeTrue();
_fileSystem.RemovedFiles.Should().Contain(payloadArchive);

var command = workItem.GetMetadata("Command");
command.Should().Contain("--launch-timeout \"00:03:00\"");
}

[Fact]
Expand Down Expand Up @@ -170,7 +173,7 @@ public void AppBundleIsReused()
_task.ConfigureServices(collection);
_task.AppBundles = new[]
{
CreateAppBundle("item-1", "ios-simulator-64_13.5", appBundlePath: "apps/System.Foo.app"),
CreateAppBundle("item-1", "ios-device_13.5", appBundlePath: "apps/System.Foo.app"),
CreateAppBundle("item-2", "ios-simulator-64_13.6", appBundlePath: "apps/System.Foo.app"),
};

Expand All @@ -182,25 +185,27 @@ public void AppBundleIsReused()
_task.WorkItems.Length.Should().Be(2);
_fileSystem.RemovedFiles.Should().BeEmpty();

var workItem1 = _task.WorkItems.Last();
workItem1.GetMetadata("Identity").Should().Be("item-2");
var workItem1 = _task.WorkItems.First();
workItem1.GetMetadata("Identity").Should().Be("item-1");

var payloadArchive = workItem1.GetMetadata("PayloadArchive");
payloadArchive.Should().NotBeNullOrEmpty();
_fileSystem.FileExists(payloadArchive).Should().BeTrue();

var command = workItem1.GetMetadata("Command");
command.Should().Contain("--target \"ios-simulator-64_13.6\"");
command.Should().Contain("--target \"ios-device_13.5\"");
command.Should().Contain("--launch-timeout \"00:05:00\"");

var workItem2 = _task.WorkItems.First();
workItem2.GetMetadata("Identity").Should().Be("item-1");
var workItem2 = _task.WorkItems.Last();
workItem2.GetMetadata("Identity").Should().Be("item-2");

payloadArchive = workItem2.GetMetadata("PayloadArchive");
payloadArchive.Should().NotBeNullOrEmpty();
_fileSystem.FileExists(payloadArchive).Should().BeTrue();

command = workItem2.GetMetadata("Command");
command.Should().Contain("--target \"ios-simulator-64_13.5\"");
command.Should().Contain("--target \"ios-simulator-64_13.6\"");
command.Should().Contain("--launch-timeout \"00:03:00\"");
}

[Fact]
Expand All @@ -225,7 +230,7 @@ public void ZippedAppIsProvided()

var workItem = _task.WorkItems.First();
workItem.GetMetadata("Identity").Should().Be("System.Foo");
workItem.GetMetadata("Timeout").Should().Be("00:15:42");
workItem.GetMetadata("Timeout").Should().Be("00:16:02");

var payloadArchive = workItem.GetMetadata("PayloadArchive");
payloadArchive.Should().NotBeNullOrEmpty();
Expand All @@ -238,13 +243,13 @@ public void ZippedAppIsProvided()
command.Should().Contain("--launch-timeout \"00:02:33\"");

_profileProvider
.Verify(x => x.AddProfilesToBundles(It.Is<ITaskItem[]>(bundles => bundles.Any(b => b.ItemSpec == "/apps/System.Foo.zip"))), Times.Once);
.Verify(x => x.AddProfileToPayload(payloadArchive, "ios-device_13.5"), Times.Once);
_zipArchiveManager
.Verify(x => x.ArchiveDirectory("/apps/System.Foo.app", payloadArchive, true), Times.Never);
_zipArchiveManager
.Verify(x => x.AddResourceFileToArchive<CreateXHarnessAppleWorkItems>(payloadArchive, It.Is<string>(s => s.Contains("xharness-helix-job.apple.sh")), "xharness-helix-job.apple.sh"), Times.Once);
.Verify(x => x.AddResourceFileToArchive<XHarnessTaskBase>(payloadArchive, It.Is<string>(s => s.Contains("xharness-helix-job.apple.sh")), "xharness-helix-job.apple.sh"), Times.Once);
_zipArchiveManager
.Verify(x => x.AddResourceFileToArchive<CreateXHarnessAppleWorkItems>(payloadArchive, It.Is<string>(s => s.Contains("xharness-runner.apple.sh")), "xharness-runner.apple.sh"), Times.Once);
.Verify(x => x.AddResourceFileToArchive<XHarnessTaskBase>(payloadArchive, It.Is<string>(s => s.Contains("xharness-runner.apple.sh")), "xharness-runner.apple.sh"), Times.Once);
_zipArchiveManager
.Verify(x => x.AddContentToArchive(payloadArchive, "command.sh", It.Is<string>(s => s.Contains("xharness apple test"))), Times.Once);
}
Expand Down
Loading