Files
threshold/internal/db/schema/migrations/oss/postgres_26_01_test.go
T
Timothy Messier fd5d15af27 feat(config): Add database config options for idle connection management (#2176)
This adds two new config options for the `database` stanza:

- `max_idle_connections`
- `max_idle_time`

These correspond to settings for the underlying `sql.DB` instance. They
can be used to have finer control over the controller's database
connection pool. For example this can be used to mitigate the high
connection overhead when connecting to postgres by setting a high
`max_idle_connections` and either setting `max_idle_time` to zero or to
a high duration.

Alternatively, if using a connection pool like pgpool-II or pgbouncer,
`max_idle_connections` can be set to 0.

See:
    https://pkg.go.dev/database/sql#DB.SetMaxIdleConns
    https://pkg.go.dev/database/sql#DB.SetConnMaxIdleTime
    https://www.pgpool.net/mediawiki/index.php/Main_Page
    https://www.pgbouncer.org/
2022-07-05 15:25:55 -04:00

230 lines
7.4 KiB
Go

package oss_test
import (
"context"
"testing"
"github.com/hashicorp/boundary/internal/db"
"github.com/hashicorp/boundary/internal/db/common"
"github.com/hashicorp/boundary/internal/db/schema"
"github.com/hashicorp/boundary/testing/dbtest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestMigrations_WareHouse_HostAddresses(t *testing.T) {
const (
priorMigration = 25001
currentMigration = 26001
)
t.Parallel()
ctx := context.Background()
dialect := dbtest.Postgres
c, u, _, err := dbtest.StartUsingTemplate(dialect, dbtest.WithTemplate(dbtest.Template1))
require.NoError(t, err)
t.Cleanup(func() {
require.NoError(t, c())
})
d, err := common.SqlOpen(dialect, u)
require.NoError(t, err)
// migration to the prior migration (before the one we want to test)
m, err := schema.NewManager(ctx, schema.Dialect(dialect), d, schema.WithEditions(
schema.TestCreatePartialEditions(schema.Dialect(dialect), schema.PartialEditions{"oss": priorMigration}),
))
require.NoError(t, err)
require.NoError(t, m.ApplyMigrations(ctx))
state, err := m.CurrentState(ctx)
require.NoError(t, err)
want := &schema.State{
Initialized: true,
Editions: []schema.EditionState{
{
Name: "oss",
BinarySchemaVersion: priorMigration,
DatabaseSchemaVersion: priorMigration,
DatabaseSchemaState: schema.Equal,
},
},
}
require.Equal(t, want, state)
// get a connection
dbType, err := db.StringToDbType(dialect)
require.NoError(t, err)
conn, err := db.Open(ctx, dbType, u)
require.NoError(t, err)
rw := db.New(conn)
type whAddress struct {
Address string
AddressType string
IpAddressFamily string
PrivateIpAddressIndicator string
DnsName string
Ip4Address string
Ip6Address string
}
addresses := []whAddress{
{
Address: "10.0.0.1",
AddressType: "IP Address",
IpAddressFamily: "IPv4",
PrivateIpAddressIndicator: "Private IP address",
DnsName: "Not Applicable",
Ip4Address: "10.0.0.1",
Ip6Address: "Not Applicable",
},
{
Address: "12.3.4.5",
AddressType: "IP Address",
IpAddressFamily: "IPv4",
PrivateIpAddressIndicator: "Public IP address",
DnsName: "Not Applicable",
Ip4Address: "12.3.4.5",
Ip6Address: "Not Applicable",
},
{
Address: "fe80::1234:5678:1234:5678",
AddressType: "IP Address",
IpAddressFamily: "IPv6",
PrivateIpAddressIndicator: "Private IP address",
DnsName: "Not Applicable",
Ip4Address: "Not Applicable",
Ip6Address: "fe80::1234:5678:1234:5678",
},
{
Address: "2001:4860:4860::8888",
AddressType: "IP Address",
IpAddressFamily: "IPv6",
PrivateIpAddressIndicator: "Public IP address",
DnsName: "Not Applicable",
Ip4Address: "Not Applicable",
Ip6Address: "2001:4860:4860::8888",
},
{
Address: "foo",
AddressType: "DNS Name",
IpAddressFamily: "Not Applicable",
PrivateIpAddressIndicator: "Not Applicable",
DnsName: "foo",
Ip4Address: "Not Applicable",
Ip6Address: "Not Applicable",
},
{
Address: "something.com",
AddressType: "DNS Name",
IpAddressFamily: "Not Applicable",
PrivateIpAddressIndicator: "Not Applicable",
DnsName: "something.com",
Ip4Address: "Not Applicable",
Ip6Address: "Not Applicable",
},
{
Address: "10.0.foo.com",
AddressType: "DNS Name",
IpAddressFamily: "Not Applicable",
PrivateIpAddressIndicator: "Not Applicable",
DnsName: "10.0.foo.com",
Ip4Address: "Not Applicable",
Ip6Address: "Not Applicable",
},
{
Address: "not valid anything",
AddressType: "DNS Name",
IpAddressFamily: "Not Applicable",
PrivateIpAddressIndicator: "Not Applicable",
DnsName: "not valid anything",
Ip4Address: "Not Applicable",
Ip6Address: "Not Applicable",
},
{
Address: "Unsupported",
AddressType: "Unknown",
IpAddressFamily: "Not Applicable",
PrivateIpAddressIndicator: "Not Applicable",
DnsName: "Not Applicable",
Ip4Address: "Not Applicable",
Ip6Address: "Not Applicable",
},
{
Address: "Unknown",
AddressType: "Unknown",
IpAddressFamily: "Not Applicable",
PrivateIpAddressIndicator: "Not Applicable",
DnsName: "Not Applicable",
Ip4Address: "Not Applicable",
Ip6Address: "Not Applicable",
},
}
{
q := `
insert into wh_host_dimension
(host_id, host_type, host_name, host_description, host_address,
host_set_id, host_set_type, host_set_name, host_set_description,
host_catalog_id, host_catalog_type, host_catalog_name, host_catalog_description,
target_id, target_type, target_name, target_description, target_default_port_number,
target_session_max_seconds, target_session_connection_limit,
project_id, project_name, project_description,
organization_id, organization_name, organization_description,
current_row_indicator, row_effective_time, row_expiration_time)
values
('h_1234567890', 'static', 'None', 'None', ?,
'hs_1234567890', 'static', 'None', 'None',
'hc_1234567890', 'static', 'None', 'None',
't_1234567890', 'tcp', 'None', 'None', 0,
30, 1,
'p_1234567890', 'None', 'None',
'o_1234567890', 'None', 'None',
'Expired', current_timestamp, current_timestamp)
`
for _, a := range addresses {
_, err := rw.Exec(ctx, q, []interface{}{a.Address})
require.NoError(t, err)
}
// Duplicate a few records...
_, err := rw.Exec(ctx, q, []interface{}{addresses[1].Address})
require.NoError(t, err)
_, err = rw.Exec(ctx, q, []interface{}{addresses[5].Address})
require.NoError(t, err)
}
// now we're ready for the migration we want to test.
m, err = schema.NewManager(ctx, schema.Dialect(dialect), d, schema.WithEditions(
schema.TestCreatePartialEditions(schema.Dialect(dialect), schema.PartialEditions{"oss": currentMigration}),
))
require.NoError(t, err)
require.NoError(t, m.ApplyMigrations(ctx))
state, err = m.CurrentState(ctx)
require.NoError(t, err)
want = &schema.State{
Initialized: true,
Editions: []schema.EditionState{
{
Name: "oss",
BinarySchemaVersion: currentMigration,
DatabaseSchemaVersion: currentMigration,
DatabaseSchemaState: schema.Equal,
},
},
}
require.Equal(t, want, state)
// Now read all the converted rows and see if we have transformed and
// calculated the values as expected.
{
rows, err := rw.Query(ctx, "select * from wh_network_address_dimension", nil)
require.NoError(t, err)
var results []whAddress
for rows.Next() {
var addr whAddress
require.NoError(t, rw.ScanRows(context.Background(), rows, &addr))
results = append(results, addr)
}
assert.ElementsMatch(t, results, addresses)
}
}