Skip to content

Commit 7ef12c2

Browse files
committed
Windows test
1 parent cf8e9db commit 7ef12c2

5 files changed

Lines changed: 139 additions & 1 deletion

File tree

.github/workflows/test.yml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,15 @@ jobs:
7474
with:
7575
python-version: ${{ matrix.python-version }}
7676

77-
- name: Install test dependencies and scikit-learn
77+
- name: Checkout server-api and patch Docker path
78+
if: runner.os == 'Linux'
79+
shell: bash
80+
run: |
81+
git clone --depth 1 https://github.com/openml/server-api.git server-api
82+
sed -i 's|\.\./server-api|./server-api|g' docker-compose.yml
83+
84+
- name: Install test dependencies, scikit-learn, and optional pandas
85+
shell: bash
7886
run: |
7987
python -m pip install --upgrade pip
8088
pip install -e .[test] scikit-learn==${{ matrix.scikit-learn }}

docker-compose.yml

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
services:
2+
database:
3+
image: "openml/test-database:20240105"
4+
container_name: "openml-test-db-ci"
5+
environment:
6+
MYSQL_ROOT_PASSWORD: ok
7+
ports:
8+
- "33060:3306"
9+
healthcheck:
10+
test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"]
11+
start_period: 30s
12+
interval: 5s
13+
retries: 10
14+
15+
# SETUP WORKER
16+
database-setup:
17+
image: mysql
18+
container_name: "openml-test-setup-ci"
19+
volumes:
20+
# You MUST save the update.sh content you shared earlier to this path
21+
- ./docker/update.sh:/database-update.sh
22+
command: /bin/sh -c "/database-update.sh"
23+
depends_on:
24+
database:
25+
condition: service_healthy
26+
27+
php-api:
28+
image: "openml/php-rest-api:v1.2.2"
29+
container_name: "openml-php-api-ci"
30+
ports:
31+
- "9002:80"
32+
depends_on:
33+
database:
34+
condition: service_started
35+
environment:
36+
- DB_HOST_OPENML=database:3306
37+
- DB_HOST_EXPDB=database:3306
38+
- BASE_URL=http://localhost:9002/
39+
- INDEX_ES_DURING_STARTUP=false
40+
41+
# V2 API (PYTHON)
42+
python-api:
43+
container_name: "openml-python-api-ci"
44+
build:
45+
# TODO: replace with image when available
46+
context: ../server-api
47+
dockerfile: docker/python/Dockerfile
48+
ports:
49+
- "9001:8000"
50+
depends_on:
51+
- database
52+
environment:
53+
- DATABASE_URL=mysql://root:ok@database:3306/openml

docker/update.sh

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#/bin/bash
2+
# Change the filepath of openml.file
3+
# from "https://www.openml.org/data/download/1666876/phpFsFYVN"
4+
# to "http://minio:9000/datasets/0000/0001/phpFsFYVN"
5+
mysql -hdatabase -uroot -pok -e 'UPDATE openml.file SET filepath = CONCAT("http://minio:9000/datasets/0000/", LPAD(id, 4, "0"), "/", SUBSTRING_INDEX(filepath, "/", -1)) WHERE extension="arff";'
6+
7+
# Update openml.expdb.dataset with the same url
8+
mysql -hdatabase -uroot -pok -e 'UPDATE openml_expdb.dataset DS, openml.file FL SET DS.url = FL.filepath WHERE DS.did = FL.id;'
9+
10+
11+
12+
13+
14+
# Create the data_feature_description TABLE. TODO: can we make sure this table exists already?
15+
mysql -hdatabase -uroot -pok -Dopenml_expdb -e 'CREATE TABLE IF NOT EXISTS `data_feature_description` (
16+
`did` int unsigned NOT NULL,
17+
`index` int unsigned NOT NULL,
18+
`uploader` mediumint unsigned NOT NULL,
19+
`date` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
20+
`description_type` enum("plain", "ontology") NOT NULL,
21+
`value` varchar(256) NOT NULL,
22+
KEY `did` (`did`,`index`),
23+
CONSTRAINT `data_feature_description_ibfk_1` FOREIGN KEY (`did`, `index`) REFERENCES `data_feature` (`did`, `index`) ON DELETE CASCADE ON UPDATE CASCADE
24+
)'
25+
26+
# SET dataset 1 to active (used in unittests java)
27+
mysql -hdatabase -uroot -pok -Dopenml_expdb -e 'INSERT IGNORE INTO dataset_status VALUES (1, "active", "2024-01-01 00:00:00", 1)'
28+
mysql -hdatabase -uroot -pok -Dopenml_expdb -e 'DELETE FROM dataset_status WHERE did = 2 AND status = "deactivated";'
29+
30+
# Temporary fix in case the database missed the kaggle table. The PHP Rest API expects the table to be there, while indexing.
31+
mysql -hdatabase -uroot -pok -Dopenml_expdb -e 'CREATE TABLE IF NOT EXISTS `kaggle` (`dataset_id` int(11) DEFAULT NULL, `kaggle_link` varchar(500) DEFAULT NULL)'

pytest.ini

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
[pytest]
2+
env =
3+
OPENML_SERVER = http://localhost:9001/api/v2
4+
OPENML_API_KEY = AD000000000000000000000000000000

tests/conftest.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from __future__ import annotations
2525

2626
import multiprocessing
27+
import sys
2728

2829
multiprocessing.set_start_method("spawn", force=True)
2930

@@ -35,6 +36,9 @@
3536
import pytest
3637
import openml_sklearn
3738

39+
import time
40+
import subprocess
41+
import requests
3842
import openml
3943
from openml.testing import TestBase
4044

@@ -296,6 +300,44 @@ def with_test_cache(test_files_directory, request):
296300
if tmp_cache.exists():
297301
shutil.rmtree(tmp_cache)
298302

303+
# This starts the entire stack once for the whole test run
304+
@pytest.fixture(scope="session", autouse=True)
305+
def openml_docker_stack():
306+
# if sys.platform == "win32":
307+
# yield
308+
# return
309+
# 1. Start the containers defined in your final docker-compose.yml
310+
subprocess.run(["docker", "compose", "up", "-d"], check=True)
311+
312+
# 2. Wait for the database setup worker to finish its tasks
313+
# This ensures update.sh has finished before we hit the APIs
314+
subprocess.run(["docker", "wait", "openml-test-setup-ci"], check=True)
315+
316+
# 3. Quick health check: Wait for the Python API to respond on port 9001
317+
timeout = 30
318+
start = time.time()
319+
while time.time() - start < timeout:
320+
try:
321+
if requests.get("http://localhost:9001/api/v2/").status_code == 200:
322+
break
323+
except requests.exceptions.ConnectionError:
324+
time.sleep(1)
325+
326+
yield # Tests run here
327+
328+
# 4. Tear everything down after tests finish to keep the machine clean
329+
subprocess.run(["docker", "compose", "down", "-v"], check=True)
330+
331+
# This resets the database state before every single test to prevent race conditions
332+
@pytest.fixture(scope="function", autouse=True)
333+
def reset_db_state():
334+
# if sys.platform == "win32":
335+
# yield
336+
# return
337+
# Fast restart of the database container to return to the 'baked-in' state
338+
subprocess.run(["docker", "compose", "restart", "database"], check=True)
339+
# Re-run the setup worker to ensure paths are still correct
340+
subprocess.run(["docker", "compose", "up", "database-setup"], check=True)
299341

300342
@pytest.fixture
301343
def static_cache_dir():

0 commit comments

Comments
 (0)