Skip to content

Commit

Permalink
Move integration tests to Go
Browse files Browse the repository at this point in the history
  • Loading branch information
tygern committed May 7, 2024
1 parent 6f30b16 commit 5012cf4
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 67 deletions.
8 changes: 5 additions & 3 deletions .github/workflows/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,14 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install --yes postgresql-client
- name: Create database user
run: |
psql --host localhost --username postgres < databases/create_databases.sql
- name: Run integration tests
env:
PGHOST: localhost
PGUSER: postgres
OPEN_AI_KEY: ${{ secrets.OPEN_AI_KEY }}
run: ./test-integration.sh
run: |
go test ./cmd/integrationtest -tags=integration
build-app:
runs-on: ubuntu-latest
needs: [ test, integration-test ]
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,5 +120,5 @@ The integration test script runs the collector and analyzer, then tests the app

```shell
source .env
./test-integration.sh
go test -count=1 ./cmd/integrationtest -tags=integration
```
125 changes: 125 additions & 0 deletions cmd/integrationtest/app_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
//go:build integration

package integration_test

import (
"context"
"database/sql"
"fmt"
"github.com/initialcapacity/ai-starter/pkg/dbsupport"
"github.com/initialcapacity/ai-starter/pkg/testsupport"
"github.com/initialcapacity/ai-starter/pkg/websupport"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"io"
"net/http"
"os"
"os/exec"
"strings"
"testing"
)

func TestIntegration(t *testing.T) {
client := http.Client{}
openAiKey := websupport.RequireEnvironmentVariable[string]("OPEN_AI_KEY")
dbUrl := "postgres://starter:starter@localhost:5432/starter_integration?sslmode=disable"

createIntegrationDatabase(t)
prepareIntegrationDatabase(t)
prepareBuildDirectory(t)

build(t, "migrate")
build(t, "cannedrss")
build(t, "collector")
build(t, "analyzer")
build(t, "app")

testCtx, cancelCtx := context.WithCancel(context.Background())
defer cancelCtx()

startCommand(t, testCtx, "./build/cannedrss")
startCommand(t, testCtx, "./build/app",
fmt.Sprintf("DATABASE_URL=%s", dbUrl),
fmt.Sprintf("OPEN_AI_KEY=%s", openAiKey),
"HOST=localhost",
"PORT=8234")

runCommand(t, testCtx, "./build/migrate",
fmt.Sprintf("DATABASE_URL=%s", dbUrl),
"MIGRATIONS_LOCATION=file://../../databases/starter")
runCommand(t, testCtx, "./build/collector",
fmt.Sprintf("DATABASE_URL=%s", dbUrl),
"FEEDS=http://localhost:8123")
runCommand(t, testCtx, "./build/analyzer",
fmt.Sprintf("DATABASE_URL=%s", dbUrl),
fmt.Sprintf("OPEN_AI_KEY=%s", openAiKey))

getResponse, err := client.Get("http://localhost:8234/")
require.NoError(t, err)
assert.Equal(t, http.StatusOK, getResponse.StatusCode)
getBody := readBody(t, getResponse)
assert.Contains(t, getBody, "What would you like to know")

postResponse, err := client.Post("http://localhost:8234/", "application/x-www-form-urlencoded", strings.NewReader("query=tell%20me%20about%20pickles"))
require.NoError(t, err)
assert.Equal(t, http.StatusOK, postResponse.StatusCode)
postBody := readBody(t, postResponse)
assert.Contains(t, postBody, "http://localhost:8123/pickles")
assert.Contains(t, postBody, "</html>")
}

func createIntegrationDatabase(t *testing.T) {
testsupport.WithSuperDb(t, func(superDb *sql.DB) {
execute(t, superDb, "drop database if exists starter_integration")
execute(t, superDb, "create database starter_integration")
execute(t, superDb, "grant all privileges on database starter_integration to starter")
})
}

func prepareIntegrationDatabase(t *testing.T) {
integrationDb := dbsupport.CreateConnection("postgres://super_test@localhost:5432/starter_integration?sslmode=disable")
defer func() {
err := integrationDb.Close()
require.NoError(t, err)
}()

execute(t, integrationDb, "create extension if not exists vector")
execute(t, integrationDb, "grant usage, create on schema public to starter")
}

func execute(t *testing.T, db *sql.DB, command string) {
_, err := db.Exec(command)
require.NoError(t, err, fmt.Sprintf("unable to execute %s", command))
}

func prepareBuildDirectory(t *testing.T) {
err := os.RemoveAll("../../build")
require.NoError(t, err)
err = os.MkdirAll("./build", os.ModePerm)
require.NoError(t, err)
}

func build(t *testing.T, name string) {
err := exec.Command("go", "build", "-o", fmt.Sprintf("./build/%s", name), fmt.Sprintf("../../cmd/%s", name)).Run()
require.NoError(t, err, fmt.Sprintf("build %s failed", name))
}

func startCommand(t *testing.T, ctx context.Context, command string, environment ...string) {
cmd := exec.CommandContext(ctx, command)
cmd.Env = append(cmd.Env, environment...)
err := cmd.Start()
require.NoError(t, err, fmt.Sprintf("failed to start %s", command))
}

func runCommand(t *testing.T, ctx context.Context, command string, environment ...string) {
cmd := exec.CommandContext(ctx, command)
cmd.Env = append(cmd.Env, environment...)
err := cmd.Run()
require.NoError(t, err, fmt.Sprintf("failed to run %s", command))
}

func readBody(t *testing.T, response *http.Response) string {
body, err := io.ReadAll(response.Body)
require.NoError(t, err, "unable to read response body")
return string(body)
}
3 changes: 2 additions & 1 deletion cmd/migrate/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ import (

func main() {
databaseUrl := websupport.RequireEnvironmentVariable[string]("DATABASE_URL")
migration, err := migrate.New("file://./databases/starter", databaseUrl)
migrationsLocation := websupport.EnvironmentVariable("MIGRATIONS_LOCATION", "file://./databases/starter")
migration, err := migrate.New(migrationsLocation, databaseUrl)
if err != nil {
log.Fatalf("failed to connect to %s, %s", databaseUrl, err)
}
Expand Down
7 changes: 0 additions & 7 deletions databases/create_databases.sql
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
drop database if exists starter_integration;
drop database if exists starter_test;
drop database if exists starter_development;
drop user starter;
drop user super_test;

create database starter_development;
create database starter_test;
create database starter_integration;
create user starter with password 'starter';
create user super_test superuser ;
grant all privileges on database starter_development to starter;
grant all privileges on database starter_test to starter;
grant all privileges on database starter_integration to starter;

\connect starter_development
create extension if not exists vector;
Expand All @@ -20,7 +17,3 @@ grant usage, create on schema public to starter;
\connect starter_test
create extension if not exists vector;
grant usage, create on schema public to starter;

\connect starter_integration
create extension if not exists vector;
grant usage, create on schema public to starter;
6 changes: 3 additions & 3 deletions pkg/testsupport/test_connection.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type TestDb struct {

func NewTestDb(t *testing.T) *TestDb {
testDbName := fmt.Sprintf("starter_test_%d", rand.IntN(1_000_000))
withSuperDb(t, func(superDb *sql.DB) {
WithSuperDb(t, func(superDb *sql.DB) {
_, err := superDb.Exec(fmt.Sprintf("create database %s template starter_test", testDbName))
assert.NoError(t, err, "unable to create test database")
})
Expand All @@ -35,7 +35,7 @@ func (tdb *TestDb) Close() {
err := tdb.DB.Close()
assert.NoError(tdb.t, err)

withSuperDb(tdb.t, func(superDb *sql.DB) {
WithSuperDb(tdb.t, func(superDb *sql.DB) {
_, err = superDb.Exec(fmt.Sprintf("drop database %s", tdb.testDbName))
assert.NoError(tdb.t, err, "unable to drop test database")
})
Expand All @@ -46,7 +46,7 @@ func (tdb *TestDb) Execute(statement string, arguments ...any) {
assert.NoError(tdb.t, err)
}

func withSuperDb(t *testing.T, action func(superDb *sql.DB)) {
func WithSuperDb(t *testing.T, action func(superDb *sql.DB)) {
superDb := dbsupport.CreateConnection("postgres://super_test@localhost:5432/postgres?sslmode=disable")
defer func(superDb *sql.DB) {
err := superDb.Close()
Expand Down
52 changes: 0 additions & 52 deletions test-integration.sh

This file was deleted.

0 comments on commit 5012cf4

Please sign in to comment.