aboutsummaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/.gitignore1
-rw-r--r--tests/Makefile.include2
-rw-r--r--tests/crypto-tls-x509-helpers.h3
-rw-r--r--tests/ide-test.c1
-rw-r--r--tests/ipmi-bt-test.c2
-rw-r--r--tests/ipmi-kcs-test.c2
-rwxr-xr-xtests/qemu-iotests/030313
-rw-r--r--tests/qemu-iotests/030.out4
-rwxr-xr-xtests/qemu-iotests/04127
-rw-r--r--tests/qemu-iotests/1393
-rwxr-xr-xtests/qemu-iotests/171212
-rw-r--r--tests/qemu-iotests/171.out313
-rw-r--r--tests/qemu-iotests/group1
-rw-r--r--tests/qemu-iotests/iotests.py5
-rw-r--r--tests/test-aio.c22
-rw-r--r--tests/test-blockjob-txn.c5
-rw-r--r--tests/test-blockjob.c4
-rw-r--r--tests/test-rfifolock.c91
-rw-r--r--tests/test-x86-cpuid-compat.c28
-rw-r--r--tests/vhost-user-test.c2
20 files changed, 902 insertions, 139 deletions
diff --git a/tests/.gitignore b/tests/.gitignore
index 64e050e859..c0d7857538 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -67,7 +67,6 @@ test-qmp-marshal.c
test-qobject-output-visitor
test-rcu-list
test-replication
-test-rfifolock
test-string-input-visitor
test-string-output-visitor
test-thread-pool
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 1a135d2340..de516341fd 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -45,7 +45,6 @@ check-unit-y += tests/test-visitor-serialization$(EXESUF)
check-unit-y += tests/test-iov$(EXESUF)
gcov-files-test-iov-y = util/iov.c
check-unit-y += tests/test-aio$(EXESUF)
-check-unit-$(CONFIG_POSIX) += tests/test-rfifolock$(EXESUF)
check-unit-y += tests/test-throttle$(EXESUF)
gcov-files-test-aio-$(CONFIG_WIN32) = aio-win32.c
gcov-files-test-aio-$(CONFIG_POSIX) = aio-posix.c
@@ -491,7 +490,6 @@ tests/check-qom-proplist$(EXESUF): tests/check-qom-proplist.o $(test-qom-obj-y)
tests/test-char$(EXESUF): tests/test-char.o qemu-char.o qemu-timer.o $(test-util-obj-y) $(qtest-obj-y) $(test-io-obj-y)
tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(test-block-obj-y)
tests/test-aio$(EXESUF): tests/test-aio.o $(test-block-obj-y)
-tests/test-rfifolock$(EXESUF): tests/test-rfifolock.o $(test-util-obj-y)
tests/test-throttle$(EXESUF): tests/test-throttle.o $(test-block-obj-y)
tests/test-blockjob$(EXESUF): tests/test-blockjob.o $(test-block-obj-y) $(test-util-obj-y)
tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(test-block-obj-y) $(test-util-obj-y)
diff --git a/tests/crypto-tls-x509-helpers.h b/tests/crypto-tls-x509-helpers.h
index a8faa92bc0..921341c649 100644
--- a/tests/crypto-tls-x509-helpers.h
+++ b/tests/crypto-tls-x509-helpers.h
@@ -21,9 +21,6 @@
#include <gnutls/gnutls.h>
#include <gnutls/x509.h>
-#include <gnutls/gnutls.h>
-#include <gnutls/x509.h>
-
#if !(defined WIN32) && \
defined(CONFIG_TASN1) && \
(LIBGNUTLS_VERSION_NUMBER >= 0x020600)
diff --git a/tests/ide-test.c b/tests/ide-test.c
index 67c7df0c8d..fb541f88b5 100644
--- a/tests/ide-test.c
+++ b/tests/ide-test.c
@@ -620,7 +620,6 @@ static void test_retry_flush(const char *machine)
prepare_blkdebug_script(debug_path, "flush_to_disk");
ide_test_start(
- "-vnc none "
"-drive file=blkdebug:%s:%s,if=ide,cache=writeback,format=raw,"
"rerror=stop,werror=stop",
debug_path, tmp_path);
diff --git a/tests/ipmi-bt-test.c b/tests/ipmi-bt-test.c
index 65d05b3d43..e84dd6889b 100644
--- a/tests/ipmi-bt-test.c
+++ b/tests/ipmi-bt-test.c
@@ -415,7 +415,7 @@ int main(int argc, char **argv)
/* Run the tests */
g_test_init(&argc, &argv, NULL);
- cmdline = g_strdup_printf("-vnc none"
+ cmdline = g_strdup_printf(
" -chardev socket,id=ipmi0,host=localhost,port=%d,reconnect=10"
" -device ipmi-bmc-extern,chardev=ipmi0,id=bmc0"
" -device isa-ipmi-bt,bmc=bmc0", emu_port);
diff --git a/tests/ipmi-kcs-test.c b/tests/ipmi-kcs-test.c
index 3750389651..9cf0b34a33 100644
--- a/tests/ipmi-kcs-test.c
+++ b/tests/ipmi-kcs-test.c
@@ -276,7 +276,7 @@ int main(int argc, char **argv)
/* Run the tests */
g_test_init(&argc, &argv, NULL);
- cmdline = g_strdup_printf("-vnc none -device ipmi-bmc-sim,id=bmc0"
+ cmdline = g_strdup_printf("-device ipmi-bmc-sim,id=bmc0"
" -device isa-ipmi-kcs,bmc=bmc0");
qtest_start(cmdline);
qtest_irq_intercept_in(global_qtest, "ioapic");
diff --git a/tests/qemu-iotests/030 b/tests/qemu-iotests/030
index 107049b50f..54db54a1ea 100755
--- a/tests/qemu-iotests/030
+++ b/tests/qemu-iotests/030
@@ -36,7 +36,7 @@ class TestSingleDrive(iotests.QMPTestCase):
qemu_img('create', '-f', iotests.imgfmt, '-o', 'backing_file=%s' % mid_img, test_img)
qemu_io('-f', 'raw', '-c', 'write -P 0x1 0 512', backing_img)
qemu_io('-f', iotests.imgfmt, '-c', 'write -P 0x1 524288 512', mid_img)
- self.vm = iotests.VM().add_drive("blkdebug::" + test_img)
+ self.vm = iotests.VM().add_drive("blkdebug::" + test_img, "backing.node-name=mid")
self.vm.launch()
def tearDown(self):
@@ -60,6 +60,25 @@ class TestSingleDrive(iotests.QMPTestCase):
qemu_io('-f', iotests.imgfmt, '-c', 'map', test_img),
'image file map does not match backing file after streaming')
+ def test_stream_intermediate(self):
+ self.assert_no_active_block_jobs()
+
+ self.assertNotEqual(qemu_io('-f', 'raw', '-c', 'map', backing_img),
+ qemu_io('-f', iotests.imgfmt, '-c', 'map', mid_img),
+ 'image file map matches backing file before streaming')
+
+ result = self.vm.qmp('block-stream', device='mid', job_id='stream-mid')
+ self.assert_qmp(result, 'return', {})
+
+ self.wait_until_completed(drive='stream-mid')
+
+ self.assert_no_active_block_jobs()
+ self.vm.shutdown()
+
+ self.assertEqual(qemu_io('-f', 'raw', '-c', 'map', backing_img),
+ qemu_io('-f', iotests.imgfmt, '-c', 'map', mid_img),
+ 'image file map does not match backing file after streaming')
+
def test_stream_pause(self):
self.assert_no_active_block_jobs()
@@ -129,6 +148,298 @@ class TestSingleDrive(iotests.QMPTestCase):
self.assert_qmp(result, 'error/class', 'GenericError')
+class TestParallelOps(iotests.QMPTestCase):
+ num_ops = 4 # Number of parallel block-stream operations
+ num_imgs = num_ops * 2 + 1
+ image_len = num_ops * 1024 * 1024
+ imgs = []
+
+ def setUp(self):
+ opts = []
+ self.imgs = []
+
+ # Initialize file names and command-line options
+ for i in range(self.num_imgs):
+ img_depth = self.num_imgs - i - 1
+ opts.append("backing." * img_depth + "node-name=node%d" % i)
+ self.imgs.append(os.path.join(iotests.test_dir, 'img-%d.img' % i))
+
+ # Create all images
+ iotests.create_image(self.imgs[0], self.image_len)
+ for i in range(1, self.num_imgs):
+ qemu_img('create', '-f', iotests.imgfmt,
+ '-o', 'backing_file=%s' % self.imgs[i-1], self.imgs[i])
+
+ # Put data into the images we are copying data from
+ for i in range(self.num_imgs / 2):
+ img_index = i * 2 + 1
+ # Alternate between 512k and 1M.
+ # This way jobs will not finish in the same order they were created
+ num_kb = 512 + 512 * (i % 2)
+ qemu_io('-f', iotests.imgfmt,
+ '-c', 'write -P %d %d %d' % (i, i*1024*1024, num_kb * 1024),
+ self.imgs[img_index])
+
+ # Attach the drive to the VM
+ self.vm = iotests.VM()
+ self.vm.add_drive(self.imgs[-1], ','.join(opts))
+ self.vm.launch()
+
+ def tearDown(self):
+ self.vm.shutdown()
+ for img in self.imgs:
+ os.remove(img)
+
+ # Test that it's possible to run several block-stream operations
+ # in parallel in the same snapshot chain
+ def test_stream_parallel(self):
+ self.assert_no_active_block_jobs()
+
+ # Check that the maps don't match before the streaming operations
+ for i in range(2, self.num_imgs, 2):
+ self.assertNotEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', self.imgs[i]),
+ qemu_io('-f', iotests.imgfmt, '-c', 'map', self.imgs[i-1]),
+ 'image file map matches backing file before streaming')
+
+ # Create all streaming jobs
+ pending_jobs = []
+ for i in range(2, self.num_imgs, 2):
+ node_name = 'node%d' % i
+ job_id = 'stream-%s' % node_name
+ pending_jobs.append(job_id)
+ result = self.vm.qmp('block-stream', device=node_name, job_id=job_id, base=self.imgs[i-2], speed=512*1024)
+ self.assert_qmp(result, 'return', {})
+
+ # Wait for all jobs to be finished.
+ while len(pending_jobs) > 0:
+ for event in self.vm.get_qmp_events(wait=True):
+ if event['event'] == 'BLOCK_JOB_COMPLETED':
+ job_id = self.dictpath(event, 'data/device')
+ self.assertTrue(job_id in pending_jobs)
+ self.assert_qmp_absent(event, 'data/error')
+ pending_jobs.remove(job_id)
+
+ self.assert_no_active_block_jobs()
+ self.vm.shutdown()
+
+ # Check that all maps match now
+ for i in range(2, self.num_imgs, 2):
+ self.assertEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', self.imgs[i]),
+ qemu_io('-f', iotests.imgfmt, '-c', 'map', self.imgs[i-1]),
+ 'image file map does not match backing file after streaming')
+
+ # Test that it's not possible to perform two block-stream
+ # operations if there are nodes involved in both.
+ def test_overlapping_1(self):
+ self.assert_no_active_block_jobs()
+
+ # Set a speed limit to make sure that this job blocks the rest
+ result = self.vm.qmp('block-stream', device='node4', job_id='stream-node4', base=self.imgs[1], speed=1024*1024)
+ self.assert_qmp(result, 'return', {})
+
+ result = self.vm.qmp('block-stream', device='node5', job_id='stream-node5', base=self.imgs[2])
+ self.assert_qmp(result, 'error/class', 'GenericError')
+
+ result = self.vm.qmp('block-stream', device='node3', job_id='stream-node3', base=self.imgs[2])
+ self.assert_qmp(result, 'error/class', 'GenericError')
+
+ result = self.vm.qmp('block-stream', device='node4', job_id='stream-node4-v2')
+ self.assert_qmp(result, 'error/class', 'GenericError')
+
+ # block-commit should also fail if it touches nodes used by the stream job
+ result = self.vm.qmp('block-commit', device='drive0', base=self.imgs[4], job_id='commit-node4')
+ self.assert_qmp(result, 'error/class', 'GenericError')
+
+ result = self.vm.qmp('block-commit', device='drive0', base=self.imgs[1], top=self.imgs[3], job_id='commit-node1')
+ self.assert_qmp(result, 'error/class', 'GenericError')
+
+ # This fails because it needs to modify the backing string in node2, which is blocked
+ result = self.vm.qmp('block-commit', device='drive0', base=self.imgs[0], top=self.imgs[1], job_id='commit-node0')
+ self.assert_qmp(result, 'error/class', 'GenericError')
+
+ self.wait_until_completed(drive='stream-node4')
+ self.assert_no_active_block_jobs()
+
+ # Similar to test_overlapping_1, but with block-commit
+ # blocking the other jobs
+ def test_overlapping_2(self):
+ self.assertLessEqual(9, self.num_imgs)
+ self.assert_no_active_block_jobs()
+
+ # Set a speed limit to make sure that this job blocks the rest
+ result = self.vm.qmp('block-commit', device='drive0', top=self.imgs[5], base=self.imgs[3], job_id='commit-node3', speed=1024*1024)
+ self.assert_qmp(result, 'return', {})
+
+ result = self.vm.qmp('block-stream', device='node3', job_id='stream-node3')
+ self.assert_qmp(result, 'error/class', 'GenericError')
+
+ result = self.vm.qmp('block-stream', device='node6', base=self.imgs[2], job_id='stream-node6')
+ self.assert_qmp(result, 'error/class', 'GenericError')
+
+ result = self.vm.qmp('block-stream', device='node4', base=self.imgs[2], job_id='stream-node4')
+ self.assert_qmp(result, 'error/class', 'GenericError')
+
+ result = self.vm.qmp('block-stream', device='node6', base=self.imgs[4], job_id='stream-node6-v2')
+ self.assert_qmp(result, 'error/class', 'GenericError')
+
+ # This fails because block-commit needs to block node6, the overlay of the 'top' image
+ result = self.vm.qmp('block-stream', device='node7', base=self.imgs[5], job_id='stream-node6-v3')
+ self.assert_qmp(result, 'error/class', 'GenericError')
+
+ # This fails because block-commit currently blocks the active layer even if it's not used
+ result = self.vm.qmp('block-stream', device='drive0', base=self.imgs[5], job_id='stream-drive0')
+ self.assert_qmp(result, 'error/class', 'GenericError')
+
+ self.wait_until_completed(drive='commit-node3')
+
+ # Similar to test_overlapping_2, but here block-commit doesn't use the 'top' parameter.
+ # Internally this uses a mirror block job, hence the separate test case.
+ def test_overlapping_3(self):
+ self.assertLessEqual(8, self.num_imgs)
+ self.assert_no_active_block_jobs()
+
+ # Set a speed limit to make sure that this job blocks the rest
+ result = self.vm.qmp('block-commit', device='drive0', base=self.imgs[3], job_id='commit-drive0', speed=1024*1024)
+ self.assert_qmp(result, 'return', {})
+
+ result = self.vm.qmp('block-stream', device='node5', base=self.imgs[3], job_id='stream-node6')
+ self.assert_qmp(result, 'error/class', 'GenericError')
+
+ event = self.vm.get_qmp_event(wait=True)
+ self.assertEqual(event['event'], 'BLOCK_JOB_READY')
+ self.assert_qmp(event, 'data/device', 'commit-drive0')
+ self.assert_qmp(event, 'data/type', 'commit')
+ self.assert_qmp_absent(event, 'data/error')
+
+ result = self.vm.qmp('block-job-complete', device='commit-drive0')
+ self.assert_qmp(result, 'return', {})
+
+ self.wait_until_completed(drive='commit-drive0')
+
+ # Test a block-stream and a block-commit job in parallel
+ def test_stream_commit(self):
+ self.assertLessEqual(8, self.num_imgs)
+ self.assert_no_active_block_jobs()
+
+ # Stream from node0 into node2
+ result = self.vm.qmp('block-stream', device='node2', job_id='node2')
+ self.assert_qmp(result, 'return', {})
+
+ # Commit from the active layer into node3
+ result = self.vm.qmp('block-commit', device='drive0', base=self.imgs[3])
+ self.assert_qmp(result, 'return', {})
+
+ # Wait for all jobs to be finished.
+ pending_jobs = ['node2', 'drive0']
+ while len(pending_jobs) > 0:
+ for event in self.vm.get_qmp_events(wait=True):
+ if event['event'] == 'BLOCK_JOB_COMPLETED':
+ node_name = self.dictpath(event, 'data/device')
+ self.assertTrue(node_name in pending_jobs)
+ self.assert_qmp_absent(event, 'data/error')
+ pending_jobs.remove(node_name)
+ if event['event'] == 'BLOCK_JOB_READY':
+ self.assert_qmp(event, 'data/device', 'drive0')
+ self.assert_qmp(event, 'data/type', 'commit')
+ self.assert_qmp_absent(event, 'data/error')
+ self.assertTrue('drive0' in pending_jobs)
+ self.vm.qmp('block-job-complete', device='drive0')
+
+ self.assert_no_active_block_jobs()
+
+ # Test the base_node parameter
+ def test_stream_base_node_name(self):
+ self.assert_no_active_block_jobs()
+
+ self.assertNotEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', self.imgs[4]),
+ qemu_io('-f', iotests.imgfmt, '-c', 'map', self.imgs[3]),
+ 'image file map matches backing file before streaming')
+
+ # Error: the base node does not exist
+ result = self.vm.qmp('block-stream', device='node4', base_node='none', job_id='stream')
+ self.assert_qmp(result, 'error/class', 'GenericError')
+
+ # Error: the base node is not a backing file of the top node
+ result = self.vm.qmp('block-stream', device='node4', base_node='node6', job_id='stream')
+ self.assert_qmp(result, 'error/class', 'GenericError')
+
+ # Error: the base node is the same as the top node
+ result = self.vm.qmp('block-stream', device='node4', base_node='node4', job_id='stream')
+ self.assert_qmp(result, 'error/class', 'GenericError')
+
+ # Error: cannot specify 'base' and 'base-node' at the same time
+ result = self.vm.qmp('block-stream', device='node4', base=self.imgs[2], base_node='node2', job_id='stream')
+ self.assert_qmp(result, 'error/class', 'GenericError')
+
+ # Success: the base node is a backing file of the top node
+ result = self.vm.qmp('block-stream', device='node4', base_node='node2', job_id='stream')
+ self.assert_qmp(result, 'return', {})
+
+ self.wait_until_completed(drive='stream')
+
+ self.assert_no_active_block_jobs()
+ self.vm.shutdown()
+
+ self.assertEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', self.imgs[4]),
+ qemu_io('-f', iotests.imgfmt, '-c', 'map', self.imgs[3]),
+ 'image file map matches backing file after streaming')
+
+class TestQuorum(iotests.QMPTestCase):
+ num_children = 3
+ children = []
+ backing = []
+
+ def setUp(self):
+ opts = ['driver=quorum', 'vote-threshold=2']
+
+ # Initialize file names and command-line options
+ for i in range(self.num_children):
+ child_img = os.path.join(iotests.test_dir, 'img-%d.img' % i)
+ backing_img = os.path.join(iotests.test_dir, 'backing-%d.img' % i)
+ self.children.append(child_img)
+ self.backing.append(backing_img)
+ qemu_img('create', '-f', iotests.imgfmt, backing_img, '1M')
+ qemu_io('-f', iotests.imgfmt,
+ '-c', 'write -P 0x55 0 1024', backing_img)
+ qemu_img('create', '-f', iotests.imgfmt,
+ '-o', 'backing_file=%s' % backing_img, child_img)
+ opts.append("children.%d.file.filename=%s" % (i, child_img))
+ opts.append("children.%d.node-name=node%d" % (i, i))
+
+ # Attach the drive to the VM
+ self.vm = iotests.VM()
+ self.vm.add_drive(path = None, opts = ','.join(opts))
+ self.vm.launch()
+
+ def tearDown(self):
+ self.vm.shutdown()
+ for img in self.children:
+ os.remove(img)
+ for img in self.backing:
+ os.remove(img)
+
+ def test_stream_quorum(self):
+ if not iotests.supports_quorum():
+ return
+
+ self.assertNotEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', self.children[0]),
+ qemu_io('-f', iotests.imgfmt, '-c', 'map', self.backing[0]),
+ 'image file map matches backing file before streaming')
+
+ self.assert_no_active_block_jobs()
+
+ result = self.vm.qmp('block-stream', device='node0', job_id='stream-node0')
+ self.assert_qmp(result, 'return', {})
+
+ self.wait_until_completed(drive='stream-node0')
+
+ self.assert_no_active_block_jobs()
+ self.vm.shutdown()
+
+ self.assertEqual(qemu_io('-f', iotests.imgfmt, '-c', 'map', self.children[0]),
+ qemu_io('-f', iotests.imgfmt, '-c', 'map', self.backing[0]),
+ 'image file map does not match backing file after streaming')
+
class TestSmallerBackingFile(iotests.QMPTestCase):
backing_len = 1 * 1024 * 1024 # MB
image_len = 2 * backing_len
diff --git a/tests/qemu-iotests/030.out b/tests/qemu-iotests/030.out
index 6323079e08..84bfd63fba 100644
--- a/tests/qemu-iotests/030.out
+++ b/tests/qemu-iotests/030.out
@@ -1,5 +1,5 @@
-..............
+......................
----------------------------------------------------------------------
-Ran 14 tests
+Ran 22 tests
OK
diff --git a/tests/qemu-iotests/041 b/tests/qemu-iotests/041
index 30e628f0f7..bc6cf782fe 100755
--- a/tests/qemu-iotests/041
+++ b/tests/qemu-iotests/041
@@ -760,9 +760,6 @@ class TestRepairQuorum(iotests.QMPTestCase):
image_len = 1 * 1024 * 1024 # MB
IMAGES = [ quorum_img1, quorum_img2, quorum_img3 ]
- def has_quorum(self):
- return 'quorum' in iotests.qemu_img_pipe('--help')
-
def setUp(self):
self.vm = iotests.VM()
@@ -783,7 +780,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
#assemble the quorum block device from the individual files
args = { "driver": "quorum", "node-name": "quorum0",
"vote-threshold": 2, "children": [ "img0", "img1", "img2" ] }
- if self.has_quorum():
+ if iotests.supports_quorum():
result = self.vm.qmp("blockdev-add", **args)
self.assert_qmp(result, 'return', {})
@@ -798,7 +795,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
pass
def test_complete(self):
- if not self.has_quorum():
+ if not iotests.supports_quorum():
return
self.assert_no_active_block_jobs()
@@ -817,7 +814,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
'target image does not match source after mirroring')
def test_cancel(self):
- if not self.has_quorum():
+ if not iotests.supports_quorum():
return
self.assert_no_active_block_jobs()
@@ -834,7 +831,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
self.vm.shutdown()
def test_cancel_after_ready(self):
- if not self.has_quorum():
+ if not iotests.supports_quorum():
return
self.assert_no_active_block_jobs()
@@ -853,7 +850,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
'target image does not match source after mirroring')
def test_pause(self):
- if not self.has_quorum():
+ if not iotests.supports_quorum():
return
self.assert_no_active_block_jobs()
@@ -883,7 +880,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
'target image does not match source after mirroring')
def test_medium_not_found(self):
- if not self.has_quorum():
+ if not iotests.supports_quorum():
return
if iotests.qemu_default_machine != 'pc':
@@ -897,7 +894,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
self.assert_qmp(result, 'error/class', 'GenericError')
def test_image_not_found(self):
- if not self.has_quorum():
+ if not iotests.supports_quorum():
return
result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
@@ -907,7 +904,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
self.assert_qmp(result, 'error/class', 'GenericError')
def test_device_not_found(self):
- if not self.has_quorum():
+ if not iotests.supports_quorum():
return
result = self.vm.qmp('drive-mirror', job_id='job0',
@@ -918,7 +915,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
self.assert_qmp(result, 'error/class', 'GenericError')
def test_wrong_sync_mode(self):
- if not self.has_quorum():
+ if not iotests.supports_quorum():
return
result = self.vm.qmp('drive-mirror', device='quorum0', job_id='job0',
@@ -928,7 +925,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
self.assert_qmp(result, 'error/class', 'GenericError')
def test_no_node_name(self):
- if not self.has_quorum():
+ if not iotests.supports_quorum():
return
result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
@@ -937,7 +934,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
self.assert_qmp(result, 'error/class', 'GenericError')
def test_nonexistent_replaces(self):
- if not self.has_quorum():
+ if not iotests.supports_quorum():
return
result = self.vm.qmp('drive-mirror', job_id='job0', device='quorum0',
@@ -946,7 +943,7 @@ class TestRepairQuorum(iotests.QMPTestCase):
self.assert_qmp(result, 'error/class', 'GenericError')
def test_after_a_quorum_snapshot(self):
- if not self.has_quorum():
+ if not iotests.supports_quorum():
return
result = self.vm.qmp('blockdev-snapshot-sync', node_name='img1',
diff --git a/tests/qemu-iotests/139 b/tests/qemu-iotests/139
index 6a0f6ca569..6d98e4f879 100644
--- a/tests/qemu-iotests/139
+++ b/tests/qemu-iotests/139
@@ -336,8 +336,9 @@ class TestBlockdevDel(iotests.QMPTestCase):
self.checkBlockDriverState('node1', False)
def testQuorum(self):
- if not 'quorum' in iotests.qemu_img_pipe('--help'):
+ if not iotests.supports_quorum():
return
+
self.addQuorum('quorum0', 'node0', 'node1')
# We cannot remove the children of a Quorum device
self.delBlockDriverState('node0', expect_error = True)
diff --git a/tests/qemu-iotests/171 b/tests/qemu-iotests/171
new file mode 100755
index 0000000000..257be10a0e
--- /dev/null
+++ b/tests/qemu-iotests/171
@@ -0,0 +1,212 @@
+#!/bin/bash
+#
+# Test 'offset' and 'size' options of the raw driver. Make sure we can't
+# (or can) read and write outside of the image size.
+#
+# Copyright (C) 2016 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+
+# creator
+owner=tgolembi@redhat.com
+
+seq=`basename $0`
+echo "QA output created by $seq"
+
+here=`pwd`
+status=1 # failure is the default!
+
+_cleanup()
+{
+ _cleanup_test_img
+}
+trap "_cleanup; exit \$status" 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+_supported_fmt raw
+_supported_proto file
+_supported_os Linux
+
+
+# Create JSON with options
+img_json() {
+ echo -n 'json:{"driver":"raw", '
+ echo -n "\"offset\":\"$img_offset\", "
+ if [ "$img_size" -ne -1 ] ; then
+ echo -n "\"size\":\"$img_size\", "
+ fi
+ echo -n '"file": {'
+ echo -n '"driver":"file", '
+ echo -n "\"filename\":\"$TEST_IMG\" "
+ echo -n "} }"
+}
+
+do_general_test() {
+ if [ "$img_size" -ge 0 ] ; then
+ test_size=$img_size
+ else
+ test_size=$((size-img_offset))
+ fi
+
+ echo
+ echo "write to image"
+ $QEMU_IO -c "write -P 0x0a 0 $test_size" "$(img_json)" | _filter_qemu_io
+
+ echo
+ echo "read the image"
+ $QEMU_IO -c "read -P 0x0a 0 $test_size" "$(img_json)" | _filter_qemu_io
+
+ echo
+ echo "check that offset is respected"
+ $QEMU_IO -c "read -v $((img_offset-2)) 4" $TEST_IMG | _filter_qemu_io
+
+ echo
+ echo "write before image boundary"
+ $QEMU_IO -c "write $((test_size-1)) 1" "$(img_json)" | _filter_qemu_io
+
+ echo
+ echo "write across image boundary"
+ $QEMU_IO -c "write $((test_size-1)) 2" "$(img_json)" | _filter_qemu_io
+
+ echo
+ echo "write at image boundary"
+ $QEMU_IO -c "write $test_size 1" "$(img_json)" | _filter_qemu_io
+
+ echo
+ echo "write after image boundary"
+ $QEMU_IO -c "write $((test_size+512)) 1" "$(img_json)" | _filter_qemu_io
+
+ echo
+ echo "writev before/after image boundary"
+ $QEMU_IO -c "writev $((test_size-512)) 512 512" "$(img_json)" | _filter_qemu_io
+
+ echo
+ echo "read before image boundary"
+ $QEMU_IO -c "read $((test_size-1)) 1" "$(img_json)" | _filter_qemu_io
+
+ echo
+ echo "read across image boundary"
+ $QEMU_IO -c "read $((test_size-1)) 2" "$(img_json)" | _filter_qemu_io
+
+ echo
+ echo "read at image boundary"
+ $QEMU_IO -c "read $test_size 1" "$(img_json)" | _filter_qemu_io
+
+ echo
+ echo "read after image boundary"
+ $QEMU_IO -c "read $((test_size+512)) 1" "$(img_json)" | _filter_qemu_io
+
+ echo
+ echo "readv before/after image boundary"
+ $QEMU_IO -c "readv $((test_size-512)) 512 512" "$(img_json)" | _filter_qemu_io
+
+ echo
+ echo "fill image with pattern"
+ $QEMU_IO -c "write -P 0x0a 0 $size" $TEST_IMG | _filter_qemu_io
+
+ echo
+ echo "write zeroes and check"
+ $QEMU_IO -c "write -z 0 512" "$(img_json)" | _filter_qemu_io
+ $QEMU_IO -c "read -v $((img_offset-2)) 4" $TEST_IMG | _filter_qemu_io
+
+ echo
+ echo "write zeroes across image boundary"
+ $QEMU_IO -c "write -z $((test_size-1)) 2" "$(img_json)" | _filter_qemu_io
+
+ echo
+ echo "write zeroes at image boundary and check"
+ $QEMU_IO -c "write -z $((test_size-2)) 2" "$(img_json)" | _filter_qemu_io
+ $QEMU_IO -c "read -v $((img_offset+test_size-2)) 2" $TEST_IMG | _filter_qemu_io
+ $QEMU_IO -c "read -v $((img_offset+test_size)) 2" $TEST_IMG | _filter_qemu_io
+
+ echo
+ echo "fill image with pattern"
+ $QEMU_IO -c "write -P 0x0a 0 $size" $TEST_IMG | _filter_qemu_io
+
+ echo
+ echo "discard and check"
+ $QEMU_IO -c "discard 0 512" "$(img_json)" | _filter_qemu_io
+ $QEMU_IO -c "read -v $((img_offset-2)) 4" $TEST_IMG | _filter_qemu_io
+
+ echo
+ echo "discard across image boundary"
+ $QEMU_IO -c "discard $((test_size-1)) 2" "$(img_json)" | _filter_qemu_io
+
+ echo
+ echo "discard at image boundary and check"
+ $QEMU_IO -c "discard $((test_size-2)) 2" "$(img_json)" | _filter_qemu_io
+ $QEMU_IO -c "read -v $((img_offset+test_size-2)) 2" $TEST_IMG | _filter_qemu_io
+ $QEMU_IO -c "read -v $((img_offset+test_size)) 2" $TEST_IMG | _filter_qemu_io
+}
+
+echo
+echo "== test 'offset' option =="
+size=4096
+img_offset=512
+img_size=-1
+_make_test_img $size
+do_general_test
+_cleanup_test_img
+
+echo
+echo "== test 'offset' and 'size' options =="
+size=4096
+img_offset=512
+img_size=2048
+_make_test_img $size
+do_general_test
+_cleanup_test_img
+
+echo
+echo "== test misaligned 'offset' =="
+size=4096
+img_offset=10
+img_size=2048
+_make_test_img $size
+do_general_test
+_cleanup_test_img
+
+echo
+echo "== test reopen =="
+size=4096
+img_offset=512
+img_size=512
+_make_test_img $size
+(
+$QEMU_IO "$(img_json)" <<EOT
+write -P 0x0a 0 512
+write -P 0x0a 511 1
+write -P 0x0a 512 1
+reopen -o driver=raw,offset=1536,size=1024
+write -P 0x0a 0 1024
+write -P 0x0a 1023 1
+write -P 0x0a 1024 1
+EOT
+) | _filter_qemu_io
+echo "checking boundaries"
+$QEMU_IO -c "read -v 510 4" $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "read -v 1022 4" $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "read -v 1534 4" $TEST_IMG | _filter_qemu_io
+$QEMU_IO -c "read -v 2558 4" $TEST_IMG | _filter_qemu_io
+_cleanup_test_img
+
+# success, all done
+echo
+echo "*** done"
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/171.out b/tests/qemu-iotests/171.out
new file mode 100644
index 0000000000..ec3363b4f4
--- /dev/null
+++ b/tests/qemu-iotests/171.out
@@ -0,0 +1,313 @@
+QA output created by 171
+
+== test 'offset' option ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4096
+
+write to image
+wrote 3584/3584 bytes at offset 0
+3.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+read the image
+read 3584/3584 bytes at offset 0
+3.500 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+check that offset is respected
+000001fe: 00 00 0a 0a ....
+read 4/4 bytes at offset 510
+4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+write before image boundary
+wrote 1/1 bytes at offset 3583
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+write across image boundary
+write failed: Input/output error
+
+write at image boundary
+write failed: Input/output error
+
+write after image boundary
+write failed: Input/output error
+
+writev before/after image boundary
+writev failed: Input/output error
+
+read before image boundary
+read 1/1 bytes at offset 3583
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+read across image boundary
+read failed: Input/output error
+
+read at image boundary
+read failed: Input/output error
+
+read after image boundary
+read failed: Input/output error
+
+readv before/after image boundary
+readv failed: Input/output error
+
+fill image with pattern
+wrote 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+write zeroes and check
+wrote 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+000001fe: 0a 0a 00 00 ....
+read 4/4 bytes at offset 510
+4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+write zeroes across image boundary
+write failed: Input/output error
+
+write zeroes at image boundary and check
+wrote 2/2 bytes at offset 3582
+2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+00000ffe: 00 00 ..
+read 2/2 bytes at offset 4094
+2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read failed: Input/output error
+
+fill image with pattern
+wrote 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+discard and check
+discard 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+000001fe: 0a 0a 00 00 ....
+read 4/4 bytes at offset 510
+4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+discard across image boundary
+discard failed: Input/output error
+
+discard at image boundary and check
+discard 2/2 bytes at offset 3582
+2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+00000ffe: 00 00 ..
+read 2/2 bytes at offset 4094
+2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+read failed: Input/output error
+
+== test 'offset' and 'size' options ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4096
+
+write to image
+wrote 2048/2048 bytes at offset 0
+2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+read the image
+read 2048/2048 bytes at offset 0
+2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+check that offset is respected
+000001fe: 00 00 0a 0a ....
+read 4/4 bytes at offset 510
+4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+write before image boundary
+wrote 1/1 bytes at offset 2047
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+write across image boundary
+write failed: Input/output error
+
+write at image boundary
+write failed: Input/output error
+
+write after image boundary
+write failed: Input/output error
+
+writev before/after image boundary
+writev failed: Input/output error
+
+read before image boundary
+read 1/1 bytes at offset 2047
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+read across image boundary
+read failed: Input/output error
+
+read at image boundary
+read failed: Input/output error
+
+read after image boundary
+read failed: Input/output error
+
+readv before/after image boundary
+readv failed: Input/output error
+
+fill image with pattern
+wrote 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+write zeroes and check
+wrote 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+000001fe: 0a 0a 00 00 ....
+read 4/4 bytes at offset 510
+4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+write zeroes across image boundary
+write failed: Input/output error
+
+write zeroes at image boundary and check
+wrote 2/2 bytes at offset 2046
+2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+000009fe: 00 00 ..
+read 2/2 bytes at offset 2558
+2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+00000a00: 0a 0a ..
+read 2/2 bytes at offset 2560
+2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+fill image with pattern
+wrote 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+discard and check
+discard 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+000001fe: 0a 0a 00 00 ....
+read 4/4 bytes at offset 510
+4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+discard across image boundary
+discard failed: Input/output error
+
+discard at image boundary and check
+discard 2/2 bytes at offset 2046
+2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+000009fe: 00 00 ..
+read 2/2 bytes at offset 2558
+2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+00000a00: 0a 0a ..
+read 2/2 bytes at offset 2560
+2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== test misaligned 'offset' ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4096
+
+write to image
+wrote 2048/2048 bytes at offset 0
+2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+read the image
+read 2048/2048 bytes at offset 0
+2 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+check that offset is respected
+00000008: 00 00 0a 0a ....
+read 4/4 bytes at offset 8
+4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+write before image boundary
+wrote 1/1 bytes at offset 2047
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+write across image boundary
+write failed: Input/output error
+
+write at image boundary
+write failed: Input/output error
+
+write after image boundary
+write failed: Input/output error
+
+writev before/after image boundary
+writev failed: Input/output error
+
+read before image boundary
+read 1/1 bytes at offset 2047
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+read across image boundary
+read failed: Input/output error
+
+read at image boundary
+read failed: Input/output error
+
+read after image boundary
+read failed: Input/output error
+
+readv before/after image boundary
+readv failed: Input/output error
+
+fill image with pattern
+wrote 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+write zeroes and check
+wrote 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+00000008: 0a 0a 00 00 ....
+read 4/4 bytes at offset 8
+4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+write zeroes across image boundary
+write failed: Input/output error
+
+write zeroes at image boundary and check
+wrote 2/2 bytes at offset 2046
+2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+00000808: 00 00 ..
+read 2/2 bytes at offset 2056
+2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+0000080a: 0a 0a ..
+read 2/2 bytes at offset 2058
+2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+fill image with pattern
+wrote 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+discard and check
+discard 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+00000008: 0a 0a 00 00 ....
+read 4/4 bytes at offset 8
+4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+discard across image boundary
+discard failed: Input/output error
+
+discard at image boundary and check
+discard 2/2 bytes at offset 2046
+2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+00000808: 00 00 ..
+read 2/2 bytes at offset 2056
+2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+0000080a: 0a 0a ..
+read 2/2 bytes at offset 2058
+2 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+== test reopen ==
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=4096
+wrote 512/512 bytes at offset 0
+512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 1/1 bytes at offset 511
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+write failed: Input/output error
+wrote 1024/1024 bytes at offset 0
+1 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 1/1 bytes at offset 1023
+1 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+write failed: Input/output error
+checking boundaries
+000001fe: 00 00 0a 0a ....
+read 4/4 bytes at offset 510
+4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+000003fe: 0a 0a 00 00 ....
+read 4/4 bytes at offset 1022
+4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+000005fe: 00 00 0a 0a ....
+read 4/4 bytes at offset 1534
+4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+000009fe: 0a 0a 00 00 ....
+read 4/4 bytes at offset 2558
+4 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 597fc2c952..866c1a032d 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -163,4 +163,5 @@
160 rw auto quick
162 auto quick
170 rw auto quick
+171 rw auto quick
172 auto
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 1f30cfcc75..bec8eb4b8d 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -348,9 +348,12 @@ def verify_platform(supported_oses=['linux']):
if True not in [sys.platform.startswith(x) for x in supported_oses]:
notrun('not suitable for this OS: %s' % sys.platform)
+def supports_quorum():
+ return 'quorum' in qemu_img_pipe('--help')
+
def verify_quorum():
'''Skip test suite if quorum support is not available'''
- if 'quorum' not in qemu_img_pipe('--help'):
+ if not supports_quorum():
notrun('quorum support missing')
def main(supported_fmts=[], supported_oses=['linux']):
diff --git a/tests/test-aio.c b/tests/test-aio.c
index 03aa846970..5be99f8287 100644
--- a/tests/test-aio.c
+++ b/tests/test-aio.c
@@ -100,6 +100,7 @@ static void event_ready_cb(EventNotifier *e)
typedef struct {
QemuMutex start_lock;
+ EventNotifier notifier;
bool thread_acquired;
} AcquireTestData;
@@ -111,6 +112,11 @@ static void *test_acquire_thread(void *opaque)
qemu_mutex_lock(&data->start_lock);
qemu_mutex_unlock(&data->start_lock);
+ /* event_notifier_set might be called either before or after
+ * the main thread's call to poll(). The test case's outcome
+ * should be the same in either case.
+ */
+ event_notifier_set(&data->notifier);
aio_context_acquire(ctx);
aio_context_release(ctx);
@@ -125,20 +131,19 @@ static void set_event_notifier(AioContext *ctx, EventNotifier *notifier,
aio_set_event_notifier(ctx, notifier, false, handler);
}
-static void dummy_notifier_read(EventNotifier *unused)
+static void dummy_notifier_read(EventNotifier *n)
{
- g_assert(false); /* should never be invoked */
+ event_notifier_test_and_clear(n);
}
static void test_acquire(void)
{
QemuThread thread;
- EventNotifier notifier;
AcquireTestData data;
/* Dummy event notifier ensures aio_poll() will block */
- event_notifier_init(&notifier, false);
- set_event_notifier(ctx, &notifier, dummy_notifier_read);
+ event_notifier_init(&data.notifier, false);
+ set_event_notifier(ctx, &data.notifier, dummy_notifier_read);
g_assert(!aio_poll(ctx, false)); /* consume aio_notify() */
qemu_mutex_init(&data.start_lock);
@@ -152,12 +157,13 @@ static void test_acquire(void)
/* Block in aio_poll(), let other thread kick us and acquire context */
aio_context_acquire(ctx);
qemu_mutex_unlock(&data.start_lock); /* let the thread run */
- g_assert(!aio_poll(ctx, true));
+ g_assert(aio_poll(ctx, true));
+ g_assert(!data.thread_acquired);
aio_context_release(ctx);
qemu_thread_join(&thread);
- set_event_notifier(ctx, &notifier, NULL);
- event_notifier_cleanup(&notifier);
+ set_event_notifier(ctx, &data.notifier, NULL);
+ event_notifier_cleanup(&data.notifier);
g_assert(data.thread_acquired);
}
diff --git a/tests/test-blockjob-txn.c b/tests/test-blockjob-txn.c
index d049cba8a3..f9afc3be41 100644
--- a/tests/test-blockjob-txn.c
+++ b/tests/test-blockjob-txn.c
@@ -13,7 +13,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/main-loop.h"
-#include "block/blockjob.h"
+#include "block/blockjob_int.h"
#include "sysemu/block-backend.h"
typedef struct {
@@ -98,7 +98,8 @@ static BlockJob *test_block_job_start(unsigned int iterations,
bs = bdrv_new();
snprintf(job_id, sizeof(job_id), "job%u", counter++);
s = block_job_create(job_id, &test_block_job_driver, bs, 0,
- test_block_job_cb, data, &error_abort);
+ BLOCK_JOB_DEFAULT, test_block_job_cb,
+ data, &error_abort);
s->iterations = iterations;
s->use_timer = use_timer;
s->rc = rc;
diff --git a/tests/test-blockjob.c b/tests/test-blockjob.c
index 5b0e934a0c..60b78a3342 100644
--- a/tests/test-blockjob.c
+++ b/tests/test-blockjob.c
@@ -13,7 +13,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/main-loop.h"
-#include "block/blockjob.h"
+#include "block/blockjob_int.h"
#include "sysemu/block-backend.h"
static const BlockJobDriver test_block_job_driver = {
@@ -31,7 +31,7 @@ static BlockJob *do_test_id(BlockBackend *blk, const char *id,
Error *errp = NULL;
job = block_job_create(id, &test_block_job_driver, blk_bs(blk), 0,
- block_job_cb, NULL, &errp);
+ BLOCK_JOB_DEFAULT, block_job_cb, NULL, &errp);
if (should_succeed) {
g_assert_null(errp);
g_assert_nonnull(job);
diff --git a/tests/test-rfifolock.c b/tests/test-rfifolock.c
deleted file mode 100644
index 471a81114d..0000000000
--- a/tests/test-rfifolock.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/*
- * RFifoLock tests
- *
- * Copyright Red Hat, Inc. 2013
- *
- * Authors:
- * Stefan Hajnoczi <stefanha@redhat.com>
- *
- * This work is licensed under the terms of the GNU LGPL, version 2 or later.
- * See the COPYING.LIB file in the top-level directory.
- */
-
-#include "qemu/osdep.h"
-#include "qemu-common.h"
-#include "qemu/rfifolock.h"
-
-static void test_nesting(void)
-{
- RFifoLock lock;
-
- /* Trivial test, ensure the lock is recursive */
- rfifolock_init(&lock, NULL, NULL);
- rfifolock_lock(&lock);
- rfifolock_lock(&lock);
- rfifolock_lock(&lock);
- rfifolock_unlock(&lock);
- rfifolock_unlock(&lock);
- rfifolock_unlock(&lock);
- rfifolock_destroy(&lock);
-}
-
-typedef struct {
- RFifoLock lock;
- int fd[2];
-} CallbackTestData;
-
-static void rfifolock_cb(void *opaque)
-{
- CallbackTestData *data = opaque;
- int ret;
- char c = 0;
-
- ret = write(data->fd[1], &c, sizeof(c));
- g_assert(ret == 1);
-}
-
-static void *callback_thread(void *opaque)
-{
- CallbackTestData *data = opaque;
-
- /* The other thread holds the lock so the contention callback will be
- * invoked...
- */
- rfifolock_lock(&data->lock);
- rfifolock_unlock(&data->lock);
- return NULL;
-}
-
-static void test_callback(void)
-{
- CallbackTestData data;
- QemuThread thread;
- int ret;
- char c;
-
- rfifolock_init(&data.lock, rfifolock_cb, &data);
- ret = qemu_pipe(data.fd);
- g_assert(ret == 0);
-
- /* Hold lock but allow the callback to kick us by writing to the pipe */
- rfifolock_lock(&data.lock);
- qemu_thread_create(&thread, "callback_thread",
- callback_thread, &data, QEMU_THREAD_JOINABLE);
- ret = read(data.fd[0], &c, sizeof(c));
- g_assert(ret == 1);
- rfifolock_unlock(&data.lock);
- /* If we got here then the callback was invoked, as expected */
-
- qemu_thread_join(&thread);
- close(data.fd[0]);
- close(data.fd[1]);
- rfifolock_destroy(&data.lock);
-}
-
-int main(int argc, char **argv)
-{
- g_test_init(&argc, &argv, NULL);
- g_test_add_func("/nesting", test_nesting);
- g_test_add_func("/callback", test_callback);
- return g_test_run();
-}
diff --git a/tests/test-x86-cpuid-compat.c b/tests/test-x86-cpuid-compat.c
index 260dd2795c..79a2e69a28 100644
--- a/tests/test-x86-cpuid-compat.c
+++ b/tests/test-x86-cpuid-compat.c
@@ -35,6 +35,7 @@ static QObject *qom_get(const char *path, const char *prop)
return ret;
}
+#ifdef CONFIG_HAS_GLIB_SUBPROCESS_TESTS
static bool qom_get_bool(const char *path, const char *prop)
{
QBool *value = qobject_to_qbool(qom_get(path, prop));
@@ -43,6 +44,7 @@ static bool qom_get_bool(const char *path, const char *prop)
QDECREF(value);
return b;
}
+#endif
typedef struct CpuidTestArgs {
const char *cmdline;
@@ -76,7 +78,8 @@ static void add_cpuid_test(const char *name, const char *cmdline,
qtest_add_data_func(name, args, test_cpuid_prop);
}
-static void test_plus_minus(void)
+#ifdef CONFIG_HAS_GLIB_SUBPROCESS_TESTS
+static void test_plus_minus_subprocess(void)
{
char *path;
@@ -86,9 +89,8 @@ static void test_plus_minus(void)
* 3) Old feature names with underscores (e.g. "sse4_2")
* should keep working
*
- * Note: rules 1 and 2 are planned to be removed soon, but we
- * need to keep compatibility for a while until we start
- * warning users about it.
+ * Note: rules 1 and 2 are planned to be removed soon, and
+ * should generate a warning.
*/
qtest_start("-cpu pentium,-fpu,+fpu,-mce,mce=on,+cx8,cx8=off,+sse4_1,sse4_2=on");
path = get_cpu0_qom_path();
@@ -108,11 +110,27 @@ static void test_plus_minus(void)
g_free(path);
}
+static void test_plus_minus(void)
+{
+ g_test_trap_subprocess("/x86/cpuid/parsing-plus-minus/subprocess", 0, 0);
+ g_test_trap_assert_passed();
+ g_test_trap_assert_stderr("*Ambiguous CPU model string. "
+ "Don't mix both \"-mce\" and \"mce=on\"*");
+ g_test_trap_assert_stderr("*Ambiguous CPU model string. "
+ "Don't mix both \"+cx8\" and \"cx8=off\"*");
+ g_test_trap_assert_stdout("");
+}
+#endif
+
int main(int argc, char **argv)
{
g_test_init(&argc, &argv, NULL);
- qtest_add_func("x86/cpuid/parsing-plus-minus", test_plus_minus);
+#ifdef CONFIG_HAS_GLIB_SUBPROCESS_TESTS
+ g_test_add_func("/x86/cpuid/parsing-plus-minus/subprocess",
+ test_plus_minus_subprocess);
+ g_test_add_func("/x86/cpuid/parsing-plus-minus", test_plus_minus);
+#endif
/* Original level values for CPU models: */
add_cpuid_test("x86/cpuid/phenom/level",
diff --git a/tests/vhost-user-test.c b/tests/vhost-user-test.c
index e4b2900898..96bf00eefa 100644
--- a/tests/vhost-user-test.c
+++ b/tests/vhost-user-test.c
@@ -22,8 +22,6 @@
#include "libqos/virtio-pci.h"
#include "qapi/error.h"
-#include "libqos/pci-pc.h"
-#include "libqos/virtio-pci.h"
#include "libqos/malloc-pc.h"
#include "hw/virtio/virtio-net.h"