qemu/tests/unit/meson.build
Emilio Cota e3feb2cc22 util: import GTree as QTree
The only reason to add this implementation is to control the memory allocator
used. Some users (e.g. TCG) cannot work reliably in multi-threaded
environments (e.g. forking in user-mode) with GTree's allocator, GSlice.
See https://gitlab.com/qemu-project/qemu/-/issues/285 for details.

Importing GTree is a temporary workaround until GTree migrates away
from GSlice.

This implementation is identical to that in glib v2.75.0, except that
we don't import recent additions to the API nor deprecated API calls,
none of which are used in QEMU.

I've imported tests from glib and added a benchmark just to
make sure that performance is similar. Note: it cannot be identical
because (1) we are not using GSlice, (2) we use different compilation flags
(e.g. -fPIC) and (3) we're linking statically.

$ cat /proc/cpuinfo| grep 'model name' | head -1
model name      : AMD Ryzen 7 PRO 5850U with Radeon Graphics
$ echo '0' | sudo tee /sys/devices/system/cpu/cpufreq/boost
$ tests/bench/qtree-bench

 Tree         Op      32            1024            4096          131072         1048576
------------------------------------------------------------------------------------------------
GTree     Lookup   83.23           43.08           25.31           19.40           16.22
QTree     Lookup  113.42 (1.36x)   53.83 (1.25x)   28.38 (1.12x)   17.64 (0.91x)   13.04 (0.80x)
GTree     Insert   44.23           29.37           25.83           19.49           17.03
QTree     Insert   46.87 (1.06x)   25.62 (0.87x)   24.29 (0.94x)   16.83 (0.86x)   12.97 (0.76x)
GTree     Remove   53.27           35.15           31.43           24.64           16.70
QTree     Remove   57.32 (1.08x)   41.76 (1.19x)   38.37 (1.22x)   29.30 (1.19x)   15.07 (0.90x)
GTree  RemoveAll  135.44          127.52          126.72          120.11           64.34
QTree  RemoveAll  127.15 (0.94x)  110.37 (0.87x)  107.97 (0.85x)   97.13 (0.81x)   55.10 (0.86x)
GTree   Traverse  277.71          276.09          272.78          246.72           98.47
QTree   Traverse  370.33 (1.33x)  411.97 (1.49x)  400.23 (1.47x)  262.82 (1.07x)   78.52 (0.80x)
------------------------------------------------------------------------------------------------

As a sanity check, the same benchmark when Glib's version
is >= $glib_dropped_gslice_version (i.e. QTree == GTree):

 Tree         Op      32            1024            4096          131072         1048576
------------------------------------------------------------------------------------------------
GTree     Lookup   82.72           43.09           24.18           19.73           16.09
QTree     Lookup   81.82 (0.99x)   43.10 (1.00x)   24.20 (1.00x)   19.76 (1.00x)   16.26 (1.01x)
GTree     Insert   45.07           29.62           26.34           19.90           17.18
QTree     Insert   45.72 (1.01x)   29.60 (1.00x)   26.38 (1.00x)   19.71 (0.99x)   17.20 (1.00x)
GTree     Remove   54.48           35.36           31.77           24.97           16.95
QTree     Remove   54.46 (1.00x)   35.32 (1.00x)   31.77 (1.00x)   24.91 (1.00x)   17.15 (1.01x)
GTree  RemoveAll  140.68          127.36          125.43          121.45           68.20
QTree  RemoveAll  140.65 (1.00x)  127.64 (1.00x)  125.01 (1.00x)  121.73 (1.00x)   67.06 (0.98x)
GTree   Traverse  278.68          276.05          266.75          251.65          104.93
QTree   Traverse  278.31 (1.00x)  275.78 (1.00x)  266.42 (1.00x)  247.89 (0.99x)  104.58 (1.00x)
------------------------------------------------------------------------------------------------

Signed-off-by: Emilio Cota <cota@braap.org>
Message-Id: <20230205163758.416992-2-cota@braap.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
2023-03-28 15:23:10 -07:00

198 lines
5.8 KiB
Meson

testblock = declare_dependency(dependencies: [block], sources: 'iothread.c')
tests = {
'check-block-qdict': [],
'check-qdict': [],
'check-qnum': [],
'check-qstring': [],
'check-qlist': [],
'check-qnull': [],
'check-qobject': [],
'check-qjson': [],
'check-qlit': [],
'test-error-report': [],
'test-qobject-output-visitor': [testqapi],
'test-clone-visitor': [testqapi],
'test-qobject-input-visitor': [testqapi],
'test-forward-visitor': [testqapi],
'test-string-input-visitor': [testqapi],
'test-string-output-visitor': [testqapi],
'test-opts-visitor': [testqapi],
'test-visitor-serialization': [testqapi],
'test-bitmap': [],
# all code tested by test-x86-cpuid is inside topology.h
'test-x86-cpuid': [],
'test-cutils': [],
'test-div128': [],
'test-shift128': [],
'test-mul64': [],
# all code tested by test-int128 is inside int128.h
'test-int128': [],
'rcutorture': [],
'test-rcu-list': [],
'test-rcu-simpleq': [],
'test-rcu-tailq': [],
'test-rcu-slist': [],
'test-qdist': [],
'test-qht': [],
'test-qtree': [],
'test-bitops': [],
'test-bitcnt': [],
'test-qgraph': ['../qtest/libqos/qgraph.c'],
'check-qom-interface': [qom],
'check-qom-proplist': [qom],
'test-qemu-opts': [],
'test-keyval': [testqapi],
'test-logging': [],
'test-uuid': [],
'ptimer-test': ['ptimer-test-stubs.c', meson.project_source_root() / 'hw/core/ptimer.c'],
'test-qapi-util': [],
'test-interval-tree': [],
'test-xs-node': [qom],
}
if have_system or have_tools
tests += {
'test-qmp-event': [testqapi],
}
if seccomp.found()
tests += {'test-seccomp': ['../../softmmu/qemu-seccomp.c', seccomp]}
endif
endif
if have_block
tests += {
'test-coroutine': [testblock],
'test-aio': [testblock],
'test-aio-multithread': [testblock],
'test-throttle': [testblock],
'test-thread-pool': [testblock],
'test-hbitmap': [testblock],
'test-bdrv-drain': [testblock],
'test-bdrv-graph-mod': [testblock],
'test-blockjob': [testblock],
'test-blockjob-txn': [testblock],
'test-block-backend': [testblock],
'test-block-iothread': [testblock],
'test-write-threshold': [testblock],
'test-crypto-hash': [crypto],
'test-crypto-hmac': [crypto],
'test-crypto-cipher': [crypto],
'test-crypto-akcipher': [crypto],
'test-crypto-secret': [crypto, keyutils],
'test-crypto-der': [crypto],
'test-authz-simple': [authz],
'test-authz-list': [authz],
'test-authz-listfile': [authz],
'test-io-task': [testblock],
'test-io-channel-socket': ['socket-helpers.c', 'io-channel-helpers.c', io],
'test-io-channel-file': ['io-channel-helpers.c', io],
'test-io-channel-command': ['io-channel-helpers.c', io],
'test-io-channel-buffer': ['io-channel-helpers.c', io],
'test-io-channel-null': [io],
'test-crypto-ivgen': [io],
'test-crypto-afsplit': [io],
'test-crypto-block': [io],
}
if gnutls.found() and \
tasn1.found() and \
'CONFIG_POSIX' in config_host
tests += {
'test-crypto-tlscredsx509': ['crypto-tls-x509-helpers.c', 'pkix_asn1_tab.c',
tasn1, crypto, gnutls],
'test-crypto-tlssession': ['crypto-tls-x509-helpers.c', 'pkix_asn1_tab.c', 'crypto-tls-psk-helpers.c',
tasn1, crypto, gnutls],
'test-io-channel-tls': ['io-channel-helpers.c', 'crypto-tls-x509-helpers.c', 'pkix_asn1_tab.c',
tasn1, io, crypto, gnutls]}
endif
if pam.found()
tests += {'test-authz-pam': [authz]}
endif
if xts == 'private'
tests += {'test-crypto-xts': [crypto, io]}
endif
if 'CONFIG_POSIX' in config_host
tests += {'test-image-locking': [testblock]}
endif
if config_host_data.get('CONFIG_REPLICATION')
tests += {'test-replication': [testblock]}
endif
if nettle.found() or gcrypt.found()
tests += {'test-crypto-pbkdf': [io]}
endif
if config_host_data.get('CONFIG_EPOLL_CREATE1')
tests += {'test-fdmon-epoll': [testblock]}
endif
endif
if have_system
tests += {
'test-iov': [],
'test-qmp-cmds': [testqapi],
'test-xbzrle': [migration],
'test-timed-average': [],
'test-util-sockets': ['socket-helpers.c'],
'test-base64': [],
'test-bufferiszero': [],
'test-smp-parse': [qom, meson.project_source_root() / 'hw/core/machine-smp.c'],
'test-vmstate': [migration, io],
'test-yank': ['socket-helpers.c', qom, io, chardev]
}
if config_host_data.get('CONFIG_INOTIFY1')
tests += {'test-util-filemonitor': []}
endif
# Some tests: test-char, test-qdev-global-props, and test-qga,
# are not runnable under TSan due to a known issue.
# https://github.com/google/sanitizers/issues/1116
if 'CONFIG_TSAN' not in config_host
if 'CONFIG_POSIX' in config_host
tests += {
'test-char': ['socket-helpers.c', qom, io, chardev]
}
endif
tests += {
'test-qdev-global-props': [qom, hwcore]
}
endif
endif
if have_ga and targetos == 'linux'
tests += {'test-qga': ['../qtest/libqmp.c']}
test_deps += {'test-qga': qga}
endif
test_env = environment()
test_env.set('G_TEST_SRCDIR', meson.current_source_dir())
test_env.set('G_TEST_BUILDDIR', meson.current_build_dir())
slow_tests = {
'test-crypto-tlscredsx509': 45,
'test-crypto-tlssession': 45
}
foreach test_name, extra: tests
src = [test_name + '.c']
deps = [qemuutil]
if extra.length() > 0
# use a sourceset to quickly separate sources and deps
test_ss = ss.source_set()
test_ss.add(extra)
src += test_ss.all_sources()
deps += test_ss.all_dependencies()
endif
exe = executable(test_name, src, genh, dependencies: deps)
test(test_name, exe,
depends: test_deps.get(test_name, []),
env: test_env,
args: ['--tap', '-k'],
protocol: 'tap',
timeout: slow_tests.get(test_name, 30),
priority: slow_tests.get(test_name, 30),
suite: ['unit'])
endforeach