def test_simple_vdev(self):
        """ 1 single vdev
        """
        # create a single 64M file
        f1 = "/var/tmp/ti_file_1"
        self.create_file(f1)

        # create a new Disk object
        d = Disk("disk")
        d.ctd = f1
        d.in_zpool = "ti_zpool_test"
        d.whole_disk = True
        self.target.insert_children(d)

        # create a new Zpool object
        zpool = self.logical.add_zpool("ti_zpool_test")

        # create the zpool and store it for later teardown
        try:
            t = instantiation.TargetInstantiation("test_ti")
            t.execute(dry_run=False)
            self.zpool_list.append(zpool)
        except Exception as err:
            import traceback
            print traceback.print_exc()
            self.fail(str(err))

        # pull the vdevs and verify
        vdev_map = vdevs._get_vdev_mapping(zpool.name)

        # verify the map is correct
        self.assertTrue("none" in vdev_map)
        self.assertEquals(1, len(vdev_map["none"]))
        self.assertEquals([f1], vdev_map["none"])
    def test_mirror_log(self):
        """ test the logmirror vdev label
        """
        # create three 64M files
        f1 = "/var/tmp/ti_file_1"
        self.create_file(f1)

        f2 = "/var/tmp/ti_file_2"
        self.create_file(f2)

        f3 = "/var/tmp/ti_file_3"
        self.create_file(f3)

        # create two disk objects
        d1 = Disk("disk1")
        d1.ctd = f1
        d1.in_zpool = "ti_zpool_test"
        d1.in_vdev = "none"
        d1.whole_disk = True

        d2 = Disk("disk2")
        d2.ctd = f2
        d2.in_zpool = "ti_zpool_test"
        d2.in_vdev = "mirror-1"
        d2.whole_disk = True

        d3 = Disk("disk3")
        d3.ctd = f3
        d3.in_zpool = "ti_zpool_test"
        d3.in_vdev = "mirror-1"
        d3.whole_disk = True

        self.target.insert_children([d1, d2, d3])

        # create a new Zpool object
        zpool = self.logical.add_zpool("ti_zpool_test")
        zpool.add_vdev("none", "none")
        zpool.add_vdev("mirror-1", "logmirror")

        # create the zpool and store it for later teardown
        try:
            t = instantiation.TargetInstantiation("test_ti")
            t.execute(dry_run=False)
            self.zpool_list.append(zpool)
        except Exception as err:
            import traceback
            print traceback.print_exc()
            self.fail(str(err))

        # pull the vdevs and verify
        vdev_map = vdevs._get_vdev_mapping(zpool.name)

        # verify the map is correct
        self.assertTrue("mirror-1" in vdev_map)
        self.assertEquals(2, len(vdev_map["mirror-1"]))
        self.assertEquals([f2, f3], vdev_map["mirror-1"])
    def set_vdev_map(self, zpool):
        """ set_vdev_map() - walk the vdev_map to set the zpool's vdev entries
        and update existing physical DOC entries with the proper in_zpool and
        in_vdev attributes.

        zpool - zpool DOC object
        """
        # get the list of Disk DOC objects already inserted
        disklist = self.root.get_children(class_type=Disk)

        # get the vdev mappings for this pool
        vdev_map = vdevs._get_vdev_mapping(zpool.name)

        for vdev_type, vdev_entries in vdev_map.iteritems():
            in_vdev_label = "%s-%s" % (zpool.name, vdev_type)
            if vdev_type != "none":
                redundancy = vdev_type.partition("-")[0]
            else:
                redundancy = vdev_type

            # create a Vdev DOC entry for the vdev_type
            zpool.add_vdev(in_vdev_label, redundancy)

            for full_entry in vdev_entries:
                # remove the device path from the entry
                entry = full_entry.rpartition("/dev/dsk/")[2]

                # try to partition the entry for slices
                (vdev_ctd, vdev_letter, vdev_index) = entry.rpartition("s")

                # if the entry is not a slice, vdev_letter and index will
                # be empty strings
                if not vdev_letter:
                    # try to partition the entry for partitions
                    (vdev_ctd, vdev_letter, vdev_index) = \
                        entry.rpartition("p")

                    # if the entry is also not a partition skip this entry
                    if not vdev_letter:
                        continue

                # walk the disk list looking for a matching ctd
                for disk in disklist:
                    if hasattr(disk, "ctd"):
                        if disk.ctd == vdev_ctd:
                            # this disk is a match
                            if vdev_letter == "s":
                                child_list = disk.get_descendants(
                                    class_type=Slice)
                            elif vdev_letter == "p":
                                child_list = disk.get_descendants(
                                    class_type=Partition)

                            # walk the child list and look for a matching name
                            for child in child_list:
                                if child.name == vdev_index:
                                    # set the in_zpool and in_vdev attributes
                                    child.in_zpool = zpool.name
                                    child.in_vdev = in_vdev_label

                            # break out of the disklist walk
                            break
    def test_duplicate_in_vdev(self):
        # create four 64M files
        f1 = "/var/tmp/ti_file_1"
        self.create_file(f1)

        f2 = "/var/tmp/ti_file_2"
        self.create_file(f2)

        f3 = "/var/tmp/ti_file_3"
        self.create_file(f3)

        f4 = "/var/tmp/ti_file_4"
        self.create_file(f4)

        # create four disk objects
        d1 = Disk("disk1")
        d1.ctd = f1
        d1.in_zpool = "ti_myroot"
        d1.in_vdev = "datavdev"
        d1.whole_disk = True

        # match the in_vdev for d2 and d3 with d1, but use a different pool and
        # a different redundancy
        d2 = Disk("disk2")
        d2.ctd = f2
        d2.in_zpool = "ti_data"
        d2.in_vdev = "datavdev"
        d2.whole_disk = True

        d3 = Disk("disk3")
        d3.ctd = f3
        d3.in_zpool = "ti_data"
        d3.in_vdev = "datavdev"
        d3.whole_disk = True

        d4 = Disk("disk4")
        d4.ctd = f4
        d4.in_zpool = "ti_data"
        d4.in_vdev = "sparevdev"
        d4.whole_disk = True

        self.target.insert_children([d1, d2, d3, d4])

        # create two new Zpool object
        zpool1 = self.logical.add_zpool("ti_myroot")
        zpool1.add_vdev("datavdev", redundancy="none")

        zpool2 = self.logical.add_zpool("ti_data")
        zpool2.add_vdev("datavdev", "mirror")
        zpool2.add_vdev("sparevdev", "spare")

        # create the zpools and store it for later teardown
        try:
            t = instantiation.TargetInstantiation("test_ti")
            t.execute(dry_run=False)
            self.zpool_list.append(zpool1)
            self.zpool_list.append(zpool2)
        except Exception as err:
            import traceback
            print traceback.print_exc()
            self.fail(str(err))

        # pull the vdevs and verify
        zpool1_vdev_map = vdevs._get_vdev_mapping(zpool1.name)
        zpool2_vdev_map = vdevs._get_vdev_mapping(zpool2.name)

        # verify both maps are correct
        self.assertTrue("none" in zpool1_vdev_map)
        self.assertEquals([f1], zpool1_vdev_map["none"])

        self.assertTrue("mirror-0" in zpool2_vdev_map)
        self.assertTrue("spare" in zpool2_vdev_map)
        self.assertEquals(2, len(zpool2_vdev_map["mirror-0"]))
        self.assertEquals([f2, f3], zpool2_vdev_map["mirror-0"])
        self.assertEquals(1, len(zpool2_vdev_map["spare"]))
        self.assertEquals([f4], zpool2_vdev_map["spare"])
    def test_complex_vdevs1(self):
        """ 10 disks: Mirrored root + raidz datapool with log and spare
        """
        # create 10 files
        for i in range(1, 11):
            f = "/var/tmp/ti_file_%d" % i
            self.create_file(f)

        # create 10 disk objects
        for i in range(1, 11):
            d = Disk("disk%d" % i)
            d.ctd = self.file_list[i - 1]
            if i in [1, 2]:
                d.in_zpool = "ti_zpool_test_root"
                d.in_vdev = "root-mirror"
            elif i in [3, 4, 5, 6]:
                d.in_zpool = "ti_zpool_test_datapool"
                d.in_vdev = "datapool-raidz"
            elif i in [7, 8]:
                d.in_zpool = "ti_zpool_test_datapool"
                d.in_vdev = "datapool-log"
            elif i in [9, 10]:
                d.in_zpool = "ti_zpool_test_datapool"
                d.in_vdev = "datapool-spare"
            self.target.insert_children(d)

        # create two new zpool objects
        zpool1 = self.logical.add_zpool("ti_zpool_test_root")
        zpool1.add_vdev("root-mirror", "mirror")

        zpool2 = self.logical.add_zpool("ti_zpool_test_datapool")
        zpool2.add_vdev("datapool-raidz", "raidz")
        zpool2.add_vdev("datapool-log", "log")
        zpool2.add_vdev("datapool-spare", "spare")

        # create the zpools and store it for later teardown
        try:
            t = instantiation.TargetInstantiation("test_ti")
            t.execute(dry_run=False)
            self.zpool_list.append(zpool1)
            self.zpool_list.append(zpool2)
        except Exception as err:
            import traceback
            print traceback.print_exc()
            self.fail(str(err))

        # pull the vdevs and verify
        vdev_map1 = vdevs._get_vdev_mapping(zpool1.name)

        # verify the map is correct
        self.assertTrue("mirror-0" in vdev_map1)
        self.assertTrue(len(vdev_map1["mirror-0"]) == 2)
        self.assertTrue(vdev_map1["mirror-0"] == self.file_list[:2])

        vdev_map2 = vdevs._get_vdev_mapping(zpool2.name)
        self.assertTrue("spare" in vdev_map2)
        self.assertTrue("logs" in vdev_map2)
        self.assertTrue("raidz-0" in vdev_map2)
        self.assertTrue(2, len(vdev_map2["spare"]))
        self.assertTrue(2, len(vdev_map2["logs"]))
        self.assertTrue(4, len(vdev_map2["raidz-0"]))
        self.assertEquals(self.file_list[-2:], vdev_map2["spare"])
        self.assertEquals(self.file_list[6:8], vdev_map2["logs"])
        self.assertEquals(self.file_list[2:6], vdev_map2["raidz-0"])