chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
# go-sql-server-driver tests (Doltgres port)
|
||||
|
||||
These tests are ported from Dolt's
|
||||
`integration-tests/go-sql-server-driver`. They exercise a real `doltgres`
|
||||
server process over the Postgres wire protocol, driven either by the YAML test
|
||||
definition format (`tests/*.yaml`, run via `testdef.go`) or by standalone Go
|
||||
tests that use the `driver` package directly.
|
||||
|
||||
## Running
|
||||
|
||||
The tests locate the `doltgres` binary via the `DOLTGRES_BIN_PATH` environment
|
||||
variable, falling back to `doltgres` on the `PATH`.
|
||||
|
||||
```
|
||||
DOLTGRES_BIN_PATH=/path/to/doltgres go test ./...
|
||||
```
|
||||
|
||||
## Differences from the Dolt suite
|
||||
|
||||
The port preserves the structure and intent of the Dolt tests, translating only
|
||||
what the Postgres dialect and wire protocol, and the doltgres binary, require:
|
||||
|
||||
* **Server CLI.** `doltgres` has a minimal CLI (`--config`, `--data-dir`) and
|
||||
*no* `-P`/`-l`/`--max-connections` flags. The listener port can only be set
|
||||
via the config file, so the test framework (`MakeServer` in `testdef.go`)
|
||||
generates/merges a config file that injects the dynamic port, host, and a
|
||||
unique unix socket. Ported YAML expresses server settings via a config file
|
||||
(referenced with `--config`) rather than via Dolt CLI flags.
|
||||
|
||||
* **Data-dir model.** Doltgres serves databases out of a data-dir; each "repo"
|
||||
is a database subdirectory. The server runs from the store (data-dir) with
|
||||
`--data-dir=.`, and `with_files` are written relative to the store directory.
|
||||
Databases are initialized by briefly running a server (there is no
|
||||
`dolt init` equivalent).
|
||||
|
||||
* **Wire protocol.** Connections use the pgx stdlib driver. Default user is
|
||||
`postgres`, password `password`.
|
||||
|
||||
* **SQL dialect.** MySQL syntax is translated to Postgres (e.g.
|
||||
`AUTO_INCREMENT` -> `SERIAL`/`GENERATED`, backtick identifiers -> unquoted or
|
||||
double-quoted, `int`/`varchar(n)` are fine, `select ... from dual` ->
|
||||
`select ...`).
|
||||
|
||||
* **DOLT procedures.** Dolt's `CALL DOLT_*(...)` / `SELECT DOLT_*()` become
|
||||
`SELECT dolt_*(...)` in Doltgres. Result columns default to the function name
|
||||
(e.g. `dolt_add`), and the value is rendered as a Postgres array, e.g.
|
||||
`{0}`.
|
||||
|
||||
* **Result columns.** Postgres lowercases unquoted identifiers and uses the
|
||||
expression text / alias for computed columns; expected `columns:` and `rows:`
|
||||
are adjusted accordingly. Prefer explicit `AS` aliases.
|
||||
|
||||
* **Cluster / remotesapi replication.** Doltgres does not yet implement Dolt's
|
||||
cluster replication or the remotes API. Config structs for these are mirrored
|
||||
into doltgres so the config files parse, but the tests that depend on the
|
||||
feature are marked `skip:` with a reason until the feature lands.
|
||||
|
||||
When a ported test does not pass yet (missing feature or behavioral
|
||||
difference), it is marked with `skip:` (YAML) or `t.Skip(...)` (Go) with a short
|
||||
reason, per the porting instructions.
|
||||
@@ -0,0 +1,185 @@
|
||||
parallel: false
|
||||
tests:
|
||||
- name: users and grants cannot be run on standby
|
||||
skip: "cluster replication / MySQL grants not yet supported in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server2
|
||||
queries:
|
||||
- exec: 'CREATE USER "brian" WITH PASSWORD ''brianspassword'''
|
||||
error_match: 'database server is set to read only mode'
|
||||
- exec: 'GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO "aaron"'
|
||||
error_match: 'database server is set to read only mode'
|
||||
- name: create database cannot be run on standby
|
||||
skip: "cluster replication not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server2
|
||||
queries:
|
||||
- exec: 'CREATE DATABASE my_db'
|
||||
error_match: 'database server is set to read only mode'
|
||||
- name: drop database cannot be run on standby
|
||||
skip: "cluster replication not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: "SET dolt_cluster_ack_writes_timeout_secs = 10"
|
||||
- exec: 'CREATE DATABASE repo1'
|
||||
- exec: 'USE repo1'
|
||||
- exec: 'CREATE TABLE vals (i INT PRIMARY KEY)'
|
||||
- exec: 'INSERT INTO vals VALUES (0),(1),(2),(3),(4)'
|
||||
- on: server2
|
||||
queries:
|
||||
- exec: 'DROP DATABASE repo1'
|
||||
error_match: 'database server is set to read only mode'
|
||||
- name: when a server becomes primary it accepts writes
|
||||
skip: "cluster replication not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server2
|
||||
queries:
|
||||
- exec: "select dolt_assume_cluster_role('primary', 2)"
|
||||
- on: server2
|
||||
queries:
|
||||
- exec: "SET dolt_cluster_ack_writes_timeout_secs = 10"
|
||||
- exec: 'CREATE DATABASE repo1'
|
||||
- exec: 'USE repo1'
|
||||
- exec: 'CREATE TABLE vals (i INT PRIMARY KEY)'
|
||||
- exec: 'INSERT INTO vals VALUES (0),(1),(2),(3),(4)'
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: 'USE repo1'
|
||||
- query: 'SELECT COUNT(*) as count FROM vals'
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows:
|
||||
- ["5"]
|
||||
@@ -0,0 +1,460 @@
|
||||
parallel: true
|
||||
tests:
|
||||
- name: tls, bad root, failover to standby fails
|
||||
skip: "cluster replication not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: https://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
tls_key: key.pem
|
||||
tls_cert: cert.pem
|
||||
tls_ca: root.pem
|
||||
- name: key.pem
|
||||
source_path: $TESTGENDIR/rsa_key.pem
|
||||
- name: cert.pem
|
||||
source_path: $TESTGENDIR/rsa_chain.pem
|
||||
- name: root.pem
|
||||
source_path: $TESTGENDIR/ed25519_root.pem
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: https://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
tls_key: key.pem
|
||||
tls_cert: cert.pem
|
||||
tls_ca: root.pem
|
||||
- name: key.pem
|
||||
source_path: $TESTGENDIR/rsa_key.pem
|
||||
- name: cert.pem
|
||||
source_path: $TESTGENDIR/rsa_chain.pem
|
||||
- name: root.pem
|
||||
source_path: $TESTGENDIR/rsa_root.pem
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: 'create database repo1'
|
||||
- exec: "use repo1"
|
||||
- query: "select dolt_assume_cluster_role('standby', '11')"
|
||||
error_match: failed to transition from primary to standby gracefully
|
||||
- exec: "create table vals (i int primary key)"
|
||||
- exec: "insert into vals values (0)"
|
||||
- name: tls, expired leaf, failover to standby fails
|
||||
skip: "cluster replication not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: https://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
tls_key: key.pem
|
||||
tls_cert: cert.pem
|
||||
tls_ca: root.pem
|
||||
- name: key.pem
|
||||
source_path: $TESTGENDIR/rsa_key.pem
|
||||
- name: cert.pem
|
||||
source_path: $TESTGENDIR/rsa_chain.pem
|
||||
- name: root.pem
|
||||
source_path: $TESTGENDIR/rsa_root.pem
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: https://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
tls_key: key.pem
|
||||
tls_cert: cert.pem
|
||||
tls_ca: root.pem
|
||||
- name: key.pem
|
||||
source_path: $TESTGENDIR/rsa_exp_key.pem
|
||||
- name: cert.pem
|
||||
source_path: $TESTGENDIR/rsa_exp_chain.pem
|
||||
- name: root.pem
|
||||
source_path: $TESTGENDIR/rsa_root.pem
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: 'create database repo1'
|
||||
- exec: "use repo1"
|
||||
- query: "select dolt_assume_cluster_role('standby', '11')"
|
||||
error_match: failed to transition from primary to standby gracefully
|
||||
- exec: "create table vals (i int primary key)"
|
||||
- exec: "insert into vals values (0)"
|
||||
- name: tls, mismatched dns, failover to standby fails
|
||||
skip: "cluster replication not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: https://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
tls_key: key.pem
|
||||
tls_cert: cert.pem
|
||||
tls_ca: root.pem
|
||||
server_name_dns: ["does-not-match.dolt-instance.dolt-integration-test.example"]
|
||||
- name: key.pem
|
||||
source_path: $TESTGENDIR/rsa_key.pem
|
||||
- name: cert.pem
|
||||
source_path: $TESTGENDIR/rsa_chain.pem
|
||||
- name: root.pem
|
||||
source_path: $TESTGENDIR/rsa_root.pem
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: https://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
tls_key: key.pem
|
||||
tls_cert: cert.pem
|
||||
tls_ca: root.pem
|
||||
- name: key.pem
|
||||
source_path: $TESTGENDIR/rsa_key.pem
|
||||
- name: cert.pem
|
||||
source_path: $TESTGENDIR/rsa_chain.pem
|
||||
- name: root.pem
|
||||
source_path: $TESTGENDIR/rsa_root.pem
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: 'create database repo1'
|
||||
- exec: "use repo1"
|
||||
- query: "select dolt_assume_cluster_role('standby', '11')"
|
||||
error_match: failed to transition from primary to standby gracefully
|
||||
- exec: "create table vals (i int primary key)"
|
||||
- exec: "insert into vals values (0)"
|
||||
- name: tls, mismatched url, failover to standby fails
|
||||
skip: "cluster replication not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: https://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
tls_key: key.pem
|
||||
tls_cert: cert.pem
|
||||
tls_ca: root.pem
|
||||
server_name_urls: ["spiffe://dolt-integration-tests.dev.trust.dolthub.com.example/dolt-instance/does-not-match"]
|
||||
- name: key.pem
|
||||
source_path: $TESTGENDIR/rsa_key.pem
|
||||
- name: cert.pem
|
||||
source_path: $TESTGENDIR/rsa_chain.pem
|
||||
- name: root.pem
|
||||
source_path: $TESTGENDIR/rsa_root.pem
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: https://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
tls_key: key.pem
|
||||
tls_cert: cert.pem
|
||||
tls_ca: root.pem
|
||||
- name: key.pem
|
||||
source_path: $TESTGENDIR/rsa_key.pem
|
||||
- name: cert.pem
|
||||
source_path: $TESTGENDIR/rsa_chain.pem
|
||||
- name: root.pem
|
||||
source_path: $TESTGENDIR/rsa_root.pem
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: 'create database repo1'
|
||||
- exec: "use repo1"
|
||||
- query: "select dolt_assume_cluster_role('standby', '11')"
|
||||
error_match: failed to transition from primary to standby gracefully
|
||||
- exec: "create table vals (i int primary key)"
|
||||
- exec: "insert into vals values (0)"
|
||||
- name: tls, good rsa certs, create new database, primary replicates to standby, fails over, new primary replicates to standby, fails over, new primary has all writes
|
||||
skip: "cluster replication not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: https://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
tls_key: key.pem
|
||||
tls_cert: cert.pem
|
||||
tls_ca: root.pem
|
||||
- name: key.pem
|
||||
source_path: $TESTGENDIR/rsa_key.pem
|
||||
- name: cert.pem
|
||||
source_path: $TESTGENDIR/rsa_chain.pem
|
||||
- name: root.pem
|
||||
source_path: $TESTGENDIR/rsa_root.pem
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: https://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
tls_key: key.pem
|
||||
tls_cert: cert.pem
|
||||
tls_ca: root.pem
|
||||
- name: key.pem
|
||||
source_path: $TESTGENDIR/rsa_key.pem
|
||||
- name: cert.pem
|
||||
source_path: $TESTGENDIR/rsa_chain.pem
|
||||
- name: root.pem
|
||||
source_path: $TESTGENDIR/rsa_root.pem
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: 'create database repo1'
|
||||
- exec: 'use repo1'
|
||||
- exec: 'create table vals (i int primary key)'
|
||||
- exec: 'insert into vals values (0),(1),(2),(3),(4)'
|
||||
- query: "select dolt_assume_cluster_role('standby', 2)"
|
||||
result:
|
||||
columns: ["dolt_assume_cluster_role"]
|
||||
rows: [["{0}"]]
|
||||
- on: server2
|
||||
queries:
|
||||
- exec: 'use repo1'
|
||||
- query: "select count(*) as count from vals"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
- query: "select dolt_assume_cluster_role('primary', 2)"
|
||||
result:
|
||||
columns: ["dolt_assume_cluster_role"]
|
||||
rows: [["{0}"]]
|
||||
- on: server2
|
||||
queries:
|
||||
- exec: 'use repo1'
|
||||
- exec: 'insert into vals values (5),(6),(7),(8),(9)'
|
||||
- query: "select dolt_assume_cluster_role('standby', 3)"
|
||||
result:
|
||||
columns: ["dolt_assume_cluster_role"]
|
||||
rows: [["{0}"]]
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: 'use repo1'
|
||||
- query: "select count(*) as count from vals"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["10"]]
|
||||
- query: "select dolt_assume_cluster_role('primary', 3)"
|
||||
result:
|
||||
columns: ["dolt_assume_cluster_role"]
|
||||
rows: [["{0}"]]
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: 'use repo1'
|
||||
- exec: 'insert into vals values (10),(11),(12),(13),(14)'
|
||||
- query: "select count(*) as count from vals"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["15"]]
|
||||
- name: tls, good ed25519 certs, create new database, primary replicates to standby, fails over, new primary replicates to standby, fails over, new primary has all writes
|
||||
skip: "cluster replication not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: https://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
tls_key: key.pem
|
||||
tls_cert: cert.pem
|
||||
tls_ca: root.pem
|
||||
server_name_urls: ["spiffe://dolt-integration-tests.dev.trust.dolthub.com.example/dolt-instance"]
|
||||
server_name_dns: ["dolt-instance.dolt-integration-test.example"]
|
||||
- name: key.pem
|
||||
source_path: $TESTGENDIR/ed25519_key.pem
|
||||
- name: cert.pem
|
||||
source_path: $TESTGENDIR/ed25519_chain.pem
|
||||
- name: root.pem
|
||||
source_path: $TESTGENDIR/ed25519_root.pem
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: https://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
tls_key: key.pem
|
||||
tls_cert: cert.pem
|
||||
tls_ca: root.pem
|
||||
server_name_urls: ["spiffe://dolt-integration-tests.dev.trust.dolthub.com.example/dolt-instance"]
|
||||
server_name_dns: ["dolt-instance.dolt-integration-test.example"]
|
||||
- name: key.pem
|
||||
source_path: $TESTGENDIR/ed25519_key.pem
|
||||
- name: cert.pem
|
||||
source_path: $TESTGENDIR/ed25519_chain.pem
|
||||
- name: root.pem
|
||||
source_path: $TESTGENDIR/ed25519_root.pem
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: 'create database repo1'
|
||||
- exec: 'use repo1'
|
||||
- exec: 'create table vals (i int primary key)'
|
||||
- exec: 'insert into vals values (0),(1),(2),(3),(4)'
|
||||
- query: "select dolt_assume_cluster_role('standby', 2)"
|
||||
result:
|
||||
columns: ["dolt_assume_cluster_role"]
|
||||
rows: [["{0}"]]
|
||||
- on: server2
|
||||
queries:
|
||||
- exec: 'use repo1'
|
||||
- query: "select count(*) as count from vals"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
- query: "select dolt_assume_cluster_role('primary', 2)"
|
||||
result:
|
||||
columns: ["dolt_assume_cluster_role"]
|
||||
rows: [["{0}"]]
|
||||
- on: server2
|
||||
queries:
|
||||
- exec: 'use repo1'
|
||||
- exec: 'insert into vals values (5),(6),(7),(8),(9)'
|
||||
- query: "select dolt_assume_cluster_role('standby', 3)"
|
||||
result:
|
||||
columns: ["dolt_assume_cluster_role"]
|
||||
rows: [["{0}"]]
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: 'use repo1'
|
||||
- query: "select count(*) as count from vals"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["10"]]
|
||||
- query: "select dolt_assume_cluster_role('primary', 3)"
|
||||
result:
|
||||
columns: ["dolt_assume_cluster_role"]
|
||||
rows: [["{0}"]]
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: 'use repo1'
|
||||
- exec: 'insert into vals values (10),(11),(12),(13),(14)'
|
||||
- query: "select count(*) as count from vals"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["15"]]
|
||||
+418
@@ -0,0 +1,418 @@
|
||||
parallel: true
|
||||
tests:
|
||||
- name: users and grants replicate
|
||||
skip: "cluster replication / MySQL grants not yet supported in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: "SET dolt_cluster_ack_writes_timeout_secs = 10"
|
||||
- exec: 'create database repo1'
|
||||
- exec: "use repo1"
|
||||
- exec: 'create table vals (i int primary key)'
|
||||
- exec: 'insert into vals values (0),(1),(2),(3),(4)'
|
||||
- exec: 'create user aaron with password ''aaronspassword'''
|
||||
- exec: 'GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO aaron'
|
||||
- exec: 'insert into vals values (5),(6),(7),(8),(9)'
|
||||
- on: server1
|
||||
user: 'aaron'
|
||||
password: 'aaronspassword'
|
||||
queries:
|
||||
- exec: "use repo1"
|
||||
- exec: 'insert into vals values (10),(11),(12),(13),(14)'
|
||||
- on: server2
|
||||
user: 'aaron'
|
||||
password: 'aaronspassword'
|
||||
queries:
|
||||
- exec: "use repo1"
|
||||
- query: 'select count(*) as count from vals'
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["15"]]
|
||||
- name: branch control replicates
|
||||
skip: "cluster replication / MySQL grants not yet supported in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: "SET dolt_cluster_ack_writes_timeout_secs = 10"
|
||||
- exec: 'create database repo1'
|
||||
- exec: "use repo1"
|
||||
- exec: 'create table vals (i int primary key)'
|
||||
- exec: 'insert into vals values (0),(1),(2),(3),(4)'
|
||||
- exec: 'create user aaron with password ''aaronspassword'''
|
||||
- exec: 'GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO aaron'
|
||||
- exec: 'create user brian with password ''brianpassword'''
|
||||
- exec: 'GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO brian'
|
||||
- exec: 'delete from dolt_branch_control'
|
||||
- exec: 'insert into dolt_branch_control values (''repo1'', ''main'', ''aaron'', ''%'', ''admin'')'
|
||||
- on: server1
|
||||
user: 'aaron'
|
||||
password: 'aaronspassword'
|
||||
queries:
|
||||
- exec: "use repo1"
|
||||
- exec: 'insert into vals values (5),(6),(7),(8),(9)'
|
||||
- exec: 'insert into vals values (10),(11),(12),(13),(14)'
|
||||
# Assert brian cannot write to `main` on server1
|
||||
- on: server1
|
||||
user: 'brian'
|
||||
password: 'brianpassword'
|
||||
queries:
|
||||
- exec: "use repo1"
|
||||
- exec: 'insert into vals values (15),(16),(17),(18),(19)'
|
||||
error_match: 'does not have the correct permissions on branch `main`'
|
||||
# Failover to `server2` so we can assert brian is restricted there as well.
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: "use repo1"
|
||||
- exec: "select dolt_assume_cluster_role('standby', 2)"
|
||||
- on: server2
|
||||
queries:
|
||||
- exec: "use repo1"
|
||||
- exec: "select dolt_assume_cluster_role('primary', 2)"
|
||||
# Assert aaron can write to main on server2 and brian cannot.
|
||||
- on: server2
|
||||
user: 'aaron'
|
||||
password: 'aaronspassword'
|
||||
queries:
|
||||
- exec: "use repo1"
|
||||
- query: 'select count(*) as count from vals'
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["15"]]
|
||||
- exec: 'insert into vals values (20),(21),(22),(23),(24)'
|
||||
- on: server2
|
||||
user: 'brian'
|
||||
password: 'brianpassword'
|
||||
queries:
|
||||
- exec: "use repo1"
|
||||
- query: 'select count(*) as count from vals'
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["20"]]
|
||||
- exec: 'insert into vals values (25),(26),(27),(28),(29)'
|
||||
error_match: 'does not have the correct permissions on branch `main`'
|
||||
# Now we are going to grant brian permission, and fail back over to server1,
|
||||
# and ensure brian can write to the branch there.
|
||||
- on: server2
|
||||
user: 'aaron'
|
||||
password: 'aaronspassword'
|
||||
queries:
|
||||
- exec: "use repo1"
|
||||
- exec: 'insert into dolt_branch_control values (''repo1'', ''main'', ''brian'', ''%'', ''write'')'
|
||||
- exec: 'insert into vals values (30)'
|
||||
- on: server2
|
||||
queries:
|
||||
- exec: "select dolt_assume_cluster_role('standby', 3)"
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: "use repo1"
|
||||
- exec: "select dolt_assume_cluster_role('primary', 3)"
|
||||
# Here brian should be allowed to write now.
|
||||
- on: server1
|
||||
user: 'brian'
|
||||
password: 'brianpassword'
|
||||
queries:
|
||||
- exec: "use repo1"
|
||||
- exec: 'insert into vals values (31)'
|
||||
- name: branch control block on write replication
|
||||
skip: "cluster replication / MySQL grants not yet supported in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
- name: nocluster.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
server:
|
||||
args: ["--config", "nocluster.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: 'create user aaron with password ''aaronspassword'''
|
||||
- exec: 'create database repo1'
|
||||
- exec: 'use repo1'
|
||||
- exec: "SET dolt_cluster_ack_writes_timeout_secs = 2"
|
||||
- exec: 'delete from dolt_branch_control'
|
||||
- query: 'show warnings'
|
||||
result:
|
||||
columns: ["Level", "Code", "Message"]
|
||||
rows: [["Warning", "3024", "Timed out replication of commit to 1 out of 1 replicas."]]
|
||||
- exec: 'insert into dolt_branch_control values (''repo1'', ''main'', ''aaron'', ''%'', ''admin'')'
|
||||
- on: server2
|
||||
restart_server:
|
||||
args: ["--config", "server.yaml"]
|
||||
- on: server1
|
||||
restart_server: {}
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: "SET dolt_cluster_ack_writes_timeout_secs = 10"
|
||||
- exec: 'use repo1'
|
||||
- exec: 'delete from dolt_branch_control'
|
||||
- query: 'show warnings'
|
||||
result:
|
||||
columns: ["Level", "Code", "Message"]
|
||||
rows: []
|
||||
- on: server2
|
||||
queries:
|
||||
- query: 'show warnings'
|
||||
result:
|
||||
columns: ["Level", "Code", "Message"]
|
||||
rows: []
|
||||
- name: users and grants block on write replication
|
||||
skip: "cluster replication / MySQL grants not yet supported in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
- name: nocluster.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
server:
|
||||
args: ["--config", "nocluster.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: "SET dolt_cluster_ack_writes_timeout_secs = 2"
|
||||
- exec: 'create user aaron with password ''aaronspassword'''
|
||||
- query: 'show warnings'
|
||||
result:
|
||||
columns: ["Level", "Code", "Message"]
|
||||
rows: [["Warning", "3024", "Timed out replication of commit to 1 out of 1 replicas."]]
|
||||
- on: server2
|
||||
restart_server:
|
||||
args: ["--config", "server.yaml"]
|
||||
- on: server1
|
||||
restart_server: {}
|
||||
- on: server1
|
||||
queries:
|
||||
# Because we run in parallel, do not be too agressive about the timeout...
|
||||
- exec: "SET dolt_cluster_ack_writes_timeout_secs = 10"
|
||||
- exec: 'create user brian with password ''brianspassword'''
|
||||
- query: 'show warnings'
|
||||
result:
|
||||
columns: ["Level", "Code", "Message"]
|
||||
rows: []
|
||||
- on: server2
|
||||
user: 'brian'
|
||||
password: 'brianspassword'
|
||||
queries:
|
||||
- query: "show warnings"
|
||||
result:
|
||||
columns: ["Level", "Code", "Message"]
|
||||
rows: []
|
||||
- name: users and grants and branch control replicate to multiple standbys
|
||||
skip: "cluster replication / MySQL grants not yet supported in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby1
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
- name: standby2
|
||||
remote_url_template: http://localhost:{{get_port "server3_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby1
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
- name: standby2
|
||||
remote_url_template: http://localhost:{{get_port "server3_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
- name: server3
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby1
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
- name: standby2
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server3_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server3
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: "SET dolt_cluster_ack_writes_timeout_secs = 10"
|
||||
- exec: 'create database repo1'
|
||||
- exec: "use repo1"
|
||||
- exec: 'create table vals (i int primary key)'
|
||||
- exec: 'insert into vals values (0),(1),(2),(3),(4)'
|
||||
- exec: 'create user aaron with password ''aaronspassword'''
|
||||
- exec: 'GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO aaron'
|
||||
- exec: 'create user brian with password ''brianpassword'''
|
||||
- exec: 'GRANT ALL PRIVILEGES ON ALL TABLES IN SCHEMA public TO brian'
|
||||
- exec: 'delete from dolt_branch_control'
|
||||
- exec: 'insert into dolt_branch_control values (''repo1'', ''main'', ''aaron'', ''%'', ''admin'')'
|
||||
- on: server2
|
||||
user: 'aaron'
|
||||
password: 'aaronspassword'
|
||||
queries:
|
||||
- exec: "use repo1"
|
||||
- query: 'select count(*) as count from vals'
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
- query: 'select count(*) as count from dolt_branch_control'
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["1"]]
|
||||
- on: server3
|
||||
user: 'aaron'
|
||||
password: 'aaronspassword'
|
||||
queries:
|
||||
- exec: "use repo1"
|
||||
- query: 'select count(*) as count from vals'
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
- query: 'select count(*) as count from dolt_branch_control'
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["1"]]
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,132 @@
|
||||
parallel: true
|
||||
tests:
|
||||
- name: dolt_transaction_commit is global variable
|
||||
skip: "dolt_transaction_commit not being respected after being set"
|
||||
repos:
|
||||
- name: repo1
|
||||
server:
|
||||
args: []
|
||||
dynamic_port: repo1
|
||||
connections:
|
||||
- on: repo1
|
||||
queries:
|
||||
- exec: "SET dolt_transaction_commit = 1"
|
||||
- query: "select current_setting('dolt_transaction_commit') as dolt_transaction_commit"
|
||||
result:
|
||||
columns: ["dolt_transaction_commit"]
|
||||
rows: [["1"]]
|
||||
- on: repo1
|
||||
queries:
|
||||
- query: "select count(*) from dolt_log"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["2"]]
|
||||
- exec: "create table tmp (i int)"
|
||||
- query: "select count(*) from dolt_log"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["3"]]
|
||||
- name: set max_connections with yaml config
|
||||
skip: "need to adapt to doltgres listener"
|
||||
repos:
|
||||
- name: repo1
|
||||
with_files:
|
||||
- name: "server.yaml"
|
||||
contents: |
|
||||
log_level: trace
|
||||
listener:
|
||||
max_connections: 999
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: repo1
|
||||
connections:
|
||||
- on: repo1
|
||||
queries:
|
||||
- query: "select current_setting('max_connections') as max_connections"
|
||||
result:
|
||||
columns: ["max_connections"]
|
||||
rows: [["999"]]
|
||||
- name: "dolt_auto_gc_enabled default"
|
||||
skip: "default not set yet"
|
||||
repos:
|
||||
- name: repo1
|
||||
server:
|
||||
args: []
|
||||
dynamic_port: repo1
|
||||
connections:
|
||||
- on: repo1
|
||||
queries:
|
||||
- query: "select current_setting('dolt_auto_gc_enabled') as dolt_auto_gc_enabled"
|
||||
result:
|
||||
columns: ["dolt_auto_gc_enabled"]
|
||||
rows: [["1"]]
|
||||
- exec: "SET dolt_auto_gc_enabled = 0"
|
||||
error_match: "Variable 'dolt_auto_gc_enabled' is a read only variable"
|
||||
- name: "@@global.dolt_auto_gc_enabled true"
|
||||
skip: "config field not supported yet"
|
||||
repos:
|
||||
- name: repo1
|
||||
with_files:
|
||||
- name: "config.yaml"
|
||||
contents: |
|
||||
behavior:
|
||||
auto_gc_behavior:
|
||||
enable: true
|
||||
server:
|
||||
args: ["--config", "config.yaml"]
|
||||
dynamic_port: repo1
|
||||
connections:
|
||||
- on: repo1
|
||||
queries:
|
||||
- query: "select current_setting('dolt_auto_gc_enabled') as dolt_auto_gc_enabled"
|
||||
result:
|
||||
columns: ["dolt_auto_gc_enabled"]
|
||||
rows: [["1"]]
|
||||
- name: "@@global.dolt_auto_gc_enabled false"
|
||||
skip: "config field not supported yet"
|
||||
repos:
|
||||
- name: repo1
|
||||
with_files:
|
||||
- name: "config.yaml"
|
||||
contents: |
|
||||
behavior:
|
||||
auto_gc_behavior:
|
||||
enable: false
|
||||
server:
|
||||
args: ["--config", "config.yaml"]
|
||||
dynamic_port: repo1
|
||||
connections:
|
||||
- on: repo1
|
||||
queries:
|
||||
- query: "select current_setting('dolt_auto_gc_enabled') as dolt_auto_gc_enabled"
|
||||
result:
|
||||
columns: ["dolt_auto_gc_enabled"]
|
||||
rows: [["0"]]
|
||||
- name: secure_file_priv set to /dev/null prevents loading files
|
||||
skip: "field / feature needs to be supported"
|
||||
repos:
|
||||
- name: repo1
|
||||
with_files:
|
||||
- name: "config.yaml"
|
||||
contents: |
|
||||
system_variables:
|
||||
secure_file_priv: "/dev/null"
|
||||
server:
|
||||
args: ["--config", "config.yaml"]
|
||||
dynamic_port: repo1
|
||||
connections:
|
||||
- on: repo1
|
||||
queries:
|
||||
- query: "select LOAD_FILE('config.yaml') as load_file"
|
||||
result:
|
||||
columns: ["load_file"]
|
||||
rows: [["NULL"]]
|
||||
- query: "select LOAD_FILE('/etc/passwd') as load_file"
|
||||
result:
|
||||
columns: ["load_file"]
|
||||
rows: [["NULL"]]
|
||||
- exec: "create table loaded (contents text)"
|
||||
- exec: "COPY loaded FROM 'config.yaml'"
|
||||
error_match: "must be superuser or have privileges of the pg_read_server_files role|secure_file_priv"
|
||||
- exec: "COPY loaded FROM '/config.yaml'"
|
||||
error_match: "must be superuser or have privileges of the pg_read_server_files role|secure_file_priv"
|
||||
@@ -0,0 +1,79 @@
|
||||
parallel: true
|
||||
tests:
|
||||
|
||||
- name: large blob values replicate to standby
|
||||
# Cluster replication is not yet implemented in Doltgres, so this test is
|
||||
# skipped. The cluster config and the large-blob schema/data (LONGBLOB ->
|
||||
# bytea) are translated faithfully so this can be enabled once replication
|
||||
# lands. The ASCII payloads are turned into bytea with convert_to(...,'UTF8'),
|
||||
# which preserves the byte length asserted by LENGTH().
|
||||
skip: "cluster/remotesapi replication not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
listener:
|
||||
host: 0.0.0.0
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
listener:
|
||||
host: 0.0.0.0
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: "SET dolt_cluster_ack_writes_timeout_secs = 10"
|
||||
- exec: 'CREATE DATABASE repo1'
|
||||
- exec: 'USE repo1'
|
||||
- exec: |
|
||||
CREATE TABLE large_blob (
|
||||
id BIGINT PRIMARY KEY,
|
||||
data BYTEA
|
||||
)
|
||||
- exec: "INSERT INTO large_blob VALUES (1, convert_to(REPEAT('abcdefghijklmnopqrst', 1250), 'UTF8'))"
|
||||
- exec: "INSERT INTO large_blob VALUES (2, convert_to(REPEAT('ABCDEFGHIJKLMNOPQRST', 1250), 'UTF8'))"
|
||||
- exec: "INSERT INTO large_blob VALUES (3, convert_to(REPEAT('01234567890123456789', 1250), 'UTF8'))"
|
||||
- exec: "INSERT INTO large_blob VALUES (4, convert_to(REPEAT('zyxwvutsrqponmlkjihg', 1250), 'UTF8'))"
|
||||
- exec: "INSERT INTO large_blob VALUES (5, convert_to(REPEAT('fedcba9876543210FEDC', 1250), 'UTF8'))"
|
||||
- query: "SELECT COUNT(*) AS count FROM large_blob WHERE LENGTH(data) = 25000"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
- on: server2
|
||||
retry_attempts: 100
|
||||
queries:
|
||||
- exec: 'USE repo1'
|
||||
- query: "SELECT COUNT(*) AS count FROM large_blob"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
- query: "SELECT COUNT(*) AS count FROM large_blob WHERE LENGTH(data) = 25000"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
@@ -0,0 +1,87 @@
|
||||
parallel: true
|
||||
tests:
|
||||
|
||||
- name: large json values replicate to standby
|
||||
# Cluster replication is not yet implemented in Doltgres, so this test is
|
||||
# skipped. The cluster config and the large-json schema/data are translated
|
||||
# faithfully (JSON_OBJECT/JSON_ARRAY -> json_build_object/json_build_array,
|
||||
# LENGTH(doc) -> LENGTH(doc::text), doc->>'$.id' -> doc->>'id') so this can be
|
||||
# enabled once replication lands.
|
||||
skip: "cluster/remotesapi replication not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
listener:
|
||||
host: 0.0.0.0
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
listener:
|
||||
host: 0.0.0.0
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: "SET dolt_cluster_ack_writes_timeout_secs = 10"
|
||||
- exec: 'CREATE DATABASE repo1'
|
||||
- exec: 'USE repo1'
|
||||
- exec: |
|
||||
CREATE TABLE large_json (
|
||||
id BIGINT PRIMARY KEY,
|
||||
doc JSON
|
||||
)
|
||||
- exec: "INSERT INTO large_json VALUES (1, json_build_object('id', 1, 'payload', REPEAT('abcde', 2200)))"
|
||||
- exec: "INSERT INTO large_json VALUES (2, json_build_object('id', 2, 'payload', REPEAT('fghij', 2200)))"
|
||||
- exec: "INSERT INTO large_json VALUES (3, json_build_object('id', 3, 'payload', REPEAT('klmno', 2200)))"
|
||||
- exec: "INSERT INTO large_json VALUES (4, json_build_object('id', 4, 'items', json_build_array(REPEAT('x',3700), REPEAT('y',3700), REPEAT('z',3700))))"
|
||||
- exec: "INSERT INTO large_json VALUES (5, json_build_object('id', 5, 'nested', json_build_object('a', REPEAT('p',5500), 'b', REPEAT('q',5500))))"
|
||||
- query: "SELECT COUNT(*) AS count FROM large_json WHERE LENGTH(doc::text) > 11000"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
- query: "SELECT doc->>'id' AS id FROM large_json WHERE id = 3"
|
||||
result:
|
||||
columns: ["id"]
|
||||
rows: [["3"]]
|
||||
- on: server2
|
||||
retry_attempts: 100
|
||||
queries:
|
||||
- exec: 'USE repo1'
|
||||
- query: "SELECT COUNT(*) AS count FROM large_json"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
- query: "SELECT COUNT(*) AS count FROM large_json WHERE LENGTH(doc::text) > 11000"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
- query: "SELECT doc->>'id' AS id FROM large_json WHERE id = 3"
|
||||
result:
|
||||
columns: ["id"]
|
||||
rows: [["3"]]
|
||||
+106
@@ -0,0 +1,106 @@
|
||||
parallel: true
|
||||
tests:
|
||||
|
||||
- name: row with multiple large columns replicates correctly
|
||||
# Cluster replication is not yet implemented in Doltgres, so this test is
|
||||
# skipped. The cluster config and the multi-large-column schema/data are
|
||||
# translated faithfully (LONGTEXT/TEXT -> text, LONGBLOB -> bytea via
|
||||
# convert_to(...,'UTF8'), JSON_OBJECT -> json_build_object, LENGTH(doc) ->
|
||||
# LENGTH(doc::text), doc->>'$.row' -> doc->>'row') so this can be enabled once
|
||||
# replication lands.
|
||||
skip: "cluster/remotesapi replication not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
listener:
|
||||
host: 0.0.0.0
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
listener:
|
||||
host: 0.0.0.0
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: "SET dolt_cluster_ack_writes_timeout_secs = 10"
|
||||
- exec: 'CREATE DATABASE repo1'
|
||||
- exec: 'USE repo1'
|
||||
- exec: |
|
||||
CREATE TABLE multi_large (
|
||||
id BIGINT PRIMARY KEY,
|
||||
txt TEXT,
|
||||
blob_data BYTEA,
|
||||
doc JSON,
|
||||
note TEXT
|
||||
)
|
||||
- exec: |
|
||||
INSERT INTO multi_large VALUES (
|
||||
1,
|
||||
REPEAT('textcol-row1-', 1154),
|
||||
convert_to(REPEAT('blobcol-row1-', 1924), 'UTF8'),
|
||||
json_build_object('row', 1, 'data', REPEAT('jsoncol-row1-', 847)),
|
||||
REPEAT('note-col-row1-', 357)
|
||||
)
|
||||
- exec: |
|
||||
INSERT INTO multi_large VALUES (
|
||||
2,
|
||||
REPEAT('textcol-row2-', 1154),
|
||||
convert_to(REPEAT('blobcol-row2-', 1924), 'UTF8'),
|
||||
json_build_object('row', 2, 'data', REPEAT('jsoncol-row2-', 847)),
|
||||
REPEAT('note-col-row2-', 357)
|
||||
)
|
||||
- exec: |
|
||||
INSERT INTO multi_large VALUES (
|
||||
3,
|
||||
REPEAT('textcol-row3-', 1154),
|
||||
convert_to(REPEAT('blobcol-row3-', 1924), 'UTF8'),
|
||||
json_build_object('row', 3, 'data', REPEAT('jsoncol-row3-', 847)),
|
||||
REPEAT('note-col-row3-', 357)
|
||||
)
|
||||
- query: "SELECT COUNT(*) AS count FROM multi_large WHERE LENGTH(txt) > 10000 AND LENGTH(blob_data) > 20000"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["3"]]
|
||||
- on: server2
|
||||
retry_attempts: 100
|
||||
queries:
|
||||
- exec: 'USE repo1'
|
||||
- query: "SELECT COUNT(*) AS count FROM multi_large"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["3"]]
|
||||
- query: "SELECT COUNT(*) AS count FROM multi_large WHERE LENGTH(txt) > 10000 AND LENGTH(blob_data) > 20000 AND LENGTH(doc::text) > 11000 AND LENGTH(note) > 4000"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["3"]]
|
||||
- query: "SELECT doc->>'row' AS row FROM multi_large WHERE id = 2"
|
||||
result:
|
||||
columns: ["row"]
|
||||
rows: [["2"]]
|
||||
@@ -0,0 +1,78 @@
|
||||
parallel: true
|
||||
tests:
|
||||
|
||||
- name: large text values replicate to standby
|
||||
# Cluster replication is not yet implemented in Doltgres, so this test is
|
||||
# skipped. The cluster config and the large-text schema/data (LONGTEXT ->
|
||||
# text) are translated faithfully so this can be enabled once replication
|
||||
# lands.
|
||||
skip: "cluster/remotesapi replication not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
listener:
|
||||
host: 0.0.0.0
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
listener:
|
||||
host: 0.0.0.0
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: "SET dolt_cluster_ack_writes_timeout_secs = 10"
|
||||
- exec: 'CREATE DATABASE repo1'
|
||||
- exec: 'USE repo1'
|
||||
- exec: |
|
||||
CREATE TABLE large_text (
|
||||
id BIGINT PRIMARY KEY,
|
||||
txt TEXT
|
||||
)
|
||||
- exec: "INSERT INTO large_text VALUES (1, REPEAT('abcdefghij', 1500))"
|
||||
- exec: "INSERT INTO large_text VALUES (2, REPEAT('klmnopqrst', 1500))"
|
||||
- exec: "INSERT INTO large_text VALUES (3, REPEAT('uvwxyz0123', 1500))"
|
||||
- exec: "INSERT INTO large_text VALUES (4, REPEAT('4567890abcd', 1363))"
|
||||
- exec: "INSERT INTO large_text VALUES (5, REPEAT('efghijklmno', 1363))"
|
||||
- query: "SELECT COUNT(*) AS count FROM large_text WHERE LENGTH(txt) > 10000"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
- on: server2
|
||||
retry_attempts: 100
|
||||
queries:
|
||||
- exec: 'USE repo1'
|
||||
- query: "SELECT COUNT(*) AS count FROM large_text"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
- query: "SELECT COUNT(*) AS count FROM large_text WHERE LENGTH(txt) > 10000"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
@@ -0,0 +1,94 @@
|
||||
parallel: true
|
||||
tests:
|
||||
|
||||
- name: large values survive failover to new primary
|
||||
skip: "cluster replication/failover not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
behavior:
|
||||
auto_gc_behavior:
|
||||
enable: false
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
behavior:
|
||||
auto_gc_behavior:
|
||||
enable: false
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: 'SET dolt_cluster_ack_writes_timeout_secs = 10'
|
||||
- exec: 'CREATE DATABASE repo1'
|
||||
- exec: 'USE repo1'
|
||||
- exec: |
|
||||
CREATE TABLE large_vals (
|
||||
id BIGINT PRIMARY KEY,
|
||||
txt TEXT,
|
||||
blob_col BYTEA
|
||||
)
|
||||
- exec: "INSERT INTO large_vals VALUES (1, REPEAT('textrow1-', 1667), REPEAT('blobrow1-', 2778)::bytea)"
|
||||
- exec: "INSERT INTO large_vals VALUES (2, REPEAT('textrow2-', 1667), REPEAT('blobrow2-', 2778)::bytea)"
|
||||
- exec: "INSERT INTO large_vals VALUES (3, REPEAT('textrow3-', 1667), REPEAT('blobrow3-', 2778)::bytea)"
|
||||
- exec: "INSERT INTO large_vals VALUES (4, REPEAT('textrow4-', 1667), REPEAT('blobrow4-', 2778)::bytea)"
|
||||
- exec: "INSERT INTO large_vals VALUES (5, REPEAT('textrow5-', 1667), REPEAT('blobrow5-', 2778)::bytea)"
|
||||
# Transition to standby; server1's epoch advances to 2 on server2.
|
||||
- query: "SELECT dolt_assume_cluster_role('standby', 2)"
|
||||
result:
|
||||
columns: ["dolt_assume_cluster_role"]
|
||||
rows: [["{0}"]]
|
||||
# Verify the standby received all rows, then promote it to primary.
|
||||
- on: server2
|
||||
retry_attempts: 100
|
||||
queries:
|
||||
- exec: 'USE repo1'
|
||||
- query: "SELECT COUNT(*) AS count FROM large_vals WHERE LENGTH(txt) > 10000 AND LENGTH(blob_col) > 20000"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
- query: "SELECT dolt_assume_cluster_role('primary', 2)"
|
||||
result:
|
||||
columns: ["dolt_assume_cluster_role"]
|
||||
rows: [["{0}"]]
|
||||
# Open a fresh connection to the new primary and confirm large values are intact.
|
||||
# Also insert two additional large rows to prove the new primary is writable.
|
||||
- on: server2
|
||||
queries:
|
||||
- exec: 'USE repo1'
|
||||
- query: "SELECT COUNT(*) AS count FROM large_vals"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
- exec: "INSERT INTO large_vals VALUES (6, REPEAT('textrow6-', 1667), REPEAT('blobrow6-', 2778)::bytea)"
|
||||
- exec: "INSERT INTO large_vals VALUES (7, REPEAT('textrow7-', 1667), REPEAT('blobrow7-', 2778)::bytea)"
|
||||
- query: "SELECT COUNT(*) AS count FROM large_vals WHERE LENGTH(txt) > 10000 AND LENGTH(blob_col) > 20000"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["7"]]
|
||||
@@ -0,0 +1,95 @@
|
||||
parallel: true
|
||||
tests:
|
||||
|
||||
- name: large values survive gc on primary then replicate to standby
|
||||
skip: "cluster replication/failover not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
behavior:
|
||||
auto_gc_behavior:
|
||||
enable: false
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
behavior:
|
||||
auto_gc_behavior:
|
||||
enable: false
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: 'SET dolt_cluster_ack_writes_timeout_secs = 10'
|
||||
- exec: 'CREATE DATABASE repo1'
|
||||
- exec: 'USE repo1'
|
||||
- exec: |
|
||||
CREATE TABLE large_text (
|
||||
id BIGINT PRIMARY KEY,
|
||||
txt TEXT
|
||||
)
|
||||
- exec: "INSERT INTO large_text VALUES (1, REPEAT('abcdefghij', 1500))"
|
||||
- exec: "INSERT INTO large_text VALUES (2, REPEAT('klmnopqrst', 1500))"
|
||||
- exec: "INSERT INTO large_text VALUES (3, REPEAT('uvwxyz0123', 1500))"
|
||||
- exec: "INSERT INTO large_text VALUES (4, REPEAT('4567890abc', 1500))"
|
||||
- exec: "INSERT INTO large_text VALUES (5, REPEAT('defghijklm', 1500))"
|
||||
- exec: 'SELECT dolt_gc()'
|
||||
- query: 'SELECT COUNT(*) FROM large_text'
|
||||
error_match: "this connection can no longer be used"
|
||||
# After GC the connection is invalidated. Open a new connection to the primary
|
||||
# and wait for the cluster to finish replicating the post-GC state.
|
||||
- on: server1
|
||||
queries:
|
||||
- query: |
|
||||
SELECT "database", standby_remote, role, epoch, replication_lag_millis, current_error
|
||||
FROM dolt_cluster.dolt_cluster_status
|
||||
ORDER BY "database" ASC
|
||||
result:
|
||||
columns: ["database","standby_remote","role","epoch","replication_lag_millis","current_error"]
|
||||
rows:
|
||||
- ["repo1","standby","primary","1","0","NULL"]
|
||||
retry_attempts: 100
|
||||
- exec: 'USE repo1'
|
||||
- query: "SELECT COUNT(*) AS count FROM large_text WHERE LENGTH(txt) = 15000"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
# Verify the standby received and preserved all large values post-GC, then
|
||||
# confirm it can perform a shallow GC of its own.
|
||||
- on: server2
|
||||
queries:
|
||||
- exec: 'USE repo1'
|
||||
- query: "SELECT COUNT(*) AS count FROM large_text WHERE LENGTH(txt) = 15000"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
- exec: "SELECT dolt_gc('--shallow')"
|
||||
- query: "SELECT COUNT(*) AS count FROM large_text WHERE LENGTH(txt) = 15000"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
@@ -0,0 +1,445 @@
|
||||
parallel: true
|
||||
tests:
|
||||
- name: read-only flag prevents modification
|
||||
repos:
|
||||
- name: repo1
|
||||
server:
|
||||
args: ["--config", "readonly.yaml"]
|
||||
dynamic_port: server1
|
||||
with_files:
|
||||
- name: readonly.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
behavior:
|
||||
read_only: true
|
||||
connections:
|
||||
- on: repo1
|
||||
queries:
|
||||
- query: "select count(*) as count from information_schema.tables where table_schema = 'public'"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["0"]]
|
||||
- exec: "create table i_should_not_exist (c0 int)"
|
||||
error_match: "read only mode"
|
||||
- query: "select count(*) as count from information_schema.tables where table_schema = 'public'"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["0"]]
|
||||
- name: read-only flag still allows select
|
||||
repos:
|
||||
- name: repo1
|
||||
server:
|
||||
args: []
|
||||
dynamic_port: server1
|
||||
with_files:
|
||||
- name: readonly.yaml
|
||||
contents: |
|
||||
behavior:
|
||||
read_only: true
|
||||
connections:
|
||||
- on: repo1
|
||||
queries:
|
||||
- exec: "create table t(c0 int)"
|
||||
- exec: "insert into t values (1)"
|
||||
restart_server:
|
||||
args: ["--config", "readonly.yaml"]
|
||||
- on: repo1
|
||||
queries:
|
||||
- query: "select * from t"
|
||||
result:
|
||||
columns: ["c0"]
|
||||
rows: [["1"]]
|
||||
- name: read-only flag prevents dolt_commit
|
||||
skip: "Doltgres read-only mode does not block the dolt_commit() procedure; it is not classified as a write by the engine read-only guard"
|
||||
repos:
|
||||
- name: repo1
|
||||
server:
|
||||
args: ["--config", "readonly.yaml"]
|
||||
dynamic_port: server1
|
||||
with_files:
|
||||
- name: readonly.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
behavior:
|
||||
read_only: true
|
||||
connections:
|
||||
- on: repo1
|
||||
queries:
|
||||
- query: "select dolt_commit('--allow-empty', '-m', 'msg')"
|
||||
error_match: "read only"
|
||||
- name: read-only flag prevents dolt_reset
|
||||
skip: "Doltgres read-only mode does not block the dolt_reset() procedure; it is not classified as a write by the engine read-only guard"
|
||||
repos:
|
||||
- name: repo1
|
||||
server:
|
||||
args: []
|
||||
dynamic_port: server1
|
||||
with_files:
|
||||
- name: readonly.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
behavior:
|
||||
read_only: true
|
||||
connections:
|
||||
- on: repo1
|
||||
queries:
|
||||
- query: "select dolt_commit('--allow-empty', '-m', 'msg')"
|
||||
result:
|
||||
columns: ["dolt_commit"]
|
||||
rows: []
|
||||
restart_server:
|
||||
args: ["--config", "readonly.yaml"]
|
||||
- on: repo1
|
||||
queries:
|
||||
- query: "select dolt_reset('--hard', 'HEAD~1')"
|
||||
error_match: "read only"
|
||||
- name: port in use
|
||||
repos:
|
||||
- name: repo1
|
||||
server:
|
||||
args: []
|
||||
dynamic_port: server1
|
||||
- name: repo2
|
||||
server:
|
||||
args: []
|
||||
dynamic_port: server1
|
||||
error_matches:
|
||||
- "already in use"
|
||||
- name: test basic querying
|
||||
repos:
|
||||
- name: repo1
|
||||
server:
|
||||
args: []
|
||||
dynamic_port: server1
|
||||
connections:
|
||||
- on: repo1
|
||||
queries:
|
||||
- query: "select table_name from information_schema.tables where table_schema = 'public' order by table_name"
|
||||
result:
|
||||
columns: ["table_name"]
|
||||
rows: []
|
||||
- on: repo1
|
||||
queries:
|
||||
- exec: |
|
||||
CREATE TABLE one_pk (
|
||||
pk bigint NOT NULL,
|
||||
c1 bigint,
|
||||
c2 bigint,
|
||||
PRIMARY KEY (pk)
|
||||
)
|
||||
- on: repo1
|
||||
queries:
|
||||
- query: "select table_name from information_schema.tables where table_schema = 'public' order by table_name"
|
||||
result:
|
||||
columns: ["table_name"]
|
||||
rows: [["one_pk"]]
|
||||
- on: repo1
|
||||
queries:
|
||||
- exec: "INSERT INTO one_pk (pk) VALUES (0)"
|
||||
- on: repo1
|
||||
queries:
|
||||
- query: "SELECT * FROM one_pk ORDER BY pk"
|
||||
result:
|
||||
columns: ["pk","c1","c2"]
|
||||
rows: [["0","NULL","NULL"]]
|
||||
- on: repo1
|
||||
queries:
|
||||
- exec: "INSERT INTO one_pk (pk,c1) VALUES (1,1)"
|
||||
- on: repo1
|
||||
queries:
|
||||
- exec: "INSERT INTO one_pk (pk,c1,c2) VALUES (2,2,2),(3,3,3)"
|
||||
- on: repo1
|
||||
queries:
|
||||
- query: "SELECT * FROM one_pk ORDER BY pk"
|
||||
result:
|
||||
columns: ["pk","c1","c2"]
|
||||
rows:
|
||||
- ["0","NULL","NULL"]
|
||||
- ["1","1","NULL"]
|
||||
- ["2","2","2"]
|
||||
- ["3","3","3"]
|
||||
- on: repo1
|
||||
queries:
|
||||
- exec: "UPDATE one_pk SET c2=c1 WHERE c2 is NULL and c1 IS NOT NULL"
|
||||
- name: test multiple queries on same connection
|
||||
repos:
|
||||
- name: repo1
|
||||
server:
|
||||
args: []
|
||||
dynamic_port: server1
|
||||
connections:
|
||||
- on: repo1
|
||||
queries:
|
||||
- exec: |
|
||||
CREATE TABLE one_pk (
|
||||
pk bigint NOT NULL,
|
||||
c1 bigint,
|
||||
c2 bigint,
|
||||
PRIMARY KEY (pk)
|
||||
)
|
||||
- exec: "INSERT INTO one_pk (pk) VALUES (0)"
|
||||
- exec: "INSERT INTO one_pk (pk,c1) VALUES (1,1)"
|
||||
- exec: "INSERT INTO one_pk (pk,c1,c2) VALUES (2,2,2),(3,3,3)"
|
||||
- query: "SELECT * FROM one_pk ORDER BY pk"
|
||||
result:
|
||||
columns: ["pk","c1","c2"]
|
||||
rows:
|
||||
- ["0","NULL","NULL"]
|
||||
- ["1","1","NULL"]
|
||||
- ["2","2","2"]
|
||||
- ["3","3","3"]
|
||||
- on: repo1
|
||||
queries:
|
||||
- query: "SELECT * FROM one_pk ORDER BY pk"
|
||||
result:
|
||||
columns: ["pk","c1","c2"]
|
||||
rows:
|
||||
- ["0","NULL","NULL"]
|
||||
- ["1","1","NULL"]
|
||||
- ["2","2","2"]
|
||||
- ["3","3","3"]
|
||||
- name: test CREATE and DROP database via sql-server
|
||||
# The original test creates a database, then `USE`s it to operate on its
|
||||
# tables on the same connection. Postgres/Doltgres binds the database at
|
||||
# connection time (no USE across databases), and this test framework can only
|
||||
# open connections to servers registered by repo/multi-repo name (via `on:`),
|
||||
# so a freshly-created database cannot be reached by name. We still exercise
|
||||
# CREATE DATABASE / DROP DATABASE and verify pg_database visibility.
|
||||
repos:
|
||||
- name: repo1
|
||||
server:
|
||||
args: []
|
||||
dynamic_port: server1
|
||||
connections:
|
||||
- on: repo1
|
||||
queries:
|
||||
- exec: "CREATE DATABASE test"
|
||||
- query: "select datname from pg_database where datname in ('repo1','test') order by datname"
|
||||
result:
|
||||
columns: ["datname"]
|
||||
rows:
|
||||
- ["repo1"]
|
||||
- ["test"]
|
||||
- exec: "drop database test"
|
||||
- query: "select datname from pg_database where datname in ('repo1','test') order by datname"
|
||||
result:
|
||||
columns: ["datname"]
|
||||
rows:
|
||||
- ["repo1"]
|
||||
- name: COPY loads CSV data from a file
|
||||
repos:
|
||||
- name: repo1
|
||||
with_files:
|
||||
- name: "1pk5col-ints.csv"
|
||||
source_path: "testdata/1pk5col-ints.csv"
|
||||
server:
|
||||
args: []
|
||||
dynamic_port: server1
|
||||
connections:
|
||||
- on: repo1
|
||||
queries:
|
||||
- exec: "CREATE TABLE test(pk int primary key, c1 int, c2 int, c3 int, c4 int, c5 int)"
|
||||
- exec: "COPY test FROM '1pk5col-ints.csv' WITH (FORMAT csv, HEADER)"
|
||||
- query: "SELECT * FROM test"
|
||||
result:
|
||||
columns: ["pk","c1","c2","c3","c4","c5"]
|
||||
rows:
|
||||
- ["0","1","2","3","4","5"]
|
||||
- ["1","1","2","3","4","5"]
|
||||
- name: JSON queries
|
||||
repos:
|
||||
- name: repo1
|
||||
server:
|
||||
args: []
|
||||
dynamic_port: server1
|
||||
connections:
|
||||
- on: repo1
|
||||
queries:
|
||||
- exec: |
|
||||
CREATE TABLE js_test (
|
||||
pk int NOT NULL,
|
||||
js json,
|
||||
PRIMARY KEY (pk)
|
||||
)
|
||||
- exec: |
|
||||
INSERT INTO js_test VALUES (1, '{"a":1}')
|
||||
- query: "SELECT * FROM js_test"
|
||||
result:
|
||||
columns: ["pk","js"]
|
||||
rows:
|
||||
or:
|
||||
- [["1", '{"a": 1}']]
|
||||
- [["1", '{"a":1}']]
|
||||
- name: select a branch with dolt_checkout
|
||||
# The original test used MySQL `USE repo1/feature-branch` to switch to a
|
||||
# branch-revision database. Doltgres has no `USE` statement, so the equivalent
|
||||
# session branch switch is done with dolt_checkout().
|
||||
repos:
|
||||
- name: repo1
|
||||
server:
|
||||
args: []
|
||||
dynamic_port: server1
|
||||
connections:
|
||||
- on: repo1
|
||||
queries:
|
||||
- query: "select dolt_branch('feature-branch')"
|
||||
result:
|
||||
columns: ["dolt_branch"]
|
||||
rows: [["{0}"]]
|
||||
- query: "select dolt_checkout('feature-branch')"
|
||||
result:
|
||||
columns: ["dolt_checkout"]
|
||||
rows:
|
||||
or:
|
||||
- [["{0,\"Switched to branch 'feature-branch'\"}"]]
|
||||
- [["{0,Switched to branch 'feature-branch'}"]]
|
||||
- exec: |
|
||||
CREATE TABLE test (
|
||||
pk int,
|
||||
c1 int,
|
||||
PRIMARY KEY (pk)
|
||||
)
|
||||
- on: repo1
|
||||
queries:
|
||||
- query: "select table_name from information_schema.tables where table_schema = 'public' order by table_name"
|
||||
result:
|
||||
columns: ["table_name"]
|
||||
rows: []
|
||||
- query: "select dolt_checkout('feature-branch')"
|
||||
result:
|
||||
columns: ["dolt_checkout"]
|
||||
rows:
|
||||
or:
|
||||
- [["{0,\"Switched to branch 'feature-branch'\"}"]]
|
||||
- [["{0,Switched to branch 'feature-branch'}"]]
|
||||
- query: "select table_name from information_schema.tables where table_schema = 'public' order by table_name"
|
||||
result:
|
||||
columns: ["table_name"]
|
||||
rows: [["test"]]
|
||||
- name: auto increment for a table should reset between drops
|
||||
repos:
|
||||
- name: repo1
|
||||
server:
|
||||
args: []
|
||||
dynamic_port: server1
|
||||
connections:
|
||||
- on: repo1
|
||||
queries:
|
||||
- exec: "CREATE TABLE t1(pk serial primary key, val int)"
|
||||
- exec: "INSERT INTO t1 (val) VALUES (1),(2)"
|
||||
- query: "SELECT * FROM t1 ORDER BY pk"
|
||||
result:
|
||||
columns: ["pk", "val"]
|
||||
rows: [["1", "1"], ["2", "2"]]
|
||||
- exec: "DROP TABLE t1"
|
||||
- exec: "CREATE TABLE t1(pk serial primary key, val int)"
|
||||
- exec: "INSERT INTO t1 (val) VALUES (1),(2)"
|
||||
- query: "SELECT * FROM t1 ORDER BY pk"
|
||||
result:
|
||||
columns: ["pk", "val"]
|
||||
rows: [["1", "1"], ["2", "2"]]
|
||||
- name: Create a temporary table and validate that it doesn't persist after a session closes
|
||||
repos:
|
||||
- name: repo1
|
||||
server:
|
||||
args: []
|
||||
dynamic_port: server1
|
||||
connections:
|
||||
- on: repo1
|
||||
queries:
|
||||
- query: "select table_name from information_schema.tables where table_schema = 'public' order by table_name"
|
||||
result:
|
||||
columns: ["table_name"]
|
||||
rows: []
|
||||
- exec: "CREATE TEMPORARY TABLE t1(pk int primary key, val int)"
|
||||
- exec: "INSERT INTO t1 VALUES (1, 1),(2, 2)"
|
||||
- on: repo1
|
||||
queries:
|
||||
- exec: "INSERT INTO t1 VALUES (1, 1),(2, 2)"
|
||||
error_match: "(does not exist|not found)"
|
||||
- name: create a collated database connected to a non-dolt database
|
||||
skip: "MySQL-specific COLLATE database creation / non-Dolt database semantics not applicable to Doltgres"
|
||||
repos:
|
||||
- name: repo1
|
||||
server:
|
||||
args: []
|
||||
dynamic_port: server1
|
||||
connections:
|
||||
- on: repo1
|
||||
queries:
|
||||
- exec: "USE mysql"
|
||||
- exec: "CREATE DATABASE testdb COLLATE utf8mb4_unicode_ci"
|
||||
- exec: "USE testdb"
|
||||
- name: dolt_gc succeeds as first write on existing database without a journal after chunk journal is enabled
|
||||
skip: "Requires the database to be initialized with the chunk journal disabled; the doltgres test harness initializes databases with the journal enabled, so this storage-internals scenario cannot be reproduced yet"
|
||||
# The original test created the database via CREATE DATABASE on a multi-repo
|
||||
# server, then USE'd it. Doltgres binds the database at connect time and this
|
||||
# framework can only connect to databases registered by repo name (via `on:`),
|
||||
# so the database is created up front as a repo and connected to directly. The
|
||||
# server starts with the chunk journal disabled, data is written, then the
|
||||
# server is restarted (re-enabling the chunk journal) and dolt_gc is run as the
|
||||
# first write.
|
||||
repos:
|
||||
- name: mydb
|
||||
server:
|
||||
envs: ["DOLT_DISABLE_CHUNK_JOURNAL=true"]
|
||||
args: []
|
||||
dynamic_port: server1
|
||||
connections:
|
||||
- on: mydb
|
||||
queries:
|
||||
- exec: "CREATE TABLE vals (id int primary key, val int)"
|
||||
- exec: "INSERT INTO vals VALUES (1, 1),(2, 2)"
|
||||
restart_server:
|
||||
envs: []
|
||||
- on: mydb
|
||||
queries:
|
||||
- query: "select dolt_gc() as dolt_gc"
|
||||
result:
|
||||
columns: ["dolt_gc"]
|
||||
rows: [["{0}"]]
|
||||
- name: file remotes update appropriately
|
||||
skip: "remotesapi/file-remote replication across servers not yet supported in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
server:
|
||||
args: []
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
server:
|
||||
args: []
|
||||
dynamic_port: server2
|
||||
- name: server3
|
||||
server:
|
||||
args: []
|
||||
dynamic_port: server3
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: "CREATE DATABASE mydb"
|
||||
- exec: "select dolt_remote('add', 'origin', 'file://{{get_tempdir \"remote_storage\"}}')"
|
||||
- exec: "select dolt_push('origin', 'main:main')"
|
||||
- on: server2
|
||||
queries:
|
||||
- exec: "select dolt_clone('file://{{get_tempdir \"remote_storage\"}}', 'mydb')"
|
||||
- on: server3
|
||||
queries:
|
||||
- exec: "select dolt_clone('file://{{get_tempdir \"remote_storage\"}}', 'mydb')"
|
||||
- on: server2
|
||||
queries:
|
||||
- exec: "CREATE TABLE test (id int PRIMARY KEY)"
|
||||
- exec: "select dolt_commit('-Am', 'create test table')"
|
||||
- exec: "select dolt_push('origin', 'main')"
|
||||
- on: server3
|
||||
queries:
|
||||
- exec: "select dolt_pull('origin', 'main')"
|
||||
- exec: "INSERT INTO test VALUES (1), (2), (47)"
|
||||
- exec: "select dolt_commit('-am', 'Insert some initial values.')"
|
||||
- exec: "select dolt_push('origin', 'main')"
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: "select dolt_pull('origin', 'main')"
|
||||
- query: "SELECT * FROM test ORDER BY id ASC"
|
||||
result:
|
||||
columns: ["id"]
|
||||
rows: [["1"], ["2"], ["47"]]
|
||||
@@ -0,0 +1,100 @@
|
||||
parallel: true
|
||||
tests:
|
||||
- name: can clone from server1 remotesapi endpoint
|
||||
# The remotes API (used to serve/clone databases between servers) is not yet
|
||||
# implemented in Doltgres, so this test is skipped. The config, remotesapi
|
||||
# port wiring, and dolt_clone/dolt_commit flow are translated faithfully so it
|
||||
# can be enabled once the feature lands.
|
||||
skip: "cluster/remotesapi replication not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
repos:
|
||||
- name: repo1
|
||||
- name: repo2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
remotesapi:
|
||||
port: {{get_port "remotesapi_port"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server_port
|
||||
- name: server2
|
||||
repos:
|
||||
- name: repo1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
listener:
|
||||
host: 0.0.0.0
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2_port
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: "use repo2"
|
||||
- exec: "create table vals (id int primary key)"
|
||||
- exec: "insert into vals values (0),(1),(2),(3),(4)"
|
||||
- exec: "select dolt_commit('-Am', 'insert some data')"
|
||||
- on: server2
|
||||
queries:
|
||||
- exec: "use repo1"
|
||||
- exec: "select dolt_clone('http://localhost:{{get_port \"remotesapi_port\"}}/repo2')"
|
||||
- exec: "use repo2"
|
||||
- query: "select count(*) from vals"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
- name: can clone from server1 remotesapi endpoint after a gc
|
||||
skip: "cluster/remotesapi replication not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
repos:
|
||||
- name: repo1
|
||||
- name: repo2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
remotesapi:
|
||||
port: {{get_port "remotesapi_port"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server_port
|
||||
- name: server2
|
||||
repos:
|
||||
- name: repo1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
listener:
|
||||
host: 0.0.0.0
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2_port
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: "use repo2"
|
||||
- exec: "create table vals (id int primary key)"
|
||||
- exec: "insert into vals values (0),(1),(2),(3),(4)"
|
||||
- exec: "select dolt_commit('-Am', 'insert some data')"
|
||||
- exec: "select dolt_gc()"
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: "use repo2"
|
||||
- exec: "insert into vals values (5),(6),(7),(8),(9)"
|
||||
- exec: "select dolt_commit('-Am', 'insert some more data')"
|
||||
- on: server2
|
||||
queries:
|
||||
- exec: "use repo1"
|
||||
- exec: "select dolt_clone('http://localhost:{{get_port \"remotesapi_port\"}}/repo2')"
|
||||
- exec: "use repo2"
|
||||
- query: "select count(*) from vals"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["10"]]
|
||||
@@ -0,0 +1,80 @@
|
||||
parallel: true
|
||||
tests:
|
||||
- name: require_secure_transport no key or cert
|
||||
repos:
|
||||
- name: repo1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
listener:
|
||||
require_secure_transport: true
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server
|
||||
error_matches:
|
||||
- "require_secure_transport can only be `true` when a tls_key and tls_cert are provided."
|
||||
- name: tls_key non-existent
|
||||
repos:
|
||||
- name: repo1
|
||||
with_files:
|
||||
- name: chain_key.pem
|
||||
source_path: $TESTGENDIR/rsa_key.pem
|
||||
- name: chain_cert.pem
|
||||
source_path: $TESTGENDIR/rsa_chain.pem
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
listener:
|
||||
tls_key: doesnotexist_key.pem
|
||||
tls_cert: chain_cert.pem
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server
|
||||
error_matches:
|
||||
- "no such file or directory"
|
||||
- name: tls_cert non-existent
|
||||
repos:
|
||||
- name: repo1
|
||||
with_files:
|
||||
- name: chain_key.pem
|
||||
source_path: $TESTGENDIR/rsa_key.pem
|
||||
- name: chain_cert.pem
|
||||
source_path: $TESTGENDIR/rsa_chain.pem
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
listener:
|
||||
tls_key: chain_key.pem
|
||||
tls_cert: doesnotexist_key.pem
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server
|
||||
error_matches:
|
||||
- "no such file or directory"
|
||||
|
||||
# XXX: It would be nice to assert on the TLS use here using a status query or similar.
|
||||
# It would be nice to assert on failing to connect using sslmode=disable.
|
||||
- name: tls only server
|
||||
repos:
|
||||
- name: repo1
|
||||
with_files:
|
||||
- name: chain_key.pem
|
||||
source_path: $TESTGENDIR/rsa_key.pem
|
||||
- name: chain_cert.pem
|
||||
source_path: $TESTGENDIR/rsa_chain.pem
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
listener:
|
||||
tls_key: chain_key.pem
|
||||
tls_cert: chain_cert.pem
|
||||
require_secure_transport: true
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server
|
||||
connections:
|
||||
- on: repo1
|
||||
driver_params:
|
||||
sslmode: require
|
||||
queries:
|
||||
- query: "select 1 as one"
|
||||
result:
|
||||
columns: ["one"]
|
||||
rows: [["1"]]
|
||||
@@ -0,0 +1,184 @@
|
||||
parallel: true
|
||||
tests:
|
||||
|
||||
- name: type diverse table replicates correctly
|
||||
# Cluster replication is not yet implemented in Doltgres, so this test is
|
||||
# skipped. The cluster config and the type-diverse schema/data are translated
|
||||
# to Postgres faithfully so this can be enabled once replication lands.
|
||||
#
|
||||
# Type translation notes (MySQL -> Postgres):
|
||||
# TINYINT -> smallint (Postgres has no 1-byte int)
|
||||
# DOUBLE -> double precision
|
||||
# DATETIME -> timestamp
|
||||
# BLOB -> bytea
|
||||
# BOOLEAN -> boolean
|
||||
# JSON -> json
|
||||
# ENUM(...) / SET(...) -> varchar (Postgres has no inline ENUM/SET); the
|
||||
# spirit (constrained categorical / multi-value column) is preserved as
|
||||
# text values.
|
||||
skip: "cluster/remotesapi replication not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
listener:
|
||||
host: 0.0.0.0
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
listener:
|
||||
host: 0.0.0.0
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: "SET dolt_cluster_ack_writes_timeout_secs = 10"
|
||||
- exec: 'CREATE DATABASE repo1'
|
||||
- exec: 'USE repo1'
|
||||
- exec: |
|
||||
CREATE TABLE type_diverse (
|
||||
id BIGINT PRIMARY KEY,
|
||||
col_tinyint SMALLINT,
|
||||
col_smallint SMALLINT,
|
||||
col_int INT,
|
||||
col_bigint BIGINT,
|
||||
col_decimal DECIMAL(20,10),
|
||||
col_float REAL,
|
||||
col_double DOUBLE PRECISION,
|
||||
col_char CHAR(50),
|
||||
col_varchar VARCHAR(500),
|
||||
col_text TEXT,
|
||||
col_blob BYTEA,
|
||||
col_date DATE,
|
||||
col_time TIME,
|
||||
col_datetime TIMESTAMP,
|
||||
col_bool BOOLEAN,
|
||||
col_json JSON,
|
||||
col_enum VARCHAR(16),
|
||||
col_set VARCHAR(64)
|
||||
)
|
||||
# Row 1: typical values.
|
||||
- exec: |
|
||||
INSERT INTO type_diverse VALUES (
|
||||
1, 42, 1000, 1000000, 9000000000,
|
||||
12345678.9012345678, 3.14, 2.71828182845905,
|
||||
'hello', 'longer varchar value',
|
||||
'some text content', '\x736f6d6520626c6f6220636f6e74656e74',
|
||||
'2024-06-15', '12:30:00', '2024-06-15 12:30:00',
|
||||
true, json_build_object('key','value','count',42),
|
||||
'alpha', 'red,green'
|
||||
)
|
||||
# Row 2: minimum boundary values.
|
||||
- exec: |
|
||||
INSERT INTO type_diverse VALUES (
|
||||
2, -128, -32768, -2147483648, -9223372036854775808,
|
||||
-9999999999.9999999999, -1.5, -1.23456789,
|
||||
'', '',
|
||||
'', '\x',
|
||||
'1000-01-01', '00:00:00', '1000-01-01 00:00:00',
|
||||
false, json_build_object(),
|
||||
'beta', 'green'
|
||||
)
|
||||
# Row 3: maximum/large values - large TEXT and BLOB cross the out-of-band threshold.
|
||||
- exec: |
|
||||
INSERT INTO type_diverse VALUES (
|
||||
3, 127, 32767, 2147483647, 9223372036854775807,
|
||||
9999999999.9999999999, 1.5, 9.87654321,
|
||||
REPEAT('x',50), REPEAT('y',500),
|
||||
REPEAT('z',15000), decode(REPEAT('62',20000), 'hex'),
|
||||
'9999-12-31', '23:59:59', '9999-12-31 23:59:59',
|
||||
true, json_build_object('data', REPEAT('d',11000)),
|
||||
'gamma', 'red,green,blue'
|
||||
)
|
||||
# Row 4: all nullable columns are NULL.
|
||||
- exec: 'INSERT INTO type_diverse (id) VALUES (4)'
|
||||
- query: "SELECT COUNT(*) AS count FROM type_diverse"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["4"]]
|
||||
- query: "SELECT COUNT(*) AS count FROM type_diverse WHERE col_int = -2147483648 AND col_bigint = -9223372036854775808"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["1"]]
|
||||
- query: "SELECT COUNT(*) AS count FROM type_diverse WHERE LENGTH(col_text) = 15000 AND LENGTH(col_blob) = 20000"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["1"]]
|
||||
- query: "SELECT COUNT(*) AS count FROM type_diverse WHERE col_tinyint IS NULL AND col_date IS NULL AND col_json IS NULL"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["1"]]
|
||||
- on: server2
|
||||
retry_attempts: 100
|
||||
queries:
|
||||
- exec: 'USE repo1'
|
||||
- query: "SELECT COUNT(*) AS count FROM type_diverse"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["4"]]
|
||||
# Integer boundaries must survive the replication round-trip.
|
||||
- query: "SELECT COUNT(*) AS count FROM type_diverse WHERE col_tinyint = -128 AND col_int = -2147483648 AND col_bigint = -9223372036854775808"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["1"]]
|
||||
- query: "SELECT COUNT(*) AS count FROM type_diverse WHERE col_tinyint = 127 AND col_int = 2147483647 AND col_bigint = 9223372036854775807"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["1"]]
|
||||
# Large out-of-band values must be present with their correct sizes.
|
||||
- query: "SELECT COUNT(*) AS count FROM type_diverse WHERE LENGTH(col_text) = 15000 AND LENGTH(col_blob) = 20000"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["1"]]
|
||||
# Date and time boundary values must be preserved.
|
||||
- query: "SELECT COUNT(*) AS count FROM type_diverse WHERE col_date = '1000-01-01' AND col_time = '00:00:00'"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["1"]]
|
||||
- query: "SELECT COUNT(*) AS count FROM type_diverse WHERE col_date = '9999-12-31' AND col_time = '23:59:59'"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["1"]]
|
||||
# ENUM/SET (translated to varchar) must replicate correctly.
|
||||
- query: "SELECT col_enum, col_set FROM type_diverse WHERE id = 1"
|
||||
result:
|
||||
columns: ["col_enum","col_set"]
|
||||
rows: [["alpha","red,green"]]
|
||||
- query: "SELECT col_enum, col_set FROM type_diverse WHERE id = 3"
|
||||
result:
|
||||
columns: ["col_enum","col_set"]
|
||||
rows: [["gamma","red,green,blue"]]
|
||||
- query: "SELECT col_json->>'key' AS key FROM type_diverse WHERE id = 1"
|
||||
result:
|
||||
columns: ["key"]
|
||||
rows: [["value"]]
|
||||
# NULL values must survive replication.
|
||||
- query: "SELECT COUNT(*) AS count FROM type_diverse WHERE col_tinyint IS NULL AND col_date IS NULL AND col_json IS NULL"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["1"]]
|
||||
@@ -0,0 +1,99 @@
|
||||
parallel: true
|
||||
tests:
|
||||
|
||||
- name: wide integer column table replicates correctly
|
||||
skip: "cluster replication/failover not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
behavior:
|
||||
auto_gc_behavior:
|
||||
enable: false
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
behavior:
|
||||
auto_gc_behavior:
|
||||
enable: false
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: 'SET dolt_cluster_ack_writes_timeout_secs = 10'
|
||||
- exec: 'CREATE DATABASE repo1'
|
||||
- exec: 'USE repo1'
|
||||
- exec: |
|
||||
CREATE TABLE wide_int (
|
||||
id BIGINT PRIMARY KEY,
|
||||
c00 BIGINT, c01 BIGINT, c02 BIGINT, c03 BIGINT, c04 BIGINT,
|
||||
c05 BIGINT, c06 BIGINT, c07 BIGINT, c08 BIGINT, c09 BIGINT,
|
||||
c10 BIGINT, c11 BIGINT, c12 BIGINT, c13 BIGINT, c14 BIGINT,
|
||||
c15 BIGINT, c16 BIGINT, c17 BIGINT, c18 BIGINT, c19 BIGINT,
|
||||
c20 BIGINT, c21 BIGINT, c22 BIGINT, c23 BIGINT, c24 BIGINT,
|
||||
c25 BIGINT, c26 BIGINT, c27 BIGINT, c28 BIGINT, c29 BIGINT
|
||||
)
|
||||
- exec: |
|
||||
INSERT INTO wide_int VALUES
|
||||
(1, 100,101,102,103,104, 105,106,107,108,109, 110,111,112,113,114, 115,116,117,118,119, 120,121,122,123,124, 125,126,127,128,129),
|
||||
(2, 200,201,202,203,204, 205,206,207,208,209, 210,211,212,213,214, 215,216,217,218,219, 220,221,222,223,224, 225,226,227,228,229),
|
||||
(3, 300,301,302,303,304, 305,306,307,308,309, 310,311,312,313,314, 315,316,317,318,319, 320,321,322,323,324, 325,326,327,328,329),
|
||||
(4, -100,-101,-102,-103,-104,-105,-106,-107,-108,-109,-110,-111,-112,-113,-114,-115,-116,-117,-118,-119,-120,-121,-122,-123,-124,-125,-126,-127,-128,-129),
|
||||
(5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)
|
||||
- query: "SELECT COUNT(*) AS count FROM wide_int"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
- query: "SELECT c00, c15, c29 FROM wide_int WHERE id = 1"
|
||||
result:
|
||||
columns: ["c00","c15","c29"]
|
||||
rows: [["100","115","129"]]
|
||||
- on: server2
|
||||
retry_attempts: 100
|
||||
queries:
|
||||
- exec: 'USE repo1'
|
||||
- query: "SELECT COUNT(*) AS count FROM wide_int"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["5"]]
|
||||
- query: "SELECT c00, c15, c29 FROM wide_int WHERE id = 1"
|
||||
result:
|
||||
columns: ["c00","c15","c29"]
|
||||
rows: [["100","115","129"]]
|
||||
- query: "SELECT c00, c15, c29 FROM wide_int WHERE id = 3"
|
||||
result:
|
||||
columns: ["c00","c15","c29"]
|
||||
rows: [["300","315","329"]]
|
||||
- query: "SELECT c00, c15, c29 FROM wide_int WHERE id = 4"
|
||||
result:
|
||||
columns: ["c00","c15","c29"]
|
||||
rows: [["-100","-115","-129"]]
|
||||
- query: "SELECT COUNT(*) AS count FROM wide_int WHERE c00 = 0 AND c29 = 0"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["1"]]
|
||||
@@ -0,0 +1,125 @@
|
||||
parallel: true
|
||||
tests:
|
||||
|
||||
- name: wide table survives failover
|
||||
skip: "cluster replication/failover not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
behavior:
|
||||
auto_gc_behavior:
|
||||
enable: false
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
behavior:
|
||||
auto_gc_behavior:
|
||||
enable: false
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: 'SET dolt_cluster_ack_writes_timeout_secs = 10'
|
||||
- exec: 'CREATE DATABASE repo1'
|
||||
- exec: 'USE repo1'
|
||||
- exec: |
|
||||
CREATE TABLE wide_mixed (
|
||||
id BIGINT PRIMARY KEY,
|
||||
i00 INT, i01 INT, i02 INT, i03 INT, i04 INT,
|
||||
i05 INT, i06 INT, i07 INT, i08 INT, i09 INT,
|
||||
t00 TEXT, t01 TEXT, t02 TEXT, t03 TEXT, t04 TEXT,
|
||||
v00 VARCHAR(300), v01 VARCHAR(300), v02 VARCHAR(300), v03 VARCHAR(300), v04 VARCHAR(300)
|
||||
)
|
||||
- exec: |
|
||||
INSERT INTO wide_mixed VALUES
|
||||
(1,
|
||||
1,2,3,4,5,6,7,8,9,10,
|
||||
REPEAT('t00',667), REPEAT('t01',667), REPEAT('t02',667), REPEAT('t03',667), REPEAT('t04',667),
|
||||
REPEAT('v',300), REPEAT('w',300), REPEAT('x',300), REPEAT('y',300), REPEAT('z',300))
|
||||
- exec: |
|
||||
INSERT INTO wide_mixed VALUES
|
||||
(2,
|
||||
11,12,13,14,15,16,17,18,19,20,
|
||||
REPEAT('T00',667), REPEAT('T01',667), REPEAT('T02',667), REPEAT('T03',667), REPEAT('T04',667),
|
||||
REPEAT('V',300), REPEAT('W',300), REPEAT('X',300), REPEAT('Y',300), REPEAT('Z',300))
|
||||
- exec: |
|
||||
INSERT INTO wide_mixed VALUES
|
||||
(3,
|
||||
-1,-2,-3,-4,-5,-6,-7,-8,-9,-10,
|
||||
REPEAT('neg',667), REPEAT('zero',501), REPEAT('mix',668), REPEAT('data',501), REPEAT('test',501),
|
||||
REPEAT('a',300), REPEAT('b',300), REPEAT('c',300), REPEAT('d',300), REPEAT('e',300))
|
||||
- query: "SELECT COUNT(*) AS count FROM wide_mixed"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["3"]]
|
||||
- query: "SELECT i00, i09, LEFT(t00,3) AS t00, LEFT(v04,1) AS v04 FROM wide_mixed WHERE id = 1"
|
||||
result:
|
||||
columns: ["i00","i09","t00","v04"]
|
||||
rows: [["1","10","t00","z"]]
|
||||
- query: "SELECT dolt_assume_cluster_role('standby', 2)"
|
||||
result:
|
||||
columns: ["dolt_assume_cluster_role"]
|
||||
rows: [["{0}"]]
|
||||
- on: server2
|
||||
retry_attempts: 100
|
||||
queries:
|
||||
- exec: 'USE repo1'
|
||||
- query: "SELECT COUNT(*) AS count FROM wide_mixed"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["3"]]
|
||||
- query: "SELECT i00, i09, LEFT(t00,3) AS t00, LEFT(v04,1) AS v04 FROM wide_mixed WHERE id = 2"
|
||||
result:
|
||||
columns: ["i00","i09","t00","v04"]
|
||||
rows: [["11","20","T00","Z"]]
|
||||
- query: "SELECT dolt_assume_cluster_role('primary', 2)"
|
||||
result:
|
||||
columns: ["dolt_assume_cluster_role"]
|
||||
rows: [["{0}"]]
|
||||
- on: server2
|
||||
queries:
|
||||
- exec: 'USE repo1'
|
||||
- exec: |
|
||||
INSERT INTO wide_mixed VALUES
|
||||
(4,
|
||||
100,200,300,400,500,600,700,800,900,1000,
|
||||
REPEAT('new',667), REPEAT('row',667), REPEAT('ins',667), REPEAT('ert',667), REPEAT('ed!',668),
|
||||
REPEAT('N',300), REPEAT('E',300), REPEAT('W',300), REPEAT('R',300), REPEAT('O',300))
|
||||
- query: "SELECT COUNT(*) AS count FROM wide_mixed"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["4"]]
|
||||
- query: "SELECT i00, LEFT(t00,3) AS t00 FROM wide_mixed WHERE id = 4"
|
||||
result:
|
||||
columns: ["i00","t00"]
|
||||
rows: [["100","new"]]
|
||||
- query: "SELECT COUNT(*) AS count FROM wide_mixed WHERE LENGTH(t00) > 1000"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["4"]]
|
||||
@@ -0,0 +1,105 @@
|
||||
parallel: true
|
||||
tests:
|
||||
|
||||
- name: wide text column table replicates correctly
|
||||
skip: "cluster replication/failover not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
behavior:
|
||||
auto_gc_behavior:
|
||||
enable: false
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
behavior:
|
||||
auto_gc_behavior:
|
||||
enable: false
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: 'SET dolt_cluster_ack_writes_timeout_secs = 10'
|
||||
- exec: 'CREATE DATABASE repo1'
|
||||
- exec: 'USE repo1'
|
||||
# 20 TEXT columns × 2 KB per cell = ~40 KB of out-of-band data per row.
|
||||
# Each row requires 20 separate external chunk references.
|
||||
- exec: |
|
||||
CREATE TABLE wide_text (
|
||||
id BIGINT PRIMARY KEY,
|
||||
t00 TEXT, t01 TEXT, t02 TEXT, t03 TEXT, t04 TEXT,
|
||||
t05 TEXT, t06 TEXT, t07 TEXT, t08 TEXT, t09 TEXT,
|
||||
t10 TEXT, t11 TEXT, t12 TEXT, t13 TEXT, t14 TEXT,
|
||||
t15 TEXT, t16 TEXT, t17 TEXT, t18 TEXT, t19 TEXT
|
||||
)
|
||||
- exec: |
|
||||
INSERT INTO wide_text VALUES
|
||||
(1,
|
||||
REPEAT('a',2000), REPEAT('b',2000), REPEAT('c',2000), REPEAT('d',2000), REPEAT('e',2000),
|
||||
REPEAT('f',2000), REPEAT('g',2000), REPEAT('h',2000), REPEAT('i',2000), REPEAT('j',2000),
|
||||
REPEAT('k',2000), REPEAT('l',2000), REPEAT('m',2000), REPEAT('n',2000), REPEAT('o',2000),
|
||||
REPEAT('p',2000), REPEAT('q',2000), REPEAT('r',2000), REPEAT('s',2000), REPEAT('t',2000))
|
||||
- exec: |
|
||||
INSERT INTO wide_text VALUES
|
||||
(2,
|
||||
REPEAT('A',2000), REPEAT('B',2000), REPEAT('C',2000), REPEAT('D',2000), REPEAT('E',2000),
|
||||
REPEAT('F',2000), REPEAT('G',2000), REPEAT('H',2000), REPEAT('I',2000), REPEAT('J',2000),
|
||||
REPEAT('K',2000), REPEAT('L',2000), REPEAT('M',2000), REPEAT('N',2000), REPEAT('O',2000),
|
||||
REPEAT('P',2000), REPEAT('Q',2000), REPEAT('R',2000), REPEAT('S',2000), REPEAT('T',2000))
|
||||
- exec: |
|
||||
INSERT INTO wide_text VALUES
|
||||
(3,
|
||||
REPEAT('1',2000), REPEAT('2',2000), REPEAT('3',2000), REPEAT('4',2000), REPEAT('5',2000),
|
||||
REPEAT('6',2000), REPEAT('7',2000), REPEAT('8',2000), REPEAT('9',2000), REPEAT('0',2000),
|
||||
REPEAT('1',2000), REPEAT('2',2000), REPEAT('3',2000), REPEAT('4',2000), REPEAT('5',2000),
|
||||
REPEAT('6',2000), REPEAT('7',2000), REPEAT('8',2000), REPEAT('9',2000), REPEAT('0',2000))
|
||||
- query: "SELECT COUNT(*) AS count FROM wide_text WHERE LENGTH(t00) = 2000 AND LENGTH(t19) = 2000"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["3"]]
|
||||
- query: "SELECT LEFT(t00,1) AS t00, LEFT(t10,1) AS t10 FROM wide_text WHERE id = 1"
|
||||
result:
|
||||
columns: ["t00","t10"]
|
||||
rows: [["a","k"]]
|
||||
- on: server2
|
||||
retry_attempts: 100
|
||||
queries:
|
||||
- exec: 'USE repo1'
|
||||
- query: "SELECT COUNT(*) AS count FROM wide_text WHERE LENGTH(t00) = 2000 AND LENGTH(t19) = 2000"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["3"]]
|
||||
- query: "SELECT LEFT(t00,1) AS t00, LEFT(t10,1) AS t10 FROM wide_text WHERE id = 1"
|
||||
result:
|
||||
columns: ["t00","t10"]
|
||||
rows: [["a","k"]]
|
||||
- query: "SELECT LEFT(t00,1) AS t00, LEFT(t10,1) AS t10 FROM wide_text WHERE id = 2"
|
||||
result:
|
||||
columns: ["t00","t10"]
|
||||
rows: [["A","K"]]
|
||||
@@ -0,0 +1,116 @@
|
||||
parallel: true
|
||||
tests:
|
||||
|
||||
- name: wide varchar column table replicates and survives gc
|
||||
skip: "cluster replication/failover not yet implemented in Doltgres"
|
||||
multi_repos:
|
||||
- name: server1
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
behavior:
|
||||
auto_gc_behavior:
|
||||
enable: false
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server2_cluster"}}/{database}
|
||||
bootstrap_role: primary
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server1_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server1
|
||||
- name: server2
|
||||
with_files:
|
||||
- name: server.yaml
|
||||
contents: |
|
||||
log_level: trace
|
||||
behavior:
|
||||
auto_gc_behavior:
|
||||
enable: false
|
||||
cluster:
|
||||
standby_remotes:
|
||||
- name: standby
|
||||
remote_url_template: http://localhost:{{get_port "server1_cluster"}}/{database}
|
||||
bootstrap_role: standby
|
||||
bootstrap_epoch: 1
|
||||
remotesapi:
|
||||
port: {{get_port "server2_cluster"}}
|
||||
server:
|
||||
args: ["--config", "server.yaml"]
|
||||
dynamic_port: server2
|
||||
connections:
|
||||
- on: server1
|
||||
queries:
|
||||
- exec: 'SET dolt_cluster_ack_writes_timeout_secs = 10'
|
||||
- exec: 'CREATE DATABASE repo1'
|
||||
- exec: 'USE repo1'
|
||||
# 8 VARCHAR(300) columns: Dolt's per-column accounting is ~8000 bytes for
|
||||
# VARCHAR(300), so 8 columns puts the row near (but under) Dolt's 64k inline limit.
|
||||
- exec: |
|
||||
CREATE TABLE wide_varchar (
|
||||
id BIGINT PRIMARY KEY,
|
||||
v00 VARCHAR(300), v01 VARCHAR(300), v02 VARCHAR(300), v03 VARCHAR(300),
|
||||
v04 VARCHAR(300), v05 VARCHAR(300), v06 VARCHAR(300), v07 VARCHAR(300)
|
||||
)
|
||||
- exec: |
|
||||
INSERT INTO wide_varchar VALUES
|
||||
(1,
|
||||
REPEAT('a',300), REPEAT('b',300), REPEAT('c',300), REPEAT('d',300),
|
||||
REPEAT('e',300), REPEAT('f',300), REPEAT('g',300), REPEAT('h',300))
|
||||
- exec: |
|
||||
INSERT INTO wide_varchar VALUES
|
||||
(2,
|
||||
REPEAT('A',300), REPEAT('B',300), REPEAT('C',300), REPEAT('D',300),
|
||||
REPEAT('E',300), REPEAT('F',300), REPEAT('G',300), REPEAT('H',300))
|
||||
- exec: |
|
||||
INSERT INTO wide_varchar VALUES
|
||||
(3,
|
||||
REPEAT('0',300), REPEAT('1',300), REPEAT('2',300), REPEAT('3',300),
|
||||
REPEAT('4',300), REPEAT('5',300), REPEAT('6',300), REPEAT('7',300))
|
||||
- query: "SELECT COUNT(*) AS count FROM wide_varchar WHERE LENGTH(v00) = 300 AND LENGTH(v07) = 300"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["3"]]
|
||||
- exec: 'SELECT dolt_gc()'
|
||||
- query: 'SELECT COUNT(*) FROM wide_varchar'
|
||||
error_match: "this connection can no longer be used"
|
||||
- on: server1
|
||||
queries:
|
||||
- query: |
|
||||
SELECT "database", standby_remote, role, epoch, replication_lag_millis, current_error
|
||||
FROM dolt_cluster.dolt_cluster_status
|
||||
ORDER BY "database" ASC
|
||||
result:
|
||||
columns: ["database","standby_remote","role","epoch","replication_lag_millis","current_error"]
|
||||
rows:
|
||||
- ["repo1","standby","primary","1","0","NULL"]
|
||||
retry_attempts: 100
|
||||
- exec: 'USE repo1'
|
||||
- query: "SELECT COUNT(*) AS count FROM wide_varchar WHERE LENGTH(v00) = 300 AND LENGTH(v07) = 300"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["3"]]
|
||||
- query: "SELECT LEFT(v00, 1) AS v00, LEFT(v07, 1) AS v07 FROM wide_varchar WHERE id = 1"
|
||||
result:
|
||||
columns: ["v00","v07"]
|
||||
rows: [["a","h"]]
|
||||
- on: server2
|
||||
queries:
|
||||
- exec: 'USE repo1'
|
||||
- query: "SELECT COUNT(*) AS count FROM wide_varchar WHERE LENGTH(v00) = 300 AND LENGTH(v07) = 300"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["3"]]
|
||||
- query: "SELECT LEFT(v00, 1) AS v00, LEFT(v07, 1) AS v07 FROM wide_varchar WHERE id = 2"
|
||||
result:
|
||||
columns: ["v00","v07"]
|
||||
rows: [["A","H"]]
|
||||
- exec: "SELECT dolt_gc('--shallow')"
|
||||
- query: "SELECT COUNT(*) AS count FROM wide_varchar WHERE LENGTH(v00) = 300 AND LENGTH(v07) = 300"
|
||||
result:
|
||||
columns: ["count"]
|
||||
rows: [["3"]]
|
||||
Reference in New Issue
Block a user