Skip to content

Commit

Permalink
Trac #3014 Add a migrator that reverts db version 40
Browse files Browse the repository at this point in the history
 - This commit reintroduce db version 40, and the db/test code which used it
  • Loading branch information
Xavier Delannoy committed Nov 14, 2014
1 parent 05a15d6 commit 5c2cf49
Show file tree
Hide file tree
Showing 11 changed files with 158 additions and 46 deletions.
11 changes: 7 additions & 4 deletions master/buildbot/data/builders.py
Expand Up @@ -40,7 +40,8 @@ def get(self, resultSpec, kwargs):
defer.returnValue(
dict(builderid=builderid,
name=bdict['name'],
description=bdict['description']))
description=bdict['description'],
tags=bdict['tags']))


class BuildersEndpoint(base.Endpoint):
Expand All @@ -59,7 +60,8 @@ def get(self, resultSpec, kwargs):
defer.returnValue([
dict(builderid=bd['id'],
name=bd['name'],
description=bd['description'])
description=bd['description'],
tags=bd['tags'])
for bd in bdicts])

def startConsuming(self, callback, options, kwargs):
Expand All @@ -78,6 +80,7 @@ class EntityType(types.Entity):
builderid = types.Integer()
name = types.Identifier(20)
description = types.NoneOk(types.String())
tags = types.NoneOk(types.List(of=types.String()))
entityType = EntityType(name)

def __init__(self, master):
Expand All @@ -88,8 +91,8 @@ def findBuilderId(self, name):
return self.master.db.builders.findBuilderId(name)

@base.updateMethod
def updateBuilderDescription(self, builderid, description):
return self.master.db.builders.updateBuilderDescription(builderid, description)
def updateBuilderInfo(self, builderid, description, tags):
return self.master.db.builders.updateBuilderInfo(builderid, description, tags)

@base.updateMethod
@defer.inlineCallbacks
Expand Down
14 changes: 9 additions & 5 deletions master/buildbot/db/builders.py
Expand Up @@ -15,6 +15,8 @@

import sqlalchemy as sa

import json

from buildbot.db import base


Expand All @@ -30,12 +32,11 @@ def findBuilderId(self, name):
name_hash=self.hashColumns(name),
))

def updateBuilderDescription(self, builderid, description):
def updateBuilderInfo(self, builderid, description, tags):
def thd(conn):
tbl = self.db.model.builders

q = tbl.update(whereclause=(tbl.c.id == builderid))
conn.execute(q, description=description)
conn.execute(q, description=description, tags=json.dumps(tags if tags else []))
return self.db.pool.do(thd)

def getBuilder(self, builderid):
Expand Down Expand Up @@ -80,7 +81,8 @@ def thd(conn):
j = j.join(limiting_bm_tbl,
onclause=(bldr_tbl.c.id == limiting_bm_tbl.c.builderid))
q = sa.select(
[bldr_tbl.c.id, bldr_tbl.c.name, bldr_tbl.c.description, bm_tbl.c.masterid],
[bldr_tbl.c.id, bldr_tbl.c.name, bldr_tbl.c.description,
bldr_tbl.c.tags, bm_tbl.c.masterid],
from_obj=[j],
order_by=[bldr_tbl.c.id, bm_tbl.c.masterid])
if masterid is not None:
Expand All @@ -94,7 +96,9 @@ def thd(conn):
last = None
for row in conn.execute(q).fetchall():
if not last or row['id'] != last['id']:
last = dict(id=row.id, name=row.name, masterids=[], description=row.description)
last = dict(id=row.id, name=row.name, masterids=[],
description=row.description,
tags=json.loads(row.tags) if row.tags else [])
rv.append(last)
if row['masterid']:
last['masterids'].append(row['masterid'])
Expand Down
24 changes: 24 additions & 0 deletions master/buildbot/db/migrate/versions/040_add_builder_tags.py
@@ -0,0 +1,24 @@
# This file is part of Buildbot. Buildbot is free software: you can
# redistribute it and/or modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation, version 2.
#
# This program 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 General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Copyright Buildbot Team Members

import sqlalchemy as sa


def upgrade(migrate_engine):
metadata = sa.MetaData()
metadata.bind = migrate_engine
builders_table = sa.Table('builders', metadata, autoload=True)
tags = sa.Column('tags', sa.Text, nullable=True)
tags.create(builders_table)
2 changes: 2 additions & 0 deletions master/buildbot/db/model.py
Expand Up @@ -447,6 +447,8 @@ class Model(base.DBConnectorComponent):
sa.Column('name', sa.Text, nullable=False),
# builder's description
sa.Column('description', sa.Text, nullable=True),
# builder's tags
sa.Column('tags', sa.Text, nullable=True),
# sha1 of name; used for a unique index
sa.Column('name_hash', sa.String(40), nullable=False),
)
Expand Down
4 changes: 3 additions & 1 deletion master/buildbot/process/builder.py
Expand Up @@ -113,7 +113,9 @@ def reconfigService(self, new_config):
# build.
builderid = yield self.getBuilderId()

self.master.data.updates.updateBuilderDescription(builderid, builder_config.description)
self.master.data.updates.updateBuilderInfo(builderid,
builder_config.description,
builder_config.tags)

self.builder_status.setDescription(builder_config.description)
self.builder_status.setTags(builder_config.tags)
Expand Down
4 changes: 2 additions & 2 deletions master/buildbot/test/fake/fakedata.py
Expand Up @@ -210,8 +210,8 @@ def updateBuilderList(self, masterid, builderNames):
self.builderNames = builderNames
return defer.succeed(None)

def updateBuilderDescription(self, builderid, description):
yield self.master.db.builders.updateBuilderDescription(builderid, description)
def updateBuilderInfo(self, builderid, description, tags):
yield self.master.db.builders.updateBuilderInfo(builderid, description, tags)

def masterDeactivated(self, masterid):
return defer.succeed(None)
Expand Down
10 changes: 7 additions & 3 deletions master/buildbot/test/fake/fakedb.py
Expand Up @@ -533,6 +533,7 @@ class Builder(Row):
name='some:builder',
name_hash=None,
description=None,
tags=None,
)

id_column = 'id'
Expand Down Expand Up @@ -2135,7 +2136,8 @@ def insertTestData(self, rows):
self.builders[row.id] = dict(
id=row.id,
name=row.name,
description=row.description)
description=row.description,
tags=row.tags if row.tags else [])
if isinstance(row, BuilderMaster):
self.builder_masters[row.id] = \
(row.builderid, row.masterid)
Expand All @@ -2148,7 +2150,8 @@ def findBuilderId(self, name, _reactor=reactor):
self.builders[id] = dict(
id=id,
name=name,
description=None)
description=None,
tags=[])
return defer.succeed(id)

def addBuilderMaster(self, builderid=None, masterid=None):
Expand Down Expand Up @@ -2194,9 +2197,10 @@ def addTestBuilder(self, builderid, name=None):
Builder(id=builderid, name=name),
])

def updateBuilderDescription(self, builderid, description):
def updateBuilderInfo(self, builderid, description, tags):
if builderid in self.builders:
self.builders[builderid]['description'] = description
self.builders[builderid]['tags'] = tags if tags else []


class FakeDBConnector(object):
Expand Down
20 changes: 10 additions & 10 deletions master/buildbot/test/unit/test_data_builders.py
Expand Up @@ -159,9 +159,9 @@ def test_findBuilderId(self):
self.master.db.builders.findBuilderId = mock.Mock(return_value=rv)
self.assertIdentical(self.rtype.findBuilderId('foo'), rv)

def test_signature_updateBuilderDescription(self):
@self.assertArgSpecMatches(self.master.data.updates.updateBuilderDescription)
def updateBuilderDescription(self, builderid, description):
def test_signature_updateBuilderInfo(self):
@self.assertArgSpecMatches(self.master.data.updates.updateBuilderInfo)
def updateBuilderInfo(self, builderid, description, tags):
pass

def test_signature_updateBuilderList(self):
Expand All @@ -178,7 +178,7 @@ def test_updateBuilderList(self):
self.assertEqual(sorted((yield self.master.db.builders.getBuilders())),
sorted([
dict(id=1, masterids=[13],
name='somebuilder', description=None),
name='somebuilder', description=None, tags=[]),
]))
self.master.mq.assertProductions([(('builders', '1', 'started'),
{'builderid': 1, 'masterid': 13, 'name': u'somebuilder'})])
Expand All @@ -188,9 +188,9 @@ def test_updateBuilderList(self):
self.assertEqual(sorted((yield self.master.db.builders.getBuilders())),
sorted([
dict(id=1, masterids=[13],
name='somebuilder', description=None),
name='somebuilder', description=None, tags=[]),
dict(id=2, masterids=[13],
name='another', description=None),
name='another', description=None, tags=[]),
]))
self.master.mq.assertProductions([(('builders', '2', 'started'),
{'builderid': 2, 'masterid': 13, 'name': u'another'})])
Expand All @@ -200,9 +200,9 @@ def test_updateBuilderList(self):
self.assertEqual(sorted((yield self.master.db.builders.getBuilders())),
sorted([
dict(id=1, masterids=[13],
name='somebuilder', description=None),
name='somebuilder', description=None, tags=[]),
dict(id=2, masterids=[13, 14],
name='another', description=None),
name='another', description=None, tags=[]),
]))
self.master.mq.assertProductions([(('builders', '2', 'started'),
{'builderid': 2, 'masterid': 14, 'name': u'another'})])
Expand All @@ -211,8 +211,8 @@ def test_updateBuilderList(self):
yield self.rtype.updateBuilderList(13, [])
self.assertEqual(sorted((yield self.master.db.builders.getBuilders())),
sorted([
dict(id=1, masterids=[], name='somebuilder', description=None),
dict(id=2, masterids=[14], name='another', description=None),
dict(id=1, masterids=[], name='somebuilder', description=None, tags=[]),
dict(id=2, masterids=[14], name='another', description=None, tags=[]),
]))
self.master.mq.assertProductions([
(('builders', '1', 'stopped'),
Expand Down
49 changes: 28 additions & 21 deletions master/buildbot/test/unit/test_db_builders.py
Expand Up @@ -58,30 +58,37 @@ def test_signature_getBuilders(self):
def getBuilders(self, masterid=None):
pass

def test_signature_updateBuilderDescription(self):
@self.assertArgSpecMatches(self.db.builders.updateBuilderDescription)
def updateBuilderDescription(self, builderid, description):
def test_signature_updateBuilderInfo(self):
@self.assertArgSpecMatches(self.db.builders.updateBuilderInfo)
def updateBuilderInfo(self, builderid, description, tags):
pass

@defer.inlineCallbacks
def test_updateBuilderDescription(self):
def test_updateBuilderInfo(self):
yield self.insertTestData([
fakedb.Builder(id=7, name='some:builder'),
fakedb.Builder(id=7, name='some:builder7'),
fakedb.Builder(id=8, name='some:builder8'),
])

yield self.db.builders.updateBuilderDescription(7, u'a string which describe the builder')
builderdict = yield self.db.builders.getBuilder(7)
validation.verifyDbDict(self, 'builderdict', builderdict)
self.assertEqual(builderdict,
dict(id=7, name='some:builder',
yield self.db.builders.updateBuilderInfo(7, u'a string which describe the builder', [u'cat1', u'cat2'])
yield self.db.builders.updateBuilderInfo(8, u'a string which describe the builder', None)
builderdict7 = yield self.db.builders.getBuilder(7)
validation.verifyDbDict(self, 'builderdict', builderdict7)
self.assertEqual(builderdict7,
dict(id=7, name='some:builder7', tags=['cat1', 'cat2'],
masterids=[], description='a string which describe the builder'))
builderdict8 = yield self.db.builders.getBuilder(8)
validation.verifyDbDict(self, 'builderdict', builderdict8)
self.assertEqual(builderdict8,
dict(id=8, name='some:builder8', tags=[],
masterids=[], description='a string which describe the builder'))

@defer.inlineCallbacks
def test_findBuilderId_new(self):
id = yield self.db.builders.findBuilderId('some:builder')
builderdict = yield self.db.builders.getBuilder(id)
self.assertEqual(builderdict,
dict(id=id, name='some:builder',
dict(id=id, name='some:builder', tags=[],
masterids=[], description=None))

@defer.inlineCallbacks
Expand All @@ -104,7 +111,7 @@ def test_addBuilderMaster(self):
builderdict = yield self.db.builders.getBuilder(7)
validation.verifyDbDict(self, 'builderdict', builderdict)
self.assertEqual(builderdict,
dict(id=7, name='some:builder',
dict(id=7, name='some:builder', tags=[],
masterids=[9, 10], description=None))

@defer.inlineCallbacks
Expand All @@ -119,7 +126,7 @@ def test_addBuilderMaster_already_present(self):
builderdict = yield self.db.builders.getBuilder(7)
validation.verifyDbDict(self, 'builderdict', builderdict)
self.assertEqual(builderdict,
dict(id=7, name='some:builder',
dict(id=7, name='some:builder', tags=[],
masterids=[9], description=None))

@defer.inlineCallbacks
Expand All @@ -135,7 +142,7 @@ def test_removeBuilderMaster(self):
builderdict = yield self.db.builders.getBuilder(7)
validation.verifyDbDict(self, 'builderdict', builderdict)
self.assertEqual(builderdict,
dict(id=7, name='some:builder',
dict(id=7, name='some:builder', tags=[],
masterids=[10], description=None))

@defer.inlineCallbacks
Expand All @@ -146,7 +153,7 @@ def test_getBuilder_no_masters(self):
builderdict = yield self.db.builders.getBuilder(7)
validation.verifyDbDict(self, 'builderdict', builderdict)
self.assertEqual(builderdict,
dict(id=7, name='some:builder',
dict(id=7, name='some:builder', tags=[],
masterids=[], description=None))

@defer.inlineCallbacks
Expand All @@ -161,7 +168,7 @@ def test_getBuilder_with_masters(self):
builderdict = yield self.db.builders.getBuilder(7)
validation.verifyDbDict(self, 'builderdict', builderdict)
self.assertEqual(builderdict,
dict(id=7, name='some:builder',
dict(id=7, name='some:builder', tags=[],
masterids=[3, 4], description=None))

@defer.inlineCallbacks
Expand All @@ -185,9 +192,9 @@ def test_getBuilders(self):
for builderdict in builderlist:
validation.verifyDbDict(self, 'builderdict', builderdict)
self.assertEqual(sorted(builderlist), sorted([
dict(id=7, name='some:builder', masterids=[3], description=None),
dict(id=8, name='other:builder', masterids=[3, 4], description=None),
dict(id=9, name='third:builder', masterids=[], description=None),
dict(id=7, name='some:builder', masterids=[3], tags=[], description=None),
dict(id=8, name='other:builder', masterids=[3, 4], tags=[], description=None),
dict(id=9, name='third:builder', masterids=[], tags=[], description=None),
]))

@defer.inlineCallbacks
Expand All @@ -206,8 +213,8 @@ def test_getBuilders_masterid(self):
for builderdict in builderlist:
validation.verifyDbDict(self, 'builderdict', builderdict)
self.assertEqual(sorted(builderlist), sorted([
dict(id=7, name='some:builder', masterids=[3], description=None),
dict(id=8, name='other:builder', masterids=[3, 4], description=None),
dict(id=7, name='some:builder', masterids=[3], tags=[], description=None),
dict(id=8, name='other:builder', masterids=[3, 4], tags=[], description=None),
]))

@defer.inlineCallbacks
Expand Down

0 comments on commit 5c2cf49

Please sign in to comment.