Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/actions/orm-tests/action.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
name: 'Doltgres ORM integration tests'
description: 'Smoke tests for ORM integrations'
runs:
using: 'docker'
image: '../../../testing/DoltgresORMDockerfile'
33 changes: 33 additions & 0 deletions .github/workflows/ci-orm-tests.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Test Doltgres ORM integrations

on:
workflow_dispatch:
repository_dispatch:
types: [ test-doltgres-orm-integrations ]

jobs:
orm_integrations_job:
runs-on: ubuntu-22.04
timeout-minutes: 20
name: Run tests
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Test Doltgres ORM integrations
uses: ./.github/actions/orm-tests
- name: Configure AWS Credentials
if: ${{ failure() }}
uses: aws-actions/configure-aws-credentials@v4
with:
aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
aws-region: us-west-2
- name: Send Email
if: ${{ failure() }}
uses: ./.github/actions/ses-email-action
with:
template: 'OrmIntegrationFailureTemplate'
region: us-west-2
version: ${{ github.ref }}
toAddresses: '["[email protected]", "[email protected]"]'
workflowURL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ jobs:
token: ${{ secrets.REPO_ACCESS_TOKEN }}
event-type: sql-correctness
client-payload: '{"version": "${{ github.sha }}", "mode": "nightly", "actor": "${{ github.actor }}", "template_script": "./.github/scripts/sql-correctness/get-doltgres-correctness-job-json.sh"}'
- uses: peter-evans/repository-dispatch@v3
with:
token: ${{ secrets.REPO_ACCESS_TOKEN }}
event-type: test-doltgres-orm-integrations
60 changes: 60 additions & 0 deletions testing/DoltgresORMDockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
FROM --platform=${BUILDPLATFORM} ubuntu:22.04

# install ORM tools and dependencies
ENV DEBIAN_FRONTEND=noninteractive
RUN apt update -y && \
apt install -y \
curl \
gnupg \
software-properties-common && \
curl -sL https://deb.nodesource.com/setup_22.x | bash - && \
add-apt-repository ppa:deadsnakes/ppa -y && \
sh -c 'echo "deb http://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list' && \
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg
RUN apt update -y && \
apt install -y \
nodejs \
python3.9 \
python3-pip \
git \
bats \
postgresql-server-dev-15 && \
update-ca-certificates -f

# install go
WORKDIR /root
ENV GO_VERSION=1.25.0
ENV GOPATH=/go
ENV PATH=$PATH:$GOPATH/bin
ENV PATH=$PATH:$GOPATH/bin:/usr/local/go/bin
RUN curl -O "https://dl.google.com/go/go${GO_VERSION}.linux-amd64.tar.gz" && \
sha256sum "go${GO_VERSION}.linux-amd64.tar.gz" && \
tar -xvf "go${GO_VERSION}.linux-amd64.tar.gz" -C /usr/local && \
chown -R root:root /usr/local/go && \
mkdir -p $HOME/go/{bin,src} && \
go version

# install doltgres from source
WORKDIR /root/building
COPY go.mod doltgresql/

# download dependencies first to persist Go dependencies download cache for doltgres despite other edits
WORKDIR doltgresql
RUN go mod download

# exclude clients directory to persist build-cache for doltgres when only editing ORM code
COPY --exclude=testing/doltgres-orm-tests/ . .

# Build the parser
WORKDIR /root/building/doltgresql/postgres/parser
RUN bash ./build.sh

# Build the doltgres binary, which we will need for bats, and put it on PATH
WORKDIR /root/building/doltgresql/cmd/doltgres
RUN go build -o /usr/local/bin/doltgres .

COPY ./testing/doltgres-orm-tests /doltgres-orm-tests
COPY ./testing/doltgres-orm-tests/doltgres-orm-tests-entrypoint.sh /doltgres-orm-tests/entrypoint.sh

WORKDIR /doltgres-orm-tests
ENTRYPOINT ["/doltgres-orm-tests/entrypoint.sh"]
22 changes: 22 additions & 0 deletions testing/doltgres-orm-tests/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
## PostgreSQL ORM Tests
We created smoke tests for Doltgres's PostgreSQL ORM library integrations,
and we run these tests through GitHub Actions on pull requests.

These tests can be run locally using Docker. From the doltgresql directory of the repo, run:

```bash
$ docker build -t doltgres-orm-tests -f testing/DoltgresORMDockerfile .
$ docker run doltgres-orm-tests:latest
```

The `docker build` step will take a few minutes to complete
as it needs to install all the dependencies in the image.

Running the built container will produce output like:
```bash
$ docker run orm-tests:latest
Running Doltgres orm-tests:
1..1
ok 1 drizzle smoke test
```
docker run doltgres-orm-tests:latest
4 changes: 4 additions & 0 deletions testing/doltgres-orm-tests/doltgres-orm-tests-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh

echo "Running Doltgres orm-tests:"
bats /doltgres-orm-tests/doltgres-orm-tests.bats
36 changes: 36 additions & 0 deletions testing/doltgres-orm-tests/doltgres-orm-tests.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
#!/usr/bin/env bats
load $BATS_TEST_DIRNAME/helpers.bash

setup() {
setup_doltgres_repo
}

teardown() {
teardown_doltgres_repo

# Check if postgresql is still running. If so stop it
active=$(service postgresql status)
if echo "$active" | grep "online"; then
service postgresql stop
fi
}

@test "Drizzle smoke test" {
# the schema should be empty
# the dolt system tables are filtered out
cd $BATS_TEST_DIRNAME/drizzle
npm i drizzle-orm pg dotenv
npm i -D drizzle-kit tsx @types/pg
npx drizzle-kit push

# we can check if 'components table was created'
query_server -c "SELECT * FROM users" -t
run query_server -c "SELECT * FROM users" -t
[ "$status" -eq 0 ]

npx tsx src/index.ts
query_server -c "SELECT * FROM users" -t
run query_server -c "SELECT age FROM users" -t
[ "$status" -eq 0 ]
[[ "$output" =~ "31" ]] || false
}
11 changes: 11 additions & 0 deletions testing/doltgres-orm-tests/drizzle/drizzle.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import 'dotenv/config';
import { defineConfig } from 'drizzle-kit';
export default defineConfig({
out: './drizzle',
schema: './src/db/schema.ts',
dialect: 'postgresql',
dbCredentials: {
url: 'postgres://postgres:password@localhost:5432/postgres',
},
tablesFilter: ["!dolt_*"], // IMPORTANT to filter out dolt system tables
});
9 changes: 9 additions & 0 deletions testing/doltgres-orm-tests/drizzle/src/db/schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { jsonb, integer, pgTable, varchar } from 'drizzle-orm/pg-core';

export const usersTable = pgTable("users", {
id: integer().primaryKey(),
name: varchar({ length: 255 }).notNull(),
age: integer().notNull(),
email: varchar({ length: 255 }).notNull().unique(),
render: jsonb('render'),
});
41 changes: 41 additions & 0 deletions testing/doltgres-orm-tests/drizzle/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import 'dotenv/config';
import { Pool } from 'pg';
import { drizzle } from 'drizzle-orm/node-postgres';
import { usersTable } from "./db/schema";
import { eq } from 'drizzle-orm';

const connectionString = 'postgres://postgres:password@localhost:5432/postgres';
const pool = new Pool({ connectionString });
const db = drizzle(pool);

async function main() {
const user: typeof usersTable.$inferInsert = {
id: 1,
name: 'John',
age: 30,
render: null,
email: '[email protected]',
};
await db.insert(usersTable).values(user);
console.log('New user created!')
const users = await db.select().from(usersTable);
console.log('Getting all users from the database: ', users)
/*
const users: {
id: number;
name: string;
age: number;
email: string;
render: jsonb;
}[]
*/
await db
.update(usersTable)
.set({
age: 31,
})
.where(eq(usersTable.email, user.email));
console.log('User info updated!')
}

main();
50 changes: 50 additions & 0 deletions testing/doltgres-orm-tests/helpers.bash
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
start_doltgres_server() {
REPO_NAME="doltgres_repo_$$"
mkdir $REPO_NAME
cd $REPO_NAME

CONFIG=$( defineCONFIG )
echo "$CONFIG" > config.yaml

doltgres --data-dir=. -config=config.yaml &
SERVER_PID=$!
# Give the server a chance to start
sleep 2
}

setup_doltgres_repo() {
run psql --version
if [[ ! "$output" =~ "(PostgreSQL) 15" ]] && [[ ! "$output" =~ "(PostgreSQL) 16" ]] && [[ ! "$output" =~ "(PostgreSQL) 17" ]]; then
echo "PSQL must be version 15, got $output"
return 1
fi

start_doltgres_server
}

teardown_doltgres_repo() {
cd ..
kill $SERVER_PID
rm -rf $REPO_NAME
}

query_server() {
PGPASSWORD="password" psql -U "postgres" -h localhost -p 5432 "$@" postgres
}

defineCONFIG() {
cat <<EOF
behavior:
read_only: false
disable_client_multi_statements: false
dolt_transaction_commit: false

user:
name: "postgres"
password: "password"

listener:
host: localhost
port: 5432
EOF
}
2 changes: 1 addition & 1 deletion testing/postgres-client-tests/postgres-client-tests.bats
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,4 @@ teardown() {
@test "python postgres: sqlalcchemy client" {
cd $BATS_TEST_DIRNAME/python
python3 sqlalchemy-test.py $USER $PORT
}
}