Add CosmosDB state store conformance tests (#622)

* Add CosmosDB conformance tests

* Fix workflow & lint

* Add more disclaimers to README.md
This commit is contained in:
Nghia Tran 2021-01-20 14:38:09 -08:00 committed by GitHub
parent 079d0b1bd0
commit 3086450ced
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 120 additions and 12 deletions

View File

@ -23,16 +23,33 @@ jobs:
#
# The KeyVault policy must be granted to your Service Principal using
# az keyvault set-policy -n $AZURE_KEYVAULT --secret-permissions get list --spn $SPN_CLIENT_ID
AZURE_KEYVAULT: conformance-tests-secret
AZURE_KEYVAULT: dapr-conf-tests
strategy:
fail-fast: false # Keep running even if one component fails
matrix:
# List here all the components that needs to be invoked in this workflow.
component:
- state.redis
- pubsub.redis
- secretstores.localenv
- state.cosmosdb
- state.redis
include:
- component: state.cosmosdb
# Unfortunately, Azure secrets can't have underscores in
# names, while environment variables with hyphens ('-') are
# troublesome.
#
# We work around here by leveraging the fact that
# environment variable names are case sensitive, so
# CamelCase would still work.
#
# That is slightly better than something like
# AZURECOSMOSDBMASTERKEY, which is extremely hard to read
# and errorprone.
#
# Only list the secrets you need for this component.
required-secrets: AzureCosmosDBMasterKey,AzureCosmosDBUrl,AzureCosmosDB,AzureCosmosDBCollection
steps:
- name: Check out code onto GOPATH
uses: actions/checkout@v2
@ -65,11 +82,11 @@ jobs:
NAME=$(echo ${{ matrix.component }} | cut -d. -f2)
KIND_UPPER="$(tr '[:lower:]' '[:upper:]' <<< ${KIND:0:1})${KIND:1}"
if [ ${KIND}=="secretstores" ]; then
if [ "${KIND}" = "secretstores" ]; then
KIND_UPPER=SecretStore
fi
if [ ${KIND}=="output-binding" ]; then
if [ "${KIND}" = "output-binding" ]; then
KIND_UPPER=OutputBinding
fi

1
go.mod
View File

@ -71,6 +71,7 @@ require (
gopkg.in/couchbase/gocb.v1 v1.6.4
gopkg.in/yaml.v2 v2.3.0
k8s.io/api v0.20.0
k8s.io/apiextensions-apiserver v0.17.2
k8s.io/apimachinery v0.20.0
k8s.io/client-go v0.20.0
)

View File

@ -0,0 +1,16 @@
apiVersion: dapr.io/v1alpha1
kind: Component
metadata:
name: statestore
spec:
type: state.azure.cosmosdb
version: v1
metadata:
- name: url
value: ${{AzureCosmosDBUrl}}
- name: masterKey
value: ${{AzureCosmosDBMasterKey}}
- name: database
value: ${{AzureCosmosDB}}
- name: collection
value: ${{AzureCosmosDBCollection}}

View File

@ -5,3 +5,12 @@ components:
config:
maxInitDuration: 30
maxSetDuration: 20
- component: cosmosdb
allOperations: true
config:
maxInitDuration: 900
maxSetDuration: 300
maxGetDuration: 300
maxBulkSetDuration: 300
maxBulkDeleteDuration: 300
maxDeleteDuration: 300

View File

@ -15,4 +15,4 @@
1. Test test setup is independent of the test run.
2. Run Redis with 6379 exposed locally.
3. Run `make conf-tests` to run the conformance tests locally.
> Note: Any component that cannot run as dockerized containers are not tested locally.
> Note Some conformance tests require credentials in the form of environment variables. For examples Azure CosmosDB conformance tests will need to have Azure CosmosDB credentials. You will need to supply them to make these tests pass.

View File

@ -1,3 +1,8 @@
// ------------------------------------------------------------
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// ------------------------------------------------------------
package conformance
import (
@ -5,6 +10,7 @@ import (
"fmt"
"io/ioutil"
"math/rand"
"os"
"path/filepath"
"strings"
"testing"
@ -12,11 +18,13 @@ import (
"fortio.org/fortio/log"
"github.com/dapr/components-contrib/pubsub"
p_servicebus "github.com/dapr/components-contrib/pubsub/azure/servicebus"
p_redis "github.com/dapr/components-contrib/pubsub/redis"
"github.com/dapr/components-contrib/secretstores"
ss_local_env "github.com/dapr/components-contrib/secretstores/local/env"
ss_local_file "github.com/dapr/components-contrib/secretstores/local/file"
"github.com/dapr/components-contrib/state"
s_cosmosdb "github.com/dapr/components-contrib/state/azure/cosmosdb"
s_redis "github.com/dapr/components-contrib/state/redis"
conf_pubsub "github.com/dapr/components-contrib/tests/conformance/pubsub"
conf_secret "github.com/dapr/components-contrib/tests/conformance/secretstores"
@ -74,10 +82,27 @@ func LoadComponents(componentPath string) ([]v1alpha1.Component, error) {
return components, nil
}
func LookUpEnv(key string) string {
if val, ok := os.LookupEnv(key); ok {
return val
}
return ""
}
func ConvertMetadataToProperties(items []v1alpha1.MetadataItem) map[string]string {
properties := map[string]string{}
for _, c := range items {
properties[c.Name] = c.Value.String()
val := c.Value.String()
if strings.HasPrefix(c.Value.String(), "${{") {
// look up env var with that name. remove ${{}} and space
k := strings.TrimSpace(strings.TrimSuffix(strings.TrimPrefix(val, "${{"), "}}"))
v := LookUpEnv(k)
if v != "" {
val = v
}
}
properties[c.Name] = val
}
return properties
@ -172,6 +197,8 @@ func loadPubSub(tc TestComponent) pubsub.PubSub {
switch tc.Component {
case "redis":
pubsub = p_redis.NewRedisStreams(testLogger)
case "azure-servicebus":
pubsub = p_servicebus.NewAzureServiceBus(testLogger)
default:
return nil
}
@ -198,6 +225,8 @@ func loadStateStore(tc TestComponent) state.Store {
switch tc.Component {
case "redis":
store = s_redis.NewRedisStateStore(testLogger)
case "cosmosdb":
store = s_cosmosdb.NewCosmosDBStateStore(testLogger)
default:
return nil
}

View File

@ -1,9 +1,12 @@
package conformance
import (
"os"
"testing"
"github.com/dapr/dapr/pkg/apis/components/v1alpha1"
"github.com/stretchr/testify/assert"
v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
)
func TestDecodeYaml(t *testing.T) {
@ -40,3 +43,36 @@ func TestIsYaml(t *testing.T) {
resp = isYaml("test.exe")
assert.False(t, resp)
}
func TestLookUpEnv(t *testing.T) {
os.Setenv("CONF_TEST_KEY", "testval")
defer os.Unsetenv("CONF_TEST_KEY")
r := LookUpEnv("CONF_TEST_KEY")
assert.Equal(t, "testval", r)
r = LookUpEnv("CONF_TEST_NOT_THERE")
assert.Equal(t, "", r)
}
func TestConvertMetadataToProperties(t *testing.T) {
items := []v1alpha1.MetadataItem{
{
Name: "test_key",
Value: v1alpha1.DynamicValue{
JSON: v1.JSON{Raw: []byte("test")},
},
},
{
Name: "env_var_sub",
Value: v1alpha1.DynamicValue{
JSON: v1.JSON{Raw: []byte("${{CONF_TEST_KEY}}")},
},
},
}
os.Setenv("CONF_TEST_KEY", "testval")
defer os.Unsetenv("CONF_TEST_KEY")
resp := ConvertMetadataToProperties(items)
assert.NotNil(t, resp)
assert.Equal(t, 2, len(resp))
assert.Equal(t, "test", resp["test_key"])
assert.Equal(t, "testval", resp["env_var_sub"])
}