添加数据库版本,单元测试不通过,报DB Migration 348 does not have a test. Please add one!

来源:互联网 发布:hive sql create 编辑:程序博客网 时间:2024/05/18 08:43

tox -e py27时, 单元测试报错。

DB Migration 348 does not have a test. Please add one!

 

首先我是添加了一个db version为348的db版本,我本来想不添加单元测试,就不会影响到新添加的db version,结果尽然这个报了个db version单元测试的错。

还是想搞明白为什么会这样,毕竟我以前用ironic的时候,并没有这样的情况。

 

跟代码:

nova/tests/unit/db/test_migrations.py       test_walk_versions(self): 

oslo_db/sqlalchemy/test_migrations.py          walk_versions()

查看 walk_version()里代码

189             versions = range(int(self.INIT_VERSION) + 1,
190                              int(self.REPOSITORY.latest) + 1)              #version = [init_version, latest_version]
191    
192             for version in versions:                                       #遍历所有版本并执行 migrate_up,于是查看migrate_up代码
193                 # upgrade -> downgrade -> upgrade
194                 self.migrate_up(version, with_data=True)
195                 if snake_walk:
196                     downgraded = self.migrate_down(version - 1, with_data=True)
197                     if downgraded:
198                         self.migrate_up(version)
def _skippable_migrations(self):                     #这个是可跳过migrations的版本,大概就是之前稳定的版本的
    special = [                                      #比如现在是0版,所以可跳过的版本感觉大概都是0版之前版本,初始版本是大概h上一版。
        216,  # Havana
        272,  # NOOP migration due to revert
    ]
    havana_placeholders = list(range(217227))
    icehouse_placeholders = list(range(235244))
    juno_placeholders = list(range(255265))
    kilo_placeholders = list(range(281291))
    liberty_placeholders = list(range(303313))
    mitaka_placeholders = list(range(320330))
    newton_placeholders = list(range(335345))
    return (special +
            havana_placeholders +
            icehouse_placeholders +
            juno_placeholders +
            kilo_placeholders +
            liberty_placeholders +
            mitaka_placeholders +
            newton_placeholders)
 
def migrate_up(self, version, with_data=False):
    if with_data:
        check = getattr(self, "_check_%03d" % version, None)                         #这个大概是第一个version都会有一个_check_
        if version not in self._skippable_migrations():                              #如果没在可跳过的version里就会报错,可跳过的version是上面函数里有解释
            self.assertIsNotNone(check,                                              #我后面加的肯定没在可跳过的里面,所以肯定报错。
                                 ('DB Migration %i does not have a '
                                  'test. Please add one!') % version)
    # NOTE(danms): This is a list of migrations where we allow dropping
    # things. The rules for adding things here are very very specific.
    # Chances are you don't meet the critera.
    # Reviewers: DO NOT ALLOW THINGS TO BE ADDED HERE
    exceptions = [
        267 enforces non-nullable instance.uuid. This was mostly
        # a special case because instance.uuid shouldn't be able
        # to be nullable
        267,
        278 removes a FK restriction, so it's an alter operation
        # that doesn't break existing users
        278,
        280 enforces non-null keypair name. This is really not
        # something we should allow, but it's in the past
        280,
        292 drops completely orphaned tables with no users, so
        # it can be done without affecting anything.
        292,
        346 Drops column scheduled_at from instances table since it
        # is no longer used. The field value is always NULL so
        # it does not affect anything.
        346,
    ]
    # Reviewers: DO NOT ALLOW THINGS TO BE ADDED HERE
    # NOTE(danms): We only started requiring things be additive in
    # kilo, so ignore all migrations before that point.
    KILO_START = 265
    if version >= KILO_START and version not in exceptions:
        banned = ['Table''Column']
    else:
        banned = None
    with nova_fixtures.BannedDBSchemaOperations(banned):
        super(NovaMigrationsCheckers, self).migrate_up(version, with_data)

 

根据分析,于是在 nova/tests/unit/db/test_migrations.py 里加上单元测试代码。

def _check_347(self, engine, data):
    self.assertIndexMembers(engine, 'instances',
                            'instances_project_id_idx',
                            ['project_id'])
     
    self.assertIndexMembers(engine, 'instances',
                            'instances_updated_at_project_id_idx',
                            ['updated_at''project_id'])
def _check_348(self, engine, data):
    self.assertIndexMembers(engine, 'instances',
                            'instances_project_id_idx',
                            ['project_id'])
     
    self.assertIndexMembers(engine, 'instances',
                            'instances_updated_at_project_id_idx',
                            ['updated_at''project_id'])

 

 

可是还是报错,报如下错误:

nova.exception.DBNotAllowed: Operation Column.alter() is not allowed in a database migration

 

这就更恼火了,怎么竟然alter都不被允许了。于是细跟代码发现

if version >= KILO_START and version not in exceptions:     # 如果version不在 exceptions里 branned,banned = ['Table''Column']
    banned = ['Table''Column']
else:
    banned = None
with nova_fixtures.BannedDBSchemaOperations(banned):
    super(NovaMigrationsCheckers, self).migrate_up(version, with_data)
class BannedDBSchemaOperations(fixtures.Fixture):
    """Ban some operations for migrations"""
    def __init__(self, banned_resources=None):
        super(BannedDBSchemaOperations, self).__init__()
        self._banned_resources = banned_resources or []               #self._banned_resources 就是上面 with nova_fixtures.BannedDBSchemaOperations(banned): 传过来的
 
    @staticmethod
    def _explode(resource, op):
        raise exception.DBNotAllowed(
            'Operation %s.%s() is not allowed in a database migration' % (
                resource, op))
    def setUp(self):
        super(BannedDBSchemaOperations, self).setUp()
        for thing in self._banned_resources:                        #如果有self._banned_resources,就会把_banned_resources里的东西,以patch的方式重新定义一次,
            self.useFixture(fixtures.MonkeyPatch(                   #大概就是 sqlalcheymy.Table.drop = lambda *a, **k: self._explode(thing, 'drop')
                'sqlalchemy.%s.drop' % thing,                       #直接patch成一个异常了,大概知道原因了,把_banned_resources置为None就可以了
                lambda *a, **k: self._explode(thing, 'drop')))
            self.useFixture(fixtures.MonkeyPatch(
                'sqlalchemy.%s.alter' % thing,
                lambda *a, **k: self._explode(thing, 'alter')))

 

于是在  exceptions 里加入 348,解决这次单元测试问题。

阅读全文
0 0