#!/usr/bin/env python3
#
# Basic validation of x86 versioned CPU models and CPU model aliases
#
#  Copyright (c) 2019 Red Hat Inc
#
# Author:
#  Eduardo Habkost <ehabkost@redhat.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2.1 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this library; if not, see <http://www.gnu.org/licenses/>.
#

import re

from qemu_test import QemuSystemTest

class X86CPUModelAliases(QemuSystemTest):
    """
    Validation of PC CPU model versions and CPU model aliases
    """
    def validate_aliases(self, cpus):
        for c in cpus.values():
            if 'alias-of' in c:
                # all aliases must point to a valid CPU model name:
                self.assertIn(c['alias-of'], cpus,
                              '%s.alias-of (%s) is not a valid CPU model name' % (c['name'], c['alias-of']))
                # aliases must not point to aliases
                self.assertNotIn('alias-of', cpus[c['alias-of']],
                                 '%s.alias-of (%s) points to another alias' % (c['name'], c['alias-of']))

                # aliases must not be static
                self.assertFalse(c['static'])

    def validate_variant_aliases(self, cpus):
        # -noTSX, -IBRS and -IBPB variants of CPU models are special:
        # they shouldn't have their own versions:
        self.assertNotIn("Haswell-noTSX-v1", cpus,
                         "Haswell-noTSX shouldn't be versioned")
        self.assertNotIn("Broadwell-noTSX-v1", cpus,
                         "Broadwell-noTSX shouldn't be versioned")
        self.assertNotIn("Nehalem-IBRS-v1", cpus,
                         "Nehalem-IBRS shouldn't be versioned")
        self.assertNotIn("Westmere-IBRS-v1", cpus,
                         "Westmere-IBRS shouldn't be versioned")
        self.assertNotIn("SandyBridge-IBRS-v1", cpus,
                         "SandyBridge-IBRS shouldn't be versioned")
        self.assertNotIn("IvyBridge-IBRS-v1", cpus,
                         "IvyBridge-IBRS shouldn't be versioned")
        self.assertNotIn("Haswell-noTSX-IBRS-v1", cpus,
                         "Haswell-noTSX-IBRS shouldn't be versioned")
        self.assertNotIn("Haswell-IBRS-v1", cpus,
                         "Haswell-IBRS shouldn't be versioned")
        self.assertNotIn("Broadwell-noTSX-IBRS-v1", cpus,
                         "Broadwell-noTSX-IBRS shouldn't be versioned")
        self.assertNotIn("Broadwell-IBRS-v1", cpus,
                         "Broadwell-IBRS shouldn't be versioned")
        self.assertNotIn("Skylake-Client-IBRS-v1", cpus,
                         "Skylake-Client-IBRS shouldn't be versioned")
        self.assertNotIn("Skylake-Server-IBRS-v1", cpus,
                         "Skylake-Server-IBRS shouldn't be versioned")
        self.assertNotIn("EPYC-IBPB-v1", cpus,
                         "EPYC-IBPB shouldn't be versioned")

    def test_4_0_alias_compatibility(self):
        """
        Check if pc-*-4.0 unversioned CPU model won't be reported as aliases
        """
        self.set_machine('pc-i440fx-4.0')
        # pc-*-4.0 won't expose non-versioned CPU models as aliases
        # We do this to help management software to keep compatibility
        # with older QEMU versions that didn't have the versioned CPU model
        self.vm.add_args('-S')
        self.vm.launch()
        cpus = dict((m['name'], m) for m in
                    self.vm.cmd('query-cpu-definitions'))

        self.assertFalse(cpus['Cascadelake-Server']['static'],
                         'unversioned Cascadelake-Server CPU model must not be static')
        self.assertNotIn('alias-of', cpus['Cascadelake-Server'],
                         'Cascadelake-Server must not be an alias')
        self.assertNotIn('alias-of', cpus['Cascadelake-Server-v1'],
                         'Cascadelake-Server-v1 must not be an alias')

        self.assertFalse(cpus['qemu64']['static'],
                         'unversioned qemu64 CPU model must not be static')
        self.assertNotIn('alias-of', cpus['qemu64'],
                         'qemu64 must not be an alias')
        self.assertNotIn('alias-of', cpus['qemu64-v1'],
                         'qemu64-v1 must not be an alias')

        self.validate_variant_aliases(cpus)

        # On pc-*-4.0, no CPU model should be reported as an alias:
        for name,c in cpus.items():
            self.assertNotIn('alias-of', c, "%s shouldn't be an alias" % (name))

    def test_4_1_alias(self):
        """
        Check if unversioned CPU model is an alias pointing to right version
        """
        self.set_machine('pc-i440fx-4.1')
        self.vm.add_args('-S')
        self.vm.launch()

        cpus = dict((m['name'], m) for m in
                    self.vm.cmd('query-cpu-definitions'))

        self.assertFalse(cpus['Cascadelake-Server']['static'],
                         'unversioned Cascadelake-Server CPU model must not be static')
        self.assertEqual(cpus['Cascadelake-Server'].get('alias-of'),
                         'Cascadelake-Server-v1',
                         'Cascadelake-Server must be an alias of Cascadelake-Server-v1')
        self.assertNotIn('alias-of', cpus['Cascadelake-Server-v1'],
                         'Cascadelake-Server-v1 must not be an alias')

        self.assertFalse(cpus['qemu64']['static'],
                         'unversioned qemu64 CPU model must not be static')
        self.assertEqual(cpus['qemu64'].get('alias-of'), 'qemu64-v1',
                         'qemu64 must be an alias of qemu64-v1')
        self.assertNotIn('alias-of', cpus['qemu64-v1'],
                         'qemu64-v1 must not be an alias')

        self.validate_variant_aliases(cpus)

        # On pc-*-4.1, -noTSX and -IBRS models should be aliases:
        self.assertEqual(cpus["Haswell"].get('alias-of'),
                         "Haswell-v1",
                         "Haswell must be an alias")
        self.assertEqual(cpus["Haswell-noTSX"].get('alias-of'),
                         "Haswell-v2",
                         "Haswell-noTSX must be an alias")
        self.assertEqual(cpus["Haswell-IBRS"].get('alias-of'),
                         "Haswell-v3",
                         "Haswell-IBRS must be an alias")
        self.assertEqual(cpus["Haswell-noTSX-IBRS"].get('alias-of'),
                         "Haswell-v4",
                         "Haswell-noTSX-IBRS must be an alias")

        self.assertEqual(cpus["Broadwell"].get('alias-of'),
                         "Broadwell-v1",
                         "Broadwell must be an alias")
        self.assertEqual(cpus["Broadwell-noTSX"].get('alias-of'),
                         "Broadwell-v2",
                         "Broadwell-noTSX must be an alias")
        self.assertEqual(cpus["Broadwell-IBRS"].get('alias-of'),
                         "Broadwell-v3",
                         "Broadwell-IBRS must be an alias")
        self.assertEqual(cpus["Broadwell-noTSX-IBRS"].get('alias-of'),
                         "Broadwell-v4",
                         "Broadwell-noTSX-IBRS must be an alias")

        self.assertEqual(cpus["Nehalem"].get('alias-of'),
                         "Nehalem-v1",
                         "Nehalem must be an alias")
        self.assertEqual(cpus["Nehalem-IBRS"].get('alias-of'),
                         "Nehalem-v2",
                         "Nehalem-IBRS must be an alias")

        self.assertEqual(cpus["Westmere"].get('alias-of'),
                         "Westmere-v1",
                         "Westmere must be an alias")
        self.assertEqual(cpus["Westmere-IBRS"].get('alias-of'),
                         "Westmere-v2",
                         "Westmere-IBRS must be an alias")

        self.assertEqual(cpus["SandyBridge"].get('alias-of'),
                         "SandyBridge-v1",
                         "SandyBridge must be an alias")
        self.assertEqual(cpus["SandyBridge-IBRS"].get('alias-of'),
                         "SandyBridge-v2",
                         "SandyBridge-IBRS must be an alias")

        self.assertEqual(cpus["IvyBridge"].get('alias-of'),
                         "IvyBridge-v1",
                         "IvyBridge must be an alias")
        self.assertEqual(cpus["IvyBridge-IBRS"].get('alias-of'),
                         "IvyBridge-v2",
                         "IvyBridge-IBRS must be an alias")

        self.assertEqual(cpus["Skylake-Client"].get('alias-of'),
                         "Skylake-Client-v1",
                         "Skylake-Client must be an alias")
        self.assertEqual(cpus["Skylake-Client-IBRS"].get('alias-of'),
                         "Skylake-Client-v2",
                         "Skylake-Client-IBRS must be an alias")

        self.assertEqual(cpus["Skylake-Server"].get('alias-of'),
                         "Skylake-Server-v1",
                         "Skylake-Server must be an alias")
        self.assertEqual(cpus["Skylake-Server-IBRS"].get('alias-of'),
                         "Skylake-Server-v2",
                         "Skylake-Server-IBRS must be an alias")

        self.assertEqual(cpus["EPYC"].get('alias-of'),
                         "EPYC-v1",
                         "EPYC must be an alias")
        self.assertEqual(cpus["EPYC-IBPB"].get('alias-of'),
                         "EPYC-v2",
                         "EPYC-IBPB must be an alias")

        self.validate_aliases(cpus)

    def test_none_alias(self):
        """
        Check if unversioned CPU model is an alias pointing to some version
        """
        self.set_machine('none')
        self.vm.add_args('-S')
        self.vm.launch()

        cpus = dict((m['name'], m) for m in
                    self.vm.cmd('query-cpu-definitions'))

        self.assertFalse(cpus['Cascadelake-Server']['static'],
                         'unversioned Cascadelake-Server CPU model must not be static')
        self.assertTrue(re.match('Cascadelake-Server-v[0-9]+', cpus['Cascadelake-Server']['alias-of']),
                        'Cascadelake-Server must be an alias of versioned CPU model')
        self.assertNotIn('alias-of', cpus['Cascadelake-Server-v1'],
                         'Cascadelake-Server-v1 must not be an alias')

        self.assertFalse(cpus['qemu64']['static'],
                         'unversioned qemu64 CPU model must not be static')
        self.assertTrue(re.match('qemu64-v[0-9]+', cpus['qemu64']['alias-of']),
                        'qemu64 must be an alias of versioned CPU model')
        self.assertNotIn('alias-of', cpus['qemu64-v1'],
                         'qemu64-v1 must not be an alias')

        self.validate_aliases(cpus)


class CascadelakeArchCapabilities(QemuSystemTest):
    """
    Validation of Cascadelake arch-capabilities
    """
    def get_cpu_prop(self, prop):
        cpu_path = self.vm.cmd('query-cpus-fast')[0].get('qom-path')
        return self.vm.cmd('qom-get', path=cpu_path, property=prop)

    def test_4_1(self):
        self.set_machine('pc-i440fx-4.1')
        # machine-type only:
        self.vm.add_args('-S')
        self.set_vm_arg('-cpu',
                        'Cascadelake-Server,x-force-features=on,check=off,'
                        'enforce=off')
        self.vm.launch()
        self.assertFalse(self.get_cpu_prop('arch-capabilities'),
                         'pc-i440fx-4.1 + Cascadelake-Server should not have arch-capabilities')

    def test_4_0(self):
        self.set_machine('pc-i440fx-4.0')
        self.vm.add_args('-S')
        self.set_vm_arg('-cpu',
                        'Cascadelake-Server,x-force-features=on,check=off,'
                        'enforce=off')
        self.vm.launch()
        self.assertFalse(self.get_cpu_prop('arch-capabilities'),
                         'pc-i440fx-4.0 + Cascadelake-Server should not have arch-capabilities')

    def test_set_4_0(self):
        self.set_machine('pc-i440fx-4.0')
        # command line must override machine-type if CPU model is not versioned:
        self.vm.add_args('-S')
        self.set_vm_arg('-cpu',
                        'Cascadelake-Server,x-force-features=on,check=off,'
                        'enforce=off,+arch-capabilities')
        self.vm.launch()
        self.assertTrue(self.get_cpu_prop('arch-capabilities'),
                        'pc-i440fx-4.0 + Cascadelake-Server,+arch-capabilities should have arch-capabilities')

    def test_unset_4_1(self):
        self.set_machine('pc-i440fx-4.1')
        self.vm.add_args('-S')
        self.set_vm_arg('-cpu',
                        'Cascadelake-Server,x-force-features=on,check=off,'
                        'enforce=off,-arch-capabilities')
        self.vm.launch()
        self.assertFalse(self.get_cpu_prop('arch-capabilities'),
                         'pc-i440fx-4.1 + Cascadelake-Server,-arch-capabilities should not have arch-capabilities')

    def test_v1_4_0(self):
        self.set_machine('pc-i440fx-4.0')
        # versioned CPU model overrides machine-type:
        self.vm.add_args('-S')
        self.set_vm_arg('-cpu',
                        'Cascadelake-Server-v1,x-force-features=on,check=off,'
                        'enforce=off')
        self.vm.launch()
        self.assertFalse(self.get_cpu_prop('arch-capabilities'),
                         'pc-i440fx-4.0 + Cascadelake-Server-v1 should not have arch-capabilities')

    def test_v2_4_0(self):
        self.set_machine('pc-i440fx-4.0')
        self.vm.add_args('-S')
        self.set_vm_arg('-cpu',
                        'Cascadelake-Server-v2,x-force-features=on,check=off,'
                        'enforce=off')
        self.vm.launch()
        self.assertTrue(self.get_cpu_prop('arch-capabilities'),
                        'pc-i440fx-4.0 + Cascadelake-Server-v2 should have arch-capabilities')

    def test_v1_set_4_0(self):
        self.set_machine('pc-i440fx-4.0')
        # command line must override machine-type and versioned CPU model:
        self.vm.add_args('-S')
        self.set_vm_arg('-cpu',
                        'Cascadelake-Server-v1,x-force-features=on,check=off,'
                        'enforce=off,+arch-capabilities')
        self.vm.launch()
        self.assertTrue(self.get_cpu_prop('arch-capabilities'),
                        'pc-i440fx-4.0 + Cascadelake-Server-v1,+arch-capabilities should have arch-capabilities')

    def test_v2_unset_4_1(self):
        self.set_machine('pc-i440fx-4.1')
        self.vm.add_args('-S')
        self.set_vm_arg('-cpu',
                        'Cascadelake-Server-v2,x-force-features=on,check=off,'
                        'enforce=off,-arch-capabilities')
        self.vm.launch()
        self.assertFalse(self.get_cpu_prop('arch-capabilities'),
                         'pc-i440fx-4.1 + Cascadelake-Server-v2,-arch-capabilities should not have arch-capabilities')

if __name__ == '__main__':
    QemuSystemTest.main()
