-
Notifications
You must be signed in to change notification settings - Fork 894
feat(coderd/database/dbtestutil): set default database timezone to non-UTC in unit tests #9672
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
Changes from 7 commits
355b16b
986db8b
fc3ba52
b3c559a
f57dc9d
d3d1274
9f1f5c6
7c2ff2f
eecfcdb
d327131
7680984
d051bbb
da059dc
0d425ba
d97ff2f
f18c6b5
5a8aa8b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,13 +3,17 @@ package dbtestutil | |
import ( | ||
"context" | ||
"database/sql" | ||
"fmt" | ||
"net/url" | ||
"os" | ||
"strings" | ||
"testing" | ||
|
||
"github.com/stretchr/testify/require" | ||
|
||
"github.com/coder/coder/v2/coderd/database" | ||
"github.com/coder/coder/v2/coderd/database/dbfake" | ||
"github.com/coder/coder/v2/coderd/database/dbtestutil/randtz" | ||
"github.com/coder/coder/v2/coderd/database/postgres" | ||
"github.com/coder/coder/v2/coderd/database/pubsub" | ||
) | ||
|
@@ -19,9 +23,30 @@ func WillUsePostgres() bool { | |
return os.Getenv("DB") != "" | ||
} | ||
|
||
func NewDB(t testing.TB) (database.Store, pubsub.Pubsub) { | ||
type options struct { | ||
fixedTimezone string | ||
} | ||
|
||
type Option func(*options) | ||
|
||
// WithTimezone sets the database to the defined timezone instead of | ||
// to a random one. | ||
// | ||
// Deprecated: If you need to use this, you may have a timezone-related bug. | ||
func WithTimezone(tz string) Option { | ||
return func(o *options) { | ||
o.fixedTimezone = tz | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. review: I originally exposed this as |
||
|
||
func NewDB(t testing.TB, opts ...Option) (database.Store, pubsub.Pubsub) { | ||
t.Helper() | ||
|
||
var o options | ||
for _, opt := range opts { | ||
opt(&o) | ||
} | ||
|
||
db := dbfake.New() | ||
ps := pubsub.NewInMemory() | ||
if WillUsePostgres() { | ||
|
@@ -35,6 +60,15 @@ func NewDB(t testing.TB) (database.Store, pubsub.Pubsub) { | |
require.NoError(t, err) | ||
t.Cleanup(closePg) | ||
} | ||
|
||
if o.fixedTimezone == "" { | ||
// To make sure we find timezone-related issues, we set the timezone | ||
// of the database to a random one. | ||
o.fixedTimezone = randtz.Name(t) | ||
} | ||
dbName := dbNameFromConnectionURL(t, connectionURL) | ||
setDBTimezone(t, connectionURL, dbName, o.fixedTimezone) | ||
|
||
sqlDB, err := sql.Open("postgres", connectionURL) | ||
require.NoError(t, err) | ||
t.Cleanup(func() { | ||
|
@@ -51,3 +85,28 @@ func NewDB(t testing.TB) (database.Store, pubsub.Pubsub) { | |
|
||
return db, ps | ||
} | ||
|
||
// setRandDBTimezone sets the timezone of the database to the given timezone. | ||
func setDBTimezone(t testing.TB, dbURL, dbname, tz string) { | ||
t.Helper() | ||
|
||
sqlDB, err := sql.Open("postgres", dbURL) | ||
require.NoError(t, err) | ||
defer func() { | ||
// The updated timezone only comes into effect on reconnect, so close | ||
// the DB after we're done. | ||
_ = sqlDB.Close() | ||
}() | ||
|
||
// nolint: gosec // This unfortunately does not work with placeholders. | ||
_, err = sqlDB.Exec(fmt.Sprintf("ALTER DATABASE %s SET TIMEZONE TO %q", dbname, tz)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. self-review: I hate this but it appears necessary. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's fine in tests, IMO. It's an unfortunate limitation of some PostgreSQL queries.
johnstcn marked this conversation as resolved.
Show resolved
Hide resolved
|
||
require.NoError(t, err, "failed to set timezone for database") | ||
} | ||
|
||
// dbNameFromConnectionURL returns the database name from the given connection URL, | ||
// where connectionURL is of the form postgres://user:pass@host:port/dbname | ||
func dbNameFromConnectionURL(t testing.TB, connectionURL string) string { | ||
u, err := url.Parse(connectionURL) | ||
require.NoError(t, err) | ||
return strings.TrimPrefix(u.Path, "/") | ||
} |
Uh oh!
There was an error while loading. Please reload this page.