Beispiel #1
0
    def test_addBuildsetForSourceStamp_list_of_renderable_builderNames(self):
        names = ['a', 'b', properties.Interpolate('%(prop:extra_builder)s')]
        sched = self.makeScheduler(name='n', builderNames=names)

        self.master.db.insertTestData([
            fakedb.Builder(id=1, name='a'),
            fakedb.Builder(id=2, name='b'),
            fakedb.Builder(id=3, name='c'),
            fakedb.SourceStamp(id=98, branch='stable'),
            fakedb.Change(changeid=25, sourcestampid=98, branch='stable'),
            fakedb.ChangeProperty(changeid=25,
                                  property_name='extra_builder',
                                  property_value='["c","Change"]'),
        ])

        bsid, brids = yield sched.addBuildsetForSourceStamps(reason='whynot',
                                                             waited_for=False,
                                                             sourcestamps=[98])
        self.assertEqual((bsid, brids), self.exp_bsid_brids)
        self.master.data.updates.addBuildset.assert_called_with(
            waited_for=False,
            builderids=[1, 2, 3],
            external_idstring=None,
            properties={
                'scheduler': ('n', 'Scheduler'),
                'extra_builder': ('c', 'Change')
            },
            reason='whynot',
            scheduler='n',
            sourcestamps=[98])
Beispiel #2
0
    def test_addBuildsetForSourceStamp_combine_change_properties(self):
        sched = self.makeScheduler()

        self.master.db.insertTestData([
            fakedb.SourceStamp(id=98, branch='stable'),
            fakedb.Change(changeid=25, sourcestampid=98, branch='stable'),
            fakedb.ChangeProperty(changeid=25,
                                  property_name='color',
                                  property_value='["pink","Change"]'),
        ])

        bsid, brids = yield sched.addBuildsetForSourceStamps(reason='whynot',
                                                             waited_for=False,
                                                             sourcestamps=[98])
        self.assertEqual((bsid, brids), self.exp_bsid_brids)
        self.master.data.updates.addBuildset.assert_called_with(
            waited_for=False,
            builderids=[1, 2],
            external_idstring=None,
            properties={
                'scheduler': ('testsched', 'Scheduler'),
                'color': ('pink', 'Change')
            },
            reason='whynot',
            scheduler='testsched',
            sourcestamps=[98])
Beispiel #3
0
    def test_bogus_row_jsoned_list(self):
        yield self.insertTestData([
            fakedb.SourceStamp(id=10),
            fakedb.ChangeProperty(changeid=13,
                                  property_name='devel',
                                  property_value='[1, 2]'),
            fakedb.Change(changeid=13, sourcestampid=10),
        ])

        c = yield self.db.changes.getChange(13)

        self.assertEqual(c['properties'], dict(devel=([1, 2], 'Change')))
Beispiel #4
0
class Tests(interfaces.InterfaceTests):

    # common sample data

    change13_rows = [
        fakedb.SourceStamp(id=92, branch="thirteen"),
        fakedb.Change(changeid=13, author="dustin", comments="fix spelling",
                      branch="master", revision="deadbeef", committer="justin",
                      when_timestamp=266738400, revlink=None, category=None,
                      repository='', codebase='', project='', sourcestampid=92),

        fakedb.ChangeFile(changeid=13, filename='master/README.txt'),
        fakedb.ChangeFile(changeid=13, filename='worker/README.txt'),

        fakedb.ChangeProperty(changeid=13, property_name='notest',
                              property_value='["no","Change"]'),
    ]

    change14_rows = [
        fakedb.SourceStamp(id=233, branch="fourteen"),
        fakedb.Change(changeid=14, author="warner", comments="fix whitespace",
                      branch="warnerdb", revision="0e92a098b", committer="david",
                      when_timestamp=266738404, revlink='http://warner/0e92a098b',
                      category='devel', repository='git://warner', codebase='mainapp',
                      project='Buildbot', sourcestampid=233),

        fakedb.ChangeFile(changeid=14, filename='master/buildbot/__init__.py'),
    ]

    change14_dict = {
        'changeid': 14,
        'parent_changeids': [],
        'author': 'warner',
        'committer': 'david',
        'branch': 'warnerdb',
        'category': 'devel',
        'comments': 'fix whitespace',
        'files': ['master/buildbot/__init__.py'],
        'project': 'Buildbot',
        'properties': {},
        'repository': 'git://warner',
        'codebase': 'mainapp',
        'revision': '0e92a098b',
        'revlink': 'http://warner/0e92a098b',
        'when_timestamp': epoch2datetime(266738404),
        'sourcestampid': 233,
    }

    # tests

    def test_signature_addChange(self):
        @self.assertArgSpecMatches(self.db.changes.addChange)
        def addChange(self, author=None, committer=None, files=None, comments=None, is_dir=None,
                      revision=None, when_timestamp=None, branch=None, category=None,
                      revlink='', properties=None, repository='', codebase='',
                      project='', uid=None):
            pass

    def test_signature_getChange(self):
        @self.assertArgSpecMatches(self.db.changes.getChange)
        def getChange(self, key, no_cache=False):
            pass

    @defer.inlineCallbacks
    def test_addChange_getChange(self):
        self.reactor.advance(SOMETIME)
        changeid = yield self.db.changes.addChange(
            author='dustin',
            committer='justin',
            files=[],
            comments='fix spelling',
            revision='2d6caa52',
            when_timestamp=epoch2datetime(OTHERTIME),
            branch='master',
            category=None,
            revlink=None,
            properties={},
            repository='repo://',
            codebase='cb',
            project='proj')
        chdict = yield self.db.changes.getChange(changeid)
        validation.verifyDbDict(self, 'chdict', chdict)
        chdict = chdict.copy()
        ss = yield self.db.sourcestamps.getSourceStamp(chdict['sourcestampid'])
        chdict['sourcestampid'] = ss
        self.assertEqual(chdict, {
            'author': 'dustin',
            'committer': 'justin',
            'branch': 'master',
            'category': None,
            'changeid': changeid,
            'parent_changeids': [],
            'codebase': 'cb',
            'comments': 'fix spelling',
            'files': [],
            'project': 'proj',
            'properties': {},
            'repository': 'repo://',
            'revision': '2d6caa52',
            'revlink': None,
            'sourcestampid': {
                'branch': 'master',
                'codebase': 'cb',
                'patch_author': None,
                'patch_body': None,
                'patch_comment': None,
                'patch_level': None,
                'patch_subdir': None,
                'patchid': None,
                'project': 'proj',
                'repository': 'repo://',
                'revision': '2d6caa52',
                'created_at': epoch2datetime(SOMETIME),
                'ssid': ss['ssid'],
            },
            'when_timestamp': epoch2datetime(OTHERTIME),
        })

    @defer.inlineCallbacks
    def test_addChange_withParent(self):
        yield self.insertTestData(self.change14_rows)

        self.reactor.advance(SOMETIME)
        changeid = yield self.db.changes.addChange(
            author='delanne',
            committer='melanne',
            files=[],
            comments='child of changeid14',
            revision='50adad56',
            when_timestamp=epoch2datetime(OTHERTIME),
            branch='warnerdb',
            category='devel',
            revlink=None,
            properties={},
            repository='git://warner',
            codebase='mainapp',
            project='Buildbot')
        chdict = yield self.db.changes.getChange(changeid)
        validation.verifyDbDict(self, 'chdict', chdict)
        chdict = chdict.copy()
        ss = yield self.db.sourcestamps.getSourceStamp(chdict['sourcestampid'])
        chdict['sourcestampid'] = ss
        self.assertEqual(chdict, {
            'author': 'delanne',
            'committer': 'melanne',
            'branch': 'warnerdb',
            'category': 'devel',
            'changeid': changeid,
            'parent_changeids': [14],
            'codebase': 'mainapp',
            'comments': 'child of changeid14',
            'files': [],
            'project': 'Buildbot',
            'properties': {},
            'repository': 'git://warner',
            'revision': '50adad56',
            'revlink': None,
            'sourcestampid': {
                'branch': 'warnerdb',
                'codebase': 'mainapp',
                'created_at': epoch2datetime(SOMETIME),
                'patch_author': None,
                'patch_body': None,
                'patch_comment': None,
                'patch_level': None,
                'patch_subdir': None,
                'patchid': None,
                'project': 'Buildbot',
                'repository': 'git://warner',
                'revision': '50adad56',
                'ssid': ss['ssid']
            },
            'when_timestamp': epoch2datetime(OTHERTIME),
        })

    @defer.inlineCallbacks
    def test_getChange_chdict(self):
        yield self.insertTestData(self.change14_rows)

        chdict = yield self.db.changes.getChange(14)

        validation.verifyDbDict(self, 'chdict', chdict)
        self.assertEqual(chdict, self.change14_dict)

    @defer.inlineCallbacks
    def test_getChange_missing(self):
        chdict = yield self.db.changes.getChange(14)

        self.assertTrue(chdict is None)

    def test_signature_getChangeUids(self):
        @self.assertArgSpecMatches(self.db.changes.getChangeUids)
        def getChangeUids(self, changeid):
            pass

    @defer.inlineCallbacks
    def test_getChangeUids_missing(self):
        res = yield self.db.changes.getChangeUids(1)

        self.assertEqual(res, [])

    @defer.inlineCallbacks
    def test_getChangeUids_found(self):
        yield self.insertTestData(self.change14_rows + [
            fakedb.SourceStamp(id=92),
            fakedb.User(uid=1),
            fakedb.ChangeUser(changeid=14, uid=1),
        ])
        res = yield self.db.changes.getChangeUids(14)

        self.assertEqual(res, [1])

    @defer.inlineCallbacks
    def test_getChangeUids_multi(self):
        yield self.insertTestData(self.change14_rows + self.change13_rows + [
            fakedb.User(uid=1, identifier="one"),
            fakedb.User(uid=2, identifier="two"),
            fakedb.User(uid=99, identifier="nooo"),
            fakedb.ChangeUser(changeid=14, uid=1),
            fakedb.ChangeUser(changeid=14, uid=2),
            fakedb.ChangeUser(changeid=13, uid=99),  # not selected
        ])
        res = yield self.db.changes.getChangeUids(14)

        self.assertEqual(sorted(res), [1, 2])

    def test_signature_getRecentChanges(self):
        @self.assertArgSpecMatches(self.db.changes.getRecentChanges)
        def getRecentChanges(self, count):
            pass

    def test_signature_getChanges(self):
        @self.assertArgSpecMatches(self.db.changes.getChanges)
        def getChanges(self):
            pass

    def insert7Changes(self):
        return self.insertTestData([
            fakedb.SourceStamp(id=922),
            fakedb.Change(changeid=8, sourcestampid=922),
            fakedb.Change(changeid=9, sourcestampid=922),
            fakedb.Change(changeid=10, sourcestampid=922),
            fakedb.Change(changeid=11, sourcestampid=922),
            fakedb.Change(changeid=12, sourcestampid=922),
        ] + self.change13_rows + self.change14_rows)

    @defer.inlineCallbacks
    def test_getRecentChanges_subset(self):
        yield self.insert7Changes()
        changes = yield self.db.changes.getRecentChanges(5)

        changeids = [c['changeid'] for c in changes]
        self.assertEqual(changeids, [10, 11, 12, 13, 14])

    @defer.inlineCallbacks
    def test_getChangesCount(self):
        yield self.insert7Changes()
        n = yield self.db.changes.getChangesCount()

        self.assertEqual(n, 7)

    @defer.inlineCallbacks
    def test_getChangesHugeCount(self):
        yield self.insertTestData([
            fakedb.SourceStamp(id=92),
        ] + [
            fakedb.Change(changeid=i) for i in range(2, 102)])
        n = yield self.db.changes.getChangesCount()

        self.assertEqual(n, 100)

    @defer.inlineCallbacks
    def test_getRecentChanges_empty(self):
        changes = yield self.db.changes.getRecentChanges(5)

        changeids = [c['changeid'] for c in changes]
        self.assertEqual(changeids, [])
        yield self.db.changes.getChanges()

        changeids = [c['changeid'] for c in changes]
        self.assertEqual(changeids, [])

    @defer.inlineCallbacks
    def test_getRecentChanges_missing(self):
        yield self.insertTestData(self.change13_rows + self.change14_rows)

        def check(changes):
            # requested all, but only got 2
            # sort by changeid, since we assert on change 13 at index 0
            changes.sort(key=lambda c: c['changeid'])
            changeids = [c['changeid'] for c in changes]
            self.assertEqual(changeids, [13, 14])
            # double-check that they have .files, etc.
            self.assertEqual(sorted(changes[0]['files']),
                             sorted(['master/README.txt', 'worker/README.txt']))
            self.assertEqual(changes[0]['properties'],
                             {'notest': ('no', 'Change')})

        changes = yield self.db.changes.getRecentChanges(5)
        check(changes)

        changes = yield self.db.changes.getChanges()
        check(changes)

    def test_signature_getLatestChangeid(self):
        @self.assertArgSpecMatches(self.db.changes.getLatestChangeid)
        def getLatestChangeid(self):
            pass

    @defer.inlineCallbacks
    def test_getLatestChangeid(self):
        yield self.insertTestData(self.change13_rows)

        changeid = yield self.db.changes.getLatestChangeid()

        self.assertEqual(changeid, 13)

    @defer.inlineCallbacks
    def test_getLatestChangeid_empty(self):
        changeid = yield self.db.changes.getLatestChangeid()

        self.assertEqual(changeid, None)

    def test_signature_getParentChangeIds(self):
        @self.assertArgSpecMatches(self.db.changes.getParentChangeIds)
        def getParentChangeIds(self, branch, repository, project, codebase):
            pass

    @defer.inlineCallbacks
    def test_getParentChangeIds(self):
        yield self.insertTestData(self.change14_rows + self.change13_rows)

        changeid = yield self.db.changes.getParentChangeIds(branch='warnerdb',
                                                      repository='git://warner',
                                                      project='Buildbot',
                                                      codebase='mainapp')
        self.assertEqual(changeid, [14])
class Change(unittest.TestCase, TestReactorMixin):

    change23_rows = [
        fakedb.Change(changeid=23, author="dustin", committer="dustin", comments="fix whitespace",
                      branch="warnerdb", revision="deadbeef",
                      when_timestamp=266738404, revlink='http://warner/0e92a098b',
                      category='devel', repository='git://warner', codebase='mainapp',
                      project='Buildbot'),

        fakedb.ChangeFile(changeid=23, filename='master/README.txt'),
        fakedb.ChangeFile(changeid=23, filename='worker/README.txt'),

        fakedb.ChangeProperty(changeid=23, property_name='notest',
                              property_value='["no","Change"]'),

        fakedb.ChangeUser(changeid=23, uid=27),
    ]

    def setUp(self):
        self.setUpTestReactor()
        self.master = fakemaster.make_master(self, wantDb=True)
        self.change23 = changes.Change(**dict(  # using **dict(..) forces kwargs
            category='devel',
            repository='git://warner',
            codebase='mainapp',
            who='dustin',
            committer='dustin',
            when=266738404,
            comments='fix whitespace',
            project='Buildbot',
            branch='warnerdb',
            revlink='http://warner/0e92a098b',
            properties={'notest': "no"},
            files=['master/README.txt', 'worker/README.txt'],
            revision='deadbeef'))
        self.change23.number = 23

        self.change24 = changes.Change(**dict(
            category='devel',
            repository='git://warner',
            codebase='mainapp',
            who='dustin',
            committer='dustin',
            when=266738405,
            comments='fix whitespace again',
            project='Buildbot',
            branch='warnerdb',
            revlink='http://warner/0e92a098c',
            properties={'notest': "no"},
            files=['master/README.txt', 'worker/README.txt'],
            revision='deadbeef'))
        self.change24.number = 24

        self.change25 = changes.Change(**dict(
            category='devel',
            repository='git://warner',
            codebase='mainapp',
            who='dustin',
            committer='dustin',
            when=266738406,
            comments='fix whitespace again',
            project='Buildbot',
            branch='warnerdb',
            revlink='http://warner/0e92a098d',
            properties={'notest': "no"},
            files=['master/README.txt', 'worker/README.txt'],
            revision='deadbeef'))
        self.change25.number = 25

    @defer.inlineCallbacks
    def test_fromChdict(self):
        # get a real honest-to-goodness chdict from the fake db
        yield self.master.db.insertTestData(self.change23_rows)
        chdict = yield self.master.db.changes.getChange(23)

        exp = self.change23
        got = yield changes.Change.fromChdict(self.master, chdict)

        # compare
        ok = True
        ok = ok and got.number == exp.number
        ok = ok and got.who == exp.who
        ok = ok and got.committer == exp.committer
        ok = ok and sorted(got.files) == sorted(exp.files)
        ok = ok and got.comments == exp.comments
        ok = ok and got.revision == exp.revision
        ok = ok and got.when == exp.when
        ok = ok and got.branch == exp.branch
        ok = ok and got.category == exp.category
        ok = ok and got.revlink == exp.revlink
        ok = ok and got.properties == exp.properties
        ok = ok and got.repository == exp.repository
        ok = ok and got.codebase == exp.codebase
        ok = ok and got.project == exp.project
        if not ok:
            def printable(c):
                return pprint.pformat(c.__dict__)
            self.fail("changes do not match; expected\n{}\ngot\n{}".format(printable(exp),
                                                                           printable(got)))

    def test_str(self):
        string = str(self.change23)
        self.assertTrue(re.match(r"Change\(.*\)", string), string)

    def test_asText(self):
        text = self.change23.asText()
        self.assertTrue(re.match(textwrap.dedent('''\
            Files:
             master/README.txt
             worker/README.txt
            On: git://warner
            For: Buildbot
            At: .*
            Changed By: dustin
            Committed By: dustin
            Comments: fix whitespaceProperties:.
              notest: no

            '''), text), text)

    def test_asDict(self):
        dict = self.change23.asDict()
        self.assertIn('1978', dict['at'])  # timezone-sensitive
        del dict['at']
        self.assertEqual(dict, {
            'branch': 'warnerdb',
            'category': 'devel',
            'codebase': 'mainapp',
            'comments': 'fix whitespace',
            'files': [{'name': 'master/README.txt'},
                      {'name': 'worker/README.txt'}],
            'number': 23,
            'project': 'Buildbot',
            'properties': [('notest', 'no', 'Change')],
            'repository': 'git://warner',
            'rev': 'deadbeef',
            'revision': 'deadbeef',
            'revlink': 'http://warner/0e92a098b',
            'when': 266738404,
            'who': 'dustin',
            'committer': 'dustin'})

    def test_getShortAuthor(self):
        self.assertEqual(self.change23.getShortAuthor(), 'dustin')

    def test_getTime(self):
        # careful, or timezones will hurt here
        self.assertIn('Jun 1978', self.change23.getTime())

    def test_getTimes(self):
        self.assertEqual(self.change23.getTimes(), (266738404, None))

    def test_getText(self):
        self.change23.who = 'nasty < nasty'  # test the html escaping (ugh!)
        self.assertEqual(self.change23.getText(), ['nasty &lt; nasty'])

    def test_getLogs(self):
        self.assertEqual(self.change23.getLogs(), {})

    def test_compare(self):
        self.assertEqual(self.change23, self.change23)
        self.assertNotEqual(self.change24, self.change23)
        self.assertGreater(self.change24, self.change23)
        self.assertGreaterEqual(self.change24, self.change23)
        self.assertGreaterEqual(self.change24, self.change24)
        self.assertLessEqual(self.change24, self.change24)
        self.assertLessEqual(self.change23, self.change24)
        self.assertLess(self.change23, self.change25)
Beispiel #6
0
 def insert_initial_data(self):
     self.master.db.insertTestData([
         fakedb.Master(id=1),
         fakedb.Worker(id=1, name='example-worker'),
         fakedb.Scheduler(id=1, name='custom', enabled=1),
         fakedb.Scheduler(id=2, name='all', enabled=2),
         fakedb.Scheduler(id=3, name='force', enabled=3),
         fakedb.SchedulerMaster(schedulerid=1, masterid=1),
         fakedb.SchedulerMaster(schedulerid=2, masterid=1),
         fakedb.SchedulerMaster(schedulerid=3, masterid=1),
         fakedb.Builder(id=1, name='runtests1'),
         fakedb.Builder(id=2, name='runtests2'),
         fakedb.Builder(id=3, name='runtests3'),
         fakedb.BuilderMaster(id=1, builderid=1, masterid=1),
         fakedb.BuilderMaster(id=2, builderid=2, masterid=1),
         fakedb.BuilderMaster(id=3, builderid=3, masterid=1),
         fakedb.Tag(id=1, name='tag1'),
         fakedb.Tag(id=2, name='tag12'),
         fakedb.Tag(id=3, name='tag23'),
         fakedb.BuildersTags(id=1, builderid=1, tagid=1),
         fakedb.BuildersTags(id=2, builderid=1, tagid=2),
         fakedb.BuildersTags(id=3, builderid=2, tagid=2),
         fakedb.BuildersTags(id=4, builderid=2, tagid=3),
         fakedb.BuildersTags(id=5, builderid=3, tagid=3),
         fakedb.Buildset(id=1,
                         results=SUCCESS,
                         reason="Force reason 1",
                         submitted_at=100000,
                         complete_at=100110,
                         complete=1),
         fakedb.Buildset(id=2,
                         results=SUCCESS,
                         reason="Force reason 2",
                         submitted_at=100200,
                         complete_at=100330,
                         complete=1),
         fakedb.Buildset(id=3,
                         results=SUCCESS,
                         reason="Force reason 3",
                         submitted_at=100400,
                         complete_at=100550,
                         complete=1),
         fakedb.BuildsetProperty(buildsetid=1,
                                 property_name='scheduler',
                                 property_value='["custom", "Scheduler"]'),
         fakedb.BuildsetProperty(buildsetid=2,
                                 property_name='scheduler',
                                 property_value='["all", "Scheduler"]'),
         fakedb.BuildsetProperty(buildsetid=3,
                                 property_name='scheduler',
                                 property_value='["force", "Scheduler"]'),
         fakedb.BuildsetProperty(
             buildsetid=3,
             property_name='owner',
             property_value='["*****@*****.**", "Force Build Form"]'),
         fakedb.SourceStamp(id=1, branch='master', revision='1234abcd'),
         fakedb.Change(changeid=1,
                       branch='master',
                       revision='1234abcd',
                       sourcestampid=1),
         fakedb.ChangeProperty(
             changeid=1,
             property_name="owner",
             property_value='["*****@*****.**", "change"]'),
         fakedb.ChangeProperty(changeid=1,
                               property_name="other_prop",
                               property_value='["value", "change"]'),
         fakedb.BuildsetSourceStamp(id=1, buildsetid=1, sourcestampid=1),
         fakedb.BuildsetSourceStamp(id=2, buildsetid=2, sourcestampid=1),
         fakedb.BuildsetSourceStamp(id=3, buildsetid=3, sourcestampid=1),
         fakedb.BuildRequest(id=1,
                             buildsetid=1,
                             builderid=1,
                             results=SUCCESS,
                             submitted_at=100001,
                             complete_at=100109,
                             complete=1),
         fakedb.BuildRequest(id=2,
                             buildsetid=2,
                             builderid=1,
                             results=SUCCESS,
                             submitted_at=100201,
                             complete_at=100329,
                             complete=1),
         fakedb.BuildRequest(id=3,
                             buildsetid=3,
                             builderid=2,
                             results=SUCCESS,
                             submitted_at=100401,
                             complete_at=100549,
                             complete=1),
         fakedb.Build(id=1,
                      number=1,
                      buildrequestid=1,
                      builderid=1,
                      workerid=1,
                      masterid=1001,
                      started_at=100002,
                      complete_at=100108,
                      state_string='build successful',
                      results=SUCCESS),
         fakedb.Build(id=2,
                      number=2,
                      buildrequestid=2,
                      builderid=1,
                      workerid=1,
                      masterid=1001,
                      started_at=100202,
                      complete_at=100328,
                      state_string='build successful',
                      results=SUCCESS),
         fakedb.Build(id=3,
                      number=1,
                      buildrequestid=3,
                      builderid=2,
                      workerid=1,
                      masterid=1001,
                      started_at=100402,
                      complete_at=100548,
                      state_string='build successful',
                      results=SUCCESS),
         fakedb.BuildProperty(buildid=3,
                              name='reason',
                              value='"force build"',
                              source="Force Build Form"),
         fakedb.BuildProperty(buildid=3,
                              name='owner',
                              value='"*****@*****.**"',
                              source="Force Build Form"),
         fakedb.BuildProperty(buildid=3,
                              name='scheduler',
                              value='"force"',
                              source="Scheduler"),
         fakedb.BuildProperty(buildid=3,
                              name='buildername',
                              value='"runtests3"',
                              source="Builder"),
         fakedb.BuildProperty(buildid=3,
                              name='workername',
                              value='"example-worker"',
                              source="Worker"),
         fakedb.Step(id=1,
                     number=1,
                     name='step1',
                     buildid=1,
                     started_at=100010,
                     complete_at=100019,
                     state_string='step1 done'),
         fakedb.Step(id=2,
                     number=2,
                     name='step2',
                     buildid=1,
                     started_at=100020,
                     complete_at=100029,
                     state_string='step2 done'),
         fakedb.Step(id=3,
                     number=3,
                     name='step3',
                     buildid=1,
                     started_at=100030,
                     complete_at=100039,
                     state_string='step3 done'),
         fakedb.Step(id=11,
                     number=1,
                     name='step1',
                     buildid=2,
                     started_at=100210,
                     complete_at=100219,
                     state_string='step1 done'),
         fakedb.Step(id=12,
                     number=2,
                     name='step2',
                     buildid=2,
                     started_at=100220,
                     complete_at=100229,
                     state_string='step2 done'),
         fakedb.Step(id=13,
                     number=3,
                     name='step3',
                     buildid=2,
                     started_at=100230,
                     complete_at=100239,
                     state_string='step3 done'),
         fakedb.Step(id=21,
                     number=1,
                     name='step1',
                     buildid=3,
                     started_at=100410,
                     complete_at=100419,
                     state_string='step1 done'),
         fakedb.Step(id=22,
                     number=2,
                     name='step2',
                     buildid=3,
                     started_at=100420,
                     complete_at=100429,
                     state_string='step2 done'),
         fakedb.Step(id=23,
                     number=3,
                     name='step3',
                     buildid=3,
                     started_at=100430,
                     complete_at=100439,
                     state_string='step3 done'),
         fakedb.Log(id=1,
                    name='stdio',
                    slug='stdio',
                    stepid=1,
                    complete=1,
                    num_lines=10),
         fakedb.Log(id=2,
                    name='stdio',
                    slug='stdio',
                    stepid=2,
                    complete=1,
                    num_lines=20),
         fakedb.Log(id=3,
                    name='stdio',
                    slug='stdio',
                    stepid=3,
                    complete=1,
                    num_lines=30),
         fakedb.Log(id=11,
                    name='stdio',
                    slug='stdio',
                    stepid=11,
                    complete=1,
                    num_lines=30),
         fakedb.Log(id=12,
                    name='stdio',
                    slug='stdio',
                    stepid=12,
                    complete=1,
                    num_lines=40),
         fakedb.Log(id=13,
                    name='stdio',
                    slug='stdio',
                    stepid=13,
                    complete=1,
                    num_lines=50),
         fakedb.Log(id=21,
                    name='stdio',
                    slug='stdio',
                    stepid=21,
                    complete=1,
                    num_lines=50),
         fakedb.Log(id=22,
                    name='stdio',
                    slug='stdio',
                    stepid=22,
                    complete=1,
                    num_lines=60),
         fakedb.Log(id=23,
                    name='stdio',
                    slug='stdio',
                    stepid=23,
                    complete=1,
                    num_lines=70),
         fakedb.LogChunk(logid=1,
                         first_line=0,
                         last_line=2,
                         content='o line1\no line2\n'),
         fakedb.LogChunk(logid=1,
                         first_line=2,
                         last_line=3,
                         content='o line3\n'),
         fakedb.LogChunk(logid=2,
                         first_line=0,
                         last_line=4,
                         content='o line1\no line2\no line3\no line4\n'),
     ])