2012-03-08 15:29:00 +04:00
|
|
|
export SRC_PATH
|
|
|
|
|
2015-09-02 13:35:52 +03:00
|
|
|
qapi-py = $(SRC_PATH)/scripts/qapi.py $(SRC_PATH)/scripts/ordereddict.py
|
|
|
|
|
2014-01-23 20:22:59 +04:00
|
|
|
# Get the list of all supported sysemu targets
|
|
|
|
SYSEMU_TARGET_LIST := $(subst -softmmu.mak,,$(notdir \
|
|
|
|
$(wildcard $(SRC_PATH)/default-configs/*-softmmu.mak)))
|
|
|
|
|
2012-03-28 17:42:01 +04:00
|
|
|
check-unit-y = tests/check-qdict$(EXESUF)
|
2013-01-15 12:49:35 +04:00
|
|
|
gcov-files-check-qdict-y = qobject/qdict.c
|
2016-10-25 12:09:25 +03:00
|
|
|
check-unit-y += tests/test-char$(EXESUF)
|
2016-12-10 00:29:03 +03:00
|
|
|
gcov-files-check-qdict-y = chardev/char.c
|
2012-03-28 17:42:01 +04:00
|
|
|
check-unit-y += tests/check-qfloat$(EXESUF)
|
2013-01-15 12:49:35 +04:00
|
|
|
gcov-files-check-qfloat-y = qobject/qfloat.c
|
2012-03-28 17:42:01 +04:00
|
|
|
check-unit-y += tests/check-qint$(EXESUF)
|
2013-01-15 12:49:35 +04:00
|
|
|
gcov-files-check-qint-y = qobject/qint.c
|
2012-03-28 17:42:01 +04:00
|
|
|
check-unit-y += tests/check-qstring$(EXESUF)
|
2013-01-15 12:49:35 +04:00
|
|
|
gcov-files-check-qstring-y = qobject/qstring.c
|
2012-03-28 17:42:01 +04:00
|
|
|
check-unit-y += tests/check-qlist$(EXESUF)
|
2013-01-15 12:49:35 +04:00
|
|
|
gcov-files-check-qlist-y = qobject/qlist.c
|
2016-04-29 00:45:21 +03:00
|
|
|
check-unit-y += tests/check-qnull$(EXESUF)
|
|
|
|
gcov-files-check-qnull-y = qobject/qnull.c
|
2012-03-28 17:42:01 +04:00
|
|
|
check-unit-y += tests/check-qjson$(EXESUF)
|
2013-01-15 12:49:35 +04:00
|
|
|
gcov-files-check-qjson-y = qobject/qjson.c
|
2016-09-30 17:45:27 +03:00
|
|
|
check-unit-y += tests/test-qobject-output-visitor$(EXESUF)
|
|
|
|
gcov-files-test-qobject-output-visitor-y = qapi/qobject-output-visitor.c
|
qapi: Add new clone visitor
We have a couple places in the code base that want to deep-clone
one QAPI object into another, and they were resorting to serializing
the struct out to QObject then reparsing it. A much more efficient
version can be done by adding a new clone visitor.
Since cloning is still relatively uncommon, expose the use of the
new visitor via a QAPI_CLONE() macro that takes care of type-punning
the underlying function pointer, rather than generating lots of
unused functions for types that won't be cloned. And yes, we're
relying on the compiler treating all pointers equally, even though
a strict C program cannot portably do so - but we're not the first
one in the qemu code base to expect it to work (hello, glib!).
The choice of adding a fourth visitor type deserves some explanation.
On the surface, the clone visitor is mostly an input visitor (it
takes arbitrary input - in this case, another QAPI object - and
creates a new QAPI object during the course of the visit). But
ever since commit da72ab0 consolidated enum visits based on the
visitor type, using VISITOR_INPUT would cause us to run
visit_type_str(), even though for cloning there is nothing to do
(we just copy the enum value across, without regards to its mapping
to strings). Also, since our input happens to be a QAPI object,
we can also satisfy the internal checks for VISITOR_OUTPUT. So in
the end, I settled with a new VISITOR_CLONE, and chose its value
such that many internal checks can use 'v->type & mask', sticking
to 'v->type == value' where the difference matters.
Note that we can only clone objects (including alternates) and lists,
not built-ins or enums. The visitor core hides integer width from
the actual visitor (since commit 04e070d), and as long as that's the
case, we can't clone top-level integers. Then again, those can
always be cloned by direct copy, since they are not objects with
deep pointers, so it's no real loss. And restricting cloning to
just objects and lists is cleaner than restricting it to non-integers.
As such, I documented that the clone visitor is for direct use only
by code internal to QAPI, and should not be used on incomplete objects
(other than a hack to work around the fact that we allow NULL in place
of "" in visit_type_str() in other output visitors). Note that as
written, the clone visitor will never fail on a complete object.
Scalars (including enums) not at the root of the clone copy just fine
with no additional effort while visiting the scalar, by virtue of a
g_memdup() each time we push another struct onto the stack. Cloning
a string requires deduplication of a pointer, which means it can also
provide the guarantee of an input visitor of never producing NULL
even when still accepting NULL in place of "" the way the QMP output
visitor does.
Cloning an 'any' type could be possible by incrementing the QObject
refcnt, but it's not obvious whether that is better than implementing
a QObject deep clone. So for now, we document it as unsupported,
and intentionally omit the .type_any() callback to let a developer
know their usage needs implementation.
Add testsuite coverage for several different clone situations, to
ensure that the code is working. I also tested that valgrind was
happy with the test.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1465490926-28625-14-git-send-email-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2016-06-09 19:48:44 +03:00
|
|
|
check-unit-y += tests/test-clone-visitor$(EXESUF)
|
|
|
|
gcov-files-test-clone-visitor-y = qapi/qapi-clone-visitor.c
|
2016-09-30 17:45:27 +03:00
|
|
|
check-unit-y += tests/test-qobject-input-visitor$(EXESUF)
|
|
|
|
gcov-files-test-qobject-input-visitor-y = qapi/qobject-input-visitor.c
|
2012-03-28 17:42:01 +04:00
|
|
|
check-unit-y += tests/test-qmp-commands$(EXESUF)
|
2012-05-01 22:45:39 +04:00
|
|
|
gcov-files-test-qmp-commands-y = qapi/qmp-dispatch.c
|
2012-03-28 17:42:01 +04:00
|
|
|
check-unit-y += tests/test-string-input-visitor$(EXESUF)
|
2012-05-01 22:45:39 +04:00
|
|
|
gcov-files-test-string-input-visitor-y = qapi/string-input-visitor.c
|
2012-03-28 17:42:01 +04:00
|
|
|
check-unit-y += tests/test-string-output-visitor$(EXESUF)
|
2012-05-01 22:45:39 +04:00
|
|
|
gcov-files-test-string-output-visitor-y = qapi/string-output-visitor.c
|
2014-06-18 10:43:29 +04:00
|
|
|
check-unit-y += tests/test-qmp-event$(EXESUF)
|
|
|
|
gcov-files-test-qmp-event-y += qapi/qmp-event.c
|
2013-08-20 02:35:40 +04:00
|
|
|
check-unit-y += tests/test-opts-visitor$(EXESUF)
|
|
|
|
gcov-files-test-opts-visitor-y = qapi/opts-visitor.c
|
2012-03-28 17:42:01 +04:00
|
|
|
check-unit-y += tests/test-coroutine$(EXESUF)
|
2013-04-08 15:11:27 +04:00
|
|
|
gcov-files-test-coroutine-y = coroutine-$(CONFIG_COROUTINE_BACKEND).c
|
2012-02-22 07:05:07 +04:00
|
|
|
check-unit-y += tests/test-visitor-serialization$(EXESUF)
|
rewrite iov_* functions
This changes implementations of all iov_*
functions, completing the previous step.
All iov_* functions now ensure that this offset
argument is within the iovec (using assertion),
but lets to specify `bytes' value larger than
actual length of the iovec - in this case they
stops at the actual end of iovec. It is also
suggested to use convinient `-1' value as `bytes'
to mean just this -- "up to the end".
There's one very minor semantic change here: new
requiriment is that `offset' points to inside of
iovec. This is checked just at the end of functions
(assert()), it does not actually need to be enforced,
but using any of these functions with offset pointing
past the end of iovec is wrong anyway.
Note: the new code in iov.c uses arithmetic with
void pointers. I thought this is not supported
everywhere and is a GCC extension (indeed, the C
standard does not define void arithmetic). However,
the original code already use void arith in
iov_from_buf() function:
(memcpy(..., buf + buf_off,...)
which apparently works well so far (it is this
way in qemu 1.0). So I left it this way and used
it in other places.
While at it, add a unit-test file test-iov.c,
to check various corner cases with iov_from_buf(),
iov_to_buf() and iov_memset().
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2012-06-07 20:08:19 +04:00
|
|
|
check-unit-y += tests/test-iov$(EXESUF)
|
2013-01-15 12:49:35 +04:00
|
|
|
gcov-files-test-iov-y = util/iov.c
|
2012-11-23 19:13:23 +04:00
|
|
|
check-unit-y += tests/test-aio$(EXESUF)
|
2017-02-13 16:52:18 +03:00
|
|
|
gcov-files-test-aio-y = util/async.c util/qemu-timer.o
|
|
|
|
gcov-files-test-aio-$(CONFIG_WIN32) += util/aio-win32.c
|
|
|
|
gcov-files-test-aio-$(CONFIG_POSIX) += util/aio-posix.c
|
2017-02-13 16:52:19 +03:00
|
|
|
check-unit-y += tests/test-aio-multithread$(EXESUF)
|
|
|
|
gcov-files-test-aio-multithread-y = $(gcov-files-test-aio-y)
|
|
|
|
gcov-files-test-aio-multithread-y += util/qemu-coroutine.c tests/iothread.c
|
2013-09-02 16:14:38 +04:00
|
|
|
check-unit-y += tests/test-throttle$(EXESUF)
|
2012-11-23 19:13:24 +04:00
|
|
|
check-unit-y += tests/test-thread-pool$(EXESUF)
|
2012-05-01 22:45:39 +04:00
|
|
|
gcov-files-test-thread-pool-y = thread-pool.c
|
add hierarchical bitmap data type and test cases
HBitmaps provides an array of bits. The bits are stored as usual in an
array of unsigned longs, but HBitmap is also optimized to provide fast
iteration over set bits; going from one bit to the next is O(logB n)
worst case, with B = sizeof(long) * CHAR_BIT: the result is low enough
that the number of levels is in fact fixed.
In order to do this, it stacks multiple bitmaps with progressively coarser
granularity; in all levels except the last, bit N is set iff the N-th
unsigned long is nonzero in the immediately next level. When iteration
completes on the last level it can examine the 2nd-last level to quickly
skip entire words, and even do so recursively to skip blocks of 64 words or
powers thereof (32 on 32-bit machines).
Given an index in the bitmap, it can be split in group of bits like
this (for the 64-bit case):
bits 0-57 => word in the last bitmap | bits 58-63 => bit in the word
bits 0-51 => word in the 2nd-last bitmap | bits 52-57 => bit in the word
bits 0-45 => word in the 3rd-last bitmap | bits 46-51 => bit in the word
So it is easy to move up simply by shifting the index right by
log2(BITS_PER_LONG) bits. To move down, you shift the index left
similarly, and add the word index within the group. Iteration uses
ffs (find first set bit) to find the next word to examine; this
operation can be done in constant time in most current architectures.
Setting or clearing a range of m bits on all levels, the work to perform
is O(m + m/W + m/W^2 + ...), which is O(m) like on a regular bitmap.
When iterating on a bitmap, each bit (on any level) is only visited
once. Hence, The total cost of visiting a bitmap with m bits in it is
the number of bits that are set in all bitmaps. Unless the bitmap is
extremely sparse, this is also O(m + m/W + m/W^2 + ...), so the amortized
cost of advancing from one bit to the next is usually constant.
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2013-01-21 20:09:40 +04:00
|
|
|
gcov-files-test-hbitmap-y = util/hbitmap.c
|
|
|
|
check-unit-y += tests/test-hbitmap$(EXESUF)
|
2015-11-06 02:13:20 +03:00
|
|
|
gcov-files-test-hbitmap-y = blockjob.c
|
2016-07-29 17:31:41 +03:00
|
|
|
check-unit-y += tests/test-blockjob$(EXESUF)
|
2015-11-06 02:13:20 +03:00
|
|
|
check-unit-y += tests/test-blockjob-txn$(EXESUF)
|
2013-01-23 21:58:27 +04:00
|
|
|
check-unit-y += tests/test-x86-cpuid$(EXESUF)
|
|
|
|
# all code tested by test-x86-cpuid is inside topology.h
|
|
|
|
gcov-files-test-x86-cpuid-y =
|
2014-12-12 14:13:38 +03:00
|
|
|
ifeq ($(CONFIG_SOFTMMU),y)
|
2013-01-31 11:12:16 +04:00
|
|
|
check-unit-y += tests/test-xbzrle$(EXESUF)
|
2014-12-12 14:13:38 +03:00
|
|
|
gcov-files-test-xbzrle-y = migration/xbzrle.c
|
|
|
|
check-unit-$(CONFIG_POSIX) += tests/test-vmstate$(EXESUF)
|
|
|
|
endif
|
2013-02-04 22:27:45 +04:00
|
|
|
check-unit-y += tests/test-cutils$(EXESUF)
|
|
|
|
gcov-files-test-cutils-y += util/cutils.c
|
2017-01-10 05:10:09 +03:00
|
|
|
check-unit-y += tests/test-shift128$(EXESUF)
|
|
|
|
gcov-files-test-shift128-y = util/host-utils.c
|
2013-02-17 00:47:01 +04:00
|
|
|
check-unit-y += tests/test-mul64$(EXESUF)
|
|
|
|
gcov-files-test-mul64-y = util/host-utils.c
|
2013-06-20 18:19:32 +04:00
|
|
|
check-unit-y += tests/test-int128$(EXESUF)
|
|
|
|
# all code tested by test-int128 is inside int128.h
|
|
|
|
gcov-files-test-int128-y =
|
2013-06-21 11:09:34 +04:00
|
|
|
check-unit-y += tests/rcutorture$(EXESUF)
|
|
|
|
gcov-files-rcutorture-y = util/rcu.c
|
2013-08-27 19:38:45 +04:00
|
|
|
check-unit-y += tests/test-rcu-list$(EXESUF)
|
|
|
|
gcov-files-test-rcu-list-y = util/rcu.c
|
2016-06-08 21:55:27 +03:00
|
|
|
check-unit-y += tests/test-qdist$(EXESUF)
|
|
|
|
gcov-files-test-qdist-y = util/qdist.c
|
2016-06-08 21:55:29 +03:00
|
|
|
check-unit-y += tests/test-qht$(EXESUF)
|
|
|
|
gcov-files-test-qht-y = util/qht.c
|
2016-06-08 21:55:31 +03:00
|
|
|
check-unit-y += tests/test-qht-par$(EXESUF)
|
|
|
|
gcov-files-test-qht-par-y = util/qht.c
|
2013-06-28 15:40:32 +04:00
|
|
|
check-unit-y += tests/test-bitops$(EXESUF)
|
2016-12-09 17:36:00 +03:00
|
|
|
check-unit-y += tests/test-bitcnt$(EXESUF)
|
2014-09-18 21:46:45 +04:00
|
|
|
check-unit-$(CONFIG_HAS_GLIB_SUBPROCESS_TESTS) += tests/test-qdev-global-props$(EXESUF)
|
2013-12-21 01:14:40 +04:00
|
|
|
check-unit-y += tests/check-qom-interface$(EXESUF)
|
|
|
|
gcov-files-check-qom-interface-y = qom/object.c
|
qom: Add object_new_with_props() / object_new_withpropv() helpers
It is reasonably common to want to create an object, set a
number of properties, register it in the hierarchy and then
mark it as complete (if a user creatable type). This requires
quite a lot of error prone, verbose, boilerplate code to achieve.
First a pair of functions object_set_props() / object_set_propv()
are added which allow for a list of objects to be set in
one single API call.
Then object_new_with_props() / object_new_with_propv() constructors
are added which simplify the sequence of calls to create an
object, populate properties, register in the object composition
tree and mark the object complete, into a single method call.
Usage would be:
Error *err = NULL;
Object *obj;
obj = object_new_with_propv(TYPE_MEMORY_BACKEND_FILE,
object_get_objects_root(),
"hostmem0",
&err,
"share", "yes",
"mem-path", "/dev/shm/somefile",
"prealloc", "yes",
"size", "1048576",
NULL);
Note all property values are passed in string form and will
be parsed into their required data types, using normal QOM
semantics for parsing from string format.
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Andreas Färber <afaerber@suse.de>
2015-05-13 19:14:06 +03:00
|
|
|
check-unit-y += tests/check-qom-proplist$(EXESUF)
|
|
|
|
gcov-files-check-qom-proplist-y = qom/object.c
|
2014-05-20 01:53:55 +04:00
|
|
|
check-unit-y += tests/test-qemu-opts$(EXESUF)
|
2017-03-01 00:26:48 +03:00
|
|
|
gcov-files-test-qemu-opts-y = util/qemu-option.c
|
keyval: New keyval_parse()
keyval_parse() parses KEY=VALUE,... into a QDict. Works like
qemu_opts_parse(), except:
* Returns a QDict instead of a QemuOpts (d'oh).
* Supports nesting, unlike QemuOpts: a KEY is split into key
fragments at '.' (dotted key convention; the block layer does
something similar on top of QemuOpts). The key fragments are QDict
keys, and the last one's value is updated to VALUE.
* Each key fragment may be up to 127 bytes long. qemu_opts_parse()
limits the entire key to 127 bytes.
* Overlong key fragments are rejected. qemu_opts_parse() silently
truncates them.
* Empty key fragments are rejected. qemu_opts_parse() happily
accepts empty keys.
* It does not store the returned value. qemu_opts_parse() stores it
in the QemuOptsList.
* It does not treat parameter "id" specially. qemu_opts_parse()
ignores all but the first "id", and fails when its value isn't
id_wellformed(), or duplicate (a QemuOpts with the same ID is
already stored). It also screws up when a value contains ",id=".
* Implied value is not supported. qemu_opts_parse() desugars "foo" to
"foo=on", and "nofoo" to "foo=off".
* An implied key's value can't be empty, and can't contain ','.
I intend to grow this into a saner replacement for QemuOpts. It'll
take time, though.
Note: keyval_parse() provides no way to do lists, and its key syntax
is incompatible with the __RFQDN_ prefix convention for downstream
extensions, because it blindly splits at '.', even in __RFQDN_. Both
issues will be addressed later in the series.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1488317230-26248-4-git-send-email-armbru@redhat.com>
2017-03-01 00:26:49 +03:00
|
|
|
check-unit-y += tests/test-keyval$(EXESUF)
|
|
|
|
gcov-files-test-keyval-y = util/keyval.c
|
block: add event when disk usage exceeds threshold
Managing applications, like oVirt (http://www.ovirt.org), make extensive
use of thin-provisioned disk images.
To let the guest run smoothly and be not unnecessarily paused, oVirt sets
a disk usage threshold (so called 'high water mark') based on the occupation
of the device, and automatically extends the image once the threshold
is reached or exceeded.
In order to detect the crossing of the threshold, oVirt has no choice but
aggressively polling the QEMU monitor using the query-blockstats command.
This lead to unnecessary system load, and is made even worse under scale:
deployments with hundreds of VMs are no longer rare.
To fix this, this patch adds:
* A new monitor command `block-set-write-threshold', to set a mark for
a given block device.
* A new event `BLOCK_WRITE_THRESHOLD', to report if a block device
usage exceeds the threshold.
* A new `write_threshold' field into the `BlockDeviceInfo' structure,
to report the configured threshold.
This will allow the managing application to use smarter and more
efficient monitoring, greatly reducing the need of polling.
[Updated qemu-iotests 067 output to add the new 'write_threshold'
property. --Stefan]
[Changed g_assert_false() to !g_assert() to fix the build on older glib
versions. --Kevin]
Signed-off-by: Francesco Romani <fromani@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Message-id: 1421068273-692-1-git-send-email-fromani@redhat.com
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
2015-01-12 16:11:13 +03:00
|
|
|
check-unit-y += tests/test-write-threshold$(EXESUF)
|
|
|
|
gcov-files-test-write-threshold-y = block/write-threshold.c
|
2016-03-11 21:09:22 +03:00
|
|
|
check-unit-y += tests/test-crypto-hash$(EXESUF)
|
2016-12-13 13:43:00 +03:00
|
|
|
check-unit-y += tests/test-crypto-hmac$(EXESUF)
|
2015-07-01 20:10:32 +03:00
|
|
|
check-unit-y += tests/test-crypto-cipher$(EXESUF)
|
crypto: add QCryptoSecret object class for password/key handling
Introduce a new QCryptoSecret object class which will be used
for providing passwords and keys to other objects which need
sensitive credentials.
The new object can provide secret values directly as properties,
or indirectly via a file. The latter includes support for file
descriptor passing syntax on UNIX platforms. Ordinarily passing
secret values directly as properties is insecure, since they
are visible in process listings, or in log files showing the
CLI args / QMP commands. It is possible to use AES-256-CBC to
encrypt the secret values though, in which case all that is
visible is the ciphertext. For ad hoc developer testing though,
it is fine to provide the secrets directly without encryption
so this is not explicitly forbidden.
The anticipated scenario is that libvirtd will create a random
master key per QEMU instance (eg /var/run/libvirt/qemu/$VMNAME.key)
and will use that key to encrypt all passwords it provides to
QEMU via '-object secret,....'. This avoids the need for libvirt
(or other mgmt apps) to worry about file descriptor passing.
It also makes life easier for people who are scripting the
management of QEMU, for whom FD passing is significantly more
complex.
Providing data inline (insecure, only for ad hoc dev testing)
$QEMU -object secret,id=sec0,data=letmein
Providing data indirectly in raw format
printf "letmein" > mypasswd.txt
$QEMU -object secret,id=sec0,file=mypasswd.txt
Providing data indirectly in base64 format
$QEMU -object secret,id=sec0,file=mykey.b64,format=base64
Providing data with encryption
$QEMU -object secret,id=master0,file=mykey.b64,format=base64 \
-object secret,id=sec0,data=[base64 ciphertext],\
keyid=master0,iv=[base64 IV],format=base64
Note that 'format' here refers to the format of the ciphertext
data. The decrypted data must always be in raw byte format.
More examples are shown in the updated docs.
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2015-10-14 11:58:38 +03:00
|
|
|
check-unit-y += tests/test-crypto-secret$(EXESUF)
|
2015-04-13 16:01:39 +03:00
|
|
|
check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlscredsx509$(EXESUF)
|
2015-03-02 20:23:31 +03:00
|
|
|
check-unit-$(CONFIG_GNUTLS) += tests/test-crypto-tlssession$(EXESUF)
|
2016-04-19 10:39:13 +03:00
|
|
|
ifneq (,$(findstring qemu-ga,$(TOOLS)))
|
|
|
|
check-unit-$(CONFIG_LINUX) += tests/test-qga$(EXESUF)
|
|
|
|
endif
|
2015-10-28 18:33:01 +03:00
|
|
|
check-unit-y += tests/test-timed-average$(EXESUF)
|
2015-03-18 20:25:45 +03:00
|
|
|
check-unit-y += tests/test-io-task$(EXESUF)
|
2015-02-27 19:19:33 +03:00
|
|
|
check-unit-y += tests/test-io-channel-socket$(EXESUF)
|
2015-02-27 21:25:25 +03:00
|
|
|
check-unit-y += tests/test-io-channel-file$(EXESUF)
|
2015-03-02 21:13:13 +03:00
|
|
|
check-unit-$(CONFIG_GNUTLS) += tests/test-io-channel-tls$(EXESUF)
|
2015-08-27 18:25:30 +03:00
|
|
|
check-unit-y += tests/test-io-channel-command$(EXESUF)
|
2015-09-15 19:27:33 +03:00
|
|
|
check-unit-y += tests/test-io-channel-buffer$(EXESUF)
|
2015-11-23 18:24:50 +03:00
|
|
|
check-unit-y += tests/test-base64$(EXESUF)
|
2016-04-04 17:08:45 +03:00
|
|
|
check-unit-$(if $(CONFIG_NETTLE_KDF),y,$(CONFIG_GCRYPT_KDF)) += tests/test-crypto-pbkdf$(EXESUF)
|
2015-10-15 14:35:28 +03:00
|
|
|
check-unit-y += tests/test-crypto-ivgen$(EXESUF)
|
2015-10-23 18:14:25 +03:00
|
|
|
check-unit-y += tests/test-crypto-afsplit$(EXESUF)
|
2016-02-11 17:00:17 +03:00
|
|
|
check-unit-y += tests/test-crypto-xts$(EXESUF)
|
2015-10-24 13:44:13 +03:00
|
|
|
check-unit-y += tests/test-crypto-block$(EXESUF)
|
2016-03-15 17:30:20 +03:00
|
|
|
check-unit-y += tests/test-logging$(EXESUF)
|
2017-03-01 00:26:48 +03:00
|
|
|
gcov-files-test-logging-y = util/log.c
|
2016-07-27 10:01:51 +03:00
|
|
|
check-unit-$(CONFIG_REPLICATION) += tests/test-replication$(EXESUF)
|
2016-08-29 21:46:16 +03:00
|
|
|
check-unit-y += tests/test-bufferiszero$(EXESUF)
|
|
|
|
gcov-files-check-bufferiszero-y = util/bufferiszero.c
|
2016-09-21 07:27:24 +03:00
|
|
|
check-unit-y += tests/test-uuid$(EXESUF)
|
2016-10-17 21:22:17 +03:00
|
|
|
check-unit-y += tests/ptimer-test$(EXESUF)
|
|
|
|
gcov-files-ptimer-test-y = hw/core/ptimer.c
|
2017-03-01 00:27:03 +03:00
|
|
|
check-unit-y += tests/test-qapi-util$(EXESUF)
|
|
|
|
gcov-files-test-qapi-util-y = qapi/qapi-util.c
|
2012-03-28 17:42:01 +04:00
|
|
|
|
|
|
|
check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
|
|
|
|
|
2012-03-28 17:42:07 +04:00
|
|
|
# All QTests for now are POSIX-only, but the dependencies are
|
|
|
|
# really in libqtest, not in the testcases themselves.
|
2013-11-07 21:25:10 +04:00
|
|
|
|
2017-03-03 15:32:23 +03:00
|
|
|
check-qtest-generic-y = tests/qmp-test$(EXESUF)
|
|
|
|
gcov-files-generic-y = monitor.c qapi/qmp-dispatch.c
|
|
|
|
check-qtest-generic-y += tests/device-introspect-test$(EXESUF)
|
2015-10-01 11:59:56 +03:00
|
|
|
gcov-files-generic-y = qdev-monitor.c qmp.c
|
tests: Fix how qom-test is run
We want to run qom-test for every architecture, without having to
manually add it to every architecture's list of tests. Commit 3687d53
accomplished this by adding it to every architecture's list
automatically.
However, some architectures inherit their tests from others, like this:
check-qtest-x86_64-y = $(check-qtest-i386-y)
check-qtest-microblazeel-y = $(check-qtest-microblaze-y)
check-qtest-xtensaeb-y = $(check-qtest-xtensa-y)
For such architectures, we ended up running the (slow!) test twice.
Commit 2b8419c attempted to avoid this by adding the test only when
it's not already present. Works only as long as we consider adding
the test to the architectures on the left hand side *after* the ones
on the right hand side: x86_64 after i386, microblazeel after
microblaze, xtensaeb after xtensa.
Turns out we consider them in $(SYSEMU_TARGET_LIST) order. Defined as
SYSEMU_TARGET_LIST := $(subst -softmmu.mak,,$(notdir \
$(wildcard $(SRC_PATH)/default-configs/*-softmmu.mak)))
On my machine, this results in the oder xtensa, x86_64, microblazeel,
microblaze, i386. Consequently, qom-test runs twice for microblazeel
and x86_64.
Replace this complex and flawed machinery with a much simpler one: add
generic tests (currently just qom-test) to check-qtest-generic-y
instead of check-qtest-$(target)-y for every target, then run
$(check-qtest-generic-y) for every target.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Message-Id: <1443689999-12182-5-git-send-email-armbru@redhat.com>
2015-10-01 11:59:53 +03:00
|
|
|
|
2013-08-02 02:48:40 +04:00
|
|
|
gcov-files-ipack-y += hw/ipack/ipack.c
|
2014-02-09 15:24:15 +04:00
|
|
|
check-qtest-ipack-y += tests/ipoctal232-test$(EXESUF)
|
|
|
|
gcov-files-ipack-y += hw/char/ipoctal232.c
|
|
|
|
|
2014-02-21 20:49:12 +04:00
|
|
|
check-qtest-virtioserial-y += tests/virtio-console-test$(EXESUF)
|
|
|
|
gcov-files-virtioserial-y += hw/char/virtio-console.c
|
|
|
|
|
2014-02-09 07:13:37 +04:00
|
|
|
gcov-files-virtio-y += i386-softmmu/hw/virtio/virtio.c
|
|
|
|
check-qtest-virtio-y += tests/virtio-net-test$(EXESUF)
|
|
|
|
gcov-files-virtio-y += i386-softmmu/hw/net/virtio-net.c
|
2014-02-09 07:39:47 +04:00
|
|
|
check-qtest-virtio-y += tests/virtio-balloon-test$(EXESUF)
|
|
|
|
gcov-files-virtio-y += i386-softmmu/hw/virtio/virtio-balloon.c
|
2014-02-09 07:32:55 +04:00
|
|
|
check-qtest-virtio-y += tests/virtio-blk-test$(EXESUF)
|
|
|
|
gcov-files-virtio-y += i386-softmmu/hw/block/virtio-blk.c
|
2014-02-09 07:43:10 +04:00
|
|
|
check-qtest-virtio-y += tests/virtio-rng-test$(EXESUF)
|
|
|
|
gcov-files-virtio-y += hw/virtio/virtio-rng.c
|
2014-02-21 19:42:15 +04:00
|
|
|
check-qtest-virtio-y += tests/virtio-scsi-test$(EXESUF)
|
|
|
|
gcov-files-virtio-y += i386-softmmu/hw/scsi/virtio-scsi.c
|
2014-02-21 20:15:21 +04:00
|
|
|
ifeq ($(CONFIG_VIRTIO)$(CONFIG_VIRTFS)$(CONFIG_PCI),yyy)
|
|
|
|
check-qtest-virtio-y += tests/virtio-9p-test$(EXESUF)
|
|
|
|
gcov-files-virtio-y += hw/9pfs/virtio-9p.c
|
|
|
|
gcov-files-virtio-y += i386-softmmu/hw/9pfs/virtio-9p-device.c
|
|
|
|
endif
|
2014-02-21 20:36:57 +04:00
|
|
|
check-qtest-virtio-y += tests/virtio-serial-test$(EXESUF)
|
|
|
|
gcov-files-virtio-y += i386-softmmu/hw/char/virtio-serial-bus.c
|
2014-02-21 20:49:12 +04:00
|
|
|
check-qtest-virtio-y += $(check-qtest-virtioserial-y)
|
|
|
|
gcov-files-virtio-y += $(gcov-files-virtioserial-y)
|
2014-02-09 07:13:37 +04:00
|
|
|
|
2013-11-07 21:25:10 +04:00
|
|
|
check-qtest-pci-y += tests/e1000-test$(EXESUF)
|
|
|
|
gcov-files-pci-y += hw/net/e1000.c
|
2016-06-01 11:23:46 +03:00
|
|
|
check-qtest-pci-y += tests/e1000e-test$(EXESUF)
|
|
|
|
gcov-files-pci-y += hw/net/e1000e.c hw/net/e1000e_core.c
|
2013-11-07 21:43:09 +04:00
|
|
|
check-qtest-pci-y += tests/rtl8139-test$(EXESUF)
|
|
|
|
gcov-files-pci-y += hw/net/rtl8139.c
|
2013-11-07 21:53:28 +04:00
|
|
|
check-qtest-pci-y += tests/pcnet-test$(EXESUF)
|
|
|
|
gcov-files-pci-y += hw/net/pcnet.c
|
|
|
|
gcov-files-pci-y += hw/net/pcnet-pci.c
|
2013-11-07 22:18:46 +04:00
|
|
|
check-qtest-pci-y += tests/eepro100-test$(EXESUF)
|
|
|
|
gcov-files-pci-y += hw/net/eepro100.c
|
2014-02-09 07:01:37 +04:00
|
|
|
check-qtest-pci-y += tests/ne2000-test$(EXESUF)
|
|
|
|
gcov-files-pci-y += hw/net/ne2000.c
|
2014-02-22 01:19:43 +04:00
|
|
|
check-qtest-pci-y += tests/nvme-test$(EXESUF)
|
|
|
|
gcov-files-pci-y += hw/block/nvme.c
|
2014-03-30 21:00:05 +04:00
|
|
|
check-qtest-pci-y += tests/ac97-test$(EXESUF)
|
|
|
|
gcov-files-pci-y += hw/audio/ac97.c
|
2014-03-30 21:05:20 +04:00
|
|
|
check-qtest-pci-y += tests/es1370-test$(EXESUF)
|
|
|
|
gcov-files-pci-y += hw/audio/es1370.c
|
2014-02-09 07:13:37 +04:00
|
|
|
check-qtest-pci-y += $(check-qtest-virtio-y)
|
|
|
|
gcov-files-pci-y += $(gcov-files-virtio-y) hw/virtio/virtio-pci.c
|
2014-02-09 06:48:44 +04:00
|
|
|
check-qtest-pci-y += tests/tpci200-test$(EXESUF)
|
2014-02-21 19:29:17 +04:00
|
|
|
gcov-files-pci-y += hw/ipack/tpci200.c
|
2014-02-09 15:24:15 +04:00
|
|
|
check-qtest-pci-y += $(check-qtest-ipack-y)
|
2014-02-21 19:29:17 +04:00
|
|
|
gcov-files-pci-y += $(gcov-files-ipack-y)
|
2014-04-28 13:01:13 +04:00
|
|
|
check-qtest-pci-y += tests/display-vga-test$(EXESUF)
|
|
|
|
gcov-files-pci-y += hw/display/vga.c
|
|
|
|
gcov-files-pci-y += hw/display/cirrus_vga.c
|
|
|
|
gcov-files-pci-y += hw/display/vga-pci.c
|
2014-04-28 13:10:12 +04:00
|
|
|
gcov-files-pci-y += hw/display/virtio-gpu.c
|
|
|
|
gcov-files-pci-y += hw/display/virtio-gpu-pci.c
|
|
|
|
gcov-files-pci-$(CONFIG_VIRTIO_VGA) += hw/display/virtio-vga.c
|
2014-03-30 21:22:48 +04:00
|
|
|
check-qtest-pci-y += tests/intel-hda-test$(EXESUF)
|
|
|
|
gcov-files-pci-y += hw/audio/intel-hda.c hw/audio/hda-codec.c
|
2016-03-15 21:34:20 +03:00
|
|
|
check-qtest-pci-$(CONFIG_EVENTFD) += tests/ivshmem-test$(EXESUF)
|
2015-10-11 01:18:32 +03:00
|
|
|
gcov-files-pci-y += hw/misc/ivshmem.c
|
2013-11-07 21:25:10 +04:00
|
|
|
|
2013-07-22 17:54:34 +04:00
|
|
|
check-qtest-i386-y = tests/endianness-test$(EXESUF)
|
|
|
|
check-qtest-i386-y += tests/fdc-test$(EXESUF)
|
2014-02-14 18:09:28 +04:00
|
|
|
gcov-files-i386-y = hw/block/fdc.c
|
2013-05-08 13:18:41 +04:00
|
|
|
check-qtest-i386-y += tests/ide-test$(EXESUF)
|
2014-08-21 21:44:32 +04:00
|
|
|
check-qtest-i386-y += tests/ahci-test$(EXESUF)
|
2012-07-10 13:12:30 +04:00
|
|
|
check-qtest-i386-y += tests/hd-geo-test$(EXESUF)
|
2014-02-14 18:09:28 +04:00
|
|
|
gcov-files-i386-y += hw/block/hd-geometry.c
|
2013-06-26 17:52:13 +04:00
|
|
|
check-qtest-i386-y += tests/boot-order-test$(EXESUF)
|
2014-05-27 23:03:14 +04:00
|
|
|
check-qtest-i386-y += tests/bios-tables-test$(EXESUF)
|
2016-09-03 12:57:51 +03:00
|
|
|
check-qtest-i386-y += tests/boot-serial-test$(EXESUF)
|
2016-02-14 19:59:27 +03:00
|
|
|
check-qtest-i386-y += tests/pxe-test$(EXESUF)
|
2012-05-15 20:19:45 +04:00
|
|
|
check-qtest-i386-y += tests/rtc-test$(EXESUF)
|
2015-12-17 21:50:09 +03:00
|
|
|
check-qtest-i386-y += tests/ipmi-kcs-test$(EXESUF)
|
|
|
|
check-qtest-i386-y += tests/ipmi-bt-test$(EXESUF)
|
2013-04-16 18:45:19 +04:00
|
|
|
check-qtest-i386-y += tests/i440fx-test$(EXESUF)
|
2013-04-16 18:45:21 +04:00
|
|
|
check-qtest-i386-y += tests/fw_cfg-test$(EXESUF)
|
2014-10-02 18:51:31 +04:00
|
|
|
check-qtest-i386-y += tests/drive_del-test$(EXESUF)
|
2014-07-15 16:57:06 +04:00
|
|
|
check-qtest-i386-y += tests/wdt_ib700-test$(EXESUF)
|
2015-07-08 10:06:15 +03:00
|
|
|
check-qtest-i386-y += tests/tco-test$(EXESUF)
|
2014-07-15 16:57:06 +04:00
|
|
|
gcov-files-i386-y += hw/watchdog/watchdog.c hw/watchdog/wdt_ib700.c
|
2013-11-07 21:25:10 +04:00
|
|
|
check-qtest-i386-y += $(check-qtest-pci-y)
|
|
|
|
gcov-files-i386-y += $(gcov-files-pci-y)
|
2013-11-07 21:37:34 +04:00
|
|
|
check-qtest-i386-y += tests/vmxnet3-test$(EXESUF)
|
|
|
|
gcov-files-i386-y += hw/net/vmxnet3.c
|
2016-06-01 11:23:39 +03:00
|
|
|
gcov-files-i386-y += hw/net/net_rx_pkt.c
|
|
|
|
gcov-files-i386-y += hw/net/net_tx_pkt.c
|
2014-02-21 23:38:48 +04:00
|
|
|
check-qtest-i386-y += tests/pvpanic-test$(EXESUF)
|
|
|
|
gcov-files-i386-y += i386-softmmu/hw/misc/pvpanic.c
|
2014-02-22 01:43:43 +04:00
|
|
|
check-qtest-i386-y += tests/i82801b11-test$(EXESUF)
|
|
|
|
gcov-files-i386-y += hw/pci-bridge/i82801b11.c
|
2014-03-30 22:02:00 +04:00
|
|
|
check-qtest-i386-y += tests/ioh3420-test$(EXESUF)
|
|
|
|
gcov-files-i386-y += hw/pci-bridge/ioh3420.c
|
2014-06-23 15:53:51 +04:00
|
|
|
check-qtest-i386-y += tests/usb-hcd-ohci-test$(EXESUF)
|
|
|
|
gcov-files-i386-y += hw/usb/hcd-ohci.c
|
2014-06-23 15:53:52 +04:00
|
|
|
check-qtest-i386-y += tests/usb-hcd-uhci-test$(EXESUF)
|
|
|
|
gcov-files-i386-y += hw/usb/hcd-uhci.c
|
2014-03-30 22:25:38 +04:00
|
|
|
check-qtest-i386-y += tests/usb-hcd-ehci-test$(EXESUF)
|
|
|
|
gcov-files-i386-y += hw/usb/hcd-ehci.c
|
2014-05-07 18:39:11 +04:00
|
|
|
gcov-files-i386-y += hw/usb/dev-hid.c
|
|
|
|
gcov-files-i386-y += hw/usb/dev-storage.c
|
2014-06-23 15:53:53 +04:00
|
|
|
check-qtest-i386-y += tests/usb-hcd-xhci-test$(EXESUF)
|
|
|
|
gcov-files-i386-y += hw/usb/hcd-xhci.c
|
2015-03-13 19:21:11 +03:00
|
|
|
check-qtest-i386-y += tests/pc-cpu-test$(EXESUF)
|
2015-04-14 16:11:36 +03:00
|
|
|
check-qtest-i386-y += tests/q35-test$(EXESUF)
|
|
|
|
gcov-files-i386-y += hw/pci-host/q35.c
|
2015-10-26 17:32:00 +03:00
|
|
|
check-qtest-i386-$(CONFIG_VHOST_NET_TEST_i386) += tests/vhost-user-test$(EXESUF)
|
|
|
|
ifeq ($(CONFIG_VHOST_NET_TEST_i386),)
|
|
|
|
check-qtest-x86_64-$(CONFIG_VHOST_NET_TEST_x86_64) += tests/vhost-user-test$(EXESUF)
|
2015-10-06 12:17:55 +03:00
|
|
|
endif
|
2015-10-07 06:52:22 +03:00
|
|
|
check-qtest-i386-y += tests/test-netfilter$(EXESUF)
|
tests/test-filter-mirror:add filter-mirror unit test
In this unit test we will test the mirror function.
start qemu with:
-netdev socket,id=qtest-bn0,fd=sockfd
-device e1000,netdev=qtest-bn0,id=qtest-e0
-chardev socket,id=mirror0,path=/tmp/filter-mirror-test.sock,server,nowait
-object filter-mirror,id=qtest-f0,netdev=qtest-bn0,queue=tx,outdev=mirror0
We inject packet to netdev socket id = qtest-bn0,
filter-mirror will copy and mirror the packet to mirror0.
we read packet from mirror0 and then compare to what we injected.
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
2016-03-15 10:41:34 +03:00
|
|
|
check-qtest-i386-y += tests/test-filter-mirror$(EXESUF)
|
tests/test-filter-redirector: Add unit test for filter-redirector
In this unit test,we will test the filter redirector function.
Case 1, tx traffic flow:
qemu side | test side
|
+---------+ | +-------+
| backend <---------------+ sock0 |
+----+----+ | +-------+
| |
+----v----+ +-------+ |
| rd0 +->+chardev| |
+---------+ +---+---+ |
| |
+---------+ | |
| rd1 <------+ |
+----+----+ |
| |
+----v----+ | +-------+
| rd2 +--------------->sock1 |
+---------+ | +-------+
+
a. we(sock0) inject packet to qemu socket backend
b. backend pass packet to filter redirector0(rd0)
c. rd0 redirect packet to out_dev(chardev) which is connected with
filter redirector1's(rd1) in_dev
d. rd1 read this packet from in_dev, and pass to next filter redirector2(rd2)
e. rd2 redirect packet to rd2's out_dev which is connected with an opened socketed(sock1)
f. we read packet from sock1 and compare to what we inject
Start qemu with:
"-netdev socket,id=qtest-bn0,fd=%d "
"-device rtl8139,netdev=qtest-bn0,id=qtest-e0 "
"-chardev socket,id=redirector0,path=%s,server,nowait "
"-chardev socket,id=redirector1,path=%s,server,nowait "
"-chardev socket,id=redirector2,path=%s,nowait "
"-object filter-redirector,id=qtest-f0,netdev=qtest-bn0,"
"queue=tx,outdev=redirector0 "
"-object filter-redirector,id=qtest-f1,netdev=qtest-bn0,"
"queue=tx,indev=redirector2 "
"-object filter-redirector,id=qtest-f2,netdev=qtest-bn0,"
"queue=tx,outdev=redirector1 "
--------------------------------------
Case 2, rx traffic flow
qemu side | test side
|
+---------+ | +-------+
| backend +---------------> sock1 |
+----^----+ | +-------+
| |
+----+----+ +-------+ |
| rd0 +<-+chardev| |
+---------+ +---+---+ |
^ |
+---------+ | |
| rd1 +------+ |
+----^----+ |
| |
+----+----+ | +-------+
| rd2 <---------------+sock0 |
+---------+ | +-------+
a. we(sock0) insert packet to filter redirector2(rd2)
b. rd2 pass packet to filter redirector1(rd1)
c. rd1 redirect packet to out_dev(chardev) which is connected with
filter redirector0's(rd0) in_dev
d. rd0 read this packet from in_dev, and pass ti to qemu backend which is
connected with an opened socketed(sock1)
e. we read packet from sock1 and compare to what we inject
Start qemu with:
"-netdev socket,id=qtest-bn0,fd=%d "
"-device rtl8139,netdev=qtest-bn0,id=qtest-e0 "
"-chardev socket,id=redirector0,path=%s,server,nowait "
"-chardev socket,id=redirector1,path=%s,server,nowait "
"-chardev socket,id=redirector2,path=%s,nowait "
"-object filter-redirector,id=qtest-f0,netdev=qtest-bn0,"
"queue=rx,outdev=redirector0 "
"-object filter-redirector,id=qtest-f1,netdev=qtest-bn0,"
"queue=rx,indev=redirector2 "
"-object filter-redirector,id=qtest-f2,netdev=qtest-bn0,"
"queue=rx,outdev=redirector1 "
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
2016-03-17 11:16:27 +03:00
|
|
|
check-qtest-i386-y += tests/test-filter-redirector$(EXESUF)
|
test: Postcopy
This is a postcopy test (x86 only) that actually runs the guest
and checks the memory contents.
The test runs from an x86 boot block with the hex embedded in the test;
the source for this is:
...........
.code16
.org 0x7c00
.file "fill.s"
.text
.globl start
.type start, @function
start: # at 0x7c00 ?
cli
lgdt gdtdesc
mov $1,%eax
mov %eax,%cr0 # Protected mode enable
data32 ljmp $8,$0x7c20
.org 0x7c20
.code32
# A20 enable - not sure I actually need this
inb $0x92,%al
or $2,%al
outb %al, $0x92
# set up DS for the whole of RAM (needed on KVM)
mov $16,%eax
mov %eax,%ds
mov $65,%ax
mov $0x3f8,%dx
outb %al,%dx
# bl keeps a counter so we limit the output speed
mov $0, %bl
mainloop:
# Start from 1MB
mov $(1024*1024),%eax
innerloop:
incb (%eax)
add $4096,%eax
cmp $(100*1024*1024),%eax
jl innerloop
inc %bl
jnz mainloop
mov $66,%ax
mov $0x3f8,%dx
outb %al,%dx
jmp mainloop
# GDT magic from old (GPLv2) Grub startup.S
.p2align 2 /* force 4-byte alignment */
gdt:
.word 0, 0
.byte 0, 0, 0, 0
/* -- code segment --
* base = 0x00000000, limit = 0xFFFFF (4 KiB Granularity), present
* type = 32bit code execute/read, DPL = 0
*/
.word 0xFFFF, 0
.byte 0, 0x9A, 0xCF, 0
/* -- data segment --
* base = 0x00000000, limit 0xFFFFF (4 KiB Granularity), present
* type = 32 bit data read/write, DPL = 0
*/
.word 0xFFFF, 0
.byte 0, 0x92, 0xCF, 0
gdtdesc:
.word 0x27 /* limit */
.long gdt /* addr */
/* I'm a bootable disk */
.org 0x7dfe
.byte 0x55
.byte 0xAA
...........
and that can be assembled by the following magic:
as --32 -march=i486 fill.s -o fill.o
objcopy -O binary fill.o fill.boot
dd if=fill.boot of=bootsect bs=256 count=2 skip=124
xxd -i bootsect
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
Message-id: 1465816605-29488-5-git-send-email-dgilbert@redhat.com
Message-Id: <1465816605-29488-5-git-send-email-dgilbert@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
2016-06-13 14:16:43 +03:00
|
|
|
check-qtest-i386-y += tests/postcopy-test$(EXESUF)
|
2016-09-20 23:11:39 +03:00
|
|
|
check-qtest-i386-y += tests/test-x86-cpuid-compat$(EXESUF)
|
2017-05-03 15:56:55 +03:00
|
|
|
check-qtest-i386-y += tests/numa-test$(EXESUF)
|
2016-06-06 19:45:07 +03:00
|
|
|
check-qtest-x86_64-y += $(check-qtest-i386-y)
|
2014-02-14 18:09:28 +04:00
|
|
|
gcov-files-i386-y += i386-softmmu/hw/timer/mc146818rtc.c
|
2013-01-26 15:45:14 +04:00
|
|
|
gcov-files-x86_64-y = $(subst i386-softmmu/,x86_64-softmmu/,$(gcov-files-i386-y))
|
2016-09-03 12:57:50 +03:00
|
|
|
|
2016-09-03 12:57:51 +03:00
|
|
|
check-qtest-alpha-y = tests/boot-serial-test$(EXESUF)
|
|
|
|
|
2013-07-22 17:54:34 +04:00
|
|
|
check-qtest-mips-y = tests/endianness-test$(EXESUF)
|
2016-09-03 12:57:50 +03:00
|
|
|
|
2013-07-22 17:54:34 +04:00
|
|
|
check-qtest-mips64-y = tests/endianness-test$(EXESUF)
|
2016-09-03 12:57:50 +03:00
|
|
|
|
2013-07-22 17:54:34 +04:00
|
|
|
check-qtest-mips64el-y = tests/endianness-test$(EXESUF)
|
2016-09-03 12:57:50 +03:00
|
|
|
|
2013-07-22 17:54:34 +04:00
|
|
|
check-qtest-ppc-y = tests/endianness-test$(EXESUF)
|
2016-09-03 12:57:50 +03:00
|
|
|
check-qtest-ppc-y += tests/boot-order-test$(EXESUF)
|
|
|
|
check-qtest-ppc-y += tests/prom-env-test$(EXESUF)
|
|
|
|
check-qtest-ppc-y += tests/drive_del-test$(EXESUF)
|
2016-09-03 12:57:51 +03:00
|
|
|
check-qtest-ppc-y += tests/boot-serial-test$(EXESUF)
|
2016-09-03 12:57:50 +03:00
|
|
|
|
|
|
|
check-qtest-ppc64-y = tests/spapr-phb-test$(EXESUF)
|
|
|
|
gcov-files-ppc64-y = ppc64-softmmu/hw/ppc/spapr_pci.c
|
|
|
|
check-qtest-ppc64-y += tests/endianness-test$(EXESUF)
|
|
|
|
check-qtest-ppc64-y += tests/boot-order-test$(EXESUF)
|
|
|
|
check-qtest-ppc64-y += tests/prom-env-test$(EXESUF)
|
2016-11-15 02:09:46 +03:00
|
|
|
check-qtest-ppc64-y += tests/pnv-xscom-test$(EXESUF)
|
2016-09-03 12:57:50 +03:00
|
|
|
check-qtest-ppc64-y += tests/drive_del-test$(EXESUF)
|
|
|
|
check-qtest-ppc64-y += tests/postcopy-test$(EXESUF)
|
2016-09-03 12:57:51 +03:00
|
|
|
check-qtest-ppc64-y += tests/boot-serial-test$(EXESUF)
|
2016-09-13 15:52:45 +03:00
|
|
|
check-qtest-ppc64-y += tests/rtas-test$(EXESUF)
|
2016-09-26 23:17:46 +03:00
|
|
|
check-qtest-ppc64-y += tests/pxe-test$(EXESUF)
|
2016-09-29 13:32:47 +03:00
|
|
|
check-qtest-ppc64-y += tests/usb-hcd-ohci-test$(EXESUF)
|
|
|
|
gcov-files-ppc64-y += hw/usb/hcd-ohci.c
|
|
|
|
check-qtest-ppc64-y += tests/usb-hcd-uhci-test$(EXESUF)
|
|
|
|
gcov-files-ppc64-y += hw/usb/hcd-uhci.c
|
|
|
|
check-qtest-ppc64-y += tests/usb-hcd-xhci-test$(EXESUF)
|
|
|
|
gcov-files-ppc64-y += hw/usb/hcd-xhci.c
|
2016-10-17 13:30:24 +03:00
|
|
|
check-qtest-ppc64-y += $(check-qtest-virtio-y)
|
2017-01-05 18:29:44 +03:00
|
|
|
check-qtest-ppc64-y += tests/test-netfilter$(EXESUF)
|
|
|
|
check-qtest-ppc64-y += tests/test-filter-mirror$(EXESUF)
|
|
|
|
check-qtest-ppc64-y += tests/test-filter-redirector$(EXESUF)
|
2017-01-05 18:29:45 +03:00
|
|
|
check-qtest-ppc64-y += tests/display-vga-test$(EXESUF)
|
2017-05-03 15:56:55 +03:00
|
|
|
check-qtest-ppc64-y += tests/numa-test$(EXESUF)
|
2017-01-05 18:29:48 +03:00
|
|
|
check-qtest-ppc64-$(CONFIG_EVENTFD) += tests/ivshmem-test$(EXESUF)
|
2016-09-03 12:57:50 +03:00
|
|
|
|
2013-07-22 17:54:34 +04:00
|
|
|
check-qtest-sh4-y = tests/endianness-test$(EXESUF)
|
2016-09-03 12:57:50 +03:00
|
|
|
|
2013-07-22 17:54:34 +04:00
|
|
|
check-qtest-sh4eb-y = tests/endianness-test$(EXESUF)
|
2016-09-03 12:57:50 +03:00
|
|
|
|
|
|
|
check-qtest-sparc-y = tests/prom-env-test$(EXESUF)
|
|
|
|
#check-qtest-sparc-y += tests/m48t59-test$(EXESUF)
|
|
|
|
#gcov-files-sparc-y = hw/timer/m48t59.c
|
|
|
|
|
2013-07-22 17:54:34 +04:00
|
|
|
check-qtest-sparc64-y = tests/endianness-test$(EXESUF)
|
|
|
|
#check-qtest-sparc64-y += tests/m48t59-test$(EXESUF)
|
2016-09-03 12:57:50 +03:00
|
|
|
#gcov-files-sparc64-y += hw/timer/m48t59.c
|
2017-02-10 21:22:57 +03:00
|
|
|
check-qtest-sparc64-y += tests/prom-env-test$(EXESUF)
|
2016-09-03 12:57:50 +03:00
|
|
|
|
2013-01-16 04:57:57 +04:00
|
|
|
check-qtest-arm-y = tests/tmp105-test$(EXESUF)
|
2016-06-27 17:37:32 +03:00
|
|
|
check-qtest-arm-y += tests/ds1338-test$(EXESUF)
|
2016-10-17 21:22:17 +03:00
|
|
|
check-qtest-arm-y += tests/m25p80-test$(EXESUF)
|
2014-02-14 18:09:28 +04:00
|
|
|
gcov-files-arm-y += hw/misc/tmp105.c
|
2015-02-25 00:21:55 +03:00
|
|
|
check-qtest-arm-y += tests/virtio-blk-test$(EXESUF)
|
|
|
|
gcov-files-arm-y += arm-softmmu/hw/block/virtio-blk.c
|
2016-10-24 18:26:54 +03:00
|
|
|
check-qtest-arm-y += tests/test-arm-mptimer$(EXESUF)
|
|
|
|
gcov-files-arm-y += hw/timer/arm_mptimer.c
|
2016-09-03 12:57:50 +03:00
|
|
|
|
2017-05-03 15:56:55 +03:00
|
|
|
check-qtest-aarch64-y = tests/numa-test$(EXESUF)
|
|
|
|
|
2013-07-29 07:44:47 +04:00
|
|
|
check-qtest-microblazeel-y = $(check-qtest-microblaze-y)
|
2016-09-03 12:57:50 +03:00
|
|
|
|
2013-07-29 07:44:47 +04:00
|
|
|
check-qtest-xtensaeb-y = $(check-qtest-xtensa-y)
|
2012-03-28 17:42:07 +04:00
|
|
|
|
2016-09-03 12:57:51 +03:00
|
|
|
check-qtest-s390x-y = tests/boot-serial-test$(EXESUF)
|
|
|
|
|
tests: Fix how qom-test is run
We want to run qom-test for every architecture, without having to
manually add it to every architecture's list of tests. Commit 3687d53
accomplished this by adding it to every architecture's list
automatically.
However, some architectures inherit their tests from others, like this:
check-qtest-x86_64-y = $(check-qtest-i386-y)
check-qtest-microblazeel-y = $(check-qtest-microblaze-y)
check-qtest-xtensaeb-y = $(check-qtest-xtensa-y)
For such architectures, we ended up running the (slow!) test twice.
Commit 2b8419c attempted to avoid this by adding the test only when
it's not already present. Works only as long as we consider adding
the test to the architectures on the left hand side *after* the ones
on the right hand side: x86_64 after i386, microblazeel after
microblaze, xtensaeb after xtensa.
Turns out we consider them in $(SYSEMU_TARGET_LIST) order. Defined as
SYSEMU_TARGET_LIST := $(subst -softmmu.mak,,$(notdir \
$(wildcard $(SRC_PATH)/default-configs/*-softmmu.mak)))
On my machine, this results in the oder xtensa, x86_64, microblazeel,
microblaze, i386. Consequently, qom-test runs twice for microblazeel
and x86_64.
Replace this complex and flawed machinery with a much simpler one: add
generic tests (currently just qom-test) to check-qtest-generic-y
instead of check-qtest-$(target)-y for every target, then run
$(check-qtest-generic-y) for every target.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Message-Id: <1443689999-12182-5-git-send-email-armbru@redhat.com>
2015-10-01 11:59:53 +03:00
|
|
|
check-qtest-generic-y += tests/qom-test$(EXESUF)
|
2017-04-25 08:16:47 +03:00
|
|
|
check-qtest-generic-y += tests/test-hmp$(EXESUF)
|
2014-01-23 20:22:59 +04:00
|
|
|
|
2016-02-18 09:48:17 +03:00
|
|
|
qapi-schema += alternate-any.json
|
2015-09-30 01:20:59 +03:00
|
|
|
qapi-schema += alternate-array.json
|
|
|
|
qapi-schema += alternate-base.json
|
|
|
|
qapi-schema += alternate-clash.json
|
|
|
|
qapi-schema += alternate-conflict-dict.json
|
qapi: Reject alternates that can't work with keyval_parse()
Alternates are sum types like unions, but use the JSON type on the
wire / QType in QObject instead of an explicit tag. That's why we
require alternate members to have distinct QTypes.
The recently introduced keyval_parse() (commit d454dbe) can only
produce string scalars. The qobject_input_visitor_new_keyval() input
visitor mostly hides the difference, so code using a QObject input
visitor doesn't have to care whether its input was parsed from JSON or
KEY=VALUE,... The difference leaks for alternates, as noted in commit
0ee9ae7: a non-string, non-enum scalar alternate value can't currently
be expressed.
In part, this is just our insufficiently sophisticated implementation.
Consider alternate type 'GuestFileWhence'. It has an integer member
and a 'QGASeek' member. The latter is an enumeration with values
'set', 'cur', 'end'. The meaning of b=set, b=cur, b=end, b=0, b=1 and
so forth is perfectly obvious. However, our current implementation
falls apart at run time for b=0, b=1, and so forth. Fixable, but not
today; add a test case and a TODO comment.
Now consider an alternate type with a string and an integer member.
What's the meaning of a=42? Is it the string "42" or the integer 42?
Whichever meaning you pick makes the other inexpressible. This isn't
just an implementation problem, it's fundamental. Our current
implementation will pick string.
So far, we haven't needed such alternates. To make sure we stop and
think before we add one that cannot sanely work with keyval_parse(),
let's require alternate members to have sufficiently distinct
representation in KEY=VALUE,... syntax:
* A string member clashes with any other scalar member
* An enumeration member clashes with bool members when it has value
'on' or 'off'.
* An enumeration member clashes with numeric members when it has a
value that starts with '-', '+', or a decimal digit. This is a
rather lazy approximation of the actual number syntax accepted by
the visitor.
Note that enumeration values starting with '-' and '+' are rejected
elsewhere already, but better safe than sorry.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Message-Id: <1495471335-23707-5-git-send-email-armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
2017-05-22 19:42:15 +03:00
|
|
|
qapi-schema += alternate-conflict-enum-bool.json
|
|
|
|
qapi-schema += alternate-conflict-enum-int.json
|
2015-09-30 01:20:59 +03:00
|
|
|
qapi-schema += alternate-conflict-string.json
|
qapi: Add tests for empty unions
The documentation claims that alternates are useful for
allowing two or more types, although nothing enforces this.
Meanwhile, it is silent on whether empty unions are allowed.
In practice, the generated code will compile, in part because
we have a 'void *data' branch; but attempting to visit such a
type will cause an abort(). While there's no technical reason
that a degenerate union could not be made to work, it's harder
to justify the time spent in chasing known (the current
abort() during visit) and unknown corner cases, than it would
be to just outlaw them. A future patch will probably take the
approach of forbidding them; in the meantime, we can at least
add testsuite coverage to make it obvious where things stand.
In addition to adding tests to expose the problems, we also
need to adjust existing tests that are meant to test something
else, but which could fail for the wrong reason if we reject
degenerate alternates/unions.
Note that empty structs are explicitly supported (for example,
right now they are the only way to specify that one branch of a
flat union adds no additional members), and empty enums are
covered by the testsuite as working (even if they do not seem
to have much use).
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1443565276-4535-8-git-send-email-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-09-30 01:21:05 +03:00
|
|
|
qapi-schema += alternate-empty.json
|
2015-09-30 01:20:59 +03:00
|
|
|
qapi-schema += alternate-nested.json
|
|
|
|
qapi-schema += alternate-unknown.json
|
|
|
|
qapi-schema += args-alternate.json
|
|
|
|
qapi-schema += args-any.json
|
|
|
|
qapi-schema += args-array-empty.json
|
|
|
|
qapi-schema += args-array-unknown.json
|
2016-07-14 06:50:20 +03:00
|
|
|
qapi-schema += args-bad-boxed.json
|
|
|
|
qapi-schema += args-boxed-anon.json
|
|
|
|
qapi-schema += args-boxed-empty.json
|
|
|
|
qapi-schema += args-boxed-string.json
|
2015-09-30 01:20:59 +03:00
|
|
|
qapi-schema += args-int.json
|
|
|
|
qapi-schema += args-invalid.json
|
|
|
|
qapi-schema += args-member-array-bad.json
|
qapi: Enforce (or whitelist) case conventions on qapi members
We document that members of enums and objects should be
'lower-case', although we were not enforcing it. We have to
whitelist a few pre-existing entities that violate the norms.
Add three new tests to expose the new error message, each of
which first uses the whitelisted name 'UuidInfo' to prove the
whitelist works, then triggers the failure (this is the same
pattern used in the existing returns-whitelist.json test).
Note that by adding this check, we have effectively forbidden
an entity with a case-insensitive clash of member names, for
any entity that is not on the whitelist (although there is
still the possibility to clash via '-' vs. '_').
Not done here: a future patch should also add naming convention
support and whitelist exceptions for command, event, and type
names.
The additions to QAPISchemaMember.check_clash() check whether
info['name'] is in the whitelist (the top-most entity name at
the point 'info' tracks), rather than self.owner (the type,
possibly implicit, that directly owns the member), because it
is easier to maintain the whitelist by the names actually in
the user's .json file, rather than worrying about the names
of implicit types.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1449033659-25497-14-git-send-email-eblake@redhat.com>
[Simplified a bit as per discussion with Eric]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-12-02 08:20:57 +03:00
|
|
|
qapi-schema += args-member-case.json
|
2015-09-30 01:20:59 +03:00
|
|
|
qapi-schema += args-member-unknown.json
|
qapi: Test for various name collisions
Expose some weaknesses in the generator: we don't always forbid
the generation of structs that contain multiple members that map
to the same C or QMP name. This has already been marked FIXME in
qapi.py in commit d90675f, but having more tests will make sure
future patches produce desired behavior; and updating existing
patches to better document things doesn't hurt, either. Some of
these collisions are already caught in the old-style parser
checks, but ultimately we want all collisions to be caught in the
new-style QAPISchema*.check() methods.
This patch focuses on C struct members, and does not consider
collisions between commands and events (affecting C function
names), or even collisions between generated C type names with
user type names (for things like automatic FOOList struct
representing array types or FOOKind for an implicit enum).
There are two types of struct collisions we want to catch:
1) Collision between two keys in a JSON object. qapi.py prevents
that within a single struct (see test duplicate-key), but it is
possible to have collisions between a type's members and its
base type's members (existing tests struct-base-clash,
struct-base-clash-deep), and its flat union variant members
(renamed test flat-union-clash-member).
2) Collision between two members of the C struct that is generated
for a given QAPI type:
a) Multiple QAPI names map to the same C name (new test
args-name-clash)
b) A QAPI name maps to a C name that is used for another purpose
(new tests flat-union-clash-branch, struct-base-clash-base,
union-clash-data). We already fixed some such cases in commit
0f61af3e and 1e6c1616, but more remain.
c) Two C names generated for other purposes clash
(updated test alternate-clash, new test union-clash-branches,
union-clash-type, flat-union-clash-type)
Ultimately, if we need to have a flat union where a tag value
clashes with a base member name, we could change the generator to
name the union (using 'foo.u.value' rather than 'foo.value') or
otherwise munge the C name corresponding to tag values. But
unless such a need arises, it will probably be easier to just
forbid these collisions.
Some of these negative tests will be deleted later, and positive
tests added to qapi-schema-test.json in their place, when the
generator code is reworked to avoid particular code generation
collisions in class 2).
[Note that viewing this patch with git rename detection enabled
may see some confusion due to renaming some tests while adding
others, but where the content is similar enough that git picks
the wrong pre- and post-patch files to associate]
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1443565276-4535-6-git-send-email-eblake@redhat.com>
[Improve commit message and comments a bit, drop an unrelated test]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-09-30 01:21:03 +03:00
|
|
|
qapi-schema += args-name-clash.json
|
2015-09-30 01:20:59 +03:00
|
|
|
qapi-schema += args-union.json
|
|
|
|
qapi-schema += args-unknown.json
|
|
|
|
qapi-schema += bad-base.json
|
|
|
|
qapi-schema += bad-data.json
|
|
|
|
qapi-schema += bad-ident.json
|
|
|
|
qapi-schema += bad-type-bool.json
|
|
|
|
qapi-schema += bad-type-dict.json
|
|
|
|
qapi-schema += bad-type-int.json
|
qapi: Detect base class loops
It should be fairly obvious that qapi base classes need to
form an acyclic graph, since QMP cannot specify the same
key more than once, while base classes are included as flat
members alongside other members added by the child. But the
old check_member_clash() parser function was not prepared to
check for this, and entered an infinite recursion (at least
until Python gives up, complaining about nesting too deep).
Now that check_member_clash() has been recently removed,
attempts at self-inheritance trigger an assertion failure
introduced by commit ac88219a. The obvious fix is to turn
the assertion into a conditional.
This patch includes both the tests (base-cycle-direct and
base-cycle-indirect) and the fix, since the .err file output
for the unfixed case is not useful (particularly when it was
warning about unbounded recursion, as that limit may be
platform-specific).
We don't need to worry about cycles in flat unions (neither
the base type nor the type of a variant can be a union) nor
in alternates (alternate branches cannot themselves be an
alternate). But if we later allow a union type as a variant,
we will still be okay, as QAPISchemaObjectTypeVariants.check()
triggers the same QAPISchemaObjectType.check() that will
detect any loops.
Likewise, we need not worry about the case of diamond
inheritance where the same class is used for a flat union base
class and one of its variants; either both uses will introduce
a collision in trying to insert the same member name twice, or
the shared type is empty and changes nothing.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1449033659-25497-16-git-send-email-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-12-02 08:20:59 +03:00
|
|
|
qapi-schema += base-cycle-direct.json
|
|
|
|
qapi-schema += base-cycle-indirect.json
|
2015-09-30 01:20:59 +03:00
|
|
|
qapi-schema += command-int.json
|
|
|
|
qapi-schema += comments.json
|
2017-03-15 15:57:25 +03:00
|
|
|
qapi-schema += doc-bad-alternate-member.json
|
2017-03-15 15:57:24 +03:00
|
|
|
qapi-schema += doc-bad-command-arg.json
|
qapi: add qapi2texi script
As the name suggests, the qapi2texi script converts JSON QAPI
description into a texi file suitable for different target
formats (info/man/txt/pdf/html...).
It parses the following kind of blocks:
Free-form:
##
# = Section
# == Subsection
#
# Some text foo with *emphasis*
# 1. with a list
# 2. like that
#
# And some code:
# | $ echo foo
# | -> do this
# | <- get that
#
##
Symbol description:
##
# @symbol:
#
# Symbol body ditto ergo sum. Foo bar
# baz ding.
#
# @param1: the frob to frobnicate
# @param2: #optional how hard to frobnicate
#
# Returns: the frobnicated frob.
# If frob isn't frobnicatable, GenericError.
#
# Since: version
# Notes: notes, comments can have
# - itemized list
# - like this
#
# Example:
#
# -> { "execute": "quit" }
# <- { "return": {} }
#
##
That's roughly following the following EBNF grammar:
api_comment = "##\n" comment "##\n"
comment = freeform_comment | symbol_comment
freeform_comment = { "# " text "\n" | "#\n" }
symbol_comment = "# @" name ":\n" { member | tag_section | freeform_comment }
member = "# @" name ':' [ text ] "\n" freeform_comment
tag_section = "# " ( "Returns:", "Since:", "Note:", "Notes:", "Example:", "Examples:" ) [ text ] "\n" freeform_comment
text = free text with markup
Note that the grammar is ambiguous: a line "# @foo:\n" can be parsed
both as freeform_comment and as symbol_comment. The actual parser
recognizes symbol_comment.
See docs/qapi-code-gen.txt for more details.
Deficiencies and limitations:
- the generated QMP documentation includes internal types
- union type support is lacking
- type information is lacking in generated documentation
- doc comment error message positions are imprecise, they point
to the beginning of the comment.
- a few minor issues, all marked TODO/FIXME in the code
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20170113144135.5150-16-marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[test-qapi.py tweaked to avoid trailing empty lines in .out]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-01-13 17:41:29 +03:00
|
|
|
qapi-schema += doc-bad-symbol.json
|
2017-03-15 15:57:25 +03:00
|
|
|
qapi-schema += doc-bad-union-member.json
|
2017-03-15 15:57:19 +03:00
|
|
|
qapi-schema += doc-before-include.json
|
|
|
|
qapi-schema += doc-before-pragma.json
|
qapi: add qapi2texi script
As the name suggests, the qapi2texi script converts JSON QAPI
description into a texi file suitable for different target
formats (info/man/txt/pdf/html...).
It parses the following kind of blocks:
Free-form:
##
# = Section
# == Subsection
#
# Some text foo with *emphasis*
# 1. with a list
# 2. like that
#
# And some code:
# | $ echo foo
# | -> do this
# | <- get that
#
##
Symbol description:
##
# @symbol:
#
# Symbol body ditto ergo sum. Foo bar
# baz ding.
#
# @param1: the frob to frobnicate
# @param2: #optional how hard to frobnicate
#
# Returns: the frobnicated frob.
# If frob isn't frobnicatable, GenericError.
#
# Since: version
# Notes: notes, comments can have
# - itemized list
# - like this
#
# Example:
#
# -> { "execute": "quit" }
# <- { "return": {} }
#
##
That's roughly following the following EBNF grammar:
api_comment = "##\n" comment "##\n"
comment = freeform_comment | symbol_comment
freeform_comment = { "# " text "\n" | "#\n" }
symbol_comment = "# @" name ":\n" { member | tag_section | freeform_comment }
member = "# @" name ':' [ text ] "\n" freeform_comment
tag_section = "# " ( "Returns:", "Since:", "Note:", "Notes:", "Example:", "Examples:" ) [ text ] "\n" freeform_comment
text = free text with markup
Note that the grammar is ambiguous: a line "# @foo:\n" can be parsed
both as freeform_comment and as symbol_comment. The actual parser
recognizes symbol_comment.
See docs/qapi-code-gen.txt for more details.
Deficiencies and limitations:
- the generated QMP documentation includes internal types
- union type support is lacking
- type information is lacking in generated documentation
- doc comment error message positions are imprecise, they point
to the beginning of the comment.
- a few minor issues, all marked TODO/FIXME in the code
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20170113144135.5150-16-marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[test-qapi.py tweaked to avoid trailing empty lines in .out]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-01-13 17:41:29 +03:00
|
|
|
qapi-schema += doc-duplicated-arg.json
|
|
|
|
qapi-schema += doc-duplicated-return.json
|
|
|
|
qapi-schema += doc-duplicated-since.json
|
|
|
|
qapi-schema += doc-empty-arg.json
|
|
|
|
qapi-schema += doc-empty-section.json
|
|
|
|
qapi-schema += doc-empty-symbol.json
|
2017-03-20 16:11:54 +03:00
|
|
|
qapi-schema += doc-good.json
|
qapi: add qapi2texi script
As the name suggests, the qapi2texi script converts JSON QAPI
description into a texi file suitable for different target
formats (info/man/txt/pdf/html...).
It parses the following kind of blocks:
Free-form:
##
# = Section
# == Subsection
#
# Some text foo with *emphasis*
# 1. with a list
# 2. like that
#
# And some code:
# | $ echo foo
# | -> do this
# | <- get that
#
##
Symbol description:
##
# @symbol:
#
# Symbol body ditto ergo sum. Foo bar
# baz ding.
#
# @param1: the frob to frobnicate
# @param2: #optional how hard to frobnicate
#
# Returns: the frobnicated frob.
# If frob isn't frobnicatable, GenericError.
#
# Since: version
# Notes: notes, comments can have
# - itemized list
# - like this
#
# Example:
#
# -> { "execute": "quit" }
# <- { "return": {} }
#
##
That's roughly following the following EBNF grammar:
api_comment = "##\n" comment "##\n"
comment = freeform_comment | symbol_comment
freeform_comment = { "# " text "\n" | "#\n" }
symbol_comment = "# @" name ":\n" { member | tag_section | freeform_comment }
member = "# @" name ':' [ text ] "\n" freeform_comment
tag_section = "# " ( "Returns:", "Since:", "Note:", "Notes:", "Example:", "Examples:" ) [ text ] "\n" freeform_comment
text = free text with markup
Note that the grammar is ambiguous: a line "# @foo:\n" can be parsed
both as freeform_comment and as symbol_comment. The actual parser
recognizes symbol_comment.
See docs/qapi-code-gen.txt for more details.
Deficiencies and limitations:
- the generated QMP documentation includes internal types
- union type support is lacking
- type information is lacking in generated documentation
- doc comment error message positions are imprecise, they point
to the beginning of the comment.
- a few minor issues, all marked TODO/FIXME in the code
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20170113144135.5150-16-marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[test-qapi.py tweaked to avoid trailing empty lines in .out]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-01-13 17:41:29 +03:00
|
|
|
qapi-schema += doc-interleaved-section.json
|
|
|
|
qapi-schema += doc-invalid-end.json
|
|
|
|
qapi-schema += doc-invalid-end2.json
|
|
|
|
qapi-schema += doc-invalid-return.json
|
|
|
|
qapi-schema += doc-invalid-section.json
|
|
|
|
qapi-schema += doc-invalid-start.json
|
2017-03-15 15:56:51 +03:00
|
|
|
qapi-schema += doc-missing.json
|
qapi: add qapi2texi script
As the name suggests, the qapi2texi script converts JSON QAPI
description into a texi file suitable for different target
formats (info/man/txt/pdf/html...).
It parses the following kind of blocks:
Free-form:
##
# = Section
# == Subsection
#
# Some text foo with *emphasis*
# 1. with a list
# 2. like that
#
# And some code:
# | $ echo foo
# | -> do this
# | <- get that
#
##
Symbol description:
##
# @symbol:
#
# Symbol body ditto ergo sum. Foo bar
# baz ding.
#
# @param1: the frob to frobnicate
# @param2: #optional how hard to frobnicate
#
# Returns: the frobnicated frob.
# If frob isn't frobnicatable, GenericError.
#
# Since: version
# Notes: notes, comments can have
# - itemized list
# - like this
#
# Example:
#
# -> { "execute": "quit" }
# <- { "return": {} }
#
##
That's roughly following the following EBNF grammar:
api_comment = "##\n" comment "##\n"
comment = freeform_comment | symbol_comment
freeform_comment = { "# " text "\n" | "#\n" }
symbol_comment = "# @" name ":\n" { member | tag_section | freeform_comment }
member = "# @" name ':' [ text ] "\n" freeform_comment
tag_section = "# " ( "Returns:", "Since:", "Note:", "Notes:", "Example:", "Examples:" ) [ text ] "\n" freeform_comment
text = free text with markup
Note that the grammar is ambiguous: a line "# @foo:\n" can be parsed
both as freeform_comment and as symbol_comment. The actual parser
recognizes symbol_comment.
See docs/qapi-code-gen.txt for more details.
Deficiencies and limitations:
- the generated QMP documentation includes internal types
- union type support is lacking
- type information is lacking in generated documentation
- doc comment error message positions are imprecise, they point
to the beginning of the comment.
- a few minor issues, all marked TODO/FIXME in the code
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20170113144135.5150-16-marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[test-qapi.py tweaked to avoid trailing empty lines in .out]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-01-13 17:41:29 +03:00
|
|
|
qapi-schema += doc-missing-colon.json
|
|
|
|
qapi-schema += doc-missing-expr.json
|
|
|
|
qapi-schema += doc-missing-space.json
|
2017-03-15 15:57:19 +03:00
|
|
|
qapi-schema += doc-no-symbol.json
|
2015-09-30 01:20:59 +03:00
|
|
|
qapi-schema += double-data.json
|
|
|
|
qapi-schema += double-type.json
|
|
|
|
qapi-schema += duplicate-key.json
|
|
|
|
qapi-schema += empty.json
|
|
|
|
qapi-schema += enum-bad-name.json
|
|
|
|
qapi-schema += enum-bad-prefix.json
|
|
|
|
qapi-schema += enum-clash-member.json
|
|
|
|
qapi-schema += enum-dict-member.json
|
|
|
|
qapi-schema += enum-int-member.json
|
qapi: Enforce (or whitelist) case conventions on qapi members
We document that members of enums and objects should be
'lower-case', although we were not enforcing it. We have to
whitelist a few pre-existing entities that violate the norms.
Add three new tests to expose the new error message, each of
which first uses the whitelisted name 'UuidInfo' to prove the
whitelist works, then triggers the failure (this is the same
pattern used in the existing returns-whitelist.json test).
Note that by adding this check, we have effectively forbidden
an entity with a case-insensitive clash of member names, for
any entity that is not on the whitelist (although there is
still the possibility to clash via '-' vs. '_').
Not done here: a future patch should also add naming convention
support and whitelist exceptions for command, event, and type
names.
The additions to QAPISchemaMember.check_clash() check whether
info['name'] is in the whitelist (the top-most entity name at
the point 'info' tracks), rather than self.owner (the type,
possibly implicit, that directly owns the member), because it
is easier to maintain the whitelist by the names actually in
the user's .json file, rather than worrying about the names
of implicit types.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1449033659-25497-14-git-send-email-eblake@redhat.com>
[Simplified a bit as per discussion with Eric]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-12-02 08:20:57 +03:00
|
|
|
qapi-schema += enum-member-case.json
|
2015-09-30 01:20:59 +03:00
|
|
|
qapi-schema += enum-missing-data.json
|
|
|
|
qapi-schema += enum-wrong-data.json
|
|
|
|
qapi-schema += escape-outside-string.json
|
|
|
|
qapi-schema += escape-too-big.json
|
|
|
|
qapi-schema += escape-too-short.json
|
2016-07-14 06:50:20 +03:00
|
|
|
qapi-schema += event-boxed-empty.json
|
2015-09-30 01:20:59 +03:00
|
|
|
qapi-schema += event-case.json
|
|
|
|
qapi-schema += event-nest-struct.json
|
|
|
|
qapi-schema += flat-union-array-branch.json
|
|
|
|
qapi-schema += flat-union-bad-base.json
|
|
|
|
qapi-schema += flat-union-bad-discriminator.json
|
|
|
|
qapi-schema += flat-union-base-any.json
|
|
|
|
qapi-schema += flat-union-base-union.json
|
qapi: Test for various name collisions
Expose some weaknesses in the generator: we don't always forbid
the generation of structs that contain multiple members that map
to the same C or QMP name. This has already been marked FIXME in
qapi.py in commit d90675f, but having more tests will make sure
future patches produce desired behavior; and updating existing
patches to better document things doesn't hurt, either. Some of
these collisions are already caught in the old-style parser
checks, but ultimately we want all collisions to be caught in the
new-style QAPISchema*.check() methods.
This patch focuses on C struct members, and does not consider
collisions between commands and events (affecting C function
names), or even collisions between generated C type names with
user type names (for things like automatic FOOList struct
representing array types or FOOKind for an implicit enum).
There are two types of struct collisions we want to catch:
1) Collision between two keys in a JSON object. qapi.py prevents
that within a single struct (see test duplicate-key), but it is
possible to have collisions between a type's members and its
base type's members (existing tests struct-base-clash,
struct-base-clash-deep), and its flat union variant members
(renamed test flat-union-clash-member).
2) Collision between two members of the C struct that is generated
for a given QAPI type:
a) Multiple QAPI names map to the same C name (new test
args-name-clash)
b) A QAPI name maps to a C name that is used for another purpose
(new tests flat-union-clash-branch, struct-base-clash-base,
union-clash-data). We already fixed some such cases in commit
0f61af3e and 1e6c1616, but more remain.
c) Two C names generated for other purposes clash
(updated test alternate-clash, new test union-clash-branches,
union-clash-type, flat-union-clash-type)
Ultimately, if we need to have a flat union where a tag value
clashes with a base member name, we could change the generator to
name the union (using 'foo.u.value' rather than 'foo.value') or
otherwise munge the C name corresponding to tag values. But
unless such a need arises, it will probably be easier to just
forbid these collisions.
Some of these negative tests will be deleted later, and positive
tests added to qapi-schema-test.json in their place, when the
generator code is reworked to avoid particular code generation
collisions in class 2).
[Note that viewing this patch with git rename detection enabled
may see some confusion due to renaming some tests while adding
others, but where the content is similar enough that git picks
the wrong pre- and post-patch files to associate]
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1443565276-4535-6-git-send-email-eblake@redhat.com>
[Improve commit message and comments a bit, drop an unrelated test]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-09-30 01:21:03 +03:00
|
|
|
qapi-schema += flat-union-clash-member.json
|
qapi: Add tests for empty unions
The documentation claims that alternates are useful for
allowing two or more types, although nothing enforces this.
Meanwhile, it is silent on whether empty unions are allowed.
In practice, the generated code will compile, in part because
we have a 'void *data' branch; but attempting to visit such a
type will cause an abort(). While there's no technical reason
that a degenerate union could not be made to work, it's harder
to justify the time spent in chasing known (the current
abort() during visit) and unknown corner cases, than it would
be to just outlaw them. A future patch will probably take the
approach of forbidding them; in the meantime, we can at least
add testsuite coverage to make it obvious where things stand.
In addition to adding tests to expose the problems, we also
need to adjust existing tests that are meant to test something
else, but which could fail for the wrong reason if we reject
degenerate alternates/unions.
Note that empty structs are explicitly supported (for example,
right now they are the only way to specify that one branch of a
flat union adds no additional members), and empty enums are
covered by the testsuite as working (even if they do not seem
to have much use).
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1443565276-4535-8-git-send-email-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-09-30 01:21:05 +03:00
|
|
|
qapi-schema += flat-union-empty.json
|
2016-07-14 06:50:13 +03:00
|
|
|
qapi-schema += flat-union-incomplete-branch.json
|
2015-09-30 01:20:59 +03:00
|
|
|
qapi-schema += flat-union-inline.json
|
|
|
|
qapi-schema += flat-union-int-branch.json
|
|
|
|
qapi-schema += flat-union-invalid-branch-key.json
|
|
|
|
qapi-schema += flat-union-invalid-discriminator.json
|
|
|
|
qapi-schema += flat-union-no-base.json
|
|
|
|
qapi-schema += flat-union-optional-discriminator.json
|
|
|
|
qapi-schema += flat-union-string-discriminator.json
|
|
|
|
qapi-schema += funny-char.json
|
|
|
|
qapi-schema += ident-with-escape.json
|
|
|
|
qapi-schema += include-before-err.json
|
|
|
|
qapi-schema += include-cycle.json
|
2017-03-15 15:56:51 +03:00
|
|
|
qapi-schema += include-extra-junk.json
|
2015-09-30 01:20:59 +03:00
|
|
|
qapi-schema += include-format-err.json
|
|
|
|
qapi-schema += include-nested-err.json
|
|
|
|
qapi-schema += include-no-file.json
|
|
|
|
qapi-schema += include-non-file.json
|
|
|
|
qapi-schema += include-relpath.json
|
|
|
|
qapi-schema += include-repetition.json
|
|
|
|
qapi-schema += include-self-cycle.json
|
|
|
|
qapi-schema += include-simple.json
|
|
|
|
qapi-schema += indented-expr.json
|
|
|
|
qapi-schema += leading-comma-list.json
|
|
|
|
qapi-schema += leading-comma-object.json
|
|
|
|
qapi-schema += missing-colon.json
|
|
|
|
qapi-schema += missing-comma-list.json
|
|
|
|
qapi-schema += missing-comma-object.json
|
|
|
|
qapi-schema += missing-type.json
|
|
|
|
qapi-schema += nested-struct-data.json
|
|
|
|
qapi-schema += non-objects.json
|
2017-03-15 15:56:51 +03:00
|
|
|
qapi-schema += pragma-doc-required-crap.json
|
|
|
|
qapi-schema += pragma-extra-junk.json
|
2017-03-15 15:56:55 +03:00
|
|
|
qapi-schema += pragma-name-case-whitelist-crap.json
|
2017-03-15 15:56:51 +03:00
|
|
|
qapi-schema += pragma-non-dict.json
|
2017-03-15 15:56:54 +03:00
|
|
|
qapi-schema += pragma-returns-whitelist-crap.json
|
2015-09-30 01:20:59 +03:00
|
|
|
qapi-schema += qapi-schema-test.json
|
|
|
|
qapi-schema += quoted-structural-chars.json
|
|
|
|
qapi-schema += redefined-builtin.json
|
|
|
|
qapi-schema += redefined-command.json
|
|
|
|
qapi-schema += redefined-event.json
|
|
|
|
qapi-schema += redefined-type.json
|
tests/qapi-schema: Test for reserved names, empty struct
Add some testsuite coverage to ensure future patches are on
the right track:
Our current C representation of qapi arrays is done by appending
'List' to the element name; but we are not preventing the
creation of an object type with the same name. Add
reserved-type-list.json to test this. Then rename
enum-union-clash.json to reserved-type-kind.json to cover the
reservation that we DO detect, and shorten it to match the fact
that the name is reserved even if there is no clash.
We are failing to detect a collision between a dictionary member
and the implicit 'has_*' flag for another optional member. The
easiest fix would be for a future patch to reserve the entire
"has[-_]" namespace for member names (the collision is also
possible for branch names within flat unions, but only as long as
branch names can collide with (non-variant) members; however,
since future patches are about to remove that, it is not worth
testing here). Add reserved-member-has.json to test this.
A similar collision exists between a dictionary member where
c_name() munges what might otherwise be a reserved name to start
with 'q_', and another member explicitly starts with "q[-_]".
Again, the easiest solution for a future patch will be reserving
the entire namespace, but here for commands as well as members.
Add reserved-member-q.json and reserved-command-q.json to test
this; separate tests since arguably our munging of command 'unix'
to 'qmp_q_unix()' could be done without a q_, which is different
than the munging of a member 'unix' to 'foo.q_unix'.
Finally, our testsuite does not have any compilation coverage
of struct inheritance with empty qapi structs. Update
qapi-schema-test.json to test this.
Note that there is currently no technical reason to forbid type
name patterns from member names, or member name patterns from
types, since the two are not in the same namespace in C and
won't collide; but it's not worth adding positive tests of these
corner cases at this time, especially while there is other churn
pending in patches that rearrange which collisions actually
happen.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1445898903-12082-2-git-send-email-eblake@redhat.com>
[Commit message tweaked slightly]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-10-27 01:34:40 +03:00
|
|
|
qapi-schema += reserved-command-q.json
|
2015-11-18 11:52:56 +03:00
|
|
|
qapi-schema += reserved-enum-q.json
|
tests/qapi-schema: Test for reserved names, empty struct
Add some testsuite coverage to ensure future patches are on
the right track:
Our current C representation of qapi arrays is done by appending
'List' to the element name; but we are not preventing the
creation of an object type with the same name. Add
reserved-type-list.json to test this. Then rename
enum-union-clash.json to reserved-type-kind.json to cover the
reservation that we DO detect, and shorten it to match the fact
that the name is reserved even if there is no clash.
We are failing to detect a collision between a dictionary member
and the implicit 'has_*' flag for another optional member. The
easiest fix would be for a future patch to reserve the entire
"has[-_]" namespace for member names (the collision is also
possible for branch names within flat unions, but only as long as
branch names can collide with (non-variant) members; however,
since future patches are about to remove that, it is not worth
testing here). Add reserved-member-has.json to test this.
A similar collision exists between a dictionary member where
c_name() munges what might otherwise be a reserved name to start
with 'q_', and another member explicitly starts with "q[-_]".
Again, the easiest solution for a future patch will be reserving
the entire namespace, but here for commands as well as members.
Add reserved-member-q.json and reserved-command-q.json to test
this; separate tests since arguably our munging of command 'unix'
to 'qmp_q_unix()' could be done without a q_, which is different
than the munging of a member 'unix' to 'foo.q_unix'.
Finally, our testsuite does not have any compilation coverage
of struct inheritance with empty qapi structs. Update
qapi-schema-test.json to test this.
Note that there is currently no technical reason to forbid type
name patterns from member names, or member name patterns from
types, since the two are not in the same namespace in C and
won't collide; but it's not worth adding positive tests of these
corner cases at this time, especially while there is other churn
pending in patches that rearrange which collisions actually
happen.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1445898903-12082-2-git-send-email-eblake@redhat.com>
[Commit message tweaked slightly]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-10-27 01:34:40 +03:00
|
|
|
qapi-schema += reserved-member-has.json
|
|
|
|
qapi-schema += reserved-member-q.json
|
2015-10-27 01:35:02 +03:00
|
|
|
qapi-schema += reserved-member-u.json
|
2015-11-18 11:52:56 +03:00
|
|
|
qapi-schema += reserved-member-underscore.json
|
tests/qapi-schema: Test for reserved names, empty struct
Add some testsuite coverage to ensure future patches are on
the right track:
Our current C representation of qapi arrays is done by appending
'List' to the element name; but we are not preventing the
creation of an object type with the same name. Add
reserved-type-list.json to test this. Then rename
enum-union-clash.json to reserved-type-kind.json to cover the
reservation that we DO detect, and shorten it to match the fact
that the name is reserved even if there is no clash.
We are failing to detect a collision between a dictionary member
and the implicit 'has_*' flag for another optional member. The
easiest fix would be for a future patch to reserve the entire
"has[-_]" namespace for member names (the collision is also
possible for branch names within flat unions, but only as long as
branch names can collide with (non-variant) members; however,
since future patches are about to remove that, it is not worth
testing here). Add reserved-member-has.json to test this.
A similar collision exists between a dictionary member where
c_name() munges what might otherwise be a reserved name to start
with 'q_', and another member explicitly starts with "q[-_]".
Again, the easiest solution for a future patch will be reserving
the entire namespace, but here for commands as well as members.
Add reserved-member-q.json and reserved-command-q.json to test
this; separate tests since arguably our munging of command 'unix'
to 'qmp_q_unix()' could be done without a q_, which is different
than the munging of a member 'unix' to 'foo.q_unix'.
Finally, our testsuite does not have any compilation coverage
of struct inheritance with empty qapi structs. Update
qapi-schema-test.json to test this.
Note that there is currently no technical reason to forbid type
name patterns from member names, or member name patterns from
types, since the two are not in the same namespace in C and
won't collide; but it's not worth adding positive tests of these
corner cases at this time, especially while there is other churn
pending in patches that rearrange which collisions actually
happen.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1445898903-12082-2-git-send-email-eblake@redhat.com>
[Commit message tweaked slightly]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-10-27 01:34:40 +03:00
|
|
|
qapi-schema += reserved-type-kind.json
|
|
|
|
qapi-schema += reserved-type-list.json
|
2015-09-30 01:20:59 +03:00
|
|
|
qapi-schema += returns-alternate.json
|
|
|
|
qapi-schema += returns-array-bad.json
|
|
|
|
qapi-schema += returns-dict.json
|
|
|
|
qapi-schema += returns-unknown.json
|
|
|
|
qapi-schema += returns-whitelist.json
|
|
|
|
qapi-schema += struct-base-clash-deep.json
|
|
|
|
qapi-schema += struct-base-clash.json
|
|
|
|
qapi-schema += struct-data-invalid.json
|
|
|
|
qapi-schema += struct-member-invalid.json
|
|
|
|
qapi-schema += trailing-comma-list.json
|
|
|
|
qapi-schema += trailing-comma-object.json
|
|
|
|
qapi-schema += type-bypass-bad-gen.json
|
|
|
|
qapi-schema += unclosed-list.json
|
|
|
|
qapi-schema += unclosed-object.json
|
|
|
|
qapi-schema += unclosed-string.json
|
|
|
|
qapi-schema += unicode-str.json
|
2017-03-15 15:56:57 +03:00
|
|
|
qapi-schema += union-base-empty.json
|
2015-09-30 01:20:59 +03:00
|
|
|
qapi-schema += union-base-no-discriminator.json
|
qapi: Enforce (or whitelist) case conventions on qapi members
We document that members of enums and objects should be
'lower-case', although we were not enforcing it. We have to
whitelist a few pre-existing entities that violate the norms.
Add three new tests to expose the new error message, each of
which first uses the whitelisted name 'UuidInfo' to prove the
whitelist works, then triggers the failure (this is the same
pattern used in the existing returns-whitelist.json test).
Note that by adding this check, we have effectively forbidden
an entity with a case-insensitive clash of member names, for
any entity that is not on the whitelist (although there is
still the possibility to clash via '-' vs. '_').
Not done here: a future patch should also add naming convention
support and whitelist exceptions for command, event, and type
names.
The additions to QAPISchemaMember.check_clash() check whether
info['name'] is in the whitelist (the top-most entity name at
the point 'info' tracks), rather than self.owner (the type,
possibly implicit, that directly owns the member), because it
is easier to maintain the whitelist by the names actually in
the user's .json file, rather than worrying about the names
of implicit types.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1449033659-25497-14-git-send-email-eblake@redhat.com>
[Simplified a bit as per discussion with Eric]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-12-02 08:20:57 +03:00
|
|
|
qapi-schema += union-branch-case.json
|
qapi: Test for various name collisions
Expose some weaknesses in the generator: we don't always forbid
the generation of structs that contain multiple members that map
to the same C or QMP name. This has already been marked FIXME in
qapi.py in commit d90675f, but having more tests will make sure
future patches produce desired behavior; and updating existing
patches to better document things doesn't hurt, either. Some of
these collisions are already caught in the old-style parser
checks, but ultimately we want all collisions to be caught in the
new-style QAPISchema*.check() methods.
This patch focuses on C struct members, and does not consider
collisions between commands and events (affecting C function
names), or even collisions between generated C type names with
user type names (for things like automatic FOOList struct
representing array types or FOOKind for an implicit enum).
There are two types of struct collisions we want to catch:
1) Collision between two keys in a JSON object. qapi.py prevents
that within a single struct (see test duplicate-key), but it is
possible to have collisions between a type's members and its
base type's members (existing tests struct-base-clash,
struct-base-clash-deep), and its flat union variant members
(renamed test flat-union-clash-member).
2) Collision between two members of the C struct that is generated
for a given QAPI type:
a) Multiple QAPI names map to the same C name (new test
args-name-clash)
b) A QAPI name maps to a C name that is used for another purpose
(new tests flat-union-clash-branch, struct-base-clash-base,
union-clash-data). We already fixed some such cases in commit
0f61af3e and 1e6c1616, but more remain.
c) Two C names generated for other purposes clash
(updated test alternate-clash, new test union-clash-branches,
union-clash-type, flat-union-clash-type)
Ultimately, if we need to have a flat union where a tag value
clashes with a base member name, we could change the generator to
name the union (using 'foo.u.value' rather than 'foo.value') or
otherwise munge the C name corresponding to tag values. But
unless such a need arises, it will probably be easier to just
forbid these collisions.
Some of these negative tests will be deleted later, and positive
tests added to qapi-schema-test.json in their place, when the
generator code is reworked to avoid particular code generation
collisions in class 2).
[Note that viewing this patch with git rename detection enabled
may see some confusion due to renaming some tests while adding
others, but where the content is similar enough that git picks
the wrong pre- and post-patch files to associate]
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1443565276-4535-6-git-send-email-eblake@redhat.com>
[Improve commit message and comments a bit, drop an unrelated test]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-09-30 01:21:03 +03:00
|
|
|
qapi-schema += union-clash-branches.json
|
qapi: Add tests for empty unions
The documentation claims that alternates are useful for
allowing two or more types, although nothing enforces this.
Meanwhile, it is silent on whether empty unions are allowed.
In practice, the generated code will compile, in part because
we have a 'void *data' branch; but attempting to visit such a
type will cause an abort(). While there's no technical reason
that a degenerate union could not be made to work, it's harder
to justify the time spent in chasing known (the current
abort() during visit) and unknown corner cases, than it would
be to just outlaw them. A future patch will probably take the
approach of forbidding them; in the meantime, we can at least
add testsuite coverage to make it obvious where things stand.
In addition to adding tests to expose the problems, we also
need to adjust existing tests that are meant to test something
else, but which could fail for the wrong reason if we reject
degenerate alternates/unions.
Note that empty structs are explicitly supported (for example,
right now they are the only way to specify that one branch of a
flat union adds no additional members), and empty enums are
covered by the testsuite as working (even if they do not seem
to have much use).
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1443565276-4535-8-git-send-email-eblake@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2015-09-30 01:21:05 +03:00
|
|
|
qapi-schema += union-empty.json
|
2015-09-30 01:20:59 +03:00
|
|
|
qapi-schema += union-invalid-base.json
|
|
|
|
qapi-schema += union-optional-branch.json
|
|
|
|
qapi-schema += union-unknown.json
|
|
|
|
qapi-schema += unknown-escape.json
|
|
|
|
qapi-schema += unknown-expr-key.json
|
qapi: add qapi2texi script
As the name suggests, the qapi2texi script converts JSON QAPI
description into a texi file suitable for different target
formats (info/man/txt/pdf/html...).
It parses the following kind of blocks:
Free-form:
##
# = Section
# == Subsection
#
# Some text foo with *emphasis*
# 1. with a list
# 2. like that
#
# And some code:
# | $ echo foo
# | -> do this
# | <- get that
#
##
Symbol description:
##
# @symbol:
#
# Symbol body ditto ergo sum. Foo bar
# baz ding.
#
# @param1: the frob to frobnicate
# @param2: #optional how hard to frobnicate
#
# Returns: the frobnicated frob.
# If frob isn't frobnicatable, GenericError.
#
# Since: version
# Notes: notes, comments can have
# - itemized list
# - like this
#
# Example:
#
# -> { "execute": "quit" }
# <- { "return": {} }
#
##
That's roughly following the following EBNF grammar:
api_comment = "##\n" comment "##\n"
comment = freeform_comment | symbol_comment
freeform_comment = { "# " text "\n" | "#\n" }
symbol_comment = "# @" name ":\n" { member | tag_section | freeform_comment }
member = "# @" name ':' [ text ] "\n" freeform_comment
tag_section = "# " ( "Returns:", "Since:", "Note:", "Notes:", "Example:", "Examples:" ) [ text ] "\n" freeform_comment
text = free text with markup
Note that the grammar is ambiguous: a line "# @foo:\n" can be parsed
both as freeform_comment and as symbol_comment. The actual parser
recognizes symbol_comment.
See docs/qapi-code-gen.txt for more details.
Deficiencies and limitations:
- the generated QMP documentation includes internal types
- union type support is lacking
- type information is lacking in generated documentation
- doc comment error message positions are imprecise, they point
to the beginning of the comment.
- a few minor issues, all marked TODO/FIXME in the code
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-Id: <20170113144135.5150-16-marcandre.lureau@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
[test-qapi.py tweaked to avoid trailing empty lines in .out]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2017-01-13 17:41:29 +03:00
|
|
|
|
|
|
|
|
2015-09-30 01:20:59 +03:00
|
|
|
check-qapi-schema-y := $(addprefix tests/qapi-schema/, $(qapi-schema))
|
2013-07-27 19:41:53 +04:00
|
|
|
|
2017-02-28 15:29:00 +03:00
|
|
|
GENERATED_FILES += tests/test-qapi-types.h tests/test-qapi-visit.h \
|
qapi: New QMP command query-qmp-schema for QMP introspection
qapi/introspect.json defines the introspection schema. It's designed
for QMP introspection, but should do for similar uses, such as QGA.
The introspection schema does not reflect all the rules and
restrictions that apply to QAPI schemata. A valid QAPI schema has an
introspection value conforming to the introspection schema, but the
converse is not true.
Introspection lowers away a number of schema details, and makes
implicit things explicit:
* The built-in types are declared with their JSON type.
All integer types are mapped to 'int', because how many bits we use
internally is an implementation detail. It could be pressed into
external interface service as very approximate range information,
but that's a bad idea. If we need range information, we better do
it properly.
* Implicit type definitions are made explicit, and given
auto-generated names:
- Array types, named by appending "List" to the name of their
element type, like in generated C.
- The enumeration types implicitly defined by simple union types,
named by appending "Kind" to the name of their simple union type,
like in generated C.
- Types that don't occur in generated C. Their names start with ':'
so they don't clash with the user's names.
* All type references are by name.
* The struct and union types are generalized into an object type.
* Base types are flattened.
* Commands take a single argument and return a single result.
Dictionary argument or list result is an implicit type definition.
The empty object type is used when a command takes no arguments or
produces no results.
The argument is always of object type, but the introspection schema
doesn't reflect that.
The 'gen': false directive is omitted as implementation detail.
The 'success-response' directive is omitted as well for now, even
though it's not an implementation detail, because it's not used by
QMP.
* Events carry a single data value.
Implicit type definition and empty object type use, just like for
commands.
The value is of object type, but the introspection schema doesn't
reflect that.
* Types not used by commands or events are omitted.
Indirect use counts as use.
* Optional members have a default, which can only be null right now
Instead of a mandatory "optional" flag, we have an optional default.
No default means mandatory, default null means optional without
default value. Non-null is available for optional with default
(possible future extension).
* Clients should *not* look up types by name, because type names are
not ABI. Look up the command or event you're interested in, then
follow the references.
TODO Should we hide the type names to eliminate the temptation?
New generator scripts/qapi-introspect.py computes an introspection
value for its input, and generates a C variable holding it.
It can generate awfully long lines. Marked TODO.
A new test-qmp-input-visitor test case feeds its result for both
tests/qapi-schema/qapi-schema-test.json and qapi-schema.json to a
QmpInputVisitor to verify it actually conforms to the schema.
New QMP command query-qmp-schema takes its return value from that
variable. Its reply is some 85KiBytes for me right now.
If this turns out to be too much, we have a couple of options:
* We can use shorter names in the JSON. Not the QMP style.
* Optionally return the sub-schema for commands and events given as
arguments.
Right now qmp_query_schema() sends the string literal computed by
qmp-introspect.py. To compute sub-schema at run time, we'd have to
duplicate parts of qapi-introspect.py in C. Unattractive.
* Let clients cache the output of query-qmp-schema.
It changes only on QEMU upgrades, i.e. rarely. Provide a command
query-qmp-schema-hash. Clients can have a cache indexed by hash,
and re-query the schema only when they don't have it cached. Even
simpler: put the hash in the QMP greeting.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
2015-09-16 14:06:28 +03:00
|
|
|
tests/test-qmp-commands.h tests/test-qapi-event.h \
|
|
|
|
tests/test-qmp-introspect.h
|
2012-03-28 17:42:01 +04:00
|
|
|
|
|
|
|
test-obj-y = tests/check-qint.o tests/check-qstring.o tests/check-qdict.o \
|
2016-04-29 00:45:21 +03:00
|
|
|
tests/check-qlist.o tests/check-qfloat.o tests/check-qnull.o \
|
|
|
|
tests/check-qjson.o \
|
2012-03-28 17:42:01 +04:00
|
|
|
tests/test-coroutine.o tests/test-string-output-visitor.o \
|
2016-09-30 17:45:27 +03:00
|
|
|
tests/test-string-input-visitor.o tests/test-qobject-output-visitor.o \
|
qapi: Add new clone visitor
We have a couple places in the code base that want to deep-clone
one QAPI object into another, and they were resorting to serializing
the struct out to QObject then reparsing it. A much more efficient
version can be done by adding a new clone visitor.
Since cloning is still relatively uncommon, expose the use of the
new visitor via a QAPI_CLONE() macro that takes care of type-punning
the underlying function pointer, rather than generating lots of
unused functions for types that won't be cloned. And yes, we're
relying on the compiler treating all pointers equally, even though
a strict C program cannot portably do so - but we're not the first
one in the qemu code base to expect it to work (hello, glib!).
The choice of adding a fourth visitor type deserves some explanation.
On the surface, the clone visitor is mostly an input visitor (it
takes arbitrary input - in this case, another QAPI object - and
creates a new QAPI object during the course of the visit). But
ever since commit da72ab0 consolidated enum visits based on the
visitor type, using VISITOR_INPUT would cause us to run
visit_type_str(), even though for cloning there is nothing to do
(we just copy the enum value across, without regards to its mapping
to strings). Also, since our input happens to be a QAPI object,
we can also satisfy the internal checks for VISITOR_OUTPUT. So in
the end, I settled with a new VISITOR_CLONE, and chose its value
such that many internal checks can use 'v->type & mask', sticking
to 'v->type == value' where the difference matters.
Note that we can only clone objects (including alternates) and lists,
not built-ins or enums. The visitor core hides integer width from
the actual visitor (since commit 04e070d), and as long as that's the
case, we can't clone top-level integers. Then again, those can
always be cloned by direct copy, since they are not objects with
deep pointers, so it's no real loss. And restricting cloning to
just objects and lists is cleaner than restricting it to non-integers.
As such, I documented that the clone visitor is for direct use only
by code internal to QAPI, and should not be used on incomplete objects
(other than a hack to work around the fact that we allow NULL in place
of "" in visit_type_str() in other output visitors). Note that as
written, the clone visitor will never fail on a complete object.
Scalars (including enums) not at the root of the clone copy just fine
with no additional effort while visiting the scalar, by virtue of a
g_memdup() each time we push another struct onto the stack. Cloning
a string requires deduplication of a pointer, which means it can also
provide the guarantee of an input visitor of never producing NULL
even when still accepting NULL in place of "" the way the QMP output
visitor does.
Cloning an 'any' type could be possible by incrementing the QObject
refcnt, but it's not obvious whether that is better than implementing
a QObject deep clone. So for now, we document it as unsupported,
and intentionally omit the .type_any() callback to let a developer
know their usage needs implementation.
Add testsuite coverage for several different clone situations, to
ensure that the code is working. I also tested that valgrind was
happy with the test.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1465490926-28625-14-git-send-email-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2016-06-09 19:48:44 +03:00
|
|
|
tests/test-clone-visitor.o \
|
2017-03-03 15:32:40 +03:00
|
|
|
tests/test-qobject-input-visitor.o \
|
2013-01-23 21:58:27 +04:00
|
|
|
tests/test-qmp-commands.o tests/test-visitor-serialization.o \
|
2013-08-20 02:35:40 +04:00
|
|
|
tests/test-x86-cpuid.o tests/test-mul64.o tests/test-int128.o \
|
2013-06-21 11:09:34 +04:00
|
|
|
tests/test-opts-visitor.o tests/test-qmp-event.o \
|
2016-06-08 21:55:27 +03:00
|
|
|
tests/rcutorture.o tests/test-rcu-list.o \
|
2017-01-10 05:10:09 +03:00
|
|
|
tests/test-qdist.o tests/test-shift128.o \
|
2016-06-27 22:02:05 +03:00
|
|
|
tests/test-qht.o tests/qht-bench.o tests/test-qht-par.o \
|
|
|
|
tests/atomic_add-bench.o
|
2012-03-28 17:42:01 +04:00
|
|
|
|
|
|
|
$(test-obj-y): QEMU_INCLUDES += -Itests
|
2013-04-16 18:45:16 +04:00
|
|
|
QEMU_CFLAGS += -I$(SRC_PATH)/tests
|
2012-03-28 17:42:01 +04:00
|
|
|
|
2015-09-02 13:35:52 +03:00
|
|
|
|
|
|
|
# Deps that are common to various different sets of tests below
|
2017-04-05 00:39:39 +03:00
|
|
|
test-util-obj-y = libqemuutil.a libqemustub.a
|
2015-09-02 13:18:16 +03:00
|
|
|
test-qom-obj-y = $(qom-obj-y) $(test-util-obj-y)
|
2015-09-02 13:35:52 +03:00
|
|
|
test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o \
|
qapi: New QMP command query-qmp-schema for QMP introspection
qapi/introspect.json defines the introspection schema. It's designed
for QMP introspection, but should do for similar uses, such as QGA.
The introspection schema does not reflect all the rules and
restrictions that apply to QAPI schemata. A valid QAPI schema has an
introspection value conforming to the introspection schema, but the
converse is not true.
Introspection lowers away a number of schema details, and makes
implicit things explicit:
* The built-in types are declared with their JSON type.
All integer types are mapped to 'int', because how many bits we use
internally is an implementation detail. It could be pressed into
external interface service as very approximate range information,
but that's a bad idea. If we need range information, we better do
it properly.
* Implicit type definitions are made explicit, and given
auto-generated names:
- Array types, named by appending "List" to the name of their
element type, like in generated C.
- The enumeration types implicitly defined by simple union types,
named by appending "Kind" to the name of their simple union type,
like in generated C.
- Types that don't occur in generated C. Their names start with ':'
so they don't clash with the user's names.
* All type references are by name.
* The struct and union types are generalized into an object type.
* Base types are flattened.
* Commands take a single argument and return a single result.
Dictionary argument or list result is an implicit type definition.
The empty object type is used when a command takes no arguments or
produces no results.
The argument is always of object type, but the introspection schema
doesn't reflect that.
The 'gen': false directive is omitted as implementation detail.
The 'success-response' directive is omitted as well for now, even
though it's not an implementation detail, because it's not used by
QMP.
* Events carry a single data value.
Implicit type definition and empty object type use, just like for
commands.
The value is of object type, but the introspection schema doesn't
reflect that.
* Types not used by commands or events are omitted.
Indirect use counts as use.
* Optional members have a default, which can only be null right now
Instead of a mandatory "optional" flag, we have an optional default.
No default means mandatory, default null means optional without
default value. Non-null is available for optional with default
(possible future extension).
* Clients should *not* look up types by name, because type names are
not ABI. Look up the command or event you're interested in, then
follow the references.
TODO Should we hide the type names to eliminate the temptation?
New generator scripts/qapi-introspect.py computes an introspection
value for its input, and generates a C variable holding it.
It can generate awfully long lines. Marked TODO.
A new test-qmp-input-visitor test case feeds its result for both
tests/qapi-schema/qapi-schema-test.json and qapi-schema.json to a
QmpInputVisitor to verify it actually conforms to the schema.
New QMP command query-qmp-schema takes its return value from that
variable. Its reply is some 85KiBytes for me right now.
If this turns out to be too much, we have a couple of options:
* We can use shorter names in the JSON. Not the QMP style.
* Optionally return the sub-schema for commands and events given as
arguments.
Right now qmp_query_schema() sends the string literal computed by
qmp-introspect.py. To compute sub-schema at run time, we'd have to
duplicate parts of qapi-introspect.py in C. Unattractive.
* Let clients cache the output of query-qmp-schema.
It changes only on QEMU upgrades, i.e. rarely. Provide a command
query-qmp-schema-hash. Clients can have a cache indexed by hash,
and re-query the schema only when they don't have it cached. Even
simpler: put the hash in the QMP greeting.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
2015-09-16 14:06:28 +03:00
|
|
|
tests/test-qapi-event.o tests/test-qmp-introspect.o \
|
2015-09-02 13:35:52 +03:00
|
|
|
$(test-qom-obj-y)
|
2015-03-13 20:39:26 +03:00
|
|
|
test-crypto-obj-y = $(crypto-obj-y) $(test-qom-obj-y)
|
2015-03-18 20:25:45 +03:00
|
|
|
test-io-obj-y = $(io-obj-y) $(test-crypto-obj-y)
|
2017-02-13 16:52:19 +03:00
|
|
|
test-block-obj-y = $(block-obj-y) $(test-io-obj-y) tests/iothread.o
|
2015-09-02 13:35:52 +03:00
|
|
|
|
|
|
|
tests/check-qint$(EXESUF): tests/check-qint.o $(test-util-obj-y)
|
|
|
|
tests/check-qstring$(EXESUF): tests/check-qstring.o $(test-util-obj-y)
|
|
|
|
tests/check-qdict$(EXESUF): tests/check-qdict.o $(test-util-obj-y)
|
|
|
|
tests/check-qlist$(EXESUF): tests/check-qlist.o $(test-util-obj-y)
|
|
|
|
tests/check-qfloat$(EXESUF): tests/check-qfloat.o $(test-util-obj-y)
|
2016-04-29 00:45:21 +03:00
|
|
|
tests/check-qnull$(EXESUF): tests/check-qnull.o $(test-util-obj-y)
|
2015-09-02 13:35:52 +03:00
|
|
|
tests/check-qjson$(EXESUF): tests/check-qjson.o $(test-util-obj-y)
|
|
|
|
tests/check-qom-interface$(EXESUF): tests/check-qom-interface.o $(test-qom-obj-y)
|
|
|
|
tests/check-qom-proplist$(EXESUF): tests/check-qom-proplist.o $(test-qom-obj-y)
|
2016-10-22 12:53:00 +03:00
|
|
|
|
2017-02-13 16:52:18 +03:00
|
|
|
tests/test-char$(EXESUF): tests/test-char.o $(test-util-obj-y) $(qtest-obj-y) $(test-io-obj-y) $(chardev-obj-y)
|
2015-09-02 13:35:52 +03:00
|
|
|
tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(test-block-obj-y)
|
|
|
|
tests/test-aio$(EXESUF): tests/test-aio.o $(test-block-obj-y)
|
2017-02-13 16:52:19 +03:00
|
|
|
tests/test-aio-multithread$(EXESUF): tests/test-aio-multithread.o $(test-block-obj-y)
|
2015-09-02 13:35:52 +03:00
|
|
|
tests/test-throttle$(EXESUF): tests/test-throttle.o $(test-block-obj-y)
|
2016-07-29 17:31:41 +03:00
|
|
|
tests/test-blockjob$(EXESUF): tests/test-blockjob.o $(test-block-obj-y) $(test-util-obj-y)
|
2015-11-06 02:13:20 +03:00
|
|
|
tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(test-block-obj-y) $(test-util-obj-y)
|
2015-09-02 13:35:52 +03:00
|
|
|
tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(test-block-obj-y)
|
|
|
|
tests/test-iov$(EXESUF): tests/test-iov.o $(test-util-obj-y)
|
|
|
|
tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o $(test-util-obj-y)
|
2013-01-23 21:58:27 +04:00
|
|
|
tests/test-x86-cpuid$(EXESUF): tests/test-x86-cpuid.o
|
2017-04-20 13:37:23 +03:00
|
|
|
tests/test-xbzrle$(EXESUF): tests/test-xbzrle.o migration/xbzrle.o migration/page_cache.o $(test-util-obj-y)
|
2013-02-04 22:27:45 +04:00
|
|
|
tests/test-cutils$(EXESUF): tests/test-cutils.o util/cutils.o
|
2013-06-20 18:19:32 +04:00
|
|
|
tests/test-int128$(EXESUF): tests/test-int128.o
|
2015-09-02 13:35:52 +03:00
|
|
|
tests/rcutorture$(EXESUF): tests/rcutorture.o $(test-util-obj-y)
|
|
|
|
tests/test-rcu-list$(EXESUF): tests/test-rcu-list.o $(test-util-obj-y)
|
2016-06-08 21:55:27 +03:00
|
|
|
tests/test-qdist$(EXESUF): tests/test-qdist.o $(test-util-obj-y)
|
2016-06-08 21:55:29 +03:00
|
|
|
tests/test-qht$(EXESUF): tests/test-qht.o $(test-util-obj-y)
|
2016-06-08 21:55:31 +03:00
|
|
|
tests/test-qht-par$(EXESUF): tests/test-qht-par.o tests/qht-bench$(EXESUF) $(test-util-obj-y)
|
qht: add qht-bench, a performance benchmark
This serves as a performance benchmark as well as a stress test
for QHT. We can tweak quite a number of things, including the
number of resize threads and how frequently resizes are triggered.
A performance comparison of QHT vs CLHT[1] and ck_hs[2] using
this same benchmark program can be found here:
http://imgur.com/a/0Bms4
The tests are run on a 64-core AMD Opteron 6376, pinning threads
to cores favoring same-socket cores. For each run, qht-bench is
invoked with:
$ tests/qht-bench -d $duration -n $n -u $u -g $range
, where $duration is in seconds, $n is the number of threads,
$u is the update rate (0.0 to 100.0), and $range is the number
of keys.
Note that ck_hs's performance drops significantly as writes go
up, since it requires an external lock (I used a ck_spinlock)
around every write.
Also, note that CLHT instead of using a seqlock, relies on an
allocator that does not ever return the same address during the
same read-critical section. This gives it a slight performance
advantage over QHT on read-heavy workloads, since the seqlock
writes aren't there.
[1] CLHT: https://github.com/LPD-EPFL/CLHT
https://infoscience.epfl.ch/record/207109/files/ascy_asplos15.pdf
[2] ck_hs: http://concurrencykit.org/
http://backtrace.io/blog/blog/2015/03/13/workload-specialization/
A few of those plots are shown in text here, since that site
might not be online forever. Throughput is on Mops/s on the Y axis.
200K keys, 0 % updates
450 ++--+------+------+-------+-------+-------+-------+------+-------+--++
| + + + + + + + + +N+ |
400 ++ ---+E+ ++
| +++---- |
350 ++ 9 ++------+------++ --+E+ -+H+ ++
| | +H+- | -+N+---- ---- +++ |
300 ++ 8 ++ +E+ ++ -----+E+ --+H+ ++
| | +++ | -+N+-----+H+-- |
250 ++ 7 ++------+------++ +++-----+E+---- ++
200 ++ 1 -+E+-----+H+ ++
| ---- qht +-E--+ |
150 ++ -+E+ clht +-H--+ ++
| ---- ck +-N--+ |
100 ++ +E+ ++
| ---- |
50 ++ -+E+ ++
| +E+E+ + + + + + + + + |
0 ++--E------+------+-------+-------+-------+-------+------+-------+--++
1 8 16 24 32 40 48 56 64
Number of threads
200K keys, 1 % updates
350 ++--+------+------+-------+-------+-------+-------+------+-------+--++
| + + + + + + + + -+E+ |
300 ++ -----+H+ ++
| +E+-- |
| 9 ++------+------++ +++---- |
250 ++ | +E+ -- | -+E+ ++
| 8 ++ -- ++ ---- |
200 ++ | +++- | +++ ---+E+ ++
| 7 ++------N------++ -+E+-- qht +-E--+ |
| 1 +++---- clht +-H--+ |
150 ++ -+E+ ck +-N--+ ++
| ---- |
100 ++ +E+ ++
| ---- |
| -+E+ |
50 ++ +H+-+N+----+N+-----+N+------ ++
| +E+E+ + + + +N+-----+N+-----+N+----+N+-----+N+ |
0 ++--E------+------+-------+-------+-------+-------+------+-------+--++
1 8 16 24 32 40 48 56 64
Number of threads
200K keys, 20 % updates
300 ++--+------+------+-------+-------+-------+-------+------+-------+--++
| + + + + + + + + + |
| -+H+ |
250 ++ ---- ++
| 9 ++------+------++ --+H+ ---+E+ |
| 8 ++ +H+-- ++ -+H+----+E+-- |
200 ++ | +E+ --| -----+E+-- +++ ++
| 7 ++ + ---- ++ ---+H+---- +++ qht +-E--+ |
150 ++ 6 ++------N------++ -+H+-----+E+ clht +-H--+ ++
| 1 -----+E+-- ck +-N--+ |
| -+H+---- |
100 ++ -----+E+ ++
| +E+-- |
| ----+++ |
50 ++ -+E+ ++
| +E+ +++ |
| +E+N+-+N+-----+ + + + + + + |
0 ++--E------+------N-------N-------N-------N-------N------N-------N--++
1 8 16 24 32 40 48 56 64
Number of threads
200K keys, 100 % updates qht +-E--+
clht +-H--+
160 ++--+------+------+-------+-------+-------+-------+---ck-+-N-----+--++
| + + + + + + + + ----H |
140 ++ +H+-- -+E+ ++
| +++---- ---- |
120 ++ 8 ++------+------++ -+H+ +E+ ++
| 7 ++ +H+---- ++ ---- +++---- |
100 ++ | +E+ | +++ ---+H+ -+E+ ++
| 6 ++ +++ ++ -+H+-- +++---- |
80 ++ 5 ++------N----------+E+-----+E+ ++
| 1 -+H+---- +++ |
| -----+E+ |
60 ++ +H+---- +++ ++
| ----+E+ |
40 ++ +H+---- ++
| --+E+ |
20 ++ +E+ ++
| +EE+ + + + + + + + + |
0 ++--+N-N---N------N-------N-------N-------N-------N------N-------N--++
1 8 16 24 32 40 48 56 64
Number of threads
Signed-off-by: Emilio G. Cota <cota@braap.org>
Message-Id: <1465412133-3029-13-git-send-email-cota@braap.org>
Signed-off-by: Richard Henderson <rth@twiddle.net>
2016-06-08 21:55:30 +03:00
|
|
|
tests/qht-bench$(EXESUF): tests/qht-bench.o $(test-util-obj-y)
|
2016-08-29 21:46:16 +03:00
|
|
|
tests/test-bufferiszero$(EXESUF): tests/test-bufferiszero.o $(test-util-obj-y)
|
2016-06-27 22:02:05 +03:00
|
|
|
tests/atomic_add-bench$(EXESUF): tests/atomic_add-bench.o $(test-util-obj-y)
|
2013-06-21 11:09:34 +04:00
|
|
|
|
2013-07-11 00:08:40 +04:00
|
|
|
tests/test-qdev-global-props$(EXESUF): tests/test-qdev-global-props.o \
|
2014-02-05 19:36:52 +04:00
|
|
|
hw/core/qdev.o hw/core/qdev-properties.o hw/core/hotplug.o\
|
2015-07-13 20:35:41 +03:00
|
|
|
hw/core/bus.o \
|
2013-07-11 00:08:40 +04:00
|
|
|
hw/core/irq.o \
|
2014-03-17 06:40:23 +04:00
|
|
|
hw/core/fw-path-provider.o \
|
2016-10-24 12:19:49 +03:00
|
|
|
hw/core/reset.o \
|
2015-09-02 13:35:52 +03:00
|
|
|
$(test-qapi-obj-y)
|
2013-11-28 18:01:18 +04:00
|
|
|
tests/test-vmstate$(EXESUF): tests/test-vmstate.o \
|
2017-04-20 14:41:20 +03:00
|
|
|
migration/vmstate.o migration/vmstate-types.o migration/qemu-file.o \
|
2016-04-27 13:05:08 +03:00
|
|
|
migration/qemu-file-channel.o migration/qjson.o \
|
|
|
|
$(test-io-obj-y)
|
2017-02-13 16:52:18 +03:00
|
|
|
tests/test-timed-average$(EXESUF): tests/test-timed-average.o $(test-util-obj-y)
|
2015-11-23 18:24:50 +03:00
|
|
|
tests/test-base64$(EXESUF): tests/test-base64.o \
|
|
|
|
libqemuutil.a libqemustub.a
|
2016-10-17 21:22:17 +03:00
|
|
|
tests/ptimer-test$(EXESUF): tests/ptimer-test.o tests/ptimer-test-stubs.o hw/core/ptimer.o libqemustub.a
|
2012-03-28 17:42:01 +04:00
|
|
|
|
2016-03-15 17:30:20 +03:00
|
|
|
tests/test-logging$(EXESUF): tests/test-logging.o $(test-util-obj-y)
|
|
|
|
|
2016-07-27 10:01:51 +03:00
|
|
|
tests/test-replication$(EXESUF): tests/test-replication.o $(test-util-obj-y) \
|
|
|
|
$(test-block-obj-y)
|
|
|
|
|
2012-03-28 17:42:01 +04:00
|
|
|
tests/test-qapi-types.c tests/test-qapi-types.h :\
|
2015-04-02 14:38:48 +03:00
|
|
|
$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py $(qapi-py)
|
2014-05-02 17:52:24 +04:00
|
|
|
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-types.py \
|
2015-04-02 14:32:16 +03:00
|
|
|
$(gen-out-type) -o tests -p "test-" $<, \
|
2016-10-04 19:27:21 +03:00
|
|
|
"GEN","$@")
|
2012-03-28 17:42:01 +04:00
|
|
|
tests/test-qapi-visit.c tests/test-qapi-visit.h :\
|
2015-04-02 14:38:48 +03:00
|
|
|
$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-visit.py $(qapi-py)
|
2014-05-02 17:52:24 +04:00
|
|
|
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-visit.py \
|
2015-04-02 14:32:16 +03:00
|
|
|
$(gen-out-type) -o tests -p "test-" $<, \
|
2016-10-04 19:27:21 +03:00
|
|
|
"GEN","$@")
|
2012-03-28 17:42:01 +04:00
|
|
|
tests/test-qmp-commands.h tests/test-qmp-marshal.c :\
|
2015-04-02 14:38:48 +03:00
|
|
|
$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-commands.py $(qapi-py)
|
2014-05-02 17:52:24 +04:00
|
|
|
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-commands.py \
|
2015-04-02 14:32:16 +03:00
|
|
|
$(gen-out-type) -o tests -p "test-" $<, \
|
2016-10-04 19:27:21 +03:00
|
|
|
"GEN","$@")
|
2014-06-18 10:43:29 +04:00
|
|
|
tests/test-qapi-event.c tests/test-qapi-event.h :\
|
2015-04-02 14:38:48 +03:00
|
|
|
$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-event.py $(qapi-py)
|
2014-06-18 10:43:29 +04:00
|
|
|
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-event.py \
|
2015-04-02 14:32:16 +03:00
|
|
|
$(gen-out-type) -o tests -p "test-" $<, \
|
2016-10-04 19:27:21 +03:00
|
|
|
"GEN","$@")
|
qapi: New QMP command query-qmp-schema for QMP introspection
qapi/introspect.json defines the introspection schema. It's designed
for QMP introspection, but should do for similar uses, such as QGA.
The introspection schema does not reflect all the rules and
restrictions that apply to QAPI schemata. A valid QAPI schema has an
introspection value conforming to the introspection schema, but the
converse is not true.
Introspection lowers away a number of schema details, and makes
implicit things explicit:
* The built-in types are declared with their JSON type.
All integer types are mapped to 'int', because how many bits we use
internally is an implementation detail. It could be pressed into
external interface service as very approximate range information,
but that's a bad idea. If we need range information, we better do
it properly.
* Implicit type definitions are made explicit, and given
auto-generated names:
- Array types, named by appending "List" to the name of their
element type, like in generated C.
- The enumeration types implicitly defined by simple union types,
named by appending "Kind" to the name of their simple union type,
like in generated C.
- Types that don't occur in generated C. Their names start with ':'
so they don't clash with the user's names.
* All type references are by name.
* The struct and union types are generalized into an object type.
* Base types are flattened.
* Commands take a single argument and return a single result.
Dictionary argument or list result is an implicit type definition.
The empty object type is used when a command takes no arguments or
produces no results.
The argument is always of object type, but the introspection schema
doesn't reflect that.
The 'gen': false directive is omitted as implementation detail.
The 'success-response' directive is omitted as well for now, even
though it's not an implementation detail, because it's not used by
QMP.
* Events carry a single data value.
Implicit type definition and empty object type use, just like for
commands.
The value is of object type, but the introspection schema doesn't
reflect that.
* Types not used by commands or events are omitted.
Indirect use counts as use.
* Optional members have a default, which can only be null right now
Instead of a mandatory "optional" flag, we have an optional default.
No default means mandatory, default null means optional without
default value. Non-null is available for optional with default
(possible future extension).
* Clients should *not* look up types by name, because type names are
not ABI. Look up the command or event you're interested in, then
follow the references.
TODO Should we hide the type names to eliminate the temptation?
New generator scripts/qapi-introspect.py computes an introspection
value for its input, and generates a C variable holding it.
It can generate awfully long lines. Marked TODO.
A new test-qmp-input-visitor test case feeds its result for both
tests/qapi-schema/qapi-schema-test.json and qapi-schema.json to a
QmpInputVisitor to verify it actually conforms to the schema.
New QMP command query-qmp-schema takes its return value from that
variable. Its reply is some 85KiBytes for me right now.
If this turns out to be too much, we have a couple of options:
* We can use shorter names in the JSON. Not the QMP style.
* Optionally return the sub-schema for commands and events given as
arguments.
Right now qmp_query_schema() sends the string literal computed by
qmp-introspect.py. To compute sub-schema at run time, we'd have to
duplicate parts of qapi-introspect.py in C. Unattractive.
* Let clients cache the output of query-qmp-schema.
It changes only on QEMU upgrades, i.e. rarely. Provide a command
query-qmp-schema-hash. Clients can have a cache indexed by hash,
and re-query the schema only when they don't have it cached. Even
simpler: put the hash in the QMP greeting.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
2015-09-16 14:06:28 +03:00
|
|
|
tests/test-qmp-introspect.c tests/test-qmp-introspect.h :\
|
|
|
|
$(SRC_PATH)/tests/qapi-schema/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-introspect.py $(qapi-py)
|
|
|
|
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi-introspect.py \
|
|
|
|
$(gen-out-type) -o tests -p "test-" $<, \
|
2016-10-04 19:27:21 +03:00
|
|
|
"GEN","$@")
|
2012-01-10 23:10:43 +04:00
|
|
|
|
2017-03-20 16:11:54 +03:00
|
|
|
tests/qapi-schema/doc-good.test.texi: $(SRC_PATH)/tests/qapi-schema/doc-good.json $(SRC_PATH)/scripts/qapi2texi.py $(qapi-py)
|
|
|
|
$(call quiet-command,$(PYTHON) $(SRC_PATH)/scripts/qapi2texi.py $< > $@,"GEN","$@")
|
|
|
|
|
2015-09-02 13:35:52 +03:00
|
|
|
tests/test-string-output-visitor$(EXESUF): tests/test-string-output-visitor.o $(test-qapi-obj-y)
|
|
|
|
tests/test-string-input-visitor$(EXESUF): tests/test-string-input-visitor.o $(test-qapi-obj-y)
|
|
|
|
tests/test-qmp-event$(EXESUF): tests/test-qmp-event.o $(test-qapi-obj-y)
|
2016-09-30 17:45:27 +03:00
|
|
|
tests/test-qobject-output-visitor$(EXESUF): tests/test-qobject-output-visitor.o $(test-qapi-obj-y)
|
qapi: Add new clone visitor
We have a couple places in the code base that want to deep-clone
one QAPI object into another, and they were resorting to serializing
the struct out to QObject then reparsing it. A much more efficient
version can be done by adding a new clone visitor.
Since cloning is still relatively uncommon, expose the use of the
new visitor via a QAPI_CLONE() macro that takes care of type-punning
the underlying function pointer, rather than generating lots of
unused functions for types that won't be cloned. And yes, we're
relying on the compiler treating all pointers equally, even though
a strict C program cannot portably do so - but we're not the first
one in the qemu code base to expect it to work (hello, glib!).
The choice of adding a fourth visitor type deserves some explanation.
On the surface, the clone visitor is mostly an input visitor (it
takes arbitrary input - in this case, another QAPI object - and
creates a new QAPI object during the course of the visit). But
ever since commit da72ab0 consolidated enum visits based on the
visitor type, using VISITOR_INPUT would cause us to run
visit_type_str(), even though for cloning there is nothing to do
(we just copy the enum value across, without regards to its mapping
to strings). Also, since our input happens to be a QAPI object,
we can also satisfy the internal checks for VISITOR_OUTPUT. So in
the end, I settled with a new VISITOR_CLONE, and chose its value
such that many internal checks can use 'v->type & mask', sticking
to 'v->type == value' where the difference matters.
Note that we can only clone objects (including alternates) and lists,
not built-ins or enums. The visitor core hides integer width from
the actual visitor (since commit 04e070d), and as long as that's the
case, we can't clone top-level integers. Then again, those can
always be cloned by direct copy, since they are not objects with
deep pointers, so it's no real loss. And restricting cloning to
just objects and lists is cleaner than restricting it to non-integers.
As such, I documented that the clone visitor is for direct use only
by code internal to QAPI, and should not be used on incomplete objects
(other than a hack to work around the fact that we allow NULL in place
of "" in visit_type_str() in other output visitors). Note that as
written, the clone visitor will never fail on a complete object.
Scalars (including enums) not at the root of the clone copy just fine
with no additional effort while visiting the scalar, by virtue of a
g_memdup() each time we push another struct onto the stack. Cloning
a string requires deduplication of a pointer, which means it can also
provide the guarantee of an input visitor of never producing NULL
even when still accepting NULL in place of "" the way the QMP output
visitor does.
Cloning an 'any' type could be possible by incrementing the QObject
refcnt, but it's not obvious whether that is better than implementing
a QObject deep clone. So for now, we document it as unsupported,
and intentionally omit the .type_any() callback to let a developer
know their usage needs implementation.
Add testsuite coverage for several different clone situations, to
ensure that the code is working. I also tested that valgrind was
happy with the test.
Signed-off-by: Eric Blake <eblake@redhat.com>
Message-Id: <1465490926-28625-14-git-send-email-eblake@redhat.com>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Markus Armbruster <armbru@redhat.com>
2016-06-09 19:48:44 +03:00
|
|
|
tests/test-clone-visitor$(EXESUF): tests/test-clone-visitor.o $(test-qapi-obj-y)
|
2016-09-30 17:45:27 +03:00
|
|
|
tests/test-qobject-input-visitor$(EXESUF): tests/test-qobject-input-visitor.o $(test-qapi-obj-y)
|
2015-09-02 13:35:52 +03:00
|
|
|
tests/test-qmp-commands$(EXESUF): tests/test-qmp-commands.o tests/test-qmp-marshal.o $(test-qapi-obj-y)
|
|
|
|
tests/test-visitor-serialization$(EXESUF): tests/test-visitor-serialization.o $(test-qapi-obj-y)
|
|
|
|
tests/test-opts-visitor$(EXESUF): tests/test-opts-visitor.o $(test-qapi-obj-y)
|
2012-02-09 14:21:03 +04:00
|
|
|
|
2017-01-10 05:10:09 +03:00
|
|
|
tests/test-shift128$(EXESUF): tests/test-shift128.o $(test-util-obj-y)
|
2015-09-02 13:35:52 +03:00
|
|
|
tests/test-mul64$(EXESUF): tests/test-mul64.o $(test-util-obj-y)
|
|
|
|
tests/test-bitops$(EXESUF): tests/test-bitops.o $(test-util-obj-y)
|
2016-12-09 17:36:00 +03:00
|
|
|
tests/test-bitcnt$(EXESUF): tests/test-bitcnt.o $(test-util-obj-y)
|
2015-09-02 12:57:27 +03:00
|
|
|
tests/test-crypto-hash$(EXESUF): tests/test-crypto-hash.o $(test-crypto-obj-y)
|
2016-12-13 13:43:00 +03:00
|
|
|
tests/test-crypto-hmac$(EXESUF): tests/test-crypto-hmac.o $(test-crypto-obj-y)
|
2015-09-02 12:57:27 +03:00
|
|
|
tests/test-crypto-cipher$(EXESUF): tests/test-crypto-cipher.o $(test-crypto-obj-y)
|
crypto: add QCryptoSecret object class for password/key handling
Introduce a new QCryptoSecret object class which will be used
for providing passwords and keys to other objects which need
sensitive credentials.
The new object can provide secret values directly as properties,
or indirectly via a file. The latter includes support for file
descriptor passing syntax on UNIX platforms. Ordinarily passing
secret values directly as properties is insecure, since they
are visible in process listings, or in log files showing the
CLI args / QMP commands. It is possible to use AES-256-CBC to
encrypt the secret values though, in which case all that is
visible is the ciphertext. For ad hoc developer testing though,
it is fine to provide the secrets directly without encryption
so this is not explicitly forbidden.
The anticipated scenario is that libvirtd will create a random
master key per QEMU instance (eg /var/run/libvirt/qemu/$VMNAME.key)
and will use that key to encrypt all passwords it provides to
QEMU via '-object secret,....'. This avoids the need for libvirt
(or other mgmt apps) to worry about file descriptor passing.
It also makes life easier for people who are scripting the
management of QEMU, for whom FD passing is significantly more
complex.
Providing data inline (insecure, only for ad hoc dev testing)
$QEMU -object secret,id=sec0,data=letmein
Providing data indirectly in raw format
printf "letmein" > mypasswd.txt
$QEMU -object secret,id=sec0,file=mypasswd.txt
Providing data indirectly in base64 format
$QEMU -object secret,id=sec0,file=mykey.b64,format=base64
Providing data with encryption
$QEMU -object secret,id=master0,file=mykey.b64,format=base64 \
-object secret,id=sec0,data=[base64 ciphertext],\
keyid=master0,iv=[base64 IV],format=base64
Note that 'format' here refers to the format of the ciphertext
data. The decrypted data must always be in raw byte format.
More examples are shown in the updated docs.
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
2015-10-14 11:58:38 +03:00
|
|
|
tests/test-crypto-secret$(EXESUF): tests/test-crypto-secret.o $(test-crypto-obj-y)
|
2016-02-11 17:00:17 +03:00
|
|
|
tests/test-crypto-xts$(EXESUF): tests/test-crypto-xts.o $(test-crypto-obj-y)
|
2015-09-21 19:25:34 +03:00
|
|
|
|
|
|
|
tests/crypto-tls-x509-helpers.o-cflags := $(TASN1_CFLAGS)
|
|
|
|
tests/crypto-tls-x509-helpers.o-libs := $(TASN1_LIBS)
|
|
|
|
tests/pkix_asn1_tab.o-cflags := $(TASN1_CFLAGS)
|
|
|
|
|
|
|
|
tests/test-crypto-tlscredsx509.o-cflags := $(TASN1_CFLAGS)
|
2015-04-13 16:01:39 +03:00
|
|
|
tests/test-crypto-tlscredsx509$(EXESUF): tests/test-crypto-tlscredsx509.o \
|
|
|
|
tests/crypto-tls-x509-helpers.o tests/pkix_asn1_tab.o $(test-crypto-obj-y)
|
2015-09-21 19:25:34 +03:00
|
|
|
|
|
|
|
tests/test-crypto-tlssession.o-cflags := $(TASN1_CFLAGS)
|
2015-03-02 20:23:31 +03:00
|
|
|
tests/test-crypto-tlssession$(EXESUF): tests/test-crypto-tlssession.o \
|
|
|
|
tests/crypto-tls-x509-helpers.o tests/pkix_asn1_tab.o $(test-crypto-obj-y)
|
2015-03-18 20:25:45 +03:00
|
|
|
tests/test-io-task$(EXESUF): tests/test-io-task.o $(test-io-obj-y)
|
2015-02-27 19:19:33 +03:00
|
|
|
tests/test-io-channel-socket$(EXESUF): tests/test-io-channel-socket.o \
|
|
|
|
tests/io-channel-helpers.o $(test-io-obj-y)
|
2015-02-27 21:25:25 +03:00
|
|
|
tests/test-io-channel-file$(EXESUF): tests/test-io-channel-file.o \
|
|
|
|
tests/io-channel-helpers.o $(test-io-obj-y)
|
2015-03-02 21:13:13 +03:00
|
|
|
tests/test-io-channel-tls$(EXESUF): tests/test-io-channel-tls.o \
|
|
|
|
tests/crypto-tls-x509-helpers.o tests/pkix_asn1_tab.o \
|
|
|
|
tests/io-channel-helpers.o $(test-io-obj-y)
|
2015-08-27 18:25:30 +03:00
|
|
|
tests/test-io-channel-command$(EXESUF): tests/test-io-channel-command.o \
|
|
|
|
tests/io-channel-helpers.o $(test-io-obj-y)
|
2015-09-15 19:27:33 +03:00
|
|
|
tests/test-io-channel-buffer$(EXESUF): tests/test-io-channel-buffer.o \
|
|
|
|
tests/io-channel-helpers.o $(test-io-obj-y)
|
2015-10-14 15:14:04 +03:00
|
|
|
tests/test-crypto-pbkdf$(EXESUF): tests/test-crypto-pbkdf.o $(test-crypto-obj-y)
|
2015-10-15 14:35:28 +03:00
|
|
|
tests/test-crypto-ivgen$(EXESUF): tests/test-crypto-ivgen.o $(test-crypto-obj-y)
|
2015-10-23 18:14:25 +03:00
|
|
|
tests/test-crypto-afsplit$(EXESUF): tests/test-crypto-afsplit.o $(test-crypto-obj-y)
|
2015-10-24 13:44:13 +03:00
|
|
|
tests/test-crypto-block$(EXESUF): tests/test-crypto-block.o $(test-crypto-obj-y)
|
2013-02-17 00:47:01 +04:00
|
|
|
|
2014-10-23 12:12:42 +04:00
|
|
|
libqos-obj-y = tests/libqos/pci.o tests/libqos/fw_cfg.o tests/libqos/malloc.o
|
2015-01-19 23:15:55 +03:00
|
|
|
libqos-obj-y += tests/libqos/i2c.o tests/libqos/libqos.o
|
2016-09-13 15:52:44 +03:00
|
|
|
libqos-spapr-obj-y = $(libqos-obj-y) tests/libqos/malloc-spapr.o
|
|
|
|
libqos-spapr-obj-y += tests/libqos/libqos-spapr.o
|
2016-09-13 15:52:45 +03:00
|
|
|
libqos-spapr-obj-y += tests/libqos/rtas.o
|
2016-09-29 13:32:44 +03:00
|
|
|
libqos-spapr-obj-y += tests/libqos/pci-spapr.o
|
2013-06-26 17:52:22 +04:00
|
|
|
libqos-pc-obj-y = $(libqos-obj-y) tests/libqos/pci-pc.o
|
2015-01-19 23:15:55 +03:00
|
|
|
libqos-pc-obj-y += tests/libqos/malloc-pc.o tests/libqos/libqos-pc.o
|
2015-01-19 23:16:03 +03:00
|
|
|
libqos-pc-obj-y += tests/libqos/ahci.o
|
2013-05-02 17:56:26 +04:00
|
|
|
libqos-omap-obj-y = $(libqos-obj-y) tests/libqos/i2c-omap.o
|
2015-09-07 12:39:31 +03:00
|
|
|
libqos-imx-obj-y = $(libqos-obj-y) tests/libqos/i2c-imx.o
|
2016-09-29 13:32:47 +03:00
|
|
|
libqos-usb-obj-y = $(libqos-spapr-obj-y) $(libqos-pc-obj-y) tests/libqos/usb.o
|
2016-10-17 13:30:24 +03:00
|
|
|
libqos-virtio-obj-y = $(libqos-spapr-obj-y) $(libqos-pc-obj-y) tests/libqos/virtio.o tests/libqos/virtio-pci.o tests/libqos/virtio-mmio.o tests/libqos/malloc-generic.o
|
2013-04-16 18:45:16 +04:00
|
|
|
|
2017-03-03 15:32:23 +03:00
|
|
|
tests/qmp-test$(EXESUF): tests/qmp-test.o
|
2015-10-01 11:59:56 +03:00
|
|
|
tests/device-introspect-test$(EXESUF): tests/device-introspect-test.o
|
2012-12-21 12:45:20 +04:00
|
|
|
tests/rtc-test$(EXESUF): tests/rtc-test.o
|
|
|
|
tests/m48t59-test$(EXESUF): tests/m48t59-test.o
|
2013-07-22 17:54:34 +04:00
|
|
|
tests/endianness-test$(EXESUF): tests/endianness-test.o
|
2014-02-10 07:52:56 +04:00
|
|
|
tests/spapr-phb-test$(EXESUF): tests/spapr-phb-test.o $(libqos-obj-y)
|
2016-06-14 16:57:56 +03:00
|
|
|
tests/prom-env-test$(EXESUF): tests/prom-env-test.o $(libqos-obj-y)
|
2016-09-13 15:52:45 +03:00
|
|
|
tests/rtas-test$(EXESUF): tests/rtas-test.o $(libqos-spapr-obj-y)
|
2012-12-21 12:45:20 +04:00
|
|
|
tests/fdc-test$(EXESUF): tests/fdc-test.o
|
2013-05-08 13:18:41 +04:00
|
|
|
tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y)
|
2015-01-19 23:15:55 +03:00
|
|
|
tests/ahci-test$(EXESUF): tests/ahci-test.o $(libqos-pc-obj-y)
|
2015-12-17 21:50:09 +03:00
|
|
|
tests/ipmi-kcs-test$(EXESUF): tests/ipmi-kcs-test.o
|
|
|
|
tests/ipmi-bt-test$(EXESUF): tests/ipmi-bt-test.o
|
2012-12-21 12:45:20 +04:00
|
|
|
tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o
|
2013-06-26 17:52:16 +04:00
|
|
|
tests/boot-order-test$(EXESUF): tests/boot-order-test.o $(libqos-obj-y)
|
2016-09-03 12:57:51 +03:00
|
|
|
tests/boot-serial-test$(EXESUF): tests/boot-serial-test.o $(libqos-obj-y)
|
2016-02-14 19:59:27 +03:00
|
|
|
tests/bios-tables-test$(EXESUF): tests/bios-tables-test.o \
|
2017-02-17 02:15:38 +03:00
|
|
|
tests/boot-sector.o tests/acpi-utils.o $(libqos-obj-y)
|
2016-02-14 19:59:27 +03:00
|
|
|
tests/pxe-test$(EXESUF): tests/pxe-test.o tests/boot-sector.o $(libqos-obj-y)
|
2013-05-02 17:56:26 +04:00
|
|
|
tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
|
2015-09-07 12:39:31 +03:00
|
|
|
tests/ds1338-test$(EXESUF): tests/ds1338-test.o $(libqos-imx-obj-y)
|
2016-10-17 21:22:17 +03:00
|
|
|
tests/m25p80-test$(EXESUF): tests/m25p80-test.o
|
2013-04-16 18:45:19 +04:00
|
|
|
tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
|
2015-04-14 16:11:36 +03:00
|
|
|
tests/q35-test$(EXESUF): tests/q35-test.o $(libqos-pc-obj-y)
|
2013-04-16 18:45:21 +04:00
|
|
|
tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y)
|
2013-11-07 21:25:10 +04:00
|
|
|
tests/e1000-test$(EXESUF): tests/e1000-test.o
|
2016-06-01 11:23:46 +03:00
|
|
|
tests/e1000e-test$(EXESUF): tests/e1000e-test.o $(libqos-pc-obj-y)
|
2015-01-08 21:38:23 +03:00
|
|
|
tests/rtl8139-test$(EXESUF): tests/rtl8139-test.o $(libqos-pc-obj-y)
|
2013-11-07 21:53:28 +04:00
|
|
|
tests/pcnet-test$(EXESUF): tests/pcnet-test.o
|
2016-11-15 02:09:46 +03:00
|
|
|
tests/pnv-xscom-test$(EXESUF): tests/pnv-xscom-test.o
|
2013-11-07 22:18:46 +04:00
|
|
|
tests/eepro100-test$(EXESUF): tests/eepro100-test.o
|
2013-11-07 21:37:34 +04:00
|
|
|
tests/vmxnet3-test$(EXESUF): tests/vmxnet3-test.o
|
2014-02-09 07:01:37 +04:00
|
|
|
tests/ne2000-test$(EXESUF): tests/ne2000-test.o
|
2014-07-15 16:57:06 +04:00
|
|
|
tests/wdt_ib700-test$(EXESUF): tests/wdt_ib700-test.o
|
2015-06-28 20:58:57 +03:00
|
|
|
tests/tco-test$(EXESUF): tests/tco-test.o $(libqos-pc-obj-y)
|
2014-02-09 07:39:47 +04:00
|
|
|
tests/virtio-balloon-test$(EXESUF): tests/virtio-balloon-test.o
|
2014-09-01 14:07:54 +04:00
|
|
|
tests/virtio-blk-test$(EXESUF): tests/virtio-blk-test.o $(libqos-virtio-obj-y)
|
2015-07-17 10:25:53 +03:00
|
|
|
tests/virtio-net-test$(EXESUF): tests/virtio-net-test.o $(libqos-pc-obj-y) $(libqos-virtio-obj-y)
|
2014-09-26 13:28:09 +04:00
|
|
|
tests/virtio-rng-test$(EXESUF): tests/virtio-rng-test.o $(libqos-pc-obj-y)
|
2015-04-24 14:35:16 +03:00
|
|
|
tests/virtio-scsi-test$(EXESUF): tests/virtio-scsi-test.o $(libqos-virtio-obj-y)
|
2016-09-16 09:58:35 +03:00
|
|
|
tests/virtio-9p-test$(EXESUF): tests/virtio-9p-test.o $(libqos-virtio-obj-y)
|
2014-02-21 20:36:57 +04:00
|
|
|
tests/virtio-serial-test$(EXESUF): tests/virtio-serial-test.o
|
2014-02-21 20:49:12 +04:00
|
|
|
tests/virtio-console-test$(EXESUF): tests/virtio-console-test.o
|
2014-02-09 06:48:44 +04:00
|
|
|
tests/tpci200-test$(EXESUF): tests/tpci200-test.o
|
2014-04-28 13:01:13 +04:00
|
|
|
tests/display-vga-test$(EXESUF): tests/display-vga-test.o
|
2014-02-09 15:24:15 +04:00
|
|
|
tests/ipoctal232-test$(EXESUF): tests/ipoctal232-test.o
|
2013-07-29 07:44:47 +04:00
|
|
|
tests/qom-test$(EXESUF): tests/qom-test.o
|
2017-04-25 08:16:47 +03:00
|
|
|
tests/test-hmp$(EXESUF): tests/test-hmp.o
|
2014-10-02 18:51:31 +04:00
|
|
|
tests/drive_del-test$(EXESUF): tests/drive_del-test.o $(libqos-pc-obj-y)
|
2013-10-30 17:54:35 +04:00
|
|
|
tests/qdev-monitor-test$(EXESUF): tests/qdev-monitor-test.o $(libqos-pc-obj-y)
|
2014-02-22 01:19:43 +04:00
|
|
|
tests/nvme-test$(EXESUF): tests/nvme-test.o
|
2014-02-21 23:38:48 +04:00
|
|
|
tests/pvpanic-test$(EXESUF): tests/pvpanic-test.o
|
2014-02-22 01:43:43 +04:00
|
|
|
tests/i82801b11-test$(EXESUF): tests/i82801b11-test.o
|
2014-03-30 21:00:05 +04:00
|
|
|
tests/ac97-test$(EXESUF): tests/ac97-test.o
|
2014-03-30 21:05:20 +04:00
|
|
|
tests/es1370-test$(EXESUF): tests/es1370-test.o
|
2014-03-30 21:22:48 +04:00
|
|
|
tests/intel-hda-test$(EXESUF): tests/intel-hda-test.o
|
2014-03-30 22:02:00 +04:00
|
|
|
tests/ioh3420-test$(EXESUF): tests/ioh3420-test.o
|
2014-09-26 13:28:14 +04:00
|
|
|
tests/usb-hcd-ohci-test$(EXESUF): tests/usb-hcd-ohci-test.o $(libqos-usb-obj-y)
|
2014-09-26 13:28:13 +04:00
|
|
|
tests/usb-hcd-uhci-test$(EXESUF): tests/usb-hcd-uhci-test.o $(libqos-usb-obj-y)
|
2014-09-26 13:28:12 +04:00
|
|
|
tests/usb-hcd-ehci-test$(EXESUF): tests/usb-hcd-ehci-test.o $(libqos-usb-obj-y)
|
2014-09-26 13:28:14 +04:00
|
|
|
tests/usb-hcd-xhci-test$(EXESUF): tests/usb-hcd-xhci-test.o $(libqos-usb-obj-y)
|
2015-03-13 19:21:11 +03:00
|
|
|
tests/pc-cpu-test$(EXESUF): tests/pc-cpu-test.o
|
test: Postcopy
This is a postcopy test (x86 only) that actually runs the guest
and checks the memory contents.
The test runs from an x86 boot block with the hex embedded in the test;
the source for this is:
...........
.code16
.org 0x7c00
.file "fill.s"
.text
.globl start
.type start, @function
start: # at 0x7c00 ?
cli
lgdt gdtdesc
mov $1,%eax
mov %eax,%cr0 # Protected mode enable
data32 ljmp $8,$0x7c20
.org 0x7c20
.code32
# A20 enable - not sure I actually need this
inb $0x92,%al
or $2,%al
outb %al, $0x92
# set up DS for the whole of RAM (needed on KVM)
mov $16,%eax
mov %eax,%ds
mov $65,%ax
mov $0x3f8,%dx
outb %al,%dx
# bl keeps a counter so we limit the output speed
mov $0, %bl
mainloop:
# Start from 1MB
mov $(1024*1024),%eax
innerloop:
incb (%eax)
add $4096,%eax
cmp $(100*1024*1024),%eax
jl innerloop
inc %bl
jnz mainloop
mov $66,%ax
mov $0x3f8,%dx
outb %al,%dx
jmp mainloop
# GDT magic from old (GPLv2) Grub startup.S
.p2align 2 /* force 4-byte alignment */
gdt:
.word 0, 0
.byte 0, 0, 0, 0
/* -- code segment --
* base = 0x00000000, limit = 0xFFFFF (4 KiB Granularity), present
* type = 32bit code execute/read, DPL = 0
*/
.word 0xFFFF, 0
.byte 0, 0x9A, 0xCF, 0
/* -- data segment --
* base = 0x00000000, limit 0xFFFFF (4 KiB Granularity), present
* type = 32 bit data read/write, DPL = 0
*/
.word 0xFFFF, 0
.byte 0, 0x92, 0xCF, 0
gdtdesc:
.word 0x27 /* limit */
.long gdt /* addr */
/* I'm a bootable disk */
.org 0x7dfe
.byte 0x55
.byte 0xAA
...........
and that can be assembled by the following magic:
as --32 -march=i486 fill.s -o fill.o
objcopy -O binary fill.o fill.boot
dd if=fill.boot of=bootsect bs=256 count=2 skip=124
xxd -i bootsect
Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Reviewed-by: Marcel Apfelbaum <marcel@redhat.com>
Message-id: 1465816605-29488-5-git-send-email-dgilbert@redhat.com
Message-Id: <1465816605-29488-5-git-send-email-dgilbert@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
2016-06-13 14:16:43 +03:00
|
|
|
tests/postcopy-test$(EXESUF): tests/postcopy-test.o
|
2017-02-13 16:52:18 +03:00
|
|
|
tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o $(test-util-obj-y) \
|
2016-12-12 15:49:01 +03:00
|
|
|
$(qtest-obj-y) $(test-io-obj-y) $(libqos-virtio-obj-y) $(libqos-pc-obj-y) \
|
|
|
|
$(chardev-obj-y)
|
2013-09-06 07:24:32 +04:00
|
|
|
tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o
|
2015-09-02 13:35:52 +03:00
|
|
|
tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o $(test-util-obj-y)
|
2017-03-20 15:55:46 +03:00
|
|
|
tests/test-keyval$(EXESUF): tests/test-keyval.o $(test-util-obj-y) $(test-qapi-obj-y)
|
2015-09-02 13:35:52 +03:00
|
|
|
tests/test-write-threshold$(EXESUF): tests/test-write-threshold.o $(test-block-obj-y)
|
2015-10-07 06:52:22 +03:00
|
|
|
tests/test-netfilter$(EXESUF): tests/test-netfilter.o $(qtest-obj-y)
|
tests/test-filter-mirror:add filter-mirror unit test
In this unit test we will test the mirror function.
start qemu with:
-netdev socket,id=qtest-bn0,fd=sockfd
-device e1000,netdev=qtest-bn0,id=qtest-e0
-chardev socket,id=mirror0,path=/tmp/filter-mirror-test.sock,server,nowait
-object filter-mirror,id=qtest-f0,netdev=qtest-bn0,queue=tx,outdev=mirror0
We inject packet to netdev socket id = qtest-bn0,
filter-mirror will copy and mirror the packet to mirror0.
we read packet from mirror0 and then compare to what we injected.
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
2016-03-15 10:41:34 +03:00
|
|
|
tests/test-filter-mirror$(EXESUF): tests/test-filter-mirror.o $(qtest-obj-y)
|
tests/test-filter-redirector: Add unit test for filter-redirector
In this unit test,we will test the filter redirector function.
Case 1, tx traffic flow:
qemu side | test side
|
+---------+ | +-------+
| backend <---------------+ sock0 |
+----+----+ | +-------+
| |
+----v----+ +-------+ |
| rd0 +->+chardev| |
+---------+ +---+---+ |
| |
+---------+ | |
| rd1 <------+ |
+----+----+ |
| |
+----v----+ | +-------+
| rd2 +--------------->sock1 |
+---------+ | +-------+
+
a. we(sock0) inject packet to qemu socket backend
b. backend pass packet to filter redirector0(rd0)
c. rd0 redirect packet to out_dev(chardev) which is connected with
filter redirector1's(rd1) in_dev
d. rd1 read this packet from in_dev, and pass to next filter redirector2(rd2)
e. rd2 redirect packet to rd2's out_dev which is connected with an opened socketed(sock1)
f. we read packet from sock1 and compare to what we inject
Start qemu with:
"-netdev socket,id=qtest-bn0,fd=%d "
"-device rtl8139,netdev=qtest-bn0,id=qtest-e0 "
"-chardev socket,id=redirector0,path=%s,server,nowait "
"-chardev socket,id=redirector1,path=%s,server,nowait "
"-chardev socket,id=redirector2,path=%s,nowait "
"-object filter-redirector,id=qtest-f0,netdev=qtest-bn0,"
"queue=tx,outdev=redirector0 "
"-object filter-redirector,id=qtest-f1,netdev=qtest-bn0,"
"queue=tx,indev=redirector2 "
"-object filter-redirector,id=qtest-f2,netdev=qtest-bn0,"
"queue=tx,outdev=redirector1 "
--------------------------------------
Case 2, rx traffic flow
qemu side | test side
|
+---------+ | +-------+
| backend +---------------> sock1 |
+----^----+ | +-------+
| |
+----+----+ +-------+ |
| rd0 +<-+chardev| |
+---------+ +---+---+ |
^ |
+---------+ | |
| rd1 +------+ |
+----^----+ |
| |
+----+----+ | +-------+
| rd2 <---------------+sock0 |
+---------+ | +-------+
a. we(sock0) insert packet to filter redirector2(rd2)
b. rd2 pass packet to filter redirector1(rd1)
c. rd1 redirect packet to out_dev(chardev) which is connected with
filter redirector0's(rd0) in_dev
d. rd0 read this packet from in_dev, and pass ti to qemu backend which is
connected with an opened socketed(sock1)
e. we read packet from sock1 and compare to what we inject
Start qemu with:
"-netdev socket,id=qtest-bn0,fd=%d "
"-device rtl8139,netdev=qtest-bn0,id=qtest-e0 "
"-chardev socket,id=redirector0,path=%s,server,nowait "
"-chardev socket,id=redirector1,path=%s,server,nowait "
"-chardev socket,id=redirector2,path=%s,nowait "
"-object filter-redirector,id=qtest-f0,netdev=qtest-bn0,"
"queue=rx,outdev=redirector0 "
"-object filter-redirector,id=qtest-f1,netdev=qtest-bn0,"
"queue=rx,indev=redirector2 "
"-object filter-redirector,id=qtest-f2,netdev=qtest-bn0,"
"queue=rx,outdev=redirector1 "
Signed-off-by: Zhang Chen <zhangchen.fnst@cn.fujitsu.com>
Signed-off-by: Wen Congyang <wency@cn.fujitsu.com>
Signed-off-by: Li Zhijian <lizhijian@cn.fujitsu.com>
Signed-off-by: Jason Wang <jasowang@redhat.com>
2016-03-17 11:16:27 +03:00
|
|
|
tests/test-filter-redirector$(EXESUF): tests/test-filter-redirector.o $(qtest-obj-y)
|
2016-09-20 23:11:39 +03:00
|
|
|
tests/test-x86-cpuid-compat$(EXESUF): tests/test-x86-cpuid-compat.o $(qtest-obj-y)
|
2017-01-05 18:29:48 +03:00
|
|
|
tests/ivshmem-test$(EXESUF): tests/ivshmem-test.o contrib/ivshmem-server/ivshmem-server.o $(libqos-pc-obj-y) $(libqos-spapr-obj-y)
|
2016-10-18 12:24:05 +03:00
|
|
|
tests/vhost-user-bridge$(EXESUF): tests/vhost-user-bridge.o contrib/libvhost-user/libvhost-user.o $(test-util-obj-y)
|
2016-09-21 07:27:24 +03:00
|
|
|
tests/test-uuid$(EXESUF): tests/test-uuid.o $(test-util-obj-y)
|
2016-10-24 18:26:54 +03:00
|
|
|
tests/test-arm-mptimer$(EXESUF): tests/test-arm-mptimer.o
|
2017-03-01 00:27:03 +03:00
|
|
|
tests/test-qapi-util$(EXESUF): tests/test-qapi-util.o $(test-util-obj-y)
|
2017-05-03 15:56:55 +03:00
|
|
|
tests/numa-test$(EXESUF): tests/numa-test.o
|
2012-03-30 21:39:33 +04:00
|
|
|
|
tests: introduce a framework for testing migration performance
This introduces a moderately general purpose framework for
testing performance of migration.
The initial guest workload is provided by the included 'stress'
program, which is configured to spawn one thread per guest CPU
and run a maximally memory intensive workload. It will loop
over GB of memory, xor'ing each byte with data from a 4k array
of random bytes. This ensures heavy read and write load across
all of guest memory to stress the migration performance. While
running the 'stress' program will record how long it takes to
xor each GB of memory and print this data for later reporting.
The test engine will spawn a pair of QEMU processes, either on
the same host, or with the target on a remote host via ssh,
using the host kernel and a custom initrd built with 'stress'
as the /init binary. Kernel command line args are set to ensure
a fast kernel boot time (< 1 second) between launching QEMU and
the stress program starting execution.
None the less, the test engine will initially wait N seconds for
the guest workload to stablize, before starting the migration
operation. When migration is running, the engine will use pause,
post-copy, autoconverge, xbzrle compression and multithread
compression features, as well as downtime & bandwidth tuning
to encourage completion. If migration completes, the test engine
will wait N seconds again for the guest workooad to stablize on
the target host. If migration does not complete after a preset
number of iterations, it will be aborted.
While the QEMU process is running on the source host, the test
engine will sample the host CPU usage of QEMU as a whole, and
each vCPU thread. While migration is running, it will record
all the stats reported by 'query-migration'. Finally, it will
capture the output of the stress program running in the guest.
All the data produced from a single test execution is recorded
in a structured JSON file. A separate program is then able to
create interactive charts using the "plotly" python + javascript
libraries, showing the characteristics of the migration.
The data output provides visualization of the effect on guest
vCPU workloads from the migration process, the corresponding
vCPU utilization on the host, and the overall CPU hit from
QEMU on the host. This is correlated from statistics from the
migration process, such as downtime, vCPU throttling and iteration
number.
While the tests can be run individually with arbitrary parameters,
there is also a facility for producing batch reports for a number
of pre-defined scenarios / comparisons, in order to be able to
get standardized results across different hardware configurations
(eg TCP vs RDMA, or comparing different VCPU counts / memory
sizes, etc).
To use this, first you must build the initrd image
$ make tests/migration/initrd-stress.img
To run a a one-shot test with all default parameters
$ ./tests/migration/guestperf.py > result.json
This has many command line args for varying its behaviour.
For example, to increase the RAM size and CPU count and
bind it to specific host NUMA nodes
$ ./tests/migration/guestperf.py \
--mem 4 --cpus 2 \
--src-mem-bind 0 --src-cpu-bind 0,1 \
--dst-mem-bind 1 --dst-cpu-bind 2,3 \
> result.json
Using mem + cpu binding is strongly recommended on NUMA
machines, otherwise the guest performance results will
vary wildly between runs of the test due to lucky/unlucky
NUMA placement, making sensible data analysis impossible.
To make it run across separate hosts:
$ ./tests/migration/guestperf.py \
--dst-host somehostname > result.json
To request that post-copy is enabled, with switchover
after 5 iterations
$ ./tests/migration/guestperf.py \
--post-copy --post-copy-iters 5 > result.json
Once a result.json file is created, a graph of the data
can be generated, showing guest workload performance per
thread and the migration iteration points:
$ ./tests/migration/guestperf-plot.py --output result.html \
--migration-iters --split-guest-cpu result.json
To further include host vCPU utilization and overall QEMU
utilization
$ ./tests/migration/guestperf-plot.py --output result.html \
--migration-iters --split-guest-cpu \
--qemu-cpu --vcpu-cpu result.json
NB, the 'guestperf-plot.py' command requires that you have
the plotly python library installed. eg you must do
$ pip install --user plotly
Viewing the result.html file requires that you have the
plotly.min.js file in the same directory as the HTML
output. This js file is installed as part of the plotly
python library, so can be found in
$HOME/.local/lib/python2.7/site-packages/plotly/offline/plotly.min.js
The guestperf-plot.py program can accept multiple json files
to plot, enabling results from different configurations to
be compared.
Finally, to run the entire standardized set of comparisons
$ ./tests/migration/guestperf-batch.py \
--dst-host somehost \
--mem 4 --cpus 2 \
--src-mem-bind 0 --src-cpu-bind 0,1 \
--dst-mem-bind 1 --dst-cpu-bind 2,3
--output tcp-somehost-4gb-2cpu
will store JSON files from all scenarios in the directory
named tcp-somehost-4gb-2cpu
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Message-Id: <1469020993-29426-7-git-send-email-berrange@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
2016-07-20 16:23:13 +03:00
|
|
|
tests/migration/stress$(EXESUF): tests/migration/stress.o
|
2016-10-04 19:27:21 +03:00
|
|
|
$(call quiet-command, $(LINKPROG) -static -O3 $(PTHREAD_LIB) -o $@ $< ,"LINK","$(TARGET_DIR)$@")
|
tests: introduce a framework for testing migration performance
This introduces a moderately general purpose framework for
testing performance of migration.
The initial guest workload is provided by the included 'stress'
program, which is configured to spawn one thread per guest CPU
and run a maximally memory intensive workload. It will loop
over GB of memory, xor'ing each byte with data from a 4k array
of random bytes. This ensures heavy read and write load across
all of guest memory to stress the migration performance. While
running the 'stress' program will record how long it takes to
xor each GB of memory and print this data for later reporting.
The test engine will spawn a pair of QEMU processes, either on
the same host, or with the target on a remote host via ssh,
using the host kernel and a custom initrd built with 'stress'
as the /init binary. Kernel command line args are set to ensure
a fast kernel boot time (< 1 second) between launching QEMU and
the stress program starting execution.
None the less, the test engine will initially wait N seconds for
the guest workload to stablize, before starting the migration
operation. When migration is running, the engine will use pause,
post-copy, autoconverge, xbzrle compression and multithread
compression features, as well as downtime & bandwidth tuning
to encourage completion. If migration completes, the test engine
will wait N seconds again for the guest workooad to stablize on
the target host. If migration does not complete after a preset
number of iterations, it will be aborted.
While the QEMU process is running on the source host, the test
engine will sample the host CPU usage of QEMU as a whole, and
each vCPU thread. While migration is running, it will record
all the stats reported by 'query-migration'. Finally, it will
capture the output of the stress program running in the guest.
All the data produced from a single test execution is recorded
in a structured JSON file. A separate program is then able to
create interactive charts using the "plotly" python + javascript
libraries, showing the characteristics of the migration.
The data output provides visualization of the effect on guest
vCPU workloads from the migration process, the corresponding
vCPU utilization on the host, and the overall CPU hit from
QEMU on the host. This is correlated from statistics from the
migration process, such as downtime, vCPU throttling and iteration
number.
While the tests can be run individually with arbitrary parameters,
there is also a facility for producing batch reports for a number
of pre-defined scenarios / comparisons, in order to be able to
get standardized results across different hardware configurations
(eg TCP vs RDMA, or comparing different VCPU counts / memory
sizes, etc).
To use this, first you must build the initrd image
$ make tests/migration/initrd-stress.img
To run a a one-shot test with all default parameters
$ ./tests/migration/guestperf.py > result.json
This has many command line args for varying its behaviour.
For example, to increase the RAM size and CPU count and
bind it to specific host NUMA nodes
$ ./tests/migration/guestperf.py \
--mem 4 --cpus 2 \
--src-mem-bind 0 --src-cpu-bind 0,1 \
--dst-mem-bind 1 --dst-cpu-bind 2,3 \
> result.json
Using mem + cpu binding is strongly recommended on NUMA
machines, otherwise the guest performance results will
vary wildly between runs of the test due to lucky/unlucky
NUMA placement, making sensible data analysis impossible.
To make it run across separate hosts:
$ ./tests/migration/guestperf.py \
--dst-host somehostname > result.json
To request that post-copy is enabled, with switchover
after 5 iterations
$ ./tests/migration/guestperf.py \
--post-copy --post-copy-iters 5 > result.json
Once a result.json file is created, a graph of the data
can be generated, showing guest workload performance per
thread and the migration iteration points:
$ ./tests/migration/guestperf-plot.py --output result.html \
--migration-iters --split-guest-cpu result.json
To further include host vCPU utilization and overall QEMU
utilization
$ ./tests/migration/guestperf-plot.py --output result.html \
--migration-iters --split-guest-cpu \
--qemu-cpu --vcpu-cpu result.json
NB, the 'guestperf-plot.py' command requires that you have
the plotly python library installed. eg you must do
$ pip install --user plotly
Viewing the result.html file requires that you have the
plotly.min.js file in the same directory as the HTML
output. This js file is installed as part of the plotly
python library, so can be found in
$HOME/.local/lib/python2.7/site-packages/plotly/offline/plotly.min.js
The guestperf-plot.py program can accept multiple json files
to plot, enabling results from different configurations to
be compared.
Finally, to run the entire standardized set of comparisons
$ ./tests/migration/guestperf-batch.py \
--dst-host somehost \
--mem 4 --cpus 2 \
--src-mem-bind 0 --src-cpu-bind 0,1 \
--dst-mem-bind 1 --dst-cpu-bind 2,3
--output tcp-somehost-4gb-2cpu
will store JSON files from all scenarios in the directory
named tcp-somehost-4gb-2cpu
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Message-Id: <1469020993-29426-7-git-send-email-berrange@redhat.com>
Signed-off-by: Amit Shah <amit.shah@redhat.com>
2016-07-20 16:23:13 +03:00
|
|
|
|
|
|
|
INITRD_WORK_DIR=tests/migration/initrd
|
|
|
|
|
|
|
|
tests/migration/initrd-stress.img: tests/migration/stress$(EXESUF)
|
|
|
|
mkdir -p $(INITRD_WORK_DIR)
|
|
|
|
cp $< $(INITRD_WORK_DIR)/init
|
|
|
|
(cd $(INITRD_WORK_DIR) && (find | cpio --quiet -o -H newc | gzip -9)) > $@
|
|
|
|
rm $(INITRD_WORK_DIR)/init
|
|
|
|
rmdir $(INITRD_WORK_DIR)
|
|
|
|
|
2014-06-19 21:35:42 +04:00
|
|
|
ifeq ($(CONFIG_POSIX),y)
|
|
|
|
LIBS += -lutil
|
|
|
|
endif
|
2014-06-10 14:03:23 +04:00
|
|
|
|
2012-03-28 17:42:05 +04:00
|
|
|
# QTest rules
|
|
|
|
|
|
|
|
TARGETS=$(patsubst %-softmmu,%, $(filter %-softmmu,$(TARGET_DIRS)))
|
2014-03-28 13:55:54 +04:00
|
|
|
ifeq ($(CONFIG_POSIX),y)
|
tests: Fix how qom-test is run
We want to run qom-test for every architecture, without having to
manually add it to every architecture's list of tests. Commit 3687d53
accomplished this by adding it to every architecture's list
automatically.
However, some architectures inherit their tests from others, like this:
check-qtest-x86_64-y = $(check-qtest-i386-y)
check-qtest-microblazeel-y = $(check-qtest-microblaze-y)
check-qtest-xtensaeb-y = $(check-qtest-xtensa-y)
For such architectures, we ended up running the (slow!) test twice.
Commit 2b8419c attempted to avoid this by adding the test only when
it's not already present. Works only as long as we consider adding
the test to the architectures on the left hand side *after* the ones
on the right hand side: x86_64 after i386, microblazeel after
microblaze, xtensaeb after xtensa.
Turns out we consider them in $(SYSEMU_TARGET_LIST) order. Defined as
SYSEMU_TARGET_LIST := $(subst -softmmu.mak,,$(notdir \
$(wildcard $(SRC_PATH)/default-configs/*-softmmu.mak)))
On my machine, this results in the oder xtensa, x86_64, microblazeel,
microblaze, i386. Consequently, qom-test runs twice for microblazeel
and x86_64.
Replace this complex and flawed machinery with a much simpler one: add
generic tests (currently just qom-test) to check-qtest-generic-y
instead of check-qtest-$(target)-y for every target, then run
$(check-qtest-generic-y) for every target.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Message-Id: <1443689999-12182-5-git-send-email-armbru@redhat.com>
2015-10-01 11:59:53 +03:00
|
|
|
QTEST_TARGETS = $(TARGETS)
|
2014-03-28 13:55:54 +04:00
|
|
|
check-qtest-y=$(foreach TARGET,$(TARGETS), $(check-qtest-$(TARGET)-y))
|
tests: Fix how qom-test is run
We want to run qom-test for every architecture, without having to
manually add it to every architecture's list of tests. Commit 3687d53
accomplished this by adding it to every architecture's list
automatically.
However, some architectures inherit their tests from others, like this:
check-qtest-x86_64-y = $(check-qtest-i386-y)
check-qtest-microblazeel-y = $(check-qtest-microblaze-y)
check-qtest-xtensaeb-y = $(check-qtest-xtensa-y)
For such architectures, we ended up running the (slow!) test twice.
Commit 2b8419c attempted to avoid this by adding the test only when
it's not already present. Works only as long as we consider adding
the test to the architectures on the left hand side *after* the ones
on the right hand side: x86_64 after i386, microblazeel after
microblaze, xtensaeb after xtensa.
Turns out we consider them in $(SYSEMU_TARGET_LIST) order. Defined as
SYSEMU_TARGET_LIST := $(subst -softmmu.mak,,$(notdir \
$(wildcard $(SRC_PATH)/default-configs/*-softmmu.mak)))
On my machine, this results in the oder xtensa, x86_64, microblazeel,
microblaze, i386. Consequently, qom-test runs twice for microblazeel
and x86_64.
Replace this complex and flawed machinery with a much simpler one: add
generic tests (currently just qom-test) to check-qtest-generic-y
instead of check-qtest-$(target)-y for every target, then run
$(check-qtest-generic-y) for every target.
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Reviewed-by: Andreas Färber <afaerber@suse.de>
Message-Id: <1443689999-12182-5-git-send-email-armbru@redhat.com>
2015-10-01 11:59:53 +03:00
|
|
|
check-qtest-y += $(check-qtest-generic-y)
|
|
|
|
else
|
|
|
|
QTEST_TARGETS =
|
2014-03-28 13:55:54 +04:00
|
|
|
endif
|
2012-03-28 17:42:05 +04:00
|
|
|
|
2015-09-02 13:35:52 +03:00
|
|
|
qtest-obj-y = tests/libqtest.o $(test-util-obj-y)
|
2012-03-28 17:42:05 +04:00
|
|
|
$(check-qtest-y): $(qtest-obj-y)
|
|
|
|
|
2015-10-02 15:58:18 +03:00
|
|
|
tests/test-qga: tests/test-qga.o $(qtest-obj-y)
|
|
|
|
|
2012-03-28 17:42:01 +04:00
|
|
|
.PHONY: check-help
|
|
|
|
check-help:
|
|
|
|
@echo "Regression testing targets:"
|
|
|
|
@echo
|
|
|
|
@echo " make check Run all tests"
|
2012-03-28 17:42:05 +04:00
|
|
|
@echo " make check-qtest-TARGET Run qtest tests for given target"
|
|
|
|
@echo " make check-qtest Run qtest tests"
|
2012-03-28 17:42:01 +04:00
|
|
|
@echo " make check-unit Run qobject tests"
|
2013-07-27 19:41:53 +04:00
|
|
|
@echo " make check-qapi-schema Run QAPI schema tests"
|
2012-03-28 17:42:01 +04:00
|
|
|
@echo " make check-block Run block tests"
|
|
|
|
@echo " make check-report.html Generates an HTML test report"
|
2013-09-26 04:42:56 +04:00
|
|
|
@echo " make check-clean Clean the tests"
|
2012-03-28 17:42:01 +04:00
|
|
|
@echo
|
|
|
|
@echo "Please note that HTML reports do not regenerate if the unit tests"
|
|
|
|
@echo "has not changed."
|
|
|
|
@echo
|
|
|
|
@echo "The variable SPEED can be set to control the gtester speed setting."
|
|
|
|
@echo "Default options are -k and (for make V=1) --verbose; they can be"
|
|
|
|
@echo "changed with variable GTESTER_OPTIONS."
|
2012-02-09 14:21:03 +04:00
|
|
|
|
2012-03-28 17:42:01 +04:00
|
|
|
SPEED = quick
|
|
|
|
GTESTER_OPTIONS = -k $(if $(V),--verbose,-q)
|
2012-05-01 22:45:39 +04:00
|
|
|
GCOV_OPTIONS = -n $(if $(V),-f,)
|
2012-01-10 23:10:43 +04:00
|
|
|
|
2012-03-28 17:42:01 +04:00
|
|
|
# gtester tests, possibly with verbose output
|
2012-01-10 23:10:43 +04:00
|
|
|
|
2012-03-28 17:42:05 +04:00
|
|
|
.PHONY: $(patsubst %, check-qtest-%, $(QTEST_TARGETS))
|
|
|
|
$(patsubst %, check-qtest-%, $(QTEST_TARGETS)): check-qtest-%: $(check-qtest-y)
|
2012-05-01 22:45:39 +04:00
|
|
|
$(if $(CONFIG_GCOV),@rm -f *.gcda */*.gcda */*/*.gcda */*/*/*.gcda,)
|
2012-03-28 17:42:05 +04:00
|
|
|
$(call quiet-command,QTEST_QEMU_BINARY=$*-softmmu/qemu-system-$* \
|
2015-04-28 22:27:51 +03:00
|
|
|
QTEST_QEMU_IMG=qemu-img$(EXESUF) \
|
2013-05-27 17:28:51 +04:00
|
|
|
MALLOC_PERTURB_=$${MALLOC_PERTURB_:-$$((RANDOM % 255 + 1))} \
|
2016-10-04 19:27:21 +03:00
|
|
|
gtester $(GTESTER_OPTIONS) -m=$(SPEED) $(check-qtest-$*-y) $(check-qtest-generic-y),"GTESTER","$@")
|
2015-10-01 11:59:56 +03:00
|
|
|
$(if $(CONFIG_GCOV),@for f in $(gcov-files-$*-y) $(gcov-files-generic-y); do \
|
2012-05-01 22:45:39 +04:00
|
|
|
echo Gcov report for $$f:;\
|
|
|
|
$(GCOV) $(GCOV_OPTIONS) $$f -o `dirname $$f`; \
|
|
|
|
done,)
|
2012-03-28 17:42:05 +04:00
|
|
|
|
2012-03-28 17:42:01 +04:00
|
|
|
.PHONY: $(patsubst %, check-%, $(check-unit-y))
|
|
|
|
$(patsubst %, check-%, $(check-unit-y)): check-%: %
|
2012-05-01 22:45:39 +04:00
|
|
|
$(if $(CONFIG_GCOV),@rm -f *.gcda */*.gcda */*/*.gcda */*/*/*.gcda,)
|
2013-05-27 17:28:51 +04:00
|
|
|
$(call quiet-command, \
|
|
|
|
MALLOC_PERTURB_=$${MALLOC_PERTURB_:-$$((RANDOM % 255 + 1))} \
|
2016-10-04 19:27:21 +03:00
|
|
|
gtester $(GTESTER_OPTIONS) -m=$(SPEED) $*,"GTESTER","$*")
|
2015-10-01 11:59:56 +03:00
|
|
|
$(if $(CONFIG_GCOV),@for f in $(gcov-files-$(subst tests/,,$*)-y) $(gcov-files-generic-y); do \
|
2012-05-01 22:45:39 +04:00
|
|
|
echo Gcov report for $$f:;\
|
|
|
|
$(GCOV) $(GCOV_OPTIONS) $$f -o `dirname $$f`; \
|
|
|
|
done,)
|
2012-01-10 23:10:43 +04:00
|
|
|
|
2012-03-28 17:42:01 +04:00
|
|
|
# gtester tests with XML output
|
2012-03-08 15:29:00 +04:00
|
|
|
|
2012-03-28 17:42:05 +04:00
|
|
|
$(patsubst %, check-report-qtest-%.xml, $(QTEST_TARGETS)): check-report-qtest-%.xml: $(check-qtest-y)
|
|
|
|
$(call quiet-command,QTEST_QEMU_BINARY=$*-softmmu/qemu-system-$* \
|
2015-07-20 19:21:18 +03:00
|
|
|
QTEST_QEMU_IMG=qemu-img$(EXESUF) \
|
2016-10-04 19:27:21 +03:00
|
|
|
gtester -q $(GTESTER_OPTIONS) -o $@ -m=$(SPEED) $(check-qtest-$*-y) $(check-qtest-generic-y),"GTESTER","$@")
|
2012-03-28 17:42:05 +04:00
|
|
|
|
2012-03-28 17:42:01 +04:00
|
|
|
check-report-unit.xml: $(check-unit-y)
|
2016-10-04 19:27:21 +03:00
|
|
|
$(call quiet-command,gtester -q $(GTESTER_OPTIONS) -o $@ -m=$(SPEED) $^,"GTESTER","$@")
|
2012-03-09 16:37:40 +04:00
|
|
|
|
2012-03-28 17:42:01 +04:00
|
|
|
# Reports and overall runs
|
2012-03-09 16:37:40 +04:00
|
|
|
|
2012-03-28 17:42:05 +04:00
|
|
|
check-report.xml: $(patsubst %,check-report-qtest-%.xml, $(QTEST_TARGETS)) check-report-unit.xml
|
2016-10-04 19:27:21 +03:00
|
|
|
$(call quiet-command,$(SRC_PATH)/scripts/gtester-cat $^ > $@,"GEN","$@")
|
2012-03-09 16:37:40 +04:00
|
|
|
|
2012-03-28 17:42:01 +04:00
|
|
|
check-report.html: check-report.xml
|
2016-10-04 19:27:21 +03:00
|
|
|
$(call quiet-command,gtester-report $< > $@,"GEN","$@")
|
2012-03-28 17:42:01 +04:00
|
|
|
|
|
|
|
|
|
|
|
# Other tests
|
|
|
|
|
2013-09-26 04:42:55 +04:00
|
|
|
QEMU_IOTESTS_HELPERS-$(CONFIG_LINUX) = tests/qemu-iotests/socket_scm_helper$(EXESUF)
|
|
|
|
|
2012-03-28 17:42:01 +04:00
|
|
|
.PHONY: check-tests/qemu-iotests-quick.sh
|
2013-09-26 04:42:55 +04:00
|
|
|
check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh qemu-img$(EXESUF) qemu-io$(EXESUF) $(QEMU_IOTESTS_HELPERS-y)
|
2012-03-28 17:42:01 +04:00
|
|
|
$<
|
|
|
|
|
2013-07-27 19:41:53 +04:00
|
|
|
.PHONY: $(patsubst %, check-%, $(check-qapi-schema-y))
|
|
|
|
$(patsubst %, check-%, $(check-qapi-schema-y)): check-%.json: $(SRC_PATH)/%.json
|
2014-05-02 17:52:24 +04:00
|
|
|
$(call quiet-command, PYTHONPATH=$(SRC_PATH)/scripts \
|
|
|
|
$(PYTHON) $(SRC_PATH)/tests/qapi-schema/test-qapi.py \
|
2014-05-02 17:52:35 +04:00
|
|
|
$^ >$*.test.out 2>$*.test.err; \
|
2014-05-02 17:52:24 +04:00
|
|
|
echo $$? >$*.test.exit, \
|
2016-10-04 19:27:21 +03:00
|
|
|
"TEST","$*.out")
|
2013-09-24 11:43:39 +04:00
|
|
|
@diff -q $(SRC_PATH)/$*.out $*.test.out
|
2014-05-02 17:52:35 +04:00
|
|
|
@# Sanitize error messages (make them independent of build directory)
|
|
|
|
@perl -p -e 's|\Q$(SRC_PATH)\E/||g' $*.test.err | diff -q $(SRC_PATH)/$*.err -
|
2013-09-24 11:43:39 +04:00
|
|
|
@diff -q $(SRC_PATH)/$*.exit $*.test.exit
|
2013-07-27 19:41:53 +04:00
|
|
|
|
2017-03-20 16:11:54 +03:00
|
|
|
.PHONY: check-tests/qapi-schema/doc-good.texi
|
|
|
|
check-tests/qapi-schema/doc-good.texi: tests/qapi-schema/doc-good.test.texi
|
|
|
|
@diff -q $(SRC_PATH)/tests/qapi-schema/doc-good.texi $<
|
|
|
|
|
2012-03-28 17:42:01 +04:00
|
|
|
# Consolidated targets
|
|
|
|
|
2013-09-26 04:42:56 +04:00
|
|
|
.PHONY: check-qapi-schema check-qtest check-unit check check-clean
|
2017-03-20 16:11:54 +03:00
|
|
|
check-qapi-schema: $(patsubst %,check-%, $(check-qapi-schema-y)) check-tests/qapi-schema/doc-good.texi
|
2012-03-28 17:42:05 +04:00
|
|
|
check-qtest: $(patsubst %,check-qtest-%, $(QTEST_TARGETS))
|
2012-03-28 17:42:01 +04:00
|
|
|
check-unit: $(patsubst %,check-%, $(check-unit-y))
|
|
|
|
check-block: $(patsubst %,check-%, $(check-block-y))
|
2013-07-27 19:41:53 +04:00
|
|
|
check: check-qapi-schema check-unit check-qtest
|
2013-09-26 04:42:56 +04:00
|
|
|
check-clean:
|
|
|
|
$(MAKE) -C tests/tcg clean
|
2014-04-07 20:33:22 +04:00
|
|
|
rm -rf $(check-unit-y) tests/*.o $(QEMU_IOTESTS_HELPERS-y)
|
2015-11-21 04:20:06 +03:00
|
|
|
rm -rf $(sort $(foreach target,$(SYSEMU_TARGET_LIST), $(check-qtest-$(target)-y)) $(check-qtest-generic-y))
|
2013-09-26 04:42:56 +04:00
|
|
|
|
|
|
|
clean: check-clean
|
2012-07-18 21:22:27 +04:00
|
|
|
|
2013-09-26 04:42:55 +04:00
|
|
|
# Build the help program automatically
|
|
|
|
|
|
|
|
all: $(QEMU_IOTESTS_HELPERS-y)
|
|
|
|
|
2012-07-18 21:22:27 +04:00
|
|
|
-include $(wildcard tests/*.d)
|
2013-06-26 17:52:14 +04:00
|
|
|
-include $(wildcard tests/libqos/*.d)
|