eaf26c7c68
The get_not_version method was put in, but never used, the underlying upgrade check code just explicitly passes the appropriate query arguments and doesn't use the helper. Why now? Because it used model_query. Change-Id: I697f13486c2e11cd04b4f381f3066eeb154ea2a3
239 lines
10 KiB
Python
239 lines
10 KiB
Python
# 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.
|
|
|
|
import random
|
|
from unittest import mock
|
|
|
|
from oslo_db.sqlalchemy import utils as db_utils
|
|
from oslo_utils import uuidutils
|
|
import sqlalchemy as sa
|
|
|
|
from ironic.common import context
|
|
from ironic.common import exception
|
|
from ironic.common import release_mappings
|
|
from ironic.db import api as db_api
|
|
from ironic.tests.unit.db import base
|
|
from ironic.tests.unit.db import utils
|
|
|
|
|
|
class UpgradingTestCase(base.DbTestCase):
|
|
|
|
def setUp(self):
|
|
super(UpgradingTestCase, self).setUp()
|
|
self.dbapi = db_api.get_instance()
|
|
self.object_versions = release_mappings.get_object_versions()
|
|
|
|
def test_check_versions_emptyDB(self):
|
|
# nothing in the DB
|
|
self.assertTrue(self.dbapi.check_versions())
|
|
|
|
@mock.patch.object(db_utils, 'column_exists', autospec=True)
|
|
def test_check_versions_missing_version_columns(self, column_exists):
|
|
column_exists.return_value = False
|
|
self.assertRaises(exception.DatabaseVersionTooOld,
|
|
self.dbapi.check_versions)
|
|
|
|
@mock.patch.object(release_mappings, 'get_object_versions', autospec=True)
|
|
@mock.patch.object(db_utils, 'column_exists', autospec=True)
|
|
def test_check_versions_handles_missing_table(
|
|
self, column_exists, mock_release_mappings):
|
|
column_exists.side_effect = sa.exc.NoSuchTableError('meow')
|
|
mock_release_mappings.return_value = {'Node': {'1.0'}}
|
|
self.assertTrue(
|
|
self.dbapi.check_versions(permit_initial_version=True))
|
|
self.assertEqual(1, column_exists.call_count)
|
|
|
|
@mock.patch.object(release_mappings, 'get_object_versions', autospec=True)
|
|
@mock.patch.object(db_utils, 'column_exists', autospec=True)
|
|
def test_check_versions_raises_missing_table(
|
|
self, column_exists, mock_release_mappings):
|
|
column_exists.side_effect = sa.exc.NoSuchTableError('meow')
|
|
mock_release_mappings.return_value = {'Node': {'1.0', '1.1'}}
|
|
self.assertRaises(sa.exc.NoSuchTableError, self.dbapi.check_versions)
|
|
self.assertEqual(1, column_exists.call_count)
|
|
|
|
def test_check_versions(self):
|
|
for v in self.object_versions['Node']:
|
|
node = utils.create_test_node(uuid=uuidutils.generate_uuid(),
|
|
version=v)
|
|
node = self.dbapi.get_node_by_id(node.id)
|
|
self.assertEqual(v, node.version)
|
|
self.assertTrue(self.dbapi.check_versions())
|
|
|
|
def test_check_versions_node_no_version(self):
|
|
node = utils.create_test_node(version=None)
|
|
node = self.dbapi.get_node_by_id(node.id)
|
|
self.assertIsNone(node.version)
|
|
self.assertFalse(self.dbapi.check_versions())
|
|
|
|
def test_check_versions_ignore_node(self):
|
|
node = utils.create_test_node(version=None)
|
|
node = self.dbapi.get_node_by_id(node.id)
|
|
self.assertIsNone(node.version)
|
|
self.assertTrue(self.dbapi.check_versions(ignore_models=['Node']))
|
|
|
|
def test_check_versions_node_old(self):
|
|
node = utils.create_test_node(version='1.0')
|
|
node = self.dbapi.get_node_by_id(node.id)
|
|
self.assertEqual('1.0', node.version)
|
|
self.assertFalse(self.dbapi.check_versions())
|
|
|
|
def test_check_versions_conductor(self):
|
|
for v in self.object_versions['Conductor']:
|
|
# NOTE(jroll) conductor model doesn't have a uuid :(
|
|
conductor = utils.create_test_conductor(
|
|
hostname=uuidutils.generate_uuid(), version=v,
|
|
id=random.randint(1, 1000000))
|
|
conductor = self.dbapi.get_conductor(conductor.hostname)
|
|
self.assertEqual(v, conductor.version)
|
|
self.assertTrue(self.dbapi.check_versions())
|
|
|
|
def test_check_versions_conductor_old(self):
|
|
conductor = utils.create_test_conductor(version='1.0')
|
|
conductor = self.dbapi.get_conductor(conductor.hostname)
|
|
self.assertEqual('1.0', conductor.version)
|
|
self.assertFalse(self.dbapi.check_versions())
|
|
|
|
|
|
class UpdateToLatestVersionsTestCase(base.DbTestCase):
|
|
|
|
def setUp(self):
|
|
super(UpdateToLatestVersionsTestCase, self).setUp()
|
|
self.context = context.get_admin_context()
|
|
self.dbapi = db_api.get_instance()
|
|
|
|
obj_versions = release_mappings.get_object_versions(
|
|
objects=['Node', 'Chassis'])
|
|
master_objs = release_mappings.RELEASE_MAPPING['master']['objects']
|
|
self.node_ver = master_objs['Node'][0]
|
|
self.chassis_ver = master_objs['Chassis'][0]
|
|
self.node_old_ver = self._get_old_object_version(
|
|
self.node_ver, obj_versions['Node'])
|
|
self.chassis_old_ver = self._get_old_object_version(
|
|
self.chassis_ver, obj_versions['Chassis'])
|
|
self.node_version_same = self.node_old_ver == self.node_ver
|
|
self.chassis_version_same = self.chassis_old_ver == self.chassis_ver
|
|
# number of objects with different versions
|
|
self.num_diff_objs = 2
|
|
if self.node_version_same:
|
|
self.num_diff_objs -= 1
|
|
if self.chassis_version_same:
|
|
self.num_diff_objs -= 1
|
|
|
|
def _get_old_object_version(self, latest_version, versions):
|
|
"""Return a version that is older (not same) as latest version.
|
|
|
|
If there aren't any older versions, return the latest version.
|
|
"""
|
|
for v in versions:
|
|
if v != latest_version:
|
|
return v
|
|
return latest_version
|
|
|
|
def test_empty_db(self):
|
|
self.assertEqual(
|
|
(0, 0), self.dbapi.update_to_latest_versions(self.context, 10))
|
|
|
|
def test_version_exists(self):
|
|
# Node will be in latest version
|
|
utils.create_test_node()
|
|
self.assertEqual(
|
|
(0, 0), self.dbapi.update_to_latest_versions(self.context, 10))
|
|
|
|
def test_one_node(self):
|
|
node = utils.create_test_node(version=self.node_old_ver)
|
|
expected = (0, 0) if self.node_version_same else (1, 1)
|
|
self.assertEqual(
|
|
expected, self.dbapi.update_to_latest_versions(self.context, 10))
|
|
res = self.dbapi.get_node_by_uuid(node.uuid)
|
|
self.assertEqual(self.node_ver, res.version)
|
|
|
|
def test_max_count_zero(self):
|
|
orig_node = utils.create_test_node(version=self.node_old_ver)
|
|
orig_chassis = utils.create_test_chassis(version=self.chassis_old_ver)
|
|
self.assertEqual((self.num_diff_objs, self.num_diff_objs),
|
|
self.dbapi.update_to_latest_versions(self.context, 0))
|
|
node = self.dbapi.get_node_by_uuid(orig_node.uuid)
|
|
self.assertEqual(self.node_ver, node.version)
|
|
chassis = self.dbapi.get_chassis_by_uuid(orig_chassis.uuid)
|
|
self.assertEqual(self.chassis_ver, chassis.version)
|
|
|
|
def test_old_version_max_count_1(self):
|
|
orig_node = utils.create_test_node(version=self.node_old_ver)
|
|
orig_chassis = utils.create_test_chassis(version=self.chassis_old_ver)
|
|
num_modified = 1 if self.num_diff_objs else 0
|
|
self.assertEqual((self.num_diff_objs, num_modified),
|
|
self.dbapi.update_to_latest_versions(self.context, 1))
|
|
node = self.dbapi.get_node_by_uuid(orig_node.uuid)
|
|
chassis = self.dbapi.get_chassis_by_uuid(orig_chassis.uuid)
|
|
self.assertTrue(node.version == self.node_old_ver
|
|
or chassis.version == self.chassis_old_ver)
|
|
self.assertTrue(node.version == self.node_ver
|
|
or chassis.version == self.chassis_ver)
|
|
|
|
def _create_nodes(self, num_nodes):
|
|
version = self.node_old_ver
|
|
nodes = []
|
|
for i in range(0, num_nodes):
|
|
node = utils.create_test_node(version=version,
|
|
uuid=uuidutils.generate_uuid())
|
|
# Create entries on the tables so we force field upgrades
|
|
utils.create_test_node_trait(node_id=node.id, trait='foo',
|
|
version='0.0')
|
|
utils.create_test_bios_setting(node_id=node.id, version='1.0')
|
|
|
|
nodes.append(node.uuid)
|
|
for uuid in nodes:
|
|
node = self.dbapi.get_node_by_uuid(uuid)
|
|
self.assertEqual(version, node.version)
|
|
return nodes
|
|
|
|
def test_old_version_max_count_2_some_nodes(self):
|
|
if self.node_version_same:
|
|
# can't test if we don't have diff versions of the node
|
|
return
|
|
|
|
nodes = self._create_nodes(5)
|
|
# Check/migrate 2, 10 remain.
|
|
self.assertEqual(
|
|
(10, 2), self.dbapi.update_to_latest_versions(self.context, 2))
|
|
# Check/migrate 10, 8 migrated, 8 remain.
|
|
self.assertEqual(
|
|
(8, 8), self.dbapi.update_to_latest_versions(self.context, 10))
|
|
# Just make sure it is still 0, 0 in case more things are added.
|
|
self.assertEqual(
|
|
(0, 0), self.dbapi.update_to_latest_versions(self.context, 10))
|
|
for uuid in nodes:
|
|
node = self.dbapi.get_node_by_uuid(uuid)
|
|
self.assertEqual(self.node_ver, node.version)
|
|
|
|
def test_old_version_max_count_same_nodes(self):
|
|
if self.node_version_same:
|
|
# can't test if we don't have diff versions of the node
|
|
return
|
|
vm_count = 5
|
|
nodes = self._create_nodes(vm_count)
|
|
# NOTE(TheJulia): Under current testing, 5 node will result in 10
|
|
# records implicitly needing to be migrated.
|
|
migrate_count = vm_count * 2
|
|
self.assertEqual(
|
|
(migrate_count, migrate_count),
|
|
self.dbapi.update_to_latest_versions(self.context,
|
|
migrate_count))
|
|
self.assertEqual(
|
|
(0, 0), self.dbapi.update_to_latest_versions(self.context,
|
|
migrate_count))
|
|
|
|
for uuid in nodes:
|
|
node = self.dbapi.get_node_by_uuid(uuid)
|
|
self.assertEqual(self.node_ver, node.version)
|