Skip to content

Commit f5cf8bb

Browse files
authored
feat(FIR-46249): Firebolt Core support (#434)
1 parent d32a87a commit f5cf8bb

40 files changed

+1438
-65
lines changed

.github/resources/core/README.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Running tests for firebolt core over https
2+
3+
In order to run the integration tests using https protocol, we need to bring up an nginx reverse proxy. On this proxy we will install the server certificate. In our case it will be a self signed cert (localhost.pem) and its private key (localhost-key.pem).
4+
5+
The cert and its key will be stored in GitHub since we cannot have secrets stored in code repository, and it would be easier to rotate them (no code changes required):
6+
- FIREBOLT_CORE_DEV_CERT is the certificate
7+
- FIREBOLT_CORE_DEV_CERT_PRIVATE_KEY is the private key
8+
9+
This is the certificate information that we currently have. Note that it wille expire in 2 years (when it will expire we will generate a new certificate and key and set them in the Git repository secrets)
10+
11+
Certificate Information:
12+
- Common Name:
13+
- Subject Alternative Names: localhost
14+
- Organization: mkcert development certificate
15+
- Organization Unit: [email protected] (George's Blue Mac)
16+
- Locality:
17+
- State:
18+
- Country:
19+
- Valid From: May 22, 2025
20+
- Valid To: August 22, 2027
21+
- Issuer: mkcert [email protected] (George's Blue Mac), mkcert development CA
22+
- Key Size: 2048 bit
23+
- Serial Number: 5b19e46ed1a5a912da2cef0129924c41
24+
25+
26+
The client will connect over https to the nginx server which will do the TLS handshake and the TLS termination. It will then call the firebolt-core over http on port 3473.

.github/resources/core/config.json

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"nodes": [
3+
{
4+
"host": "firebolt-core"
5+
}
6+
]
7+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# this is the nginx configuration
2+
# for http we are already exposing port 3473 on the docker so it will connect to the firebolt directly without going through nginx
3+
4+
# HTTPS server
5+
server {
6+
listen 443 ssl;
7+
server_name localhost;
8+
9+
# On github these the localhost
10+
ssl_certificate /etc/nginx/certs/server.pem;
11+
ssl_certificate_key /etc/nginx/certs/server.key;
12+
13+
location / {
14+
proxy_pass http://firebolt-core:3473;
15+
proxy_set_header Host $host;
16+
}
17+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
name: firebolt-core
2+
3+
services:
4+
firebolt-core:
5+
image: ghcr.io/firebolt-db/firebolt-core:${IMAGE_TAG}
6+
container_name: firebolt-core
7+
command: --node 0
8+
privileged: true
9+
restart: no # equivalent to --rm (no persistence)
10+
ulimits:
11+
memlock: 8589934592
12+
ports:
13+
- 3473:3473
14+
volumes:
15+
# Mount the config file into the container.
16+
- ${BASE_DIR}/.github/resources/core/config.json:/firebolt-core/config.json:ro
17+
# Create an anonymous volume for Firebolt's internal database files. Not using a volume would have a performance impact.
18+
- ${BASE_DIR}/firebolt-core:/firebolt-core/data
19+
20+
nginx:
21+
image: nginx:alpine
22+
ports:
23+
- "443:443"
24+
volumes:
25+
- ${BASE_DIR}/.github/resources/core/certs:/etc/nginx/certs:ro
26+
- ${BASE_DIR}/.github/resources/core/default.conf:/etc/nginx/conf.d/default.conf:ro
27+
depends_on:
28+
- firebolt-core
Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
name: Core integration tests
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
tag_version:
7+
description: 'The docker image tag for the firebolt core'
8+
required: false
9+
type: string
10+
python_version:
11+
description: 'Python version'
12+
required: false
13+
type: string
14+
default: '3.10'
15+
os_name:
16+
description: 'The operating system'
17+
required: false
18+
type: string
19+
default: 'ubuntu-latest'
20+
workflow_call:
21+
inputs:
22+
tag_version:
23+
description: 'The docker image tag for the firebolt core'
24+
required: false
25+
type: string
26+
python_version:
27+
description: 'Python version'
28+
required: false
29+
type: string
30+
default: '3.10'
31+
os_name:
32+
description: 'Operating system'
33+
required: false
34+
type: string
35+
default: 'ubuntu-latest'
36+
sendSlackNotifications:
37+
description: 'Send Slack notifications on failure'
38+
required: false
39+
type: boolean
40+
default: false
41+
secrets:
42+
SLACK_BOT_TOKEN:
43+
required: false
44+
env:
45+
DEFAULT_IMAGE_TAG: ${{ vars.DEFAULT_CORE_IMAGE_TAG }}
46+
jobs:
47+
run-core-integration-tests:
48+
runs-on: ${{ inputs.os_name }}
49+
env:
50+
DOCKER_COMPOSE_FILE: ${{ github.workspace }}/.github/resources/core/docker-compose.yml
51+
SERVICE_PORT: 3473
52+
SERVICE_URL: http://localhost:3473
53+
MAX_RETRIES: 30
54+
RETRY_INTERVAL: 2
55+
steps:
56+
- name: Check out code
57+
uses: actions/checkout@v4
58+
with:
59+
repository: 'firebolt-db/firebolt-python-sdk'
60+
61+
- name: Set up Python
62+
uses: actions/setup-python@v5
63+
with:
64+
python-version: ${{ inputs.python_version }}
65+
66+
- name: Install dependencies
67+
run: |
68+
python -m pip install --upgrade pip
69+
pip install ".[dev]"
70+
71+
- name: Log in to GitHub Container Registry
72+
uses: docker/login-action@v3
73+
with:
74+
registry: ghcr.io
75+
username: ${{ github.actor }}
76+
password: ${{ secrets.GITHUB_TOKEN }}
77+
78+
- name: Set up Docker Buildx
79+
uses: docker/setup-buildx-action@v3
80+
81+
- name: Cache Docker layers
82+
uses: actions/cache@v3
83+
with:
84+
path: /tmp/.buildx-cache
85+
key: ${{ runner.os }}-buildx-${{ github.sha }}
86+
restore-keys: |
87+
${{ runner.os }}-buildx-
88+
89+
- name: Write certificate and certificate key to file
90+
run: |
91+
mkdir "${{ github.workspace }}/.github/resources/core/certs"
92+
pip install trustme
93+
# Generate a self-signed certificate for localhost
94+
python3 -m trustme -d "${{ github.workspace }}/.github/resources/core/certs/"
95+
96+
- name: Install certs to keystore
97+
run: |
98+
sudo cp ${GITHUB_WORKSPACE}/.github/resources/core/certs/client.pem /usr/local/share/ca-certificates/client.crt
99+
sudo update-ca-certificates
100+
101+
# if no image tag was passed in, then use the image tag from the defaults
102+
- name: Set image tag
103+
id: set-tag
104+
run: |
105+
IMAGE_TAG="${{ inputs.tag_version }}"
106+
if [ -z "$IMAGE_TAG" ]; then
107+
IMAGE_TAG="$DEFAULT_IMAGE_TAG"
108+
fi
109+
echo "tag=$IMAGE_TAG" >> $GITHUB_OUTPUT
110+
111+
- name: Prepare docker-compose.yml
112+
run: |
113+
if [ ! -f "$DOCKER_COMPOSE_FILE" ]; then
114+
echo "Error: Docker compose file not found at $DOCKER_COMPOSE_FILE"
115+
exit 1
116+
fi
117+
sed -i "s|\${IMAGE_TAG}|${{ steps.set-tag.outputs.tag }}|g" "$DOCKER_COMPOSE_FILE"
118+
sed -i "s|\${BASE_DIR}|${{ github.workspace }}|g" "$DOCKER_COMPOSE_FILE"
119+
echo "Docker compose file prepared:"
120+
cat "$DOCKER_COMPOSE_FILE"
121+
122+
- name: Start service container
123+
run: |
124+
docker compose -f "$DOCKER_COMPOSE_FILE" up -d
125+
docker compose -f "$DOCKER_COMPOSE_FILE" ps
126+
127+
- name: Wait for service to be ready
128+
run: |
129+
for i in $(seq 1 $MAX_RETRIES); do
130+
if curl --silent --fail "$SERVICE_URL" --data-binary "SELECT 1" | grep -q "1"; then
131+
echo "Service is up and responding!"
132+
exit 0
133+
fi
134+
echo "Waiting for service... ($i/$MAX_RETRIES)"
135+
sleep $RETRY_INTERVAL
136+
done
137+
echo "Error: Service failed to start within timeout"
138+
docker compose -f "$DOCKER_COMPOSE_FILE" logs
139+
exit 1
140+
141+
- name: Run integration tests HTTP
142+
env:
143+
SERVICE_ID: ${{ secrets.FIREBOLT_CLIENT_ID_STG_NEW_IDN }}
144+
SERVICE_SECRET: ${{ secrets.FIREBOLT_CLIENT_SECRET_STG_NEW_IDN }}
145+
DATABASE_NAME: "firebolt"
146+
ENGINE_NAME: ""
147+
STOPPED_ENGINE_NAME: ""
148+
API_ENDPOINT: ""
149+
ACCOUNT_NAME: ""
150+
CORE_URL: "http://localhost:3473"
151+
run: |
152+
pytest -o log_cli=true -o log_cli_level=WARNING tests/integration -k "core" --alluredir=allure-results/
153+
154+
- name: Run integration tests HTTPS
155+
env:
156+
SERVICE_ID: ${{ secrets.FIREBOLT_CLIENT_ID_STG_NEW_IDN }}
157+
SERVICE_SECRET: ${{ secrets.FIREBOLT_CLIENT_SECRET_STG_NEW_IDN }}
158+
DATABASE_NAME: "firebolt"
159+
ENGINE_NAME: ""
160+
STOPPED_ENGINE_NAME: ""
161+
API_ENDPOINT: ""
162+
ACCOUNT_NAME: ""
163+
CORE_URL: "https://localhost:443"
164+
run: |
165+
pytest -o log_cli=true -o log_cli_level=WARNING tests/integration -k "core" --alluredir=allure-results-https/
166+
167+
- name: Stop container
168+
if: always()
169+
run: |
170+
docker compose -f "$DOCKER_COMPOSE_FILE" down
171+
172+
# Need to pull the pages branch in order to fetch the previous runs
173+
- name: Get Allure history
174+
uses: actions/checkout@v4
175+
if: always()
176+
continue-on-error: true
177+
with:
178+
ref: gh-pages
179+
path: gh-pages
180+
181+
- name: Allure Report
182+
uses: firebolt-db/action-allure-report@v1
183+
if: always()
184+
with:
185+
github-key: ${{ secrets.GITHUB_TOKEN }}
186+
test-type: integration
187+
allure-dir: allure-results
188+
pages-branch: gh-pages
189+
repository-name: python-sdk
190+
191+
- name: Allure Report HTTPS
192+
uses: firebolt-db/action-allure-report@v1
193+
if: always()
194+
with:
195+
github-key: ${{ secrets.GITHUB_TOKEN }}
196+
test-type: integration_https
197+
allure-dir: allure-results-https
198+
pages-branch: gh-pages
199+
repository-name: python-sdk

.github/workflows/integration-tests-v1.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ jobs:
5959
API_ENDPOINT: "api.staging.firebolt.io"
6060
ACCOUNT_NAME: "firebolt"
6161
run: |
62-
pytest --last-failed -n 6 --dist loadgroup --timeout_method "signal" -o log_cli=true -o log_cli_level=INFO tests/integration -k "not V2" --runslow
62+
pytest --last-failed -n 6 --dist loadgroup --timeout_method "signal" -o log_cli=true -o log_cli_level=INFO tests/integration -k "not V2 and not core" --runslow
6363
6464
- name: Save failed tests
6565
id: cache-tests-save

.github/workflows/integration-tests-v2.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ jobs:
5757
API_ENDPOINT: "api.staging.firebolt.io"
5858
ACCOUNT_NAME: ${{ vars.FIREBOLT_ACCOUNT }}
5959
run: |
60-
pytest -n 6 --dist loadgroup --timeout_method "signal" -o log_cli=true -o log_cli_level=WARNING tests/integration -k "not V1" --runslow --alluredir=allure-results
60+
pytest -n 6 --dist loadgroup --timeout_method "signal" -o log_cli=true -o log_cli_level=WARNING tests/integration -k "not V1 and not core" --runslow --alluredir=allure-results
6161
6262
# Need to pull the pages branch in order to fetch the previous runs
6363
- name: Get Allure history

.github/workflows/integration-tests.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,10 @@ jobs:
2323
integration-test-v2:
2424
uses: ./.github/workflows/integration-tests-v2.yml
2525
secrets: inherit
26+
integration-test-core:
27+
uses: ./.github/workflows/integration-tests-core.yml
2628
report-test-results:
27-
needs: [integration-test-v1, integration-test-v2]
29+
needs: [integration-test-v1, integration-test-v2, integration-test-core]
2830
if: always()
2931
runs-on: ubuntu-latest
3032
steps:

0 commit comments

Comments
 (0)