Skip to content

Commit 698ffb5

Browse files
pkedytanvigourdaixiang0CodeMonkeyLeet
authored
Initial certification testing "framework" (#1204)
* WIP * tweaks * Simplifying runnables * Increase network timeout * tweaks * More tweaks * Docker compose and structural tweaks Co-authored-by: tanvigour <60332928+tanvigour@users.noreply.github.com> * Tweak * Working Kafka test * Watcher ordered vs unordered * Error simulation * Made port explicit, removed Redis * package.Run (better naming) * terraform related changes * Restructuring certification testing * Remove copied go-sdk client package * Fix terraform.go build issues * Using master of go-sdk * Using main of go-sdk * Tweaks per PR * Adding file headers and some tweaks per PR * More tweaks * More comments in Kafka test Co-authored-by: tanvigour <60332928+tanvigour@users.noreply.github.com> Co-authored-by: Tanvi Gour <tanvi.gour@gmail.com> Co-authored-by: tanvigour <> Co-authored-by: Long Dai <long.dai@intel.com> Co-authored-by: Simon Leet <31784195+CodeMonkeyLeet@users.noreply.github.com>
1 parent 32d6083 commit 698ffb5

File tree

22 files changed

+5092
-0
lines changed

22 files changed

+5092
-0
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// ------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation and Dapr Contributors.
3+
// Licensed under the MIT License.
4+
// ------------------------------------------------------------
5+
6+
package embedded
7+
8+
import (
9+
"github.com/dapr/dapr/pkg/runtime"
10+
"github.com/dapr/kit/logger"
11+
12+
// Name resolutions.
13+
nr "github.com/dapr/components-contrib/nameresolution"
14+
nr_consul "github.com/dapr/components-contrib/nameresolution/consul"
15+
nr_kubernetes "github.com/dapr/components-contrib/nameresolution/kubernetes"
16+
nr_mdns "github.com/dapr/components-contrib/nameresolution/mdns"
17+
18+
nr_loader "github.com/dapr/dapr/pkg/components/nameresolution"
19+
)
20+
21+
func CommonComponents(log logger.Logger) []runtime.Option {
22+
return []runtime.Option{
23+
runtime.WithNameResolutions(
24+
nr_loader.New("mdns", func() nr.Resolver {
25+
return nr_mdns.NewResolver(log)
26+
}),
27+
nr_loader.New("kubernetes", func() nr.Resolver {
28+
return nr_kubernetes.NewResolver(log)
29+
}),
30+
nr_loader.New("consul", func() nr.Resolver {
31+
return nr_consul.NewResolver(log)
32+
}),
33+
),
34+
}
35+
}
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
// ------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation and Dapr Contributors.
3+
// Licensed under the MIT License.
4+
// ------------------------------------------------------------
5+
6+
package embedded
7+
8+
import (
9+
"fmt"
10+
"os"
11+
12+
"github.com/dapr/dapr/pkg/acl"
13+
global_config "github.com/dapr/dapr/pkg/config"
14+
env "github.com/dapr/dapr/pkg/config/env"
15+
"github.com/dapr/dapr/pkg/cors"
16+
"github.com/dapr/dapr/pkg/modes"
17+
"github.com/dapr/dapr/pkg/operator/client"
18+
"github.com/dapr/dapr/pkg/runtime"
19+
"github.com/dapr/dapr/pkg/runtime/security"
20+
"github.com/dapr/kit/logger"
21+
)
22+
23+
const (
24+
placementAddresses = "127.0.0.1"
25+
controlPlaneAddress = ""
26+
allowedOrigins = cors.DefaultAllowedOrigins
27+
mode = modes.StandaloneMode
28+
config = "config.yaml"
29+
componentsPath = "./components"
30+
profilePort = runtime.DefaultProfilePort
31+
enableProfiling = true
32+
maxConcurrency = -1
33+
enableMTLS = false
34+
sentryAddress = ""
35+
appSSL = false
36+
maxRequestBodySize = 4
37+
38+
daprHTTPPort = runtime.DefaultDaprHTTPPort
39+
daprAPIGRPCPort = runtime.DefaultDaprAPIGRPCPort
40+
daprInternalGRPC = runtime.DefaultDaprAPIGRPCPort + 1
41+
appPort = 8000
42+
)
43+
44+
var log = logger.NewLogger("dapr.runtime")
45+
46+
type Option func(config *runtime.Config)
47+
48+
func WithAppProtocol(protocol runtime.Protocol, port int) Option {
49+
return func(config *runtime.Config) {
50+
config.ApplicationProtocol = protocol
51+
config.ApplicationPort = port
52+
}
53+
}
54+
55+
func WithDaprHTTPPort(port int) Option {
56+
return func(config *runtime.Config) {
57+
config.HTTPPort = port
58+
}
59+
}
60+
61+
func WithDaprGRPCPort(port int) Option {
62+
return func(config *runtime.Config) {
63+
config.APIGRPCPort = port
64+
}
65+
}
66+
67+
func WithDaprInternalGRPCPort(port int) Option {
68+
return func(config *runtime.Config) {
69+
config.InternalGRPCPort = port
70+
}
71+
}
72+
73+
func WithListenAddresses(addresses []string) Option {
74+
return func(config *runtime.Config) {
75+
config.APIListenAddresses = addresses
76+
}
77+
}
78+
79+
func NewRuntime(appID string, opts ...Option) (*runtime.DaprRuntime, error) {
80+
var err error
81+
82+
runtimeConfig := runtime.NewRuntimeConfig(
83+
appID, []string{}, controlPlaneAddress,
84+
allowedOrigins, config, componentsPath, string(runtime.HTTPProtocol), string(mode),
85+
daprHTTPPort, daprInternalGRPC, daprAPIGRPCPort, []string{"127.0.0.1"}, nil, appPort, profilePort,
86+
enableProfiling, maxConcurrency, enableMTLS, sentryAddress, appSSL, maxRequestBodySize, "",
87+
runtime.DefaultReadBufferSize, false)
88+
89+
for _, opt := range opts {
90+
opt(runtimeConfig)
91+
}
92+
93+
variables := map[string]string{
94+
env.AppID: runtimeConfig.ID,
95+
env.AppPort: fmt.Sprintf("%d", runtimeConfig.ApplicationPort),
96+
env.HostAddress: "127.0.0.1",
97+
env.DaprPort: fmt.Sprintf("%d", runtimeConfig.InternalGRPCPort),
98+
env.DaprGRPCPort: fmt.Sprintf("%d", runtimeConfig.APIGRPCPort),
99+
env.DaprHTTPPort: fmt.Sprintf("%d", runtimeConfig.HTTPPort),
100+
env.DaprProfilePort: fmt.Sprintf("%d", runtimeConfig.ProfilePort),
101+
}
102+
103+
for key, value := range variables {
104+
err := os.Setenv(key, value)
105+
if err != nil {
106+
return nil, err
107+
}
108+
}
109+
110+
var globalConfig *global_config.Configuration
111+
var configErr error
112+
113+
if enableMTLS {
114+
if runtimeConfig.CertChain, err = security.GetCertChain(); err != nil {
115+
return nil, err
116+
}
117+
}
118+
119+
var accessControlList *global_config.AccessControlList
120+
var namespace string
121+
122+
if config != "" {
123+
switch modes.DaprMode(mode) {
124+
case modes.KubernetesMode:
125+
client, conn, clientErr := client.GetOperatorClient(controlPlaneAddress, security.TLSServerName, runtimeConfig.CertChain)
126+
if clientErr != nil {
127+
return nil, err
128+
}
129+
defer conn.Close()
130+
namespace = os.Getenv("NAMESPACE")
131+
globalConfig, configErr = global_config.LoadKubernetesConfiguration(config, namespace, client)
132+
case modes.StandaloneMode:
133+
globalConfig, _, configErr = global_config.LoadStandaloneConfiguration(config)
134+
}
135+
136+
if configErr != nil {
137+
log.Debugf("Config error: %v", configErr)
138+
}
139+
}
140+
141+
if configErr != nil {
142+
return nil, fmt.Errorf("error loading configuration: %w", configErr)
143+
}
144+
if globalConfig == nil {
145+
log.Info("loading default configuration")
146+
globalConfig = global_config.LoadDefaultConfiguration()
147+
}
148+
149+
accessControlList, err = acl.ParseAccessControlSpec(globalConfig.Spec.AccessControlSpec, string(runtimeConfig.ApplicationProtocol))
150+
if err != nil {
151+
return nil, err
152+
}
153+
154+
return runtime.NewDaprRuntime(runtimeConfig, globalConfig, accessControlList), nil
155+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
// ------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation and Dapr Contributors.
3+
// Licensed under the MIT License.
4+
// ------------------------------------------------------------
5+
6+
package app
7+
8+
import (
9+
"log"
10+
"net/http"
11+
12+
"github.com/dapr/go-sdk/service/common"
13+
14+
daprd "github.com/dapr/go-sdk/service/http"
15+
16+
"github.com/dapr/components-contrib/tests/certification/flow"
17+
)
18+
19+
type App struct {
20+
appName string
21+
address string
22+
setup SetupFn
23+
}
24+
25+
type SetupFn func(flow.Context, common.Service) error
26+
27+
func Run(appName, address string, setup SetupFn) (string, flow.Runnable, flow.Runnable) {
28+
return New(appName, address, setup).ToStep()
29+
}
30+
31+
func New(appName, address string, setup SetupFn) App {
32+
return App{
33+
appName: appName,
34+
address: address,
35+
setup: setup,
36+
}
37+
}
38+
39+
func (a App) AppName() string {
40+
return a.appName
41+
}
42+
43+
func (a App) ToStep() (string, flow.Runnable, flow.Runnable) {
44+
return a.appName, a.Start, a.Stop
45+
}
46+
47+
func Start(appName, address string, setup SetupFn) flow.Runnable {
48+
return New(appName, address, setup).Start
49+
}
50+
51+
func (a App) Start(ctx flow.Context) error {
52+
s := daprd.NewService(a.address)
53+
54+
if err := a.setup(ctx, s); err != nil {
55+
return err
56+
}
57+
58+
go func() {
59+
if err := s.Start(); err != nil && err != http.ErrServerClosed {
60+
log.Printf("error listenning: %v", err)
61+
}
62+
}()
63+
64+
ctx.Set(a.appName, s)
65+
66+
return nil
67+
}
68+
69+
func Stop(appName string) flow.Runnable {
70+
return App{appName: appName}.Stop
71+
}
72+
73+
func (a App) Stop(ctx flow.Context) error {
74+
var s common.Service
75+
if ctx.Get(a.appName, &s) {
76+
return s.Stop()
77+
}
78+
79+
return nil
80+
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
// ------------------------------------------------------------
2+
// Copyright (c) Microsoft Corporation and Dapr Contributors.
3+
// Licensed under the MIT License.
4+
// ------------------------------------------------------------
5+
6+
package flow
7+
8+
import (
9+
"context"
10+
"testing"
11+
"time"
12+
)
13+
14+
type Context struct {
15+
name string
16+
context.Context
17+
*testing.T
18+
*Flow
19+
}
20+
21+
func (c Context) Name() string {
22+
return c.name
23+
}
24+
func (c Context) Deadline() (deadline time.Time, ok bool) {
25+
return c.Context.Deadline()
26+
}
27+
func (c Context) Done() <-chan struct{} {
28+
return c.Context.Done()
29+
}
30+
func (c Context) Err() error {
31+
return c.Context.Err()
32+
}
33+
func (c Context) Value(key interface{}) interface{} {
34+
return c.Context.Value(key)
35+
}
36+
func (c Context) MustGet(args ...interface{}) {
37+
if len(args)%2 != 0 {
38+
c.Fatal("invalid number of arguments passed to Get")
39+
}
40+
41+
for i := 0; i < len(args); i += 2 {
42+
varName, ok := args[i].(string)
43+
if !ok {
44+
c.Fatalf("argument %d is not a string", i)
45+
}
46+
47+
c.varsMu.RLock()
48+
variable, ok := c.variables[varName]
49+
c.varsMu.RUnlock()
50+
if !ok {
51+
c.Fatalf("could not find variable %q", varName)
52+
}
53+
if !as(variable, args[i+1]) {
54+
c.Fatalf("could not resolve variable %q", varName)
55+
}
56+
}
57+
}
58+
59+
func (c Context) Get(args ...interface{}) bool {
60+
if len(args)%2 != 0 {
61+
c.Fatal("invalid number of arguments passed to Get")
62+
}
63+
64+
for i := 0; i < len(args); i += 2 {
65+
varName, ok := args[i].(string)
66+
if !ok {
67+
c.Fatalf("argument %d is not a string", i)
68+
}
69+
70+
c.varsMu.RLock()
71+
variable, ok := c.variables[varName]
72+
c.varsMu.RUnlock()
73+
if !ok {
74+
return false
75+
}
76+
if !as(variable, args[i+1]) {
77+
c.Fatalf("could not resolve variable %q", varName)
78+
}
79+
}
80+
81+
return true
82+
}
83+
84+
func (c Context) Set(varName string, value interface{}) {
85+
c.varsMu.Lock()
86+
defer c.varsMu.Unlock()
87+
88+
c.variables[varName] = value
89+
}

0 commit comments

Comments
 (0)