# Copyright 2015 NEC Corporation.  All rights reserved.
#
#    Licensed under the Apache License, Version 2.0 (the "License"); you may
#    not use this file except in compliance with the License. You may obtain
#    a copy of the License at
#
#         http://www.apache.org/licenses/LICENSE-2.0
#
#    Unless required by applicable law or agreed to in writing, software
#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
#    License for the specific language governing permissions and limitations
#    under the License.

from oslo_config import cfg
import testtools

from tempest.api.compute import base as compute_base
from tempest import config
from tempest import exceptions
from tempest.tests import base
from tempest.tests import fake_config


class VersionTestNoneTolatest(compute_base.BaseV2ComputeTest):
    min_microversion = None
    max_microversion = 'latest'


class VersionTestNoneTo2_2(compute_base.BaseV2ComputeTest):
    min_microversion = None
    max_microversion = '2.2'


class VersionTest2_3ToLatest(compute_base.BaseV2ComputeTest):
    min_microversion = '2.3'
    max_microversion = 'latest'


class VersionTest2_5To2_10(compute_base.BaseV2ComputeTest):
    min_microversion = '2.5'
    max_microversion = '2.10'


class VersionTest2_10To2_10(compute_base.BaseV2ComputeTest):
    min_microversion = '2.10'
    max_microversion = '2.10'


class InvalidVersionTest(compute_base.BaseV2ComputeTest):
    min_microversion = '2.11'
    max_microversion = '2.1'


class TestMicroversionsTestsClass(base.TestCase):

    def setUp(self):
        super(TestMicroversionsTestsClass, self).setUp()
        self.useFixture(fake_config.ConfigFixture())
        self.stubs.Set(config, 'TempestConfigPrivate',
                       fake_config.FakePrivate)

    def _test_version(self, cfg_min, cfg_max,
                      expected_pass_tests,
                      expected_skip_tests):
        cfg.CONF.set_default('min_microversion',
                             cfg_min, group='compute-feature-enabled')
        cfg.CONF.set_default('max_microversion',
                             cfg_max, group='compute-feature-enabled')
        try:
            for test_class in expected_pass_tests:
                test_class.skip_checks()
            for test_class in expected_skip_tests:
                self.assertRaises(testtools.TestCase.skipException,
                                  test_class.skip_checks)
        except testtools.TestCase.skipException as e:
            raise testtools.TestCase.failureException(e.message)

    def test_config_version_none_none(self):
        expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2]
        expected_skip_tests = [VersionTest2_3ToLatest, VersionTest2_5To2_10,
                               VersionTest2_10To2_10]
        self._test_version(None, None,
                           expected_pass_tests,
                           expected_skip_tests)

    def test_config_version_none_23(self):
        expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
                               VersionTest2_3ToLatest]
        expected_skip_tests = [VersionTest2_5To2_10, VersionTest2_10To2_10]
        self._test_version(None, '2.3',
                           expected_pass_tests,
                           expected_skip_tests)

    def test_config_version_22_latest(self):
        expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
                               VersionTest2_3ToLatest, VersionTest2_5To2_10,
                               VersionTest2_10To2_10]
        expected_skip_tests = []
        self._test_version('2.2', 'latest',
                           expected_pass_tests,
                           expected_skip_tests)

    def test_config_version_22_23(self):
        expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
                               VersionTest2_3ToLatest]
        expected_skip_tests = [VersionTest2_5To2_10, VersionTest2_10To2_10]
        self._test_version('2.2', '2.3',
                           expected_pass_tests,
                           expected_skip_tests)

    def test_config_version_210_210(self):
        expected_pass_tests = [VersionTestNoneTolatest,
                               VersionTest2_3ToLatest,
                               VersionTest2_5To2_10,
                               VersionTest2_10To2_10]
        expected_skip_tests = [VersionTestNoneTo2_2]
        self._test_version('2.10', '2.10',
                           expected_pass_tests,
                           expected_skip_tests)

    def test_config_version_none_latest(self):
        expected_pass_tests = [VersionTestNoneTolatest, VersionTestNoneTo2_2,
                               VersionTest2_3ToLatest, VersionTest2_5To2_10,
                               VersionTest2_10To2_10]
        expected_skip_tests = []
        self._test_version(None, 'latest',
                           expected_pass_tests,
                           expected_skip_tests)

    def test_config_version_latest_latest(self):
        expected_pass_tests = [VersionTestNoneTolatest, VersionTest2_3ToLatest]
        expected_skip_tests = [VersionTestNoneTo2_2, VersionTest2_5To2_10,
                               VersionTest2_10To2_10]
        self._test_version('latest', 'latest',
                           expected_pass_tests,
                           expected_skip_tests)

    def test_config_invalid_version(self):
        cfg.CONF.set_default('min_microversion',
                             '2.5', group='compute-feature-enabled')
        cfg.CONF.set_default('max_microversion',
                             '2.1', group='compute-feature-enabled')
        self.assertRaises(exceptions.InvalidAPIVersionRange,
                          VersionTestNoneTolatest.skip_checks)

    def test_config_version_invalid_test_version(self):
        cfg.CONF.set_default('min_microversion',
                             None, group='compute-feature-enabled')
        cfg.CONF.set_default('max_microversion',
                             '2.13', group='compute-feature-enabled')
        self.assertRaises(exceptions.InvalidAPIVersionRange,
                          InvalidVersionTest.skip_checks)
