powershell/resources/psruntime/BuildTime/Cmdlets/ExportTestStub.cs (149 lines of code) (raw):
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
using System;
using System.IO;
using System.Linq;
using System.Management.Automation;
using System.Text;
using static Microsoft.Rest.ClientRuntime.PowerShell.PsProxyOutputExtensions;
using static Microsoft.Rest.ClientRuntime.PowerShell.PsHelpers;
namespace Microsoft.Rest.ClientRuntime.PowerShell
{
[Cmdlet(VerbsData.Export, "TestStub")]
[DoNotExport]
public class ExportTestStub : PSCmdlet
{
[Parameter(Mandatory = true)]
[ValidateNotNullOrEmpty]
public string ModuleName { get; set; }
[Parameter(Mandatory = true)]
[ValidateNotNullOrEmpty]
public string ExportsFolder { get; set; }
[Parameter(Mandatory = true)]
[ValidateNotNullOrEmpty]
public string OutputFolder { get; set; }
[Parameter]
public SwitchParameter IncludeGenerated { get; set; }
protected override void ProcessRecord()
{
try
{
if (!Directory.Exists(ExportsFolder))
{
throw new ArgumentException($"Exports folder '{ExportsFolder}' does not exist");
}
var exportDirectories = Directory.GetDirectories(ExportsFolder);
if (!exportDirectories.Any())
{
exportDirectories = new[] { ExportsFolder };
}
/*var loadEnvFile = Path.Combine(OutputFolder, "loadEnv.ps1");
if (!File.Exists(loadEnvFile))
{
var sc = new StringBuilder();
sc.AppendLine(@"
$envFile = 'env.json'
if ($TestMode -eq 'live') {
$envFile = 'localEnv.json'
}
if (Test-Path -Path (Join-Path $PSScriptRoot $envFile)) {
$envFilePath = Join-Path $PSScriptRoot $envFile
} else {
$envFilePath = Join-Path $PSScriptRoot '..\$envFile'
}
$env = @{}
if (Test-Path -Path $envFilePath) {
$env = Get-Content (Join-Path $PSScriptRoot $envFile) | ConvertFrom-Json
}");
File.WriteAllText(loadEnvFile, sc.ToString());
}*/
var utilFile = Path.Combine(OutputFolder, "utils.ps1");
if (!File.Exists(utilFile))
{
var sc = new StringBuilder();
sc.AppendLine(@"function RandomString([bool]$allChars, [int32]$len) {
if ($allChars) {
return -join ((33..126) | Get-Random -Count $len | % {[char]$_})
} else {
return -join ((48..57) + (97..122) | Get-Random -Count $len | % {[char]$_})
}
}
function Start-TestSleep {
[CmdletBinding(DefaultParameterSetName = 'SleepBySeconds')]
param(
[parameter(Mandatory = $true, Position = 0, ParameterSetName = 'SleepBySeconds')]
[ValidateRange(0.0, 2147483.0)]
[double] $Seconds,
[parameter(Mandatory = $true, ParameterSetName = 'SleepByMilliseconds')]
[ValidateRange('NonNegative')]
[Alias('ms')]
[int] $Milliseconds
)
if ($TestMode -ne 'playback') {
switch ($PSCmdlet.ParameterSetName) {
'SleepBySeconds' {
Start-Sleep -Seconds $Seconds
}
'SleepByMilliseconds' {
Start-Sleep -Milliseconds $Milliseconds
}
}
}
}
$env = @{}
if ($UsePreviousConfigForRecord) {
$previousEnv = Get-Content (Join-Path $PSScriptRoot 'env.json') | ConvertFrom-Json
$previousEnv.psobject.properties | Foreach-Object { $env[$_.Name] = $_.Value }
}
# Add script method called AddWithCache to $env, when useCache is set true, it will try to get the value from the $env first.
# example: $val = $env.AddWithCache('key', $val, $true)
$env | Add-Member -Type ScriptMethod -Value { param( [string]$key, [object]$val, [bool]$useCache) if ($this.Contains($key) -and $useCache) { return $this[$key] } else { $this[$key] = $val; return $val } } -Name 'AddWithCache'
function setupEnv() {
# Preload subscriptionId and tenant from context, which will be used in test
# as default. You could change them if needed.
$env.SubscriptionId = (Get-AzContext).Subscription.Id
$env.Tenant = (Get-AzContext).Tenant.Id
# For any resources you created for test, you should add it to $env here.
$envFile = 'env.json'
if ($TestMode -eq 'live') {
$envFile = 'localEnv.json'
}
set-content -Path (Join-Path $PSScriptRoot $envFile) -Value (ConvertTo-Json $env)
}
function cleanupEnv() {
# Clean resources you create for testing
}
");
File.WriteAllText(utilFile, sc.ToString());
}
foreach (var exportDirectory in exportDirectories)
{
var outputFolder = OutputFolder;
if (exportDirectory != ExportsFolder)
{
outputFolder = Path.Combine(OutputFolder, Path.GetFileName(exportDirectory));
Directory.CreateDirectory(outputFolder);
}
var variantGroups = GetScriptCmdlets(exportDirectory)
.SelectMany(fi => fi.ToVariants())
.Where(v => !v.IsDoNotExport)
.GroupBy(v => v.CmdletName)
.Select(vg => new VariantGroup(ModuleName, vg.Key, vg.Select(v => v).ToArray(), outputFolder, isTest: true))
.Where(vtg => !File.Exists(vtg.FilePath) && (IncludeGenerated || !vtg.IsGenerated));
foreach (var variantGroup in variantGroups)
{
var sb = new StringBuilder();
sb.AppendLine($"if(($null -eq $TestName) -or ($TestName -contains '{variantGroup.CmdletName}'))");
sb.AppendLine(@"{
$loadEnvPath = Join-Path $PSScriptRoot 'loadEnv.ps1'
if (-Not (Test-Path -Path $loadEnvPath)) {
$loadEnvPath = Join-Path $PSScriptRoot '..\loadEnv.ps1'
}
. ($loadEnvPath)"
);
sb.AppendLine($@" $TestRecordingFile = Join-Path $PSScriptRoot '{variantGroup.CmdletName}.Recording.json'");
sb.AppendLine(@" $currentPath = $PSScriptRoot
while(-not $mockingPath) {
$mockingPath = Get-ChildItem -Path $currentPath -Recurse -Include 'HttpPipelineMocking.ps1' -File
$currentPath = Split-Path -Path $currentPath -Parent
}
. ($mockingPath | Select-Object -First 1).FullName
}
");
sb.AppendLine($"Describe '{variantGroup.CmdletName}' {{");
var variants = variantGroup.Variants
.Where(v => IncludeGenerated || !v.Attributes.OfType<GeneratedAttribute>().Any())
.ToList();
foreach (var variant in variants)
{
sb.AppendLine($"{Indent}It '{variant.VariantName}' -skip {{");
sb.AppendLine($"{Indent}{Indent}{{ throw [System.NotImplementedException] }} | Should -Not -Throw");
var variantSeparator = variants.IndexOf(variant) == variants.Count - 1 ? String.Empty : Environment.NewLine;
sb.AppendLine($"{Indent}}}{variantSeparator}");
}
sb.AppendLine("}");
File.WriteAllText(variantGroup.FilePath, sb.ToString());
}
}
}
catch (Exception ee)
{
Console.WriteLine($"${ee.GetType().Name}/{ee.StackTrace}");
throw ee;
}
}
}
}