From f3fcf2a76e3aec40f8a4ea3d6bd22c983822f0ec Mon Sep 17 00:00:00 2001 From: Mostafa Date: Tue, 3 Sep 2024 11:05:56 -0500 Subject: [PATCH] Make running integration tests easier --- CONTRIBUTING.md | 22 +++++++++++++++++++ start_test_env.sh | 34 ++++++++++++++++++++++++++++ tests/docker/docker-compose.yml | 1 - tests/docker/run.sh | 39 +++++++++++++++++++++------------ 4 files changed, 81 insertions(+), 15 deletions(-) create mode 100755 start_test_env.sh diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index e0d5d16..22762a6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -6,6 +6,28 @@ Thank you for contributing! Just a few tips here: 2. Run the test suite (e.g. `pgbench`) to make sure everything still works. The tests are in `.circleci/run_tests.sh`. 3. Performance is important, make sure there are no regressions in your branch vs. `main`. +## How to run the integration tests locally and iterate on them +We have integration tests written in Ruby, Python, Go and Rust. +Below are the steps to run them in a developer-friendly way that allows iterating and quick turnaround. +Hear me out, this should be easy, it will involve opening a shell into a container with all the necessary dependancies available for you and you can modify the test code and immediately rerun your test in the interactive shell. + + +Quite simply, make sure you have docker installed and then run +`./start_test_env.sh` + +That is it! + +Within this test environment you can modify the file in your favorite IDE and rerun the tests without having to bootstrap the entire environment again. + +Once the environment is ready, you can run the tests by running +Ruby: `cd /app/tests/ruby && bundle exec ruby .rb --format documentation` +Python: `cd /app && python3 tests/python/tests.py` +Rust: `cd /app/tests/rust && cargo run` +Go: `cd /app/tests/go && /usr/local/go/bin/go test` + +You can also rebuild PgCat directly within the environment and the tests will run against the newly built binary +To rebuild PgCat, just run `cargo build` within the container under `/app` + Happy hacking! ## TODOs diff --git a/start_test_env.sh b/start_test_env.sh new file mode 100755 index 0000000..24a6b3f --- /dev/null +++ b/start_test_env.sh @@ -0,0 +1,34 @@ +GREEN="\033[0;32m" +RED="\033[0;31m" +BLUE="\033[0;34m" +RESET="\033[0m" + + +cd tests/docker/ +docker compose kill main || true +docker compose build main +docker compose down +docker compose up -d +# wait for the container to start +while ! docker compose exec main ls; do + echo "Waiting for test environment to start" + sleep 1 +done +echo "===================================" +docker compose exec -e LOG_LEVEL=error -d main toxiproxy-server +docker compose exec --workdir /app main cargo build +docker compose exec -d --workdir /app main ./target/debug/pgcat ./.circleci/pgcat.toml +docker compose exec --workdir /app/tests/ruby main bundle install +docker compose exec --workdir /app/tests/python main pip3 install -r requirements.txt +echo "Interactive test environment ready" +echo "To run integration tests, you can use the following commands:" +echo -e " ${BLUE}Ruby: ${RED}cd /app/tests/ruby && bundle exec ruby tests.rb --format documentation${RESET}" +echo -e " ${BLUE}Python: ${RED}cd /app && python3 tests/python/tests.py${RESET}" +echo -e " ${BLUE}Rust: ${RED}cd /app/tests/rust && cargo run ${RESET}" +echo -e " ${BLUE}Go: ${RED}cd /app/tests/go && /usr/local/go/bin/go test${RESET}" +echo "the source code for tests are directly linked to the source code in the container so you can modify the code and run the tests again" +echo "You can rebuild PgCat from within the container by running" +echo -e " ${GREEN}cargo build${RESET}" +echo "and then run the tests again" +echo "===================================" +docker compose exec --workdir /app/tests main bash diff --git a/tests/docker/docker-compose.yml b/tests/docker/docker-compose.yml index 28abcf3..0e174d8 100644 --- a/tests/docker/docker-compose.yml +++ b/tests/docker/docker-compose.yml @@ -1,4 +1,3 @@ -version: "3" services: pg1: image: postgres:14 diff --git a/tests/docker/run.sh b/tests/docker/run.sh index 233dd3e..07452cb 100644 --- a/tests/docker/run.sh +++ b/tests/docker/run.sh @@ -8,20 +8,31 @@ rm -rf /app/cov || true # Prepares the interactive test environment # if [ -n "$INTERACTIVE_TEST_ENVIRONMENT" ]; then - cargo build - LOG_LEVEL=error toxiproxy-server & - cd /app/tests/ruby - sudo bundle install - cd /app/tests/python - pip3 install -r tests/python/requirements.txt - echo "Interactive test environment ready" - echo "Run the following commands to start the tests:" - echo " docker compose exec main bash" - echo " cd /app/tests/ruby && sudo bundle exec ruby tests.rb --format documentation # Ruby tests" - echo " cd /app/tests/python && python3 tests.py # Python tests" - echo "You can rebuild PgCat from within the container by running" - echo " cargo build --release in /app" - echo "and then run the tests again" + ports=(5432 7432 8432 9432 10432) + for port in "${ports[@]}"; do + is_it_up=0 + attempts=0 + while [ $is_it_up -eq 0 ]; do + PGPASSWORD=postgres psql -h 127.0.0.1 -p $port -U postgres -c '\q' > /dev/null 2>&1 + if [ $? -eq 0 ]; then + echo "PostgreSQL on port $port is up." + is_it_up=1 + else + attempts=$((attempts+1)) + if [ $attempts -gt 10 ]; then + echo "PostgreSQL on port $port is down, giving up." + exit 1 + fi + echo "PostgreSQL on port $port is down, waiting for it to start." + sleep 1 + fi + done + done + PGPASSWORD=postgres psql -e -h 127.0.0.1 -p 5432 -U postgres -f /app/tests/sharding/query_routing_setup.sql + PGPASSWORD=postgres psql -e -h 127.0.0.1 -p 7432 -U postgres -f /app/tests/sharding/query_routing_setup.sql + PGPASSWORD=postgres psql -e -h 127.0.0.1 -p 8432 -U postgres -f /app/tests/sharding/query_routing_setup.sql + PGPASSWORD=postgres psql -e -h 127.0.0.1 -p 9432 -U postgres -f /app/tests/sharding/query_routing_setup.sql + PGPASSWORD=postgres psql -e -h 127.0.0.1 -p 10432 -U postgres -f /app/tests/sharding/query_routing_setup.sql sleep 100000000000000000 exit 0 fi