From 6bc756193ff61bf5e7b3cfedfbb0873bf40f8055 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Wed, 17 Jun 2015 17:23:32 -0400 Subject: tools/testing/nvdimm: libnvdimm unit test infrastructure 'libnvdimm' is the first driver sub-system in the kernel to implement mocking for unit test coverage. The nfit_test module gets built as an external module and arranges for external module replacements of nfit, libnvdimm, nd_pmem, and nd_blk. These replacements use the linker --wrap option to redirect calls to ioremap() + request_mem_region() to custom defined unit test resources. The end result is a fully functional nvdimm_bus, as far as userspace is concerned, but with the capability to perform otherwise destructive tests on emulated resources. Q: Why not use QEMU for this emulation? QEMU is not suitable for unit testing. QEMU's role is to faithfully emulate the platform. A unit test's role is to unfaithfully implement the platform with the goal of triggering bugs in the corners of the sub-system implementation. As bugs are discovered in platforms, or the sub-system itself, the unit tests are extended to backstop a fix with a reproducer unit test. Another problem with QEMU is that it would require coordination of 3 software projects instead of 2 (kernel + libndctl [1]) to maintain and execute the tests. The chances for bit rot and the difficulty of getting the tests running goes up non-linearly the more components involved. Q: Why submit this to the kernel tree instead of external modules in libndctl? Simple, to alleviate the same risk that out-of-tree external modules face. Updates to drivers/nvdimm/ can be immediately evaluated to see if they have any impact on tools/testing/nvdimm/. Q: What are the negative implications of merging this? It is a unique maintenance burden because the purpose of mocking an interface to enable a unit test is to purposefully short circuit the semantics of a routine to enable testing. For example __wrap_ioremap_cache() fakes the pmem driver into "ioremap()'ing" a test resource buffer allocated by dma_alloc_coherent(). The future maintenance burden hits when someone changes the semantics of ioremap_cache() and wonders what the implications are for the unit test. [1]: https://github.com/pmem/ndctl Cc: Cc: Lv Zheng Cc: Robert Moore Cc: Rafael J. Wysocki Cc: Christoph Hellwig Signed-off-by: Dan Williams --- tools/testing/nvdimm/test/nfit_test.h | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 tools/testing/nvdimm/test/nfit_test.h (limited to 'tools/testing/nvdimm/test/nfit_test.h') diff --git a/tools/testing/nvdimm/test/nfit_test.h b/tools/testing/nvdimm/test/nfit_test.h new file mode 100644 index 000000000000..96c5e16d7db9 --- /dev/null +++ b/tools/testing/nvdimm/test/nfit_test.h @@ -0,0 +1,29 @@ +/* + * Copyright(c) 2013-2015 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * 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. + */ +#ifndef __NFIT_TEST_H__ +#define __NFIT_TEST_H__ + +struct nfit_test_resource { + struct list_head list; + struct resource *res; + struct device *dev; + void *buf; +}; + +typedef struct nfit_test_resource *(*nfit_test_lookup_fn)(resource_size_t); +void __iomem *__wrap_ioremap_nocache(resource_size_t offset, + unsigned long size); +void __wrap_iounmap(volatile void __iomem *addr); +void nfit_test_setup(nfit_test_lookup_fn lookup); +void nfit_test_teardown(void); +#endif -- cgit v1.2.3-59-g8ed1b