diff --git a/.devcontainer/README.md b/.devcontainer/README.md new file mode 100644 index 00000000000..1169668ec4d --- /dev/null +++ b/.devcontainer/README.md @@ -0,0 +1,97 @@ +# Cloud Controller Development Environment + +This document outlines how to set up and use the development environment for the Cloud Controller. + +## Getting Started + +1. **Prerequisites**: Ensure you have Docker and Visual Studio Code with the "Remote - Containers" extension installed. +2. **Launch the Environment**: + * Open the `cloud_controller_ng` project folder in VS Code. + * When prompted, click **"Reopen in Container"**. This will build the Docker images and start the development container. Also you can use the command palette (`Ctrl+Shift+P` or `Cmd+Shift+P` on macOS) and select **"Dev Containers: Reopen in Container"** or go to the remote explorer and select **"Reopen in Container"**. + * The initial build may take some time as it installs all dependencies. + +## Interacting with the Environment + +Once the container is running, the startup script (`.devcontainer/scripts/codespaces_start.sh`) will automatically: + +* Set up and seed the PostgreSQL and MariaDB databases. +* Configure the Cloud Controller application. +* Start all necessary services (UAA, Minio, Nginx, etc.). + +## VS Code Launch Configurations + +The `.vscode/launch.json` file contains several configurations for running and debugging different components of the Cloud Controller. You can access these from the "Run and Debug" panel in VS Code. + +### Main Application + +* **`[Postgres] CloudController`**: Runs the main Cloud Controller API using PostgreSQL as the database. +* **`[Mariadb] CloudController`**: Runs the main Cloud Controller API using MariaDB as the database. + +> Note only one can be run at a time. Ensure the other is stopped before starting a new one. + +### Workers & Scheduler + +* **`[Postgres/Mariadb] CC Worker`**: Starts the generic background job worker against the respective database. +* **`[Postgres/Mariadb] CC Local Worker`**: Starts the local background job worker against the respective database. +* **`[Postgres/Mariadb] CC Scheduler`**: Starts the clock process for scheduling recurring tasks against the respective database. + +> Note only one can be run at a time either against Postgres or Mysql. Ensure the other is stopped before starting a new one. + +### Testing + +* **`[Postgres/Mariadb] Unittests`**: Runs the complete RSpec test suite against the specified database. + +### Cloud Foundry CLI + +The environment comes pre-installed with the `cf8-cli` and `uaac`. You can interact with the local Cloud Foundry deployment from the VS Code terminal. + +**API Endpoint**: `http://localhost:80` + +**Admin Credentials**: + +* **Username**: `ccadmin` +* **Password**: `secret` + +**Example Login Workflow**: + +1. **Target the API**: + + ```bash + cf api http://localhost:80 --skip-ssl-validation + ``` + +2. **Log In**: + + ```bash + cf auth ccadmin secret + ``` + +### PostgreSQL and MariaDB Access + +You can connect directly to the databases running in the environment from the VS Code terminal. + +#### PostgreSQL + +* **Host**: `localhost` +* **Port**: `5432` +* **User**: `postgres` +* **Password**: `supersecret` + +**Example Connection**: + +```bash +PGPASSWORD=supersecret psql -h localhost -U postgres -d ccdb +``` + +#### MariaDB (MySQL) + +* **Host**: `127.0.0.1` +* **Port**: `3306` +* **User**: `root` +* **Password**: `supersecret` + +**Example Connection**: + +```bash +mysql -h 127.0.0.1 -u root -psupersecret ccdb +``` diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index 4fbbe631148..01df7627c67 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -20,8 +20,7 @@ "nginx" ], "workspaceFolder": "/workspace", - "initializeCommand": ".devcontainer/scripts/codespaces_init.sh", - "onCreateCommand": ".devcontainer/scripts/codespaces_start.sh", + "onCreateCommand": "bash .devcontainer/scripts/startup.sh", "customizations": { // Configure properties specific to VS Code. "vscode": { diff --git a/.devcontainer/docker-compose.override.yml b/.devcontainer/docker-compose.override.yml index a9d2ab587a9..5d718b2ba7f 100644 --- a/.devcontainer/docker-compose.override.yml +++ b/.devcontainer/docker-compose.override.yml @@ -1,4 +1,3 @@ -version: "3.3" services: # Dev Container @@ -8,7 +7,6 @@ services: context: ./ dockerfile: .devcontainer/images/devcontainer/Dockerfile restart: unless-stopped - command: /bin/sh -c "while sleep 1000; do :; done" volumes: - .:/workspace:cached - /var/run/docker.sock:/var/run/docker.sock @@ -17,3 +15,4 @@ services: - SYS_PTRACE security_opt: - seccomp:unconfined + privileged: true diff --git a/.devcontainer/images/bbs/Dockerfile b/.devcontainer/images/bbs/Dockerfile index 41ff1964f07..13116d64edb 100644 --- a/.devcontainer/images/bbs/Dockerfile +++ b/.devcontainer/images/bbs/Dockerfile @@ -1,6 +1,6 @@ FROM golang:1 -RUN apt update && apt install -y jq && git clone --recurse-submodules -b $(curl -s https://api.github.com/repos/cloudfoundry/diego-release/releases/latest | jq -r '.tag_name') https://github.com/cloudfoundry/diego-release && cd ./diego-release/src/code.cloudfoundry.org && \ +RUN apt update && git clone --recurse-submodules -b v2.118.0 https://github.com/cloudfoundry/diego-release && cd ./diego-release/src/code.cloudfoundry.org && \ CG_ENABLED=0 go install code.cloudfoundry.org/locket/cmd/locket && \ CG_ENABLED=0 go install code.cloudfoundry.org/bbs/cmd/bbs VOLUME /bbs diff --git a/.devcontainer/images/devcontainer/Dockerfile b/.devcontainer/images/devcontainer/Dockerfile index 13c83c04fae..00b9c6dbf20 100644 --- a/.devcontainer/images/devcontainer/Dockerfile +++ b/.devcontainer/images/devcontainer/Dockerfile @@ -1,7 +1,129 @@ -FROM mcr.microsoft.com/vscode/devcontainers/ruby:3.2 +FROM mcr.microsoft.com/devcontainers/base:ubuntu-24.04 + + +SHELL ["/bin/bash", "-o", "pipefail", "-c"] + +# Set environment variables for Ruby development +ENV BUNDLE_PATH=/home/vscode/.bundle +ENV GEM_HOME=/home/vscode/.gem +ENV GEM_PATH=/home/vscode/.gem +ENV RAILS_ENV=development +ENV RACK_ENV=development + +# Install system dependencies for Ruby development +RUN wget -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | gpg --dearmor -o /usr/share/keyrings/cli.cloudfoundry.org.gpg && \ + echo "deb [signed-by=/usr/share/keyrings/cli.cloudfoundry.org.gpg] https://packages.cloudfoundry.org/debian stable main" > /etc/apt/sources.list.d/cloudfoundry-cli.list && \ + apt-get update && \ + apt-get install -y \ + # CF CLI + cf8-cli \ + # Build tools + build-essential \ + autoconf \ + bison \ + patch \ + # Ruby dependencies + libssl-dev \ + libreadline-dev \ + zlib1g-dev \ + libncurses5-dev \ + libffi-dev \ + libgdbm-dev \ + libyaml-dev \ + libsqlite3-dev \ + sqlite3 \ + libgmp-dev \ + libgdbm6 \ + libdb-dev \ + uuid-dev \ + # Database clients + postgresql-client \ + postgresql-client-common \ + mysql-client \ + redis-tools \ + # Database development headers + libpq-dev \ + default-libmysqlclient-dev \ + # Development tools + curl \ + wget \ + git \ + vim \ + nano \ + htop \ + tree \ + jq \ + unzip \ + zip \ + # Network tools + netcat-openbsd \ + # XML/HTML processing + libxml2-dev \ + libxslt1-dev \ + # GPG for RVM + gnupg2 \ + # Additional utilities + tmux \ + screen \ + less \ + man-db \ + && rm -rf /var/lib/apt/lists/* + +# Install yq v4 for the correct architecture +RUN YQ_ARCH=$(uname -m) && \ + case $YQ_ARCH in \ + x86_64) YQ_ARCH="amd64";; \ + aarch64) YQ_ARCH="arm64";; \ + esac && \ + wget "https://github.com/mikefarah/yq/releases/download/v4.47.1/yq_linux_${YQ_ARCH}" -O /usr/local/bin/yq && \ + chmod +x /usr/local/bin/yq + -COPY --from=docker:dind /usr/local/bin/docker /usr/local/bin/ -COPY .devcontainer/images/devcontainer/setup.sh /tmp/setup.sh -COPY .ruby-version /tmp/.ruby-version USER vscode -RUN /tmp/setup.sh && sudo rm /tmp/setup.sh /tmp/.ruby-version + +# Create necessary directories and set permissions +RUN mkdir -p $BUNDLE_PATH $GEM_HOME && chown -R vscode:vscode $BUNDLE_PATH $GEM_HOME + +# Install GPG keys for RVM +RUN gpg2 --keyserver keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB + +# Install RVM +RUN curl -sSL https://get.rvm.io | bash -s stable --path /home/vscode/.rvm + +# Copy Ruby version file for reference +COPY .ruby-version /tmp/ruby-version + +# Install Ruby using RVM with binary packages when available, fallback to parallel source compilation +RUN /bin/bash -l -c "source /home/vscode/.rvm/scripts/rvm && \ + export rvm_make_opts=\"-j$(nproc)\" && \ + export RUBY_CONFIGURE_OPTS=\"--disable-install-doc\" && \ + rvm install $(cat /tmp/ruby-version) && \ + rvm use $(cat /tmp/ruby-version) --default && \ + gem install bundler" + +# Configure Bundler and install cf-uaac as vscode user +RUN /bin/bash -l -c "source /home/vscode/.rvm/scripts/rvm && \ + bundle config set --global path \"$BUNDLE_PATH\" && \ + bundle config set --global jobs $(nproc) && \ + bundle config set --global specific_platform true && \ + gem install cf-uaac" + +# Configure Git +RUN git config --global core.fileMode false + +# Source RVM and configure shell +RUN echo 'export BUNDLE_PATH="$BUNDLE_PATH"' >> /home/vscode/.bashrc \ + && echo 'export GEM_HOME="$GEM_HOME"' >> /home/vscode/.bashrc \ + && echo 'export GEM_PATH="$GEM_PATH"' >> /home/vscode/.bashrc \ + && echo 'source /home/vscode/.rvm/scripts/rvm' >> /home/vscode/.bashrc + +# Configure Git (useful defaults) +RUN git config --global init.defaultBranch main \ + && git config --global pull.rebase false \ + && git config --global core.autocrlf input + +# Set working directory +WORKDIR /workspace +USER root +# Sleep forever to keep the container running +CMD ["tail", "-f", "/dev/null"] diff --git a/.devcontainer/images/devcontainer/setup.sh b/.devcontainer/images/devcontainer/setup.sh deleted file mode 100755 index 64ac33c39ba..00000000000 --- a/.devcontainer/images/devcontainer/setup.sh +++ /dev/null @@ -1,59 +0,0 @@ -#!/bin/bash -set -Eeuo pipefail -# shellcheck disable=SC2064 -trap "pkill -P $$" EXIT - -setupAptPackages () { - # CF CLI is not available for aarch64 :( - if [[ $(uname -m) == aarch64 ]]; then - PACKAGES="postgresql-client postgresql-client-common mariadb-client ruby-dev" - else - PACKAGES="cf8-cli postgresql-client postgresql-client-common mariadb-client ruby-dev" - fi - - wget -q -O - https://packages.cloudfoundry.org/debian/cli.cloudfoundry.org.key | sudo apt-key add - - echo "deb https://packages.cloudfoundry.org/debian stable main" | sudo tee /etc/apt/sources.list.d/cloudfoundry-cli.list - sudo apt-get update - export DEBIAN_FRONTEND="noninteractive" && echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections - sudo apt-get install -o Dpkg::Options::="--force-overwrite" $PACKAGES -y -} - -setupRuby () { - rbenv install $(cat /tmp/.ruby-version) - rbenv global $(cat /tmp/.ruby-version) -} - -setupRubyGems () { - gem install cf-uaac -} - -setupCredhubCli () { - set -x - wget "$(curl -s https://api.github.com/repos/cloudfoundry/credhub-cli/releases/latest | - jq -r '.assets[] | select(.name|match("credhub-linux.*")) | .browser_download_url')" -O /tmp/credhub.tar.gz - cd /tmp - sudo tar -xzf /tmp/credhub.tar.gz && sudo rm -f /tmp/credhub.tar.gz && sudo mv /tmp/credhub /usr/bin -} - -setupYqCli () { - sudo wget "$(curl -s https://api.github.com/repos/mikefarah/yq/releases/latest | - jq -r '.assets[] | select(.name|match("linux_amd64$")) | .browser_download_url')" -O /usr/bin/yq - sudo chmod +x /usr/bin/yq -} - -echo """ -export COMPOSE_DOCKER_CLI_BUILD=1 -export DOCKER_BUILDKIT=1 -""" > ~/.bashrc - -setupAptPackages -setupRuby -setupRubyGems -setupCredhubCli -setupYqCli - -# Setup User Permissions -sudo groupadd docker -sudo usermod -aG docker "vscode" - -trap "" EXIT \ No newline at end of file diff --git a/.devcontainer/scripts/codespaces_init.sh b/.devcontainer/scripts/codespaces_init.sh deleted file mode 100755 index c9aa8f38683..00000000000 --- a/.devcontainer/scripts/codespaces_init.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/bin/bash -set -Eeuxo pipefail -set -o allexport -# shellcheck disable=SC2064 -trap "pkill -P $$" EXIT - -# Setup volume mounts -mkdir -p tmp - -# Speed up docker builds by prebuilding with buildx -docker-compose pull || tee tmp/fail & -docker buildx bake -f docker-compose.yml -f .devcontainer/docker-compose.override.yml || tee tmp/fail & - -wait $(jobs -p) -test -f tmp/fail && rm tmp/fail && exit 1 - -trap "" EXIT \ No newline at end of file diff --git a/.devcontainer/scripts/codespaces_start.sh b/.devcontainer/scripts/codespaces_start.sh deleted file mode 100755 index 6934883c137..00000000000 --- a/.devcontainer/scripts/codespaces_start.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash -set -Eeuxo pipefail -# shellcheck disable=SC2064 -trap "pkill -P $$" EXIT - -# Setup IDEs -./.devcontainer/scripts/setupIDEs.sh - -# Setup DBs and CC Config File -./.devcontainer/scripts/setupDevelopmentEnvironment.sh - -trap "" EXIT \ No newline at end of file diff --git a/.devcontainer/scripts/setupIDEs.sh b/.devcontainer/scripts/setupIDEs.sh deleted file mode 100755 index 19b9a2391b8..00000000000 --- a/.devcontainer/scripts/setupIDEs.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash -set -Eeuo pipefail -# shellcheck disable=SC2064 -trap "pkill -P $$" EXIT - -# Setup IDEs -cp -a -f .devcontainer/configs/vscode/.vscode . -cp -a -f .devcontainer/configs/intellij/.idea . - -trap "" EXIT \ No newline at end of file diff --git a/.devcontainer/scripts/setupDevelopmentEnvironment.sh b/.devcontainer/scripts/startup.sh old mode 100755 new mode 100644 similarity index 78% rename from .devcontainer/scripts/setupDevelopmentEnvironment.sh rename to .devcontainer/scripts/startup.sh index d4522b8ec5e..def264b1606 --- a/.devcontainer/scripts/setupDevelopmentEnvironment.sh +++ b/.devcontainer/scripts/startup.sh @@ -1,7 +1,9 @@ #!/bin/bash -set -Eeuo pipefail -# shellcheck disable=SC2064 -trap "pkill -P $$" EXIT +set -Eeuxo pipefail + +# Setup IDEs +cp -a -f .devcontainer/configs/vscode/.vscode . +cp -a -f .devcontainer/configs/intellij/.idea . # Database Information POSTGRES_CONNECTION_PREFIX="postgres://postgres:supersecret@localhost:5432" @@ -10,39 +12,49 @@ MYSQL_CONNECTION_PREFIX="mysql2://root:supersecret@127.0.0.1:3306" SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd ) setupPostgres () { - export DB="postgres" + echo "Waiting for postgres..." + while ! pg_isready -h localhost -p 5432 -q -U postgres; do + sleep 1 + done + echo "Postgres is up." + # Parallel Test DBs - export POSTGRES_CONNECTION_PREFIX - bundle exec rake db:pick db:parallel:recreate + export PARALLEL_TEST_PROCESSORS=`ruby -e 'require "etc"; puts (Etc.nprocessors * (ENV["PARALLEL_TEST_PROCESSORS_MULTIPLE"] || 0.8).to_f).ceil'` + DB="postgres" POSTGRES_CONNECTION_PREFIX="postgres://postgres:supersecret@localhost:5432" bundle exec rake db:pick db:parallel:recreate # Sequential Test DBs export PGPASSWORD=supersecret psql -U postgres -h localhost -tc "SELECT 1 FROM pg_database WHERE datname = 'cc_test'" | grep -q 1 || psql -U postgres -h localhost -c "CREATE DATABASE cc_test" psql -U postgres -h localhost -tc "SELECT 1 FROM pg_database WHERE datname = 'diego'" | grep -q 1 || psql -U postgres -h localhost -c "CREATE DATABASE diego" psql -U postgres -h localhost -tc "SELECT 1 FROM pg_database WHERE datname = 'locket'" | grep -q 1 || psql -U postgres -h localhost -c "CREATE DATABASE locket" # Main DB - export DB_CONNECTION_STRING="${POSTGRES_CONNECTION_PREFIX}/ccdb" - bundle exec rake db:recreate db:migrate db:seed + DB="postgres" DB_CONNECTION_STRING="postgres://postgres:supersecret@localhost:5432/ccdb" bundle exec rake db:recreate db:migrate db:seed } setupMariadb () { - export DB="mysql" + echo "Waiting for mysql..." + while ! mysqladmin ping -h 127.0.0.1 -u root -psupersecret --silent; do + sleep 1 + done + echo "MySQL is up." + # Parallel Test DBs - export MYSQL_CONNECTION_PREFIX - bundle exec rake db:pick db:parallel:recreate + export PARALLEL_TEST_PROCESSORS=`ruby -e 'require "etc"; puts (Etc.nprocessors * (ENV["PARALLEL_TEST_PROCESSORS_MULTIPLE"] || 0.8).to_f).ceil'` + DB="mysql" MYSQL_CONNECTION_PREFIX="mysql2://root:supersecret@127.0.0.1:3306" bundle exec rake db:pick db:parallel:recreate # Sequential Test DBs mysql -h 127.0.0.1 -u root -psupersecret -e "CREATE DATABASE IF NOT EXISTS cc_test; CREATE DATABASE IF NOT EXISTS diego; CREATE DATABASE IF NOT EXISTS locket;" # Main DB - export DB_CONNECTION_STRING="${MYSQL_CONNECTION_PREFIX}/ccdb" - bundle exec rake db:recreate db:migrate db:seed + DB="mysql" DB_CONNECTION_STRING="mysql2://root:supersecret@127.0.0.1:3306/ccdb" bundle exec rake db:recreate db:migrate db:seed } # Install packages bundle config set --local with 'debug' -bundle install +bundle install -j"$(nproc)" # Setup Containers -setupPostgres || tee tmp/fail & -setupMariadb || tee tmp/fail & +setupPostgres & +POSTGRES_PID=$! +setupMariadb & +MARIADB_PID=$! # CC config mkdir -p tmp @@ -107,9 +119,5 @@ yq -i e '.diego.bbs.ca_file="spec/fixtures/certs/bbs_ca.crt"' tmp/cloud_controll yq -i e '.packages.max_package_size=2147483648' tmp/cloud_controller.yml -# Wait for background jobs and exit 1 if any error happened -# shellcheck disable=SC2046 -wait $(jobs -p) -test -f tmp/fail && rm tmp/fail && exit 1 - -trap "" EXIT \ No newline at end of file +wait $POSTGRES_PID +wait $MARIADB_PID diff --git a/.github/workflows/unit_tests.yml b/.github/workflows/unit_tests.yml index ba493331473..046b5b91b66 100644 --- a/.github/workflows/unit_tests.yml +++ b/.github/workflows/unit_tests.yml @@ -54,12 +54,24 @@ jobs: --health-interval 10s --health-timeout 5s --health-retries 5 + --tmpfs /var/lib/postgresql/data + --shm-size=256m ports: - 5432:5432 steps: - uses: hmarr/debug-action@v3 - uses: actions/checkout@v4 - uses: ./.github/workflows/composite/setup + - name: Configure PostgreSQL for performance + run: | + sudo apt-get update && sudo apt-get install -y postgresql-client + PGPASSWORD=rootpassword psql -h localhost -U postgres -c "ALTER SYSTEM SET fsync = off;" + PGPASSWORD=rootpassword psql -h localhost -U postgres -c "ALTER SYSTEM SET synchronous_commit = off;" + PGPASSWORD=rootpassword psql -h localhost -U postgres -c "ALTER SYSTEM SET full_page_writes = off;" + PGPASSWORD=rootpassword psql -h localhost -U postgres -c "ALTER SYSTEM SET checkpoint_completion_target = 0.9;" + PGPASSWORD=rootpassword psql -h localhost -U postgres -c "ALTER SYSTEM SET wal_buffers = '16MB';" + PGPASSWORD=rootpassword psql -h localhost -U postgres -c "ALTER SYSTEM SET shared_buffers = '256MB';" + PGPASSWORD=rootpassword psql -h localhost -U postgres -c "SELECT pg_reload_conf();" - name: Run tests run: DB=postgres POSTGRES_CONNECTION_PREFIX="postgres://postgres:rootpassword@localhost:5432" bundle exec rake spec - uses: ravsamhq/notify-slack-action@v2 @@ -83,13 +95,24 @@ jobs: env: MYSQL_DATABASE: cc_test MYSQL_ROOT_PASSWORD: password - options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + options: >- + --health-cmd="mysqladmin ping" + --health-interval=10s + --health-timeout=5s + --health-retries=3 + --tmpfs /var/lib/mysql + --tmpfs /tmp ports: - 3306:3306 steps: - uses: hmarr/debug-action@v3 - uses: actions/checkout@v4 - uses: ./.github/workflows/composite/setup + - name: Configure MySQL for performance + run: | + sudo apt-get update && sudo apt-get install -y mysql-client + mysql -h 127.0.0.1 -u root -ppassword -e "SET GLOBAL innodb_flush_log_at_trx_commit = 0;" + mysql -h 127.0.0.1 -u root -ppassword -e "SET GLOBAL innodb_buffer_pool_size = 268435456;" - name: Run tests run: DB=mysql MYSQL_CONNECTION_PREFIX="mysql2://root:password@127.0.0.1:3306" bundle exec rake spec - uses: ravsamhq/notify-slack-action@v2 @@ -98,4 +121,4 @@ jobs: status: ${{ job.status }} notify_when: 'failure' # default is 'success,failure,warnings' env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} # required \ No newline at end of file + SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} # required diff --git a/.github/workflows/unit_tests_backwards_compatibility.yml b/.github/workflows/unit_tests_backwards_compatibility.yml index 61840c56837..1083443a725 100644 --- a/.github/workflows/unit_tests_backwards_compatibility.yml +++ b/.github/workflows/unit_tests_backwards_compatibility.yml @@ -4,7 +4,6 @@ concurrency: cancel-in-progress: true on: workflow_dispatch: - description: "This action tests backwards compatibility when db migrations are introduced. It tests database schema at new code(old_cc_ref) with unittests running old code(new_cc_ref) " inputs: old_cc_ref: description: 'Old Version of CC_NG that the backwards compatibility should be checked against' @@ -44,6 +43,8 @@ jobs: --health-interval 10s --health-timeout 5s --health-retries 5 + --tmpfs /var/lib/postgresql/data + --shm-size=256m ports: - 5432:5432 steps: @@ -63,6 +64,16 @@ jobs: )}} - name: Setup Environment uses: ./.github/workflows/composite/setup + - name: Configure PostgreSQL for performance + run: | + sudo apt-get update && sudo apt-get install -y postgresql-client + PGPASSWORD=rootpassword psql -h localhost -U postgres -c "ALTER SYSTEM SET fsync = off;" + PGPASSWORD=rootpassword psql -h localhost -U postgres -c "ALTER SYSTEM SET synchronous_commit = off;" + PGPASSWORD=rootpassword psql -h localhost -U postgres -c "ALTER SYSTEM SET full_page_writes = off;" + PGPASSWORD=rootpassword psql -h localhost -U postgres -c "ALTER SYSTEM SET checkpoint_completion_target = 0.9;" + PGPASSWORD=rootpassword psql -h localhost -U postgres -c "ALTER SYSTEM SET wal_buffers = '16MB';" + PGPASSWORD=rootpassword psql -h localhost -U postgres -c "ALTER SYSTEM SET shared_buffers = '256MB';" + PGPASSWORD=rootpassword psql -h localhost -U postgres -c "SELECT pg_reload_conf();" - name: Migrate Database run: DB=postgres POSTGRES_CONNECTION_PREFIX="postgres://postgres:rootpassword@localhost:5432" bundle exec rake db:parallel:recreate db:parallel:migrate - name: Checkout code to run the unit tests with @@ -92,7 +103,13 @@ jobs: env: MYSQL_DATABASE: cc_test MYSQL_ROOT_PASSWORD: password - options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3 + options: >- + --health-cmd="mysqladmin ping" + --health-interval=10s + --health-timeout=5s + --health-retries=3 + --tmpfs /var/lib/mysql + --tmpfs /tmp ports: - 3306:3306 steps: @@ -112,6 +129,11 @@ jobs: )}} - name: Setup Environment uses: ./.github/workflows/composite/setup + - name: Configure MySQL for performance + run: | + sudo apt-get update && sudo apt-get install -y mysql-client + mysql -h 127.0.0.1 -u root -ppassword -e "SET GLOBAL innodb_flush_log_at_trx_commit = 0;" + mysql -h 127.0.0.1 -u root -ppassword -e "SET GLOBAL innodb_buffer_pool_size = 268435456;" - name: Migrate Database run: DB=mysql MYSQL_CONNECTION_PREFIX="mysql2://root:password@127.0.0.1:3306" bundle exec rake db:parallel:recreate db:parallel:migrate - name: Checkout code to run the unit tests with @@ -125,4 +147,4 @@ jobs: - name: Setup Environment uses: ./.github/workflows/composite/setup - name: Run tests - run: DB=mysql MYSQL_CONNECTION_PREFIX="mysql2://root:password@127.0.0.1:3306" bundle exec rake spec:without_migrate \ No newline at end of file + run: DB=mysql MYSQL_CONNECTION_PREFIX="mysql2://root:password@127.0.0.1:3306" bundle exec rake spec:without_migrate diff --git a/devenv.sh b/devenv.sh index c9ea501bcb5..6a7d17af681 100755 --- a/devenv.sh +++ b/devenv.sh @@ -18,27 +18,27 @@ help_command() { # Create a clean development environment create_command(){ - docker-compose -p "" down + docker compose -p "" down docker buildx bake -f docker-compose.yml & - docker-compose -p "" pull & + docker compose -p "" pull & wait $(jobs -p) - docker-compose -p "" up -d --build - ./.devcontainer/scripts/setupDevelopmentEnvironment.sh + docker compose -p "" up -d --build + ./.devcontainer/scripts/startup.sh } # Start containers start_command(){ - docker-compose -p "" start + docker compose -p "" start } # Stop containers stop_command(){ - docker-compose -p "" stop + docker compose -p "" stop } # Remove containers destroy_command(){ - docker-compose -p "" down + docker compose -p "" down } # Call Setup IDEs Script @@ -72,7 +72,7 @@ fi # Check Prerequisites export should_exit=0 # Check Path Exists -for p in docker docker-compose ruby bundle mysql psql yq; do +for p in docker ruby bundle mysql psql yq; do if ! command -v "${p}" >/dev/null 2>&1; then echo "Error: Dependency \"$p\" is not installed" && export should_exit=1 fi diff --git a/docker-compose.yml b/docker-compose.yml index 3e13466f356..5c41b980614 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,4 +1,3 @@ -version: "3.3" services: # Postgres @@ -7,10 +6,27 @@ services: image: postgres:16-alpine environment: POSTGRES_PASSWORD: supersecret - command: # logs every statement sent to the server. Slow, but helpful. Fills up disk Quickly ! + command: - "postgres" - "-c" + - "fsync=off" + - "-c" + - "synchronous_commit=off" + - "-c" + - "full_page_writes=off" + - "-c" - "log_statement=all" + - "-c" + - "checkpoint_segments=32" + - "-c" + - "checkpoint_completion_target=0.9" + - "-c" + - "wal_buffers=16MB" + - "-c" + - "shared_buffers=256MB" + tmpfs: + - /var/lib/postgresql/data + shm_size: 256m ports: - "127.0.0.1:5432:5432" networks: @@ -28,6 +44,18 @@ services: image: mysql:8.2 environment: MYSQL_ROOT_PASSWORD: supersecret + command: + - "--innodb-flush-method=nosync" + - "--innodb-flush-log-at-trx-commit=0" + - "--innodb-doublewrite=0" + - "--innodb-buffer-pool-size=256M" + - "--innodb-log-buffer-size=16M" + - "--innodb-log-file-size=64M" + - "--skip-innodb-checksums" + - "--skip-sync-frm" + tmpfs: + - /var/lib/mysql + - /tmp ports: - "127.0.0.1:3306:3306" healthcheck: @@ -100,13 +128,7 @@ services: environment: MC_HOST_custom: http://localhost:9001 healthcheck: - test: - [ - "CMD", - "mc", - "ready", - "custom" - ] + test: [ "CMD", "mc", "ready", "custom" ] interval: 30s timeout: 20s retries: 3 @@ -124,13 +146,7 @@ services: - "127.0.0.1:9292:9292" - "127.0.0.1:9393:80" healthcheck: - test: - [ - "CMD", - "curl", - "-f", - "http://localhost:9292/v2/catalog" - ] + test: [ "CMD", "curl", "-f", "http://localhost:9292/v2/catalog" ] interval: 30s timeout: 20s retries: 3 @@ -152,12 +168,10 @@ services: - cc-net volumes: - .devcontainer/images/nginx/conf:/usr/local/nginx/conf:ro - - ./tmp:/tmp cap_add: - NET_BIND_SERVICE extra_hosts: - "host.docker.internal:host-gateway" restart: unless-stopped - networks: cc-net: diff --git a/lib/tasks/spec.rake b/lib/tasks/spec.rake index 06b8e5923c3..16426c2908a 100644 --- a/lib/tasks/spec.rake +++ b/lib/tasks/spec.rake @@ -2,7 +2,9 @@ desc 'Runs all specs' task spec: 'spec:all' namespace :spec do - task all: ['db:pick', 'db:parallel:recreate'] do + task all: ['db:pick'] do + ENV['PARALLEL_TEST_PROCESSORS'] = (Etc.nprocessors * (ENV['PARALLEL_TEST_PROCESSORS_MULTIPLE'] || 0.8).to_f).ceil.to_s + Rake::Task['db:parallel:recreate'].invoke if ARGV[1] run_specs(ARGV[1]) else @@ -44,6 +46,7 @@ namespace :spec do def run_specs_parallel(path, env_vars='') command = <<~CMD #{env_vars} bundle exec parallel_rspec \ + -n `ruby -e 'require "etc"; puts (Etc.nprocessors * (ENV["PARALLEL_TEST_PROCESSORS_MULTIPLE"] || 0.8).to_f).ceil'` \ --test-options '--order rand' \ --single spec/integration/ \ --single spec/acceptance/ \