Skip to content

Commit 95211b4

Browse files
Test Go and Java SDK client retry behavior
1 parent cbf37be commit 95211b4

File tree

27 files changed

+1471
-147
lines changed

27 files changed

+1471
-147
lines changed

cmd/run.go

Lines changed: 95 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"io"
1111
"net"
1212
"os"
13+
"os/exec"
1314
"os/signal"
1415
"path/filepath"
1516
"runtime"
@@ -30,8 +31,9 @@ import (
3031
)
3132

3233
const (
33-
summaryListenAddr = "127.0.0.1:0"
34-
FeaturePassed = "PASSED"
34+
proxyExecutableAuto = "auto"
35+
freePortListenAddr = "127.0.0.1:0"
36+
FeaturePassed = "PASSED"
3537
)
3638

3739
func runCmd() *cli.Command {
@@ -66,6 +68,40 @@ type RunConfig struct {
6668
RetainTempDir bool
6769
SummaryURI string
6870
HTTPProxyURL string
71+
ProxyControlURI string
72+
ProxyListenHostPort string
73+
}
74+
75+
func (config RunConfig) appendFlags(out []string) ([]string, error) {
76+
out = append(out, "--server="+config.Server)
77+
out = append(out, "--namespace="+config.Namespace)
78+
if config.ClientCertPath != "" {
79+
clientCertPath, err := filepath.Abs(config.ClientCertPath)
80+
if err != nil {
81+
return nil, err
82+
}
83+
out = append(out, "--client-cert-path="+clientCertPath)
84+
}
85+
if config.ClientKeyPath != "" {
86+
clientKeyPath, err := filepath.Abs(config.ClientKeyPath)
87+
if err != nil {
88+
return nil, err
89+
}
90+
out = append(out, "--client-key-path="+clientKeyPath)
91+
}
92+
if config.SummaryURI != "" {
93+
out = append(out, "--summary-uri="+config.SummaryURI)
94+
}
95+
if config.HTTPProxyURL != "" {
96+
out = append(out, "--http-proxy-url", config.HTTPProxyURL)
97+
}
98+
if config.ProxyControlURI != "" {
99+
out = append(out, "--proxy-control-uri="+config.ProxyControlURI)
100+
}
101+
if config.ProxyListenHostPort != "" {
102+
out = append(out, "--proxy-listen-host-port="+config.ProxyListenHostPort)
103+
}
104+
return out, nil
69105
}
70106

71107
// dockerRunFlags are a subset of flags that apply when running in a docker container
@@ -134,6 +170,7 @@ type Runner struct {
134170
rootDir string
135171
createTime time.Time
136172
program sdkbuild.Program
173+
proxy *exec.Cmd
137174
}
138175

139176
// NewRunner creates a new runner for the given config.
@@ -188,13 +225,17 @@ func (r *Runner) Run(ctx context.Context, patterns []string) error {
188225
}
189226
// Aa task queue to every feature
190227
run := &cmd.Run{Features: make([]cmd.RunFeature, len(features))}
191-
var expectsProxy bool
228+
var expectsHTTPProxy bool
229+
var expectsGrpcProxy bool
192230
for i, feature := range features {
193231
run.Features[i].Dir = feature.Dir
194232
run.Features[i].TaskQueue = fmt.Sprintf("features-%v-%v", feature.Dir, uuid.NewString())
195233
run.Features[i].Config = feature.Config
196234
if feature.Config.ExpectUnauthedProxyCount > 0 || feature.Config.ExpectAuthedProxyCount > 0 {
197-
expectsProxy = true
235+
expectsHTTPProxy = true
236+
}
237+
if feature.Config.GrpcProxy {
238+
expectsGrpcProxy = true
198239
}
199240
}
200241

@@ -228,15 +269,32 @@ func (r *Runner) Run(ctx context.Context, patterns []string) error {
228269
}
229270

230271
// If any feature requires an HTTP proxy, we must run it
231-
var proxyServer *harness.HTTPConnectProxyServer
232-
if expectsProxy {
233-
proxyServer, err = harness.StartHTTPConnectProxyServer(harness.HTTPConnectProxyServerOptions{Log: r.log})
272+
var httpProxyServer *harness.HTTPConnectProxyServer
273+
if expectsHTTPProxy {
274+
httpProxyServer, err = harness.StartHTTPConnectProxyServer(harness.HTTPConnectProxyServerOptions{Log: r.log})
275+
if err != nil {
276+
return fmt.Errorf("could not start http proxy server: %w", err)
277+
}
278+
r.config.HTTPProxyURL = "https://" + httpProxyServer.Address
279+
r.log.Info("Started HTTP CONNECT proxy server", "address", httpProxyServer.Address)
280+
defer httpProxyServer.Close()
281+
}
282+
283+
// if any feature requires a gRPC proxy, we must run it
284+
if expectsGrpcProxy {
285+
grpcProxyServer, err := harness.StartGRPCProxyServer(harness.GRPCProxyServerOptions{
286+
DialAddress: r.config.Server,
287+
ClientCertPath: r.config.ClientCertPath,
288+
ClientKeyPath: r.config.ClientKeyPath,
289+
Log: r.log,
290+
})
234291
if err != nil {
235-
return fmt.Errorf("could not start proxy server: %w", err)
292+
return fmt.Errorf("could not start grpc proxy server: %w", err)
236293
}
237-
r.config.HTTPProxyURL = "https://" + proxyServer.Address
238-
r.log.Info("Started HTTP CONNECT proxy server", "address", proxyServer.Address)
239-
defer proxyServer.Close()
294+
r.config.ProxyListenHostPort = grpcProxyServer.ProxyAddress()
295+
r.config.ProxyControlURI = "http://" + grpcProxyServer.ControlAddress()
296+
r.log.Info("Started gRPC proxy server", "address", grpcProxyServer.ProxyAddress(), "control", grpcProxyServer.ControlAddress())
297+
defer grpcProxyServer.Close()
240298
}
241299

242300
// Ensure any created temp dir is cleaned on ctrl-c or normal exit
@@ -251,14 +309,14 @@ func (r *Runner) Run(ctx context.Context, patterns []string) error {
251309
defer r.destroyTempDir()
252310
}
253311

254-
l, err := net.Listen("tcp", summaryListenAddr)
312+
summaryListener, err := net.Listen("tcp", freePortListenAddr)
255313
if err != nil {
256314
return err
257315
}
258-
defer l.Close()
316+
defer summaryListener.Close()
259317
summaryChan := make(chan Summary)
260-
go r.summaryServer(l, summaryChan)
261-
r.config.SummaryURI = "tcp://" + l.Addr().String()
318+
go r.summaryServer(summaryListener, summaryChan)
319+
r.config.SummaryURI = "tcp://" + summaryListener.Addr().String()
262320

263321
err = nil
264322
switch r.config.Lang {
@@ -273,12 +331,14 @@ func (r *Runner) Run(ctx context.Context, patterns []string) error {
273331
}
274332
} else {
275333
err = cmd.NewRunner(cmd.RunConfig{
276-
Server: r.config.Server,
277-
Namespace: r.config.Namespace,
278-
ClientCertPath: r.config.ClientCertPath,
279-
ClientKeyPath: r.config.ClientKeyPath,
280-
SummaryURI: r.config.SummaryURI,
281-
HTTPProxyURL: r.config.HTTPProxyURL,
334+
Server: r.config.Server,
335+
Namespace: r.config.Namespace,
336+
ClientCertPath: r.config.ClientCertPath,
337+
ClientKeyPath: r.config.ClientKeyPath,
338+
SummaryURI: r.config.SummaryURI,
339+
HTTPProxyURL: r.config.HTTPProxyURL,
340+
ProxyControlURI: r.config.ProxyControlURI,
341+
ProxyListenHostPort: r.config.ProxyListenHostPort,
282342
}).Run(ctx, run)
283343
}
284344
case "java":
@@ -315,7 +375,7 @@ func (r *Runner) Run(ctx context.Context, patterns []string) error {
315375
if err != nil {
316376
return err
317377
}
318-
l.Close()
378+
summaryListener.Close()
319379
summary, ok := <-summaryChan
320380
if !ok {
321381
r.log.Debug("did not receive a test run summary - adopting legacy behavior of assuming no tests were skipped")
@@ -327,7 +387,7 @@ func (r *Runner) Run(ctx context.Context, patterns []string) error {
327387
// For features that expected proxy connections, count how many expected
328388
// ignoring skips and compare count with actual. If any failed we don't need
329389
// even do the comparison.
330-
if proxyServer != nil {
390+
if httpProxyServer != nil {
331391
var anyFailed bool
332392
var expectUnauthedProxyCount, expectAuthedProxyCount int
333393
for _, summ := range summary {
@@ -345,21 +405,26 @@ func (r *Runner) Run(ctx context.Context, patterns []string) error {
345405
}
346406
}
347407
if !anyFailed {
348-
if proxyServer.UnauthedConnectionsTunneled.Load() != uint32(expectUnauthedProxyCount) {
408+
if httpProxyServer.UnauthedConnectionsTunneled.Load() != uint32(expectUnauthedProxyCount) {
349409
return fmt.Errorf("expected %v unauthed HTTP proxy connections, got %v",
350-
expectUnauthedProxyCount, proxyServer.UnauthedConnectionsTunneled.Load())
351-
} else if proxyServer.AuthedConnectionsTunneled.Load() != uint32(expectAuthedProxyCount) {
410+
expectUnauthedProxyCount, httpProxyServer.UnauthedConnectionsTunneled.Load())
411+
} else if httpProxyServer.AuthedConnectionsTunneled.Load() != uint32(expectAuthedProxyCount) {
352412
return fmt.Errorf("expected %v authed HTTP proxy connections, got %v",
353-
expectAuthedProxyCount, proxyServer.AuthedConnectionsTunneled.Load())
413+
expectAuthedProxyCount, httpProxyServer.AuthedConnectionsTunneled.Load())
354414
} else {
355415
r.log.Debug("Matched expected HTTP proxy connections",
356-
"expectUnauthed", expectUnauthedProxyCount, "actualUnauthed", proxyServer.UnauthedConnectionsTunneled.Load(),
357-
"expectAuthed", expectAuthedProxyCount, "actualAuthed", proxyServer.AuthedConnectionsTunneled.Load())
416+
"expectUnauthed", expectUnauthedProxyCount, "actualUnauthed", httpProxyServer.UnauthedConnectionsTunneled.Load(),
417+
"expectAuthed", expectAuthedProxyCount, "actualAuthed", httpProxyServer.AuthedConnectionsTunneled.Load())
358418
}
359419
}
360420
}
361421

362-
return r.handleHistory(ctx, run, summary)
422+
err = r.handleHistory(ctx, run, summary)
423+
if err != nil {
424+
return err
425+
}
426+
427+
return nil
363428
}
364429

365430
func (r *Runner) handleHistory(ctx context.Context, run *cmd.Run, summary Summary) error {

cmd/run_dotnet.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,11 +64,15 @@ func (r *Runner) RunDotNetExternal(ctx context.Context, run *cmd.Run) error {
6464
}
6565
}
6666

67-
args := []string{"--server", r.config.Server, "--namespace", r.config.Namespace}
68-
if r.config.ClientCertPath != "" {
69-
args = append(args, "--client-cert-path", r.config.ClientCertPath, "--client-key-path", r.config.ClientKeyPath)
67+
// Build args
68+
args := make([]string, 0, 64)
69+
args, err := r.config.appendFlags(args)
70+
if err != nil {
71+
return err
7072
}
7173
args = append(args, run.ToArgs()...)
74+
75+
// Run
7276
cmd, err := r.program.NewCommand(ctx, args...)
7377
if err == nil {
7478
r.log.Debug("Running Go separately", "Args", cmd.Args)

cmd/run_go.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ func (r *Runner) RunGoExternal(ctx context.Context, run *cmd.Run) error {
6868
if r.config.HTTPProxyURL != "" {
6969
args = append(args, "--http-proxy-url", r.config.HTTPProxyURL)
7070
}
71+
if r.config.ProxyControlURI != "" {
72+
args = append(args, "--proxy-control-uri", r.config.ProxyControlURI)
73+
}
74+
if r.config.ProxyListenHostPort != "" {
75+
args = append(args, "--proxy-listen-host-port", r.config.ProxyListenHostPort)
76+
}
7177
args = append(args, run.ToArgs()...)
7278
cmd, err := r.program.NewCommand(ctx, args...)
7379
if err == nil {

cmd/run_java.go

Lines changed: 4 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ package cmd
33
import (
44
"context"
55
"fmt"
6-
"path/filepath"
76

87
"github.com/temporalio/features/harness/go/cmd"
98
"github.com/temporalio/features/sdkbuild"
@@ -40,26 +39,10 @@ func (r *Runner) RunJavaExternal(ctx context.Context, run *cmd.Run) error {
4039
}
4140

4241
// Build args
43-
args := []string{"--server", r.config.Server, "--namespace", r.config.Namespace}
44-
if r.config.ClientCertPath != "" {
45-
clientCertPath, err := filepath.Abs(r.config.ClientCertPath)
46-
if err != nil {
47-
return err
48-
}
49-
args = append(args, "--client-cert-path", clientCertPath)
50-
}
51-
if r.config.ClientKeyPath != "" {
52-
clientKeyPath, err := filepath.Abs(r.config.ClientKeyPath)
53-
if err != nil {
54-
return err
55-
}
56-
args = append(args, "--client-key-path", clientKeyPath)
57-
}
58-
if r.config.SummaryURI != "" {
59-
args = append(args, "--summary-uri", r.config.SummaryURI)
60-
}
61-
if r.config.HTTPProxyURL != "" {
62-
args = append(args, "--http-proxy-url", r.config.HTTPProxyURL)
42+
args := make([]string, 0, 64)
43+
args, err := r.config.appendFlags(args)
44+
if err != nil {
45+
return err
6346
}
6447
args = append(args, run.ToArgs()...)
6548

cmd/run_python.go

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -60,23 +60,11 @@ func (r *Runner) RunPythonExternal(ctx context.Context, run *cmd.Run) error {
6060
}
6161

6262
// Build args
63-
args := []string{"harness.python.main", "--server", r.config.Server, "--namespace", r.config.Namespace}
64-
if r.config.ClientCertPath != "" {
65-
clientCertPath, err := filepath.Abs(r.config.ClientCertPath)
66-
if err != nil {
67-
return err
68-
}
69-
args = append(args, "--client-cert-path", clientCertPath)
70-
}
71-
if r.config.ClientKeyPath != "" {
72-
clientKeyPath, err := filepath.Abs(r.config.ClientKeyPath)
73-
if err != nil {
74-
return err
75-
}
76-
args = append(args, "--client-key-path", clientKeyPath)
77-
}
78-
if r.config.HTTPProxyURL != "" {
79-
args = append(args, "--http-proxy-url", r.config.HTTPProxyURL)
63+
args := make([]string, 0, 64)
64+
args = append(args, "harness.python.main")
65+
args, err := r.config.appendFlags(args)
66+
if err != nil {
67+
return err
8068
}
8169
args = append(args, run.ToArgs()...)
8270

cmd/run_typescript.go

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -58,26 +58,11 @@ func (r *Runner) RunTypeScriptExternal(ctx context.Context, run *cmd.Run) error
5858
}
5959

6060
// Build args
61-
args := []string{
62-
"./tslib/harness/ts/main.js",
63-
"--server",
64-
r.config.Server,
65-
"--namespace",
66-
r.config.Namespace,
67-
}
68-
if r.config.ClientCertPath != "" {
69-
clientCertPath, err := filepath.Abs(r.config.ClientCertPath)
70-
if err != nil {
71-
return err
72-
}
73-
args = append(args, "--client-cert-path", clientCertPath)
74-
}
75-
if r.config.ClientKeyPath != "" {
76-
clientKeyPath, err := filepath.Abs(r.config.ClientKeyPath)
77-
if err != nil {
78-
return err
79-
}
80-
args = append(args, "--client-key-path", clientKeyPath)
61+
args := make([]string, 0, 64)
62+
args = append(args, "./tslib/harness/ts/main.js")
63+
args, err := r.config.appendFlags(args)
64+
if err != nil {
65+
return err
8166
}
8267
args = append(args, run.ToArgs()...)
8368

features/features.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ import (
2626
data_converter_json_protobuf "github.com/temporalio/features/features/data_converter/json_protobuf"
2727
eager_activity_non_remote_activities_worker "github.com/temporalio/features/features/eager_activity/non_remote_activities_worker"
2828
eager_workflow_successful_start "github.com/temporalio/features/features/eager_workflow/successful_start"
29+
grpc_retry_server_frozen_for_initiator "github.com/temporalio/features/features/grpc_retry/server_frozen_for_initiator"
30+
grpc_retry_server_restarted_for_initiator "github.com/temporalio/features/features/grpc_retry/server_restarted_for_initiator"
31+
grpc_retry_server_unavailable_for_initiator "github.com/temporalio/features/features/grpc_retry/server_unavailable_for_initiator"
2932
query_successful_query "github.com/temporalio/features/features/query/successful_query"
3033
query_timeout_due_to_no_active_workers "github.com/temporalio/features/features/query/timeout_due_to_no_active_workers"
3134
query_unexpected_arguments "github.com/temporalio/features/features/query/unexpected_arguments"
@@ -71,15 +74,18 @@ func init() {
7174
client_http_proxy.Feature,
7275
client_http_proxy_auth.Feature,
7376
continue_as_new_continue_as_same.Feature,
74-
data_converter_binary_protobuf.Feature,
7577
data_converter_binary.Feature,
78+
data_converter_binary_protobuf.Feature,
7679
data_converter_codec.Feature,
7780
data_converter_empty.Feature,
7881
data_converter_failure.Feature,
79-
data_converter_json_protobuf.Feature,
8082
data_converter_json.Feature,
83+
data_converter_json_protobuf.Feature,
8184
eager_activity_non_remote_activities_worker.Feature,
8285
eager_workflow_successful_start.Feature,
86+
grpc_retry_server_frozen_for_initiator.Feature,
87+
grpc_retry_server_restarted_for_initiator.Feature,
88+
grpc_retry_server_unavailable_for_initiator.Feature,
8389
query_successful_query.Feature,
8490
query_timeout_due_to_no_active_workers.Feature,
8591
query_unexpected_arguments.Feature,
@@ -96,8 +102,8 @@ func init() {
96102
update_activities.Feature,
97103
update_async_accepted.Feature,
98104
update_basic.Feature,
99-
update_deduplication.Feature,
100105
update_client_interceptor.Feature,
106+
update_deduplication.Feature,
101107
update_non_durable_reject.Feature,
102108
update_self.Feature,
103109
update_task_failure.Feature,
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"grpcProxy": true
3+
}

0 commit comments

Comments
 (0)