#!/usr/bin/python # -*- coding: utf-8 -*- # This file is part of Cockpit. # # Copyright (C) 2015 Red Hat, Inc. # # Cockpit is free software; you can redistribute it and/or modify it # under the terms of the GNU Lesser General Public License as published by # the Free Software Foundation; either version 2.1 of the License, or # (at your option) any later version. # # Cockpit 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 # Lesser General Public License for more details. # # You should have received a copy of the GNU Lesser General Public License # along with Cockpit; If not, see . import parent from testlib import * from storagelib import * @skipImage("UDisks doesn't have support for multipath", "debian-stable", "ubuntu-1604", "ubuntu-stable") @skipImage("No multipath on Debian", "debian-testing") class TestStorage(StorageCase): def testBasic(self): m = self.machine b = self.browser def detail_row(index): return '#detail-header tr:nth-child(%s)' % index def detail_row_name(index): return '#detail-header tr:nth-child(%s) td:nth-child(1)' % index def detail_row_value(index): return '#detail-header tr:nth-child(%s) td:nth-child(2)' % index def wait_detail_row(index, name): b.wait_present(detail_row(index)) b.wait_text(detail_row_name(index), name) def check_free_block_devices(expected): blocks = b.eval_js("ph_texts('#dialog [data-field=\"disks\"] .checkbox')") if len(blocks) != len(expected): return False for i in range(len(expected)): if not expected[i] in blocks[i]: return False return True self.login_and_go("/storage") b.wait_in_text("#drives", "VirtIO") b.eval_js(""" ph_texts = function (sel) { return $(sel).map(function (i, e) { return $(e).text(); }).get(); }""") # Add a disk disk = m.add_disk("10M", serial="MYSERIAL") b.wait_in_text("#drives", "MYSERIAL") b.click('tr:contains("MYSERIAL")') b.wait_visible('#storage-detail') wait_detail_row(5, "Device File") b.wait_in_text(detail_row_value(5), "/dev/sda") # Add another path to the same disk. The primary device file # should disappear and multipathed devices should be listed. m.add_disk_path(disk) b.wait_text_not(detail_row_value(5), "/dev/sda") wait_detail_row(6, "Multipathed Devices") b.wait_in_text(detail_row_value(6), "/dev/sda") b.wait_in_text(detail_row_value(6), "/dev/sdb") # Check that neither is offered as a free block device b.go("#/") b.wait_visible('#create-volume-group') b.click('#create-volume-group') self.dialog_wait_open() check_free_block_devices([]) self.dialog_cancel() self.dialog_wait_close() b.go("#/sda") b.wait_visible('#storage-detail') # Switch on multipathd. A primary device should appear. b.wait_visible('#multipath-broken') b.click('#activate-multipath') b.wait_in_text(detail_row_value(5), "/dev/mapper/mpatha") b.wait_not_visible('#multipath-broken') # Check that (exactly) the primary device is offered as free b.go("#/") b.wait_visible('#create-volume-group') b.click('#create-volume-group') self.dialog_wait_open() check_free_block_devices([ "/dev/mapper/mpatha" ]) self.dialog_cancel() self.dialog_wait_close() if __name__ == '__main__': test_main()