Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate temporalite & temporaltest packages #4026

Merged
merged 56 commits into from
Oct 18, 2023
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
804337e
Add temporalite & temporaltest packages
jlegrone Mar 7, 2023
ceb5741
Move test workflow/interceptor into temoraltest package
jlegrone Mar 10, 2023
9062c19
Move liteconfig into temporalite package
jlegrone Mar 10, 2023
9a527fd
Remove ui server
jlegrone Mar 10, 2023
b8fee47
Remove unused timeoutFromContext func
jlegrone Mar 10, 2023
53d73e1
Avoid stuttering in temporalite package
jlegrone Mar 10, 2023
b5e7487
Always use dynamic ports
jlegrone Mar 10, 2023
3f2d1e5
Add additional config doc comments
jlegrone Mar 10, 2023
73dacd0
Update copyright
jlegrone Mar 17, 2023
2ca1af6
Refactor temporalite into temporal package
jlegrone Mar 21, 2023
1022888
Remove PublicClient config
jlegrone Mar 22, 2023
e650816
Revert "Remove PublicClient config"
jlegrone Mar 22, 2023
34760eb
Add license header
jlegrone Mar 22, 2023
9faaebc
Test setting BaseServerOptions
jlegrone Mar 22, 2023
c613ba8
Update godoc
jlegrone Mar 22, 2023
0cd959a
Move temporaltest to top level
jlegrone Mar 22, 2023
ecd00c4
Update temporaltest backwards compatability policy
jlegrone Mar 22, 2023
2e4bd13
Spellcheck
jlegrone Mar 22, 2023
40fd094
Update godoc
jlegrone Mar 28, 2023
73d31cc
Add temporaltest package to integration tests
jlegrone Mar 28, 2023
c512a54
Move LiteServer into internal package
jlegrone Apr 25, 2023
9ecf117
Merge branch 'master' into jlegrone/migrate-temporalite
jlegrone Apr 25, 2023
87a65ed
Add TODO to remove PublicClient config
jlegrone Apr 25, 2023
43810ea
Document that TestServer methods are unsafe for concurrent use
jlegrone Apr 25, 2023
6aa60b0
Don't return an error from denyAllClaimMapper
jlegrone Apr 25, 2023
2b717b0
Merge branch 'master' into jlegrone/migrate-temporalite
jlegrone Jun 15, 2023
b41ac72
Merge branch 'master' into jlegrone/migrate-temporalite
jlegrone Jul 26, 2023
3030a0c
Test registering and listing workflows using custom search attribute
jlegrone Jul 26, 2023
f8ff2a7
Use errors.As to check for permission denied
jlegrone Jul 26, 2023
04bf716
Verify that a custom worker option was set
jlegrone Jul 26, 2023
f9d60cf
Add TODO to investigate whether randomized db name is necessary in sh…
jlegrone Jul 26, 2023
5a39dec
Return error instead of panic while getting port
jlegrone Jul 26, 2023
ac773d3
Update freeport.go to be unique implementation
jlegrone Jul 26, 2023
ff3ebf3
Remove temporaltest from UNIT_TEST_DIRS
jlegrone Jul 26, 2023
8d29d27
Skip conditional check when appending opts
jlegrone Jul 26, 2023
cf56460
Remove godoc comment about overriding ConnectionOptions
jlegrone Jul 26, 2023
9a0e082
Use maps.Keys
jlegrone Jul 26, 2023
4d1d04b
Don't set MembershipPort twice
jlegrone Jul 26, 2023
4f4070c
Add log.Logger type assertion
jlegrone Jul 26, 2023
d240ccf
Simplify TestServerOption applyFunc
jlegrone Jul 26, 2023
4ecfb55
Delegate to NewWorkerWithOptions
jlegrone Jul 26, 2023
0da8117
Start server synchronously
jlegrone Jul 26, 2023
12bdf7a
Add internal/temporalite to integration tests
jlegrone Jul 26, 2023
f599ac3
Merge branch 'main' into jlegrone/migrate-temporalite
jlegrone Aug 8, 2023
d233bed
Flaky fixes
jlegrone Aug 8, 2023
364b2db
Remove deprecated rand.Seed call
jlegrone Aug 8, 2023
af4f963
WIP
jlegrone Aug 8, 2023
67032f0
Use Eventually to speed up TestSearchAttributeRegistration
jlegrone Aug 16, 2023
20ab82a
Merge branch 'main' into jlegrone/migrate-temporalite
jlegrone Aug 16, 2023
fe318f9
Merge branch 'main' into jlegrone/migrate-temporalite
yiminc Aug 25, 2023
60c302e
Merge branch 'main' into jlegrone/migrate-temporalite
jlegrone Sep 5, 2023
b5e2ef7
Merge branch 'main' into jlegrone/migrate-temporalite
yiminc Oct 13, 2023
211c9af
Fix lint warnings: add error handling on test server shutdown
jlegrone Oct 17, 2023
5d217dd
Inline useless else branch
jlegrone Oct 17, 2023
a936d52
Fix unit test filter
jlegrone Oct 17, 2023
79883a7
Remove parallelism from temporaltest tests to avoid tripping race det…
jlegrone Oct 17, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ FUNCTIONAL_TEST_XDC_ROOT := ./tests/xdc
FUNCTIONAL_TEST_NDC_ROOT := ./tests/ndc
DB_INTEGRATION_TEST_ROOT := ./common/persistence/tests
DB_TOOL_INTEGRATION_TEST_ROOT := ./tools/tests
INTEGRATION_TEST_DIRS := $(DB_INTEGRATION_TEST_ROOT) $(DB_TOOL_INTEGRATION_TEST_ROOT)
INTEGRATION_TEST_DIRS := $(DB_INTEGRATION_TEST_ROOT) $(DB_TOOL_INTEGRATION_TEST_ROOT) ./temporaltest
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤔 Right now temporaltest is being run with both unit and integration test targets. In CI it consistently passes in unit tests, but fails in integration tests.

I can't reproduce this failure locally either with go test ./temporaltest or make integration-test-coverage (the latter after removing DB_INTEGRATION_TEST_ROOT and DB_TOOL_INTEGRATION_TEST_ROOT on this line since I don't have DBs running).

Any ideas?

Copy link
Contributor Author

@jlegrone jlegrone Apr 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update: I'm able to reproduce the integration test failures locally after starting up dependencies using make start-dependencies. The integration-test target succeeds:

$ make integration-test
Run integration tests...
ok  	go.temporal.io/server/common/persistence/tests	223.242s
ok  	go.temporal.io/server/tools/tests	23.265s
ok  	go.temporal.io/server/temporaltest	13.404s

But coverage fails:

$ make integration-test-coverage
Run integration tests with coverage...
ok  	go.temporal.io/server/common/persistence/tests	177.682s	coverage: 64.7% of statements in go.temporal.io/server/common/persistence/..., go.temporal.io/server/tools/...
ok  	go.temporal.io/server/tools/tests	18.036s	coverage: 5.6% of statements in go.temporal.io/server/common/persistence/..., go.temporal.io/server/tools/...
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x28 pc=0x10215c8d4]

goroutine 2602 [running]:
go.temporal.io/server/service/history.(*historyEngineImpl).NotifyNewTasks(0x14001a963c0, 0x140007cbad0?)
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/service/history/historyEngine.go:662 +0x194
go.temporal.io/server/service/history/shard.(*ContextImpl).notifyQueueProcessor(0x14001038800)
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/service/history/shard/context_impl.go:1691 +0x2d0
go.temporal.io/server/service/history/shard.(*ContextImpl).acquireShard.func1()
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/service/history/shard/context_impl.go:1949 +0x158
go.temporal.io/server/common/backoff.ThrottleRetry.func1({0x140018f6ce8, 0x1})
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/common/backoff/retry.go:175 +0x24
go.temporal.io/server/common/backoff.ThrottleRetryContext({0x102e3cb00, 0x1400019e008}, 0x1400101be18, {0x102e21400, 0x14000b8ed80}, 0x102c79780?)
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/common/backoff/retry.go:199 +0x140
go.temporal.io/server/common/backoff.ThrottleRetry(0x1?, {0x102e21400?, 0x14000b8ed80?}, 0x101cda3a8?)
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/common/backoff/retry.go:176 +0x60
go.temporal.io/server/service/history/shard.(*ContextImpl).acquireShard(0x14001038800)
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/service/history/shard/context_impl.go:1974 +0xf0
created by go.temporal.io/server/service/history/shard.(*ContextImpl).transition.func1
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/service/history/shard/context_impl.go:1574 +0x6c
FAIL	go.temporal.io/server/temporaltest	0.633s
FAIL
make: *** [integration-test-coverage] Error 1

Copy link
Contributor Author

@jlegrone jlegrone Apr 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually I've gotten three different failures through make unit-test locally as well (after running it in a loop a few hundred times):

Client must be created with client.Dial() or client.NewLazyClient()
$ make unit-test-coverage
Run unit tests with coverage...
ok  	go.temporal.io/server/temporal	0.956s	coverage: 46.4% of statements
panic: Client must be created with client.Dial() or client.NewLazyClient()

goroutine 18877 [running]:
go.temporal.io/sdk/internal.NewWorker(...)
	/Users/jacoblegrone/go/pkg/mod/go.temporal.io/[email protected]/internal/worker.go:279
go.temporal.io/sdk/worker.New({_, _}, {_, _}, {0xa, 0x0, 0x0, 0x0, 0x0, 0x8, ...})
	/Users/jacoblegrone/go/pkg/mod/go.temporal.io/[email protected]/worker/worker.go:245 +0xbc
go.temporal.io/server/common/sdk.(*clientFactory).NewWorker(_, {_, _}, {_, _}, {0xa, 0x0, 0x0, 0x0, 0x0, ...})
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/common/sdk/factory.go:137 +0x68
go.temporal.io/server/service/worker/scanner.(*Scanner).Start(0xc001692780)
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/service/worker/scanner/scanner.go:179 +0xc28
go.temporal.io/server/service/worker.(*Service).startScanner(0xc005ce4000)
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/service/worker/service.go:502 +0x48
go.temporal.io/server/service/worker.(*Service).Start(0xc005ce4000)
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/service/worker/service.go:391 +0x41c
go.temporal.io/server/service/worker.ServiceLifetimeHooks.func1.1({0x10690ceb0, 0xc005ce4000}, 0x1027e1820?)
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/service/worker/fx.go:133 +0x3c
created by go.temporal.io/server/service/worker.ServiceLifetimeHooks.func1
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/service/worker/fx.go:131 +0x124
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x58 pc=0x104be7d94]

goroutine 19020 [running]:
go.temporal.io/server/service/worker/scanner.(*Scanner).startWorkflow(0xc001692780, {0x10691c9e8, 0xc0017cff80}, {0x0, 0x0}, {{0x104ee50cc, 0x1c}, {0x104f10ab6, 0x28}, 0x0, ...}, ...)
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/service/worker/scanner/scanner.go:232 +0x84
go.temporal.io/server/service/worker/scanner.(*Scanner).startWorkflowWithRetry.func1({0x10691c9e8, 0xc0017cff80})
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/service/worker/scanner/scanner.go:208 +0xf0
go.temporal.io/server/common/backoff.ThrottleRetryContext({0x10691c9e8, 0xc0017cff80}, 0xc001ae1de8, {0x106901840, 0xc002510300}, 0x1068f50d8)
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/common/backoff/retry.go:199 +0x15c
go.temporal.io/server/service/worker/scanner.(*Scanner).startWorkflowWithRetry(0xc001692780, {0x10691c9e8, 0xc0017cff80}, {{0x104ee50cc, 0x1c}, {0x104f10ab6, 0x28}, 0x0, 0x0, 0x0, ...}, ...)
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/service/worker/scanner/scanner.go:207 +0x1d4
created by go.temporal.io/server/service/worker/scanner.(*Scanner).Start
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/service/worker/scanner/scanner.go:174 +0xaa0
FAIL	go.temporal.io/server/temporaltest	10.176s
ok  	go.temporal.io/server/tools/cassandra	0.968s	coverage: 7.5% of statements
ok  	go.temporal.io/server/tools/common/schema	0.342s	coverage: 33.8% of statements
ok  	go.temporal.io/server/tools/tdbg	0.693s	coverage: 4.3% of statements
FAIL
make: *** [unit-test-coverage] Error 1
nil pointer exception
$ make unit-test-coverage
Run unit tests with coverage...
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x2 addr=0x0 pc=0x10703364c]

goroutine 16118 [running]:
go.temporal.io/server/service/worker/scanner.(*Scanner).Stop(0xc005f00820)
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/service/worker/scanner/scanner.go:197 +0x3c
go.temporal.io/server/service/worker.(*Service).Stop(0xc003988900)
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/service/worker/service.go:433 +0x78
go.temporal.io/server/service/worker.ServiceLifetimeHooks.func2({0x10a1ef780?, 0x108d4e580?})
	/Users/jacoblegrone/Development/github.com/temporalio/temporal/service/worker/fx.go:140 +0x30
go.uber.org/fx/internal/lifecycle.(*Lifecycle).runStopHook(0xc0011f8e00, {0x108d68a58, 0xc00164d560}, {0xc0056c74d0, 0xc003a7af40, {0x0, 0x0}, {0x0, 0x0}, {{0xc0064091c0, ...}, ...}})
	/Users/jacoblegrone/go/pkg/mod/go.uber.org/[email protected]/internal/lifecycle/lifecycle.go:338 +0x21c
go.uber.org/fx/internal/lifecycle.(*Lifecycle).Stop(0xc0011f8e00, {0x108d68a58, 0xc00164d560})
	/Users/jacoblegrone/go/pkg/mod/go.uber.org/[email protected]/internal/lifecycle/lifecycle.go:300 +0x458
go.uber.org/fx.(*App).Stop.func2({0x108d68a58, 0xc00164d560})
	/Users/jacoblegrone/go/pkg/mod/go.uber.org/[email protected]/app.go:700 +0xb8
go.uber.org/fx.withTimeout.func1()
	/Users/jacoblegrone/go/pkg/mod/go.uber.org/[email protected]/app.go:781 +0xb0
created by go.uber.org/fx.withTimeout
	/Users/jacoblegrone/go/pkg/mod/go.uber.org/[email protected]/app.go:769 +0x124
FAIL	go.temporal.io/server/temporaltest	5.218s
FAIL
make: *** [unit-test-coverage] Error 1
data race
$ make unit-test-coverage
Run unit tests with coverage...
==================
WARNING: DATA RACE
Read at 0x00c009498840 by goroutine 14464:
  runtime.mapaccess1_faststr()
      /opt/homebrew/Cellar/go/1.19.5/libexec/src/runtime/map_faststr.go:13 +0x41c
  github.com/temporalio/tchannel-go/json.Register.func1()
      /Users/jacoblegrone/go/pkg/mod/github.com/temporalio/[email protected]/json/handler.go:100 +0x78
  github.com/temporalio/tchannel-go.HandlerFunc.Handle()
      /Users/jacoblegrone/go/pkg/mod/github.com/temporalio/[email protected]/handlers.go:49 +0x48
  github.com/temporalio/tchannel-go.(*handlerMap).Handle()
      /Users/jacoblegrone/go/pkg/mod/github.com/temporalio/[email protected]/handlers.go:123 +0x26c
  github.com/temporalio/tchannel-go.channelHandler.Handle()
      /Users/jacoblegrone/go/pkg/mod/github.com/temporalio/[email protected]/handlers.go:131 +0x9c
  github.com/temporalio/tchannel-go.(*Connection).dispatchInbound()
      /Users/jacoblegrone/go/pkg/mod/github.com/temporalio/[email protected]/inbound.go:203 +0x694
  github.com/temporalio/tchannel-go.(*Connection).handleCallReq.func3()
      /Users/jacoblegrone/go/pkg/mod/github.com/temporalio/[email protected]/inbound.go:125 +0x64

Previous write at 0x00c009498840 by goroutine 14376:
  runtime.mapaccess2_faststr()
      /opt/homebrew/Cellar/go/1.19.5/libexec/src/runtime/map_faststr.go:108 +0x43c
  github.com/temporalio/tchannel-go/json.Register()
      /Users/jacoblegrone/go/pkg/mod/github.com/temporalio/[email protected]/json/handler.go:119 +0x238
  github.com/temporalio/ringpop-go/swim.(*Node).registerHandlers()
      /Users/jacoblegrone/go/pkg/mod/github.com/temporalio/[email protected]/swim/handlers.go:81 +0xa8c
  github.com/temporalio/ringpop-go/swim.NewNode()
      /Users/jacoblegrone/go/pkg/mod/github.com/temporalio/[email protected]/swim/node.go:278 +0x99c
  github.com/temporalio/ringpop-go.(*Ringpop).init()
      /Users/jacoblegrone/go/pkg/mod/github.com/temporalio/[email protected]/ringpop.go:195 +0x420
  github.com/temporalio/ringpop-go.(*Ringpop).Bootstrap()
      /Users/jacoblegrone/go/pkg/mod/github.com/temporalio/[email protected]/ringpop.go:419 +0x3c
  go.temporal.io/server/common/membership/ringpop.(*service).bootstrap.func1()
      /Users/jacoblegrone/Development/github.com/temporalio/temporal/common/membership/ringpop/ringpop.go:108 +0x1a8
  go.temporal.io/server/common/backoff.ThrottleRetry.func1()
      /Users/jacoblegrone/Development/github.com/temporalio/temporal/common/backoff/retry.go:175 +0x30
  go.temporal.io/server/common/backoff.ThrottleRetryContext()
      /Users/jacoblegrone/Development/github.com/temporalio/temporal/common/backoff/retry.go:199 +0x158
  go.temporal.io/server/common/backoff.ThrottleRetry()
      /Users/jacoblegrone/Development/github.com/temporalio/temporal/common/backoff/retry.go:176 +0x78
  go.temporal.io/server/common/membership/ringpop.(*service).bootstrap()
      /Users/jacoblegrone/Development/github.com/temporalio/temporal/common/membership/ringpop/ringpop.go:114 +0x128
  go.temporal.io/server/common/membership/ringpop.(*service).start()
      /Users/jacoblegrone/Development/github.com/temporalio/temporal/common/membership/ringpop/ringpop.go:84 +0x50
  go.temporal.io/server/common/membership/ringpop.(*monitor).Start()
      /Users/jacoblegrone/Development/github.com/temporalio/temporal/common/membership/ringpop/monitor.go:139 +0x3c0
  go.temporal.io/server/common/membership/ringpop.(*monitor).Start-fm()
      <autogenerated>:1 +0x34
  go.uber.org/fx/internal/lifecycle.Wrap[...].func1()
      /Users/jacoblegrone/go/pkg/mod/go.uber.org/[email protected]/internal/lifecycle/lifecycle.go:80 +0x30
  go.uber.org/fx/internal/lifecycle.(*Lifecycle).runStartHook()
      /Users/jacoblegrone/go/pkg/mod/go.uber.org/[email protected]/internal/lifecycle/lifecycle.go:256 +0x218
  go.uber.org/fx/internal/lifecycle.(*Lifecycle).Start()
      /Users/jacoblegrone/go/pkg/mod/go.uber.org/[email protected]/internal/lifecycle/lifecycle.go:216 +0x408
  go.uber.org/fx.(*App).start.func1()
      /Users/jacoblegrone/go/pkg/mod/go.uber.org/[email protected]/app.go:678 +0x64
  go.uber.org/fx.(*App).withRollback()
      /Users/jacoblegrone/go/pkg/mod/go.uber.org/[email protected]/app.go:660 +0x48
  go.uber.org/fx.(*App).start()
      /Users/jacoblegrone/go/pkg/mod/go.uber.org/[email protected]/app.go:677 +0x50
  go.uber.org/fx.(*App).start-fm()
      <autogenerated>:1 +0x44
  go.uber.org/fx.withTimeout.func1()
      /Users/jacoblegrone/go/pkg/mod/go.uber.org/[email protected]/app.go:781 +0xac

Goroutine 14464 (running) created at:
  github.com/temporalio/tchannel-go.(*Connection).handleCallReq()
      /Users/jacoblegrone/go/pkg/mod/github.com/temporalio/[email protected]/inbound.go:125 +0x1598
  github.com/temporalio/tchannel-go.(*Connection).handleFrameNoRelay()
      /Users/jacoblegrone/go/pkg/mod/github.com/temporalio/[email protected]/connection.go:709 +0xc4
  github.com/temporalio/tchannel-go.(*Connection).readFrames()
      /Users/jacoblegrone/go/pkg/mod/github.com/temporalio/[email protected]/connection.go:676 +0x14c
  github.com/temporalio/tchannel-go.(*Channel).newConnection.func1()
      /Users/jacoblegrone/go/pkg/mod/github.com/temporalio/[email protected]/connection.go:374 +0x40

Goroutine 14376 (running) created at:
  go.uber.org/fx.withTimeout()
      /Users/jacoblegrone/go/pkg/mod/go.uber.org/[email protected]/app.go:769 +0x120
  go.uber.org/fx.(*App).Start()
      /Users/jacoblegrone/go/pkg/mod/go.uber.org/[email protected]/app.go:646 +0x280
  go.temporal.io/server/temporal.(*ServerImpl).startServices.func1()
      /Users/jacoblegrone/Development/github.com/temporalio/temporal/temporal/server_impl.go:158 +0x58
  go.temporal.io/server/temporal.(*ServerImpl).startServices.func2()
      /Users/jacoblegrone/Development/github.com/temporalio/temporal/temporal/server_impl.go:163 +0x44
==================
--- FAIL: TestBaseServerOptions (0.18s)
    testing.go:1319: race detected during execution of test
FAIL
coverage: 77.1% of statements
FAIL	go.temporal.io/server/temporaltest	9.363s
FAIL
make: *** [unit-test-coverage] Error 1

Perhaps we should quarantine temporaltest in an internal package for now until we know it can be used reliably?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. The only way I can see this happening is if something swallows log.Fatal and doesn't end the process.
  2. Scanner.Stop: I think this one is fixed now
  3. Race in tchannel: I'm not sure but I think this is a long-standing bug in tchannel. We'll eventually remove the dependency but for now we might have to live with it.

In general, bugs when you stop the server immediately after starting or before it's fully started are not surprising. I did a little fx refactoring to try to avoid some of them so if you merge with the latest changes I think those should be reduced.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'd set up the test targets so that these run in "integration" tests and not unit or functional. Probably all of ./temporal should be there too.

UNIT_TEST_DIRS := $(filter-out $(FUNCTIONAL_TEST_ROOT)% $(FUNCTIONAL_TEST_XDC_ROOT)% $(FUNCTIONAL_TEST_NDC_ROOT)% $(DB_INTEGRATION_TEST_ROOT)% $(DB_TOOL_INTEGRATION_TEST_ROOT)%,$(TEST_DIRS))

# github.com/urfave/cli/[email protected] - needs to accept comma in values before unlocking https://github.com/urfave/cli/pull/1241.
Expand Down
78 changes: 78 additions & 0 deletions internal/temporalite/freeport.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// The MIT License
//
// Copyright (c) 2021 Datadog, Inc.
//
// Copyright (c) 2020 Temporal Technologies Inc. All rights reserved.
//
// Copyright (c) 2020 Uber Technologies, Inc.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package temporalite

import (
"fmt"
"net"
)

// Modified from https://github.com/phayes/freeport/blob/95f893ade6f232a5f1511d61735d89b1ae2df543/freeport.go
jlegrone marked this conversation as resolved.
Show resolved Hide resolved

func newPortProvider() *portProvider {
return &portProvider{}
}

type portProvider struct {
listeners []*net.TCPListener
}

// GetFreePort asks the kernel for a free open port that is ready to use.
func (p *portProvider) GetFreePort() (int, error) {
addr, err := net.ResolveTCPAddr("tcp", "127.0.0.1:0")
if err != nil {
if addr, err = net.ResolveTCPAddr("tcp6", "[::1]:0"); err != nil {
panic(fmt.Sprintf("temporalite: failed to get free port: %v", err))
jlegrone marked this conversation as resolved.
Show resolved Hide resolved
}
}

l, err := net.ListenTCP("tcp", addr)
if err != nil {
return 0, err
}

p.listeners = append(p.listeners, l)

return l.Addr().(*net.TCPAddr).Port, nil
}

func (p *portProvider) MustGetFreePort() int {
port, err := p.GetFreePort()
if err != nil {
panic(err)
}
return port
}

func (p *portProvider) Close() error {
for _, l := range p.listeners {
if err := l.Close(); err != nil {
return err
}
}
return nil
}
Loading