aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Snow <jsnow@redhat.com>2015-05-22 14:13:43 -0400
committerJohn Snow <jsnow@redhat.com>2015-05-22 15:58:22 -0400
commit278128ab06c36341edb2c8b0bfcfd92760f4db52 (patch)
treece979b59ab6ae66927d4a62ee562daaf0c8137b8
parent04329029a8c539eb5f75dcb6d8b016f0c53a031a (diff)
qtest/ahci: Add migration test
Notes: * The migration is performed on QOSState objects. * The migration is performed in such a way that it does not assume consistency between the allocators attached to each. That is to say, you can use each QOSState object completely independently and then at an arbitrary point decide to migrate, and the destination object will now be consistent with the memory within the source guest. The source object that was migrated from will have a completely blank allocator. ahci-test.c: - verify_state is added - ahci_migrate is added as a frontend to migrate - test_migrate_sanity test case is added. Signed-off-by: John Snow <jsnow@redhat.com> Reviewed-by: Kevin Wolf <kwolf@redhat.com> Message-id: 1430417242-11859-6-git-send-email-jsnow@redhat.com
-rw-r--r--tests/ahci-test.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/tests/ahci-test.c b/tests/ahci-test.c
index 7c23bb2180..9fccafcbd8 100644
--- a/tests/ahci-test.c
+++ b/tests/ahci-test.c
@@ -97,6 +97,72 @@ static void generate_pattern(void *buffer, size_t len, size_t cycle_len)
}
}
+/**
+ * Verify that the transfer did not corrupt our state at all.
+ */
+static void verify_state(AHCIQState *ahci)
+{
+ int i, j;
+ uint32_t ahci_fingerprint;
+ uint64_t hba_base;
+ uint64_t hba_stored;
+ AHCICommandHeader cmd;
+
+ ahci_fingerprint = qpci_config_readl(ahci->dev, PCI_VENDOR_ID);
+ g_assert_cmphex(ahci_fingerprint, ==, ahci->fingerprint);
+
+ /* If we haven't initialized, this is as much as can be validated. */
+ if (!ahci->hba_base) {
+ return;
+ }
+
+ hba_base = (uint64_t)qpci_config_readl(ahci->dev, PCI_BASE_ADDRESS_5);
+ hba_stored = (uint64_t)(uintptr_t)ahci->hba_base;
+ g_assert_cmphex(hba_base, ==, hba_stored);
+
+ g_assert_cmphex(ahci_rreg(ahci, AHCI_CAP), ==, ahci->cap);
+ g_assert_cmphex(ahci_rreg(ahci, AHCI_CAP2), ==, ahci->cap2);
+
+ for (i = 0; i < 32; i++) {
+ g_assert_cmphex(ahci_px_rreg(ahci, i, AHCI_PX_FB), ==,
+ ahci->port[i].fb);
+ g_assert_cmphex(ahci_px_rreg(ahci, i, AHCI_PX_CLB), ==,
+ ahci->port[i].clb);
+ for (j = 0; j < 32; j++) {
+ ahci_get_command_header(ahci, i, j, &cmd);
+ g_assert_cmphex(cmd.prdtl, ==, ahci->port[i].prdtl[j]);
+ g_assert_cmphex(cmd.ctba, ==, ahci->port[i].ctba[j]);
+ }
+ }
+}
+
+static void ahci_migrate(AHCIQState *from, AHCIQState *to, const char *uri)
+{
+ QOSState *tmp = to->parent;
+ QPCIDevice *dev = to->dev;
+ if (uri == NULL) {
+ uri = "tcp:127.0.0.1:1234";
+ }
+
+ /* context will be 'to' after completion. */
+ migrate(from->parent, to->parent, uri);
+
+ /* We'd like for the AHCIState objects to still point
+ * to information specific to its specific parent
+ * instance, but otherwise just inherit the new data. */
+ memcpy(to, from, sizeof(AHCIQState));
+ to->parent = tmp;
+ to->dev = dev;
+
+ tmp = from->parent;
+ dev = from->dev;
+ memset(from, 0x00, sizeof(AHCIQState));
+ from->parent = tmp;
+ from->dev = dev;
+
+ verify_state(to);
+}
+
/*** Test Setup & Teardown ***/
/**
@@ -146,6 +212,8 @@ static AHCIQState *ahci_boot(const char *cli, ...)
static void ahci_shutdown(AHCIQState *ahci)
{
QOSState *qs = ahci->parent;
+
+ set_context(qs);
ahci_clean_mem(ahci);
free_ahci_device(ahci->dev);
g_free(ahci);
@@ -1022,6 +1090,26 @@ static void test_flush_retry(void)
ahci_shutdown(ahci);
}
+/**
+ * Basic sanity test to boot a machine, find an AHCI device, and shutdown.
+ */
+static void test_migrate_sanity(void)
+{
+ AHCIQState *src, *dst;
+ const char *uri = "tcp:127.0.0.1:1234";
+
+ src = ahci_boot("-m 1024 -M q35 "
+ "-hda %s ", tmp_path);
+ dst = ahci_boot("-m 1024 -M q35 "
+ "-hda %s "
+ "-incoming %s", tmp_path, uri);
+
+ ahci_migrate(src, dst, uri);
+
+ ahci_shutdown(src);
+ ahci_shutdown(dst);
+}
+
/******************************************************************************/
/* AHCI I/O Test Matrix Definitions */
@@ -1271,6 +1359,8 @@ int main(int argc, char **argv)
qtest_add_func("/ahci/flush/simple", test_flush);
qtest_add_func("/ahci/flush/retry", test_flush_retry);
+ qtest_add_func("/ahci/migrate/sanity", test_migrate_sanity);
+
ret = g_test_run();
/* Cleanup */