diff --git a/.github/workflows/build-cpack-packages.yml b/.github/workflows/build-cpack-packages.yml new file mode 100644 index 00000000..2722b472 --- /dev/null +++ b/.github/workflows/build-cpack-packages.yml @@ -0,0 +1,256 @@ +name: Build CPack Packages + +on: + workflow_call: + inputs: + build-type: + description: CMake build type used for packaging + type: string + default: Release + extra-cmake-flags: + description: Additional flags passed to CMake configure step + type: string + default: "" + save-artifacts: + description: Save built packages as artifacts + type: boolean + default: false + secrets: {} + workflow_dispatch: + inputs: + build-type: + description: CMake build type used for packaging + type: string + default: Release + extra-cmake-flags: + description: Additional flags passed to CMake configure step + type: string + default: "" + save-artifacts: + description: Save built packages as artifacts + type: boolean + default: false + secrets: {} + +env: + CARGO_TERM_COLOR: always + CMAKE_BUILD_TYPE: ${{ inputs.build-type }} + CMAKE_FLAGS: ${{ inputs.extra-cmake-flags }} + +jobs: + linux: + name: Linux packages + runs-on: ubuntu-22.04 + steps: + - uses: actions/checkout@v4 + + - name: Build packages + run: make build-package + + - name: Install driver dev package + run: make -C packaging/smoke-test-app install-driver-dev + + - name: Install driver package + run: gmake -C packaging/smoke-test-app install-driver + + - name: Build smoke-test application package + run: make -C packaging/smoke-test-app build-package + + - name: Install smoke-test application package + run: make -C packaging/smoke-test-app install-app + + - name: Test smoke-test application + run: make -C packaging/smoke-test-app test-app-package + + - name: Collect artifacts + run: | + set -euo pipefail + shopt -s nullglob + mkdir -p artifacts/linux + for file in build/*.deb build/*.rpm; do + cp "$file" artifacts/linux/ + done + + - uses: actions/upload-artifact@v4 + if: inputs.save-artifacts + with: + name: linux-packages + path: artifacts/linux + retention-days: 7 + + macos: + name: macOS packages + runs-on: macos-15-intel + steps: + - uses: actions/checkout@v4 + + - name: Install GNU make + run: brew install make + + - name: Build packages + run: gmake build-package + + - name: Install driver dev package + run: gmake -C packaging/smoke-test-app install-driver-dev + + - name: Install driver package + run: gmake -C packaging/smoke-test-app install-driver + + - name: Build smoke-test application package + run: gmake -C packaging/smoke-test-app build-package + + - name: Install smoke-test application package + run: gmake -C packaging/smoke-test-app install-app + + - name: Test smoke-test application + run: gmake -C packaging/smoke-test-app test-app-package + + - name: Collect artifacts + run: | + set -euo pipefail + shopt -s nullglob + mkdir -p artifacts/macos + for file in build/*.pkg build/*.dmg \ + packaging/smoke-test-app/build/*.pkg \ + packaging/smoke-test-app/build/*.dmg; do + cp "$file" artifacts/macos/ + done + + - uses: actions/upload-artifact@v4 + if: inputs.save-artifacts + with: + name: macos-packages + path: artifacts/macos + retention-days: 7 + + windows: + name: Windows packages + runs-on: windows-2022 + steps: + - uses: actions/checkout@v4 + + - name: Install Docker + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + $dockerService = Get-Service -Name docker -ErrorAction SilentlyContinue + if (-not $dockerService) { + Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force + Install-Module -Name DockerMsftProvider -Repository PSGallery -Force + Install-Package -Name docker -ProviderName DockerMsftProvider -Force + } + try { + Start-Service docker -ErrorAction Stop + } catch { + Write-Warning "Docker service failed to start: $($_.Exception.Message)" + } + + - name: Add WiX to PATH + shell: pwsh + run: | + $wixPath = "C:\\Program Files (x86)\\WiX Toolset v3.11\\bin" + if (Test-Path $wixPath) { Add-Content -Path $env:GITHUB_PATH -Value $wixPath } + + - name: Build packages + run: make build-package + + - name: Install driver packages (MSI) + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + $packages = Get-ChildItem build -Filter *.msi + if (-not $packages) { + throw "No driver MSI packages produced" + } + Write-Host "Installing $($packages.Count) MSI package(s):" + foreach ($pkg in $packages) { + Write-Host " - $($pkg.Name)" + } + # Install all packages (Windows WIX creates a single MSI with components) + foreach ($pkg in $packages) { + $process = Start-Process msiexec.exe -ArgumentList "/i `"$($pkg.FullName)`" /qn /norestart" -Wait -PassThru + if ($process.ExitCode -ne 0) { + throw "Failed to install driver package $($pkg.Name): exit code $($process.ExitCode)" + } + } + + - name: Verify dev package installation + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + $installPath = "C:\Program Files\ScyllaDB\Scylla CPP Driver" + # Verify headers are installed + $headerPath = Join-Path $installPath "include\cassandra.h" + if (-not (Test-Path $headerPath)) { + throw "ERROR: cassandra.h header not found at $headerPath - dev package may not be installed" + } + # Verify pkg-config file is installed + $pkgConfigPath = Join-Path $installPath "lib\pkgconfig\scylla-cpp-driver.pc" + if (-not (Test-Path $pkgConfigPath)) { + throw "ERROR: scylla-cpp-driver.pc not found at $pkgConfigPath - dev package may not be installed" + } + Write-Host "Dev package verification successful" + + - name: Build smoke-test application package + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + $env:PKG_CONFIG_PATH = "C:/Program Files/ScyllaDB/Scylla CPP Driver/lib/pkgconfig" + cmake -S packaging/smoke-test-app -B packaging/smoke-test-app/build -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=${{ inputs.build-type }} + cmake --build packaging/smoke-test-app/build --config ${{ inputs.build-type }} + Push-Location packaging/smoke-test-app/build + cpack -G WIX -C ${{ inputs.build-type }} + Pop-Location + + - name: Install smoke-test application package (MSI) + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + $packages = Get-ChildItem packaging/smoke-test-app/build -Filter *.msi + if (-not $packages) { + throw "No smoke-test MSI packages produced" + } + foreach ($pkg in $packages) { + $process = Start-Process msiexec.exe -ArgumentList "/i `"$($pkg.FullName)`" /qn /norestart" -Wait -PassThru + if ($process.ExitCode -ne 0) { + throw "Failed to install smoke-test package $($pkg.Name): exit code $($process.ExitCode)" + } + } + + - name: Run smoke-test application against local Scylla + shell: pwsh + run: | + $ErrorActionPreference = 'Stop' + $composeFile = "tests/examples_cluster/docker-compose.yml" + function Cleanup { + docker compose -f $composeFile down --remove-orphans | Out-Null + } + try { + $dockerService = Get-Service -Name docker -ErrorAction SilentlyContinue + if ($dockerService -and $dockerService.Status -ne 'Running') { + Start-Service docker + } + docker compose -f $composeFile up -d --wait + $smokePath = "C:\Program Files\ScyllaDB\Scylla CPP Driver Smoke Test\bin\scylla-cpp-driver-smoke-test.exe" + if (-not (Test-Path $smokePath)) { + throw "Smoke-test binary not found at $smokePath" + } + & $smokePath 172.43.0.2 + } finally { + Cleanup + } + + - name: Collect artifacts + if: inputs.save-artifacts + shell: pwsh + run: | + New-Item -ItemType Directory -Path artifacts\windows -Force | Out-Null + Get-ChildItem build -Filter *.msi | Copy-Item -Destination artifacts\windows + Get-ChildItem packaging/smoke-test-app/build -Filter *.msi | Copy-Item -Destination artifacts\windows + + - uses: actions/upload-artifact@v4 + if: inputs.save-artifacts + with: + name: windows-packages + path: artifacts/windows + retention-days: 7 diff --git a/.github/workflows/pkg.yml b/.github/workflows/pkg.yml index 4dd3dca5..e098c582 100644 --- a/.github/workflows/pkg.yml +++ b/.github/workflows/pkg.yml @@ -2,66 +2,29 @@ name: Build packages on: push: + paths-ignore: + - "docs/**" + - ".github/workflows/docs-**" + - ".github/workflows/build-lint-and-test.yml" + - "examples/**" + - "*.md" branches: [ master ] pull_request: + paths-ignore: + - "docs/**" + - ".github/workflows/docs-**" + - ".github/workflows/build-lint-and-test.yml" + - "examples/**" + - "*.md" branches: [ master ] env: CARGO_TERM_COLORS: always jobs: - build-rpm-pkgs: - name: Build rpm packages - runs-on: ubuntu-22.04 - container: - image: fedora:latest - # Required by `mock`: - ### INFO: It seems that you run Mock in a Docker container. - ### Mock though uses container tooling itself (namely Podman) for downloading bootstrap image. - ### This might require you to run Mock in 'docker run --privileged'. - options: --privileged - # It does not seem to be necessary (CI run without it was successful). - # However, without it, there appear some errors during `mock` execution. - # I've found the solution to these errors here: https://github.com/containers/buildah/issues/3666. - # They are related to podman, which is used by `mock` under the hood. - volumes: - - /var/lib/containers:/var/lib/containers - - strategy: - matrix: - dist-version: [rocky-9-x86_64, fedora-41-x86_64, fedora-42-x86_64] - fail-fast: false - - steps: - # See: https://github.com/actions/checkout/issues/363 - # An issue related to GH actions containers - - name: Install git and update safe directory - run: | - dnf update -y - dnf install -y git - git config --global --add safe.directory "$GITHUB_WORKSPACE" - - - name: Checkout - uses: actions/checkout@v4 - - - name: Build rpm package for ${{ matrix.dist-version }} - run: ./dist/redhat/build_rpm.sh --target ${{ matrix.dist-version }} - - build-deb-pkgs: - name: Build deb packages - runs-on: ubuntu-22.04 - - strategy: - matrix: - dist-version: [jammy, noble] - fail-fast: false - - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Update apt cache - run: sudo apt-get update -y - - - name: Build deb package for ${{ matrix.dist-version }} - run: ./dist/debian/build_deb.sh --target ${{ matrix.dist-version }} + build-packages: + uses: ./.github/workflows/build-cpack-packages.yml + with: + save-artifacts: false + build-type: Release + secrets: inherit diff --git a/.github/workflows/release-upload-packages.yml b/.github/workflows/release-upload-packages.yml new file mode 100644 index 00000000..39de7583 --- /dev/null +++ b/.github/workflows/release-upload-packages.yml @@ -0,0 +1,42 @@ +name: Attach Packages to Release + +on: + release: + types: [published] + workflow_dispatch: + inputs: + release-tag: + description: release tag + type: string + required: true + +permissions: + contents: write + +jobs: + build-packages: + uses: ./.github/workflows/build-cpack-packages.yml + with: + save-artifacts: true + build-type: Release + secrets: inherit + + publish: + name: Upload artifacts to release + runs-on: ubuntu-22.04 + needs: build-packages + steps: + - uses: actions/download-artifact@v4 + with: + path: packages + - name: Upload packages to GitHub Release + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + TAG_NAME: ${{ inputs.release-tag || github.event.release.tag_name }} + run: | + set -euo pipefail + shopt -s nullglob + for file in packages/*/*; do + echo "Uploading $file" + gh release upload "$TAG_NAME" "$file" --clobber + done diff --git a/.gitignore b/.gitignore index 806d1ddd..7e8a73d3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,9 @@ .vscode/ .zed build/ +build-macos/ +**/build/ +**/build-macos/ scylla-rust-wrapper/target/ .idea/ cmake-build-debug/ diff --git a/CMakeLists.txt b/CMakeLists.txt index 611ca120..787540ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -51,6 +51,18 @@ option(CASS_USE_LIBUV "Use libuv" OFF) set(CASS_CPP_STANDARD "11" CACHE STRING "C++ standard (11, 14, 17, etc.)") +# Component metadata used for macOS productbuild packages. Other platforms +# ignore these values, so keep the defaults empty by default. +set(SCYLLA_DRIVER_COMPONENT_NAME "scylla_cpp_driver") +set(SCYLLA_DRIVER_COMPONENT_ARGS COMPONENT ${SCYLLA_DRIVER_COMPONENT_NAME}) + +# Define component names for runtime and dev packages +# These must be set before add_subdirectory() calls so install commands can use them +set(SCYLLA_DRIVER_RUNTIME_COMPONENT_NAME "${SCYLLA_DRIVER_COMPONENT_NAME}") +set(SCYLLA_DRIVER_DEV_COMPONENT_NAME "${SCYLLA_DRIVER_COMPONENT_NAME}-dev") +string(TOUPPER "${SCYLLA_DRIVER_RUNTIME_COMPONENT_NAME}" SCYLLA_DRIVER_RUNTIME_COMPONENT_NAME_UPPER) +string(TOUPPER "${SCYLLA_DRIVER_DEV_COMPONENT_NAME}" SCYLLA_DRIVER_DEV_COMPONENT_NAME_UPPER) + if(CASS_BUILD_SHARED) set(BUILD_SHARED_LIBS ON) endif() @@ -243,3 +255,155 @@ endif() if(CASS_BUILD_INTEGRATION_TESTS OR CASS_BUILD_TESTS) add_subdirectory(tests) endif() + +#------------------------ +# Packaging (CPack) +#------------------------ + +set(_CPACK_PACKAGE_NAME "scylla-cpp-driver") +set(CPACK_PACKAGE_NAME ${_CPACK_PACKAGE_NAME}) +set(CPACK_PACKAGE_VENDOR "ScyllaDB") +set(CPACK_PACKAGE_CONTACT "ScyllaDB ") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY + "ScyllaDB C++ driver backed by the Rust core driver") +set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/scylladb/cpp-rs-driver") +set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION_STRING}) +set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) +set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) +set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) +if(WIN32) + # Prevent drive letters from bleeding into the staging path when CPack creates + # the temporary install tree on Windows. + set(CPACK_PACKAGING_INSTALL_PREFIX "/") +else() + set(CPACK_PACKAGING_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}") +endif() +set(CPACK_MONOLITHIC_INSTALL ON) +set(CPACK_VERBATIM_VARIABLES ON) + +# Normalize package output names so generated artifacts share a consistent +# `scylla_cpp_driver__.{deb,rpm,pkg,msi}` pattern. +set(CPACK_MONOLITHIC_INSTALL OFF) + +set(SCYLLA_DRIVER_ARTIFACT_BASE_NAME ${SCYLLA_DRIVER_COMPONENT_NAME}) +set(_scylla_driver_system_processor "${CMAKE_SYSTEM_PROCESSOR}") + +set(SCYLLA_DRIVER_DEB_ARCH "${_scylla_driver_system_processor}") +set(SCYLLA_DRIVER_RPM_ARCH "${_scylla_driver_system_processor}") +set(SCYLLA_DRIVER_WIN_ARCH "${_scylla_driver_system_processor}") + +if(_scylla_driver_system_processor MATCHES "^(x86_64|AMD64)$") + set(SCYLLA_DRIVER_DEB_ARCH "amd64") + set(SCYLLA_DRIVER_RPM_ARCH "x86_64") + set(SCYLLA_DRIVER_WIN_ARCH "x64") +elseif(_scylla_driver_system_processor MATCHES "^(aarch64|ARM64)$") + set(SCYLLA_DRIVER_DEB_ARCH "arm64") + set(SCYLLA_DRIVER_RPM_ARCH "aarch64") + set(SCYLLA_DRIVER_WIN_ARCH "arm64") +endif() + +# Fall back to raw processor strings when no mapping exists. +if(NOT SCYLLA_DRIVER_DEB_ARCH) + set(SCYLLA_DRIVER_DEB_ARCH "${_scylla_driver_system_processor}") +endif() +if(NOT SCYLLA_DRIVER_RPM_ARCH) + set(SCYLLA_DRIVER_RPM_ARCH "${_scylla_driver_system_processor}") +endif() +if(NOT SCYLLA_DRIVER_WIN_ARCH) + set(SCYLLA_DRIVER_WIN_ARCH "${_scylla_driver_system_processor}") +endif() + +# Provide a default artifact name that individual generators can refine. +set(CPACK_PACKAGE_FILE_NAME + "${SCYLLA_DRIVER_ARTIFACT_BASE_NAME}_${PROJECT_VERSION_STRING}") + +# Set the list of components for CPack +set(CPACK_COMPONENTS_ALL ${SCYLLA_DRIVER_RUNTIME_COMPONENT_NAME} ${SCYLLA_DRIVER_DEV_COMPONENT_NAME}) + +# Ensure CPack emits one artifact per component instead of merging them into a +# single bundle. +set(CPACK_COMPONENTS_GROUPING IGNORE) + +include(CPackComponent) + +# Runtime component: shared libraries only +cpack_add_component(${SCYLLA_DRIVER_RUNTIME_COMPONENT_NAME} + DISPLAY_NAME "Scylla C++ Driver Runtime" + DESCRIPTION "Shared libraries for the Scylla C++ Driver" + REQUIRED) + +# Dev component: headers, static libraries, pkg-config files, and development symlinks +cpack_add_component(${SCYLLA_DRIVER_DEV_COMPONENT_NAME} + DISPLAY_NAME "Scylla C++ Driver Development" + DESCRIPTION "Headers, static libraries, and development files for the Scylla C++ Driver") + +if(WIN32) + set(CPACK_GENERATOR "WIX") + set(CPACK_PACKAGE_INSTALL_DIRECTORY "ScyllaDB\\Scylla CPP Driver") + # Stable GUID keeps WiX upgrades working between versions + set(CPACK_WIX_UPGRADE_GUID "3E09F4F4-1C4A-4B8B-973D-0CBA64D5E78F") + set(CPACK_PACKAGE_FILE_NAME + "${SCYLLA_DRIVER_ARTIFACT_BASE_NAME}_${PROJECT_VERSION_STRING}_${SCYLLA_DRIVER_WIN_ARCH}") +elseif(APPLE) + configure_file( + "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE" + "${CMAKE_CURRENT_BINARY_DIR}/LICENSE.txt" + COPYONLY) + set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_BINARY_DIR}/LICENSE.txt") + set(CPACK_GENERATOR "productbuild;DragNDrop") + set(CPACK_DMG_COMPONENT_INSTALL ON) + set(CPACK_PACKAGE_FILE_NAME + "${SCYLLA_DRIVER_ARTIFACT_BASE_NAME}_${PROJECT_VERSION_STRING}_macos") + set(CPACK_PRODUCTBUILD_IDENTIFIER "com.scylladb.cpp-rs-driver") + set(CPACK_PRODUCTBUILD_SIGNING_IDENTITY "") + set(CPACK_PRODUCTBUILD_COMPONENT_INSTALL ON) + +else() + set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") + set(CPACK_GENERATOR "DEB;RPM") + set(CPACK_DEBIAN_PACKAGE_ARCHITECTURE "${SCYLLA_DRIVER_DEB_ARCH}") + + set(CPACK_DEBIAN_${SCYLLA_DRIVER_RUNTIME_COMPONENT_NAME_UPPER}_FILE_NAME + "${SCYLLA_DRIVER_RUNTIME_COMPONENT_NAME}_${PROJECT_VERSION_STRING}_${SCYLLA_DRIVER_DEB_ARCH}.deb") + set(CPACK_DEBIAN_${SCYLLA_DRIVER_DEV_COMPONENT_NAME_UPPER}_FILE_NAME + "${SCYLLA_DRIVER_DEV_COMPONENT_NAME}_${PROJECT_VERSION_STRING}_${SCYLLA_DRIVER_DEB_ARCH}.deb") + + # DEB package configuration + set(CPACK_DEB_COMPONENT_INSTALL ON) + set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) + set(CPACK_DEBIAN_PACKAGE_MAINTAINER "ScyllaDB") + set(CPACK_DEBIAN_PACKAGE_SECTION "database") + set(CPACK_DEBIAN_PACKAGE_HOMEPAGE ${CPACK_PACKAGE_HOMEPAGE_URL}) + set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) + + # DEB runtime package + set(CPACK_DEBIAN_${SCYLLA_DRIVER_RUNTIME_COMPONENT_NAME_UPPER}_PACKAGE_NAME "${_CPACK_PACKAGE_NAME}") + set(CPACK_DEBIAN_${SCYLLA_DRIVER_RUNTIME_COMPONENT_NAME_UPPER}_PACKAGE_SECTION "libs") + + # DEB dev package + set(CPACK_DEBIAN_${SCYLLA_DRIVER_DEV_COMPONENT_NAME_UPPER}_PACKAGE_NAME "${_CPACK_PACKAGE_NAME}-dev") + set(CPACK_DEBIAN_${SCYLLA_DRIVER_DEV_COMPONENT_NAME_UPPER}_PACKAGE_SECTION "libdevel") + + # RPM package configuration + set(CPACK_RPM_COMPONENT_INSTALL ON) + set(CPACK_RPM_PACKAGE_LICENSE "Apache-2.0") + set(CPACK_RPM_PACKAGE_URL ${CPACK_PACKAGE_HOMEPAGE_URL}) + set(CPACK_RPM_PACKAGE_RELEASE 1) + set(CPACK_RPM_PACKAGE_GROUP "Applications/Databases") + set(CPACK_RPM_PACKAGE_ARCHITECTURE "${SCYLLA_DRIVER_RPM_ARCH}") + + set(CPACK_RPM_${SCYLLA_DRIVER_RUNTIME_COMPONENT_NAME}_FILE_NAME + "${SCYLLA_DRIVER_RUNTIME_COMPONENT_NAME}_${PROJECT_VERSION_STRING}_${SCYLLA_DRIVER_RPM_ARCH}.rpm") + + # RPM runtime package + set(CPACK_RPM_${SCYLLA_DRIVER_RUNTIME_COMPONENT_NAME}_PACKAGE_NAME "${_CPACK_PACKAGE_NAME}") + set(CPACK_RPM_${SCYLLA_DRIVER_RUNTIME_COMPONENT_NAME}_PACKAGE_GROUP "System Environment/Libraries") + + # RPM dev package (devel suffix is standard for RPM) + set(CPACK_RPM_${SCYLLA_DRIVER_DEV_COMPONENT_NAME}_PACKAGE_NAME "${_CPACK_PACKAGE_NAME}-devel") + set(CPACK_RPM_${SCYLLA_DRIVER_DEV_COMPONENT_NAME}_PACKAGE_GROUP "Development/Libraries") + set(CPACK_RPM_${SCYLLA_DRIVER_DEV_COMPONENT_NAME}_FILE_NAME + "${SCYLLA_DRIVER_COMPONENT_NAME}-devel_${PROJECT_VERSION_STRING}_${SCYLLA_DRIVER_RPM_ARCH}.rpm") +endif() + +include(CPack) diff --git a/MAINTENANCE.md b/MAINTENANCE.md index 1a7b64cf..fa44f6a3 100644 --- a/MAINTENANCE.md +++ b/MAINTENANCE.md @@ -35,10 +35,9 @@ Description of this PR should consist of just release notes. **NOTE: Preferably 8. Create a new tag (e.g. `git tag -a v1.2.0 -m "Release 1.2.0"`). 9. Push `master` and the new tag, preferably using atomic push (e.g. `git push --atomic origin master v1.2.0`). 10. Remove `version` file if present. This file contains version information (`X.Y.Z..`) and should be generated from scratch when releasing new version. The file will be re-generated automatically by instructions described in the next steps. -11. Build RPM packages (e.g. `./dist/redhat/build_rpm.sh --target rocky-8-x86_64`) - see `Build rpm package` section of README.md for more details. We don't have a strict policy which distribution versions to choose during release. As an example, during release 0.4.0, we provided packages for Fedora40, Fedora41 and Rocky9. This would correspond to two latest Fedora versions and latest Rocky version at the time. Ideally, the chosen versions should be in-sync with distribution versions we use in our CI. -12. Build DEB packages (e.g. .`/dist/debian/build_deb.sh --target jammy`) - see `Build deb package` section of README.md for more details. Again, we don't have a strict policy regarding the chosen distribution versions. Looking at the previous releases, we always built packages for `jammy` and `noble`. -13. Go to https://github.com/scylladb/cpp-rs-driver/releases , click the `Draft new release` button and follow the procedure to create a new release on GitHub. Use the release notes as its description. Be sure to upload built packages from the previous steps - see previous releases to check which files are included. -14. (Mandatory for major / minor release, optional for patch release) Publish a post on the forum: +11. Go to https://github.com/scylladb/cpp-rs-driver/releases , click the `Draft new release` button and follow the procedure to create a new release on GitHub. Use the release notes as its description. +12. After the release is published, the `Attach Packages to Release` workflow (`.github/workflows/release-upload-packages.yml`) automatically builds fresh packages using CPack and uploads every artifact to the release. Verify that the workflow finished successfully and that RPM/DEB/MSI/PKG/DMG files are attached. +13. (Mandatory for major / minor release, optional for patch release) Publish a post on the forum: - Go to [Release notes](https://forum.scylladb.com/c/scylladb-release-notes/18) section. - Click "New Topic". - Title should be `[RELEASE] ScyllaDB CPP RS Driver `, e.g. `[RELEASE] ScyllaDB CPP RS Driver 0.5.0` @@ -143,4 +142,3 @@ Contributors since the last release: | 17 | Mercedes Marks | ``` - diff --git a/Makefile b/Makefile index 15d7d333..c9aa6f82 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,22 @@ EMPTY := SPACE := ${EMPTY} ${EMPTY} +SHELL = bash +ifeq ($(OS),Windows_NT) + SHELL := pwsh.exe + .SHELLFLAGS := -NoProfile -Command + .ONESHELL: +endif + +UNAME_S := $(shell uname -s) +ifeq ($(OS),Windows_NT) + OS_TYPE = windows +else ifeq ($(UNAME_S),Darwin) + OS_TYPE = macos +else + OS_TYPE = linux +endif + ifndef SCYLLA_TEST_FILTER SCYLLA_TEST_FILTER := $(subst ${SPACE},${EMPTY},ClusterTests.*\ :BasicsTests.*\ @@ -181,6 +197,22 @@ FULL_RUSTFLAGS := --cfg cpp_rust_unstable --cfg cpp_integration_testing CURRENT_DIR := $(dir $(abspath $(lastword $(MAKEFILE_LIST)))) BUILD_DIR := "${CURRENT_DIR}build" INTEGRATION_TEST_BIN := ${BUILD_DIR}/cassandra-integration-tests +CMAKE_FLAGS ?= +CMAKE_BUILD_TYPE ?= Release + +ifeq ($(OS_TYPE),macos) + CMAKE_INSTALL_PREFIX ?= /usr/local +else + CMAKE_INSTALL_PREFIX ?= /usr +endif + +ifeq ($(OS_TYPE),macos) + CPACK_GENERATORS ?= DragNDrop productbuild +else ifeq ($(OS_TYPE),windows) + CPACK_GENERATORS ?= WIX +else + CPACK_GENERATORS ?= DEB RPM +endif clean: rm -rf "${BUILD_DIR}" @@ -260,6 +292,59 @@ build-examples: cmake -DCASS_BUILD_INTEGRATION_TESTS=off -DCASS_BUILD_EXAMPLES=on -DCMAKE_BUILD_TYPE=Release .. && (make -j 4 || make);\ } +.ubuntu-package-install-dependencies: update-apt-cache-if-needed + sudo apt-get install -y rpm ninja-build pkg-config + +.package-build-prepare-ubuntu: + @missing=""; \ + for bin in ninja rpmbuild pkg-config; do \ + if ! command -v $$bin >/dev/null 2>&1; then \ + missing="$$missing $$bin"; \ + fi; \ + done; \ + if [ -n "$$missing" ]; then \ + $(MAKE) .ubuntu-package-install-dependencies; \ + fi + +.package-build-prepare-windows-openssl: + if (-not (choco list --local-only --exact openssl.light | Select-String '^openssl.light$$')) { + choco install openssl.light --no-progress -y + } + +.package-build-prepare-windows-pkgconfiglite: + if (-not (choco list --local-only --exact pkgconfiglite | Select-String '^pkgconfiglite$$')) { + choco install pkgconfiglite --no-progress -y + } + +.package-build-prepare-windows: .package-build-prepare-windows-openssl .package-build-prepare-windows-pkgconfiglite + +ifeq ($(OS_TYPE),macos) +.package-build-prepare: +else ifeq ($(OS_TYPE),windows) +.package-build-prepare: .package-build-prepare-windows +else +.package-build-prepare: .package-build-prepare-ubuntu +endif + +.package-configure: .package-build-prepare +ifeq ($(OS_TYPE),windows) + cmake -S . -B build -G "Visual Studio 17 2022" -A x64 -DCMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) $(CMAKE_FLAGS) +else + cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=$(CMAKE_BUILD_TYPE) -DCMAKE_INSTALL_PREFIX=$(CMAKE_INSTALL_PREFIX) $(CMAKE_FLAGS) +endif + +build-driver: .package-configure + cmake --build build --config $(CMAKE_BUILD_TYPE) + +build-package: build-driver + @cd build; for gen in $(CPACK_GENERATORS); do \ + if [ "$${gen}" = "productbuild" ] && [ "$(OS_TYPE)" = "macos" ]; then \ + cmake -DCPACK_BUILD_DIR="$$PWD" -DCPACK_BUILD_CONFIG="$(CMAKE_BUILD_TYPE)" -P ../cmake/RunMacProductbuild.cmake; \ + else \ + cpack -G $${gen} -C $(CMAKE_BUILD_TYPE); \ + fi; \ + done + _update-rust-tooling: @echo "Run rustup update" @rustup update diff --git a/README.md b/README.md index 9feb2c2e..eda8ce9b 100644 --- a/README.md +++ b/README.md @@ -424,48 +424,47 @@ Now, use `--gtest_filter` to run certain integration tests: ##### Note: Tests that pass with ScyllaDB and Cassandra clusters can be found in Makefile: `SCYLLA_TEST_FILTER` and `CASSANDRA_TEST_FILTER` env variables. -# Build rpm package +# Packaging with CPack ___ -To build rpm package, run the following command: -```shell -./dist/redhat/build_rpm.sh --target rocky-8-x86_64 -``` -It will construct chrooted build environment of target distribution using mock, -and build rpm in the environment. -Target parameter should be mock .cfg file name. -Currently tested on rocky-8-x86_64, rocky-9-x86_64, fedora-38-x86_64, fedora-39-x86_64, fedora-40-x86_64, fedora-rawhide-x86_64. -Build environment should be Fedora or RHEL variants + EPEL, since -other distribution does not provide mock package. -Built result will placed under build/redhat/{rpms,srpms}. - -# Build deb package -___ +The project uses CPack to produce installable artifacts for Linux, macOS, and +Windows. Start by configuring and building the project: -To build deb package, run the following command: ```shell -./dist/debian/build_deb.sh --target mantic +cmake -S . -B build -DCMAKE_BUILD_TYPE=Release +cmake --build build --config Release ``` -It will construct chrooted build environment of target distribution using -pbuilder, and build deb in the environment. -Target parameter should be debian/ubuntu codename. -On Ubuntu targets, currently tested on bionic (18.04), focal (20.04), jammy (22.04), mantic (23.10), noble (24.04). -On Debian targets, currently tested on buster (10), bullseye (11), bookworm (12), trixie (13), sid (unstable). -Build environment should be Fedora, Ubuntu or Debian, since these distribution -provides pbuilder package. -Built result will placed under build/debian/debs. - -# Build & install HomeBrew package (macOS) ---- - -To build HomeBrew pacakge, run the following command: -```shell -cd dist/homebrew -brew install --HEAD ./scylla-cpp-rs-driver.rb -``` -It will run build & install the driver in HomeBrew environment. -Tested on macOS 14.5. +From the `build` directory you can invoke `cpack` with the generator that +matches your target platform: + +* **Linux (Debian/Ubuntu/Fedora/Rocky):** + ```shell + cpack -G DEB -C Release # produces .deb in build/ + cpack -G RPM -C Release # produces .rpm in build/ + ``` + Debian packages set shlibdeps automatically; RPM packages target the + `Applications/Databases` group and use release number `1` by default. + +* **macOS (pkg / dmg):** + ```shell + cpack -G productbuild -C Release # generates .pkg + cpack -G DragNDrop -C Release # generates .dmg + ``` + Both outputs bundle the compiled libraries alongside headers and pkg-config + manifests. + +* **Windows (MSI):** + ```powershell + cpack -G WIX -C Release # requires WiX Toolset 3.11+ + ``` + The MSI installs into `Program Files\ScyllaDB\Scylla CPP Driver` and reuses a + stable upgrade GUID for seamless upgrades. + +GitHub Actions can exercise the same flow via the reusable workflow defined in +`.github/workflows/build-cpack-packages.yml`. Releases published through +`.github/workflows/release-upload-packages.yml` automatically upload the +generated artifacts. # Getting Help ___ diff --git a/cmake/FindOpenSSL.cmake b/cmake/FindOpenSSL.cmake index 5176d0fc..d142e03c 100644 --- a/cmake/FindOpenSSL.cmake +++ b/cmake/FindOpenSSL.cmake @@ -42,6 +42,8 @@ # Set ``OPENSSL_USE_STATIC_LIBS`` to ``TRUE`` to look for static libraries. # Set ``OPENSSL_MSVC_STATIC_RT`` set ``TRUE`` to choose the MT version of the lib. +include(FindPackageHandleStandardArgs) + if (UNIX) if(CMAKE_VERSION VERSION_LESS "2.8.0") find_package(PkgConfig) diff --git a/cmake/RunMacProductbuild.cmake b/cmake/RunMacProductbuild.cmake new file mode 100644 index 00000000..63a1cb41 --- /dev/null +++ b/cmake/RunMacProductbuild.cmake @@ -0,0 +1,59 @@ +cmake_minimum_required(VERSION 3.16) + +if(NOT DEFINED CPACK_BUILD_DIR OR CPACK_BUILD_DIR STREQUAL "") + message(FATAL_ERROR "CPACK_BUILD_DIR must point to the CPack build directory") +endif() + +if(NOT DEFINED CPACK_BUILD_CONFIG OR CPACK_BUILD_CONFIG STREQUAL "") + set(CPACK_BUILD_CONFIG "Release") +endif() + +set(_cpack_config "${CPACK_BUILD_DIR}/CPackConfig.cmake") +if(NOT EXISTS "${_cpack_config}") + message(FATAL_ERROR "Could not find CPack configuration file at ${_cpack_config}") +endif() + +include("${_cpack_config}") + +if(NOT DEFINED CPACK_COMPONENTS_ALL OR CPACK_COMPONENTS_ALL STREQUAL "") + message(FATAL_ERROR "No components configured for packaging") +endif() + +if(NOT DEFINED CPACK_PACKAGE_FILE_NAME OR CPACK_PACKAGE_FILE_NAME STREQUAL "") + message(FATAL_ERROR "CPACK_PACKAGE_FILE_NAME is empty") +endif() + +set(_cpack_executable "cpack") +if(DEFINED CPACK_EXECUTABLE AND NOT CPACK_EXECUTABLE STREQUAL "") + set(_cpack_executable "${CPACK_EXECUTABLE}") +endif() + +string(REGEX MATCH "^(.+)_([0-9].*)$" _matched "${CPACK_PACKAGE_FILE_NAME}") +if(NOT _matched) + message(FATAL_ERROR "Unexpected CPACK_PACKAGE_FILE_NAME format: ${CPACK_PACKAGE_FILE_NAME}") +endif() +set(_base_name "${CMAKE_MATCH_1}") +set(_suffix "${CMAKE_MATCH_2}") + +foreach(_component IN LISTS CPACK_COMPONENTS_ALL) + set(_package_name "${_base_name}_${_suffix}") + if(NOT _component STREQUAL "${_base_name}") + string(REPLACE "${_base_name}" "${_component}" _package_name "${_package_name}") + if(_package_name STREQUAL "${_base_name}_${_suffix}") + set(_package_name "${_component}_${_suffix}") + endif() + endif() + + message(STATUS "Generating productbuild package for component '${_component}' as '${_package_name}.pkg'") + + execute_process( + COMMAND "${_cpack_executable}" -G productbuild -C "${CPACK_BUILD_CONFIG}" + -D "CPACK_COMPONENTS_ALL=${_component}" + -D "CPACK_PACKAGE_FILE_NAME=${_package_name}" + --config "${_cpack_config}" + WORKING_DIRECTORY "${CPACK_BUILD_DIR}" + RESULT_VARIABLE _result) + if(NOT _result EQUAL 0) + message(FATAL_ERROR "cpack failed for component ${_component} with exit code ${_result}") + endif() +endforeach() diff --git a/dist/debian/build_deb.sh b/dist/debian/build_deb.sh deleted file mode 100755 index 882bd367..00000000 --- a/dist/debian/build_deb.sh +++ /dev/null @@ -1,146 +0,0 @@ -#!/bin/bash -e - -. /etc/os-release -print_usage() { - echo "build_deb.sh --jobs 2 --target jammy" - echo " --target target distribution codename" - echo " --no-clean don't rebuild pbuilder tgz" - echo " --jobs specify number of jobs" - exit 1 -} - -TARGET= -NO_CLEAN=0 -JOBS="$(nproc)" -while [ $# -gt 0 ]; do - case "$1" in - "--target") - TARGET=$2 - shift 2 - ;; - "--no-clean") - NO_CLEAN=1 - shift 1 - ;; - "--jobs") - JOBS=$2 - shift 2 - ;; - *) - print_usage - ;; - esac -done - -is_redhat_variant() { - [[ -f /etc/redhat-release ]] -} -is_debian_variant() { - [[ -f /etc/debian_version ]] -} -is_debian() { - case "$1" in - buster|bullseye|bookworm|trixie|sid) return 0;; - *) return 1;; - esac -} -is_ubuntu() { - case "$1" in - bionic|focal|jammy|mantic|noble) return 0;; - *) return 1;; - esac -} - - -APT_UPDATED=0 -declare -A DEB_PKG=( - ["debian-keyring"]="debian-archive-keyring" - ["ubu-keyring"]="ubuntu-keyring" -) -pkg_install() { - if is_redhat_variant; then - sudo yum install -y "$1" - elif is_debian_variant; then - if [[ "${APT_UPDATED}" -eq 0 ]]; then - sudo apt-get -y update - APT_UPDATED=1 - fi - if [[ -n "${DEB_PKG[$1]}" ]]; then - pkg="${DEB_PKG[$1]}" - else - pkg="$1" - fi - sudo apt-get install -y "$pkg" - else - echo "Requires to install following command: $1" - exit 1 - fi -} - -if [[ ! -e dist/debian/build_deb.sh ]]; then - echo "run build_deb.sh in top of scylla dir" - exit 1 -fi - -if [[ -z "${TARGET}" ]]; then - echo "Please specify target" - exit 1 -fi - -if [[ ! -f /usr/bin/git ]]; then - pkg_install git -fi -if [[ ! -f /usr/sbin/pbuilder ]]; then - pkg_install pbuilder -fi -if [[ ! -f /usr/bin/dh_testdir ]]; then - pkg_install debhelper -fi -if is_debian "${TARGET}" && [[ ! -f /usr/share/keyrings/debian-archive-keyring.gpg ]]; then - pkg_install debian-keyring -fi -if is_ubuntu "${TARGET}" && [[ ! -f /usr/share/keyrings/ubuntu-archive-keyring.gpg ]]; then - pkg_install ubu-keyring -fi - -./SCYLLA-VERSION-GEN -DRIVER_NAME=scylla-cpp-rs-driver -DRIVER_VERSION="$(sed 's/-/~/' build/SCYLLA-VERSION-FILE)" -DRIVER_RELEASE="$(cat build/SCYLLA-RELEASE-FILE)" -ARCH="$(dpkg --print-architecture)" - -mkdir -p build/debian/debs -git archive HEAD --prefix "${DRIVER_NAME}-${DRIVER_VERSION}/" --output "build/debian/${DRIVER_NAME}_${DRIVER_VERSION}-${DRIVER_RELEASE}.orig.tar" -echo "$(cat build/SCYLLA-VERSION-FILE)-$(cat build/SCYLLA-RELEASE-FILE)" > version -tar --xform "s#^#${DRIVER_NAME}-${DRIVER_VERSION}/#" -rf "build/debian/${DRIVER_NAME}_${DRIVER_VERSION}-${DRIVER_RELEASE}.orig.tar" version -gzip -f --fast "build/debian/${DRIVER_NAME}_${DRIVER_VERSION}-${DRIVER_RELEASE}.orig.tar" - -if is_debian "${TARGET}"; then - DRIVER_REVISION="1~${TARGET}" -elif is_ubuntu "${TARGET}"; then - DRIVER_REVISION="0ubuntu1~${TARGET}" -else - echo "Unknown distribution: ${TARGET}" -fi -tar xpvf "build/debian/${DRIVER_NAME}_${DRIVER_VERSION}-${DRIVER_RELEASE}.orig.tar.gz" -C build/debian - -./dist/debian/debian_files_gen.py --version "${DRIVER_VERSION}" --release "${DRIVER_RELEASE}" --revision "${DRIVER_REVISION}" --codename "${TARGET}" --output-dir "build/debian/${DRIVER_NAME}"-"${DRIVER_VERSION}"/debian - -# pbuilder generates files owned by root, fix this up -fix_ownership() { - CURRENT_UID="$(id -u)" - CURRENT_GID="$(id -g)" - sudo chown "${CURRENT_UID}":"${CURRENT_GID}" -R "$@" -} - -# use from pbuilderrc -if [[ "${NO_CLEAN}" -eq 0 ]]; then - sudo rm -fv "/var/cache/pbuilder/${DRIVER_NAME}-${TARGET}-${ARCH}-base.tgz" - sudo mkdir -p "/var/cache/pbuilder/${DRIVER_NAME}-${TARGET}-${ARCH}/aptcache" - sudo DRIVER_NAME="${DRIVER_NAME}" DIST="${TARGET}" ARCH="${ARCH}" /usr/sbin/pbuilder clean --configfile ./dist/debian/pbuilderrc - sudo DRIVER_NAME="${DRIVER_NAME}" DIST="${TARGET}" ARCH="${ARCH}" /usr/sbin/pbuilder create --configfile ./dist/debian/pbuilderrc -fi -sudo DRIVER_NAME="${DRIVER_NAME}" DIST="${TARGET}" ARCH="${ARCH}" /usr/sbin/pbuilder update --configfile ./dist/debian/pbuilderrc -(cd "build/debian/${DRIVER_NAME}"-"${DRIVER_VERSION}"; dpkg-source -b .) -sudo DRIVER_NAME="${DRIVER_NAME}" DIST="${TARGET}" ARCH="${ARCH}" /usr/sbin/pbuilder build --configfile ./dist/debian/pbuilderrc --buildresult build/debian/debs "build/debian/${DRIVER_NAME}_${DRIVER_VERSION}-${DRIVER_RELEASE}-${DRIVER_REVISION}.dsc" -fix_ownership build/debian/debs diff --git a/dist/debian/changelog.template b/dist/debian/changelog.template deleted file mode 100644 index ea26c758..00000000 --- a/dist/debian/changelog.template +++ /dev/null @@ -1,5 +0,0 @@ -scylla-cpp-rs-driver (%{version}-%{release}-%{revision}) %{codename}; urgency=medium - - * Initial release. - - -- Takuya ASADA Wed, 1 May 2024 11:02:04 +0000 diff --git a/dist/debian/debian/control b/dist/debian/debian/control deleted file mode 100644 index e0fb4ab1..00000000 --- a/dist/debian/debian/control +++ /dev/null @@ -1,31 +0,0 @@ -Source: scylla-cpp-rs-driver -Maintainer: Takuya ASADA -Homepage: https://github.com/scylladb/cpp-rs-driver -Section: libs -Priority: optional -Standards-Version: 4.6.0 -Build-Depends: debhelper-compat (= 11), - libssl-dev, - pkg-config, - openssl, - ca-certificates, - curl, - clang, - cmake - -Package: libscylla-cpp-driver0 -Architecture: any -Depends: ${misc:Depends}, - ${shlibs:Depends}, -Conflicts: scylla-cpp-driver -Description: ScyllaDB CPP RS Driver - API-compatible rewrite of https://github.com/scylladb/cpp-driver as a wrapper for Rust driver. - -Package: libscylla-cpp-driver-dev -Section: libdevel -Architecture: any -Depends: libscylla-cpp-driver0 (= ${binary:Version}), - ${misc:Depends}, -Conflicts: scylla-cpp-driver-dev -Description: Development libraries for ScyllaDB CPP RS Driver - API-compatible rewrite of https://github.com/scylladb/cpp-driver as a wrapper for Rust driver. diff --git a/dist/debian/debian/copyright b/dist/debian/debian/copyright deleted file mode 100644 index d751f4a2..00000000 --- a/dist/debian/debian/copyright +++ /dev/null @@ -1,25 +0,0 @@ -Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: Scylla DB -Upstream-Contact: http://www.scylladb.com/ -Source: https://github.com/scylladb/cpp-rs-driver - -Files: * -Copyright: Copyright (C) 2024 ScyllaDB -License: LGPL-2.1+ - -License: LGPL-2.1+ - This package is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - . - This package is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - . - You should have received a copy of the GNU Lesser General Public - License along with this package; if not, write to the Free Software - Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -X-Comment: on Debian systems, the complete text of the GNU Lesser General - Public License v2.1 can be found in `/usr/share/common-licenses/LGPL-2.1'. diff --git a/dist/debian/debian/debcargo.toml b/dist/debian/debian/debcargo.toml deleted file mode 100644 index 20e07a16..00000000 --- a/dist/debian/debian/debcargo.toml +++ /dev/null @@ -1,5 +0,0 @@ -overlay = "." -uploaders = ["Takuya ASADA "] - -[source] -section = "libs" diff --git a/dist/debian/debian/debhelper-build-stamp b/dist/debian/debian/debhelper-build-stamp deleted file mode 100644 index db9ee593..00000000 --- a/dist/debian/debian/debhelper-build-stamp +++ /dev/null @@ -1,2 +0,0 @@ -libscylla-cpp-driver0 -libscylla-cpp-driver-dev diff --git a/dist/debian/debian/files b/dist/debian/debian/files deleted file mode 100644 index d841941c..00000000 --- a/dist/debian/debian/files +++ /dev/null @@ -1,4 +0,0 @@ -libscylla-cpp-driver-dev_0.0.1-0.20240328.f143d09a2057-1_amd64.deb libdevel optional -libscylla-cpp-driver0-dbgsym_0.0.1-0.20240328.f143d09a2057-1_amd64.ddeb debug optional automatic=yes -libscylla-cpp-driver0_0.0.1-0.20240328.f143d09a2057-1_amd64.deb libs optional -libscylla-cpp-driver0_0.0.1-0.20240328.f143d09a2057-1_amd64.buildinfo libs optional diff --git a/dist/debian/debian/libscylla-cpp-driver-dev.install b/dist/debian/debian/libscylla-cpp-driver-dev.install deleted file mode 100644 index a1a1516d..00000000 --- a/dist/debian/debian/libscylla-cpp-driver-dev.install +++ /dev/null @@ -1,4 +0,0 @@ -usr/include/* -usr/lib/*/*.so -usr/lib/*/*.a -usr/lib/*/pkgconfig/*.pc diff --git a/dist/debian/debian/libscylla-cpp-driver0.install b/dist/debian/debian/libscylla-cpp-driver0.install deleted file mode 100644 index 3de3b10a..00000000 --- a/dist/debian/debian/libscylla-cpp-driver0.install +++ /dev/null @@ -1 +0,0 @@ -usr/lib/*/*.so.* diff --git a/dist/debian/debian/rules b/dist/debian/debian/rules deleted file mode 100755 index a6c631c7..00000000 --- a/dist/debian/debian/rules +++ /dev/null @@ -1,25 +0,0 @@ -#!/usr/bin/make -f -# -*- makefile -*- - -export DH_VERBOSE=1 - -include /usr/share/dpkg/architecture.mk -include /usr/share/dpkg/buildflags.mk - -export CFLAGS CXXFLAGS CPPFLAGS LDFLAGS DEB_HOST_GNU_TYPE -jobs := $(shell echo $$DEB_BUILD_OPTIONS | sed -r "s/.*parallel=([0-9]+).*/-j\1/") -CARGO_HOME := $(CURDIR)/scylla-rust-wrapper/.cargo -RUSTUP_HOME := $(CURDIR)/scylla-rust-wrapper/.rustup -export CARGO_HOME -export RUSTUP_HOME - -%: - dh $@ --buildsystem=cmake - -override_dh_auto_clean: - rm -rf scylla-rust-wrapper/.cargo - rm -rf scylla-rust-wrapper/.rustup - -override_dh_auto_configure: - /usr/bin/curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | /bin/sh -s -- -v -y --no-modify-path - dh_auto_configure -- -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_RustFLAGS="--cap-lints warn -C linker=$(DEB_HOST_GNU_TYPE)-gcc -C link-arg=-Wl,-Bsymbolic-functions -C link-arg=-Wl,-z,relro" diff --git a/dist/debian/debian/source/format b/dist/debian/debian/source/format deleted file mode 100644 index 163aaf8d..00000000 --- a/dist/debian/debian/source/format +++ /dev/null @@ -1 +0,0 @@ -3.0 (quilt) diff --git a/dist/debian/debian_files_gen.py b/dist/debian/debian_files_gen.py deleted file mode 100755 index 4dc102f4..00000000 --- a/dist/debian/debian_files_gen.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -# -# Copyright (C) 2020-present ScyllaDB -# - -# -# SPDX-License-Identifier: AGPL-3.0-or-later -# - -import argparse -import string -import os -import shutil -import re -import subprocess -from pathlib import Path - -class DebianFilesTemplate(string.Template): - delimiter = '%' - -def generate_changelog(scriptdir, outputdir, version, release, revision, codename): - with open(os.path.join(scriptdir, 'changelog.template')) as f: - changelog_template = f.read() - s = DebianFilesTemplate(changelog_template) - changelog_applied = s.substitute(version=version, - release=release, - revision=revision, - codename=codename) - with open(os.path.join(outputdir, 'changelog'), 'w', encoding='utf-8') as f: - f.write(changelog_applied) - -def main(): - arg_parser = argparse.ArgumentParser() - arg_parser.add_argument('--version', action='store', help='specify version') - arg_parser.add_argument('--release', action='store', help='specify release') - arg_parser.add_argument('--revision', action='store', help='specify revision') - arg_parser.add_argument('--codename', action='store', help='specify distribution codename') - arg_parser.add_argument('--output-dir', action='store', default='debian/debian', - help='output directory') - args = arg_parser.parse_args() - outputdir = args.output_dir - if os.path.exists(outputdir): - shutil.rmtree(outputdir) - shutil.copytree('dist/debian/debian', outputdir) - scriptdir = os.path.dirname(__file__) - generate_changelog(scriptdir, outputdir, args.version, args.release, args.revision, args.codename) - - -if __name__ == '__main__': - main() diff --git a/dist/debian/pbuilderrc b/dist/debian/pbuilderrc deleted file mode 100644 index 684220b8..00000000 --- a/dist/debian/pbuilderrc +++ /dev/null @@ -1,20 +0,0 @@ -USENETWORK=yes -BUILD_HOME=/tmp -ARCHITECTURE="$ARCH" -DISTRIBUTION="$DIST" -BASETGZ="/var/cache/pbuilder/$DRIVER_NAME-$DIST-$ARCH-base.tgz" -APTCACHE="/var/cache/pbuilder/$DRIVER_NAME-$DIST-$ARCH/aptcache/" -EXTRAPACKAGES="sudo" - -if [ "$DIST" = "bionic" ] || [ "$DIST" = "focal" ] || [ "$DIST" = "jammy" ] || [ "$DIST" = "mantic" ] || [ "$DIST" = "noble" ]; then - MIRRORSITE="http://archive.ubuntu.com/ubuntu/" - COMPONENTS="main restricted universe multiverse" - DEBOOTSTRAPOPTS="--keyring=/usr/share/keyrings/ubuntu-archive-keyring.gpg" -elif [ "$DIST" = "buster" ] || [ "$DIST" = "bullseye" ] || [ "$DIST" = "bookworm" ] || [ "$DIST" = "trixie" ] || [ "$DIST" = "sid" ]; then - MIRRORSITE="http://deb.debian.org/debian/" - COMPONENTS="main contrib non-free" - DEBOOTSTRAPOPTS="--keyring=/usr/share/keyrings/debian-archive-keyring.gpg" -else - echo "Unknown distribution: $DIST" - exit 1 -fi diff --git a/dist/homebrew/scylla-cpp-rs-driver.rb b/dist/homebrew/scylla-cpp-rs-driver.rb deleted file mode 100644 index a21ceb24..00000000 --- a/dist/homebrew/scylla-cpp-rs-driver.rb +++ /dev/null @@ -1,16 +0,0 @@ -require "formula" - -class ScyllaCppRustDriver < Formula - homepage "https://github.com/scylladb/cpp-rs-driver" - head "https://github.com/scylladb/cpp-rs-driver.git", branch: "master" - - depends_on "cmake" => :build - depends_on "rust" => :build - depends_on "openssl@3" - - def install - system "cmake", "-S", ".", "-B", "build", "-DCMAKE_BUILD_TYPE=RelWithDebInfo", "-DCMAKE_VERBOSE_MAKEFILE=ON", *std_cmake_args - system "cmake", "--build", "build" - system "cmake", "--install", "build" - end -end diff --git a/dist/redhat/build_rpm.sh b/dist/redhat/build_rpm.sh deleted file mode 100755 index e317550b..00000000 --- a/dist/redhat/build_rpm.sh +++ /dev/null @@ -1,88 +0,0 @@ -#!/bin/bash -e - -. /etc/os-release -print_usage() { - echo "build_rpm.sh --jobs 2 --target rocky-9-x86_64" - echo " --jobs specify number of jobs" - echo " --target target distribution in mock cfg name" - exit 1 -} -JOBS="$(nproc)" -TARGET= -while [[ $# -gt 0 ]]; do - case "$1" in - "--jobs") - JOBS="$2" - shift 2 - ;; - "--target") - TARGET="$2" - shift 2 - ;; - *) - print_usage - ;; - esac -done - -is_redhat_variant() { - [[ -f /etc/redhat-release ]] -} - -pkg_install() { - if is_redhat_variant; then - sudo dnf install -y "$1" - else - echo "Requires to install following command: $1" - exit 1 - fi -} - -TOPDIR="$(pwd)" -if [[ ! -e dist/redhat/build_rpm.sh ]]; then - echo "run build_rpm.sh in top of scylla dir" - exit 1 -fi - -if [[ -z "${TARGET}" ]]; then - echo "Please specify target" - exit 1 -fi - -if [[ ! -f /usr/bin/mock ]]; then - pkg_install mock -fi -if [[ ! -f /usr/bin/git ]]; then - pkg_install git -fi - -echo "Selected target: ${TARGET}" - -./SCYLLA-VERSION-GEN -DRIVER_NAME=scylla-cpp-rs-driver -DRIVER_VERSION="$(sed 's/-/~/' build/SCYLLA-VERSION-FILE)" -DRIVER_RELEASE="$(cat build/SCYLLA-RELEASE-FILE)" - -mkdir -p build/redhat/sources -git archive HEAD --prefix "${DRIVER_NAME}-${DRIVER_VERSION}/" --output "build/redhat/sources/${DRIVER_NAME}-${DRIVER_VERSION}-${DRIVER_RELEASE}.tar" -echo "$(cat build/SCYLLA-VERSION-FILE)-$(cat build/SCYLLA-RELEASE-FILE)" > version -tar --xform "s#^#${DRIVER_NAME}-${DRIVER_VERSION}/#" -rf "build/redhat/sources/${DRIVER_NAME}-${DRIVER_VERSION}-${DRIVER_RELEASE}.tar" version - -# mock generates files owned by root, fix this up -fix_ownership() { - CURRENT_UID="$(id -u)" - CURRENT_GID="$(id -g)" - sudo chown "${CURRENT_UID}":"${CURRENT_GID}" -R "$@" -} - -MOCK_OPTS=( - -D"driver_version ${DRIVER_VERSION}" - -D"driver_release ${DRIVER_RELEASE}" - -D"_smp_mflags -j${JOBS}" -) -sudo mock "${MOCK_OPTS[@]}" --rootdir="${TOPDIR}/build/redhat/mock" --buildsrpm --root="${TARGET}" --resultdir="${TOPDIR}/build/redhat/srpms" --spec="dist/redhat/${DRIVER_NAME}.spec" --sources="build/redhat/sources/${DRIVER_NAME}-${DRIVER_VERSION}-${DRIVER_RELEASE}.tar" -SRPM="$(sed -n -e "s@Wrote: /builddir/build/SRPMS/\(${DRIVER_NAME}-${DRIVER_VERSION//./\.}-${DRIVER_RELEASE}\..*\.src\.rpm\)@\1@p" build/redhat/srpms/build.log | tail -n1)" -sudo mock "${MOCK_OPTS[@]}" --rootdir="${TOPDIR}/build/redhat/mock" --enable-network --rebuild --root="${TARGET}" --resultdir="${TOPDIR}/build/redhat/rpms" "build/redhat/srpms/${SRPM}" -fix_ownership build/redhat/sources -fix_ownership build/redhat/srpms -fix_ownership build/redhat/rpms diff --git a/dist/redhat/scylla-cpp-rs-driver.spec b/dist/redhat/scylla-cpp-rs-driver.spec deleted file mode 100644 index 9444cbcf..00000000 --- a/dist/redhat/scylla-cpp-rs-driver.spec +++ /dev/null @@ -1,69 +0,0 @@ -Name: scylla-cpp-rs-driver -Version: %{driver_version} -Release: %{driver_release}%{?dist} -Summary: ScyllaDB CPP RS Driver -Group: Development/Tools - -License: LGPLv2.1 -URL: https://github.com/scylladb/cpp-rs-driver -Source0: %{name}-%{driver_version}-%{driver_release}.tar -BuildRequires: openssl-devel -BuildRequires: clang -BuildRequires: curl -BuildRequires: cmake -Conflicts: scylla-cpp-driver - -%description -API-compatible rewrite of https://github.com/scylladb/cpp-driver as a wrapper for Rust driver. - -%package devel -Summary: Development libraries for %{name} -Group: Development/Tools -Requires: %{name} = %{version}-%{release} -Requires: pkgconfig -Conflicts: scylla-cpp-driver-devel - -%description devel -Development libraries for %{name} - -%prep -%autosetup -%{__rm} -rf scylla-rust-wrapper/.cargo -%{__rm} -rf scylla-rust-wrapper/.rustup -export CARGO_HOME=$(pwd)/scylla-rust-wrapper/.cargo -export RUSTUP_HOME=$(pwd)/scylla-rust-wrapper/.rustup -/usr/bin/curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | RUSTUP_INIT_SKIP_PATH_CHECK=yes /bin/sh -s -- -y - -%build -export CARGO_HOME=$(pwd)/scylla-rust-wrapper/.cargo -export RUSTUP_HOME=$(pwd)/scylla-rust-wrapper/.rustup -%cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_VERBOSE_MAKEFILE=ON -DCMAKE_RustFLAGS="-Cforce-frame-pointers=yes --cap-lints=warn" -%cmake_build - -%install -%cmake_install - -%check -%ctest - -%ldconfig_scriptlets - -%clean -rm -rf %{buildroot} - -%files -%defattr(-,root,root) -%doc README.md LICENSE -%{_libdir}/*.so.* - -%files devel -%defattr(-,root,root) -%doc README.md LICENSE -%{_includedir}/*.h -%{_libdir}/*.so -%{_libdir}/*.a -%{_libdir}/pkgconfig/*.pc - -%changelog -* Thu Mar 28 2024 Takuya ASADA -- initial version of scylla-cpp-rs-driver.spec diff --git a/packaging/smoke-test-app/CMakeLists.txt b/packaging/smoke-test-app/CMakeLists.txt new file mode 100644 index 00000000..acc4f602 --- /dev/null +++ b/packaging/smoke-test-app/CMakeLists.txt @@ -0,0 +1,297 @@ +cmake_minimum_required(VERSION 3.15) +project(scylla_cpp_driver_smoke_app LANGUAGES C) + +# Derive driver version information from pkg-config metadata when the +# scylla-cpp-driver dev package is available. This keeps the smoke-app +# aligned with the installed driver packages instead of relying on +# building the driver from the same CMake project. +get_filename_component(CPP_DRIVER_ROOT "${CMAKE_CURRENT_LIST_DIR}/.." ABSOLUTE) +get_filename_component(CPP_DRIVER_ROOT "${CPP_DRIVER_ROOT}/.." ABSOLUTE) + +find_package(PkgConfig REQUIRED) +pkg_check_modules(SCYLLA_CPP_DRIVER REQUIRED IMPORTED_TARGET scylla-cpp-driver) + +option(SCYLLA_SMOKE_BUILD_STATIC + "Build statically linked smoke test executable" OFF) + +set(_pkg_config_use_static_libs_saved OFF) +if(DEFINED PKG_CONFIG_USE_STATIC_LIBS) + set(_pkg_config_use_static_libs_saved "${PKG_CONFIG_USE_STATIC_LIBS}") +endif() +set(PKG_CONFIG_USE_STATIC_LIBS ON) +pkg_check_modules(SCYLLA_CPP_DRIVER_STATIC IMPORTED_TARGET scylla-cpp-driver_static) +if(_pkg_config_use_static_libs_saved) + set(PKG_CONFIG_USE_STATIC_LIBS "${_pkg_config_use_static_libs_saved}") +else() + unset(PKG_CONFIG_USE_STATIC_LIBS) +endif() +unset(_pkg_config_use_static_libs_saved) + +set(PROJECT_VERSION_STRING "") +if(SCYLLA_CPP_DRIVER_VERSION) + set(PROJECT_VERSION_STRING "${SCYLLA_CPP_DRIVER_VERSION}") + string(REPLACE "-" ";" _version_parts "${PROJECT_VERSION_STRING}") + list(GET _version_parts 0 _numeric_version) + list(LENGTH _version_parts _parts_length) + if(_parts_length GREATER 1) + list(REMOVE_AT _version_parts 0) + list(JOIN _version_parts "-" PROJECT_VERSION_SUFFIX) + else() + set(PROJECT_VERSION_SUFFIX "") + endif() + + string(REPLACE "." ";" _numeric_split "${_numeric_version}") + list(LENGTH _numeric_split _numeric_length) + if(_numeric_length GREATER 0) + list(GET _numeric_split 0 PROJECT_VERSION_MAJOR) + else() + set(PROJECT_VERSION_MAJOR "") + endif() + if(_numeric_length GREATER 1) + list(GET _numeric_split 1 PROJECT_VERSION_MINOR) + else() + set(PROJECT_VERSION_MINOR "") + endif() + if(_numeric_length GREATER 2) + list(GET _numeric_split 2 PROJECT_VERSION_PATCH) + else() + set(PROJECT_VERSION_PATCH "") + endif() +endif() + +if(PROJECT_VERSION_STRING STREQUAL "") + # Fallback to parsing cassandra.h when pkg-config metadata does not provide + # version information (should be rare, but keeps backwards compatibility). + set(CASS_INCLUDE_DIR "") + foreach(_candidate_dir IN LISTS SCYLLA_CPP_DRIVER_INCLUDE_DIRS) + if(EXISTS "${_candidate_dir}/cassandra.h") + set(CASS_INCLUDE_DIR "${_candidate_dir}") + break() + endif() + endforeach() + if(CASS_INCLUDE_DIR STREQUAL "") + set(CASS_INCLUDE_DIR "${CPP_DRIVER_ROOT}/include") + endif() + + file(STRINGS "${CASS_INCLUDE_DIR}/cassandra.h" _VERSION_PARTS + REGEX "^#define[ \t]+CASS_VERSION_(MAJOR|MINOR|PATCH|SUFFIX)[ \t]+([0-9]+|\"([^\"]+)\")$") + + foreach(part MAJOR MINOR PATCH SUFFIX) + string(REGEX MATCH "CASS_VERSION_${part}[ \t]+([0-9]+|\"([^\"]+)\")" + PROJECT_VERSION_${part} "${_VERSION_PARTS}") + if(PROJECT_VERSION_${part}) + string(REGEX REPLACE "CASS_VERSION_${part}[ \t]+([0-9]+|\"([^\"]+)\")" "\\1" + PROJECT_VERSION_${part} "${PROJECT_VERSION_${part}}") + endif() + endforeach() + + if(NOT PROJECT_VERSION_MAJOR OR NOT PROJECT_VERSION_MINOR) + message(FATAL_ERROR "Unable to extract driver version from metadata or cassandra.h") + endif() + + set(PROJECT_VERSION_STRING + "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") + if(NOT PROJECT_VERSION_PATCH STREQUAL "") + set(PROJECT_VERSION_STRING + "${PROJECT_VERSION_STRING}.${PROJECT_VERSION_PATCH}") + endif() + if(NOT PROJECT_VERSION_SUFFIX STREQUAL "") + string(REPLACE "\"" "" PROJECT_VERSION_SUFFIX ${PROJECT_VERSION_SUFFIX}) + set(PROJECT_VERSION_STRING + "${PROJECT_VERSION_STRING}-${PROJECT_VERSION_SUFFIX}") + endif() +endif() + +set(CMAKE_C_STANDARD 11) +set(CMAKE_C_STANDARD_REQUIRED ON) +set(CMAKE_POSITION_INDEPENDENT_CODE ON) +if(PROJECT_VERSION_SUFFIX) + string(REPLACE "\"" "" PROJECT_VERSION_SUFFIX ${PROJECT_VERSION_SUFFIX}) + if(PROJECT_VERSION_PATCH) + set(PROJECT_VERSION_STRING + "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}-${PROJECT_VERSION_SUFFIX}") + else() + set(PROJECT_VERSION_STRING + "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}-${PROJECT_VERSION_SUFFIX}") + endif() +elseif(PROJECT_VERSION_STRING STREQUAL "") + set(PROJECT_VERSION_STRING + "${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}") + if(NOT PROJECT_VERSION_PATCH STREQUAL "") + set(PROJECT_VERSION_STRING + "${PROJECT_VERSION_STRING}.${PROJECT_VERSION_PATCH}") + endif() +endif() + +add_executable(scylla-cpp-driver-smoke-test + src/smoke_test.c) + +set(_smoke_link_target "PkgConfig::SCYLLA_CPP_DRIVER") +set(_smoke_use_static TRUE) +set(_smoke_extra_link_libraries "") +if(WIN32) + set(_smoke_use_static FALSE) +else() + if(APPLE) + set(_smoke_shared_patterns ".dylib" ".dylib.*") + else() + set(_smoke_shared_patterns ".so" ".so.*") + endif() + foreach(_smoke_dir IN LISTS SCYLLA_CPP_DRIVER_LIBRARY_DIRS) + foreach(_smoke_lib IN LISTS SCYLLA_CPP_DRIVER_LIBRARIES) + foreach(_smoke_pattern IN LISTS _smoke_shared_patterns) + file(GLOB _smoke_shared_candidates + "${_smoke_dir}/lib${_smoke_lib}${_smoke_pattern}") + if(_smoke_shared_candidates) + set(_smoke_use_static FALSE) + break() + endif() + endforeach() + if(NOT _smoke_use_static) + break() + endif() + endforeach() + if(NOT _smoke_use_static) + break() + endif() + endforeach() +endif() +if(_smoke_use_static) + if(SCYLLA_CPP_DRIVER_STATIC_FOUND AND TARGET PkgConfig::SCYLLA_CPP_DRIVER_STATIC) + message(STATUS + "scylla-cpp-driver shared library not found; linking smoke test statically") + set(_smoke_link_target "PkgConfig::SCYLLA_CPP_DRIVER_STATIC") + if(NOT WIN32) + list(APPEND _smoke_extra_link_libraries m) + endif() + else() + message(FATAL_ERROR + "scylla-cpp-driver shared library not found and static package metadata unavailable; cannot link smoke test") + endif() +endif() +unset(_smoke_dir) +unset(_smoke_lib) +unset(_smoke_pattern) +unset(_smoke_shared_candidates) +unset(_smoke_shared_patterns) +unset(_smoke_use_static) + +target_link_libraries(scylla-cpp-driver-smoke-test PRIVATE + ${_smoke_link_target} + ${_smoke_extra_link_libraries}) +unset(_smoke_extra_link_libraries) +unset(_smoke_link_target) + +if(SCYLLA_SMOKE_BUILD_STATIC) + if(NOT SCYLLA_CPP_DRIVER_STATIC_FOUND) + message(FATAL_ERROR + "Static scylla-cpp-driver pkg-config metadata required to build static smoke test") + endif() + + add_executable(scylla-cpp-driver-smoke-test-static + src/smoke_test.c) + set_target_properties(scylla-cpp-driver-smoke-test-static PROPERTIES + OUTPUT_NAME "scylla-cpp-driver-smoke-test-static") + if(NOT PKG_CONFIG_EXECUTABLE) + message(FATAL_ERROR "pkg-config executable not available for static linkage") + endif() + execute_process( + COMMAND ${PKG_CONFIG_EXECUTABLE} --libs --static scylla-cpp-driver_static + OUTPUT_VARIABLE _smoke_static_libs_output + RESULT_VARIABLE _smoke_static_libs_result + OUTPUT_STRIP_TRAILING_WHITESPACE) + if(NOT _smoke_static_libs_result EQUAL 0 OR _smoke_static_libs_output STREQUAL "") + message(FATAL_ERROR + "Unable to resolve static link flags from scylla-cpp-driver_static pkg-config metadata") + endif() + separate_arguments(_smoke_static_link_libraries UNIX_COMMAND "${_smoke_static_libs_output}") + if(NOT WIN32) + list(APPEND _smoke_static_link_libraries m) + endif() + target_link_libraries(scylla-cpp-driver-smoke-test-static PRIVATE + ${_smoke_static_link_libraries}) + unset(_smoke_static_libs_output) + unset(_smoke_static_link_libraries) +endif() + +set(SMOKE_APP_COMPONENT_NAME "") +set(SMOKE_APP_COMPONENT_ARGS "") +if(APPLE) + set(SMOKE_APP_COMPONENT_NAME "scylla_cpp_driver_smoke_app") + set(SMOKE_APP_COMPONENT_ARGS COMPONENT ${SMOKE_APP_COMPONENT_NAME}) +endif() + +set(_smoke_install_targets scylla-cpp-driver-smoke-test) +if(TARGET scylla-cpp-driver-smoke-test-static) + list(APPEND _smoke_install_targets scylla-cpp-driver-smoke-test-static) +endif() + +install(TARGETS + ${_smoke_install_targets} + DESTINATION bin + ${SMOKE_APP_COMPONENT_ARGS}) +unset(_smoke_install_targets) + +#------------------------ +# Packaging (CPack) +#------------------------ + +if(NOT DEFINED CPACK_PACKAGE_NAME) + set(CPACK_PACKAGE_NAME "scylla-cpp-driver-smoke-app") +endif() +set(_SMOKE_APP_PACKAGE_BASENAME "${CPACK_PACKAGE_NAME}") +set(CPACK_PACKAGE_VENDOR "ScyllaDB") +set(CPACK_PACKAGE_CONTACT "ScyllaDB ") +set(CPACK_PACKAGE_DESCRIPTION_SUMMARY + "Smoke test application for scylla-cpp-driver binary packages") +set(CPACK_PACKAGE_HOMEPAGE_URL "https://github.com/scylladb/cpp-rs-driver") +set(CPACK_PACKAGE_VERSION ${PROJECT_VERSION_STRING}) +set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR}) +set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR}) +set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH}) +set(CPACK_VERBATIM_VARIABLES ON) +set(CPACK_MONOLITHIC_INSTALL ON) + +if(WIN32) + set(CPACK_GENERATOR "WIX") + set(CPACK_PACKAGE_INSTALL_DIRECTORY "ScyllaDB\\Scylla CPP Driver Smoke Test") + set(CPACK_WIX_UPGRADE_GUID "180C9F7E-8D90-40F1-A91E-9DE5DB451A80") +elseif(APPLE) + set(CPACK_GENERATOR "productbuild;DragNDrop") + configure_file( + "${CPP_DRIVER_ROOT}/LICENSE" + "${CMAKE_CURRENT_BINARY_DIR}/LICENSE.txt" + COPYONLY) + set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_BINARY_DIR}/LICENSE.txt") + set(CPACK_PACKAGE_FILE_NAME + "${_SMOKE_APP_PACKAGE_BASENAME}-${PROJECT_VERSION_STRING}-macos") + set(CPACK_PRODUCTBUILD_IDENTIFIER "com.scylladb.cpp-rs-driver.smoke-app") + set(CPACK_PRODUCTBUILD_SIGNING_IDENTITY "") + if(SMOKE_APP_COMPONENT_NAME) + include(CPackComponent) + set(CPACK_MONOLITHIC_INSTALL OFF) + set(CPACK_COMPONENTS_ALL ${SMOKE_APP_COMPONENT_NAME}) + cpack_add_component(${SMOKE_APP_COMPONENT_NAME} + DISPLAY_NAME "Smoke Test Binary" + DESCRIPTION "CLI smoke test for installed driver packages" + REQUIRED) + set(CPACK_PRODUCTBUILD_COMPONENT_INSTALL ON) + endif() +else() + set(CPACK_GENERATOR "DEB;RPM") + set(CPACK_RESOURCE_FILE_LICENSE "${CPP_DRIVER_ROOT}/LICENSE") + set(CPACK_PACKAGE_FILE_NAME + "${_SMOKE_APP_PACKAGE_BASENAME}-${PROJECT_VERSION_STRING}-${CMAKE_SYSTEM_NAME}") + set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT) + set(CPACK_DEBIAN_PACKAGE_MAINTAINER "ScyllaDB") + set(CPACK_DEBIAN_PACKAGE_SECTION "database") + set(CPACK_DEBIAN_PACKAGE_HOMEPAGE ${CPACK_PACKAGE_HOMEPAGE_URL}) + set(CPACK_DEBIAN_PACKAGE_SHLIBDEPS ON) + set(CPACK_RPM_PACKAGE_LICENSE "Apache-2.0") + set(CPACK_RPM_PACKAGE_URL ${CPACK_PACKAGE_HOMEPAGE_URL}) + set(CPACK_RPM_PACKAGE_RELEASE 1) + set(CPACK_RPM_PACKAGE_GROUP "Applications/Databases") +endif() + +include(CPack) +unset(_SMOKE_APP_PACKAGE_BASENAME) diff --git a/packaging/smoke-test-app/Makefile b/packaging/smoke-test-app/Makefile new file mode 100644 index 00000000..139a1281 --- /dev/null +++ b/packaging/smoke-test-app/Makefile @@ -0,0 +1,294 @@ +SHELL := /bin/bash +.ONESHELL: + +MAKEFILE_PATH := $(abspath $(dir $(abspath $(lastword $(MAKEFILE_LIST))))) +BUILD_DIR ?= ${MAKEFILE_PATH}/build +CMAKE_FLAGS ?= +BUILD_TYPE ?= Release +CMAKE_GENERATOR ?= +INSTALL_PREFIX ?= +INSTALL_TARGET ?= / + +CMAKE_GENERATOR_FLAG := +ifneq ($(strip $(CMAKE_GENERATOR)),) +CMAKE_GENERATOR_FLAG := -G $(CMAKE_GENERATOR) +endif + +CMAKE_INSTALL_PREFIX_FLAG := +ifneq ($(strip $(INSTALL_PREFIX)),) +CMAKE_INSTALL_PREFIX_FLAG := -DCMAKE_INSTALL_PREFIX=$(INSTALL_PREFIX) +endif + +UNAME_S := $(shell uname -s) +ifeq ($(OS),Windows_NT) + OS_TYPE = windows +else ifeq ($(UNAME_S),Darwin) + OS_TYPE = macos +else + OS_TYPE = linux +endif + +.prepare-docker-macos: + @if ! docker --version 2>&1 1>/dev/null; then \ + brew install colima docker;\ + colima start;\ + docker context use colima;\ + fi + +ifeq ($(OS_TYPE),macos) +CPACK_GENERATORS ?= productbuild DragNDrop + +.prepare-for-test: .prepare-docker-macos +else ifeq ($(OS_TYPE),windows) +CPACK_GENERATORS ?= WIX + +.prepare-for-test: +else +CPACK_GENERATORS ?= DEB RPM + +.prepare-for-test: +endif + +define INSTALL_PACKAGE_SCRIPT + set -euo pipefail + if [ "$${#packages[@]}" -eq 0 ]; then + echo "No ${package_name} package found" + exit 1 + fi + if [ "$${#packages[@]}" -gt 1 ]; then + echo "Found more than one file for ${package_name}: $${packages[@]}" + exit 1 + fi + package=$${packages[0]} + if [[ "$$package" == *".deb" ]]; then + sudo dpkg -i "$$package"; + elif [[ "$$package" == *".pkg" ]]; then + sudo installer -pkg "$$pkg" -target $(INSTALL_TARGET) + elif [[ "$$package" == *".rpm" ]]; then + if command -v dnf >/dev/null 2>&1; then + sudo dnf -y install "$$package" + elif command -v yum >/dev/null 2>&1; then + sudo yum -y install "$$package" + elif command -v zypper >/dev/null 2>&1; then + sudo zypper --non-interactive install "$$package" + else + sudo rpm -Uvh "$$package" + fi + else + echo "$$package has unknown package type" + fi +endef + +define REMOVE_PACKAGE_SCRIPT + set -euo pipefail + if [ "$${#packages[@]}" -eq 0 ]; then + echo "No ${package_name} package found" + exit 1 + fi + if [ "$${#packages[@]}" -gt 1 ]; then + echo "Found more than one file for ${package_name}: $${packages[@]}" + exit 1 + fi + package=$${packages[0]} + if [[ "$$package" == *".deb" ]]; then + # For Debian/Ubuntu systems + pkg_name=$$(dpkg-deb -f "$$package" Package) + sudo dpkg -r "$$pkg_name" + elif [[ "$$package" == *".pkg" ]]; then + # macOS packages don't have standard uninstallers + echo "Uninstalling macOS .pkg is not standardized; manual cleanup may be required" + elif [[ "$$package" == *".rpm" ]]; then + # For RHEL/Fedora/SUSE systems + pkg_name=$$(rpm -qp --queryformat '%{NAME}' "$$package" 2>/dev/null || true) + if [ -z "$$pkg_name" ]; then + echo "Could not determine RPM package name for $$package" + exit 1 + fi + if command -v dnf >/dev/null 2>&1; then + sudo dnf -y remove "$$pkg_name" + elif command -v yum >/dev/null 2>&1; then + sudo yum -y remove "$$pkg_name" + elif command -v zypper >/dev/null 2>&1; then + sudo zypper --non-interactive remove "$$pkg_name" + else + sudo rpm -e "$$pkg_name" + fi + else + echo "$$package has unknown package type" + fi +endef + +build-package: + cmake -S . -B $(BUILD_DIR) $(CMAKE_GENERATOR_FLAG) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) $(CMAKE_FLAGS) $(CMAKE_INSTALL_PREFIX_FLAG) + cmake --build $(BUILD_DIR) --config $(BUILD_TYPE) + for generator in $(CPACK_GENERATORS); do \ + (cd $(BUILD_DIR) && cpack -G $$generator -C $(BUILD_TYPE));\ + done + +install-app-pkg: + @shopt -s nullglob + packages=($(BUILD_DIR)/scylla-cpp-driver-smoke-app-*.pkg) + package_name="some-test-app PKG" + ${INSTALL_PACKAGE_SCRIPT} + +install-app-deb: + @shopt -s nullglob + packages=($(BUILD_DIR)/scylla-cpp-driver-smoke-app*.deb) + package_name="some-test-app DEB" + ${INSTALL_PACKAGE_SCRIPT} + +install-app-rpm: + @shopt -s nullglob + packages=($(BUILD_DIR)/scylla-cpp-driver-smoke-app*.rpm) + package_name="some-test-app RPM" + ${INSTALL_PACKAGE_SCRIPT} + +install-driver-dev-deb: + @shopt -s nullglob + packages=(${MAKEFILE_PATH}/../../build/scylla_cpp_driver-dev_*.deb) + package_name="scylla-rs-driver dev DEB" + ${INSTALL_PACKAGE_SCRIPT} + +install-driver-deb: + @shopt -s nullglob; + packages=(${MAKEFILE_PATH}/../../build/scylla_cpp_driver_*.deb) + package_name="scylla-rs-driver dev DEB" + ${INSTALL_PACKAGE_SCRIPT} + +install-driver-dev-rpm: + @shopt -s nullglob + packages=(${MAKEFILE_PATH}/../../build/scylla_cpp_driver-devel_*.rpm) + package_name="scylla-rs-driver dev RPM" + ${INSTALL_PACKAGE_SCRIPT} + +install-driver-rpm: + @shopt -s nullglob + packages=(${MAKEFILE_PATH}/../../build/scylla_cpp_driver_*.rpm) + package_name="scylla-rs-driver RPM" + ${INSTALL_PACKAGE_SCRIPT} + +install-driver-dev-pkg: + @shopt -s nullglob + packages=(${MAKEFILE_PATH}/../../build/scylla_cpp_driver-dev_*_macos.pkg) + package_name="scylla-rs-driver dev PKG" + ${INSTALL_PACKAGE_SCRIPT} + +install-driver-pkg: + @shopt -s nullglob + packages=(${MAKEFILE_PATH}/../../build/scylla_cpp_driver_*_macos.pkg) + package_name="scylla-rs-driver PKG" + ${INSTALL_PACKAGE_SCRIPT} + +ifeq ($(OS_TYPE),macos) +install-driver: install-driver-pkg +install-driver-dev: install-driver-dev-pkg +install-app: install-app-pkg + +else ifeq ($(OS_TYPE),windows) +install-driver: + echo "NOT IMPLEMENTED" + exit 1 +install-driver-dev: + echo "NOT IMPLEMENTED" + exit 1 +install-app: + echo "NOT IMPLEMENTED" + exit 1 + +else ifeq ($(shell command -v dpkg >/dev/null 2>&1 && echo yes),yes) +install-driver: install-driver-deb +install-driver-dev: install-driver-dev-deb +install-app: install-app-deb +else +install-driver: install-driver-rpm +install-driver-dev: install-driver-dev-rpm +install-app: install-app-rpm +endif + +remove-app-pkg: + @shopt -s nullglob + packages=($(BUILD_DIR)/scylla-cpp-driver-smoke-app-*.pkg) + package_name="some-test-app PKG" + ${REMOVE_PACKAGE_SCRIPT} + +remove-app-deb: + @shopt -s nullglob + packages=($(BUILD_DIR)/scylla-cpp-driver-smoke-app*.deb) + package_name="some-test-app DEB" + ${REMOVE_PACKAGE_SCRIPT} + +remove-app-rpm: + @shopt -s nullglob + packages=($(BUILD_DIR)/scylla-cpp-driver-smoke-app*.rpm) + package_name="some-test-app RPM" + ${REMOVE_PACKAGE_SCRIPT} + +remove-driver-dev-deb: + @shopt -s nullglob + packages=(${MAKEFILE_PATH}/../../build/*-dev*.deb) + package_name="scylla-rs-driver dev DEB" + ${REMOVE_PACKAGE_SCRIPT} + +remove-driver-deb: + @shopt -s nullglob + packages=(${MAKEFILE_PATH}/../../build/*scylla_cpp_driver_*.deb) + package_name="scylla-rs-driver DEB" + ${REMOVE_PACKAGE_SCRIPT} + +remove-driver-dev-rpm: + @shopt -s nullglob + packages=(${MAKEFILE_PATH}/../../build/*-cpp_driver-dev.rpm) + package_name="scylla-rs-driver dev RPM" + ${REMOVE_PACKAGE_SCRIPT} + +remove-driver-rpm: + @shopt -s nullglob + packages=(${MAKEFILE_PATH}/../../build/*-cpp_driver.rpm) + package_name="scylla-rs-driver RPM" + ${REMOVE_PACKAGE_SCRIPT} + +remove-driver-dev-pkg: + @shopt -s nullglob + packages=(${MAKEFILE_PATH}/../../build/*-scylla_cpp_driver-dev.pkg) + package_name="scylla-rs-driver dev PKG" + ${REMOVE_PACKAGE_SCRIPT} + +remove-driver-pkg: + @shopt -s nullglob + packages=(${MAKEFILE_PATH}/../../build/*-scylla_cpp_driver.pkg) + package_name="scylla-rs-driver PKG" + ${REMOVE_PACKAGE_SCRIPT} + +ifeq ($(OS_TYPE),macos) +remove-driver: remove-driver-pkg +remove-driver-dev: remove-driver-dev-pkg +remove-app: remove-app-pkg + +else ifeq ($(OS_TYPE),windows) +remove-driver: + echo "NOT IMPLEMENTED" + exit 1 +remove-driver-dev: + echo "NOT IMPLEMENTED" + exit 1 +remove-app: + echo "NOT IMPLEMENTED" + exit 1 + +else ifeq ($(shell command -v dpkg >/dev/null 2>&1 && echo yes),yes) +remove-driver: remove-driver-deb +remove-driver-dev: remove-driver-dev-deb +remove-app: remove-app-deb +else +remove-driver: remove-driver-rpm +remove-driver-dev: remove-driver-dev-rpm +remove-app: remove-app-rpm +endif + +test-app-package: .prepare-for-test + @cleanup() {\ + sudo docker compose -f ${MAKEFILE_PATH}/docker-compose.yml down --remove-orphans;\ + };\ + trap cleanup EXIT;\ + sudo docker compose -f ${MAKEFILE_PATH}/docker-compose.yml up -d --wait;\ + /usr/bin/scylla-cpp-driver-smoke-test 172.44.0.2 diff --git a/packaging/smoke-test-app/docker-compose.yml b/packaging/smoke-test-app/docker-compose.yml new file mode 100644 index 00000000..3f4cc797 --- /dev/null +++ b/packaging/smoke-test-app/docker-compose.yml @@ -0,0 +1,33 @@ +networks: + public: + name: somke_test_app_public + driver: bridge + ipam: + driver: default + config: + - subnet: 172.44.0.0/16 +services: + scylla: + image: scylladb/scylla + networks: + public: + ipv4_address: 172.44.0.2 + command: | + --rpc-address 172.44.0.2 + --listen-address 172.44.0.2 + --skip-wait-for-gossip-to-settle 0 + --ring-delay-ms 0 + --smp 2 + --memory 1G + healthcheck: + test: + [ + "CMD", + "cqlsh", + "scylla", + "-e", + "select * from system.local WHERE key='local'", + ] + interval: 5s + timeout: 5s + retries: 60 diff --git a/packaging/smoke-test-app/src/smoke_test.c b/packaging/smoke-test-app/src/smoke_test.c new file mode 100644 index 00000000..b3bc8fdc --- /dev/null +++ b/packaging/smoke-test-app/src/smoke_test.c @@ -0,0 +1,96 @@ +#include + +#include +#include +#include + +typedef enum { SMOKE_OK = 0, SMOKE_ERR = 1 } smoke_status_t; + +static void log_future_error(CassFuture* future, const char* context) { + const char* message = NULL; + size_t message_length = 0; + cass_future_error_message(future, &message, &message_length); + fprintf(stderr, "%s: %.*s\n", context, (int)message_length, + message ? message : "(no message)"); +} + +int main(int argc, char* argv[]) { + const char* contact_point = getenv("SCYLLA_CONTACT_POINT"); + if (argc > 1 && argv[1] && strlen(argv[1]) > 0) { + contact_point = argv[1]; + } + if (contact_point == NULL || strlen(contact_point) == 0) { + contact_point = "127.0.0.1"; + } + + CassCluster* cluster = cass_cluster_new(); + CassSession* session = cass_session_new(); + CassFuture* connect_future = NULL; + smoke_status_t result = SMOKE_ERR; + + cass_cluster_set_contact_points(cluster, contact_point); + + connect_future = cass_session_connect(session, cluster); + if (cass_future_error_code(connect_future) != CASS_OK) { + log_future_error(connect_future, "Failed to connect to cluster"); + goto cleanup; + } + + const char* query = "SELECT key, data_center, cluster_name FROM system.local"; + CassStatement* statement = cass_statement_new(query, 0); + CassFuture* result_future = cass_session_execute(session, statement); + + if (cass_future_error_code(result_future) != CASS_OK) { + log_future_error(result_future, "Failed to execute smoke-test query"); + cass_statement_free(statement); + cass_future_free(result_future); + goto cleanup; + } + + const CassResult* cass_result = cass_future_get_result(result_future); + CassIterator* rows = cass_iterator_from_result(cass_result); + + while (cass_iterator_next(rows)) { + const CassRow* row = cass_iterator_get_row(rows); + + const CassValue* key_value = cass_row_get_column_by_name(row, "key"); + const CassValue* dc_value = cass_row_get_column_by_name(row, "data_center"); + const CassValue* cluster_value = cass_row_get_column_by_name(row, "cluster_name"); + + const char* key = NULL; + const char* data_center = NULL; + const char* cluster_name = NULL; + size_t key_length = 0; + size_t dc_length = 0; + size_t cluster_length = 0; + + if (cass_value_get_string(key_value, &key, &key_length) == CASS_OK && + cass_value_get_string(dc_value, &data_center, &dc_length) == CASS_OK && + cass_value_get_string(cluster_value, &cluster_name, &cluster_length) == + CASS_OK) { + printf("system.local -> key=%.*s, data_center=%.*s, cluster_name=%.*s\n", + (int)key_length, key ? key : "", + (int)dc_length, data_center ? data_center : "", + (int)cluster_length, cluster_name ? cluster_name : ""); + result = SMOKE_OK; + } else { + fprintf(stderr, "Unable to decode system.local row\n"); + result = SMOKE_ERR; + break; + } + } + + cass_iterator_free(rows); + cass_result_free(cass_result); + cass_statement_free(statement); + cass_future_free(result_future); + +cleanup: + if (connect_future != NULL) { + cass_future_free(connect_future); + } + cass_session_free(session); + cass_cluster_free(cluster); + + return result == SMOKE_OK ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/scylla-rust-wrapper/CMakeLists.txt b/scylla-rust-wrapper/CMakeLists.txt index a0356c90..fd0e1183 100644 --- a/scylla-rust-wrapper/CMakeLists.txt +++ b/scylla-rust-wrapper/CMakeLists.txt @@ -118,35 +118,50 @@ endif() # Determine if the header should be installed if(CASS_INSTALL_HEADER) file(GLOB CASS_API_HEADER_FILES ${CASS_INCLUDE_DIR}/*.h) - install(FILES ${CASS_API_HEADER_FILES} DESTINATION ${INSTALL_HEADER_DIR}) + # Headers go to dev package + install(FILES ${CASS_API_HEADER_FILES} + DESTINATION ${INSTALL_HEADER_DIR} + COMPONENT ${SCYLLA_DRIVER_DEV_COMPONENT_NAME}) endif() # Install the dynamic/shared library if(CASS_BUILD_SHARED) - install(FILES $ + # Versioned shared library goes to runtime package + install(FILES $ DESTINATION ${CMAKE_INSTALL_LIBDIR} + COMPONENT ${SCYLLA_DRIVER_RUNTIME_COMPONENT_NAME} PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_EXECUTE WORLD_READ) + # Major version symlink goes to runtime package install(FILES ${CMAKE_BINARY_DIR}/${INSTALL_NAME_SHARED_SYMLINK_VERSION} - DESTINATION ${CMAKE_INSTALL_LIBDIR}) + DESTINATION ${CMAKE_INSTALL_LIBDIR} + COMPONENT ${SCYLLA_DRIVER_RUNTIME_COMPONENT_NAME}) + # Unversioned development symlink goes to dev package install(FILES ${CMAKE_BINARY_DIR}/${INSTALL_NAME_SHARED_SYMLINK_NO_VERSION} - DESTINATION ${CMAKE_INSTALL_LIBDIR}) + DESTINATION ${CMAKE_INSTALL_LIBDIR} + COMPONENT ${SCYLLA_DRIVER_DEV_COMPONENT_NAME}) + # pkg-config file goes to dev package if(CASS_INSTALL_PKG_CONFIG) if(PKG_CONFIG_FOUND) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scylla-cpp-driver.pc.in" "scylla-cpp-driver.pc" @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/scylla-cpp-driver.pc" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" + COMPONENT ${SCYLLA_DRIVER_DEV_COMPONENT_NAME}) endif() endif() endif() +# Static library goes to dev package if(CASS_BUILD_STATIC) - install(FILES $ - DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(FILES $ + DESTINATION ${CMAKE_INSTALL_LIBDIR} + COMPONENT ${SCYLLA_DRIVER_DEV_COMPONENT_NAME}) + # Static library pkg-config file goes to dev package if(CASS_INSTALL_PKG_CONFIG) if(PKG_CONFIG_FOUND) configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scylla-cpp-driver_static.pc.in" "scylla-cpp-driver_static.pc" @ONLY) install(FILES "${CMAKE_CURRENT_BINARY_DIR}/scylla-cpp-driver_static.pc" - DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig") + DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig" + COMPONENT ${SCYLLA_DRIVER_DEV_COMPONENT_NAME}) endif() endif() endif() diff --git a/scylla-rust-wrapper/src/cass_error.rs b/scylla-rust-wrapper/src/cass_error.rs index fb05a183..b3e61ef2 100644 --- a/scylla-rust-wrapper/src/cass_error.rs +++ b/scylla-rust-wrapper/src/cass_error.rs @@ -134,7 +134,11 @@ impl ToCassError for DbError { DbError::AlreadyExists { .. } => CassError::CASS_ERROR_SERVER_ALREADY_EXISTS, DbError::Unprepared { .. } => CassError::CASS_ERROR_SERVER_UNPREPARED, DbError::Other(num) => { - CassError((CassErrorSource::CASS_ERROR_SOURCE_SERVER.0 << 24) | *num as u32) + // On windows enums are i32, so we need to cast it + #[allow(clippy::unnecessary_cast)] + let source = CassErrorSource::CASS_ERROR_SOURCE_SERVER.0 as u32; + let code = (source << 24) | (*num as u32); + CassError(code as _) } // TODO: add appropriate error if rate limit reached DbError::RateLimitReached { .. } => CassError::CASS_ERROR_SERVER_UNAVAILABLE, diff --git a/src/testing.cpp b/src/testing.cpp index 30b0b3b7..f781bf50 100644 --- a/src/testing.cpp +++ b/src/testing.cpp @@ -47,44 +47,44 @@ String get_host_from_future(CassFuture* future) { } StringVec get_attempted_hosts_from_future(CassFuture* future) { - // Original implementation commented out for reference. - /* - if (future->type() != Future::FUTURE_TYPE_RESPONSE) { - return StringVec(); - } + // Original implementation commented out for reference. + /* + if (future->type() != Future::FUTURE_TYPE_RESPONSE) { + return StringVec(); + } - StringVec attempted_hosts; - ResponseFuture* response_future = static_cast(future->from()); + StringVec attempted_hosts; + ResponseFuture* response_future = static_cast(future->from()); - AddressVec attempted_addresses = response_future->attempted_addresses(); - for (const auto& address : attempted_addresses) { - attempted_hosts.push_back(address.to_string()); - } - std::sort(attempted_hosts.begin(), attempted_hosts.end()); - return attempted_hosts; - */ - - StringVec attempted_hosts; - - char* const concatenated_attempted_addresses = testing_future_get_attempted_hosts(future); - - std::string concatenated_addresses = concatenated_attempted_addresses; - std::stringstream stream{concatenated_addresses}; - while (true) { - String address; - if (std::getline(stream, address, '\n')) { - if (!address.empty()) { - attempted_hosts.push_back(address); - } - } else { - break; // No more addresses to read. - } + AddressVec attempted_addresses = response_future->attempted_addresses(); + for (const auto& address : attempted_addresses) { + attempted_hosts.push_back(address.to_string()); + } + std::sort(attempted_hosts.begin(), attempted_hosts.end()); + return attempted_hosts; + */ + + StringVec attempted_hosts; + + char* const concatenated_attempted_addresses = testing_future_get_attempted_hosts(future); + + std::string concatenated_addresses = concatenated_attempted_addresses; + std::stringstream stream{ concatenated_addresses }; + while (true) { + String address; + if (std::getline(stream, address, '\n')) { + if (!address.empty()) { + attempted_hosts.push_back(address); + } + } else { + break; // No more addresses to read. } - std::sort(attempted_hosts.begin(), attempted_hosts.end()); + } + std::sort(attempted_hosts.begin(), attempted_hosts.end()); - testing_free_cstring(concatenated_attempted_addresses); + testing_free_cstring(concatenated_attempted_addresses); - return attempted_hosts; + return attempted_hosts; } unsigned get_connect_timeout_from_cluster(CassCluster* cluster) { @@ -143,7 +143,7 @@ String get_server_name(CassFuture* future) { } void set_record_attempted_hosts(CassStatement* statement, bool enable) { - testing_statement_set_recording_history_listener(statement, (cass_bool_t) enable); + testing_statement_set_recording_history_listener(statement, (cass_bool_t)enable); } void set_sleeping_history_listener_on_statement(CassStatement* statement, uint64_t sleep_time_ms) { @@ -154,8 +154,6 @@ void set_sleeping_history_listener_on_batch(CassBatch* batch, uint64_t sleep_tim testing_batch_set_sleeping_history_listener(batch, sleep_time_ms); } -CassRetryPolicy* retry_policy_ignoring_new() { - return testing_retry_policy_ignoring_new(); -} +CassRetryPolicy* retry_policy_ignoring_new() { return testing_retry_policy_ignoring_new(); } }}} // namespace datastax::internal::testing diff --git a/src/testing.hpp b/src/testing.hpp index 7ca0e473..0ae13f0f 100644 --- a/src/testing.hpp +++ b/src/testing.hpp @@ -50,7 +50,8 @@ CASS_EXPORT String get_server_name(CassFuture* future); CASS_EXPORT void set_record_attempted_hosts(CassStatement* statement, bool enable); -CASS_EXPORT void set_sleeping_history_listener_on_statement(CassStatement* statement, uint64_t sleep_time_ms); +CASS_EXPORT void set_sleeping_history_listener_on_statement(CassStatement* statement, + uint64_t sleep_time_ms); CASS_EXPORT void set_sleeping_history_listener_on_batch(CassBatch* batch, uint64_t sleep_time_ms); diff --git a/src/testing_rust_impls.h b/src/testing_rust_impls.h index d1cd0a3b..00ef37c9 100644 --- a/src/testing_rust_impls.h +++ b/src/testing_rust_impls.h @@ -25,33 +25,34 @@ CASS_EXPORT void testing_cluster_get_contact_points(CassCluster* cluster, char** // This method fails if the future resolved to some error. // // On success, it allocates a host string which needs to be then freed wih `testing_free_cstring`. -CASS_EXPORT void testing_future_get_host(const CassFuture* future, char** host, size_t* host_length); +CASS_EXPORT void testing_future_get_host(const CassFuture* future, char** host, + size_t* host_length); -CASS_EXPORT void testing_free_cstring(char *s); +CASS_EXPORT void testing_free_cstring(char* s); // Sets a sleeping history listener on the statement. // This can be used to enforce a sleep time during statement execution, which increases the latency. -CASS_EXPORT void testing_statement_set_sleeping_history_listener(CassStatement *statement, +CASS_EXPORT void testing_statement_set_sleeping_history_listener(CassStatement* statement, cass_uint64_t sleep_time_ms); // Sets a sleeping history listener on the batch. // This can be used to enforce a sleep time during batch execution, which increases the latency. -CASS_EXPORT void testing_batch_set_sleeping_history_listener(CassBatch *batch, - cass_uint64_t sleep_time_ms); +CASS_EXPORT void testing_batch_set_sleeping_history_listener(CassBatch* batch, + cass_uint64_t sleep_time_ms); } // Sets a recording history listener on the statement. // This can be used to collect addresses of hosts attempted during statement execution. // Those can be later retrieved using `testing_future_get_attempted_hosts`. -CASS_EXPORT void testing_statement_set_recording_history_listener(CassStatement *statement, - cass_bool_t enable); +CASS_EXPORT void testing_statement_set_recording_history_listener(CassStatement* statement, + cass_bool_t enable); // Retrieves a concatenated string of attempted hosts from the future. // Hosts are delimited with '\n' character. // Hosts are recorded only if `testing_statement_set_recording_history_listener` // was called on the statement previously. // The returned pointer is allocated and must be freed with `testing_free_cstring`. -CASS_EXPORT char* testing_future_get_attempted_hosts(CassFuture *future); +CASS_EXPORT char* testing_future_get_attempted_hosts(CassFuture* future); /** * Creates a new ignoring retry policy.