diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index ab514ed1c3..f1151e7c7b 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -62,12 +62,6 @@ jobs:
arguments: '-TargetFile binver\binver\version.h -BuildVersion $(BuildVer)'
workingDirectory: 'src'
- - task: DownloadSecureFile@1
- name: signingCert
- displayName: 'Download signing certificate'
- inputs:
- secureFile: 'AppInstallerTest.pfx'
-
- task: VSBuild@1
displayName: Build Solution
inputs:
@@ -77,10 +71,7 @@ jobs:
msbuildArgs: '/p:AppxBundlePlatforms="$(buildPlatform)"
/p:AppxPackageDir="$(appxPackageDir)"
/p:AppxBundle=Always
- /p:UapAppxPackageBuildMode=StoreUpload
- /p:AppxPackageSigningEnabled=true
- /p:PackageCertificateThumbprint=""
- /p:PackageCertificateKeyFile="$(signingCert.secureFilePath)"'
+ /p:UapAppxPackageBuildMode=StoreUpload'
- task: CmdLine@2
displayName: Run Unit Tests Unpackaged
@@ -155,7 +146,8 @@ jobs:
testSelector: 'testAssemblies'
testAssemblyVer2: 'src\AnyCPU\Release\AppInstallerCLIE2ETests\AppInstallerCLIE2ETests.dll'
runSettingsFile: 'src\AnyCPU\Release\AppInstallerCLIE2ETests\Test.runsettings'
- overrideTestrunParameters: '-PackagedContext false -AICLIPath $(system.defaultWorkingDirectory)\src\x64\Release\AppInstallerCLI\AppInstallerCLI.exe'
+ overrideTestrunParameters: '-PackagedContext false
+ -AICLIPath $(system.defaultWorkingDirectory)\src\x64\Release\AppInstallerCLI\AppInstallerCLI.exe'
- task: VSTest@2
displayName: Run E2E Tests Packaged
@@ -163,7 +155,11 @@ jobs:
testSelector: 'testAssemblies'
testAssemblyVer2: 'src\AnyCPU\Release\AppInstallerCLIE2ETests\AppInstallerCLIE2ETests.dll'
runSettingsFile: 'src\AnyCPU\Release\AppInstallerCLIE2ETests\Test.runsettings'
- overrideTestrunParameters: '-PackagedContext true -AICLIPackagePath $(appxPackageDir)AppInstallerCLIPackage_0.0.0.2_Test\AppInstallerCLIPackage_0.0.0.2_x86_x64_ARM.appxbundle -AICLIPath AppInst.exe'
+ overrideTestrunParameters: '-PackagedContext true
+ -AICLIPackagePath $(system.defaultWorkingDirectory)\src\AppInstallerCLIPackage\bin\x64\Release
+ -AICLIPath AppInstallerCLI\AppInstallerCLI.exe
+ -LooseFileRegistration true
+ -InvokeCommandInDesktopPackage true'
- task: PublishBuildArtifacts@1
displayName: Publish CLI Binary
diff --git a/src/AppInstallerCLIE2ETests/Constants.cs b/src/AppInstallerCLIE2ETests/Constants.cs
index 1a35719528..3808961823 100644
--- a/src/AppInstallerCLIE2ETests/Constants.cs
+++ b/src/AppInstallerCLIE2ETests/Constants.cs
@@ -9,6 +9,8 @@ public class Constants
public const string AICLIPathParameter = "AICLIPath";
public const string AICLIPackagePathParameter = "AICLIPackagePath";
public const string VerboseLoggingParameter = "VerboseLogging";
+ public const string LooseFileRegistrationParameter = "LooseFileRegistration";
+ public const string InvokeCommandInDesktopPackageParameter = "InvokeCommandInDesktopPackage";
public const string AppInstallerTestCert = "AppInstallerTest.cer";
public const string AppInstallerTestCertThumbprint = "d03e7a688b388b1edde8476a627531c49db88017";
@@ -17,8 +19,9 @@ public class Constants
public const string IndexPackageCert = "IndexPackageInt.cer";
public const string IndexPackageCertThumbprint = "1da968e670a0257f61628aad20c60c64fdecd41a";
- public const string AICLIPackageFile = "AppInstallerCLIPackage.appxbundle";
+ public const string AICLIPackageFamilyName = "AppInstallerCLI_8wekyb3d8bbwe";
public const string AICLIPackageName = "AppInstallerCLI";
+ public const string AICLIAppId = "AppInst";
// Todo: there's a deployment bug that if the last optional package is removed, the main package is also removed.
// We should remove this when the deployment bug is fixed.
diff --git a/src/AppInstallerCLIE2ETests/SetUpFixture.cs b/src/AppInstallerCLIE2ETests/SetUpFixture.cs
index fb337f835e..e0eb2761c7 100644
--- a/src/AppInstallerCLIE2ETests/SetUpFixture.cs
+++ b/src/AppInstallerCLIE2ETests/SetUpFixture.cs
@@ -6,6 +6,7 @@ namespace AppInstallerCLIE2ETests
using Microsoft.Win32;
using NUnit.Framework;
using System;
+ using System.IO;
[SetUpFixture]
public class SetUpFixture
@@ -15,19 +16,25 @@ public class SetUpFixture
[OneTimeSetUp]
public void Setup()
{
- TestCommon.IsPackagedContext = TestContext.Parameters.Exists(Constants.PackagedContextParameter) &&
+ TestCommon.PackagedContext = TestContext.Parameters.Exists(Constants.PackagedContextParameter) &&
TestContext.Parameters.Get(Constants.PackagedContextParameter).Equals("true", StringComparison.OrdinalIgnoreCase);
TestCommon.VerboseLogging = TestContext.Parameters.Exists(Constants.VerboseLoggingParameter) &&
TestContext.Parameters.Get(Constants.VerboseLoggingParameter).Equals("true", StringComparison.OrdinalIgnoreCase);
+ TestCommon.LooseFileRegistration = TestContext.Parameters.Exists(Constants.LooseFileRegistrationParameter) &&
+ TestContext.Parameters.Get(Constants.LooseFileRegistrationParameter).Equals("true", StringComparison.OrdinalIgnoreCase);
+
+ TestCommon.InvokeCommandInDesktopPackage = TestContext.Parameters.Exists(Constants.InvokeCommandInDesktopPackageParameter) &&
+ TestContext.Parameters.Get(Constants.InvokeCommandInDesktopPackageParameter).Equals("true", StringComparison.OrdinalIgnoreCase);
+
if (TestContext.Parameters.Exists(Constants.AICLIPathParameter))
{
TestCommon.AICLIPath = TestContext.Parameters.Get(Constants.AICLIPathParameter);
}
else
{
- if (TestCommon.IsPackagedContext)
+ if (TestCommon.PackagedContext)
{
TestCommon.AICLIPath = "AppInst.exe";
}
@@ -43,7 +50,12 @@ public void Setup()
}
else
{
- TestCommon.AICLIPackagePath = TestCommon.GetTestFile(Constants.AICLIPackageFile);
+ TestCommon.AICLIPackagePath = TestCommon.GetTestFile("AppInstallerCLIPackage.appxbundle");
+ }
+
+ if (TestCommon.LooseFileRegistration && TestCommon.InvokeCommandInDesktopPackage)
+ {
+ TestCommon.AICLIPath = Path.Combine(TestCommon.AICLIPackagePath, TestCommon.AICLIPath);
}
ShouldDisableDevModeOnExit = EnableDevMode(true);
@@ -51,9 +63,16 @@ public void Setup()
Assert.True(TestCommon.RunCommand("certutil.exe", "-addstore -f \"TRUSTEDPEOPLE\" " + TestCommon.GetTestDataFile(Constants.AppInstallerTestCert)));
Assert.True(TestCommon.RunCommand("certutil.exe", "-addstore -f \"TRUSTEDPEOPLE\" " + TestCommon.GetTestDataFile(Constants.IndexPackageCert)));
- if (TestCommon.IsPackagedContext)
+ if (TestCommon.PackagedContext)
{
- Assert.True(TestCommon.InstallMsix(TestCommon.AICLIPackagePath));
+ if (TestCommon.LooseFileRegistration)
+ {
+ Assert.True(TestCommon.InstallMsixRegister(TestCommon.AICLIPackagePath));
+ }
+ else
+ {
+ Assert.True(TestCommon.InstallMsix(TestCommon.AICLIPackagePath));
+ }
Assert.True(TestCommon.InstallMsix(TestCommon.GetTestDataFile(Constants.PlaceholderPackageFile)));
}
}
@@ -69,7 +88,7 @@ public void TearDown()
TestCommon.RunCommand("certutil.exe", $"-delstore \"TRUSTEDPEOPLE\" {Constants.AppInstallerTestCertThumbprint}");
TestCommon.RunCommand("certutil.exe", $"-delstore \"TRUSTEDPEOPLE\" {Constants.IndexPackageCertThumbprint}");
- if (TestCommon.IsPackagedContext)
+ if (TestCommon.PackagedContext)
{
TestCommon.RemoveMsix(Constants.PlaceholderPackageName);
TestCommon.RemoveMsix(Constants.AICLIPackageName);
diff --git a/src/AppInstallerCLIE2ETests/SourceCommand.cs b/src/AppInstallerCLIE2ETests/SourceCommand.cs
index 6e2aa14846..1489c4824f 100644
--- a/src/AppInstallerCLIE2ETests/SourceCommand.cs
+++ b/src/AppInstallerCLIE2ETests/SourceCommand.cs
@@ -75,6 +75,8 @@ public void SourceCommands()
Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);
Assert.True(result.StdOut.Contains("Done"));
+ TestCommon.WaitForDeploymentFinish();
+
// List should show no source
result = TestCommon.RunAICLICommand("source", "list");
Assert.AreEqual(Constants.ErrorCode.S_OK, result.ExitCode);
diff --git a/src/AppInstallerCLIE2ETests/Test.runsettings b/src/AppInstallerCLIE2ETests/Test.runsettings
index 3843ae27f8..b97ff53de3 100644
--- a/src/AppInstallerCLIE2ETests/Test.runsettings
+++ b/src/AppInstallerCLIE2ETests/Test.runsettings
@@ -7,5 +7,7 @@
+
+
\ No newline at end of file
diff --git a/src/AppInstallerCLIE2ETests/TestCommon.cs b/src/AppInstallerCLIE2ETests/TestCommon.cs
index 95f7d85d91..4857eaeeb0 100644
--- a/src/AppInstallerCLIE2ETests/TestCommon.cs
+++ b/src/AppInstallerCLIE2ETests/TestCommon.cs
@@ -15,10 +15,14 @@ public class TestCommon
public static string AICLIPackagePath { get; set; }
- public static bool IsPackagedContext { get; set; }
+ public static bool PackagedContext { get; set; }
public static bool VerboseLogging { get; set; }
+ public static bool LooseFileRegistration { get; set; }
+
+ public static bool InvokeCommandInDesktopPackage { get; set; }
+
public struct RunCommandResult
{
public int ExitCode;
@@ -35,8 +39,20 @@ public static RunCommandResult RunAICLICommand(string command, string parameters
(string.IsNullOrEmpty(stdIn) ? "" : " StdIn: " + stdIn) +
" Timeout: " + timeOut;
- TestContext.Out.WriteLine("Started command run. " + inputMsg);
+ TestContext.Out.WriteLine($"Starting command run. {inputMsg} InvokeCommandInDesktopPackage: {InvokeCommandInDesktopPackage}");
+
+ if (InvokeCommandInDesktopPackage)
+ {
+ return RunAICLICommandViaInvokeCommandInDesktopPackage(command, parameters, stdIn, timeOut);
+ }
+ else
+ {
+ return RunAICLICommandViaDirectProcess(command, parameters, stdIn, timeOut);
+ }
+ }
+ public static RunCommandResult RunAICLICommandViaDirectProcess(string command, string parameters, string stdIn = null, int timeOut = 60000)
+ {
RunCommandResult result = new RunCommandResult();
Process p = new Process();
p.StartInfo = new ProcessStartInfo(AICLIPath, command + ' ' + parameters);
@@ -49,16 +65,7 @@ public static RunCommandResult RunAICLICommand(string command, string parameters
p.StartInfo.RedirectStandardInput = true;
}
- try
- {
- p.Start();
- }
- catch (System.ComponentModel.Win32Exception)
- {
- // App may be updating, give another try.
- WaitForDeploymentFinish();
- p.Start();
- }
+ p.Start();
if (!string.IsNullOrEmpty(stdIn))
{
@@ -75,22 +82,64 @@ public static RunCommandResult RunAICLICommand(string command, string parameters
if (!string.IsNullOrEmpty(result.StdErr))
{
- TestContext.Error.WriteLine("Command run error. " + inputMsg + " Error: " + result.StdErr);
+ TestContext.Error.WriteLine("Command run error. Error: " + result.StdErr);
}
if (VerboseLogging && !string.IsNullOrEmpty(result.StdOut))
{
- TestContext.Out.WriteLine("Command run output. " + inputMsg + " Output: " + result.StdOut);
+ TestContext.Out.WriteLine("Command run output. Output: " + result.StdOut);
}
}
else
{
- throw new TimeoutException("Command run timed out. " + inputMsg);
+ throw new TimeoutException("Command run timed out.");
}
return result;
}
+ public static RunCommandResult RunAICLICommandViaInvokeCommandInDesktopPackage(string command, string parameters, string stdIn = null, int timeOut = 60000)
+ {
+ string cmdCommandPiped = "";
+ if (!string.IsNullOrEmpty(stdIn))
+ {
+ cmdCommandPiped += $"echo {stdIn} | ";
+ }
+
+ string workDirectory = GetRandomTestDir();
+ string exitCodeFile = Path.Combine(workDirectory, "ExitCode.txt");
+ string stdOutFile = Path.Combine(workDirectory, "StdOut.txt");
+ string stdErrFile = Path.Combine(workDirectory, "StdErr.txt");
+
+ cmdCommandPiped += $"{AICLIPath} {command} {parameters} > {stdOutFile} 2> {stdErrFile} & call echo %^ERRORLEVEL% > {exitCodeFile}";
+
+ string psCommand = $"Invoke-CommandInDesktopPackage -PackageFamilyName {Constants.AICLIPackageFamilyName} -AppId {Constants.AICLIAppId} -PreventBreakaway -Command cmd.exe -Args '/c \"{cmdCommandPiped}\"'";
+
+ var psInvokeResult = RunCommandWithResult("powershell", psCommand);
+
+ if (psInvokeResult.ExitCode != 0)
+ {
+ // PS invocation failed, return result and no need to check piped output.
+ return psInvokeResult;
+ }
+
+ // The PS command just launches the app and immediately returns, we'll have to wait the timeOut specified here
+ int waitedTime = 0;
+ while (!File.Exists(exitCodeFile) && waitedTime <= timeOut)
+ {
+ Thread.Sleep(1000);
+ waitedTime += 1000;
+ }
+
+ RunCommandResult result = new RunCommandResult();
+
+ result.ExitCode = File.Exists(exitCodeFile) ? int.Parse(File.ReadAllText(exitCodeFile).Trim()) : unchecked((int)0x80004005);
+ result.StdOut = File.Exists(stdOutFile) ? File.ReadAllText(stdOutFile) : "";
+ result.StdErr = File.Exists(stdErrFile) ? File.ReadAllText(stdErrFile) : "";
+
+ return result;
+ }
+
public static bool RunCommand(string fileName, string args, int timeOut = 60000)
{
return RunCommandWithResult(fileName, args, timeOut).ExitCode == 0;
@@ -136,7 +185,7 @@ public static string GetTestDataFile(string fileName)
public static string GetRandomTestDir()
{
- string randDir = Path.Combine(TestContext.CurrentContext.TestDirectory, Path.GetRandomFileName());
+ string randDir = Path.Combine(TestContext.CurrentContext.TestDirectory, Path.Combine("WorkDirectory", Path.GetRandomFileName()));
Directory.CreateDirectory(randDir);
return randDir;
}
@@ -146,6 +195,12 @@ public static bool InstallMsix(string file)
return RunCommand("powershell", $"Add-AppxPackage \"{file}\"");
}
+ public static bool InstallMsixRegister(string packagePath)
+ {
+ string manifestFile = Path.Combine(packagePath, "AppxManifest.xml");
+ return RunCommand("powershell", $"Add-AppxPackage -Register \"{manifestFile}\"");
+ }
+
public static bool RemoveMsix(string name)
{
return RunCommand("powershell", $"Get-AppxPackage \"{name}\" | Remove-AppxPackage");
@@ -153,7 +208,7 @@ public static bool RemoveMsix(string name)
public static void WaitForDeploymentFinish()
{
- if (IsPackagedContext)
+ if (PackagedContext)
{
// Since we are doing a lot index add/remove, and some of the methods are fire and forget.
// Sometimes process start will fail because app is updating.