Add state.sqlserver conformance test against Azure SQL (#1182)

* Add Azure SQL to setup-azure-conf-test.sh

* Add state.sqlserver conformance test on Azure SQL

Co-authored-by: Dapr Bot <56698301+dapr-bot@users.noreply.github.com>
This commit is contained in:
Simon Leet 2021-10-06 12:33:50 -07:00 committed by GitHub
parent e457b307b6
commit 9f77037de2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 119 additions and 1 deletions

View File

@ -0,0 +1,25 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation and Dapr Contributors.
// Licensed under the MIT License.
// ------------------------------------------------------------
param sqlServerName string
param rgLocation string = resourceGroup().location
param confTestTags object = {}
param sqlServerAdminPassword string
var sqlServerAdminName = '${sqlServerName}-admin'
resource sqlServer 'Microsoft.Sql/servers@2021-02-01-preview' = {
name: sqlServerName
location: rgLocation
tags: confTestTags
properties: {
administratorLogin: sqlServerAdminName
administratorLoginPassword: sqlServerAdminPassword
minimalTlsVersion: '1.2'
publicNetworkAccess: 'Enabled'
}
}
output sqlServerAdminName string = sqlServer.properties.administratorLogin

View File

@ -33,6 +33,10 @@ param sdkAuthSpId string
@description('Provide the objectId of the Service Principal using cert auth with get and list access to all assets in Azure Key Vault.')
param certAuthSpId string
@minLength(16)
@description('Provide the SQL server admin password of at least 16 characters.')
param sqlServerAdminPassword string
var confTestRgName = '${toLower(namePrefix)}-conf-test-rg'
var cosmosDbName = '${toLower(namePrefix)}-conf-test-db'
var eventGridTopicName = '${toLower(namePrefix)}-conf-test-eventgrid-topic'
@ -40,6 +44,7 @@ var eventHubsNamespaceName = '${toLower(namePrefix)}-conf-test-eventhubs'
var iotHubName = '${toLower(namePrefix)}-conf-test-iothub'
var keyVaultName = '${toLower(namePrefix)}-conf-test-kv'
var serviceBusName = '${toLower(namePrefix)}-conf-test-servicebus'
var sqlServerName = '${toLower(namePrefix)}-conf-test-sql'
var storageName = '${toLower(namePrefix)}ctstorage'
resource confTestRg 'Microsoft.Resources/resourceGroups@2021-04-01' = {
@ -105,6 +110,16 @@ module serviceBus 'conf-test-azure-servicebus.bicep' = {
}
}
module sqlServer 'conf-test-azure-sqlserver.bicep' = {
name: sqlServerName
scope: resourceGroup(confTestRg.name)
params: {
confTestTags: confTestTags
sqlServerName: sqlServerName
sqlServerAdminPassword: sqlServerAdminPassword
}
}
module storage 'conf-test-azure-storage.bicep' = {
name: storageName
scope: resourceGroup(confTestRg.name)
@ -131,4 +146,6 @@ output iotHubBindingsConsumerGroupName string = iotHub.outputs.iotHubBindingsCon
output iotHubPubsubConsumerGroupName string = iotHub.outputs.iotHubPubsubConsumerGroupName
output keyVaultName string = keyVault.name
output serviceBusName string = serviceBus.name
output sqlServerName string = sqlServer.name
output sqlServerAdminName string = sqlServer.outputs.sqlServerAdminName
output storageName string = storage.name

View File

@ -184,8 +184,13 @@ KEYVAULT_CLIENT_ID_VAR_NAME="AzureKeyVaultSecretStoreClientId"
KEYVAULT_TENANT_ID_VAR_NAME="AzureKeyVaultSecretStoreTenantId"
KEYVAULT_NAME_VAR_NAME="AzureKeyVaultName"
RESOURCE_GROUP_NAME_VAR_NAME="AzureResourceGroupName"
SERVICE_BUS_CONNECTION_STRING_VAR_NAME="AzureServiceBusConnectionString"
SQL_SERVER_NAME_VAR_NAME="AzureSqlServerName"
SQL_SERVER_CONNECTION_STRING_VAR_NAME="AzureSqlServerConnectionString"
STORAGE_ACCESS_KEY_VAR_NAME="AzureBlobStorageAccessKey"
STORAGE_ACCOUNT_VAR_NAME="AzureBlobStorageAccount"
STORAGE_CONTAINER_VAR_NAME="AzureBlobStorageContainer"
@ -231,6 +236,9 @@ else
echo "${SDK_AUTH_SP_INFO}" > "${AZURE_CREDENTIALS_FILENAME}"
fi
# Generate new password for SQL Server admin
SQL_SERVER_ADMIN_PASSWORD=$(openssl rand -base64 32)
# Build the bicep template and deploy to Azure
az bicep install
ARM_TEMPLATE_FILE="${OUTPUT_PATH}/${PREFIX}-azure-conf-test.json"
@ -238,7 +246,7 @@ echo "Building conf-test-azure.bicep to ${ARM_TEMPLATE_FILE} ..."
az bicep build --file conf-test-azure.bicep --outfile "${ARM_TEMPLATE_FILE}"
echo "Creating azure deployment ${DEPLOY_NAME} in ${DEPLOY_LOCATION} and resource prefix ${PREFIX}-* ..."
az deployment sub create --name "${DEPLOY_NAME}" --location "${DEPLOY_LOCATION}" --template-file "${ARM_TEMPLATE_FILE}" -p namePrefix="${PREFIX}" -p adminId="${ADMIN_ID}" -p certAuthSpId="${CERT_AUTH_SP_ID}" -p sdkAuthSpId="${SDK_AUTH_SP_ID}" -p rgLocation="${DEPLOY_LOCATION}"
az deployment sub create --name "${DEPLOY_NAME}" --location "${DEPLOY_LOCATION}" --template-file "${ARM_TEMPLATE_FILE}" -p namePrefix="${PREFIX}" -p adminId="${ADMIN_ID}" -p certAuthSpId="${CERT_AUTH_SP_ID}" -p sdkAuthSpId="${SDK_AUTH_SP_ID}" -p rgLocation="${DEPLOY_LOCATION}" -p sqlServerAdminPassword="${SQL_SERVER_ADMIN_PASSWORD}"
echo "Sleeping for 5s to allow created ARM deployment info to propagate to query endpoints ..."
sleep 5s
@ -281,6 +289,10 @@ IOT_HUB_BINDINGS_CONSUMER_GROUP_FULLNAME="$(az deployment sub show --name "${DEP
echo "INFO: IOT_HUB_BINDINGS_CONSUMER_GROUP_FULLNAME=${IOT_HUB_BINDINGS_CONSUMER_GROUP_FULLNAME}"
IOT_HUB_PUBSUB_CONSUMER_GROUP_FULLNAME="$(az deployment sub show --name "${DEPLOY_NAME}" --query "properties.outputs.iotHubPubsubConsumerGroupName.value" | sed -E 's/[[:space:]]|\"//g')"
echo "INFO: IOT_HUB_PUBSUB_CONSUMER_GROUP_FULLNAME=${IOT_HUB_PUBSUB_CONSUMER_GROUP_FULLNAME}"
SQL_SERVER_NAME="$(az deployment sub show --name "${DEPLOY_NAME}" --query "properties.outputs.sqlServerName.value" | sed -E 's/[[:space:]]|\"//g')"
echo "INFO: SQL_SERVER_NAME=${SQL_SERVER_NAME}"
SQL_SERVER_ADMIN_NAME="$(az deployment sub show --name "${DEPLOY_NAME}" --query "properties.outputs.sqlServerAdminName.value" | sed -E 's/[[:space:]]|\"//g')"
echo "INFO: SQL_SERVER_ADMIN_NAME=${SQL_SERVER_ADMIN_NAME}"
# Update service principal credentials and roles for created resources
echo "Creating ${CERT_AUTH_SP_NAME} certificate ..."
@ -297,6 +309,11 @@ IOT_HUB_SCOPE="/subscriptions/${SUB_ID}/resourceGroups/${RESOURCE_GROUP_NAME}/pr
echo "Assigning \"Contributor\" role to ${SDK_AUTH_SP_NAME} in scope \"${IOT_HUB_SCOPE}\"..."
MSYS_NO_PATHCONV=1 az role assignment create --assignee "${SDK_AUTH_SP_ID}" --role "Contributor" --scope "${IOT_HUB_SCOPE}"
# Add SQL Server Contributor role to the SDK auth Service Principal so it can update firewall rules to run sqlserver state conformance tests.
SQL_SERVER_SCOPE="/subscriptions/${SUB_ID}/resourceGroups/${RESOURCE_GROUP_NAME}/providers/Microsoft.Sql/servers/${SQL_SERVER_NAME}"
echo "Assigning \"Contributor\" role to ${SDK_AUTH_SP_NAME} in scope \"${SQL_SERVER_SCOPE}\"..."
MSYS_NO_PATHCONV=1 az role assignment create --assignee "${SDK_AUTH_SP_ID}" --role "Contributor" --scope "${SQL_SERVER_SCOPE}"
##==============================================================================
##
## Create output files for environment config and teardown of conformance tests
@ -466,6 +483,23 @@ SERVICE_BUS_CONNECTION_STRING="$(az servicebus namespace authorization-rule keys
echo export ${SERVICE_BUS_CONNECTION_STRING_VAR_NAME}=\"${SERVICE_BUS_CONNECTION_STRING}\" >> "${ENV_CONFIG_FILENAME}"
az keyvault secret set --name "${SERVICE_BUS_CONNECTION_STRING_VAR_NAME}" --vault-name "${KEYVAULT_NAME}" --value "${SERVICE_BUS_CONNECTION_STRING}"
# ----------------------------------
# Populate SQL Server test settings
# ----------------------------------
echo "Configuring SQL Server test settings ..."
# Not specific to SQL server, but this is currently only consumed by setting SQL server firewall rules
echo export ${RESOURCE_GROUP_NAME_VAR_NAME}=\"${RESOURCE_GROUP_NAME}\" >> "${ENV_CONFIG_FILENAME}"
az keyvault secret set --name "${RESOURCE_GROUP_NAME_VAR_NAME}" --vault-name "${KEYVAULT_NAME}" --value "${RESOURCE_GROUP_NAME}"
echo export ${SQL_SERVER_NAME_VAR_NAME}=\"${SQL_SERVER_NAME}\" >> "${ENV_CONFIG_FILENAME}"
az keyvault secret set --name "${SQL_SERVER_NAME_VAR_NAME}" --vault-name "${KEYVAULT_NAME}" --value "${SQL_SERVER_NAME}"
# Note that `az sql db show-connection-string` does not currently support a `go` --client type, so we construct our own here.
SQL_SERVER_CONNECTION_STRING="Server=${SQL_SERVER_NAME}.database.windows.net;port=1433;User ID=${SQL_SERVER_ADMIN_NAME};Password=${SQL_SERVER_ADMIN_PASSWORD};Encrypt=true;"
echo export ${SQL_SERVER_CONNECTION_STRING_VAR_NAME}=\"${SQL_SERVER_CONNECTION_STRING}\" >> "${ENV_CONFIG_FILENAME}"
az keyvault secret set --name "${SQL_SERVER_CONNECTION_STRING_VAR_NAME}" --vault-name "${KEYVAULT_NAME}" --value "${SQL_SERVER_CONNECTION_STRING}"
# ----------------------------------
# Populate Event Hubs test settings
# ----------------------------------

View File

@ -93,6 +93,8 @@ jobs:
CRON_COMPONENTS=$(yq -I0 --tojson eval - << EOF
- component: state.azure.cosmosdb
required-secrets: AzureCosmosDBMasterKey,AzureCosmosDBUrl,AzureCosmosDB,AzureCosmosDBCollection
- component: state.azure.sql
required-secrets: AzureResourceGroupName, AzureSqlServerName, AzureSqlServerConnectionString
- component: state.azure.tablestorage
required-secrets: AzureBlobStorageAccessKey,AzureBlobStorageAccount
- component: pubsub.azure.eventhubs
@ -269,6 +271,18 @@ jobs:
go mod download
go install gotest.tools/gotestsum@latest
- name: Configure Azure SQL Firewall
run: |
set +e
TEST_OUTPUT="$(go test -v -tags=conftests -count=1 -timeout=1m ./tests/conformance -run=TestStateConformance/azure.sql)"
echo "Trial run result:\n\"$TEST_OUTPUT\""
PUBLIC_IP=$(echo "$TEST_OUTPUT" | grep -Po "Client with IP address '\K[^']*")
if [[ -n ${PUBLIC_IP} ]]; then
echo "Setting Azure SQL firewall-rule AllowTestRunnerIP to allow $PUBLIC_IP..."
az sql server firewall-rule create --resource-group ${{ env.AzureResourceGroupName }} --server ${{ env.AzureSqlServerName }} -n "AllowTestRunnerIP" --start-ip-address "$PUBLIC_IP" --end-ip-address "$PUBLIC_IP"
fi
if: contains(matrix.component, 'azure.sql')
- name: Run tests
continue-on-error: true
run: |
@ -307,6 +321,13 @@ jobs:
continue-on-error: true
run: pkill ngrok; cat /tmp/ngrok.log
- name: Cleanup Azure SQL Firewall and test DB instance
if: contains(matrix.component, 'azure.sql')
continue-on-error: true
run: |
az sql server firewall-rule delete --resource-group ${{ env.AzureResourceGroupName }} --server ${{ env.AzureSqlServerName }} -n "AllowTestRunnerIP"
az sql db delete --resource-group ${{ env.AzureResourceGroupName }} --server ${{ env.AzureSqlServerName }} -n dapr --yes
# Download the required certificates into files, and set env var pointing to their names
- name: Clean up certs
if: matrix.required-certs != ''

View File

@ -0,0 +1,17 @@
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.sqlserver
metadata:
- name: connectionString
value: ${{AzureSqlServerConnectionString}}
- name: tableName
value: dapr_conf_test
- name: keyType
value: string
- name: keyLength
value: 120
- name: schema
value: proto

View File

@ -7,6 +7,8 @@ components:
allOperations: true
- component: azure.cosmosdb
allOperations: true
- component: azure.sql
allOperations: true
- component: sqlserver
allOperations: true
- component: mysql

View File

@ -374,6 +374,8 @@ func loadStateStore(tc TestComponent) state.Store {
store = s_cosmosdb.NewCosmosDBStateStore(testLogger)
case "mongodb":
store = s_mongodb.NewMongoDB(testLogger)
case "azure.sql":
fallthrough
case "sqlserver":
store = s_sqlserver.NewSQLServerStateStore(testLogger)
case "mysql":