Shuvajyoti/Load Test Infrastructure (#5)

* Adding Create Infra script empty file

* Script to create AKS cluster

* Adding pipeline for load test infra setup

* Correcting File Path

* Adding task to fetch secret from keyvault

* Adding tenant as a variable

* Wrapping region

* Adding scripts to trigger load tests from user local machines.

* Using camelcase for script parameters

* Removing unused statements

* Variables are not needed in repo, they will be supplied while running pipeline

* Secret parameter updated

* Standardizing secret name

* Adding delete infrastructure scripts

* Addressing PR Comments
This commit is contained in:
Shuvajyoti Deb 2021-08-20 14:36:24 +05:30 коммит произвёл GitHub
Родитель dca1b50ac5
Коммит 302e2dbd40
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
7 изменённых файлов: 290 добавлений и 0 удалений

4
.gitignore поставляемый
Просмотреть файл

@ -53,6 +53,10 @@ nunit-*.xml
[Rr]eleasePS/
dlldata.c
#LoadTestResults
report/
Reports/
# Benchmark Results
BenchmarkDotNet.Artifacts/

Просмотреть файл

@ -0,0 +1,47 @@
param(
[Parameter(Mandatory = $True)]
[string]$tenant,
[Parameter(Mandatory = $True)]
[string]$defaultNamespace,
[Parameter(Mandatory = $True)]
[string]$resourceGroup,
[Parameter(Mandatory = $True)]
[string]$aksClusterName,
[Parameter(Mandatory = $True)]
[string]$spnClientId,
[Parameter(Mandatory = $True)]
[string]$spnClientSecret,
[Parameter(Mandatory = $True)]
[string]$aksRegion,
[Parameter(Mandatory = $False)]
[string]$nodeVmSize = "Standard_D2s_v3"
)
function log([string] $message, [string] $color) {
Write-Host "$(get-date) $message" -ForegroundColor $color
Write-Host " "
}
#################### Creating AKS Cluster ################################################
try {
log "############# Installing Extension : aks-preview ###############" "DarkYellow"
az extension add --name aks-preview
az login --service-principal --username $spnClientId --password $spnClientSecret --tenant $tenant
log "############# AKS Cluster Name : $($aksClusterName) ###############" "DarkMagenta"
log "############# Creating AKS Cluster ###############" "DarkYellow"
az aks create --resource-group $resourceGroup --name $aksClusterName --node-vm-size $nodeVmSize --location $aksRegion --service-principal $spnClientId --client-secret $spnClientSecret --node-count 3 --min-count 1 --max-count 50 --enable-cluster-autoscaler --enable-aad --enable-azure-rbac --generate-ssh-keys
log "############# AKS Cluster creation completed ###############" "DarkGreen"
log "############# Getting cluster credentials #############" "DarkYellow"
az aks get-credentials --name $aksClusterName --resource-group $resourceGroup --admin
log "############# Creating AKS Namespace #############" "DarkYellow"
kubectl create namespace $defaultNamespace
}
catch {
Write-Error "An error occurred while creating Load Test Infrastructure"
Write-Host $_.ScriptStackTrace
}

Просмотреть файл

@ -0,0 +1,42 @@
param(
[Parameter(Mandatory = $True)]
[string]$aksClusterName,
[Parameter(Mandatory = $True)]
[string]$resourceGroup,
[Parameter(Mandatory = $True)]
[string]$spnClientId,
[Parameter(Mandatory = $True)]
[string]$spnClientSecret,
[Parameter(Mandatory = $True)]
[string]$tenant
)
Set-StrictMode -Version latest
$ErrorActionPreference = "Stop"
function log([string] $message, [string] $color) {
Write-Host "$(get-date) $message" -ForegroundColor $color
Write-Host " "
}
try {
if ($(az account list).contains("[]")) {
Exit-PSSession
}
az login --service-principal --username $spnClientId --password $spnClientSecret --tenant $tenant
log "########### Deleting AKS Instance ###########" "DarkYellow"
az aks delete --name $aksClusterName --resource-group $resourceGroup -y
log "############# AKS Instance deleted ###############" "DarkGreen"
log "########### Removing local auth ###########" "DarkYellow"
kubectl config use-context docker-desktop
kubectl config delete-context $aksClusterName
kubectl config delete-cluster $aksClusterName
kubectl config unset "users.clusterUser_$($aksClusterName)_$($aksClusterName)"
}
catch {
Write-Error "An error occurred while deleting Load Test Infrastructure"
Write-Host $_.ScriptStackTrace
}

Просмотреть файл

@ -0,0 +1,32 @@
pool:
vmImage: "windows-latest"
trigger: none
# variables:
# DefaultNamespace: ""
# AksClusterName: ""
# ResourceGroup: ""
# ServicePrincipalId: ""
# AksRegion: ""
# NodeVmSize: ""
# ServiceConnection: ""
# KeyVaultName: ""
# SecretNames: ""
# Tenant: ""
steps:
- task: AzureKeyVault@1
displayName: Get Keyvault Secrets
inputs:
azureSubscription: $(ServiceConnection)
KeyVaultName: $(KeyVaultName)
SecretsFilter: $(SecretName)
RunAsPreJob: true
- task: PowerShell@2
displayName: "Create AKS Cluster"
inputs:
targetType: filePath
filePath: "./JMeterAKSPipeline/CreateLoadTestInfrastructure.ps1"
arguments: "-tenant $(Tenant) -defaultNamespace $(DefaultNamespace) -resourceGroup $(ResourceGroup) -aksClusterName $(AksClusterName) -spnClientId $(ServicePrincipalId) -spnClientSecret $(AKSSPNClientSecret) -aksRegion $(AksRegion) -nodeVmSize $(NodeVmSize)"

Просмотреть файл

@ -0,0 +1,43 @@
param(
[Parameter(Mandatory = $True)]
[string]$namespace,
[Parameter(Mandatory = $False)]
[int]$agentCount = 1
)
Set-StrictMode -Version latest
$ErrorActionPreference = "Stop"
function log([string] $message, [string] $color) {
Write-Host "$(get-date) $message" -ForegroundColor $color
Write-Host " "
}
try {
$PathToManifestFolder = Join-Path -Path (Split-Path $(Get-Location) -Parent) -ChildPath "jmeter-kubernetes-setup"
#################### Creating JMeter Master and Slave pods ################################################
log "############## Creating JMeter Slave ##############" "DarkYellow"
kubectl -n $namespace apply -f $(Join-Path -Path $PathToManifestFolder -ChildPath "jmeter_slaves_deploy.yaml")
kubectl -n $namespace apply -f $(Join-Path -Path $PathToManifestFolder -ChildPath "jmeter_slaves_svc.yaml")
log "############## JMeter Slave deployment completed ##############" "DarkGreen"
log "############## Creating JMeter Master ##############" "DarkYellow"
kubectl -n $namespace apply -f $(Join-Path -Path $PathToManifestFolder -ChildPath "jmeter_master_configmap.yaml")
kubectl -n $namespace apply -f $(Join-Path -Path $PathToManifestFolder -ChildPath "jmeter_master_deploy.yaml")
log "############## JMeter Master deployment completed ##############" "DarkGreen"
if ($agentCount -gt 1) {
log "############## Creating $agentCount replicas of JMeter Slave ##############" "DarkYellow"
kubectl scale -n $namespace --replicas=$agentCount deployment/jmeter-slaves
}
log "############## Total number of Slave pods running the tests $agentCount ##############" "DarkYellow"
kubectl -n $namespace rollout status deployment jmeter-master
kubectl -n $namespace rollout status deployment jmeter-slaves
}
catch {
Write-Error "An error occurred while creating JMeter cluster"
Write-Host $_.ScriptStackTrace
}

Просмотреть файл

@ -0,0 +1,26 @@
param(
[Parameter(Mandatory = $True)]
[string]$namespace
)
Set-StrictMode -Version latest
$ErrorActionPreference = "Stop"
function log([string] $message, [string] $color) {
Write-Host "$(get-date) $message" -ForegroundColor $color
Write-Host " "
}
try {
$PathToManifestFolder = Join-Path -Path (Split-Path $(Get-Location) -Parent) -ChildPath "jmeter-kubernetes-setup"
log "############## Removing JMeter Master and Slave pods ##############" "DarkYellow"
kubectl -n $namespace delete -f $(Join-Path -Path $PathToManifestFolder -ChildPath "jmeter_master_deploy.yaml") --wait=true
kubectl -n $namespace delete -f $(Join-Path -Path $PathToManifestFolder -ChildPath "jmeter_slaves_deploy.yaml") --wait=true
kubectl -n $namespace wait --for=delete pods --selector=jmeter_mode=master --timeout=60s
kubectl -n $namespace wait --for=delete pods --selector=jmeter_mode=slave --timeout=60s
}
catch {
Write-Error "An error occurred while deleting JMeter cluster"
Write-Host $_.ScriptStackTrace
}

96
Scripts/Run-Test.ps1 Normal file
Просмотреть файл

@ -0,0 +1,96 @@
param(
[Parameter(Mandatory = $False)]
[string]$namespace = "",
# Complete path of test
[Parameter(Mandatory = $True)]
[string]$testPath,
[Parameter(Mandatory = $True)]
[string]$resourceGroup,
[Parameter(Mandatory = $True)]
[string]$aksClusterName,
# Relative Path to Script Folder
[Parameter(Mandatory = $False)]
[string]$reportFolder = "Reports",
# Add more than 1 instances
[Parameter(Mandatory = $False)]
[int]$agentCount = 1,
[Parameter(Mandatory = $False)]
[bool]$deleteJMeterCluster = $True,
[Parameter(HelpMessage = "Change this to true if you want to keep the namespace intact. Otherwise the namespace will be deleted after the test")]
[bool]$retainNamespace = $False
)
Set-StrictMode -Version latest
$ErrorActionPreference = "Stop"
function log([string] $message, [string] $color) {
Write-Host "$(get-date) $message" -ForegroundColor $color
Write-Host " "
}
$SlavePods = ''
$folderName = "report_" + (Get-Date).tostring("dd-MM-yyyy-hh-mm-ss")
$root = $PSScriptRoot
try {
log "############## Test Execution Started ##############" "DarkCyan"
log "############## Getting Cluster Credentials ##############" "DarkCyan"
az aks get-credentials --name $aksClusterName --resource-group $resourceGroup --admin
if ($namespace -eq '') {
log "############## Namespace not specified so creating new namespace ##############" "DarkCyan"
$chars = [char[]]"abcdefghijklmnopqrstuvwxyz0123456789"
$randomString = [string](($chars | Get-Random -Count 5) -join "")
$namespace = 'jmeter' + "-" + $randomString
kubectl create namespace $namespace
log "############## Created Namespace - $($namespace) ##############" "DarkCyan"
}
$IsEligibleUser = $(kubectl auth can-i create deployments --namespace $namespace)
if ($IsEligibleUser -ne 'yes') {
Write-Error "############## Cannot Continue Test Execution, get contributor access on cluster ##############"
exit
}
Invoke-Expression "& '$root\Create-Jmeter-Cluster.ps1' -namespace $namespace -agentCount $agentCount"
if ($null -eq $(kubectl -n $namespace get pods --selector=jmeter_mode=master --no-headers=true --output=name) ) {
Write-Error "Master pod does not exist"
exit
}
$MasterPod = $(kubectl -n $namespace get pods --selector=jmeter_mode=master --no-headers=true --output=name).Replace("pod/", "")
$TestName = Split-Path $testPath -Leaf
log "############## Copying test plan $TestName to controller pod ##############" "DarkYellow"
kubectl cp $testPath $namespace/${MasterPod}:/$TestName
$SlavePods = $(kubectl -n $namespace get pods --selector=jmeter_mode=slave --no-headers=true --output=name)
$SlavePod = ""
log "############## Executing test ##############" "DarkYellow"
kubectl -n $namespace exec $MasterPod -- /bin/bash /load_test "$TestName"
log "############## Retrieving dashboard and results to : $($root + '\' + $reportFolder + '\' + $folderName) ##############" "Green"
kubectl cp $namespace/${MasterPod}:/report $reportFolder/$folderName
foreach ($SlavePod in $SlavePods) {
$SlavePod = $SlavePod -replace 'pod/', ''
kubectl cp -n $namespace ${SlavePod}:jmeter-server.log $reportFolder/$folderName/jmeter-server-$SlavePod.log
}
}
catch {
Write-Error "An error occurred while running Load Test"
Write-Host $_.ScriptStackTrace
}
finally {
if ($deleteJMeterCluster) {
Invoke-Expression "& '$root\Delete-Jmeter-Cluster.ps1' -namespace $namespace"
}
if (!($retainNamespace)) {
log "############## Deleting namespace $namespace ##############" "DarkCyan"
kubectl delete namespace $namespace
}
log "############## Test Execution Ends ##############" "DarkCyan"
}