Ejemplo n.º 1
0
    def test_phone_home(self):
        instance_id = data_factory.generate_random_string(12)
        address = '127.0.0.1'
        port = network.find_free_port(address=address)
        server = cloudinit.PhoneHomeServer((address, port), instance_id)
        self.assertFalse(server.instance_phoned_back)

        server_thread = threading.Thread(target=server.handle_request)
        server_thread.start()
        conn = http_client.HTTPConnection(address, port)

        # contact the wrong url, and check the server does not
        # consider it a call back from the expected caller
        conn.request('POST', '/BAD_INSTANCE_ID')
        try:
            conn.getresponse()
        except:
            pass
        self.assertFalse(server.instance_phoned_back)
        conn.close()

        # now the right url
        server_thread = threading.Thread(target=server.handle_request)
        server_thread.start()
        conn = http_client.HTTPConnection(address, port)
        conn.request('POST', '/' + instance_id)
        try:
            conn.getresponse()
        except:
            pass
        self.assertTrue(server.instance_phoned_back)
        conn.close()
        server.server_close()
Ejemplo n.º 2
0
    def add_repo(self, url):
        """
        Adds package repository located on [url].

        :param url: Universal Resource Locator of the repository.
        """
        # Check if we URL is already set
        for section in self.repo_config_parser.sections():
            for option, value in self.repo_config_parser.items(section):
                if option == 'url' and value == url:
                    return True

        # Didn't find it, let's set it up
        while True:
            section_name = 'software_manager' + '_'
            section_name += data_factory.generate_random_string(4)
            if not self.repo_config_parser.has_section(section_name):
                break
        try:
            self.repo_config_parser.add_section(section_name)
            self.repo_config_parser.set(section_name, 'name',
                                        'Avocado managed repository')
            self.repo_config_parser.set(section_name, 'url', url)
            self.repo_config_parser.set(section_name, 'enabled', '1')
            self.repo_config_parser.set(section_name, 'gpgcheck', '0')
            prefix = 'avocado_software_manager'
            with tempfile.NamedTemporaryFile("w", prefix=prefix) as tmp_file:
                self.repo_config_parser.write(tmp_file)
                tmp_file.flush()  # Sync the content
                process.system(f'cp {tmp_file.name} {self.REPO_FILE_PATH}',
                               sudo=True)
            return True
        except (OSError, process.CmdError) as details:
            log.error(details)
            return False
Ejemplo n.º 3
0
    def test_badly_behaved(self):
        """
        Make sure avocado can cleanly get out of a loop of badly behaved tests.
        """
        bad_test_basename = ('wontquit-%s' %
                             data_factory.generate_random_string(5))
        bad_test = script.TemporaryScript(bad_test_basename,
                                          BAD_TEST,
                                          'avocado_interrupt_test',
                                          mode=DEFAULT_MODE)

        bad_test.save()

        os.chdir(basedir)
        cmd_line = ('./scripts/avocado run --sysinfo=off --job-results-dir %s '
                    '%s %s %s' %
                    (self.tmpdir, bad_test.path, bad_test.path, bad_test.path))
        proc = aexpect.Expect(command=cmd_line, linesep='')
        proc.read_until_last_line_matches(os.path.basename(bad_test.path))
        proc.sendline('\x03')
        proc.read_until_last_line_matches('Interrupt requested. Waiting 2 '
                                          'seconds for test to finish '
                                          '(ignoring new Ctrl+C until then)')
        # We have to actually wait 2 seconds until the ignore window is over
        time.sleep(2.5)
        proc.sendline('\x03')
        proc.read_until_last_line_matches('TESTS TIME : %d s')
        wait.wait_for(lambda: not proc.is_alive(), timeout=1)

        # Make sure the bad test will be really gone from the process table
        def wait_until_no_badtest():
            bad_test_processes = []

            old_psutil = False
            try:
                process_list = psutil.pids()
            except AttributeError:
                process_list = psutil.get_pid_list()
                old_psutil = True

            for p in process_list:
                try:
                    p_obj = psutil.Process(p)
                    if p_obj is not None:
                        if old_psutil:
                            cmdline_list = psutil.Process(p).cmdline
                        else:
                            cmdline_list = psutil.Process(p).cmdline()
                        if bad_test.path in " ".join(cmdline_list):
                            bad_test_processes.append(p_obj)
                # psutil.NoSuchProcess happens when the original
                # process already ended and left the process table
                except psutil.NoSuchProcess:
                    pass

            return len(bad_test_processes) == 0

        wait.wait_for(wait_until_no_badtest, timeout=2)
        # Make sure the Killing test subprocess message did appear
        self.assertIn('Killing test subprocess', proc.get_output())
Ejemplo n.º 4
0
    def test_badly_behaved(self):
        """
        Make sure avocado can cleanly get out of a loop of badly behaved tests.
        """
        bad_test_basename = ('wontquit-%s' %
                             data_factory.generate_random_string(5))
        bad_test = script.TemporaryScript(bad_test_basename, BAD_TEST,
                                          'avocado_interrupt_test',
                                          mode=0755)
        bad_test.save()

        os.chdir(basedir)
        cmd_line = ('./scripts/avocado run --sysinfo=off --job-results-dir %s '
                    '%s %s %s' % (self.tmpdir,
                                  bad_test.path,
                                  bad_test.path,
                                  bad_test.path))
        proc = aexpect.Expect(command=cmd_line, linesep='')
        proc.read_until_last_line_matches(os.path.basename(bad_test.path))
        proc.sendline('\x03')
        proc.read_until_last_line_matches('Interrupt requested. Waiting 2 '
                                          'seconds for test to finish '
                                          '(ignoring new Ctrl+C until then)')
        # We have to actually wait 2 seconds until the ignore window is over
        time.sleep(2)
        proc.sendline('\x03')
        proc.read_until_last_line_matches('TIME       : %d s')
        wait.wait_for(lambda: not proc.is_alive(), timeout=1)

        # Make sure the bad test will be really gone from the process table
        def wait_until_no_badtest():
            bad_test_processes = []

            old_psutil = False
            try:
                process_list = psutil.pids()
            except AttributeError:
                process_list = psutil.get_pid_list()
                old_psutil = True

            for p in process_list:
                try:
                    p_obj = psutil.Process(p)
                    if p_obj is not None:
                        if old_psutil:
                            cmdline_list = psutil.Process(p).cmdline
                        else:
                            cmdline_list = psutil.Process(p).cmdline()
                        if bad_test.path in " ".join(cmdline_list):
                            bad_test_processes.append(p_obj)
                # psutil.NoSuchProcess happens when the original
                # process already ended and left the process table
                except psutil.NoSuchProcess:
                    pass

            return len(bad_test_processes) == 0

        wait.wait_for(wait_until_no_badtest, timeout=2)
        # Make sure the Killing test subprocess message did appear
        self.assertIn('Killing test subprocess', proc.get_output())
Ejemplo n.º 5
0
        def test(self):
            self.disk_path = None
            while self.disk_path is None or os.path.exists(self.disk_path):
                self.disk_path = (
                    "%s/disk_%s" %
                    (test.tmpdir, data_factory.generate_random_string(3)))

            disk_size = int(
                utils_misc.normalize_data_size(params.get("disk_size", "10M"),
                                               "M"))

            exp_str = r".*gzip: stdout: No space left on device.*"
            vm_guest = env.get_vm("virt_test_vm1_guest")
            process.run("mkdir -p %s" % (mount_path))

            vm_guest.verify_alive()
            vm_guest.wait_for_login(timeout=login_timeout)

            create_file_disk(self.disk_path, disk_size)
            mount(self.disk_path, mount_path, "-o loop")

            vm_guest.migrate(mig_timeout,
                             mig_protocol,
                             not_wait_for_migration=True,
                             migration_exec_cmd_src=migration_exec_cmd_src,
                             env=env)

            if not utils_misc.wait_for(
                    lambda: process_output_check(vm_guest.process, exp_str),
                    timeout=60,
                    first=1):
                test.fail("The migration to destination with low "
                          "storage space didn't fail as it should.")
        def test(self):
            self.disk_path = None
            while self.disk_path is None or os.path.exists(self.disk_path):
                self.disk_path = (
                    "%s/disk_%s" %
                    (test.tmpdir, data_factory.generate_random_string(3)))

            disk_size = int(utils_misc.normalize_data_size(
                params.get("disk_size", "10M"), "M"))

            exp_str = r".*gzip: stdout: No space left on device.*"
            vm_guest = env.get_vm("virt_test_vm1_guest")
            process.run("mkdir -p %s" % (mount_path))

            vm_guest.verify_alive()
            vm_guest.wait_for_login(timeout=login_timeout)

            create_file_disk(self.disk_path, disk_size)
            mount(self.disk_path, mount_path, "-o loop")

            vm_guest.migrate(mig_timeout, mig_protocol,
                             not_wait_for_migration=True,
                             migration_exec_cmd_src=migration_exec_cmd_src,
                             env=env)

            if not utils_misc.wait_for(lambda: process_output_check(
                                       vm_guest.process, exp_str),
                                       timeout=60, first=1):
                test.fail("The migration to destination with low "
                          "storage space didn't fail as it should.")
Ejemplo n.º 7
0
    def test_well_behaved(self):
        """
        Make sure avocado can cleanly get out of a loop of well behaved tests.
        """
        good_test_basename = ('goodtest-%s.py' %
                              data_factory.generate_random_string(5))
        good_test = script.TemporaryScript(good_test_basename,
                                           GOOD_TEST,
                                           'avocado_interrupt_test',
                                           mode=DEFAULT_MODE)
        good_test.save()

        os.chdir(basedir)
        cmd_line = ('%s run --sysinfo=off --job-results-dir %s '
                    '%s %s %s' % (AVOCADO, self.tmpdir, good_test.path,
                                  good_test.path, good_test.path))
        proc = aexpect.Expect(command=cmd_line, linesep='')
        proc.read_until_last_line_matches(os.path.basename(good_test.path))
        proc.sendline('\x03')
        proc.read_until_last_line_matches('TESTS TIME : %d s')
        wait.wait_for(lambda: not proc.is_alive(), timeout=1)

        # Make sure the good test will be really gone from the process table
        def wait_until_no_goodtest():
            good_test_processes = []

            old_psutil = False
            try:
                process_list = psutil.pids()
            except AttributeError:
                process_list = psutil.get_pid_list()
                old_psutil = True

            for p in process_list:
                try:
                    p_obj = psutil.Process(p)
                    if p_obj is not None:
                        if old_psutil:
                            cmdline_list = psutil.Process(p).cmdline
                        else:
                            try:
                                cmdline_list = psutil.Process(p).cmdline()
                            except psutil.AccessDenied:
                                cmdline_list = []
                        if good_test.path in " ".join(cmdline_list):
                            good_test_processes.append(p_obj)
                # psutil.NoSuchProcess happens when the original
                # process already ended and left the process table
                except psutil.NoSuchProcess:
                    pass

            return len(good_test_processes) == 0

        wait.wait_for(wait_until_no_goodtest, timeout=2)
        # Make sure the Killing test subprocess message is not there
        self.assertNotIn('Killing test subprocess', proc.get_output())
        # Make sure the Interrupted requested sentence is there
        self.assertIn(
            'Interrupt requested. Waiting 2 seconds for test to '
            'finish (ignoring new Ctrl+C until then)', proc.get_output())
Ejemplo n.º 8
0
    def compress_and_check_dir(self, extension):
        hash_map_1 = {}
        for i in xrange(self.sys_random.randint(10, 20)):
            if i % 2 == 0:
                compressdir = tempfile.mkdtemp(dir=self.compressdir)
            else:
                compressdir = self.compressdir
            str_length = self.sys_random.randint(30, 50)
            fd, filename = tempfile.mkstemp(dir=compressdir, text=True)
            os.write(fd, data_factory.generate_random_string(str_length))
            relative_path = filename.replace(self.compressdir, '')
            hash_map_1[relative_path] = crypto.hash_file(filename)

        archive_filename = self.compressdir + extension
        archive.compress(archive_filename, self.compressdir)
        archive.uncompress(archive_filename, self.decompressdir)

        hash_map_2 = {}
        for root, _, files in os.walk(self.decompressdir):
            for name in files:
                file_path = os.path.join(root, name)
                relative_path = file_path.replace(self.decompressdir, '')
                hash_map_2[relative_path] = crypto.hash_file(file_path)

        self.assertEqual(hash_map_1, hash_map_2)
Ejemplo n.º 9
0
    def compress_and_check_dir(self, extension):
        hash_map_1 = {}
        for i in xrange(self.sys_random.randint(10, 20)):
            if i % 2 == 0:
                compressdir = tempfile.mkdtemp(dir=self.compressdir)
            else:
                compressdir = self.compressdir
            str_length = self.sys_random.randint(30, 50)
            fd, filename = tempfile.mkstemp(dir=compressdir, text=True)
            with os.fdopen(fd, 'w') as f:
                f.write(data_factory.generate_random_string(str_length))
            relative_path = filename.replace(self.compressdir, '')
            hash_map_1[relative_path] = crypto.hash_file(filename)

        archive_filename = self.compressdir + extension
        archive.compress(archive_filename, self.compressdir)
        archive.uncompress(archive_filename, self.decompressdir)

        hash_map_2 = {}
        for root, _, files in os.walk(self.decompressdir):
            for name in files:
                file_path = os.path.join(root, name)
                relative_path = file_path.replace(self.decompressdir, '')
                hash_map_2[relative_path] = crypto.hash_file(file_path)

        self.assertEqual(hash_map_1, hash_map_2)
Ejemplo n.º 10
0
    def test_well_behaved(self):
        """
        Make sure avocado can cleanly get out of a loop of well behaved tests.
        """
        good_test_basename = ('goodtest-%s.py' %
                              data_factory.generate_random_string(5))
        good_test = script.TemporaryScript(good_test_basename, GOOD_TEST,
                                           'avocado_interrupt_test',
                                           mode=DEFAULT_MODE)
        good_test.save()

        os.chdir(basedir)
        cmd_line = ('%s run --sysinfo=off --job-results-dir %s '
                    '%s %s %s' % (AVOCADO, self.tmpdir, good_test.path,
                                  good_test.path, good_test.path))
        proc = aexpect.Expect(command=cmd_line, linesep='')
        proc.read_until_last_line_matches(os.path.basename(good_test.path))
        proc.sendline('\x03')
        proc.read_until_last_line_matches('JOB TIME   : %d s')
        wait.wait_for(lambda: not proc.is_alive(), timeout=1)

        # Make sure the good test will be really gone from the process table
        def wait_until_no_goodtest():
            good_test_processes = []

            old_psutil = False
            try:
                process_list = psutil.pids()
            except AttributeError:
                process_list = psutil.get_pid_list()
                old_psutil = True

            for p in process_list:
                try:
                    p_obj = psutil.Process(p)
                    if p_obj is not None:
                        if old_psutil:
                            cmdline_list = psutil.Process(p).cmdline
                        else:
                            try:
                                cmdline_list = psutil.Process(p).cmdline()
                            except psutil.AccessDenied:
                                cmdline_list = []
                        if good_test.path in " ".join(cmdline_list):
                            good_test_processes.append(p_obj)
                # psutil.NoSuchProcess happens when the original
                # process already ended and left the process table
                except psutil.NoSuchProcess:
                    pass

            return len(good_test_processes) == 0

        wait.wait_for(wait_until_no_goodtest, timeout=2)
        # Make sure the Killing test subprocess message is not there
        self.assertNotIn('Killing test subprocess', proc.get_output())
        # Make sure the Interrupted requested sentence is there
        self.assertIn('Interrupt requested. Waiting 2 seconds for test to '
                      'finish (ignoring new Ctrl+C until then)',
                      proc.get_output())
Ejemplo n.º 11
0
    def __init__(self, params, root_dir):
        """
        common __init__ function used to initialize iSCSI service

        :param params:      parameters dict for iSCSI
        :param root_dir:    path for image
        """
        self.target = params.get("target")
        self.export_flag = False
        self.luns = None
        self.iscsi_lun_attrs = params.get("iscsi_lun_attrs")
        self.restart_tgtd = 'yes' == params.get("restart_tgtd", "no")
        if params.get("portal_ip"):
            self.portal_ip = params.get("portal_ip")
        else:
            self.portal_ip = "127.0.0.1"
        if params.get("iscsi_thread_id"):
            self.id = params.get("iscsi_thread_id")
        else:
            self.id = data_factory.generate_random_string(4)
        self.initiator = params.get("initiator")

        # CHAP AUTHENTICATION
        self.chap_flag = False
        self.chap_user = params.get("chap_user")
        self.chap_passwd = params.get("chap_passwd")
        if self.chap_user and self.chap_passwd:
            self.chap_flag = True

        if params.get("emulated_image"):
            self.initiator = None
            emulated_image = params.get("emulated_image")
            self.emulated_image = os.path.join(root_dir, emulated_image)
            self.device = "device.%s" % os.path.basename(self.emulated_image)
            self.emulated_id = ""
            self.emulated_size = params.get("image_size")
            self.unit = self.emulated_size[-1].upper()
            self.emulated_size = self.emulated_size[:-1]
            # maps K,M,G,T => (count, bs)
            emulated_size = {
                'K': (1, 1),
                'M': (1, 1024),
                'G': (1024, 1024),
                'T': (1024, 1048576),
            }
            if self.unit in emulated_size:
                block_size = emulated_size[self.unit][1]
                size = int(self.emulated_size) * emulated_size[self.unit][0]
                self.emulated_expect_size = block_size * size
                self.create_cmd = ("dd if=/dev/zero of=%s count=%s bs=%sK" %
                                   (self.emulated_image, size, block_size))
            else:
                raise exceptions.TestError(
                    "Image size provided is not in valid"
                    " format, specify proper units [K|M|G|T]")
        else:
            self.device = None
Ejemplo n.º 12
0
    def _create_account_group(self, account_type):
        """
        Execute the test of creating account group
        """
        account_name = data_factory.generate_random_string(6)
        account_pass = data_factory.generate_random_string(12)
        account_out_name = data_factory.generate_random_string(6)
        account_out_pass = data_factory.generate_random_string(12)

        resp = self.iscsi_client.create_account_group(account_name,
                                                      account_pass,
                                                      account_type,
                                                      account_out_name,
                                                      account_out_pass)
        if not resp and utils.verify_response(self.body, resp):
            raise exceptions.TestFail("Create account group failed: %s")

        return resp['group_id']
Ejemplo n.º 13
0
 def compress_and_check_file(self, extension):
     str_length = self.sys_random.randint(30, 50)
     fd, filename = tempfile.mkstemp(dir=self.basedir, text=True)
     os.write(fd, data_factory.generate_random_string(str_length))
     original_hash = crypto.hash_file(filename)
     dstfile = filename + extension
     archive_filename = os.path.join(self.basedir, dstfile)
     archive.compress(archive_filename, filename)
     archive.uncompress(archive_filename, self.decompressdir)
     decompress_file = os.path.join(self.decompressdir,
                                    os.path.basename(filename))
     decompress_hash = crypto.hash_file(decompress_file)
     self.assertEqual(original_hash, decompress_hash)
Ejemplo n.º 14
0
 def compress_and_check_file(self, extension):
     str_length = self.sys_random.randint(30, 50)
     fd, filename = tempfile.mkstemp(dir=self.basedir, text=True)
     os.write(fd, data_factory.generate_random_string(str_length))
     original_hash = crypto.hash_file(filename)
     dstfile = filename + extension
     archive_filename = os.path.join(self.basedir, dstfile)
     archive.compress(archive_filename, filename)
     archive.uncompress(archive_filename, self.decompressdir)
     decompress_file = os.path.join(self.decompressdir,
                                    os.path.basename(filename))
     decompress_hash = crypto.hash_file(decompress_file)
     self.assertEqual(original_hash, decompress_hash)
Ejemplo n.º 15
0
    def __init__(self, params, root_dir):
        """
        common __init__ function used to initialize iSCSI service

        :param params:      parameters dict for iSCSI
        :param root_dir:    path for image
        """
        self.target = params.get("target")
        self.export_flag = False
        self.luns = None
        self.restart_tgtd = 'yes' == params.get("restart_tgtd", "no")
        if params.get("portal_ip"):
            self.portal_ip = params.get("portal_ip")
        else:
            self.portal_ip = "127.0.0.1"
        if params.get("iscsi_thread_id"):
            self.id = params.get("iscsi_thread_id")
        else:
            self.id = data_factory.generate_random_string(4)
        self.initiator = params.get("initiator")

        # CHAP AUTHENTICATION
        self.chap_flag = False
        self.chap_user = params.get("chap_user")
        self.chap_passwd = params.get("chap_passwd")
        if self.chap_user and self.chap_passwd:
            self.chap_flag = True

        if params.get("emulated_image"):
            self.initiator = None
            emulated_image = params.get("emulated_image")
            self.emulated_image = os.path.join(root_dir, emulated_image)
            self.device = "device.%s" % os.path.basename(self.emulated_image)
            self.emulated_id = ""
            self.emulated_size = params.get("image_size")
            self.unit = self.emulated_size[-1].upper()
            self.emulated_size = self.emulated_size[:-1]
            # maps K,M,G,T => (count, bs)
            emulated_size = {'K': (1, 1),
                             'M': (1, 1024),
                             'G': (1024, 1024),
                             'T': (1024, 1048576),
                             }
            if emulated_size.has_key(self.unit):
                block_size = emulated_size[self.unit][1]
                size = int(self.emulated_size) * emulated_size[self.unit][0]
                self.emulated_expect_size = block_size * size
                self.create_cmd = ("dd if=/dev/zero of=%s count=%s bs=%sK"
                                   % (self.emulated_image, size, block_size))
        else:
            self.device = None
Ejemplo n.º 16
0
    def _create_iscsi_target(self):
        self.iscsi_target_name = "cloudtest" + \
                                 data_factory.generate_random_string(6)
        body = {
            'initiator_ips': self.initiator_ip,
            'target_name': self.iscsi_target_name,
            'multipath': self.params.get('multipath', '2')
        }

        resp = self.iscsi_client.create(**body)
        if not resp and utils.verify_response(body, resp):
            raise exceptions.TestFail("Create target failed: %s" % body)

        return resp.body['target_id']
Ejemplo n.º 17
0
    def test_badly_behaved_sigint(self):
        """
        Make sure avocado can cleanly get out of a loop of badly behaved tests.

        :avocado: tags=parallel:1
        """
        bad_test_basename = ('wontquit-%s' %
                             data_factory.generate_random_string(5))
        bad_test = script.TemporaryScript(bad_test_basename,
                                          BAD_TEST,
                                          'avocado_interrupt_test',
                                          mode=DEFAULT_MODE)
        bad_test.save()
        self.test_module = bad_test.path
        os.chdir(BASEDIR)
        cmd = ('%s run %s --sysinfo=off --job-results-dir %s ' %
               (AVOCADO, self.test_module, self.tmpdir.name))
        proc = subprocess.Popen(cmd.split(),
                                stdout=subprocess.PIPE,
                                stderr=subprocess.STDOUT)

        if not wait.wait_for(lambda: self.has_children(proc), timeout=10):
            process.kill_process_tree(proc.pid)
            self.fail('Avocado did not start the test process.')

        # This test will ignore SIGINT, so it should terminate
        # when we send the second SIGINT.
        os.kill(proc.pid, signal.SIGINT)
        # We have to actually wait 2+ seconds until
        # the ignore window is over
        time.sleep(2.5)
        os.kill(proc.pid, signal.SIGINT)

        if not wait.wait_for(lambda: self.is_finished(proc), timeout=30):
            process.kill_process_tree(proc.pid)
            self.fail('Avocado was still running after receiving SIGINT '
                      'twice.')

        self.assertTrue(
            wait.wait_for(self._no_test_in_process_table, timeout=10),
            'Avocado left processes behind.')

        output = proc.stdout.read()
        # Make sure the Interrupted requested sentence is there
        self.assertIn(
            b'Interrupt requested. Waiting 2 seconds for test to '
            b'finish (ignoring new Ctrl+C until then)', output)
        # Make sure the Killing test subprocess message did appear
        self.assertIn(b'Killing test subprocess', output)
Ejemplo n.º 18
0
    def test_well_behaved_sigint(self):
        """
        Make sure avocado can cleanly get out of a loop of well behaved tests.

        :avocado: tags=parallel:1
        """
        good_test_basename = ('goodtest-%s.py' %
                              data_factory.generate_random_string(5))
        good_test = script.TemporaryScript(good_test_basename,
                                           GOOD_TEST,
                                           'avocado_interrupt_test',
                                           mode=DEFAULT_MODE)
        good_test.save()
        self.test_module = good_test.path
        os.chdir(BASEDIR)
        cmd = ('%s run %s --disable-sysinfo --job-results-dir %s ' %
               (AVOCADO, self.test_module, self.tmpdir.name))
        proc = subprocess.Popen(cmd.split(),
                                stdout=subprocess.PIPE,
                                stderr=subprocess.STDOUT)

        if not wait.wait_for(lambda: self.has_children(proc), timeout=10):
            process.kill_process_tree(proc.pid)
            self.fail('Avocado did not start the test process.')

        # This test will not ignore SIGINT, so it should
        # terminate right away.
        os.kill(proc.pid, signal.SIGINT)

        if not wait.wait_for(lambda: self.is_finished(proc), timeout=10):
            process.kill_process_tree(proc.pid)
            self.fail('Avocado was still running after receiving SIGINT '
                      'twice.')

        self.assertTrue(
            wait.wait_for(self._no_test_in_process_table, timeout=10),
            'Avocado left processes behind.')

        output = proc.stdout.read()
        # Make sure the Interrupted requested sentence is there
        self.assertIn(
            b'Interrupt requested. Waiting 2 seconds for test to '
            b'finish (ignoring new Ctrl+C until then)', output)
        # Make sure the Killing test subprocess message is not there
        self.assertNotIn(b'Killing test subprocess', output)
Ejemplo n.º 19
0
    def test_well_behaved(self):
        """
        Make sure avocado can cleanly get out of a loop of well behaved tests.
        """
        good_test_basename = ('goodtest-%s.py' %
                              data_factory.generate_random_string(5))
        good_test = script.TemporaryScript(good_test_basename,
                                           GOOD_TEST,
                                           'avocado_interrupt_test',
                                           mode=0755)
        good_test.save()

        os.chdir(basedir)
        cmd_line = (
            './scripts/avocado run --sysinfo=off --job-results-dir %s '
            '%s %s %s' %
            (self.tmpdir, good_test.path, good_test.path, good_test.path))
        proc = aexpect.Expect(command=cmd_line, linesep='')
        proc.read_until_last_line_matches(os.path.basename(good_test.path))
        proc.sendline('\x03')
        proc.read_until_last_line_matches('TIME       : %d s')
        wait.wait_for(lambda: not proc.is_alive(), timeout=1)

        # Make sure the good test will be really gone from the process table
        def wait_until_no_goodtest():
            good_test_processes = []
            for p in psutil.pids():
                p_obj = None
                try:
                    p_obj = psutil.Process(p)
                except psutil.NoSuchProcess:
                    pass
                if p_obj is not None:
                    if good_test.path in " ".join(psutil.Process(p).cmdline()):
                        good_test_processes.append(p_obj)
            return len(good_test_processes) == 0

        wait.wait_for(wait_until_no_goodtest, timeout=2)
        # Make sure the Killing test subprocess message is not there
        self.assertNotIn('Killing test subprocess', proc.get_output())
        # Make sure the Interrupted requested sentence is there
        self.assertIn(
            'Interrupt requested. Waiting 2 seconds for test to '
            'finish (ignoring new Ctrl+C until then)', proc.get_output())
Ejemplo n.º 20
0
    def test_badly_behaved_sigint(self):
        """
        Make sure avocado can cleanly get out of a loop of badly behaved tests.
        """
        bad_test_basename = ('wontquit-%s' %
                             data_factory.generate_random_string(5))
        bad_test = script.TemporaryScript(bad_test_basename, BAD_TEST,
                                          'avocado_interrupt_test',
                                          mode=DEFAULT_MODE)
        bad_test.save()
        self.test_module = bad_test.path
        os.chdir(BASEDIR)
        cmd = ('%s run %s --sysinfo=off --job-results-dir %s ' %
               (AVOCADO, self.test_module, self.tmpdir))
        self.proc = subprocess.Popen(cmd.split(),
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.STDOUT)

        if not wait.wait_for(self._has_children, timeout=10):
            process.kill_process_tree(self.proc.pid)
            self.fail('Avocado did not start the test process.')

        # This test will ignore SIGINT, so it should terminate
        # when we send the second SIGINT.
        os.kill(self.proc.pid, signal.SIGINT)
        # We have to actually wait 2+ seconds until
        # the ignore window is over
        time.sleep(2.5)
        os.kill(self.proc.pid, signal.SIGINT)

        if not wait.wait_for(self._is_finished, timeout=10):
            process.kill_process_tree(self.proc.pid)
            self.fail('Avocado was still running after receiving SIGINT '
                      'twice.')

        self.assertTrue(wait.wait_for(self._no_test_in_process_table,
                        timeout=10), 'Avocado left processes behind.')

        output = self.proc.stdout.read()
        # Make sure the Interrupted requested sentence is there
        self.assertIn(b'Interrupt requested. Waiting 2 seconds for test to '
                      b'finish (ignoring new Ctrl+C until then)', output)
        # Make sure the Killing test subprocess message did appear
        self.assertIn(b'Killing test subprocess', output)
Ejemplo n.º 21
0
    def test_badly_behaved(self):
        """
        Make sure avocado can cleanly get out of a loop of badly behaved tests.
        """
        bad_test_basename = "wontquit-%s" % data_factory.generate_random_string(5)
        bad_test = script.TemporaryScript(bad_test_basename, BAD_TEST, "avocado_interrupt_test", mode=0755)
        bad_test.save()

        os.chdir(basedir)
        cmd_line = "./scripts/avocado run --sysinfo=off --job-results-dir %s " "%s %s %s" % (
            self.tmpdir,
            bad_test.path,
            bad_test.path,
            bad_test.path,
        )
        proc = aexpect.Expect(command=cmd_line, linesep="")
        proc.read_until_last_line_matches(os.path.basename(bad_test.path))
        proc.sendline("\x03")
        proc.read_until_last_line_matches(
            "Interrupt requested. Waiting 2 " "seconds for test to finish " "(ignoring new Ctrl+C until then)"
        )
        # We have to actually wait 2 seconds until the ignore window is over
        time.sleep(2)
        proc.sendline("\x03")
        proc.read_until_last_line_matches("TIME       : %d s")
        wait.wait_for(lambda: not proc.is_alive(), timeout=1)

        # Make sure the bad test will be really gone from the process table
        def wait_until_no_badtest():
            bad_test_processes = []
            for p in psutil.pids():
                p_obj = None
                try:
                    p_obj = psutil.Process(p)
                except psutil.NoSuchProcess:
                    pass
                if p_obj is not None:
                    if bad_test.path in " ".join(psutil.Process(p).cmdline()):
                        bad_test_processes.append(p_obj)
            return len(bad_test_processes) == 0

        wait.wait_for(wait_until_no_badtest, timeout=2)
        # Make sure the Killing test subprocess message did appear
        self.assertIn("Killing test subprocess", proc.get_output())
Ejemplo n.º 22
0
    def test_well_behaved(self):
        """
        Make sure avocado can cleanly get out of a loop of well behaved tests.
        """
        good_test_basename = "goodtest-%s.py" % data_factory.generate_random_string(5)
        good_test = script.TemporaryScript(good_test_basename, GOOD_TEST, "avocado_interrupt_test", mode=0755)
        good_test.save()

        os.chdir(basedir)
        cmd_line = "./scripts/avocado run --sysinfo=off --job-results-dir %s " "%s %s %s" % (
            self.tmpdir,
            good_test.path,
            good_test.path,
            good_test.path,
        )
        proc = aexpect.Expect(command=cmd_line, linesep="")
        proc.read_until_last_line_matches(os.path.basename(good_test.path))
        proc.sendline("\x03")
        proc.read_until_last_line_matches("TIME       : %d s")
        wait.wait_for(lambda: not proc.is_alive(), timeout=1)

        # Make sure the good test will be really gone from the process table
        def wait_until_no_goodtest():
            good_test_processes = []
            for p in psutil.pids():
                p_obj = None
                try:
                    p_obj = psutil.Process(p)
                except psutil.NoSuchProcess:
                    pass
                if p_obj is not None:
                    if good_test.path in " ".join(psutil.Process(p).cmdline()):
                        good_test_processes.append(p_obj)
            return len(good_test_processes) == 0

        wait.wait_for(wait_until_no_goodtest, timeout=2)
        # Make sure the Killing test subprocess message is not there
        self.assertNotIn("Killing test subprocess", proc.get_output())
        # Make sure the Interrupted requested sentence is there
        self.assertIn(
            "Interrupt requested. Waiting 2 seconds for test to " "finish (ignoring new Ctrl+C until then)",
            proc.get_output(),
        )
Ejemplo n.º 23
0
    def test_well_behaved_sigterm(self):
        """
        Make sure avocado can cleanly get out of a loop of well behaved tests.

        :avocado: tags=parallel:1
        """
        good_test_basename = ('goodtest-%s.py' %
                              data_factory.generate_random_string(5))
        good_test = script.TemporaryScript(good_test_basename,
                                           GOOD_TEST,
                                           'avocado_interrupt_test',
                                           mode=DEFAULT_MODE)
        good_test.save()
        self.test_module = good_test.path
        os.chdir(BASEDIR)
        cmd = ('%s run %s --sysinfo=off --job-results-dir %s ' %
               (AVOCADO, self.test_module, self.tmpdir.name))
        proc = subprocess.Popen(cmd.split(),
                                stdout=subprocess.PIPE,
                                stderr=subprocess.STDOUT)

        if not wait.wait_for(lambda: self.has_children(proc), timeout=10):
            process.kill_process_tree(proc.pid)
            self.fail('Avocado did not start the test process.')

        # This test should be terminated when the main process
        # receives a SIGTERM.
        os.kill(proc.pid, signal.SIGTERM)

        if not wait.wait_for(lambda: self.is_finished(proc), timeout=10):
            process.kill_process_tree(proc.pid)
            self.fail('Avocado was still running after receiving SIGINT '
                      'twice.')

        self.assertTrue(
            wait.wait_for(self._no_test_in_process_table, timeout=10),
            'Avocado left processes behind.')

        # Make sure the Interrupted test sentence is there
        self.assertIn(b'Terminated\n', proc.stdout.read())
Ejemplo n.º 24
0
    def test_well_behaved_sigint(self):
        """
        Make sure avocado can cleanly get out of a loop of well behaved tests.
        """
        good_test_basename = ('goodtest-%s.py' %
                              data_factory.generate_random_string(5))
        good_test = script.TemporaryScript(good_test_basename, GOOD_TEST,
                                           'avocado_interrupt_test',
                                           mode=DEFAULT_MODE)
        good_test.save()
        self.test_module = good_test.path
        os.chdir(basedir)
        cmd = ('%s run %s --sysinfo=off --job-results-dir %s ' %
               (AVOCADO, self.test_module, self.tmpdir))
        self.proc = subprocess.Popen(cmd.split(),
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.STDOUT)

        if not wait.wait_for(self._has_children, timeout=10):
            process.kill_process_tree(self.proc.pid)
            self.fail('Avocado did not start the test process.')

        # This test will not ignore SIGINT, so it should
        # terminate right away.
        os.kill(self.proc.pid, signal.SIGINT)

        if not wait.wait_for(self._is_finished, timeout=10):
            process.kill_process_tree(self.proc.pid)
            self.fail('Avocado was still running after receiving SIGINT '
                      'twice.')

        self.assertTrue(wait.wait_for(self._no_test_in_process_table,
                        timeout=10), 'Avocado left processes behind.')

        output = self.proc.stdout.read()
        # Make sure the Interrupted requested sentence is there
        self.assertIn(b'Interrupt requested. Waiting 2 seconds for test to '
                      b'finish (ignoring new Ctrl+C until then)', output)
        # Make sure the Killing test subprocess message is not there
        self.assertNotIn(b'Killing test subprocess', output)
Ejemplo n.º 25
0
    def test_badly_behaved_sigterm(self):
        """
        Make sure avocado can cleanly get out of a loop of badly behaved tests.
        """
        bad_test_basename = ('wontquit-%s' %
                             data_factory.generate_random_string(5))
        bad_test = script.TemporaryScript(bad_test_basename,
                                          BAD_TEST,
                                          'avocado_interrupt_test',
                                          mode=DEFAULT_MODE)
        bad_test.save()
        self.test_module = bad_test.path
        os.chdir(basedir)
        cmd = ('%s run %s --sysinfo=off --job-results-dir %s ' %
               (AVOCADO, self.test_module, self.tmpdir))
        self.proc = subprocess.Popen(cmd.split(),
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.STDOUT)

        if not wait.wait_for(self._has_children, timeout=10):
            process.kill_process_tree(self.proc.pid)
            self.fail('Avocado did not start the test process.')

        # This test should be terminated when the main process
        # receives a SIGTERM, even if the test process ignores SIGTERM.
        os.kill(self.proc.pid, signal.SIGTERM)

        if not wait.wait_for(self._is_finished, timeout=10):
            process.kill_process_tree(self.proc.pid)
            self.fail('Avocado was still running after receiving SIGINT '
                      'twice.')

        self.assertTrue(
            wait.wait_for(self._no_test_in_process_table, timeout=10),
            'Avocado left processes behind.')

        # Make sure the Interrupted test sentence is there
        self.assertIn('Terminated\n', self.proc.stdout.read())
Ejemplo n.º 26
0
    def add_repo(self, url):
        """
        Adds package repository located on [url].

        :param url: Universal Resource Locator of the repository.
        """
        # Check if we URL is already set
        for section in self.cfgparser.sections():
            for option, value in self.cfgparser.items(section):
                if option == 'url' and value == url:
                    return True

        # Didn't find it, let's set it up
        while True:
            section_name = 'software_manager' + '_'
            section_name += data_factory.generate_random_string(4)
            if not self.cfgparser.has_section(section_name):
                break
        self.cfgparser.add_section(section_name)
        self.cfgparser.set(section_name, 'name', 'Avocado managed repository')
        self.cfgparser.set(section_name, 'url', url)
        self.cfgparser.set(section_name, 'enabled', 1)
        self.cfgparser.set(section_name, 'gpgcheck', 0)
        self.cfgparser.write(open(self.repo_file_path, "w"))
Ejemplo n.º 27
0
    def test_well_behaved_sigterm(self):
        """
        Make sure avocado can cleanly get out of a loop of well behaved tests.
        """
        good_test_basename = ('goodtest-%s.py' %
                              data_factory.generate_random_string(5))
        good_test = script.TemporaryScript(good_test_basename, GOOD_TEST,
                                           'avocado_interrupt_test',
                                           mode=DEFAULT_MODE)
        good_test.save()
        self.test_module = good_test.path
        os.chdir(BASEDIR)
        cmd = ('%s run %s --sysinfo=off --job-results-dir %s ' %
               (AVOCADO, self.test_module, self.tmpdir))
        self.proc = subprocess.Popen(cmd.split(),
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.STDOUT)

        if not wait.wait_for(self._has_children, timeout=10):
            process.kill_process_tree(self.proc.pid)
            self.fail('Avocado did not start the test process.')

        # This test should be terminated when the main process
        # receives a SIGTERM.
        os.kill(self.proc.pid, signal.SIGTERM)

        if not wait.wait_for(self._is_finished, timeout=10):
            process.kill_process_tree(self.proc.pid)
            self.fail('Avocado was still running after receiving SIGINT '
                      'twice.')

        self.assertTrue(wait.wait_for(self._no_test_in_process_table,
                        timeout=10), 'Avocado left processes behind.')

        # Make sure the Interrupted test sentence is there
        self.assertIn(b'Terminated\n', self.proc.stdout.read())
Ejemplo n.º 28
0
    def _create_vm_and_cpus(self, numa_count):
        self.log.info("NUMA count is %s" % numa_count)

        extra_spec = {"hw:numa_nodes": numa_count}
        i = 0
        while i < numa_count:
            extra_spec['hw:numa_node.' + str(i)] = str(i)
            i += 1
        for key, value in extra_spec.items():
            self.log.info('Flavor extra specs key %s => value %s', key, value)

        vm_name = 'cloudtest_' + data_factory.generate_random_string(6)

        self.flavor = self.compute_utils.create_flavor(ram=self.ram,
                                                       vcpus=self.vcpus,
                                                       disk=self.disk,
                                                       extra_spec=extra_spec)

        # Create instance1 with cpu_policy and cpu_thread_policy
        instance = test_utils.create_vm_with_cpu_pinning_and_wait_for_login(
            self.params,
            vm_name,
            injected_key=self.pub_key,
            ram=self.ram,
            vcpus=self.vcpus,
            disk=self.disk,
            flavor_name=self.flavor.name,
            **extra_spec)
        self.vm_list.append(instance)

        # Get instance name via name
        self.instance_name = self.compute_utils.get_vm_domain_name(vm_name)
        self.log.info("instance name is %s" % self.instance_name)
        # Get host via name
        self.compute_ip = self.compute_utils.get_server_host(vm_name)
        self.log.info("host is %s" % self.compute_ip)
Ejemplo n.º 29
0
 def setUp(self):
     self.port = network.find_free_port(address=self.ADDRESS, sequent=False)
     self.instance_id = data_factory.generate_random_string(12)
     self.server = cloudinit.PhoneHomeServer((self.ADDRESS, self.port),
                                             self.instance_id)
Ejemplo n.º 30
0
def run(test, params, env):
    """
    KVM migration with destination problems.
    Contains group of test for testing qemu behavior if some
    problems happens on destination side.

    Tests are described right in test classes comments down in code.

    Test needs params: nettype = bridge.

    :param test: kvm test object.
    :param params: Dictionary with test parameters.
    :param env: Dictionary with the test environment.
    """
    login_timeout = int(params.get("login_timeout", 360))
    mig_timeout = float(params.get("mig_timeout", "3600"))
    mig_protocol = params.get("migration_protocol", "tcp")

    test_rand = None
    mount_path = None
    while mount_path is None or os.path.exists(mount_path):
        test_rand = data_factory.generate_random_string(3)
        mount_path = ("%s/ni_mount_%s" % (data_dir.get_data_dir(), test_rand))

    mig_dst = os.path.join(mount_path, "mig_dst")

    migration_exec_cmd_src = params.get("migration_exec_cmd_src",
                                        "gzip -c > %s")
    migration_exec_cmd_src = (migration_exec_cmd_src % (mig_dst))

    class MiniSubtest(object):
        def __new__(cls, *args, **kargs):
            self = super(MiniSubtest, cls).__new__(cls)
            ret = None
            exc_info = None
            if args is None:
                args = []
            try:
                try:
                    ret = self.test(*args, **kargs)
                except Exception:
                    exc_info = sys.exc_info()
            finally:
                if hasattr(self, "clean"):
                    try:
                        self.clean()
                    except Exception:
                        if exc_info is None:
                            raise
                    if exc_info:
                        six.reraise(exc_info[0], exc_info[1], exc_info[2])
            return ret

    def control_service(session, service, init_service, action, timeout=60):
        """
        Start service on guest.

        :param vm: Virtual machine for vm.
        :param service: service to stop.
        :param action: action with service (start|stop|restart)
        :param init_service: name of service for old service control.
        """
        status = utils_misc.get_guest_service_status(
            session, service, service_former=init_service)
        if action == "start" and status == "active":
            logging.debug("%s already started, no need start it again.",
                          service)
            return
        if action == "stop" and status == "inactive":
            logging.debug("%s already stopped, no need stop it again.",
                          service)
            return
        try:
            session.cmd("systemctl --version", timeout=timeout)
            session.cmd("systemctl %s %s.service" % (action, service),
                        timeout=timeout)
        except:
            session.cmd("service %s %s" % (init_service, action),
                        timeout=timeout)

    def set_nfs_server(vm, share_cfg):
        """
        Start nfs server on guest.

        :param vm: Virtual machine for vm.
        """
        session = vm.wait_for_login(timeout=login_timeout)
        cmd = "echo '%s' > /etc/exports" % (share_cfg)
        control_service(session, "nfs-server", "nfs", "stop")
        session.cmd(cmd)
        control_service(session, "nfs-server", "nfs", "start")
        session.cmd("iptables -F")
        session.close()

    def umount(mount_path):
        """
        Umount nfs server mount_path

        :param mount_path: path where nfs dir will be placed.
        """
        process.run("umount -f %s" % (mount_path))

    def create_file_disk(dst_path, size):
        """
        Create file with size and create there ext3 filesystem.

        :param dst_path: Path to file.
        :param size: Size of file in MB
        """
        process.run("dd if=/dev/zero of=%s bs=1M count=%s" % (dst_path, size))
        process.run("mkfs.ext3 -F %s" % (dst_path))

    def mount(disk_path, mount_path, options=None):
        """
        Mount Disk to path

        :param disk_path: Path to disk
        :param mount_path: Path where disk will be mounted.
        :param options: String with options for mount
        """
        if options is None:
            options = ""
        else:
            options = "%s" % options

        process.run("mount %s %s %s" % (options, disk_path, mount_path))

    def find_disk_vm(vm, disk_serial):
        """
        Find disk on vm which ends with disk_serial

        :param vm: VM where to find a disk.
        :param disk_serial: sufix of disk id.

        :return: string Disk path
        """
        session = vm.wait_for_login(timeout=login_timeout)

        disk_path = os.path.join("/", "dev", "disk", "by-id")
        disks = session.cmd("ls %s" % disk_path).split("\n")
        session.close()
        disk = list(filter(lambda x: x.endswith(disk_serial), disks))
        if not disk:
            return None
        return os.path.join(disk_path, disk[0])

    def prepare_disk(vm, disk_path, mount_path):
        """
        Create Ext3 on disk a send there data from main disk.

        :param vm: VM where to find a disk.
        :param disk_path: Path to disk in guest system.
        """
        session = vm.wait_for_login(timeout=login_timeout)
        session.cmd("mkfs.ext3 -F %s" % (disk_path))
        session.cmd("mount %s %s" % (disk_path, mount_path))
        session.close()

    def disk_load(vm, src_path, dst_path, copy_timeout=None, dsize=None):
        """
        Start disk load. Cyclic copy from src_path to dst_path.

        :param vm: VM where to find a disk.
        :param src_path: Source of data
        :param dst_path: Path to destination
        :param copy_timeout: Timeout for copy
        :param dsize: Size of data block which is periodical copied.
        """
        if dsize is None:
            dsize = 100
        session = vm.wait_for_login(timeout=login_timeout)
        cmd = ("nohup /bin/bash -c 'while true; do dd if=%s of=%s bs=1M "
               "count=%s; done;' 2> /dev/null &" % (src_path, dst_path, dsize))
        pid = re.search(r"\[.+\] (.+)",
                        session.cmd_output(cmd, timeout=copy_timeout))
        return pid.group(1)

    class IscsiServer_tgt(object):
        """
        Class for set and start Iscsi server.
        """
        def __init__(self):
            self.server_name = "autotest_guest_" + test_rand
            self.user = "******"
            self.passwd = "pass"
            self.config = """
<target %s:dev01>
    backing-store %s
    incominguser %s %s
</target>
"""

        def set_iscsi_server(self, vm_ds, disk_path, disk_size):
            """
            Set iscsi server with some variant.

            @oaram vm_ds: VM where should be iscsi server started.
            :param disk_path: path where should be disk placed.
            :param disk_size: size of new disk.
            """
            session = vm_ds.wait_for_login(timeout=login_timeout)

            session.cmd("dd if=/dev/zero of=%s bs=1M count=%s" %
                        (disk_path, disk_size))
            status, output = session.cmd_status_output("setenforce 0")
            if status not in [0, 127]:
                logging.warn("Function setenforce fails.\n %s" % (output))

            config = self.config % (self.server_name, disk_path, self.user,
                                    self.passwd)
            cmd = "cat > /etc/tgt/conf.d/virt.conf << EOF" + config + "EOF"
            control_service(session, "tgtd", "tgtd", "stop")
            session.sendline(cmd)
            control_service(session, "tgtd", "tgtd", "start")
            session.cmd("iptables -F")
            session.close()

        def find_disk(self):
            disk_path = os.path.join("/", "dev", "disk", "by-path")
            disks = process.run("ls %s" % disk_path).stdout.split("\n")
            disk = list(filter(lambda x: self.server_name in x, disks))
            if not disk:
                return None
            return os.path.join(disk_path, disk[0].strip())

        def connect(self, vm_ds):
            """
            Connect to iscsi server on guest.

            :param vm_ds: Guest where is iscsi server running.

            :return: path where disk is connected.
            """
            ip_dst = vm_ds.get_address()
            process.run("iscsiadm -m discovery -t st -p %s" % (ip_dst))

            server_ident = ('iscsiadm -m node --targetname "%s:dev01"'
                            ' --portal %s' % (self.server_name, ip_dst))
            process.run("%s --op update --name node.session.auth.authmethod"
                        " --value CHAP" % (server_ident))
            process.run("%s --op update --name node.session.auth.username"
                        " --value %s" % (server_ident, self.user))
            process.run("%s --op update --name node.session.auth.password"
                        " --value %s" % (server_ident, self.passwd))
            process.run("%s --login" % (server_ident))
            time.sleep(1.0)
            return self.find_disk()

        def disconnect(self):
            server_ident = ('iscsiadm -m node --targetname "%s:dev01"' %
                            (self.server_name))
            process.run("%s --logout" % (server_ident))

    class IscsiServer(object):
        """
        Iscsi server implementation interface.
        """
        def __init__(self, iscsi_type, *args, **kargs):
            if iscsi_type == "tgt":
                self.ic = IscsiServer_tgt(*args, **kargs)
            else:
                raise NotImplementedError()

        def __getattr__(self, name):
            if self.ic:
                return self.ic.__getattribute__(name)
            raise AttributeError("Cannot find attribute %s in class" % name)

    class test_read_only_dest(MiniSubtest):
        """
        Migration to read-only destination by using a migration to file.

        1) Start guest with NFS server.
        2) Config NFS server share for read-only.
        3) Mount the read-only share to host.
        4) Start second guest and try to migrate to read-only dest.

        result) Migration should fail with error message about read-only dst.
        """
        def test(self):
            if params.get("nettype") != "bridge":
                test.cancel("Unable start test without params nettype=bridge.")

            vm_ds = env.get_vm("virt_test_vm2_data_server")
            vm_guest = env.get_vm("virt_test_vm1_guest")
            ro_timeout = int(params.get("read_only_timeout", "480"))
            exp_str = r".*Read-only file system.*"
            process.run("mkdir -p %s" % (mount_path))

            vm_ds.verify_alive()
            vm_guest.create()
            vm_guest.verify_alive()

            set_nfs_server(vm_ds, "/mnt *(ro,async,no_root_squash)")

            mount_src = "%s:/mnt" % (vm_ds.get_address())
            mount(mount_src, mount_path,
                  "-o hard,timeo=14,rsize=8192,wsize=8192")
            vm_guest.migrate(mig_timeout,
                             mig_protocol,
                             not_wait_for_migration=True,
                             migration_exec_cmd_src=migration_exec_cmd_src,
                             env=env)

            if not utils_misc.wait_for(
                    lambda: process_output_check(vm_guest.process, exp_str),
                    timeout=ro_timeout,
                    first=2):
                test.fail("The Read-only file system warning not"
                          " come in time limit.")

        def clean(self):
            if os.path.exists(mig_dst):
                os.remove(mig_dst)
            if os.path.exists(mount_path):
                umount(mount_path)
                os.rmdir(mount_path)

    class test_low_space_dest(MiniSubtest):
        """
        Migrate to destination with low space.

        1) Start guest.
        2) Create disk with low space.
        3) Try to migratie to the disk.

        result) Migration should fail with warning about No left space on dev.
        """
        def test(self):
            self.disk_path = None
            while self.disk_path is None or os.path.exists(self.disk_path):
                self.disk_path = (
                    "%s/disk_%s" %
                    (test.tmpdir, data_factory.generate_random_string(3)))

            disk_size = int(
                utils_misc.normalize_data_size(params.get("disk_size", "10M"),
                                               "M"))

            exp_str = r".*gzip: stdout: No space left on device.*"
            vm_guest = env.get_vm("virt_test_vm1_guest")
            process.run("mkdir -p %s" % (mount_path))

            vm_guest.verify_alive()
            vm_guest.wait_for_login(timeout=login_timeout)

            create_file_disk(self.disk_path, disk_size)
            mount(self.disk_path, mount_path, "-o loop")

            vm_guest.migrate(mig_timeout,
                             mig_protocol,
                             not_wait_for_migration=True,
                             migration_exec_cmd_src=migration_exec_cmd_src,
                             env=env)

            if not utils_misc.wait_for(
                    lambda: process_output_check(vm_guest.process, exp_str),
                    timeout=60,
                    first=1):
                test.fail("The migration to destination with low "
                          "storage space didn't fail as it should.")

        def clean(self):
            if os.path.exists(mount_path):
                umount(mount_path)
                os.rmdir(mount_path)
            if os.path.exists(self.disk_path):
                os.remove(self.disk_path)

    class test_extensive_io(MiniSubtest):
        """
        Migrate after extensive_io abstract class. This class only define
        basic funtionaly and define interface. For other tests.

        1) Start ds_guest which starts data server.
        2) Create disk for data stress in ds_guest.
        3) Share and prepare disk from ds_guest
        6) Mount the disk to mount_path
        7) Create disk for second guest in the mounted path.
        8) Start second guest with prepared disk.
        9) Start stress on the prepared disk on second guest.
        10) Wait few seconds.
        11) Restart iscsi server.
        12) Migrate second guest.

        result) Migration should be successful.
        """
        def test(self):
            self.copier_pid = None
            if params.get("nettype") != "bridge":
                test.cancel("Unable start test without params nettype=bridge.")

            self.disk_serial = params.get("drive_serial_image2_vm1",
                                          "nfs-disk-image2-vm1")
            self.disk_serial_src = params.get("drive_serial_image1_vm1",
                                              "root-image1-vm1")
            self.guest_mount_path = params.get("guest_disk_mount_path", "/mnt")
            self.copy_timeout = int(params.get("copy_timeout", "1024"))

            self.copy_block_size = int(
                utils_misc.normalize_data_size(
                    params.get("copy_block_size", "100M"), "M"))
            self.disk_size = "%sM" % int(self.copy_block_size * 1.4)

            self.server_recover_timeout = (int(
                params.get("server_recover_timeout", "240")))

            process.run("mkdir -p %s" % (mount_path))

            self.test_params()
            self.config()

            self.vm_guest_params = params.copy()
            self.vm_guest_params["images_base_dir_image2_vm1"] = mount_path
            self.vm_guest_params[
                "image_name_image2_vm1"] = "ni_mount_%s/test" % (test_rand)
            self.vm_guest_params["image_size_image2_vm1"] = self.disk_size
            self.vm_guest_params = self.vm_guest_params.object_params("vm1")
            self.image2_vm_guest_params = (
                self.vm_guest_params.object_params("image2"))

            env_process.preprocess_image(test, self.image2_vm_guest_params,
                                         env)
            self.vm_guest.create(params=self.vm_guest_params)

            self.vm_guest.verify_alive()
            self.vm_guest.wait_for_login(timeout=login_timeout)
            self.workload()

            self.restart_server()

            self.vm_guest.migrate(mig_timeout, mig_protocol, env=env)

            try:
                self.vm_guest.verify_alive()
                self.vm_guest.wait_for_login(timeout=login_timeout)
            except aexpect.ExpectTimeoutError:
                test.fail("Migration should be successful.")

        def test_params(self):
            """
            Test specific params. Could be implemented in inherited class.
            """
            pass

        def config(self):
            """
            Test specific config.
            """
            raise NotImplementedError()

        def workload(self):
            disk_path = find_disk_vm(self.vm_guest, self.disk_serial)
            if disk_path is None:
                test.fail("It was impossible to find disk on VM")

            prepare_disk(self.vm_guest, disk_path, self.guest_mount_path)

            disk_path_src = find_disk_vm(self.vm_guest, self.disk_serial_src)
            dst_path = os.path.join(self.guest_mount_path, "test.data")
            self.copier_pid = disk_load(self.vm_guest, disk_path_src, dst_path,
                                        self.copy_timeout,
                                        self.copy_block_size)

        def restart_server(self):
            raise NotImplementedError()

        def clean_test(self):
            """
            Test specific cleanup.
            """
            pass

        def clean(self):
            if self.copier_pid:
                try:
                    if self.vm_guest.is_alive():
                        session = self.vm_guest.wait_for_login(
                            timeout=login_timeout)
                        session.cmd("kill -9 %s" % (self.copier_pid))
                except:
                    logging.warn("It was impossible to stop copier. Something "
                                 "probably happened with GUEST or NFS server.")

            if params.get("kill_vm") == "yes":
                if self.vm_guest.is_alive():
                    self.vm_guest.destroy()
                    utils_misc.wait_for(lambda: self.vm_guest.is_dead(), 30, 2,
                                        2, "Waiting for dying of guest.")
                qemu_img = qemu_storage.QemuImg(self.image2_vm_guest_params,
                                                mount_path, None)
                qemu_img.check_image(self.image2_vm_guest_params, mount_path)

            self.clean_test()

    class test_extensive_io_nfs(test_extensive_io):
        """
        Migrate after extensive io.

        1) Start ds_guest which starts NFS server.
        2) Create disk for data stress in ds_guest.
        3) Share disk over NFS.
        4) Mount the disk to mount_path
        5) Create disk for second guest in the mounted path.
        6) Start second guest with prepared disk.
        7) Start stress on the prepared disk on second guest.
        8) Wait few seconds.
        9) Restart iscsi server.
        10) Migrate second guest.

        result) Migration should be successful.
        """
        def config(self):
            vm_ds = env.get_vm("virt_test_vm2_data_server")
            self.vm_guest = env.get_vm("vm1")
            self.image2_vm_guest_params = None
            self.copier_pid = None
            self.qemu_img = None

            vm_ds.verify_alive()
            self.control_session_ds = vm_ds.wait_for_login(
                timeout=login_timeout)

            set_nfs_server(vm_ds, "/mnt *(rw,async,no_root_squash)")

            mount_src = "%s:/mnt" % (vm_ds.get_address())
            mount(mount_src, mount_path,
                  "-o hard,timeo=14,rsize=8192,wsize=8192")

        def restart_server(self):
            time.sleep(10)  # Wait for wail until copy start working.
            control_service(self.control_session_ds, "nfs-server", "nfs",
                            "stop")  # Stop NFS server
            time.sleep(5)
            control_service(self.control_session_ds, "nfs-server", "nfs",
                            "start")  # Start NFS server
            """
            Touch waits until all previous requests are invalidated
            (NFS grace period). Without grace period qemu start takes
            to long and timers for machine creation dies.
            """
            qemu_img = qemu_storage.QemuImg(self.image2_vm_guest_params,
                                            mount_path, None)
            process.run("touch %s" % (qemu_img.image_filename),
                        self.server_recover_timeout)

        def clean_test(self):
            if os.path.exists(mount_path):
                umount(mount_path)
                os.rmdir(mount_path)

    class test_extensive_io_iscsi(test_extensive_io):
        """
        Migrate after extensive io.

        1) Start ds_guest which starts iscsi server.
        2) Create disk for data stress in ds_guest.
        3) Share disk over iscsi.
        4) Join to disk on host.
        5) Prepare partition on the disk.
        6) Mount the disk to mount_path
        7) Create disk for second guest in the mounted path.
        8) Start second guest with prepared disk.
        9) Start stress on the prepared disk on second guest.
        10) Wait few seconds.
        11) Restart iscsi server.
        12) Migrate second guest.

        result) Migration should be successful.
        """
        def test_params(self):
            self.iscsi_variant = params.get("iscsi_variant", "tgt")
            self.ds_disk_path = os.path.join(self.guest_mount_path, "test.img")

        def config(self):
            vm_ds = env.get_vm("virt_test_vm2_data_server")
            self.vm_guest = env.get_vm("vm1")
            self.image2_vm_guest_params = None
            self.copier_pid = None
            self.qemu_img = None

            vm_ds.verify_alive()
            self.control_session_ds = vm_ds.wait_for_login(
                timeout=login_timeout)

            self.isci_server = IscsiServer("tgt")
            disk_path = os.path.join(self.guest_mount_path, "disk1")
            self.isci_server.set_iscsi_server(
                vm_ds, disk_path,
                (int(float(self.disk_size) * 1.1) / (1024 * 1024)))
            self.host_disk_path = self.isci_server.connect(vm_ds)

            process.run("mkfs.ext3 -F %s" % (self.host_disk_path))
            mount(self.host_disk_path, mount_path)

        def restart_server(self):
            time.sleep(10)  # Wait for wail until copy start working.
            control_service(self.control_session_ds, "tgtd", "tgtd", "stop",
                            240)  # Stop Iscsi server
            time.sleep(5)
            control_service(self.control_session_ds, "tgtd", "tgtd", "start",
                            240)  # Start Iscsi server
            """
            Wait for iscsi server after restart and will be again
            accessible.
            """
            qemu_img = qemu_storage.QemuImg(self.image2_vm_guest_params,
                                            mount_path, None)
            process.run("touch %s" % (qemu_img.image_filename),
                        self.server_recover_timeout)

        def clean_test(self):
            if os.path.exists(mount_path):
                umount(mount_path)
                os.rmdir(mount_path)
            if os.path.exists(self.host_disk_path):
                self.isci_server.disconnect()

    test_type = params.get("test_type")
    if (test_type in locals()):
        tests_group = locals()[test_type]
        tests_group()
    else:
        test.fail("Test group '%s' is not defined in"
                  " migration_with_dst_problem test" % test_type)
Ejemplo n.º 31
0
 def setUp(self):
     self.port = network.find_free_port(address=self.ADDRESS)
     self.instance_id = data_factory.generate_random_string(12)
     self.server = cloudinit.PhoneHomeServer((self.ADDRESS, self.port),
                                             self.instance_id)
Ejemplo n.º 32
0
 def setUp(self):
     self.instance_id = data_factory.generate_random_string(12)
     self.server = cloudinit.PhoneHomeServer((self.ADDRESS, 0),
                                             self.instance_id)
def run(test, params, env):
    """
    KVM migration with destination problems.
    Contains group of test for testing qemu behavior if some
    problems happens on destination side.

    Tests are described right in test classes comments down in code.

    Test needs params: nettype = bridge.

    :param test: kvm test object.
    :param params: Dictionary with test parameters.
    :param env: Dictionary with the test environment.
    """
    login_timeout = int(params.get("login_timeout", 360))
    mig_timeout = float(params.get("mig_timeout", "3600"))
    mig_protocol = params.get("migration_protocol", "tcp")

    test_rand = None
    mount_path = None
    while mount_path is None or os.path.exists(mount_path):
        test_rand = data_factory.generate_random_string(3)
        mount_path = ("%s/ni_mount_%s" %
                      (data_dir.get_data_dir(), test_rand))

    mig_dst = os.path.join(mount_path, "mig_dst")

    migration_exec_cmd_src = params.get("migration_exec_cmd_src",
                                        "gzip -c > %s")
    migration_exec_cmd_src = (migration_exec_cmd_src % (mig_dst))

    class MiniSubtest(object):

        def __new__(cls, *args, **kargs):
            self = super(MiniSubtest, cls).__new__(cls)
            ret = None
            exc_info = None
            if args is None:
                args = []
            try:
                try:
                    ret = self.test(*args, **kargs)
                except Exception:
                    exc_info = sys.exc_info()
            finally:
                if hasattr(self, "clean"):
                    try:
                        self.clean()
                    except Exception:
                        if exc_info is None:
                            raise
                    if exc_info:
                        six.reraise(exc_info[0], exc_info[1], exc_info[2])
            return ret

    def control_service(session, service, init_service, action, timeout=60):
        """
        Start service on guest.

        :param vm: Virtual machine for vm.
        :param service: service to stop.
        :param action: action with service (start|stop|restart)
        :param init_service: name of service for old service control.
        """
        status = utils_misc.get_guest_service_status(session, service,
                                                     service_former=init_service)
        if action == "start" and status == "active":
            logging.debug("%s already started, no need start it again.",
                          service)
            return
        if action == "stop" and status == "inactive":
            logging.debug("%s already stopped, no need stop it again.",
                          service)
            return
        try:
            session.cmd("systemctl --version", timeout=timeout)
            session.cmd("systemctl %s %s.service" % (action, service),
                        timeout=timeout)
        except:
            session.cmd("service %s %s" % (init_service, action),
                        timeout=timeout)

    def set_nfs_server(vm, share_cfg):
        """
        Start nfs server on guest.

        :param vm: Virtual machine for vm.
        """
        session = vm.wait_for_login(timeout=login_timeout)
        cmd = "echo '%s' > /etc/exports" % (share_cfg)
        control_service(session, "nfs-server", "nfs", "stop")
        session.cmd(cmd)
        control_service(session, "nfs-server", "nfs", "start")
        session.cmd("iptables -F")
        session.close()

    def umount(mount_path):
        """
        Umount nfs server mount_path

        :param mount_path: path where nfs dir will be placed.
        """
        process.run("umount -f %s" % (mount_path))

    def create_file_disk(dst_path, size):
        """
        Create file with size and create there ext3 filesystem.

        :param dst_path: Path to file.
        :param size: Size of file in MB
        """
        process.run("dd if=/dev/zero of=%s bs=1M count=%s" % (dst_path, size))
        process.run("mkfs.ext3 -F %s" % (dst_path))

    def mount(disk_path, mount_path, options=None):
        """
        Mount Disk to path

        :param disk_path: Path to disk
        :param mount_path: Path where disk will be mounted.
        :param options: String with options for mount
        """
        if options is None:
            options = ""
        else:
            options = "%s" % options

        process.run("mount %s %s %s" % (options, disk_path, mount_path))

    def find_disk_vm(vm, disk_serial):
        """
        Find disk on vm which ends with disk_serial

        :param vm: VM where to find a disk.
        :param disk_serial: sufix of disk id.

        :return: string Disk path
        """
        session = vm.wait_for_login(timeout=login_timeout)

        disk_path = os.path.join("/", "dev", "disk", "by-id")
        disks = session.cmd("ls %s" % disk_path).split("\n")
        session.close()
        disk = list(filter(lambda x: x.endswith(disk_serial), disks))
        if not disk:
            return None
        return os.path.join(disk_path, disk[0])

    def prepare_disk(vm, disk_path, mount_path):
        """
        Create Ext3 on disk a send there data from main disk.

        :param vm: VM where to find a disk.
        :param disk_path: Path to disk in guest system.
        """
        session = vm.wait_for_login(timeout=login_timeout)
        session.cmd("mkfs.ext3 -F %s" % (disk_path))
        session.cmd("mount %s %s" % (disk_path, mount_path))
        session.close()

    def disk_load(vm, src_path, dst_path, copy_timeout=None, dsize=None):
        """
        Start disk load. Cyclic copy from src_path to dst_path.

        :param vm: VM where to find a disk.
        :param src_path: Source of data
        :param dst_path: Path to destination
        :param copy_timeout: Timeout for copy
        :param dsize: Size of data block which is periodical copied.
        """
        if dsize is None:
            dsize = 100
        session = vm.wait_for_login(timeout=login_timeout)
        cmd = ("nohup /bin/bash -c 'while true; do dd if=%s of=%s bs=1M "
               "count=%s; done;' 2> /dev/null &" % (src_path, dst_path, dsize))
        pid = re.search(r"\[.+\] (.+)",
                        session.cmd_output(cmd, timeout=copy_timeout))
        return pid.group(1)

    class IscsiServer_tgt(object):

        """
        Class for set and start Iscsi server.
        """

        def __init__(self):
            self.server_name = "autotest_guest_" + test_rand
            self.user = "******"
            self.passwd = "pass"
            self.config = """
<target %s:dev01>
    backing-store %s
    incominguser %s %s
</target>
"""

        def set_iscsi_server(self, vm_ds, disk_path, disk_size):
            """
            Set iscsi server with some variant.

            @oaram vm_ds: VM where should be iscsi server started.
            :param disk_path: path where should be disk placed.
            :param disk_size: size of new disk.
            """
            session = vm_ds.wait_for_login(timeout=login_timeout)

            session.cmd("dd if=/dev/zero of=%s bs=1M count=%s" % (disk_path,
                                                                  disk_size))
            status, output = session.cmd_status_output("setenforce 0")
            if status not in [0, 127]:
                logging.warn("Function setenforce fails.\n %s" % (output))

            config = self.config % (self.server_name, disk_path,
                                    self.user, self.passwd)
            cmd = "cat > /etc/tgt/conf.d/virt.conf << EOF" + config + "EOF"
            control_service(session, "tgtd", "tgtd", "stop")
            session.sendline(cmd)
            control_service(session, "tgtd", "tgtd", "start")
            session.cmd("iptables -F")
            session.close()

        def find_disk(self):
            disk_path = os.path.join("/", "dev", "disk", "by-path")
            disks = process.run("ls %s" % disk_path).stdout.split("\n")
            disk = list(filter(lambda x: self.server_name in x, disks))
            if not disk:
                return None
            return os.path.join(disk_path, disk[0].strip())

        def connect(self, vm_ds):
            """
            Connect to iscsi server on guest.

            :param vm_ds: Guest where is iscsi server running.

            :return: path where disk is connected.
            """
            ip_dst = vm_ds.get_address()
            process.run("iscsiadm -m discovery -t st -p %s" % (ip_dst))

            server_ident = ('iscsiadm -m node --targetname "%s:dev01"'
                            ' --portal %s' % (self.server_name, ip_dst))
            process.run("%s --op update --name node.session.auth.authmethod"
                        " --value CHAP" % (server_ident))
            process.run("%s --op update --name node.session.auth.username"
                        " --value %s" % (server_ident, self.user))
            process.run("%s --op update --name node.session.auth.password"
                        " --value %s" % (server_ident, self.passwd))
            process.run("%s --login" % (server_ident))
            time.sleep(1.0)
            return self.find_disk()

        def disconnect(self):
            server_ident = ('iscsiadm -m node --targetname "%s:dev01"' %
                            (self.server_name))
            process.run("%s --logout" % (server_ident))

    class IscsiServer(object):

        """
        Iscsi server implementation interface.
        """

        def __init__(self, iscsi_type, *args, **kargs):
            if iscsi_type == "tgt":
                self.ic = IscsiServer_tgt(*args, **kargs)
            else:
                raise NotImplementedError()

        def __getattr__(self, name):
            if self.ic:
                return self.ic.__getattribute__(name)
            raise AttributeError("Cannot find attribute %s in class" % name)

    class test_read_only_dest(MiniSubtest):

        """
        Migration to read-only destination by using a migration to file.

        1) Start guest with NFS server.
        2) Config NFS server share for read-only.
        3) Mount the read-only share to host.
        4) Start second guest and try to migrate to read-only dest.

        result) Migration should fail with error message about read-only dst.
        """

        def test(self):
            if params.get("nettype") != "bridge":
                test.cancel("Unable start test without params nettype=bridge.")

            vm_ds = env.get_vm("virt_test_vm2_data_server")
            vm_guest = env.get_vm("virt_test_vm1_guest")
            ro_timeout = int(params.get("read_only_timeout", "480"))
            exp_str = r".*Read-only file system.*"
            process.run("mkdir -p %s" % (mount_path))

            vm_ds.verify_alive()
            vm_guest.create()
            vm_guest.verify_alive()

            set_nfs_server(vm_ds, "/mnt *(ro,async,no_root_squash)")

            mount_src = "%s:/mnt" % (vm_ds.get_address())
            mount(mount_src, mount_path,
                  "-o hard,timeo=14,rsize=8192,wsize=8192")
            vm_guest.migrate(mig_timeout, mig_protocol,
                             not_wait_for_migration=True,
                             migration_exec_cmd_src=migration_exec_cmd_src,
                             env=env)

            if not utils_misc.wait_for(lambda: process_output_check(
                                       vm_guest.process, exp_str),
                                       timeout=ro_timeout, first=2):
                test.fail("The Read-only file system warning not"
                          " come in time limit.")

        def clean(self):
            if os.path.exists(mig_dst):
                os.remove(mig_dst)
            if os.path.exists(mount_path):
                umount(mount_path)
                os.rmdir(mount_path)

    class test_low_space_dest(MiniSubtest):

        """
        Migrate to destination with low space.

        1) Start guest.
        2) Create disk with low space.
        3) Try to migratie to the disk.

        result) Migration should fail with warning about No left space on dev.
        """

        def test(self):
            self.disk_path = None
            while self.disk_path is None or os.path.exists(self.disk_path):
                self.disk_path = (
                    "%s/disk_%s" %
                    (test.tmpdir, data_factory.generate_random_string(3)))

            disk_size = int(utils_misc.normalize_data_size(
                params.get("disk_size", "10M"), "M"))

            exp_str = r".*gzip: stdout: No space left on device.*"
            vm_guest = env.get_vm("virt_test_vm1_guest")
            process.run("mkdir -p %s" % (mount_path))

            vm_guest.verify_alive()
            vm_guest.wait_for_login(timeout=login_timeout)

            create_file_disk(self.disk_path, disk_size)
            mount(self.disk_path, mount_path, "-o loop")

            vm_guest.migrate(mig_timeout, mig_protocol,
                             not_wait_for_migration=True,
                             migration_exec_cmd_src=migration_exec_cmd_src,
                             env=env)

            if not utils_misc.wait_for(lambda: process_output_check(
                                       vm_guest.process, exp_str),
                                       timeout=60, first=1):
                test.fail("The migration to destination with low "
                          "storage space didn't fail as it should.")

        def clean(self):
            if os.path.exists(mount_path):
                umount(mount_path)
                os.rmdir(mount_path)
            if os.path.exists(self.disk_path):
                os.remove(self.disk_path)

    class test_extensive_io(MiniSubtest):

        """
        Migrate after extensive_io abstract class. This class only define
        basic funtionaly and define interface. For other tests.

        1) Start ds_guest which starts data server.
        2) Create disk for data stress in ds_guest.
        3) Share and prepare disk from ds_guest
        6) Mount the disk to mount_path
        7) Create disk for second guest in the mounted path.
        8) Start second guest with prepared disk.
        9) Start stress on the prepared disk on second guest.
        10) Wait few seconds.
        11) Restart iscsi server.
        12) Migrate second guest.

        result) Migration should be successful.
        """

        def test(self):
            self.copier_pid = None
            if params.get("nettype") != "bridge":
                test.cancel("Unable start test without params nettype=bridge.")

            self.disk_serial = params.get("drive_serial_image2_vm1",
                                          "nfs-disk-image2-vm1")
            self.disk_serial_src = params.get("drive_serial_image1_vm1",
                                              "root-image1-vm1")
            self.guest_mount_path = params.get("guest_disk_mount_path", "/mnt")
            self.copy_timeout = int(params.get("copy_timeout", "1024"))

            self.copy_block_size = int(utils_misc.normalize_data_size(
                params.get("copy_block_size", "100M"), "M"))
            self.disk_size = "%sM" % int(self.copy_block_size * 1.4)

            self.server_recover_timeout = (
                int(params.get("server_recover_timeout", "240")))

            process.run("mkdir -p %s" % (mount_path))

            self.test_params()
            self.config()

            self.vm_guest_params = params.copy()
            self.vm_guest_params["images_base_dir_image2_vm1"] = mount_path
            self.vm_guest_params["image_name_image2_vm1"] = "ni_mount_%s/test" % (test_rand)
            self.vm_guest_params["image_size_image2_vm1"] = self.disk_size
            self.vm_guest_params = self.vm_guest_params.object_params("vm1")
            self.image2_vm_guest_params = (self.vm_guest_params.
                                           object_params("image2"))

            env_process.preprocess_image(test,
                                         self.image2_vm_guest_params,
                                         env)
            self.vm_guest.create(params=self.vm_guest_params)

            self.vm_guest.verify_alive()
            self.vm_guest.wait_for_login(timeout=login_timeout)
            self.workload()

            self.restart_server()

            self.vm_guest.migrate(mig_timeout, mig_protocol, env=env)

            try:
                self.vm_guest.verify_alive()
                self.vm_guest.wait_for_login(timeout=login_timeout)
            except aexpect.ExpectTimeoutError:
                test.fail("Migration should be successful.")

        def test_params(self):
            """
            Test specific params. Could be implemented in inherited class.
            """
            pass

        def config(self):
            """
            Test specific config.
            """
            raise NotImplementedError()

        def workload(self):
            disk_path = find_disk_vm(self.vm_guest, self.disk_serial)
            if disk_path is None:
                test.fail("It was impossible to find disk on VM")

            prepare_disk(self.vm_guest, disk_path, self.guest_mount_path)

            disk_path_src = find_disk_vm(self.vm_guest, self.disk_serial_src)
            dst_path = os.path.join(self.guest_mount_path, "test.data")
            self.copier_pid = disk_load(self.vm_guest, disk_path_src, dst_path,
                                        self.copy_timeout, self.copy_block_size)

        def restart_server(self):
            raise NotImplementedError()

        def clean_test(self):
            """
            Test specific cleanup.
            """
            pass

        def clean(self):
            if self.copier_pid:
                try:
                    if self.vm_guest.is_alive():
                        session = self.vm_guest.wait_for_login(timeout=login_timeout)
                        session.cmd("kill -9 %s" % (self.copier_pid))
                except:
                    logging.warn("It was impossible to stop copier. Something "
                                 "probably happened with GUEST or NFS server.")

            if params.get("kill_vm") == "yes":
                if self.vm_guest.is_alive():
                    self.vm_guest.destroy()
                    utils_misc.wait_for(lambda: self.vm_guest.is_dead(), 30,
                                        2, 2, "Waiting for dying of guest.")
                qemu_img = qemu_storage.QemuImg(self.image2_vm_guest_params,
                                                mount_path,
                                                None)
                qemu_img.check_image(self.image2_vm_guest_params,
                                     mount_path)

            self.clean_test()

    class test_extensive_io_nfs(test_extensive_io):

        """
        Migrate after extensive io.

        1) Start ds_guest which starts NFS server.
        2) Create disk for data stress in ds_guest.
        3) Share disk over NFS.
        4) Mount the disk to mount_path
        5) Create disk for second guest in the mounted path.
        6) Start second guest with prepared disk.
        7) Start stress on the prepared disk on second guest.
        8) Wait few seconds.
        9) Restart iscsi server.
        10) Migrate second guest.

        result) Migration should be successful.
        """

        def config(self):
            vm_ds = env.get_vm("virt_test_vm2_data_server")
            self.vm_guest = env.get_vm("vm1")
            self.image2_vm_guest_params = None
            self.copier_pid = None
            self.qemu_img = None

            vm_ds.verify_alive()
            self.control_session_ds = vm_ds.wait_for_login(timeout=login_timeout)

            set_nfs_server(vm_ds, "/mnt *(rw,async,no_root_squash)")

            mount_src = "%s:/mnt" % (vm_ds.get_address())
            mount(mount_src, mount_path,
                  "-o hard,timeo=14,rsize=8192,wsize=8192")

        def restart_server(self):
            time.sleep(10)  # Wait for wail until copy start working.
            control_service(self.control_session_ds, "nfs-server",
                            "nfs", "stop")  # Stop NFS server
            time.sleep(5)
            control_service(self.control_session_ds, "nfs-server",
                            "nfs", "start")  # Start NFS server

            """
            Touch waits until all previous requests are invalidated
            (NFS grace period). Without grace period qemu start takes
            to long and timers for machine creation dies.
            """
            qemu_img = qemu_storage.QemuImg(self.image2_vm_guest_params,
                                            mount_path,
                                            None)
            process.run("touch %s" % (qemu_img.image_filename),
                        self.server_recover_timeout)

        def clean_test(self):
            if os.path.exists(mount_path):
                umount(mount_path)
                os.rmdir(mount_path)

    class test_extensive_io_iscsi(test_extensive_io):

        """
        Migrate after extensive io.

        1) Start ds_guest which starts iscsi server.
        2) Create disk for data stress in ds_guest.
        3) Share disk over iscsi.
        4) Join to disk on host.
        5) Prepare partition on the disk.
        6) Mount the disk to mount_path
        7) Create disk for second guest in the mounted path.
        8) Start second guest with prepared disk.
        9) Start stress on the prepared disk on second guest.
        10) Wait few seconds.
        11) Restart iscsi server.
        12) Migrate second guest.

        result) Migration should be successful.
        """

        def test_params(self):
            self.iscsi_variant = params.get("iscsi_variant", "tgt")
            self.ds_disk_path = os.path.join(self.guest_mount_path, "test.img")

        def config(self):
            vm_ds = env.get_vm("virt_test_vm2_data_server")
            self.vm_guest = env.get_vm("vm1")
            self.image2_vm_guest_params = None
            self.copier_pid = None
            self.qemu_img = None

            vm_ds.verify_alive()
            self.control_session_ds = vm_ds.wait_for_login(timeout=login_timeout)

            self.isci_server = IscsiServer("tgt")
            disk_path = os.path.join(self.guest_mount_path, "disk1")
            self.isci_server.set_iscsi_server(vm_ds, disk_path,
                                              (int(float(self.disk_size) * 1.1) / (1024 * 1024)))
            self.host_disk_path = self.isci_server.connect(vm_ds)

            process.run("mkfs.ext3 -F %s" % (self.host_disk_path))
            mount(self.host_disk_path, mount_path)

        def restart_server(self):
            time.sleep(10)  # Wait for wail until copy start working.
            control_service(self.control_session_ds, "tgtd",
                            "tgtd", "stop", 240)  # Stop Iscsi server
            time.sleep(5)
            control_service(self.control_session_ds, "tgtd",
                            "tgtd", "start", 240)  # Start Iscsi server

            """
            Wait for iscsi server after restart and will be again
            accessible.
            """
            qemu_img = qemu_storage.QemuImg(self.image2_vm_guest_params,
                                            mount_path,
                                            None)
            process.run("touch %s" % (qemu_img.image_filename),
                        self.server_recover_timeout)

        def clean_test(self):
            if os.path.exists(mount_path):
                umount(mount_path)
                os.rmdir(mount_path)
            if os.path.exists(self.host_disk_path):
                self.isci_server.disconnect()

    test_type = params.get("test_type")
    if (test_type in locals()):
        tests_group = locals()[test_type]
        tests_group()
    else:
        test.fail("Test group '%s' is not defined in"
                  " migration_with_dst_problem test" % test_type)
Ejemplo n.º 34
0
class VMOperationTest(NFVTestBase):
    def __init__(self, params, env):
        super(VMOperationTest, self).__init__(params, env)

        self.test_vms_names = []
        self.created_pssr_nics = []
        self.router_name = None
        self.pssr_host = None
        self.pssr_net = None
        self.vm_fip = None
        self.vm_name = None

    def setup(self):
        self.params['vm_name'] = 'cloudtest-' + \
            utils_misc.generate_random_string(6)
        self.vm_name = self.params['vm_name']
        flavor_name = self.params.get('flavor_name')
        if flavor_name is not None:
            self.__create_flavor(flavor_name,
                                 int(self.params.get('flavor_ram', 2048)),
                                 int(self.params.get('flavor_vcpus', 2)),
                                 int(self.params.get('flavor_disk', 20)))

        self.tenant_id = test_utils.get_tenant_id(
            self.params, self.params.get('tenant_name', 'admin'))

        self.limits_before = self.compute_utils.get_limits(self.tenant_id)
        self.log.info("The limits before creating vm: %s" %
                      self.limits_before.__dict__['_info'])

    def __create_flavor(self, flavor_name, ram, vcpus, disk):
        try:
            self.compute_utils.get_flavor_id(name=flavor_name)
        except:
            self.log.info("Failed to find flavor %s, try to create one!" %
                          flavor_name)
            self.flavor = self.compute_utils.create_flavor(name=flavor_name,
                                                           ram=ram,
                                                           vcpus=vcpus,
                                                           disk=disk)

    def __wait_for_vm_responsive(self, vm_name, vm_fip):
        login_benchmark = int(self.params.get('vm_creation_benchmark', '360'))
        cmd = self.params.get('test_vm_responsive_cmd', 'hostname')
        session = test_utils.get_host_session(self.params, 'instance', vm_fip)
        expected_result = None
        if cmd in 'hostname':
            expected_result = vm_name
        elif cmd in 'whoami':
            expected_result = self.image_username
        return test_utils.wait_for_cmd_execution_within_vm(
            session, cmd, expected_result, login_benchmark)

    def __create_specified_vm_and_wait_for_login(self):
        # create ports for VM
        vnic_count = int(self.params.get('vnics_count_per_vm', 1))
        network_name = None
        vnics = []
        if vnic_count > 1:
            vnics = test_utils.create_ports(self.params)
            for vnic in vnics:
                self.register_cleanup(vnic["id"], 'port')
        else:
            net = test_utils.get_test_network(self.params)
            network_name = net['name']

        vm = self.compute_utils.create_vm(
            vm_name=self.vm_name,
            image_name=self.params.get('image_name'),
            flavor_name=self.params.get('flavor_name'),
            network_name=network_name,
            injected_key=self.pub_key,
            sec_group=None,
            nics=vnics)
        self.register_cleanup(vm)

        if not self.compute_utils.wait_for_vm_active(vm):
            raise exceptions.TestFail("Failed to build VM: %s" % vm)

        self.vm_fip = self.compute_utils.assign_floating_ip_to_vm(vm)
        self.log.info("Created VM '%s', try to login via %s" %
                      (vm.name, self.vm_fip))
        if not self.__wait_for_vm_responsive(vm.name, self.vm_fip):
            self.compute_utils.capture_vm_console_log(vm)
            raise exceptions.TestFail("Failed to wait for VM responsive: %s" %
                                      vm.name)
        return vm

    def __create_vm(self):
        self.log.info("Test vm creation within specified time")
        start_time = time.time()
        benchmark = int(self.params.get('vm_creation_benchmark', '360'))
        self.vm = self.__create_specified_vm_and_wait_for_login()

        cost_time = time.time() - start_time
        if cost_time > benchmark:
            msg = ("Failed to created VM within %d(s)!" % benchmark)
            raise exceptions.TestFail(msg)

        self.log.info(
            "Successfully created VM within %d(s), actually used %d(s)" %
            (benchmark, cost_time))
        return self.vm

    def __delete_vm(self):
        self.log.info("Start VM deletion test")
        limits_before_del = self.compute_utils.get_limits(self.tenant_id)
        self.log.info("The limits before deleting vm: %s" %
                      limits_before_del.__dict__['_info'])

        benchmark = int(self.params.get('vm_deletion_benchmark', 6))
        if not self.compute_utils.delete_vm(self.vm_name, benchmark):
            raise exceptions.TestFail("Failed to delete vm '%s' within %d(s)" %
                                      (self.vm_name, benchmark))
        self.log.info("Successfully deleted VM within %d(s), "
                      "try to checking the resource release!" % benchmark)

        limits_after = self.compute_utils.get_limits(self.tenant_id)
        self.log.info("The limits after deleting vm: %s" %
                      limits_after.__dict__['_info'])
        if limits_after.__dict__['_info'] == self.limits_before.__dict__[
                '_info']:
            self.log.info("The resource of deleted vm has been released!")
        else:
            msg = "Not all resource of the deleted vm be released"
            if self.params.get('check_resource_deleted', 'no') == 'yes':
                raise exceptions.TestFail(msg)
            self.log.error(msg)

    def __stop_vm(self):
        self.log.info("Start VM stop test")
        limits_before_stop = self.compute_utils.get_limits(self.tenant_id)
        self.log.info("The limits before stopping vm: %s" %
                      limits_before_stop.__dict__['_info'])
        benchmark = int(self.params.get('vm_stop_benchmark', 60))
        self.log.info("Try to stop vm: %s" % self.vm_name)
        if not self.compute_utils.stop_vm(self.vm_name, benchmark):
            raise exceptions.TestFail("Failed to stop vm '%s' within %d(s)" %
                                      (self.vm_name, benchmark))
        self.log.info("Successfully stopped VM within %d(s), "
                      "try to checking the resource!" % benchmark)

        limits_after = self.compute_utils.get_limits(self.tenant_id)
        self.log.info("The limits after stopping vm: %s" %
                      limits_after.__dict__['_info'])
        if limits_after.__dict__['_info'] == limits_before_stop.__dict__[
                '_info']:
            self.log.info("The resource of stopped vm was not released!")
        else:
            raise exceptions.TestFail(
                "The resource was changed after vm stopped!")

    def __start_vm(self):
        self.log.info("Start VM startup test")
        start_time = time.time()
        benchmark = int(self.params.get('vm_start_benchmark', 60))
        self.log.info("Try to start vm: %s" % self.vm_name)
        if not self.compute_utils.start_vm(self.vm_name, benchmark):
            raise exceptions.TestFail("Failed to start vm '%s' within %d(s)" %
                                      (self.vm_name, benchmark))
        cost_time = time.time() - start_time
        self.log.info(
            "Successfully started VM within %d(s), actually used %d(s)" %
            (benchmark, cost_time))

    def __reboot_vm(self):
        self.log.info("Start VM soft reboot test")
        start_time = time.time()
        benchmark = int(self.params.get('vm_reboot_benchmark', 60))
        self.log.info("Try to reboot vm: %s" % self.vm_name)
        if not self.compute_utils.reboot_vm(self.vm_name, benchmark):
            raise exceptions.TestFail("Failed to reboot vm '%s' within %d(s)" %
                                      (self.vm_name, benchmark))
        cost_time = time.time() - start_time
        self.log.info(
            "Successfully reboot VM within %d(s), actually used %d(s)" %
            (benchmark, cost_time))

        if not self.__wait_for_vm_responsive(self.vm_name, self.vm_fip):
            self.compute_utils.capture_vm_console_log(self.vm)
            raise exceptions.TestFail("Failed to wait for VM responsive: %s" %
                                      self.vm.name)

    def test_create_delete_vm(self):
        self.__create_vm()
        self.__delete_vm()

    def test_create_reboot_vm(self):
        self.__create_vm()
        self.__reboot_vm()

    def test_stop_start_vm(self):
        self.__create_vm()
        self.__stop_vm()
        self.__start_vm()
        self.__delete_vm()

    def create_vm_with_pssr_nic(self):
        pssr_type = self.params.get('passthrough_type')
        self.pssr_host = self.params.get('pssr_hostname')
        self.pssr_nic = self.params.get('pssr_nic')
        if not self.pssr_nic and not self.pssr_host:
            pssr_resource = self.compute_utils.setup_pssr(
                pssr_type, self.params.get('second_physical_network'), None,
                None, self.params.get('vfnum'), self.params.get('mtu'))
            if not pssr_resource:
                raise exceptions.TestSetupError(
                    'Failed to find PSSR resource to test')
            self.pssr_nic = pssr_resource['nic']
            self.pssr_host = pssr_resource['host']

        elif self.pssr_nic != "" and self.pssr_host != "":

            if not self.compute_utils.setup_pssr(
                    pssr_type, self.params.get('second_physical_network'),
                    self.pssr_host, self.pssr_nic, self.params.get('vfnum'),
                    self.params.get('mtu')):
                raise exceptions.TestSetupError('Failed to setup PSSR')

        pssr_az = self.compute_utils.get_host_from('host_name',
                                                   self.pssr_host).zone
        normal_az = None

        hosts = self.compute_utils.get_host_from()
        for host in hosts:
            if host.service in 'compute':
                if self.pssr_host not in host.host_name:
                    normal_az = host.zone

        if not normal_az:
            raise exceptions.TestError('Did not find a second host')

        self.log.info('Test creating VM with %s nic' % pssr_type)

        def __check_vm_responsive(vm_ip,
                                  username='******',
                                  password=None,
                                  timeout=360):
            cmd = self.params.get('test_vm_responsive_cmd', 'whoami')
            use_key = password is None
            end_time = time.time() + timeout
            responsive = False
            while time.time() < end_time:
                if responsive:
                    return True
                try:
                    session = remote.RemoteRunner(host=vm_ip,
                                                  username=username,
                                                  password=password,
                                                  use_key=use_key,
                                                  timeout=20)
                    if not session:
                        continue
                    result = session.run(cmd)
                    if 'root' in result.stdout:
                        responsive = True
                except Exception, e:
                    self.log.error('Failed to login vm: %s' % e)
                    continue
            return responsive

        # Create SR-IOV provider network on specified physical network
        physical_net = self.params.get('second_physical_network')
        if not physical_net:
            raise exceptions.TestError('Please specify physical network name')

        suffix = data_factory.generate_random_string(6)

        # Create provider network based on the physical network
        self.pssr_net_name = 'pssr_net_' + suffix
        self.pssr_subnet = self.pssr_net_name + '_subnet'
        segmentation_id = self.params.get('provider_net_segmentation_id', 0)
        provider_net_type = self.params.get('provider_network_type', 'vlan')

        self.pssr_net = self.network_utils.create_network(
            name=self.pssr_net_name,
            subnet=True,
            start_cidr='192.168.%s.0/24' % segmentation_id,
            provider_network_type=provider_net_type,
            provider_segmentation_id=segmentation_id,
            provider_physical_network=physical_net)

        # Create a router and connect it to the pssr_net
        self.router_name = 'cloudtest_router_' + suffix
        self.network_utils.create_router(self.router_name,
                                         external_gw=True,
                                         subnet_name=self.pssr_subnet)
        self.network_utils.add_interface_router(self.pssr_net_name,
                                                self.router_name)

        floating_ips = []
        login_benchmark = int(self.params.get('login_benchmark', 360))

        vm_count = 2
        if pssr_type == 'pci-passthrough':
            vm_count = len(self.pssr_nic)

        # Use customization script to workaround a product bug that VM did
        # not get a private IP from dhcp server at start up
        userdata = self.params.get('create_vm_post_script')
        if userdata:
            self.log.info('Customization script after create vm: %s' %
                          userdata)

        for i in range(vm_count):
            _suffix = suffix + '_%d' % i

            self.log.info('Try to create #%d VM...' % (i + 1))

            # Create a vNic using Virtual Functions
            nic_name = 'pssr_nic_' + _suffix
            nic = self.network_utils.create_port(
                nic_name,
                network_id=self.pssr_net['network']['id'],
                binding_vnic_type='direct')
            self.log.info('Created %s nic: \n%s' % (pssr_type, nic))
            self.created_pssr_nics.append(nic)
            vm_name = 'cloudtest_pssr_' + _suffix
            vm = self.compute_utils.create_vm(
                vm_name=vm_name,
                image_name=self.params.get('image_name'),
                flavor_name=self.params.get('flavor_name'),
                injected_key=self.pub_key,
                availability_zone=pssr_az,
                nics=[nic],
                userdata=userdata)

            self.register_cleanup(vm)
            if not self.compute_utils.wait_for_vm_active(
                    vm=vm,
                    timeout=login_benchmark,
                    delete_on_failure=self.params.get('delete_vm_on_error',
                                                      'yes') == 'yes'):
                raise exceptions.TestFail(
                    'Failed to create vm: %s; status: %s' %
                    (vm.name, vm.status))

            vm_ip = self.compute_utils.assign_floating_ip_to_vm(vm)
            floating_ips.append(vm_ip)
            self.log.info("Created VM '%s', try to login via %s" %
                          (vm.name, vm_ip))

            if __check_vm_responsive(vm_ip,
                                     password=self.image_password,
                                     timeout=login_benchmark):
                self.log.info('Successfully created VM: %s' % vm.name)
                self.test_vms_names.append(vm_name)
                self.vm_list.append(vm)
            else:
                self.compute_utils.capture_vm_console_log(vm)
                raise exceptions.TestFail('VM is not responsive: %s' % vm_ip)

        # Create 2 VMs with virtio nic
        for i in range(2):
            _suffix = suffix + '_%d' % i

            vm_name = 'cloudtest_virtio_' + _suffix
            vm = self.compute_utils.create_vm(
                vm_name=vm_name,
                network_name=self.pssr_net_name,
                image_name=self.params.get('image_name'),
                injected_key=self.pub_key,
                flavor_name=self.params.get('flavor_name'),
                availability_zone=normal_az)

            if not self.compute_utils.wait_for_vm_active(
                    vm=vm,
                    timeout=login_benchmark,
                    delete_on_failure=self.params.get('delete_vm_on_error',
                                                      'yes') == 'yes'):
                raise exceptions.TestFail(
                    'Failed to create vm: %s; status: %s' %
                    (vm.name, vm.status))
            self.vm_list.append(vm)
            self.test_vms_names.append(vm_name)

        # Try to ping from vm1 to vm2, vm3, vm4
        results = []
        vm1_session = remote.RemoteRunner(host=floating_ips[0],
                                          username=self.image_username,
                                          password=self.image_password)
        for vm_name in self.test_vms_names:
            vm = self.compute_utils.find_vm_from_name(vm_name)
            if not vm.addresses:
                raise exceptions.TestFail("VM '%s' has no valid IP address" %
                                          vm_name)

            pri_ip = vm.addresses[self.pssr_net_name][0]['addr']
            self.log.info('Try to ping vm: %s' % pri_ip)
            result = vm1_session.run('ping -c 10 %s' % pri_ip,
                                     ignore_status=False)
            res = (result.exit_status == 0) and ('10 received'
                                                 in result.stdout)
            self.log.info("Result of ping vm '%s': %s" % (pri_ip, res))
            self.log.info('STDOUT: %s' % result.stdout)
            results.append(res)
        if not any(results):
            raise exceptions.TestFail('Ping all VMs failed')
        self.log.info('Ping all VMs successfully')