Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue 4577 - Add GitHub actions #4625

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 12 additions & 3 deletions .github/scripts/generate_matrix.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import os
import glob
import json
from itertools import product

suites = next(os.walk('dirsrvtests/tests/suites/'))[1]

Expand All @@ -13,7 +14,15 @@
suites += [repl_test.replace('dirsrvtests/tests/suites/', '') for repl_test in repl_tests]
suites.sort()

suites_list = [{ "suite": suite} for suite in suites]
matrix = {"include": suites_list}
variants = ['gcc', 'gcc-asan']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

gcc-asan doesn't work with rust, so we can't use this. We need clang-asan to be consistent, especially so to match the correct llvm versions.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I will replace gcc-asan with clang-asan.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Firstyear, clang with -fsanitize=address fails to compile: https://github.com/vashirov/389-ds-base/runs/3554323865#step:6:3541
Any ideas?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found that I filed an issue for this some time ago #4596
I feel that clang-asan would require more efforts than I expected, so I'd like to to keep gcc-asan for now and add clang-asan in a follow up PR.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Didn't we change how lto was managed here to make it work? I'm building and using clang-asan just fine?

The issue with gcc-asan is that I've noticed more and more that gcc asan and rust's llvm backed asan aren't compatible and can not be mixed, which has led to failures to build. That's why I've been using clang now so that they both have the same llvm backend and asan versions.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, we didn't :( I couldn't make LTO builds with clang and then I switched to other things, forgetting about the issue.
I need some help from you regarding Rust + LTO, I will put the details in the related issue.

I haven't encountered any failures myself. Ideally I'd like to have the full matrix (gcc, gcc-asan, clang, clang-asan), so that we can catch these build issues too. But I'm hitting GH actions limit of 256 jobs in the matrix. I have some ideas how to circumvent this with composable actions, will try it next week.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I'll look at the LTO issue later, but I think we can't do gcc-asan + rust at all. I've had so many conflicts between the two ASAN apis as they exist, and a bunch of false positives at this point, that I don't think it should be considered reliable.

# Disable clang matrix for now, otherwise we generate more than 256 jobs...
# variants += ['clang', 'clang-asan']

print(json.dumps(matrix))

jobs = []
for suite, variant in product(suites, variants):
jobs.append({"suite": suite, "variant": variant})

matrix = {"include": jobs}

print(json.dumps(matrix))
162 changes: 107 additions & 55 deletions .github/workflows/pytest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,85 +4,137 @@ on:
push:
pull_request:
schedule:
- cron: '0 0 * * *'
- cron: "0 0 * * *"

jobs:
build:
name: Build
build_rpms:
name: Build RPMs
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
#variant: [gcc, gcc-asan, clang, clang-asan]
variant: [gcc, gcc-asan]

include:
- variant: gcc
asan: 0
clang: 0
- variant: gcc-asan
asan: 1
clang: 0
# - variant: clang
# asan: 0
# clang: 1
# - variant: clang-asan
# asan: 1
# clang: 1
container:
image: quay.io/389ds/ci-images:test
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}

steps:
- name: Checkout
uses: actions/checkout@v2

- name: Get a list of all test suites
id: set-matrix
run: echo "::set-output name=matrix::$(python3 .github/scripts/generate_matrix.py)"
- name: Enable AddressSanitizer support
if: matrix.asan == 1
run: |
set -x
sed -i -e "/^ASAN_ON/s/.*/ASAN_ON = ${{ matrix.asan }}/" rpm.mk
sed -i -e "s/__RELEASE__/__RELEASE__.asan/g" rpm/389-ds-base.spec.in

- name: Enable Clang support
if: matrix.clang == 1
run: |
set -x
sed -i -e "/^CLANG_ON/s/.*/CLANG_ON = ${{ matrix.clang }}/" rpm.mk

- name: Build RPMs
run: cd $GITHUB_WORKSPACE && SKIP_AUDIT_CI=1 make -f rpm.mk dist-bz2 rpms
run: SKIP_AUDIT_CI=1 make -f rpm.mk dist-bz2 rpms

- name: Tar build artifacts
run: tar -cvf dist.tar dist/

- name: Upload RPMs
uses: actions/upload-artifact@v2
with:
name: rpms
name: rpms-${{ matrix.variant }}
path: dist.tar

generate_matrix:
runs-on: ubuntu-latest
needs: build_rpms
name: Generate test matrix
outputs:
matrix: ${{ steps.set-matrix.outputs.matrix }}
steps:
- name: Checkout
uses: actions/checkout@v2

- name: Get a list of all test suites
id: set-matrix
run: echo "::set-output name=matrix::$(python3 .github/scripts/generate_matrix.py)"

test:
name: Test
runs-on: ubuntu-latest
needs: build
needs: generate_matrix
strategy:
fail-fast: false
matrix: ${{ fromJson(needs.build.outputs.matrix) }}
matrix: ${{ fromJson(needs.generate_matrix.outputs.matrix) }}

steps:
- name: Checkout
uses: actions/checkout@v2

- name: Install dependencies
run: |
sudo apt update -y
sudo apt install -y docker.io containerd runc

sudo cp .github/daemon.json /etc/docker/daemon.json

sudo systemctl unmask docker
sudo systemctl start docker

- name: Download RPMs
uses: actions/download-artifact@master
with:
name: rpms

- name: Extract RPMs
run: tar xvf dist.tar

- name: Run pytest in a container
run: |
set -x
CID=$(sudo docker run -d -h server.example.com --privileged --rm -v /sys/fs/cgroup:/sys/fs/cgroup:rw,rslave -v ${PWD}:/workspace quay.io/389ds/ci-images:test)
sudo docker exec $CID sh -c "dnf install -y -v dist/rpms/*rpm"
sudo docker exec $CID py.test --suppress-no-test-exit-code -m "not flaky" --junit-xml=pytest.xml -v dirsrvtests/tests/suites/${{ matrix.suite }}

- name: Make the results file readable by all
if: always()
run:
sudo chmod -f a+r pytest.xml

- name: Sanitize filename
run: echo "PYTEST_SUITE=$(echo ${{ matrix.suite }} | sed -e 's#\/#-#g')" >> $GITHUB_ENV

- name: Upload pytest test results
if: always()
uses: actions/upload-artifact@v2
with:
name: pytest-${{ env.PYTEST_SUITE }}
path: pytest.xml

- name: Checkout
uses: actions/checkout@v2

- name: Install dependencies
run: |
sudo apt update -y
sudo apt install -y docker.io containerd runc

sudo cp .github/daemon.json /etc/docker/daemon.json

sudo systemctl unmask docker
sudo systemctl start docker

- name: Download RPMs
uses: actions/download-artifact@v2
with:
name: rpms-${{ matrix.variant }}

- name: Extract RPMs
run: tar xvf dist.tar

- name: Run pytest in a container
run: |
set -x
CID=$(sudo docker run -d -h server.example.com --privileged --rm -v /sys/fs/cgroup:/sys/fs/cgroup:rw,rslave -v ${PWD}:/workspace quay.io/389ds/ci-images:test)
sudo docker exec $CID sh -c "dnf install -y -v dist/rpms/*rpm"
sudo docker exec -e ASAN_OPTIONS="log_path=/run/dirsrv/ns-slapd.asan:log_exe_name=1" $CID py.test --suppress-no-test-exit-code -m "not flaky" --junit-xml=pytest.xml --html=pytest.html -v dirsrvtests/tests/suites/${{ matrix.suite }}

- name: Make the results file readable by all
if: always()
run: |
sudo chmod -f -v -R a+r pytest.*ml assets
sudo chmod -f -v a+x assets

- name: Print AddressSanitizer reports, if any
if: always()
run: |
tail -n +1 assets/*.txt || true

- name: Sanitize filename
if: always()
run: |
set -x
echo "PYTEST_SUITE=$(echo ${{ matrix.suite }} | sed -e 's#\/#-#g')" >> $GITHUB_ENV

- name: Upload pytest test results
if: always()
uses: actions/upload-artifact@v2
with:
name: pytest-${{ env.PYTEST_SUITE }}-${{ matrix.variant }}
path: |
pytest.xml
pytest.html
assets
4 changes: 2 additions & 2 deletions dirsrvtests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ def rotate_xsan_logs(request):
# rotate the ASAN logs so that only relevant logs are attached to the case in the report.
xsan_logs_dir = f'{p.run_dir}/bak'
if not os.path.exists(xsan_logs_dir):
os.mkdir(xsan_logs_dir)
os.makedirs(xsan_logs_dir)
else:
for f in glob.glob(f'{p.run_dir}/ns-slapd-*san*'):
for f in glob.glob(f'{p.run_dir}/ns-slapd*san*'):
shutil.move(f, xsan_logs_dir)
return rotate_xsan_logs

Expand Down