diff --git a/eng/pipelines/templates/stages/archetype-sdk-tool-pwsh.yml b/eng/pipelines/templates/stages/archetype-sdk-tool-pwsh.yml
index 0f611bdfe4f..55ec834220e 100644
--- a/eng/pipelines/templates/stages/archetype-sdk-tool-pwsh.yml
+++ b/eng/pipelines/templates/stages/archetype-sdk-tool-pwsh.yml
@@ -36,43 +36,9 @@ stages:
vmImage: $(Image)
steps:
- - pwsh: |
- Install-Module -Name Pester -Force
- displayName: Install Pester
-
- # default test steps
- - ${{ if eq(length(parameters.CustomTestSteps), 0) }}:
- - pwsh: |
- $tags = "${{ parameters.TargetTags }}" -Split "," | ForEach-Object { return $_.Trim() }
-
- $config = New-PesterConfiguration
- $config.CodeCoverage.Enabled = $true
- $config.TestResult.Enabled = $true
-
- if ($tags) {
- $config.Filter.Tag = $tags
- }
-
- Invoke-Pester -Configuration $config
- displayName: Run Tests
- env: ${{ parameters.EnvVars }}
- workingDirectory: $(Build.SourcesDirectory)/${{ parameters.TargetDirectory }}
-
- - ${{ if not(eq(length(parameters.CustomTestSteps), 0)) }}:
- - ${{ parameters.CustomTestSteps }}
-
- - task: PublishTestResults@2
- displayName: 'Publish Test Results'
- condition: succeededOrFailed()
- inputs:
- testResultsFormat: 'NUnit'
- testResultsFiles: $(Build.SourcesDirectory)/${{ parameters.TargetDirectory }}/testResults.xml
- testRunTitle: 'Tests_$(Image)'
-
- - task: PublishCodeCoverageResults@1
- displayName: 'Publish Code Coverage to Azure DevOps'
- condition: succeededOrFailed()
- inputs:
- codeCoverageTool: 'JaCoCo'
- summaryFileLocation: '$(Build.SourcesDirectory)/${{ parameters.TargetDirectory }}/coverage.xml'
- pathToSources: '$(Build.SourcesDirectory)/${{ parameters.TargetDirectory }}'
+ - template: /eng/pipelines/templates/steps/run-pester-tests.yml
+ parameters:
+ TargetDirectory: ${{ parameters.TargetDirectory }}
+ CustomTestSteps: ${{ parameters.CustomTestSteps }}
+ EnvVars: ${{ parameters.EnvVars }}
+ TargetTags: ${{ parameters.TargetTags }}
diff --git a/eng/pipelines/templates/steps/run-pester-tests.yml b/eng/pipelines/templates/steps/run-pester-tests.yml
new file mode 100644
index 00000000000..d6c0f449259
--- /dev/null
+++ b/eng/pipelines/templates/steps/run-pester-tests.yml
@@ -0,0 +1,54 @@
+parameters:
+ - name: TargetDirectory
+ type: string
+ - name: CustomTestSteps
+ type: object
+ default: []
+ - name: EnvVars
+ type: object
+ default: {}
+ - name: TargetTags
+ type: string
+ default: ''
+
+steps:
+ - pwsh: |
+ Install-Module -Name Pester -Force
+ displayName: Install Pester
+
+ # default test steps
+ - ${{ if eq(length(parameters.CustomTestSteps), 0) }}:
+ - pwsh: |
+ $tags = "${{ parameters.TargetTags }}" -Split "," | ForEach-Object { return $_.Trim() }
+
+ $config = New-PesterConfiguration
+ $config.CodeCoverage.Enabled = $true
+ $config.TestResult.Enabled = $true
+
+ if ($tags) {
+ $config.Filter.Tag = $tags
+ }
+
+ Invoke-Pester -Configuration $config
+ displayName: Run Tests
+ env: ${{ parameters.EnvVars }}
+ workingDirectory: $(Build.SourcesDirectory)/${{ parameters.TargetDirectory }}
+
+ - ${{ if not(eq(length(parameters.CustomTestSteps), 0)) }}:
+ - ${{ parameters.CustomTestSteps }}
+
+ - task: PublishTestResults@2
+ displayName: 'Publish Test Results'
+ condition: succeededOrFailed()
+ inputs:
+ testResultsFormat: 'NUnit'
+ testResultsFiles: $(Build.SourcesDirectory)/${{ parameters.TargetDirectory }}/testResults.xml
+ testRunTitle: '$(System.StageName)_$(Agent.JobName)_Tests'
+
+ - task: PublishCodeCoverageResults@1
+ displayName: 'Publish Code Coverage to Azure DevOps'
+ condition: succeededOrFailed()
+ inputs:
+ codeCoverageTool: 'JaCoCo'
+ summaryFileLocation: '$(Build.SourcesDirectory)/${{ parameters.TargetDirectory }}/coverage.xml'
+ pathToSources: '$(Build.SourcesDirectory)/${{ parameters.TargetDirectory }}'
\ No newline at end of file
diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/IntegrationTests/GitStoreIntegrationPushTests.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/IntegrationTests/GitStoreIntegrationPushTests.cs
index 9ed60c95ff2..94d2e8b8247 100644
--- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/IntegrationTests/GitStoreIntegrationPushTests.cs
+++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy.Tests/IntegrationTests/GitStoreIntegrationPushTests.cs
@@ -13,6 +13,11 @@
namespace Azure.Sdk.Tools.TestProxy.Tests.IntegrationTests
{
+
+ // With the use of tags, the push scenarios are going to be somewhat redundant since
+ // tags are vastly simplified, in terms of processing compared to branches. The
+ // Scenarios below are similar but use 3 different starting tags with different
+ // files and different file versions.
public class GitStoreIntegrationPushTests
{
public GitStoreIntegrationPushTests()
@@ -24,13 +29,11 @@ public GitStoreIntegrationPushTests()
private GitStore _defaultStore = new GitStore();
///
- /// New push scenario
- /// 1. Auto Branch Doesn't Exist Yet
- /// 2. New branch is created off of main
- /// 3. Add/Delete/Update files
- /// 4. Push to new branch
- /// 5. Verify local files are what is expected
- /// 6. Verify assets.json was updated with the new commit Tag
+ /// 1. Restore from the initial tag in pull/scenarios
+ /// 2. Add/Delete/Update files
+ /// 3. Push to new branch
+ /// 4. Verify local files are what is expected
+ /// 5. Verify assets.json was updated with the new commit Tag
///
///
///
@@ -44,7 +47,7 @@ public GitStoreIntegrationPushTests()
""Tag"": ""language/tables_fc54d0""
}")]
[Trait("Category", "Integration")]
- public async Task ScenarioNewPush(string inputJson)
+ public async Task Scenario1(string inputJson)
{
var folderStructure = new string[]
{
@@ -52,13 +55,13 @@ public async Task ScenarioNewPush(string inputJson)
};
Assets assets = JsonSerializer.Deserialize(inputJson);
Assets updatedAssets = null;
- string originalAssetsRepoBranch = assets.TagPrefix;
- string originalSHA = assets.Tag;
+ string originalTagPrefix = assets.TagPrefix;
+ string originalTag = assets.Tag;
var testFolder = TestHelpers.DescribeTestFolder(assets, folderStructure, isPushTest:true);
try
{
// Ensure that the TagPrefix was updated
- Assert.NotEqual(originalAssetsRepoBranch, assets.TagPrefix);
+ Assert.NotEqual(originalTagPrefix, assets.TagPrefix);
var jsonFileLocation = Path.Join(testFolder, GitStoretests.AssetsJson);
@@ -94,7 +97,7 @@ public async Task ScenarioNewPush(string inputJson)
// Ensure that the config was updated with the new Tag as part of the push
updatedAssets = TestHelpers.LoadAssetsFromFile(jsonFileLocation);
- Assert.NotEqual(originalSHA, updatedAssets.Tag);
+ Assert.NotEqual(originalTag, updatedAssets.Tag);
// Ensure that the targeted tag is present on the repo
TestHelpers.CheckExistenceOfTag(updatedAssets, localFilePath);
@@ -107,10 +110,9 @@ public async Task ScenarioNewPush(string inputJson)
}
///
- /// Clean Push Scenario
- /// 1. Branch already exists and we're on the latest Tag
+ /// 1. Restore from the second tag in pull/scenarios
/// 2. Add/Delete/Update files
- /// 3. Push commit to branch
+ /// 3. Push to new branch
/// 4. Verify local files are what is expected
/// 5. Verify assets.json was updated with the new commit Tag
///
@@ -126,7 +128,7 @@ public async Task ScenarioNewPush(string inputJson)
""Tag"": ""language/tables_bb2223""
}")]
[Trait("Category", "Integration")]
- public async Task ScenarioCleanPush(string inputJson)
+ public async Task Scenario2(string inputJson)
{
var folderStructure = new string[]
{
@@ -134,13 +136,13 @@ public async Task ScenarioCleanPush(string inputJson)
};
Assets assets = JsonSerializer.Deserialize(inputJson);
Assets updatedAssets = null;
- string originalAssetsRepoBranch = assets.TagPrefix;
- string originalSHA = assets.Tag;
+ string originalTagPrefix = assets.TagPrefix;
+ string originalTag = assets.Tag;
var testFolder = TestHelpers.DescribeTestFolder(assets, folderStructure, isPushTest: true);
try
{
// Ensure that the TagPrefix was updated
- Assert.NotEqual(originalAssetsRepoBranch, assets.TagPrefix);
+ Assert.NotEqual(originalTagPrefix, assets.TagPrefix);
var jsonFileLocation = Path.Join(testFolder, GitStoretests.AssetsJson);
@@ -176,7 +178,7 @@ public async Task ScenarioCleanPush(string inputJson)
// Ensure that the config was updated with the new Tag as part of the push
updatedAssets = TestHelpers.LoadAssetsFromFile(jsonFileLocation);
- Assert.NotEqual(originalSHA, updatedAssets.Tag);
+ Assert.NotEqual(originalTag, updatedAssets.Tag);
// Ensure that the targeted tag is present on the repo
TestHelpers.CheckExistenceOfTag(updatedAssets, localFilePath);
@@ -189,10 +191,9 @@ public async Task ScenarioCleanPush(string inputJson)
}
///
- /// Conflict Push Scenario
- /// 1. Branch already exists and we're not on the latest Tag
+ /// 1. Restore from the third tag in pull/scenarios
/// 2. Add/Delete/Update files
- /// 3. Push commit to branch, detects a conflict
+ /// 3. Push to new branch
/// 4. Verify local files are what is expected
/// 5. Verify assets.json was updated with the new commit Tag
///
@@ -208,7 +209,7 @@ public async Task ScenarioCleanPush(string inputJson)
""Tag"": ""language/tables_9e81fb""
}")]
[Trait("Category", "Integration")]
- public async Task ScenarioConflictPush(string inputJson)
+ public async Task Scenario3(string inputJson)
{
var folderStructure = new string[]
{
@@ -216,13 +217,13 @@ public async Task ScenarioConflictPush(string inputJson)
};
Assets assets = JsonSerializer.Deserialize(inputJson);
Assets updatedAssets = null;
- string originalAssetsRepoBranch = assets.TagPrefix;
- string originalSHA = assets.Tag;
+ string originalTagPrefix = assets.TagPrefix;
+ string originalTag = assets.Tag;
var testFolder = TestHelpers.DescribeTestFolder(assets, folderStructure, isPushTest: true);
try
{
// Ensure that the TagPrefix was updated
- Assert.NotEqual(originalAssetsRepoBranch, assets.TagPrefix);
+ Assert.NotEqual(originalTagPrefix, assets.TagPrefix);
var jsonFileLocation = Path.Join(testFolder, GitStoretests.AssetsJson);
@@ -269,7 +270,7 @@ public async Task ScenarioConflictPush(string inputJson)
// Ensure that the config was updated with the new Tag as part of the push
updatedAssets = TestHelpers.LoadAssetsFromFile(jsonFileLocation);
- Assert.NotEqual(originalSHA, updatedAssets.Tag);
+ Assert.NotEqual(originalTag, updatedAssets.Tag);
// Ensure that the targeted tag is present on the repo
TestHelpers.CheckExistenceOfTag(updatedAssets, localFilePath);
diff --git a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Startup.cs b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Startup.cs
index 79557e5970b..9e7ea8f114b 100644
--- a/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Startup.cs
+++ b/tools/test-proxy/Azure.Sdk.Tools.TestProxy/Startup.cs
@@ -56,6 +56,7 @@ private static string resolveRepoLocation(string storageLocation = null)
/// CommandLineParser arguments. In server mode use double dash '--' and everything after that becomes additional arguments to Host.CreateDefaultBuilder. Ex. -- arg1 value1 arg2 value2
public static async Task Main(string[] args = null)
{
+ VerifyVerb(args);
// JRS - Temporarily disable this check because of https://github.com/Azure/azure-sdk-tools/issues/4116
// This throws and will exit
// new GitProcessHandler().VerifyGitMinVersion();
@@ -66,8 +67,55 @@ public static async Task Main(string[] args = null)
settings.HelpWriter = System.Console.Out;
settings.EnableDashDash = true;
});
-
- await parser.ParseArguments(args).WithParsedAsync(Run);
+
+ await parser.ParseArguments(args)
+ .WithNotParsed(ExitWithError)
+ .WithParsedAsync(Run);
+ }
+
+ static void ExitWithError(IEnumerable errors)
+ {
+ Environment.Exit(1);
+ }
+
+ ///
+ /// This is only necessary because if there's a default verb defined, ours is start,
+ /// CommandLineParser doesn't verify the verb. If the issue is fixed this function
+ /// can be removed.
+ /// https://github.com/commandlineparser/commandline/issues/849
+ ///
+ ///
+ static void VerifyVerb(string[] args)
+ {
+ // no arguments means the server is starting with all the default options
+ if (args.Length == 0)
+ {
+ return;
+ }
+
+ // if the first argument starts with a dash then they're options and the
+ // default verb is being used.
+ if (args[0].StartsWith("-"))
+ {
+ return;
+ }
+
+ // last but not least, the first argument is a verb, verify it's our verb
+ string[] array = { "start", "reset", "restore", "push" };
+ if (!array.Contains(args[0]))
+ {
+ // The odd looking formatting is to make this look like the same error
+ // CommandLineParser would output if the verb wasn't recognized.
+ string error = @$"ERROR(S):
+ Verb '{args[0]}' is not recognized.
+
+ --help Display this help screen.
+
+ --version Display version information.
+";
+ System.Console.WriteLine(error);
+ Environment.Exit(1);
+ }
}
private static async Task Run(object commandObj)
diff --git a/tools/test-proxy/test-scripts/CLIIntegration.Tests.ps1 b/tools/test-proxy/test-scripts/CLIIntegration.Tests.ps1
new file mode 100644
index 00000000000..940142b2926
--- /dev/null
+++ b/tools/test-proxy/test-scripts/CLIIntegration.Tests.ps1
@@ -0,0 +1,392 @@
+# Invoke-Pester .\CLIIntegration.Tests.ps1 -PassThru
+BeforeAll {
+ . $PSScriptRoot/assets.Tests.Helpers.ps1
+ . $PSScriptRoot/../../../eng/common/scripts/common.ps1
+
+ # Each machine installs test-proxy.exe and adds it to the path. Verify that
+ # the it's on the path prior to trying to run tests
+ $TestProxyExe = "test-proxy"
+ $proxyInPath = Test-Exe-In-Path($TestProxyExe)
+ if (-not $proxyInPath) {
+ LogError "$TestProxyExe was not found in the path. Please ensure the install has been done prior to running tests."
+ exit(1)
+ }
+ Set-StrictMode -Version 3
+}
+
+Describe "AssetsModuleTests" {
+ Context "RestoreAssetsRepoTests" -Tag "Integration" {
+ BeforeEach {
+ $testFolder = $null
+ }
+ It "Should restore from original push of assets." {
+ $recordingJson = [PSCustomObject]@{
+ AssetsRepo = "Azure/azure-sdk-assets-integration"
+ AssetsRepoPrefixPath = "pull/scenarios"
+ AssetsRepoId = ""
+ TagPrefix = "main"
+ Tag = "language/tables_fc54d0"
+ }
+ $files = @(
+ "assets.json"
+ )
+ $testFolder = Describe-TestFolder -AssetsJsonContent $recordingJson -Files $files
+ $assetsFile = Join-Path $testFolder "assets.json"
+ $CommandArgs = "restore --assets-json-path $assetsFile"
+ Invoke-ProxyCommand -TestProxyExe $TestProxyExe $CommandArgs
+ $LASTEXITCODE | Should -Be 0
+ $localAssetsFilePath = Get-AssetsFilePath -AssetsJsonContent $recordingJson -AssetsJsonFile $assetsFile
+ Test-DirectoryFileCount -Directory $localAssetsFilePath -ExpectedNumberOfFiles 3
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file1.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file2.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file3.txt" -ExpectedVersion 1
+ }
+ It "Should restore from second push of assets." {
+ $recordingJson = [PSCustomObject]@{
+ AssetsRepo = "Azure/azure-sdk-assets-integration"
+ AssetsRepoPrefixPath = "pull/scenarios"
+ AssetsRepoId = ""
+ TagPrefix = "main"
+ Tag = "language/tables_9e81fb"
+ }
+
+ $files = @(
+ "assets.json"
+ )
+ $testFolder = Describe-TestFolder -AssetsJsonContent $recordingJson -Files $files
+ $assetsFile = Join-Path $testFolder "assets.json"
+ $CommandArgs = "restore --assets-json-path $assetsFile"
+ Invoke-ProxyCommand -TestProxyExe $TestProxyExe $CommandArgs
+ $LASTEXITCODE | Should -Be 0
+ $localAssetsFilePath = Get-AssetsFilePath -AssetsJsonContent $recordingJson -AssetsJsonFile $assetsFile
+ Test-DirectoryFileCount -Directory $localAssetsFilePath -ExpectedNumberOfFiles 4
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file1.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file2.txt" -ExpectedVersion 2
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file3.txt" -ExpectedVersion 2
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file4.txt" -ExpectedVersion 1
+ }
+ It "Should restore from third push of files." {
+ $recordingJson = [PSCustomObject]@{
+ AssetsRepo = "Azure/azure-sdk-assets-integration"
+ AssetsRepoPrefixPath = "pull/scenarios"
+ AssetsRepoId = ""
+ TagPrefix = "main"
+ Tag = "language/tables_bb2223"
+ }
+
+ $files = @(
+ "assets.json"
+ )
+ $testFolder = Describe-TestFolder -AssetsJsonContent $recordingJson -Files $files
+ $assetsFile = Join-Path $testFolder "assets.json"
+ $CommandArgs = "restore --assets-json-path $assetsFile"
+ Invoke-ProxyCommand -TestProxyExe $TestProxyExe $CommandArgs
+ $LASTEXITCODE | Should -Be 0
+ $localAssetsFilePath = Get-AssetsFilePath -AssetsJsonContent $recordingJson -AssetsJsonFile $assetsFile
+ Test-DirectoryFileCount -Directory $localAssetsFilePath -ExpectedNumberOfFiles 3
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file2.txt" -ExpectedVersion 2
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file4.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file5.txt" -ExpectedVersion 1
+ }
+ AfterEach {
+ Remove-Test-Folder $testFolder
+ }
+ }
+ Context "ResetAssetsRepoTests" -Tag "Integration" {
+ BeforeEach {
+ $testFolder = $null
+ }
+ It "It should call Reset without prompt if no files have changed" {
+ $recordingJson = [PSCustomObject]@{
+ AssetsRepo = "Azure/azure-sdk-assets-integration"
+ AssetsRepoPrefixPath = "pull/scenarios"
+ AssetsRepoId = ""
+ TagPrefix = "main"
+ Tag = "language/tables_fc54d0"
+ }
+ $files = @(
+ "assets.json"
+ )
+ $testFolder = Describe-TestFolder -AssetsJsonContent $recordingJson -Files $files
+ $assetsFile = Join-Path $testFolder "assets.json"
+ $CommandArgs = "restore --assets-json-path $assetsFile"
+ Invoke-ProxyCommand -TestProxyExe $TestProxyExe $CommandArgs
+ $LASTEXITCODE | Should -Be 0
+ $localAssetsFilePath = Get-AssetsFilePath -AssetsJsonContent $recordingJson -AssetsJsonFile $assetsFile
+ Test-DirectoryFileCount -Directory $localAssetsFilePath -ExpectedNumberOfFiles 3
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file1.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file2.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file3.txt" -ExpectedVersion 1
+
+ $CommandArgs = "reset --assets-json-path $assetsFile"
+ Invoke-ProxyCommand -TestProxyExe $TestProxyExe $CommandArgs
+ # With no pending changes, the reset should leave everything alone
+ Test-DirectoryFileCount -Directory $localAssetsFilePath -ExpectedNumberOfFiles 3
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file1.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file2.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file3.txt" -ExpectedVersion 1
+ }
+ It "It should call Reset and prompt Yes to restore files" {
+ $recordingJson = [PSCustomObject]@{
+ AssetsRepo = "Azure/azure-sdk-assets-integration"
+ AssetsRepoPrefixPath = "pull/scenarios"
+ AssetsRepoId = ""
+ TagPrefix = "main"
+ Tag = "language/tables_fc54d0"
+ }
+ $files = @(
+ "assets.json"
+ )
+ $testFolder = Describe-TestFolder -AssetsJsonContent $recordingJson -Files $files
+ $assetsFile = Join-Path $testFolder "assets.json"
+ $CommandArgs = "restore --assets-json-path $assetsFile"
+ Invoke-ProxyCommand -TestProxyExe $TestProxyExe $CommandArgs
+ $LASTEXITCODE | Should -Be 0
+ $localAssetsFilePath = Get-AssetsFilePath -AssetsJsonContent $recordingJson -AssetsJsonFile $assetsFile
+ Test-DirectoryFileCount -Directory $localAssetsFilePath -ExpectedNumberOfFiles 3
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file1.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file2.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file3.txt" -ExpectedVersion 1
+
+ # Create a new file and verify
+ Edit-FileVersion -FilePath $localAssetsFilePath -FileName "file4.txt" -Version 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file4.txt" -ExpectedVersion 1
+ # Update a file and verify
+ Edit-FileVersion -FilePath $localAssetsFilePath -FileName "file1.txt" -Version 2
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file1.txt" -ExpectedVersion 2
+ # Delete a file
+ $fileToRemove = Join-Path -Path $localAssetsFilePath -ChildPath "file2.txt"
+ Remove-Item -Path $fileToRemove
+
+ # Reset answering Y and they should all go back to original restore
+ $CommandArgs = "reset --assets-json-path $assetsFile"
+ Invoke-ProxyCommand -TestProxyExe $TestProxyExe $CommandArgs -WriteOutput "Y"
+ Test-DirectoryFileCount -Directory $localAssetsFilePath -ExpectedNumberOfFiles 3
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file1.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file2.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file3.txt" -ExpectedVersion 1
+ }
+ It "It should call Reset and prompt No to restore files" {
+ $recordingJson = [PSCustomObject]@{
+ AssetsRepo = "Azure/azure-sdk-assets-integration"
+ AssetsRepoPrefixPath = "pull/scenarios"
+ AssetsRepoId = ""
+ TagPrefix = "main"
+ Tag = "language/tables_fc54d0"
+ }
+ $files = @(
+ "assets.json"
+ )
+ $testFolder = Describe-TestFolder -AssetsJsonContent $recordingJson -Files $files
+ $assetsFile = Join-Path $testFolder "assets.json"
+ $CommandArgs = "restore --assets-json-path $assetsFile"
+ Invoke-ProxyCommand -TestProxyExe $TestProxyExe $CommandArgs
+ $LASTEXITCODE | Should -Be 0
+ $localAssetsFilePath = Get-AssetsFilePath -AssetsJsonContent $recordingJson -AssetsJsonFile $assetsFile
+ Test-DirectoryFileCount -Directory $localAssetsFilePath -ExpectedNumberOfFiles 3
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file1.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file2.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file3.txt" -ExpectedVersion 1
+
+ # Create two new files and verify
+ Edit-FileVersion -FilePath $localAssetsFilePath -FileName "file4.txt" -Version 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file4.txt" -ExpectedVersion 1
+ Edit-FileVersion -FilePath $localAssetsFilePath -FileName "file5.txt" -Version 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file5.txt" -ExpectedVersion 1
+ # Update a file and verify
+ Edit-FileVersion -FilePath $localAssetsFilePath -FileName "file1.txt" -Version 2
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file1.txt" -ExpectedVersion 2
+ # Delete a file
+ $fileToRemove = Join-Path -Path $localAssetsFilePath -ChildPath "file2.txt"
+ Remove-Item -Path $fileToRemove
+
+ # Reset answering N and they should remain changed as per the previous changes
+ $CommandArgs = "reset --assets-json-path $assetsFile"
+ Invoke-ProxyCommand -TestProxyExe $TestProxyExe $CommandArgs -WriteOutput "N"
+ Test-DirectoryFileCount -Directory $localAssetsFilePath -ExpectedNumberOfFiles 4
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file1.txt" -ExpectedVersion 2
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file3.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file4.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file5.txt" -ExpectedVersion 1
+ }
+ AfterEach {
+ Remove-Test-Folder $testFolder
+ }
+ }
+ Context "PushAssetsRepoTests" -Tag "Integration" {
+ BeforeEach {
+ $updatedAssets = $null
+ $testFolder = $null
+ }
+ It "Should push new, updated and deleted files, original restore from first push of assets." {
+ $recordingJson = [PSCustomObject]@{
+ AssetsRepo = "Azure/azure-sdk-assets-integration"
+ AssetsRepoPrefixPath = "pull/scenarios"
+ AssetsRepoId = ""
+ TagPrefix = "language/tables"
+ Tag = "language/tables_fc54d0"
+ }
+ $files = @(
+ "assets.json"
+ )
+
+ $originalTagPrefix = $recordingJson.TagPrefix
+ $testFolder = Describe-TestFolder -AssetsJsonContent $recordingJson -Files $files -IsPushTest $true
+ # Ensure that the TagPrefix was updated for testing
+ $originalTagPrefix | Should -not -Be $recordingJson.TagPrefix
+ $assetsFile = Join-Path $testFolder "assets.json"
+ $CommandArgs = "restore --assets-json-path $assetsFile"
+
+ # The initial restore/verification
+ Invoke-ProxyCommand -TestProxyExe $TestProxyExe $CommandArgs
+ $LASTEXITCODE | Should -Be 0
+ $localAssetsFilePath = Get-AssetsFilePath -AssetsJsonContent $recordingJson -AssetsJsonFile $assetsFile
+ Test-DirectoryFileCount -Directory $localAssetsFilePath -ExpectedNumberOfFiles 3
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file1.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file2.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file3.txt" -ExpectedVersion 1
+
+ # Create a new file
+ Edit-FileVersion -FilePath $localAssetsFilePath -FileName "file4.txt" -Version 1
+ # Update the version on an existing file
+ Edit-FileVersion -FilePath $localAssetsFilePath -FileName "file1.txt" -Version 2
+ # Delete a file
+ $fileToRemove = Join-Path -Path $localAssetsFilePath -ChildPath "file2.txt"
+ Remove-Item -Path $fileToRemove
+ $assetsFile = Join-Path $testFolder "assets.json"
+
+ # Push the changes
+ $CommandArgs = "push --assets-json-path $assetsFile"
+ Invoke-ProxyCommand -TestProxyExe $TestProxyExe $CommandArgs
+
+ # Verify that after the push the directory still contains our updated files
+ Test-DirectoryFileCount -Directory $localAssetsFilePath -ExpectedNumberOfFiles 3
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file1.txt" -ExpectedVersion 2
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file3.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file4.txt" -ExpectedVersion 1
+
+ $updatedAssets = Update-AssetsFromFile -AssetsJsonContent $assetsFile
+ Write-Host "updatedAssets.Tag=$($updatedAssets.Tag), originalAssets.Tag=$($recordingJson.Tag)"
+ $updatedAssets.Tag | Should -not -Be $recordingJson.Tag
+
+ $exists = Test-TagExists -AssetsJsonContent $updatedAssets -WorkingDirectory $localAssetsFilePath
+ $exists | Should -Be $true
+ }
+ It "Should push new, updated and deleted files, original restore from second push of assets." {
+ $recordingJson = [PSCustomObject]@{
+ AssetsRepo = "Azure/azure-sdk-assets-integration"
+ AssetsRepoPrefixPath = "pull/scenarios"
+ AssetsRepoId = ""
+ TagPrefix = "language/tables"
+ Tag = "language/tables_bb2223"
+ }
+
+ $files = @(
+ "assets.json"
+ )
+ $originalTagPrefix = $recordingJson.TagPrefix
+ $testFolder = Describe-TestFolder -AssetsJsonContent $recordingJson -Files $files -IsPushTest $true
+ # Ensure that the TagPrefix was updated for testing
+ $originalTagPrefix | Should -not -Be $recordingJson.TagPrefix
+ $assetsFile = Join-Path $testFolder "assets.json"
+ $CommandArgs = "restore --assets-json-path $assetsFile"
+
+ # The initial restore/verification
+ Invoke-ProxyCommand -TestProxyExe $TestProxyExe $CommandArgs
+ $LASTEXITCODE | Should -Be 0
+ $localAssetsFilePath = Get-AssetsFilePath -AssetsJsonContent $recordingJson -AssetsJsonFile $assetsFile
+ Test-DirectoryFileCount -Directory $localAssetsFilePath -ExpectedNumberOfFiles 3
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file2.txt" -ExpectedVersion 2
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file4.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file5.txt" -ExpectedVersion 1
+
+ # Create a new file
+ Edit-FileVersion -FilePath $localAssetsFilePath -FileName "file6.txt" -Version 1
+ # Update the version on an existing file
+ Edit-FileVersion -FilePath $localAssetsFilePath -FileName "file2.txt" -Version 3
+ # Delete a file
+ $fileToRemove = Join-Path -Path $localAssetsFilePath -ChildPath "file5.txt"
+ Remove-Item -Path $fileToRemove
+ $assetsFile = Join-Path $testFolder "assets.json"
+
+ # Push the changes
+ $CommandArgs = "push --assets-json-path $assetsFile"
+ Invoke-ProxyCommand -TestProxyExe $TestProxyExe $CommandArgs
+
+ # Verify that after the push the directory still contains our updated files
+ Test-DirectoryFileCount -Directory $localAssetsFilePath -ExpectedNumberOfFiles 3
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file2.txt" -ExpectedVersion 3
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file4.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file6.txt" -ExpectedVersion 1
+
+ $updatedAssets = Update-AssetsFromFile -AssetsJsonContent $assetsFile
+ Write-Host "updatedAssets.Tag=$($updatedAssets.Tag), originalAssets.Tag=$($recordingJson.Tag)"
+ $updatedAssets.Tag | Should -not -Be $recordingJson.Tag
+
+ $exists = Test-TagExists -AssetsJsonContent $updatedAssets -WorkingDirectory $localAssetsFilePath
+ $exists | Should -Be $true
+ }
+ It "Should push new, updated and deleted files, original restore from third push of assets." {
+ $recordingJson = [PSCustomObject]@{
+ AssetsRepo = "Azure/azure-sdk-assets-integration"
+ AssetsRepoPrefixPath = "pull/scenarios"
+ AssetsRepoId = ""
+ TagPrefix = "language/tables"
+ Tag = "language/tables_9e81fb"
+ }
+
+ $files = @(
+ "assets.json"
+ )
+ $originalTagPrefix = $recordingJson.TagPrefix
+ $testFolder = Describe-TestFolder -AssetsJsonContent $recordingJson -Files $files -IsPushTest $true
+ # Ensure that the TagPrefix was updated for testing
+ $originalTagPrefix | Should -not -Be $recordingJson.TagPrefix
+ $assetsFile = Join-Path $testFolder "assets.json"
+ $CommandArgs = "restore --assets-json-path $assetsFile"
+
+ # The initial restore/verification
+ Invoke-ProxyCommand -TestProxyExe $TestProxyExe $CommandArgs
+ $LASTEXITCODE | Should -Be 0
+ $localAssetsFilePath = Get-AssetsFilePath -AssetsJsonContent $recordingJson -AssetsJsonFile $assetsFile
+ Test-DirectoryFileCount -Directory $localAssetsFilePath -ExpectedNumberOfFiles 4
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file1.txt" -ExpectedVersion 1
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file2.txt" -ExpectedVersion 2
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file3.txt" -ExpectedVersion 2
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file4.txt" -ExpectedVersion 1
+
+ # Create a new file
+ Edit-FileVersion -FilePath $localAssetsFilePath -FileName "file6.txt" -Version 1
+ # Update the version on an existing file
+ Edit-FileVersion -FilePath $localAssetsFilePath -FileName "file1.txt" -Version 2
+ Edit-FileVersion -FilePath $localAssetsFilePath -FileName "file2.txt" -Version 3
+ # Delete files 3 & 4
+ $fileToRemove = Join-Path -Path $localAssetsFilePath -ChildPath "file3.txt"
+ Remove-Item -Path $fileToRemove
+ $fileToRemove = Join-Path -Path $localAssetsFilePath -ChildPath "file4.txt"
+ Remove-Item -Path $fileToRemove
+ $assetsFile = Join-Path $testFolder "assets.json"
+
+ # Push the changes
+ $CommandArgs = "push --assets-json-path $assetsFile"
+ Invoke-ProxyCommand -TestProxyExe $TestProxyExe $CommandArgs
+
+ # Verify that after the push the directory still contains our updated files
+ Test-DirectoryFileCount -Directory $localAssetsFilePath -ExpectedNumberOfFiles 3
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file1.txt" -ExpectedVersion 2
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file2.txt" -ExpectedVersion 3
+ Test-FileVersion -FilePath $localAssetsFilePath -FileName "file6.txt" -ExpectedVersion 1
+
+ $updatedAssets = Update-AssetsFromFile -AssetsJsonContent $assetsFile
+ Write-Host "updatedAssets.Tag=$($updatedAssets.Tag), originalAssets.Tag=$($recordingJson.Tag)"
+ $updatedAssets.Tag | Should -not -Be $recordingJson.Tag
+
+ $exists = Test-TagExists -AssetsJsonContent $updatedAssets -WorkingDirectory $localAssetsFilePath
+ $exists | Should -Be $true
+ }
+ AfterEach {
+ Remove-Test-Folder $testFolder
+ Remove-Integration-Tag $updatedAssets
+ }
+ }
+}
\ No newline at end of file
diff --git a/tools/test-proxy/test-scripts/assets.Tests.Helpers.ps1 b/tools/test-proxy/test-scripts/assets.Tests.Helpers.ps1
new file mode 100644
index 00000000000..3cbaca359a3
--- /dev/null
+++ b/tools/test-proxy/test-scripts/assets.Tests.Helpers.ps1
@@ -0,0 +1,352 @@
+# Helper functions used by the CLI Integration Tests
+
+# Test whether or not a given executable is in the path. This is used to ensure TestProxy.exe
+# has been installed and is on the path.
+Function Test-Exe-In-Path {
+ Param([string] $ExeToLookFor)
+ if ($null -eq (Get-Command $ExeToLookFor -ErrorAction SilentlyContinue)) {
+ Write-Host "Unable to find $ExeToLookFor in your PATH"
+ return $false
+ }
+ else {
+ Write-Host "Found $ExeToLookFor in path"
+ return $true
+ }
+}
+
+# Get the CloneURL. If the GIT_TOKEN environment variable has been set
+# then the token is part of the git URL.
+Function Get-CloneUrl {
+ Param([string] $AssetsRepo)
+ $gitToken = $env:GIT_TOKEN
+ if (-not ([string]::IsNullOrWhitespace($gitToken))) {
+ return "https://$($gitToken)@github.com/$($AssetsRepo)"
+ }
+ else {
+ return "https://github.com/$($AssetsRepo)"
+ }
+}
+
+# Returns the TEMP directory
+Function Get-TestFolder {
+ return [System.IO.Path]::GetTempPath()
+}
+
+# Gets the path that will be used by the test to do Git actions. A
+# temporary, unique directory is created of the form /
+# unless permanent storage is disabled at which point the temporary
+# directory is TestDrive:
+Function Get-TestPath {
+ Param([string] $TestGuid)
+
+ $disablePermanentStorage = $env:USE_TESTDRIVE
+ $localTempPath = Get-TestFolder
+
+ if ($disablePermanentStorage) {
+ $testPath = "TestDrive:\$TestGuid\"
+
+ New-Item -Type Directory -Force -Path $testPath | Out-Null
+ return $testPath
+ }
+ else {
+ $testPath = (Join-Path $localTempPath "$($TestGuid)")
+
+ New-Item -Type Directory -Force -Path $testPath | Out-Null
+ return $testPath
+ }
+}
+
+# This is only used by the push tests. It basically creates a tag that
+# we can automatically push to instead of one that requires a PR and
+# has to be manually merged. This is necessary for automation.
+Function Initialize-Integration-Tag {
+ param(
+ [PSCustomObject] $Assets,
+ [string] $AdjustedAssetsRepoTag
+ )
+
+ $tempPath = "TestDrive:\$([Guid]::NewGuid())\"
+ New-Item -Type Directory -Force -Path $tempPath | Out-Null
+ try {
+ Push-Location $tempPath
+ $gitCloneUrl = Get-CloneUrl $Assets.AssetsRepo
+ Write-Host "git clone $($gitCloneUrl) ."
+ git clone $gitCloneUrl . | Out-Null
+ Write-Host "git ls-remote --heads $($gitCloneUrl) $($Assets.TagPrefix)"
+ $stdOut = git ls-remote --heads $($gitCloneUrl) $($Assets.TagPrefix) | Out-String
+ # If the command response is empty there's nothing to do and we can just return
+ if ([string]::IsNullOrWhitespace($stdOut)) {
+ return
+ }
+
+ # If the response isn't empty, we need to create the test tag
+ # 1. Checkout the current TagPrefix
+ Write-Host "git checkout $($Assets.TagPrefix)"
+ git checkout $($Assets.TagPrefix) | Out-Null
+ # 2. Create the AdjustedAssetsRepoTag from the original TagPrefix. The reason being
+ # is that pushing will be automatic.
+ Write-Host "git tag $($AdjustedAssetsRepoTag)"
+ git tag $($AdjustedAssetsRepoTag) | Out-Null
+ # 3. Push the contents of the TagPrefix into the AdjustedAssetsRepoTag
+ Write-Host "git push origin $($AdjustedAssetsRepoTag)"
+ git push origin $($AdjustedAssetsRepoTag) | Out-Null
+ }
+ catch {
+ Write-Error $_
+ }
+ finally {
+ Pop-Location
+ Remove-Item -Force -Recurse $tempPath | Out-Null
+ }
+ return
+}
+
+# Clean up the tag that was pushed as part of the integration tests.
+Function Remove-Integration-Tag {
+ param(
+ [PSCustomObject] $Assets
+ )
+
+ # This can happen if the test failed prior to the push happening
+ if ($null -eq $Assets) {
+ Write-Host "Remove-Integration-Tag - Assets was null, nothing to clean up."
+ return
+ }
+ # If cleanup is disabled, for diagnostics purposes, just return. This is here in case
+ # a test calls this directly
+ if (!([string]::IsNullOrWhitespace($env:DISABLE_INTEGRATION_BRANCH_CLEANUP))) {
+ return
+ }
+
+ $tempPath = "TestDrive:\$([Guid]::NewGuid())\"
+ New-Item -Type Directory -Force -Path $tempPath | Out-Null
+
+ try {
+ Push-Location $tempPath
+ $gitCloneUrl = Get-CloneUrl $Assets.AssetsRepo
+ Write-Host "git clone $($gitCloneUrl) ."
+ git clone $($gitCloneUrl) .
+ Write-Host "git push origin --delete $($Assets.Tag)"
+ git push origin --delete $($Assets.Tag)
+ }
+ catch {
+ Write-Error $_
+ }
+ finally {
+ Pop-Location
+ Remove-Item -Force -Recurse $tempPath
+ }
+}
+
+# Used to define any set of file constructs we want. This enables us to
+# roll a target environment to point various GitStore functionalities at.
+# Creates folder under the temp directory (or TestDrive if permanent storage
+# has been disabled) that will be used for testing CLI commands.
+Function Describe-TestFolder {
+ param(
+ [PSCustomObject] $AssetsJsonContent,
+ [string[]] $Files = @(),
+ [bool] $IsPushTest = $false
+ )
+
+ $testGuid = [Guid]::NewGuid()
+ $testPath = Get-TestPath $testGuid
+ # Initialize-Integration-Tag only needs to be called when running a push test
+ if ($IsPushTest) {
+ $adjustedAssetsRepoTag = "test_$($testGuid)_$($AssetsJsonContent.TagPrefix)"
+ Initialize-Integration-Tag -Assets $AssetsJsonContent -AdjustedAssetsRepoTag $adjustedAssetsRepoTag
+ $AssetsJsonContent.TagPrefix = $adjustedAssetsRepoTag
+ }
+
+ "test content" | Set-Content -Path (Join-Path $testPath ".git")
+ $assetJsonLocation = Join-Path $testPath "assets.json"
+
+ # if a path ending with assets.json is provided, the assets.json content will be written there
+ # instead of the root of the test folder
+ foreach ($file in $files) {
+ if ($file.ToLower().EndsWith("assets.json")) {
+
+ $assetJsonLocation = Join-Path $testPath $file
+
+ $directory = Split-Path $assetJsonLocation
+
+ if (-not (Test-Path $directory)) {
+ New-Item -Type Directory -Force -Path $directory | Out-Null
+ }
+ }
+ }
+
+ # write the content
+ if ($AssetsJsonContent) {
+ $AssetsJsonContent | ConvertTo-Json | Set-Content -Path $assetJsonLocation | Out-Null
+ }
+
+ # generate some fake files and folders
+ foreach ($file in $Files) {
+ $ext = [System.IO.Path]::GetExtension($file)
+ $resolvedFilePath = (Join-Path $testPath $file)
+
+ if ($ext) {
+ if ($ext -eq ".json" -and -not $file.EndsWith("assets.json")) {
+ $directory = Split-Path $resolvedFilePath
+
+ if (-not (Test-Path $directory)) {
+ New-Item -Type Directory -Force -Path $directory | Out-Null
+ }
+
+ $testObj = [PSCustomObject]@{
+ a = [guid]::NewGuid().ToString()
+ } | ConvertTo-Json
+
+ New-Item -Path $resolvedFilePath -ItemType File -Value $testObj | Out-Null
+ }
+ }
+ else {
+ if (-not (Test-Path $file)) {
+ New-Item -Type Directory -Force -Path $file | Out-Null
+ }
+ }
+ }
+ return $testPath
+}
+
+# Cleanup the test folder used for testing. The DISABLE_INTEGRATION_BRANCH_CLEANUP
+# environment variable will allow us to keep things around for investigations.
+Function Remove-Test-Folder {
+ param(
+ [string] $TestFolder = ""
+ )
+ if (![string]::IsNullOrWhitespace($env:DISABLE_INTEGRATION_BRANCH_CLEANUP)) {
+ return
+ }
+
+ if ($null -ne $TestFolder) {
+ Remove-Item -LiteralPath $TestFolder -Force -Recurse
+ }
+}
+
+# Invoke the proxy command and echo the output. The WriteOutput
+# is used to output a command response when executing Reset commands.
+# When Reset detects pending changes it'll prompt to override. This
+# works because there's a single response required.
+Function Invoke-ProxyCommand {
+ param(
+ [string] $TestProxyExe,
+ [string] $CommandArgs,
+ [string] $WriteOutput = $null
+ )
+
+ Write-Host "$TestProxyExe $CommandArgs"
+ # Need to cast the output into an array otherwise it'll be one long string with no newlines
+ if ($WriteOutput) {
+ # CommandArgs needs to be split otherwise all of the arguments will be quoted into a single
+ # argument.
+ [array] $output = Write-Output $WriteOutput | & "$TestProxyExe" $CommandArgs.Split(" ")
+ } else {
+ [array] $output = & "$TestProxyExe" $CommandArgs.Split(" ")
+ }
+ # echo the command output
+ foreach ($line in $output) {
+ Write-Host "$line"
+ }
+}
+
+# The assets directory will either be in the .assets directory, in the same
+# directory as the assets.json file OR the PROXY_ASSETS_FOLDER. Now, in order
+# to not have a ridiculous subdirectory length, the proxy creates a 10 character
+# short hash directory, instead of having Azure/azure-sdk-assets-integration/
+# , which will be the only sub-directory. From there
+# For testing purposes we know that there will only be single sub-directory under
+# which the directory referenced by the AssetsRepoPrefixPath will contain the files
+# being manipulated by the CLI commands.
+Function Get-AssetsFilePath {
+ param(
+ [PSCustomObject] $AssetsJsonContent,
+ [string] $AssetsJsonFile
+ )
+ $startingPath = $env:PROXY_ASSETS_FOLDER
+ # If the assets folder is not defined then the .assets directory will
+ # be in the same directory that the assets json file is in
+ if ([string]::IsNullOrWhitespace($startingPath)) {
+ $assetsDir = Split-Path -Path $AssetsJsonFile
+ $startingPath = Join-Path -Path $assetsDir -ChildPath ".assets"
+ }
+ # It's odd that $folder.Count and $folders.Lenght work and we need to do this
+ $numDirs = Get-ChildItem $startingPath -Directory | Measure-Object | ForEach-Object{$_.Count}
+ $folders = Get-ChildItem $startingPath -Directory
+ # There should only be one folder
+ if (1 -ne $numDirs) {
+ LogError "The assets directory ($startingPath) should only contain 1 subfolder not $numDirs ($folders -join $([Environment]::NewLine))"
+ return $assetsFilePath
+ }
+ $assetsFilePath = Join-Path -Path $folders[0].FullName -ChildPath $AssetsJsonContent.AssetsRepoPrefixPath
+ return $assetsFilePath
+}
+
+
+# Given a directory and an expected number of files, verify that we only have that many files.
+Function Test-DirectoryFileCount {
+ param(
+ [string] $Directory,
+ [int] $ExpectedNumberOfFiles
+ )
+ $numFiles = Get-ChildItem $Directory -File | Measure-Object | ForEach-Object{$_.Count}
+ $ExpectedNumberOfFiles | Should -Be $numFiles
+}
+
+# For testing purposes file versions are a single number within the file. Verify that
+# the version in the file is the one we expect.
+Function Test-FileVersion {
+ param(
+ [string] $FilePath,
+ [string] $FileName,
+ [int] $ExpectedVersion
+ )
+ $fileFullPath = Join-Path -Path $FilePath -ChildPath $FileName
+ $actualVersion = Get-Content -Path $fileFullPath -TotalCount 1
+ $actualVersion | Should -Be $ExpectedVersion
+}
+
+# This will create a new file that contains the input version number or
+# update an existing file to the input version number
+Function Edit-FileVersion {
+ param(
+ [string] $FilePath,
+ [string] $FileName,
+ [int] $Version
+ )
+ # this will create the file if it doesn't exist and set the version if it does
+ $fileFullPath = Join-Path -Path $FilePath -ChildPath $FileName
+ $Version | Out-File $fileFullPath
+}
+
+# Given an assets.json file on disk, create a PSCustomObject from that Json file.
+Function Update-AssetsFromFile {
+ param(
+ [string] $AssetsJsonContent
+ )
+ return [PSCustomObject](Get-Content $AssetsJsonContent | Out-String | ConvertFrom-Json)
+}
+
+# Verify that a given tag exists.
+Function Test-TagExists{
+ param(
+ [PSCustomObject] $AssetsJsonContent,
+ [string] $WorkingDirectory
+ )
+ $tagExists = $false
+ try {
+ Push-Location $WorkingDirectory
+ $gitCloneUrl = Get-CloneUrl $AssetsJsonContent.AssetsRepo
+ Write-Host "git ls-remote --heads $($gitCloneUrl) $($AssetsJsonContent.Tag)"
+ $stdOut = git ls-remote --heads $($gitCloneUrl) $($AssetsJsonContent.Tag) | Out-String
+ if ([string]::IsNullOrWhitespace($stdOut)) {
+ $tagExists = $true
+ } else {
+ Write-Host "Test-TagExists git ls-remote --heads $($gitCloneUrl) $($AssetsJsonContent.Tag) returned:=$stdOut"
+ }
+ } finally {
+ Pop-Location
+ }
+ return $tagExists
+}
\ No newline at end of file
diff --git a/tools/test-proxy/tests.yml b/tools/test-proxy/tests.yml
index 9ff6abb1661..23028be48c5 100644
--- a/tools/test-proxy/tests.yml
+++ b/tools/test-proxy/tests.yml
@@ -7,7 +7,7 @@ stages:
- stage: IntegrationTests
displayName: "Asset Sync Integration Tests"
jobs:
- - job: Integration_Test
+ - job: Solution_Integration_Test
strategy:
matrix:
@@ -48,6 +48,43 @@ stages:
testResultsFormat: 'VSTest'
mergeTestResults: true
+ - job: CLI_Integration_Test
+
+ strategy:
+ matrix:
+ Windows:
+ Pool: 'azsdk-pool-mms-win-2019-general'
+ OS: 'Windows'
+ Linux:
+ Pool: 'azsdk-pool-mms-ubuntu-2004-general'
+ OS: 'Linux'
+ Mac:
+ Pool: 'Azure Pipelines'
+ OS: 'Mac'
+
+ pool:
+ name: $(Pool)
+
+ steps:
+ - task: UseDotNet@2
+ displayName: 'Use .NET Core sdk 6.x'
+ inputs:
+ version: '6.x'
+
+ - template: /eng/pipelines/templates/steps/test-proxy-local-tool.yml
+ parameters:
+ runProxy: false
+ rootFolder: $(Build.SourcesDirectory)
+
+ - template: /eng/pipelines/templates/steps/run-pester-tests.yml
+ parameters:
+ TargetTags: "Integration"
+ TargetDirectory: tools/test-proxy/test-scripts/
+ EnvVars:
+ GIT_TOKEN: $(azuresdk-github-pat)
+ GIT_COMMIT_OWNER: azure-sdk
+ GIT_COMMIT_EMAIL: azuresdk@microsoft.com
+
- stage: RepoUnitTests
displayName: Repo-Specific Unit Tests
dependsOn: []