-
Notifications
You must be signed in to change notification settings - Fork 117
feat: add DST setup #879
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
feat: add DST setup #879
Changes from 31 commits
f66f8e2
df41f3d
eead415
3b91230
24c347a
0addc57
dc15569
d64d1ef
32759cc
a380c0b
b22e498
0919823
8aa8fb7
6d3747a
256bfb9
10acc49
a2351d6
58524d7
4ed1eb5
8aaa393
3ec2e4c
9f22e06
aa9fa2b
e8b6e82
9fc1cf7
e52be33
40c1a39
c8ab708
f8fa1ba
979b33a
49b0414
9248bd8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
name: Antithesis Integration | ||
on: | ||
workflow_dispatch: | ||
inputs: | ||
run_tests: | ||
description: 'Run Antithesis tests after pushing images' | ||
type: boolean | ||
default: true | ||
push: | ||
branches: | ||
- main | ||
pull_request: | ||
types: [opened, synchronize, reopened] | ||
paths: | ||
- 'test/antithesis/**' | ||
|
||
jobs: | ||
push-antithesis-images: | ||
name: Push Images to Antithesis | ||
runs-on: shipfox-4vcpu-ubuntu-2404 | ||
steps: | ||
- name: Checkout code | ||
uses: actions/checkout@v4 | ||
with: | ||
fetch-depth: 0 | ||
|
||
- name: Setup Earthly | ||
uses: earthly/actions-setup@v1 | ||
with: | ||
github-token: ${{ secrets.GITHUB_TOKEN }} | ||
version: "latest" | ||
|
||
- name: Setup Environment | ||
uses: ./.github/actions/default | ||
with: | ||
token: ${{ secrets.NUMARY_GITHUB_TOKEN }} | ||
|
||
- name: Set up QEMU | ||
uses: docker/setup-qemu-action@v3 | ||
|
||
- name: Set up Docker Buildx | ||
uses: docker/setup-buildx-action@v3 | ||
|
||
- name: Login to Antithesis Docker Registry | ||
run: | | ||
echo '${{ secrets.ANTITHESIS_JSON_KEY }}' | docker login -u _json_key https://us-central1-docker.pkg.dev --password-stdin | ||
|
||
- name: Build and Push Config Image | ||
run: | | ||
cd test/antithesis | ||
earthly --push +requirements-build --ANTITHESIS_REPOSITORY=${{ secrets.ANTITHESIS_REPOSITORY }} | ||
|
||
- name: Run Antithesis Tests | ||
if: ${{ github.event_name == 'workflow_dispatch' && inputs.run_tests == true }} | ||
run: | | ||
cd test/antithesis | ||
earthly +run --ANTITHESIS_SLACK_REPORT_RECIPIENT="${{ secrets.ANTITHESIS_SLACK_REPORT_RECIPIENT }}" --ANTITHESIS_REPOSITORY=${{ secrets.ANTITHESIS_REGISTRY }} --ANTITHESIS_PASSWORD=${{ secrets.ANTITHESIS_PASSWORD }} | ||
# env: | ||
# ANTITHESIS_PASSWORD: ${{ secrets.ANTITHESIS_PASSWORD }} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,13 +4,15 @@ | |
"context" | ||
"errors" | ||
"fmt" | ||
"sync" | ||
"time" | ||
|
||
"github.com/antithesishq/antithesis-sdk-go/assert" | ||
"github.com/formancehq/ledger/internal/storage/common" | ||
systemstore "github.com/formancehq/ledger/internal/storage/system" | ||
"github.com/formancehq/ledger/internal/tracing" | ||
"go.opentelemetry.io/otel/trace" | ||
"go.opentelemetry.io/otel/trace/noop" | ||
"sync" | ||
"time" | ||
|
||
"github.com/alitto/pond" | ||
"github.com/formancehq/go-libs/v3/bun/bunpaginate" | ||
|
@@ -35,13 +37,31 @@ | |
parallelBucketMigrations int | ||
} | ||
|
||
func (d *Driver) CreateLedger(ctx context.Context, l *ledger.Ledger) (*ledgerstore.Store, error) { | ||
/* | ||
CreateLedger creates a new ledger in the system and sets up all necessary database objects. | ||
|
||
The function follows these steps: | ||
1. Create a ledger record in the system store (_system.ledgers table) | ||
2. Get the bucket (database schema) for this ledger | ||
3. Check if the bucket is already initialized: | ||
a. If initialized: Verify it's up to date and add ledger-specific objects to it | ||
b. If not initialized: Create the bucket schema with all necessary tables | ||
4. Return a ledger store that provides an interface to interact with the ledger | ||
|
||
Note: This entire process is wrapped in a database transaction, ensuring atomicity. | ||
If any step fails, the entire transaction is rolled back, preventing partial state. | ||
*/ | ||
func (d *Driver) CreateLedger(ctx context.Context, l *ledger.Ledger) (*ledgerstore.Store, error) { | ||
var ret *ledgerstore.Store | ||
|
||
// Run the entire ledger creation process in a transaction for atomicity | ||
// This ensures that either all steps succeed or none do (preventing partial state) | ||
err := d.db.RunInTx(ctx, nil, func(ctx context.Context, tx bun.Tx) error { | ||
systemStore := d.systemStoreFactory.Create(tx) | ||
|
||
// Step 1: Create the ledger record in the system store | ||
if err := systemStore.CreateLedger(ctx, l); err != nil { | ||
// Handle the case where the ledger already exists | ||
if errors.Is(postgres.ResolveError(err), postgres.ErrConstraintsFailed{}) { | ||
return systemcontroller.ErrLedgerAlreadyExists | ||
} | ||
|
@@ -53,13 +73,26 @@ | |
if err != nil { | ||
return fmt.Errorf("checking if bucket is initialized: %w", err) | ||
} | ||
|
||
if isInitialized { | ||
upToDate, err := b.IsUpToDate(ctx, tx) | ||
if err != nil { | ||
return fmt.Errorf("checking if bucket is up to date: %w", err) | ||
} | ||
|
||
if !upToDate { | ||
assert.AlwaysOrUnreachable( | ||
// @todo: replace this with a proper flag detailing wether we're | ||
// operating a new version of the binary or not. | ||
// if we are, we are definitely expecting this to happen. | ||
// if we're not, this should be unreachable. | ||
false, | ||
"Bucket is outdated", | ||
map[string]any{ | ||
"bucket": l.Bucket, | ||
}, | ||
) | ||
|
||
Comment on lines
+84
to
+95
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 💡 Verification agent 🧩 Analysis chainTodo indicates temporary assertion pattern The assertion is using Consider:
🏁 Script executed: #!/bin/bash
# Check if there are any tests covering this assertion in the driver code
rg -A 5 -B 5 "test.*Bucket.*Outdated" --type go Length of output: 49 To be certain this assertion path is untested, let’s list any driver test files and search them for 🏁 Script executed: #!/bin/bash
# List Go test files in internal/storage/driver
fd -e go --glob '*_test.go' internal/storage/driver
# Search those test files for AlwaysOrUnreachable
rg "AlwaysOrUnreachable" -n --glob "internal/storage/driver/*_test.go" Length of output: 348 Ensure proper flag control and add tests for the unreachable assertion The • Introduce the boolean flag referenced in the TODO (e.g.
This will satisfy the TODO and ensure the code path is exercised. 🧰 Tools🪛 GitHub Check: codecov/patch[warning] 84-95: internal/storage/driver/driver.go#L84-L95 |
||
return systemcontroller.ErrBucketOutdated | ||
} | ||
|
||
|
@@ -72,14 +105,18 @@ | |
} | ||
} | ||
|
||
// Step 4: Create a store for interacting with the ledger | ||
ret = d.ledgerStoreFactory.Create(b, *l) | ||
|
||
return nil | ||
}) | ||
|
||
// If any error occurred during the transaction, resolve and return it | ||
if err != nil { | ||
return nil, postgres.ResolveError(err) | ||
} | ||
|
||
// Return the created ledger store | ||
return ret, nil | ||
} | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
VERSION 0.7 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Stop using Earthfile, there is no Earthfile anymore in the repsoitory ;) |
||
|
||
FROM --platform=linux/amd64 golang:1.22.2 | ||
|
||
client: | ||
FROM scratch | ||
COPY . /client | ||
SAVE ARTIFACT /client client |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
VERSION 0.8 | ||
|
||
IMPORT github.com/formancehq/earthly:tags/v0.17.1 AS core | ||
|
||
FROM core+base-image | ||
|
||
run: | ||
WAIT | ||
BUILD +requirements-build | ||
END | ||
|
||
FROM curlimages/curl | ||
ARG ANTITHESIS_USERNAME=formance | ||
ARG --required ANTITHESIS_SLACK_REPORT_RECIPIENT | ||
RUN --no-cache --secret ANTITHESIS_PASSWORD curl \ | ||
--fail \ | ||
--user "$ANTITHESIS_USERNAME:$ANTITHESIS_PASSWORD" \ | ||
-X POST https://formance.antithesis.com/api/v1/launch_experiment/formance -d "{ | ||
\"params\": { | ||
\"custom.duration\": \"0.1\", | ||
\"antithesis.report.recipients\": \"${ANTITHESIS_SLACK_REPORT_RECIPIENT}\", | ||
\"antithesis.config_image\": \"antithesis-config:latest\", | ||
\"antithesis.images\": \"ledger:latest;workload:latest\" | ||
} | ||
}" | ||
|
||
run-1h: | ||
WAIT | ||
BUILD +requirements-build | ||
END | ||
|
||
FROM curlimages/curl | ||
ARG ANTITHESIS_USERNAME=formance | ||
ARG --required ANTITHESIS_SLACK_REPORT_RECIPIENT | ||
RUN --no-cache --secret ANTITHESIS_PASSWORD curl \ | ||
--fail \ | ||
--user "$ANTITHESIS_USERNAME:$ANTITHESIS_PASSWORD" \ | ||
-X POST https://formance.antithesis.com/api/v1/launch_experiment/formance -d "{ | ||
\"params\": { | ||
\"custom.duration\": \"1\", | ||
\"antithesis.report.recipients\": \"${ANTITHESIS_SLACK_REPORT_RECIPIENT}\", | ||
\"antithesis.config_image\": \"antithesis-config:latest\", | ||
\"antithesis.images\": \"ledger:latest;workload:latest\" | ||
} | ||
}" | ||
|
||
debugger: | ||
FROM curlimages/curl | ||
|
||
ARG ANTITHESIS_USERNAME=formance | ||
ARG --required ANTITHESIS_SLACK_REPORT_RECIPIENT | ||
ARG --required VTIME | ||
ARG --required SESSION_ID | ||
ARG --required HASH | ||
RUN echo "{ | ||
\"params\": { | ||
\"antithesis.debugging.session_id\": \"${SESSION_ID}\", | ||
\"antithesis.debugging.input_hash\": \"${HASH}\", | ||
\"antithesis.debugging.vtime\": \"${VTIME}\", | ||
\"antithesis.report.recipients\": \"${ANTITHESIS_SLACK_REPORT_RECIPIENT}\" | ||
} | ||
}" > /tmp/debug_params.json | ||
|
||
# Display the debug parameters for verification | ||
RUN cat /tmp/debug_params.json | ||
|
||
RUN --no-cache --secret ANTITHESIS_PASSWORD curl \ | ||
--fail \ | ||
--user "$ANTITHESIS_USERNAME:$ANTITHESIS_PASSWORD" \ | ||
-X POST https://formance.antithesis.com/api/v1/launch/debugging \ | ||
-d @/tmp/debug_params.json | ||
|
||
requirements-build: | ||
ARG --required ANTITHESIS_REPOSITORY | ||
|
||
BUILD --pass-args ./config+build | ||
BUILD --pass-args ./image+build | ||
BUILD --pass-args ./workload+build |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
VERSION 0.8 | ||
|
||
IMPORT github.com/formancehq/earthly:tags/v0.17.1 AS core | ||
|
||
build: | ||
FROM --platform=linux/amd64 scratch | ||
ARG --required ANTITHESIS_REPOSITORY | ||
COPY docker-compose.yml /docker-compose.yml | ||
COPY --dir gateway /gateway | ||
|
||
SAVE IMAGE --push --no-manifest-list ${ANTITHESIS_REPOSITORY}/antithesis-config:latest |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
--- | ||
networks: | ||
formance: | ||
driver: bridge | ||
ipam: | ||
config: | ||
- subnet: 10.0.29.0/24 | ||
|
||
services: | ||
postgres: | ||
image: "postgres:15-alpine" | ||
hostname: postgres | ||
container_name: postgres | ||
command: | ||
- -c | ||
- max_connections=100 | ||
environment: | ||
POSTGRES_USER: "ledger" | ||
POSTGRES_PASSWORD: "ledger" | ||
POSTGRES_DB: "ledger" | ||
PGDATA: /data/postgres | ||
healthcheck: | ||
test: [ "CMD-SHELL", "pg_isready -U ledger" ] | ||
interval: 10s | ||
timeout: 5s | ||
retries: 5 | ||
networks: | ||
formance: | ||
ipv4_address: 10.0.29.16 | ||
|
||
ledger1: | ||
image: "us-central1-docker.pkg.dev/molten-verve-216720/formance-repository/ledger:latest" | ||
hostname: ledger1 | ||
container_name: ledger1 | ||
environment: | ||
POSTGRES_URI: "postgresql://ledger:ledger@10.0.29.16:5432/ledger?sslmode=disable" | ||
BIND: ":8080" | ||
POSTGRES_CONN_MAX_IDLE_TIME: "1m0s" | ||
POSTGRES_MAX_IDLE_CONNS: "20" | ||
POSTGRES_MAX_OPEN_CONNS: "20" | ||
networks: | ||
formance: | ||
ipv4_address: 10.0.29.17 | ||
depends_on: | ||
postgres: | ||
condition: service_healthy | ||
|
||
ledger2: | ||
image: "us-central1-docker.pkg.dev/molten-verve-216720/formance-repository/ledger:latest" | ||
hostname: ledger2 | ||
container_name: ledger2 | ||
environment: | ||
POSTGRES_URI: "postgresql://ledger:ledger@10.0.29.16:5432/ledger?sslmode=disable" | ||
POSTGRES_CONN_MAX_IDLE_TIME: "1m0s" | ||
POSTGRES_MAX_IDLE_CONNS: "20" | ||
POSTGRES_MAX_OPEN_CONNS: "20" | ||
BIND: ":8080" | ||
networks: | ||
formance: | ||
ipv4_address: 10.0.29.18 | ||
depends_on: | ||
postgres: | ||
condition: service_healthy | ||
|
||
workload: | ||
image: "us-central1-docker.pkg.dev/molten-verve-216720/formance-repository/workload:latest" | ||
hostname: workload | ||
container_name: workload | ||
networks: | ||
formance: | ||
ipv4_address: 10.0.29.19 | ||
depends_on: | ||
- gateway | ||
|
||
gateway: | ||
image: "ghcr.io/formancehq/gateway:v2.0.0-rc.20" | ||
hostname: gateway | ||
container_name: gateway | ||
volumes: | ||
- ./gateway/Caddyfile:/etc/caddy/Caddyfile | ||
ports: | ||
- "8080:8080" | ||
networks: | ||
formance: | ||
ipv4_address: 10.0.29.20 | ||
depends_on: | ||
- ledger1 | ||
- ledger2 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
{ | ||
# Local env dev config | ||
auto_https off | ||
debug | ||
} | ||
|
||
:8080 { | ||
reverse_proxy { | ||
to ledger1:8080 ledger2:8080 | ||
lb_policy first | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know comments are useful, but this kind of comment just rephrase the code ^^