SQL Server Certification Tests (#1265)
* SQL Server certification test: WIP * Certification tests certifiably certifying * Custom schema * Verify custom schema and indexed properties * docker startup retry backoff * some refactoring * Adds SQL injection testing * linter * Adds SQL Server to certification workflow * Update SQL Server certification README * Add line break at EOF * go mod tidy * Update Readme
This commit is contained in:
parent
daf99fd3c2
commit
d1d5033dd3
|
@ -78,6 +78,8 @@ jobs:
|
|||
- component: secretstores.azure.keyvault
|
||||
required-secrets: AzureKeyVaultName,AzureKeyVaultSecretStoreTenantId,AzureKeyVaultSecretStoreClientId,AzureKeyVaultSecretStoreServicePrincipalClientId,AzureKeyVaultSecretStoreServicePrincipalClientSecret
|
||||
required-certs: AzureKeyVaultSecretStoreCert
|
||||
- component: state.sqlserver
|
||||
required-secrets: AzureSqlServerConnectionString
|
||||
EOF
|
||||
)
|
||||
echo "::set-output name=cloud-components::$CRON_COMPONENTS"
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
# SQL Server certification testing
|
||||
|
||||
This project aims to test the SQL Server State Store component under various conditions.
|
||||
|
||||
## Test plan
|
||||
|
||||
### SQL Injection
|
||||
|
||||
* Not prone to SQL injection on write
|
||||
* Not prone to SQL injection on read
|
||||
* Not prone to SQL injection on delete
|
||||
|
||||
### Indexed Properties
|
||||
|
||||
* Verifies Indices are created for each indexed property in component metadata
|
||||
* Verifies JSON data properties are parsed and written to dedicated database columns
|
||||
|
||||
### Custom Properties
|
||||
|
||||
* Verifies the use of custom tablename (default is states)
|
||||
* Verifies the use of a custom schema (default is dbo)
|
||||
|
||||
### Connection to different SQL Server types
|
||||
|
||||
* Verifies connection handling with Azure SQL Server
|
||||
* Verifies connection handling with SQL Server in Docker to represent self hosted SQL Server options
|
||||
|
||||
### Other tests
|
||||
|
||||
* Client reconnects (if applicable) upon network interruption
|
||||
|
||||
|
||||
### Running the tests
|
||||
|
||||
This must be run in the GitHub Actions Workflow configured for test infrastructure setup.
|
||||
|
||||
If you have access to an Azure subscription you can run this locally on Mac or Linux after running `setup-azure-conf-test.sh` in `.github/infrastructure/conformance/azure` and then sourcing the generated bash rc file.
|
|
@ -0,0 +1,9 @@
|
|||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: envvar-secret-store
|
||||
namespace: default
|
||||
spec:
|
||||
type: secretstores.local.env
|
||||
version: v1
|
||||
metadata:
|
|
@ -0,0 +1,24 @@
|
|||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: dapr-state-store
|
||||
spec:
|
||||
type: state.sqlserver
|
||||
metadata:
|
||||
- name: connectionString
|
||||
secretKeyRef:
|
||||
name: AzureSqlServerConnectionString
|
||||
value: AzureSqlServerConnectionString
|
||||
- name: databaseName
|
||||
value: stablecertification
|
||||
- name: tableName
|
||||
value: dapr_certification_test
|
||||
- name: keyType
|
||||
value: string
|
||||
- name: keyLength
|
||||
value: 120
|
||||
- name: schema
|
||||
value: proto
|
||||
|
||||
auth:
|
||||
secretStore: envvar-secret-store
|
|
@ -0,0 +1,18 @@
|
|||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: dapr-state-store
|
||||
spec:
|
||||
type: state.sqlserver
|
||||
metadata:
|
||||
- name: connectionString
|
||||
value: "server=localhost;user id=sa;password=Pass@Word1;port=1433;Connection Timeout=30;"
|
||||
- name: databaseName
|
||||
value: certificationtest
|
||||
- name: schema
|
||||
value: customschema
|
||||
- name: tableName
|
||||
value: mystates
|
||||
- name: indexedProperties
|
||||
value: '[{"column": "transactionid", "property": "id", "type": "int"}, {"column": "customerid", "property": "customer", "type": "nvarchar(100)"}]'
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Component
|
||||
metadata:
|
||||
name: dapr-state-store
|
||||
spec:
|
||||
type: state.sqlserver
|
||||
metadata:
|
||||
- name: connectionString
|
||||
value: "server=localhost;user id=sa;password=Pass@Word1;port=1433;Connection Timeout=5;"
|
||||
- name: databaseName
|
||||
value: certificationtest
|
|
@ -0,0 +1,6 @@
|
|||
apiVersion: dapr.io/v1alpha1
|
||||
kind: Configuration
|
||||
metadata:
|
||||
name: keyvaultconfig
|
||||
spec:
|
||||
features:
|
|
@ -0,0 +1,9 @@
|
|||
version: "3.7"
|
||||
services:
|
||||
sqlserver:
|
||||
image: mcr.microsoft.com/mssql/server:2019-GA-ubuntu-16.04
|
||||
ports:
|
||||
- "1433:1433"
|
||||
environment:
|
||||
ACCEPT_EULA: Y
|
||||
SA_PASSWORD: "Pass@Word1"
|
|
@ -0,0 +1,110 @@
|
|||
module github.com/dapr/components-contrib/tests/certification/secretstores/azure/keyvault
|
||||
|
||||
go 1.17
|
||||
|
||||
require (
|
||||
github.com/dapr/components-contrib v1.4.0-rc2
|
||||
github.com/dapr/components-contrib/tests/certification v1.4.0-rc2
|
||||
github.com/dapr/dapr v1.4.4-0.20211026235832-5e8d7275a35e
|
||||
github.com/dapr/go-sdk v1.2.1-0.20211017032306-de68193d5cd9
|
||||
github.com/dapr/kit v0.0.2-0.20210614175626-b9074b64d233
|
||||
github.com/stretchr/testify v1.7.0
|
||||
)
|
||||
|
||||
require (
|
||||
contrib.go.opencensus.io/exporter/prometheus v0.2.0 // indirect
|
||||
contrib.go.opencensus.io/exporter/zipkin v0.1.1 // indirect
|
||||
github.com/AdhityaRamadhanus/fasthttpcors v0.0.0-20170121111917-d4c07198763a // indirect
|
||||
github.com/PuerkitoBio/purell v1.1.1 // indirect
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
|
||||
github.com/agrea/ptr v0.0.0-20180711073057-77a518d99b7b // indirect
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
|
||||
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect
|
||||
github.com/andybalholm/brotli v1.0.2 // indirect
|
||||
github.com/antlr/antlr4 v0.0.0-20200503195918-621b933c7a7f // indirect
|
||||
github.com/armon/go-metrics v0.0.0-20190430140413-ec5e00d3c878 // indirect
|
||||
github.com/beorn7/perks v1.0.1 // indirect
|
||||
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.1.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.1.1 // indirect
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/denisenkom/go-mssqldb v0.0.0-20210411162248-d9abbec934ba // indirect
|
||||
github.com/fasthttp/router v1.3.8 // indirect
|
||||
github.com/ghodss/yaml v1.0.0 // indirect
|
||||
github.com/go-logr/logr v0.3.0 // indirect
|
||||
github.com/gogo/protobuf v1.3.2 // indirect
|
||||
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect
|
||||
github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e // indirect
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/google/cel-go v0.7.3 // indirect
|
||||
github.com/google/gofuzz v1.1.0 // indirect
|
||||
github.com/google/uuid v1.2.0 // indirect
|
||||
github.com/googleapis/gnostic v0.5.1 // indirect
|
||||
github.com/grandcat/zeroconf v0.0.0-20190424104450-85eadb44205c // indirect
|
||||
github.com/grpc-ecosystem/go-grpc-middleware v1.2.2 // indirect
|
||||
github.com/hashicorp/consul/api v1.3.0 // indirect
|
||||
github.com/hashicorp/errwrap v1.0.0 // indirect
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1 // indirect
|
||||
github.com/hashicorp/go-immutable-radix v1.0.0 // indirect
|
||||
github.com/hashicorp/go-multierror v1.1.1 // indirect
|
||||
github.com/hashicorp/go-rootcerts v1.0.0 // indirect
|
||||
github.com/hashicorp/golang-lru v0.5.4 // indirect
|
||||
github.com/hashicorp/serf v0.8.2 // indirect
|
||||
github.com/imdario/mergo v0.3.10 // indirect
|
||||
github.com/json-iterator/go v1.1.11 // indirect
|
||||
github.com/klauspost/compress v1.12.2 // indirect
|
||||
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
|
||||
github.com/miekg/dns v1.1.35 // indirect
|
||||
github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.1 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.1 // indirect
|
||||
github.com/openzipkin/zipkin-go v0.2.2 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/prometheus/client_golang v1.9.0 // indirect
|
||||
github.com/prometheus/client_model v0.2.0 // indirect
|
||||
github.com/prometheus/common v0.15.0 // indirect
|
||||
github.com/prometheus/procfs v0.6.0 // indirect
|
||||
github.com/prometheus/statsd_exporter v0.15.0 // indirect
|
||||
github.com/savsgio/gotils v0.0.0-20210217112953-d4a072536008 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/stoewer/go-strcase v1.2.0 // indirect
|
||||
github.com/stretchr/objx v0.2.0 // indirect
|
||||
github.com/tylertreat/comcast v1.0.1 // indirect
|
||||
github.com/valyala/bytebufferpool v1.0.0 // indirect
|
||||
github.com/valyala/fasthttp v1.28.0 // indirect
|
||||
go.opencensus.io v0.22.5 // indirect
|
||||
go.opentelemetry.io/otel v0.19.0 // indirect
|
||||
go.uber.org/atomic v1.8.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e // indirect
|
||||
golang.org/x/net v0.0.0-20210614182718-04defd469f4e // indirect
|
||||
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93 // indirect
|
||||
golang.org/x/sys v0.0.0-20210616094352-59db8d763f22 // indirect
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 // indirect
|
||||
golang.org/x/text v0.3.6 // indirect
|
||||
golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba // indirect
|
||||
google.golang.org/appengine v1.6.6 // indirect
|
||||
google.golang.org/genproto v0.0.0-20210524171403-669157292da3 // indirect
|
||||
google.golang.org/grpc v1.40.0 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect
|
||||
gopkg.in/inf.v0 v0.9.1 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
|
||||
k8s.io/api v0.20.0 // indirect
|
||||
k8s.io/apiextensions-apiserver v0.20.0 // indirect
|
||||
k8s.io/apimachinery v0.20.0 // indirect
|
||||
k8s.io/client-go v0.20.0 // indirect
|
||||
k8s.io/klog/v2 v2.4.0 // indirect
|
||||
k8s.io/utils v0.0.0-20201110183641-67b214c5f920 // indirect
|
||||
sigs.k8s.io/controller-runtime v0.7.0 // indirect
|
||||
sigs.k8s.io/structured-merge-diff/v4 v4.0.2 // indirect
|
||||
sigs.k8s.io/yaml v1.2.0 // indirect
|
||||
)
|
||||
|
||||
replace github.com/dapr/components-contrib/tests/certification => ../../
|
||||
|
||||
replace github.com/dapr/components-contrib => ../../../../
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,304 @@
|
|||
// ------------------------------------------------------------
|
||||
// Copyright (c) Microsoft Corporation and Dapr Contributors.
|
||||
// Licensed under the MIT License.
|
||||
// ------------------------------------------------------------
|
||||
|
||||
package sqlserver_test
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
// State.
|
||||
"github.com/dapr/components-contrib/state"
|
||||
state_sqlserver "github.com/dapr/components-contrib/state/sqlserver"
|
||||
state_loader "github.com/dapr/dapr/pkg/components/state"
|
||||
|
||||
// Secret stores.
|
||||
"github.com/dapr/components-contrib/secretstores"
|
||||
secretstore_env "github.com/dapr/components-contrib/secretstores/local/env"
|
||||
secretstores_loader "github.com/dapr/dapr/pkg/components/secretstores"
|
||||
|
||||
// Dapr runtime and Go-SDK
|
||||
"github.com/dapr/dapr/pkg/runtime"
|
||||
dapr_testing "github.com/dapr/dapr/pkg/testing"
|
||||
"github.com/dapr/go-sdk/client"
|
||||
"github.com/dapr/kit/logger"
|
||||
|
||||
// Certification testing runnables
|
||||
"github.com/dapr/components-contrib/tests/certification/embedded"
|
||||
"github.com/dapr/components-contrib/tests/certification/flow"
|
||||
|
||||
"github.com/dapr/components-contrib/tests/certification/flow/dockercompose"
|
||||
"github.com/dapr/components-contrib/tests/certification/flow/network"
|
||||
"github.com/dapr/components-contrib/tests/certification/flow/retry"
|
||||
"github.com/dapr/components-contrib/tests/certification/flow/sidecar"
|
||||
)
|
||||
|
||||
const (
|
||||
sidecarNamePrefix = "sqlserver-sidecar-"
|
||||
dockerComposeYAML = "docker-compose.yml"
|
||||
stateStoreName = "dapr-state-store"
|
||||
certificationTestPrefix = "stable-certification-"
|
||||
dockerConnectionString = "server=localhost;user id=sa;password=Pass@Word1;port=1433;"
|
||||
)
|
||||
|
||||
func TestSqlServer(t *testing.T) {
|
||||
log := logger.NewLogger("dapr.components")
|
||||
ports, err := dapr_testing.GetFreePorts(2)
|
||||
assert.NoError(t, err)
|
||||
|
||||
currentGrpcPort := ports[0]
|
||||
currentHTTPPort := ports[1]
|
||||
|
||||
basicTest := func(ctx flow.Context) error {
|
||||
client, err := client.NewClientWithPort(fmt.Sprint(currentGrpcPort))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
// save state, default options: strong, last-write
|
||||
err = client.SaveState(ctx, stateStoreName, certificationTestPrefix+"key1", []byte("certificationdata"))
|
||||
assert.NoError(t, err)
|
||||
|
||||
// get state
|
||||
item, err := client.GetState(ctx, stateStoreName, certificationTestPrefix+"key1")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, "certificationdata", string(item.Value))
|
||||
|
||||
// delete state
|
||||
err = client.DeleteState(ctx, stateStoreName, certificationTestPrefix+"key1")
|
||||
assert.NoError(t, err)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// this test function heavily depends on the values defined in ./components/docker/customschemawithindex
|
||||
verifyIndexedPopertiesTest := func(ctx flow.Context) error {
|
||||
// verify indices were created by Dapr as specified in the component metadata
|
||||
db, err := sql.Open("sqlserver", fmt.Sprintf("%sdatabase=certificationtest;", dockerConnectionString))
|
||||
assert.NoError(t, err)
|
||||
defer db.Close()
|
||||
|
||||
rows, err := db.Query("sp_helpindex '[customschema].[mystates]'")
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, rows.Err())
|
||||
defer rows.Close()
|
||||
|
||||
indexFoundCount := 0
|
||||
for rows.Next() {
|
||||
var indexedField, otherdata1, otherdata2 string
|
||||
err = rows.Scan(&indexedField, &otherdata1, &otherdata2)
|
||||
assert.NoError(t, err)
|
||||
|
||||
expectedIndices := []string{"IX_customerid", "IX_transactionid", "PK_mystates"}
|
||||
for _, item := range expectedIndices {
|
||||
if item == indexedField {
|
||||
indexFoundCount++
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
assert.Equal(t, 3, indexFoundCount)
|
||||
|
||||
// write JSON data to the state store (which will automatically be indexed in separate columns)
|
||||
client, err := client.NewClientWithPort(fmt.Sprint(currentGrpcPort))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
order := struct {
|
||||
ID int `json:"id"`
|
||||
Customer string `json:"customer"`
|
||||
Description string `json:"description"`
|
||||
}{123456, "John Doe", "something"}
|
||||
|
||||
data, err := json.Marshal(order)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// save state with the key certificationkey1, default options: strong, last-write
|
||||
err = client.SaveState(ctx, stateStoreName, certificationTestPrefix+"key1", data)
|
||||
assert.NoError(t, err)
|
||||
|
||||
// get state for key certificationkey1
|
||||
item, err := client.GetState(ctx, stateStoreName, certificationTestPrefix+"key1")
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, string(data), string(item.Value))
|
||||
|
||||
// check that Dapr wrote the indexed properties to separate columns
|
||||
rows, err = db.Query("SELECT TOP 1 transactionid, customerid FROM [customschema].[mystates];")
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, rows.Err())
|
||||
defer rows.Close()
|
||||
if rows.Next() {
|
||||
var transactionID int
|
||||
var customerID string
|
||||
err = rows.Scan(&transactionID, &customerID)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, transactionID, order.ID)
|
||||
assert.Equal(t, customerID, order.Customer)
|
||||
} else {
|
||||
assert.Fail(t, "no rows returned")
|
||||
}
|
||||
|
||||
// delete state for key certificationkey1
|
||||
err = client.DeleteState(ctx, stateStoreName, certificationTestPrefix+"key1")
|
||||
assert.NoError(t, err)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// helper function for testing the use of an existing custom schema
|
||||
createCustomSchema := func(ctx flow.Context) error {
|
||||
db, err := sql.Open("sqlserver", dockerConnectionString)
|
||||
assert.NoError(t, err)
|
||||
_, err = db.Exec("CREATE SCHEMA customschema;")
|
||||
assert.NoError(t, err)
|
||||
db.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
// helper function to insure the SQL Server Docker Container is truly ready
|
||||
checkSQLServerAvailability := func(ctx flow.Context) error {
|
||||
db, err := sql.Open("sqlserver", dockerConnectionString)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_, err = db.Exec("SELECT * FROM INFORMATION_SCHEMA.TABLES;")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// checks the state store component is not vulnerable to SQL injection
|
||||
verifySQLInjectionTest := func(ctx flow.Context) error {
|
||||
client, err := client.NewClientWithPort(fmt.Sprint(currentGrpcPort))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
defer client.Close()
|
||||
|
||||
// common SQL injection techniques for SQL Server
|
||||
sqlInjectionAttempts := []string{
|
||||
"; DROP states--",
|
||||
"dapr' OR '1'='1",
|
||||
}
|
||||
|
||||
for _, sqlInjectionAttempt := range sqlInjectionAttempts {
|
||||
// save state with sqlInjectionAttempt's value as key, default options: strong, last-write
|
||||
err = client.SaveState(ctx, stateStoreName, sqlInjectionAttempt, []byte(sqlInjectionAttempt))
|
||||
assert.NoError(t, err)
|
||||
|
||||
// get state for key sqlInjectionAttempt's value
|
||||
item, err := client.GetState(ctx, stateStoreName, sqlInjectionAttempt)
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, sqlInjectionAttempt, string(item.Value))
|
||||
|
||||
// delete state for key sqlInjectionAttempt's value
|
||||
err = client.DeleteState(ctx, stateStoreName, sqlInjectionAttempt)
|
||||
assert.NoError(t, err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
flow.New(t, "SQLServer certification using SQL Server Docker").
|
||||
// Run SQL Server using Docker Compose.
|
||||
Step(dockercompose.Run("sqlserver", dockerComposeYAML)).
|
||||
Step("wait for SQL Server readiness", retry.Do(time.Second*3, 10, checkSQLServerAvailability)).
|
||||
|
||||
// Run the Dapr sidecar with the SQL Server component.
|
||||
Step(sidecar.Run(sidecarNamePrefix+"dockerDefault",
|
||||
embedded.WithoutApp(),
|
||||
embedded.WithDaprGRPCPort(currentGrpcPort),
|
||||
embedded.WithDaprHTTPPort(currentHTTPPort),
|
||||
embedded.WithComponentsPath("components/docker/default"),
|
||||
runtime.WithSecretStores(
|
||||
secretstores_loader.New("local.env", func() secretstores.SecretStore {
|
||||
return secretstore_env.NewEnvSecretStore(log)
|
||||
})),
|
||||
runtime.WithStates(
|
||||
state_loader.New("sqlserver", func() state.Store {
|
||||
return state_sqlserver.NewSQLServerStateStore(log)
|
||||
}),
|
||||
))).
|
||||
Step("Run basic test", basicTest).
|
||||
// Introduce network interruption of 15 seconds
|
||||
// Note: the connection timeout is set to 5 seconds via the component metadata connection string.
|
||||
Step("interrupt network",
|
||||
network.InterruptNetwork(15*time.Second, nil, nil, "1433", "1434")).
|
||||
|
||||
// Component should recover at this point.
|
||||
Step("wait", flow.Sleep(5*time.Second)).
|
||||
Step("Run basic test again to verify reconnection occurred", basicTest).
|
||||
Step("Run SQL injection test", verifySQLInjectionTest, sidecar.Stop(sidecarNamePrefix+"dockerDefault")).
|
||||
Step("Stopping SQL Server Docker container", dockercompose.Stop("sqlserver", dockerComposeYAML)).
|
||||
Run()
|
||||
|
||||
ports, err = dapr_testing.GetFreePorts(2)
|
||||
assert.NoError(t, err)
|
||||
|
||||
currentGrpcPort = ports[0]
|
||||
currentHTTPPort = ports[1]
|
||||
|
||||
flow.New(t, "Using existing custom schema with indexed data").
|
||||
// Run SQL Server using Docker Compose.
|
||||
Step(dockercompose.Run("sqlserver", dockerComposeYAML)).
|
||||
Step("wait for SQL Server readiness", retry.Do(time.Second*3, 10, checkSQLServerAvailability)).
|
||||
Step("Creating schema", createCustomSchema).
|
||||
|
||||
// Run the Dapr sidecar with the SQL Server component.
|
||||
Step(sidecar.Run(sidecarNamePrefix+"dockerCustomSchema",
|
||||
embedded.WithoutApp(),
|
||||
embedded.WithDaprGRPCPort(currentGrpcPort),
|
||||
embedded.WithDaprHTTPPort(currentHTTPPort),
|
||||
embedded.WithComponentsPath("components/docker/customschemawithindex"),
|
||||
runtime.WithStates(
|
||||
state_loader.New("sqlserver", func() state.Store {
|
||||
return state_sqlserver.NewSQLServerStateStore(log)
|
||||
}),
|
||||
))).
|
||||
Step("Run indexed properties verification test", verifyIndexedPopertiesTest, sidecar.Stop(sidecarNamePrefix+"dockerCustomSchema")).
|
||||
Step("Stopping SQL Server Docker container", dockercompose.Stop("sqlserver", dockerComposeYAML)).
|
||||
Run()
|
||||
|
||||
ports, err = dapr_testing.GetFreePorts(2)
|
||||
assert.NoError(t, err)
|
||||
|
||||
currentGrpcPort = ports[0]
|
||||
currentHTTPPort = ports[1]
|
||||
|
||||
flow.New(t, "SQL Server certification using Azure SQL").
|
||||
// Run the Dapr sidecar with the SQL Server component.
|
||||
Step(sidecar.Run(sidecarNamePrefix+"azure",
|
||||
embedded.WithoutApp(),
|
||||
embedded.WithDaprGRPCPort(currentGrpcPort),
|
||||
embedded.WithDaprHTTPPort(currentHTTPPort),
|
||||
embedded.WithComponentsPath("components/azure"),
|
||||
runtime.WithSecretStores(
|
||||
secretstores_loader.New("local.env", func() secretstores.SecretStore {
|
||||
return secretstore_env.NewEnvSecretStore(log)
|
||||
})),
|
||||
runtime.WithStates(
|
||||
state_loader.New("sqlserver", func() state.Store {
|
||||
return state_sqlserver.NewSQLServerStateStore(log)
|
||||
}),
|
||||
))).
|
||||
Step("Run basic test", basicTest).
|
||||
Step("interrupt network",
|
||||
network.InterruptNetwork(40*time.Second, nil, nil, "1433", "1434")).
|
||||
|
||||
// Component should recover at this point.
|
||||
Step("wait", flow.Sleep(10*time.Second)).
|
||||
Step("Run basic test again to verify reconnection occurred", basicTest).
|
||||
Step("Run SQL injection test", verifySQLInjectionTest, sidecar.Stop(sidecarNamePrefix+"azure")).
|
||||
Run()
|
||||
}
|
Loading…
Reference in New Issue