Device Mapper Test Suite
Tests device mapper kernel targets for Linux.
This test suite replaces the thinp-test-suite package. It switches to using Ruby 1.9, has an improved user interface and configuration file, and tests more than just the thin provisioning target.
I recommend you use RVM to manage your Ruby installation. It allows you to install many versions of Ruby concurrently, and automatically switch between them depending on the contents of a .ruby-version file in your project's root directory.
The above link gives more details, but here's a quickstart:
curl -L https://get.rvm.io | bash
Make sure you follow the instructions at the end of the script regarding setting your shell's environment.
Now we need to install Ruby 2.5.3
rvm install 2.5.3
Ruby Index (ri)
If you wish to use ri to consult the Ruby Documentation (RDoc) for the newly installed ruby then it will need to be generated
rvm docs generate-ri
Now we need to make sure the gem catalogue is up to date. Gems are packaged Ruby libraries.
Grab the [bundler] package, which will automatically install all our Ruby dependencies for us.
gem install bundler
In the device-mapper-test-suite directory:
This should install all the ruby libraries we need.
The tests use various tools which you'll need in your path (I don't think this list is complete):
Now run dmtest. The first time it's run it will set up a ~/.dmtest/ directory for you, and write an example config file (~/.dmtest/config).
profile :ssd do metadata_dev '/dev/vdb' data_dev '/dev/vdc' end profile :spindle do metadata_dev '/dev/vdd' data_dev '/dev/vde' end profile :mix do metadata_dev '/dev/vdb' data_dev '/dev/vde' end default_profile :ssd
The config file consists of one or more profiles (these are selected with the --profile command line switch). Within each profile you have to specify a device which is used to store thin provisioning metadata and cache data on it. Typically this should be a fast device such as an SSD (or a logical volume allocated on an SSD of course). The other device should be a slower data device.
As you can see I normally use several profiles, depending on whether I'm developing new code and want the tests to run quickly (:ssd), testing a realistic set up (:mix), or just searching for those race conditions that only appear when using slower devices (:spindle).
A metadata dev of 1G, and data dev of 4G is sufficient. Some poorly written tests use all of the data dev, no matter how big it is, so will take longer to run with large volumes.
dmtest <cmd> <switches>*
The tests are divided up into suites, which are specific to a particular target. Use the --suite switch to specify this:
dmtest list --suite thin-provisioning
Though only thin-provisioning and cache are generally used.
You can select the configuration profile using --profile.
dmtest run --suite thin-provisioning --profile spindle -t /Creation/
Use the list command get an idea of the tests that are available.
dmtest list --suite thin-provisioning thin-provisioning BasicTests dd_benchmark ext4_weirdness overwrite_a_linear_device overwriting_various_thin_devices CreationTests create_lots_of_empty_thins create_lots_of_recursive_snaps create_lots_of_snaps huge_block_size largest_data_block_size_succeeds largest_dev_t_succeeds non_power_of_2_data_block_size_fails too_large_a_dev_t_fails too_large_data_block_size_fails too_small_a_metadata_dev_fails too_small_data_block_size_fails DeletionTests create_delete_cycle create_many_thins_then_delete_them delete_active_device_fails delete_thin ...
The indentation indicates the organisation of the tests by suite/class/test.
You can specify an exact match for the class:
dmtest list --suite thin-provisioning -t SnapshotTests thin-provisioning SnapshotTests break_sharing_ext4 break_sharing_xfs create_snap_ext4 create_snap_xfs many_snapshots_of_same_volume parallel_io_to_shared_thins ref_count_tree thin_overwrite_ext4 thin_overwrite_xfs
Or you can use a regular expression for the class:
dmtest list --suite thin-provisioning -t /Creation\|Deletion/ thin-provisioning CreationTests create_lots_of_empty_thins create_lots_of_recursive_snaps create_lots_of_snaps huge_block_size largest_data_block_size_succeeds largest_dev_t_succeeds non_power_of_2_data_block_size_fails too_large_a_dev_t_fails too_large_data_block_size_fails too_small_a_metadata_dev_fails too_small_data_block_size_fails DeletionTests create_delete_cycle create_many_thins_then_delete_them delete_active_device_fails delete_thin delete_unknown_devices rolling_create_delete
Selecting individual tests is similarly done via the -n switch:
dmtest list --suite thin-provisioning -n /create/ thin-provisioning CreationTests create_lots_of_empty_thins create_lots_of_recursive_snaps create_lots_of_snaps DeletionTests create_delete_cycle create_many_thins_then_delete_them rolling_create_delete MultiplePoolTests two_pools_can_create_thins ReadOnlyTests cant_create_new_thins create_read_only SnapshotTests create_snap_ext4 create_snap_xfs
Currently you can use multiple selectors. I'll add at some point.
Once you're happy with the subset of tests that you're listing, you should run them:
dmtest run --suite thin-provisioning -n /create/
Loaded suite thin-provisioning Started test_create_lots_of_empty_thins(CreationTests): . test_create_lots_of_recursive_snaps(CreationTests): . test_create_lots_of_snaps(CreationTests): . test_create_delete_cycle(DeletionTests): . test_create_many_thins_then_delete_them(DeletionTests): . test_rolling_create_delete(DeletionTests): . test_two_pools_can_create_thins(MultiplePoolTests): . test_cant_create_new_thins(ReadOnlyTests): E test_create_read_only(ReadOnlyTests): F test_create_snap_ext4(SnapshotTests): . test_create_snap_xfs(SnapshotTests): .
Generally the tests run quietly. Just the test name will be printed, and a character to indicate the outcome of the test:
. - Success F - The test failed E - There's a bug in the test itself
Once all the tests have run you'll get some Ruby back traces for the failing and erroring tests.
A full log of each test can be found in ~/.dmtest/log/<class>_<test>.log
Digging around in log files can be tedious. So after every test run, dmtest generates a set of html reports that can be found in ~/.dmtest/reports. Either open them directly, or get dmtest to fire up a little http server:
dmtest serve --port 1234
Then point your browser at http://localhost:1234
The default port is 8080. These reports summarise which tests have passed or failed, when the tests were last run, and gives access to markedup versions of the logs.
Generally I run the server all the time in the background; it will automatically pick up any newly generated reports.
Generating test reports happens automatically as part of the run command. But there are times when you want to generate the reports by hand (eg, a test bug caused dmtest to exit before generating the reports).