version: 2.1

executors:
  windows-cpu:
    machine:
      resource_class: windows.medium
      image: windows-server-2019-vs2019:stable
      shell: bash.exe

jobs:
  windows_build:
    parameters:
      gtest_lib_path:
        type: string
        default: ""
      libuv_path:
        type: string
        default: ""
    executor:
      name: windows-cpu
    steps:
      - checkout
      - run:
          name: Setup Build Env
          command: |
            PATH=$PATH:"C:/Program Files (x86)/Microsoft Visual Studio/2019/Community/MSBuild/Current/Bin"
            eval "$('/C/tools/miniconda3/Scripts/conda.exe' 'shell.bash' 'hook')"
            conda create -n py376_build python=3.7.6
            conda activate py376_build
            conda install cmake
      - run:
          name: Install libuv
          command: |
            eval "$('/C/tools/miniconda3/Scripts/conda.exe' 'shell.bash' 'hook')"
            conda activate py376_build
            curl https://dist.libuv.org/dist/v1.38.0/libuv-v1.38.0.tar.gz \
              --output libuv-v1.38.0.tar.gz
            tar xzvf libuv-v1.38.0.tar.gz
            cd libuv-v1.38.0
            mkdir -p build
            cd build
            mkdir << parameters.libuv_path >>
            cmake .. -DCMAKE_INSTALL_PREFIX=<< parameters.libuv_path >>
            msbuild.exe INSTALL.vcxproj
      - run:
          name: Install googletest
          command: |
            eval "$('/C/tools/miniconda3/Scripts/conda.exe' 'shell.bash' 'hook')"
            conda activate py376_build
            curl https://codeload.github.com/google/googletest/tar.gz/release-1.10.0 \
              --output googletest-release-1.10.0.tar.gz
            tar xzvf googletest-release-1.10.0.tar.gz
            cd googletest-release-1.10.0
            mkdir -p build
            cd build
            mkdir << parameters.gtest_lib_path >>
            cmake .. \
              -DCMAKE_INSTALL_PREFIX=<< parameters.gtest_lib_path >> \
              -Dgtest_force_shared_crt=ON
            msbuild.exe INSTALL.vcxproj
      - run:
          name: Build
          command: |
            eval "$('/C/tools/miniconda3/Scripts/conda.exe' 'shell.bash' 'hook')"
            conda activate py376_build
            git submodule sync
            git submodule update --init --recursive
            mkdir build
            cd build
            cmake .. \
              -DBUILD_TEST=ON \
              -Dlibuv_ROOT=<< parameters.libuv_path >> \
              -DGTEST_LIBRARY=<< parameters.gtest_lib_path >>/lib/gtestd.lib \
              -DGTEST_INCLUDE_DIR=<< parameters.gtest_lib_path >>/include \
              -DGTEST_MAIN_LIBRARY=<< parameters.gtest_lib_path >>/lib/gtest_maind.lib
            msbuild.exe ALL_BUILD.vcxproj
      - run:
          name: Test
          command: |
            build/gloo/test/Debug/gloo_test.exe
  build:
    parameters:
      docker_image:
        type: string
        default: ""
      apt_get:
        type: string
        default: ""
      cmake_compiler:
        type: string
        default: ""
      cmake_args:
        type: string
        default: ""
      build_openssl:
        type: boolean
        default: false
    docker:
      - image: << parameters.docker_image >>
    steps:
      - checkout
      - run:
          name: Install apt packages
          command: |
            apt-get update
            apt-get install -y build-essential cmake libibverbs-dev libssl-dev << parameters.apt_get >>
      - when:
          condition: << parameters.build_openssl >>
          steps:
            - run:
                name: Install openssl
                command: |
                  apt-get install -y wget perl
                  wget -q https://www.openssl.org/source/openssl-1.1.1b.tar.gz
                  tar -xzf openssl-1.1.1b.tar.gz
                  cd openssl-1.1.1b
                  ./config --prefix=/opt/openssl --openssldir=/opt/openssl/ssl
                  make -j 2
                  make install
      - run:
          name: Install libuv
          command: |
            apt-get install -y wget pkg-config
            wget \
              -q \
              -O libuv-v1.26.0.tar.gz \
              https://dist.libuv.org/dist/v1.26.0/libuv-v1.26.0.tar.gz
            tar xf libuv-v1.26.0.tar.gz
            cd libuv-v1.26.0
            mkdir -p build
            cd build
            cmake ../ \
              -DCMAKE_INSTALL_PREFIX=/usr/local \
              << parameters.cmake_compiler >>
            make install
      - run:
          name: Install googletest
          command: |
            wget \
              -q \
              -O googletest-release-1.10.0.tar.gz \
              https://github.com/google/googletest/archive/release-1.10.0.tar.gz
            tar xf googletest-release-1.10.0.tar.gz
            cd googletest-release-1.10.0
            mkdir -p build
            cd build
            cmake ../ \
              -DCMAKE_INSTALL_PREFIX=/usr/local \
              << parameters.cmake_compiler >>
            make install
      - run:
          name: Build
          command: |
            mkdir build
            cd build
            cmake ../ \
              -DCMAKE_VERBOSE_MAKEFILE=ON \
              -DBUILD_TEST=ON \
              << parameters.cmake_compiler >> \
              << parameters.cmake_args >>
            make
      - run:
          name: Test
          command: |
            export TSAN_OPTIONS="suppressions=$PWD/.tsan-suppressions"

            # Exclude large broadcast test because it OOMs on CircleCI.
            EXCLUDE="LargeBroadcast/BroadcastTest*"

            # Exclude multi-process transport tests because
            # they appear to have some crashing problem...
            # EXCLUDE="Transport/TransportMultiProcTest*:$EXCLUDE"

            # Exclude memory leak test for tsan job (false positive).
            if [[ "$CIRCLE_JOB" =~ tsan ]]; then
              EXCLUDE="*MemoryTest.ManySlotsNoLeaks*:$EXCLUDE"
            fi

            build/gloo/test/gloo_test --gtest_filter="-$EXCLUDE"

workflows:
  build:
    jobs:
      - windows_build:
          name: windows_build
          gtest_lib_path: c:/googletest
          libuv_path: c:/libuv
      - build:
          name: gcc5
          docker_image: ubuntu:18.04
          apt_get: "gcc-5 g++-5"
          cmake_compiler: -DCMAKE_C_COMPILER=gcc-5 -DCMAKE_CXX_COMPILER=g++-5
      - build:
          name: gcc5-all-transports
          docker_image: ubuntu:18.04
          apt_get: "gcc-5 g++-5"
          cmake_compiler: -DCMAKE_C_COMPILER=gcc-5 -DCMAKE_CXX_COMPILER=g++-5
          cmake_args: -DUSE_IBVERBS=ON -DUSE_LIBUV=ON -DUSE_TCP_OPENSSL_LINK=ON
      - build:
          name: gcc5-load-openssl
          docker_image: ubuntu:18.04
          apt_get: "gcc-5 g++-5"
          cmake_compiler: -DCMAKE_C_COMPILER=gcc-5 -DCMAKE_CXX_COMPILER=g++-5
          cmake_args: -DUSE_TCP_OPENSSL_LOAD=ON
      - build:
          name: gcc7
          docker_image: ubuntu:18.04
          apt_get: "gcc-7 g++-7"
          cmake_compiler: -DCMAKE_C_COMPILER=gcc-7 -DCMAKE_CXX_COMPILER=g++-7
      - build:
          name: gcc7-all-transports
          docker_image: ubuntu:18.04
          apt_get: "gcc-7 g++-7"
          cmake_compiler: -DCMAKE_C_COMPILER=gcc-7 -DCMAKE_CXX_COMPILER=g++-7
          cmake_args: -DUSE_IBVERBS=ON -DUSE_LIBUV=ON -DUSE_TCP_OPENSSL_LINK=ON
      - build:
          name: gcc7-load-openssl
          docker_image: ubuntu:18.04
          apt_get: "gcc-7 g++-7"
          cmake_compiler: -DCMAKE_C_COMPILER=gcc-7 -DCMAKE_CXX_COMPILER=g++-7
          cmake_args: -DUSE_TCP_OPENSSL_LOAD=ON
      - build:
          name: clang6
          docker_image: ubuntu:18.04
          apt_get: "clang-6.0"
          cmake_compiler: -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0
      - build:
          name: clang6-all-transports
          docker_image: ubuntu:18.04
          apt_get: "clang-6.0"
          cmake_compiler: -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0
          cmake_args: -DUSE_IBVERBS=ON -DUSE_LIBUV=ON -DUSE_TCP_OPENSSL_LINK=ON
      - build:
          name: clang6-load-openssl
          docker_image: ubuntu:18.04
          apt_get: "clang-6.0"
          cmake_compiler: -DCMAKE_C_COMPILER=clang-6.0 -DCMAKE_CXX_COMPILER=clang++-6.0
          cmake_args: -DUSE_TCP_OPENSSL_LOAD=ON
      - build:
          name: cuda9.2
          docker_image: nvidia/cuda:9.2-devel-ubuntu18.04
          cmake_args: -DUSE_CUDA=ON
      - build:
          name: cuda9.2-all-transports
          docker_image: nvidia/cuda:9.2-devel-ubuntu18.04
          cmake_args: -DUSE_IBVERBS=ON -DUSE_LIBUV=ON -DUSE_TCP_OPENSSL_LINK=ON -DUSE_CUDA=ON
      - build:
          name: cuda10.1
          docker_image: nvidia/cuda:10.1-devel-ubuntu18.04
          cmake_args: -DUSE_CUDA=ON
      - build:
          name: cuda10.1-all-transports
          docker_image: nvidia/cuda:10.1-devel-ubuntu18.04
          cmake_args: -DUSE_IBVERBS=ON -DUSE_LIBUV=ON -DUSE_TCP_OPENSSL_LINK=ON -DUSE_CUDA=ON
      - build:
          name: cuda11.7-all-transports
          apt_get: "gcc-9 g++-9"
          docker_image: nvidia/cuda:11.7.1-devel-ubuntu22.04
          cmake_compiler: -DCMAKE_C_COMPILER=gcc-9 -DCMAKE_CXX_COMPILER=g++-9 -DCMAKE_CUDA_HOST_COMPILER=g++-9
          cmake_args: -DUSE_IBVERBS=ON -DUSE_LIBUV=ON -DUSE_TCP_OPENSSL_LINK=ON -DUSE_CUDA=ON -DGLOO_USE_CUDA_TOOLKIT=ON -DOPENSSL_ROOT_DIR=/opt/openssl/
          build_openssl: true
      - build:
          name: tsan-all-transports
          docker_image: ubuntu:18.04
          apt_get: "gcc-7 g++-7"
          cmake_compiler: -DCMAKE_C_COMPILER=gcc-7 -DCMAKE_CXX_COMPILER=g++-7
          cmake_args: -DUSE_IBVERBS=ON -DUSE_LIBUV=ON -DUSE_TCP_OPENSSL_LINK=ON -DCMAKE_BUILD_TYPE=Debug -DSANITIZE=thread
