1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
|
---
kind: pipeline
type: docker
name: default
platform:
os: linux
arch: amd64
steps:
- name: prepare
# any image with a root shell can be used here, but Ubuntu used as base
# image for build and test images and we need to download it anyway
image: ubuntu:20.04
pull: if-not-exists
volumes:
- name: rspamd
path: /rspamd
commands:
- install -d -o nobody -g nogroup /rspamd/build /rspamd/install /rspamd/fedora/build /rspamd/fedora/install
- name: build
# https://github.com/rspamd/rspamd-build-docker/blob/master/ubuntu-build/Dockerfile
image: rspamd/ci-ubuntu-build
pull: always
volumes:
- name: rspamd
path: /rspamd
depends_on: [ prepare ]
commands:
# build directories should be writable by nobody, for rspamd in functional tests
# works as nobody and writes coverage files there
- test "$(id -un)" = nobody
- cd /rspamd/build
- >
cmake
-DCMAKE_INSTALL_PREFIX=/rspamd/install
-DCMAKE_RULE_MESSAGES=OFF
-DCMAKE_VERBOSE_MAKEFILE=ON
-DENABLE_COVERAGE=ON
-DENABLE_LIBUNWIND=ON
$CI_WORKSPACE
- ncpu=$(getconf _NPROCESSORS_ONLN)
- make -j $ncpu install
- make -j $ncpu rspamd-test
- make -j $ncpu rspamd-test-cxx
- name: build-clang
# https://github.com/rspamd/rspamd-build-docker/blob/master/fedora-build/Dockerfile
image: rspamd/ci-fedora-build
pull: always
volumes:
- name: rspamd
path: /rspamd
depends_on: [ prepare ]
commands:
- test "$(id -un)" = nobody
- cd /rspamd/fedora/build
- export LDFLAGS='-fuse-ld=lld'
#- export CFLAGS='-fsanitize=address,undefined,implicit-integer-truncation'
#- export CXXFLAGS='-fsanitize=address,undefined,implicit-integer-truncation'
- export ASAN_OPTIONS=detect_leaks=0
- >
cmake
-DCMAKE_INSTALL_PREFIX=/rspamd/fedora/install
-DCMAKE_C_COMPILER=/usr/bin/clang -DCMAKE_CXX_COMPILER=/usr/bin/clang++
-DCMAKE_RULE_MESSAGES=OFF
-DCMAKE_VERBOSE_MAKEFILE=ON
-DENABLE_CLANG_PLUGIN=ON
-DENABLE_FULL_DEBUG=ON
-DSANITIZE=address
$CI_WORKSPACE
- ncpu=$(getconf _NPROCESSORS_ONLN)
- make -j $ncpu install
- make -j $ncpu rspamd-test
- make -j $ncpu rspamd-test-cxx
# We run rspamd-test (unit test) and functional test (runned by robot) in
# parallel to save time. To avoid conflict in saving lua coverage we run them
# from different directories. For C code coverage counters is saved to .gcda
# files and binary contain absolute path to them, so rspamd-test and
# processes started by functional test are writing to the same files. On
# process exit new coverage data merged with existing content of .gcda file.
# Race is possible if rspamd-test and some rspamd process in functional test
# will try to write .gcda file simultaneous. But it is very unlikely and
# performance is more important then correct coverage data.
- name: rspamd-test
# https://github.com/rspamd/rspamd-build-docker/blob/master/ubuntu-test/Dockerfile
image: rspamd/ci-ubuntu-test
pull: always
volumes:
- name: rspamd
path: /rspamd
depends_on: [ build ]
commands:
- test "$(id -un)" = nobody
- ulimit -c unlimited
# rspamd-test and functional test both use luacov.stats.out file and should be started from
# different directories (if started in parallel)
- cd /rspamd/build/test
- set +e
- ./rspamd-test -p /rspamd/lua; EXIT_CODE=$?
- set -e
# shell sets exit status of a process terminated by a signal to '128 + signal-number'
# if rspamd-test was terminated by a signal it should be SIGSEGV or SIGABRT, try to examine core
- >
if [ $EXIT_CODE -gt 128 ]; then
gdb --batch -ex 'thread apply all bt full' -c /var/tmp/*.rspamd-test.core ./rspamd-test;
exit $EXIT_CODE;
fi
# luacov-coveralls reads luacov.stats.out written by rspamd-test using luacov module
# and writes json report for coveralls.io service
- luacov-coveralls -o /rspamd/build/unit_test_lua.json --dryrun
- set +e
- ./rspamd-test-cxx -s; EXIT_CODE=$?
- set -e
# shell sets exit status of a process terminated by a signal to '128 + signal-number'
# if rspamd-test was terminated by a signal it should be SIGSEGV or SIGABRT, try to examine core
- >
if [ $EXIT_CODE -gt 128 ]; then
gdb --batch -ex 'thread apply all bt full' -c /var/tmp/*.rspamd-test-cxx.core ./rspamd-test-cxx;
exit $EXIT_CODE;
fi
- exit $EXIT_CODE
- name: test-fedora-clang
# https://github.com/rspamd/rspamd-build-docker/blob/master/fedora-test/Dockerfile
image: rspamd/ci-fedora-test
pull: always
volumes:
- name: rspamd
path: /rspamd
depends_on: [ build-clang ]
commands:
- test "$(id -un)" = nobody
# Asan reserves 20Tb of virtual memory, limit core size to 2 Gb to avoid writing huge core
- ulimit -c 2097152
- ulimit -s unlimited
# disable leak sanitizer: too many leaks detected, most of them probably FP
- export ASAN_OPTIONS="detect_leaks=0:print_stacktrace=1:disable_coredump=0"
- export UBSAN_OPTIONS="print_stacktrace=1:print_summary=0:log_path=/tmp/ubsan"
- cd /rspamd/fedora/build/test
- set +e
- ./rspamd-test -p /rspamd/lua; EXIT_CODE=$?
- set -e
# shell sets exit status of a process terminated by a signal to '128 + signal-number'
# if rspamd-test was terminated by a signal it should be SIGSEGV or SIGABRT, try to examine core
- >
if [ $EXIT_CODE -gt 128 ]; then
gdb --batch -ex 'bt' -c /var/tmp/*.rspamd-test.core ./rspamd-test;
fi
- set +e
- ./rspamd-test-cxx -s; EXIT_CODE=$?
- set -e
# shell sets exit status of a process terminated by a signal to '128 + signal-number'
# if rspamd-test was terminated by a signal it should be SIGSEGV or SIGABRT, try to examine core
- >
if [ $EXIT_CODE -gt 128 ]; then
gdb --batch -ex 'thread apply all bt full' -c /var/tmp/*.rspamd-test-cxx.core ./rspamd-test-cxx;
exit $EXIT_CODE;
fi
- cat /tmp/ubsan.* || true
- exit $EXIT_CODE
- name: functional
# https://github.com/rspamd/rspamd-build-docker/blob/master/ubuntu-test-func/Dockerfile
image: rspamd/ci-ubuntu-test-func
pull: always
volumes:
- name: rspamd
path: /rspamd
depends_on: [ build ]
commands:
- cd /rspamd/build
- ulimit -c unlimited
- ulimit -s unlimited
# some rspamd processes during this test work as root and some as nobody
# use umask to create world-writable files so nobody can write to *.gcda files created by root
- umask 0000
- set +e
- RSPAMD_INSTALLROOT=/rspamd/install robot --removekeywords wuks --exclude isbroken $CI_WORKSPACE/test/functional/cases; EXIT_CODE=$?
- set -e
# upload test results to nginx frontent using WebDAV PUT
- >
if [ -n "$HTTP_PUT_AUTH" ]; then
$CI_WORKSPACE/test/tools/http_put.py log.html report.html https://$DRONE_SYSTEM_HOSTNAME/testlogs/$DRONE_REPO/$DRONE_BUILD_NUMBER/;
fi
# core_pattern=/var/tmp/%u.%e.core so one or two cores can be saved for each binary
- core_files=$(find /var/tmp/ -name '*.core')
# use 'info proc mappings' to find path to executable file for given core
# first mapping is usually program executable
- >
for core in $core_files;
do
exe=$(gdb --batch -ex 'info proc mappings' -c $core | tail -1 | awk '{print $5}');
gdb --batch -ex 'bt' -c $core $exe; echo '---';
done
- exit $EXIT_CODE
environment:
HTTP_PUT_AUTH: { from_secret: http_put_auth }
- name: send-coverage
image: rspamd/ci-ubuntu-test
pull: if-not-exists
volumes:
- name: rspamd
path: /rspamd
depends_on: [ functional, rspamd-test ]
commands:
- cd /rspamd/build
# extract coverage data for C code from .gcda files and save it in a format suitable for coveralls.io
- $CI_WORKSPACE/test/tools/gcov_coveralls.py --exclude test --prefix /rspamd/build --prefix $CI_WORKSPACE --out coverage.c.json
# luacov-coveralls reads luacov.stats.out generated by functional tests
# (see collect_lua_coverage() in test/functional/lib/rspamd.py)
# and writes json report for coveralls.io
- luacov-coveralls -o coverage.functional.lua.json --dryrun
# * merge coverage for C and Lua code
# * remove prefixes from absolute paths (in luacov-coveralls files), filter test, contrib, e. t.c
# * upload report to coveralls.io
- $CI_WORKSPACE/test/tools/merge_coveralls.py --root $CI_WORKSPACE --input coverage.c.json unit_test_lua.json coverage.functional.lua.json --token=$COVERALLS_REPO_TOKEN
environment:
COVERALLS_REPO_TOKEN: { from_secret: coveralls_repo_token }
when:
branch: [ master ]
# don't send coverage report for pull request
event: [push, tag]
- name: eslint
image: node:17-alpine
pull: if-not-exists
failure: ignore
commands:
- npm install
- ./node_modules/.bin/eslint -v
- ./node_modules/.bin/eslint ./
# Run stylelint checks
- ./node_modules/.bin/stylelint -v
- npm show stylelint-config-standard version
- ./node_modules/.bin/stylelint ./**/*.css ./**/*.html ./**/*.js
- name: perl-tidyall
# https://github.com/rspamd/rspamd-build-docker/blob/master/perl-tidyall/Dockerfile
image: rspamd/ci-perl-tidyall
pull: if-not-exists
failure: ignore
commands:
- tidyall --version
- perltidy --version | head -1
# checks are configured in .tidyallrc at the top of rspamd repo
- tidyall --all --check-only --no-cache --data-dir /tmp/tidyall
- name: notify
image: drillster/drone-email
pull: if-not-exists
depends_on:
- rspamd-test
- test-fedora-clang
- functional
- send-coverage
- eslint
- perl-tidyall
settings:
from: noreply@rspamd.com
host: { from_secret: email_host }
username: { from_secret: email_username }
password: { from_secret: email_password }
when:
status: [ failure ]
volumes:
- name: rspamd
temp: {}
trigger:
event: [push, tag, pull_request]
---
kind: signature
hmac: 9e142da57023b8a8a23e6c34e6de62552ab32cd5323e9b47a09ae20089992b67
...
|