aboutsummaryrefslogtreecommitdiffstats
path: root/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot')
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/VERSION1
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/__init__.py48
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildbot.pngbin783 -> 0 bytes
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildrequest.py17
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/__init__.py20
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/base.py1049
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/ec2.py319
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/libvirt.py302
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/openstack.py183
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/base.py95
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/bonsaipoller.py277
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/changes.py289
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/filter.py119
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/gerritchangesource.py204
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/gitpoller.py244
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/hgbuildbot.py168
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/hgpoller.py305
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/mail.py507
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/manager.py72
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/p4poller.py192
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/pb.py161
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/svnpoller.py412
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/base.py73
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/debug.glade684
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/debug.py186
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/gtkPanes.py551
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/sendchange.py59
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/text.py91
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/tryclient.py891
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/usersclient.py50
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/config.py730
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/__init__.py14
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/base.py79
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/buildrequests.py284
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/builds.py80
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/buildsets.py202
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/changes.py257
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/connector.py125
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/enginestrategy.py206
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/exceptions.py17
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/migrate.cfg20
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/001_initial.py283
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/002_add_proj_repo.py30
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/003_scheduler_class_name.py29
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/004_add_autoincrement.py139
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/005_add_indexes.py144
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/006_drop_last_access.py23
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/007_add_object_tables.py37
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/008_add_scheduler_changes_index.py31
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/009_add_patch_author.py36
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/010_fix_column_lengths.py63
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/011_add_buildrequest_claims.py119
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/012_add_users_table.py66
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/013_remove_schedulers_state_column.py40
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/014_add_users_userpass_columns.py31
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/015_remove_bad_master_objectid.py71
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/016_restore_buildrequest_indices.py36
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/017_restore_other_indices.py68
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/018_add_sourcestampset.py64
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/019_merge_schedulers_to_objects.py75
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/020_remove_change_links.py23
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/021_fix_postgres_sequences.py52
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/022_add_codebase.py34
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/model.py539
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/pool.py288
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/schedulers.py93
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/sourcestamps.py145
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/sourcestampsets.py29
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/state.py151
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/users.py233
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/ec2buildslave.py27
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/interfaces.py1216
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/libvirtbuildslave.py29
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/locks.py310
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/manhole.py323
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/master.py779
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/__init__.py83
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug4520.py53
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug4881.py213
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug5079.py49
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/gatherResults.py71
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/servicechecks.py34
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/sqlalchemy2189.py120
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/sqlalchemy2364.py26
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/testcase_patch.py32
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/pbmanager.py187
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/pbutil.py155
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/base.py17
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/botmaster.py492
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/build.py567
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/builder.py629
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildrequest.py253
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildrequestdistributor.py544
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildstep.py985
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/cache.py73
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/debug.py136
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/factory.py202
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/metrics.py494
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/mtrlogobserver.py474
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/properties.py689
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/slavebuilder.py297
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/subunitlogobserver.py112
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/manager.py45
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/manual.py234
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/users.py184
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/revlinks.py58
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scheduler.py24
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/base.py453
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/basic.py256
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/dependent.py148
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/filter.py18
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/forcesched.py666
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/manager.py95
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/timed.py410
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/triggerable.py94
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/trysched.py304
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/base.py172
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/buildbot_tac.tmpl42
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/checkconfig.py56
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/create_master.py150
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/debugclient.py21
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/logwatcher.py110
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/reconfig.py92
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/restart.py31
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/runner.py731
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/sample.cfg126
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/sendchange.py54
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/start.py115
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/statusgui.py27
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/statuslog.py27
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/stop.py79
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/trycmd.py20
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/tryserver.py40
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/upgrade_master.py180
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/user.py48
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/sourcestamp.py359
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/__init__.py19
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/base.py104
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/build.py479
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/builder.py583
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildrequest.py149
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildset.py68
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildstep.py386
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/client.py586
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/event.py35
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/html.py21
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/logfile.py699
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/mail.py798
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/master.py475
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/persistent_queue.py382
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/progress.py324
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/results.py25
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/slave.py118
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/status_gerrit.py149
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/status_push.py442
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/testresult.py39
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/tinderbox.py276
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/about.py35
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/auth.py220
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/authz.py188
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/base.py806
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/baseweb.py607
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/build.py332
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/builder.py632
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/buildstatus.py66
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/change_hook.py136
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/changes.py71
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/console.py744
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/feeds.py275
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/bg_gradient.jpgbin1822 -> 0 bytes
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/default.css604
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/favicon.icobin1150 -> 0 bytes
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/robots.txt11
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/templates_readme.txt12
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/grid.py341
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/__init__.py1
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/base.py80
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/github.py147
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/googlecode.py87
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/poller.py54
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/logs.py177
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/olpb.py118
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/root.py57
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/session.py121
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/slaves.py203
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/status_json.py741
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/step.py96
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/about.html32
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/authfail.html11
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/authzfail.html10
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/box_macros.html37
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/build.html238
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/build_line.html45
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/builder.html184
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/builders.html50
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildslave.html68
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildslaves.html76
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildstatus.html19
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildstep.html73
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change.html20
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change_macros.html76
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change_sources.html21
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/console.html276
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/directory.html37
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/empty.html5
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_atom10.xml40
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_description.html18
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_rss20.xml39
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_sources.html16
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/footer.html23
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/forms.html288
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid.html31
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid_macros.html65
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid_transposed.html30
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/jsonhelp.html28
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/layout.html90
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/logs.html23
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/onelineperbuild.html36
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/onelineperbuildonebuilder.html18
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/revmacros.html35
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/root.html61
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/testresult.html34
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/user.html29
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/users.html27
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/waterfall.html66
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/waterfallhelp.html140
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/tests.py84
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/users.py90
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/waterfall.py813
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/words.py1097
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/master.py207
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/maxq.py46
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/__init__.py18
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/lintian.py91
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/pbuilder.py213
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/__init__.py27
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/mock.py174
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmbuild.py137
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmlint.py77
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmspec.py71
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/python.py304
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/python_twisted.py611
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/shell.py756
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/slave.py270
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/__init__.py21
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/base.py230
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/bzr.py244
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/cvs.py302
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/git.py481
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/mercurial.py338
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/oldsource.py1173
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/p4.py354
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/repo.py434
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/svn.py381
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/yoctogit.py640
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/subunit.py102
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/transfer.py632
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/trigger.py224
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/vstudio.py408
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/__init__.py26
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/botmaster.py35
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakebuild.py57
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakedb.py1224
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakemaster.py112
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/libvirt.py67
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/openstack.py86
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/pbmanager.py47
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/remotecommand.py294
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/slave.py17
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/state.py24
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/web.py76
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_bad_change_properties_rows.py67
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_import_unicode_changes.py107
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_oldpaths.py191
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_shell_command_properties.py116
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_sourcestamp_revision.py26
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_steps_shell_WarningCountingShellCommand.py48
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_unpickling.py61
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/test_extra_coverage.py65
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_base.py228
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_libvirt.py282
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_openstack.py110
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_base.py81
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_bonsaipoller.py283
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_changes.py113
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_filter.py129
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_gerritchangesource.py85
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_gitpoller.py580
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_hgpoller.py178
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_mail.py99
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_mail_CVSMaildirSource.py214
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_manager.py58
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_p4poller.py238
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_pb.py265
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_svnpoller.py627
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_sendchange.py237
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_tryclient.py135
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_usersclient.py86
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_config.py1207
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_contrib_buildbot_cvs_mail.py191
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_base.py106
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_buildrequests.py729
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_builds.py159
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_buildsets.py430
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_changes.py522
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_connector.py87
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_enginestrategy.py176
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_011_add_buildrequest_claims.py107
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_015_remove_bad_master_objectid.py140
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_016_restore_buildrequest_indices.py81
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_017_restore_other_indices.py124
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_018_add_sourcestampset.py234
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_019_merge_schedulers_to_objects.py120
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_020_remove_change_links.py66
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_021_fix_postgres_sequences.py75
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_022_add_codebase.py135
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_model.py58
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_pool.py185
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_schedulers.py161
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_sourcestamps.py212
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_sourcestampsets.py61
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_state.py182
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_users.py473
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_master.py567
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_pbmanager.py98
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_botmaster_BotMaster.py259
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_botmaster_DuplicateSlaveArbitrator.py213
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_build.py823
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_builder.py427
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildrequest.py346
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildrequestdistributor_BuildRequestDistributor.py1031
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildstep.py272
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_cache.py53
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_debug.py146
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_factory.py81
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_metrics.py233
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_properties.py1407
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_manager.py51
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_manual.py304
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_users.py152
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_revlinks.py82
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_base.py523
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_basic.py452
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_dependent.py153
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_forcesched.py506
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_manager.py168
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Nightly.py208
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_NightlyBase.py206
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_NightlyTriggerable.py309
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Periodic.py173
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Timed.py62
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_triggerable.py211
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_trysched.py727
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_base.py268
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_checkconfig.py169
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_create_master.py214
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_restart.py70
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_runner.py971
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_sendchange.py119
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_start.py108
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_statuslog.py32
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_stop.py126
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_trycmd.py33
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_tryserver.py46
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_upgrade_master.py258
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_user.py100
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_sourcestamp.py195
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_build.py135
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_builder_cache.py73
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_buildstep.py67
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_client.py47
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_logfile.py336
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_mail.py816
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_master.py95
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_persistent_queue.py147
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_progress.py43
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_auth_HTPasswdAprAuth.py75
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_auth_HTPasswdAuth.py55
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_authz_Authz.py227
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_base.py98
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hook.py168
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_github.py205
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_googlecode.py90
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_poller.py107
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_links.py239
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_words.py617
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_master.py229
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_maxq.py71
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_deb_lintian.py55
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_deb_pbuilder.py372
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_mock.py128
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_rpmbuild.py64
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_rpmlint.py56
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_python.py445
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_python_twisted.py194
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_shell.py836
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_slave.py381
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_base_Source.py137
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_bzr.py482
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_cvs.py765
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_git.py1457
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_mercurial.py863
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource.py74
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource_ComputeRepositoryURL.py106
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource_Repo.py31
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_p4.py423
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_repo.py613
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_svn.py1477
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_subunit.py86
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_transfer.py267
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_trigger.py502
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_vstudio.py824
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_test_util_gpo.py323
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util.py194
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_ComparableMixin.py72
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_bbcollections.py69
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_eventual.py108
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_lru.py576
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_maildir.py88
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_misc.py130
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_netstrings.py42
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_sautils.py22
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_state.py77
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_subscriptions.py64
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/__init__.py0
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/change_import.py62
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/changesource.py75
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/compat.py41
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/config.py41
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/connector_component.py54
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/db.py149
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/dirs.py40
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/gpo.py116
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/interfaces.py32
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/logging.py32
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/migration.py80
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/misc.py51
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/pbmanager.py50
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/properties.py24
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/querylog.py35
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/scheduler.py142
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/sourcesteps.py61
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/steps.py256
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/__init__.py204
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/bbcollections.py40
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/croniter.py311
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/eventual.py85
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/lru.py232
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/maildir.py142
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/misc.py69
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/netstrings.py60
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/sautils.py42
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/state.py26
-rw-r--r--lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/subscription.py48
467 files changed, 0 insertions, 98969 deletions
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/VERSION b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/VERSION
deleted file mode 100644
index 5c5cbb3b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/VERSION
+++ /dev/null
@@ -1 +0,0 @@
-0.8.8 \ No newline at end of file
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/__init__.py
deleted file mode 100644
index e9948006..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/__init__.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-# strategy:
-#
-# if there is a VERSION file, use its contents. otherwise, call git to
-# get a version string. if that also fails, use 'latest'.
-#
-import os
-
-version = "latest"
-
-try:
- fn = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'VERSION')
- with open(fn) as f:
- version = f.read().strip()
-
-except IOError:
- from subprocess import Popen, PIPE
- import re
-
- VERSION_MATCH = re.compile(r'\d+\.\d+\.\d+(\w|-)*')
-
- try:
- dir = os.path.dirname(os.path.abspath(__file__))
- p = Popen(['git', 'describe', '--tags', '--always'], cwd=dir, stdout=PIPE, stderr=PIPE)
- out = p.communicate()[0]
-
- if (not p.returncode) and out:
- v = VERSION_MATCH.search(out)
- if v:
- version = v.group()
- except OSError:
- pass
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildbot.png b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildbot.png
deleted file mode 100644
index 387ba15f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildbot.png
+++ /dev/null
Binary files differ
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildrequest.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildrequest.py
deleted file mode 100644
index ed6b6db6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildrequest.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# 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
-
-from buildbot.process.buildrequest import BuildRequest
-_hush_pyflakes = [ BuildRequest ]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/__init__.py
deleted file mode 100644
index c216e0c7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/__init__.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# 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
-
-from buildbot.buildslave.base import (
- AbstractBuildSlave, BuildSlave, AbstractLatentBuildSlave)
-
-_hush_pyflakes = [
- AbstractBuildSlave, BuildSlave, AbstractLatentBuildSlave ]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/base.py
deleted file mode 100644
index 272b323d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/base.py
+++ /dev/null
@@ -1,1049 +0,0 @@
-# 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.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright Canonical Ltd. 2009
-
-import time
-from email.Message import Message
-from email.Utils import formatdate
-from zope.interface import implements
-from twisted.python import log
-from twisted.internet import defer, reactor
-from twisted.application import service
-from twisted.spread import pb
-from twisted.python.reflect import namedModule
-
-from buildbot.status.slave import SlaveStatus
-from buildbot.status.mail import MailNotifier
-from buildbot.process import metrics, botmaster
-from buildbot.interfaces import IBuildSlave, ILatentBuildSlave
-from buildbot.process.properties import Properties
-from buildbot.util import subscription
-from buildbot.util.eventual import eventually
-from buildbot import config
-
-class AbstractBuildSlave(config.ReconfigurableServiceMixin, pb.Avatar,
- service.MultiService):
- """This is the master-side representative for a remote buildbot slave.
- There is exactly one for each slave described in the config file (the
- c['slaves'] list). When buildbots connect in (.attach), they get a
- reference to this instance. The BotMaster object is stashed as the
- .botmaster attribute. The BotMaster is also our '.parent' Service.
-
- I represent a build slave -- a remote machine capable of
- running builds. I am instantiated by the configuration file, and can be
- subclassed to add extra functionality."""
-
- implements(IBuildSlave)
- keepalive_timer = None
- keepalive_interval = None
-
- # reconfig slaves after builders
- reconfig_priority = 64
-
- def __init__(self, name, password, max_builds=None,
- notify_on_missing=[], missing_timeout=3600,
- properties={}, locks=None, keepalive_interval=3600):
- """
- @param name: botname this machine will supply when it connects
- @param password: password this machine will supply when
- it connects
- @param max_builds: maximum number of simultaneous builds that will
- be run concurrently on this buildslave (the
- default is None for no limit)
- @param properties: properties that will be applied to builds run on
- this slave
- @type properties: dictionary
- @param locks: A list of locks that must be acquired before this slave
- can be used
- @type locks: dictionary
- """
- service.MultiService.__init__(self)
- self.slavename = name
- self.password = password
-
- # PB registration
- self.registration = None
- self.registered_port = None
-
- # these are set when the service is started, and unset when it is
- # stopped
- self.botmaster = None
- self.master = None
-
- self.slave_status = SlaveStatus(name)
- self.slave = None # a RemoteReference to the Bot, when connected
- self.slave_commands = None
- self.slavebuilders = {}
- self.max_builds = max_builds
- self.access = []
- if locks:
- self.access = locks
- self.lock_subscriptions = []
-
- self.properties = Properties()
- self.properties.update(properties, "BuildSlave")
- self.properties.setProperty("slavename", name, "BuildSlave")
-
- self.lastMessageReceived = 0
- if isinstance(notify_on_missing, str):
- notify_on_missing = [notify_on_missing]
- self.notify_on_missing = notify_on_missing
- for i in notify_on_missing:
- if not isinstance(i, str):
- config.error(
- 'notify_on_missing arg %r is not a string' % (i,))
- self.missing_timeout = missing_timeout
- self.missing_timer = None
- self.keepalive_interval = keepalive_interval
-
- self.detached_subs = None
-
- self._old_builder_list = None
-
- def __repr__(self):
- return "<%s %r>" % (self.__class__.__name__, self.slavename)
-
- def updateLocks(self):
- """Convert the L{LockAccess} objects in C{self.locks} into real lock
- objects, while also maintaining the subscriptions to lock releases."""
- # unsubscribe from any old locks
- for s in self.lock_subscriptions:
- s.unsubscribe()
-
- # convert locks into their real form
- locks = [ (self.botmaster.getLockFromLockAccess(a), a)
- for a in self.access ]
- self.locks = [(l.getLock(self), la) for l, la in locks]
- self.lock_subscriptions = [ l.subscribeToReleases(self._lockReleased)
- for l, la in self.locks ]
-
- def locksAvailable(self):
- """
- I am called to see if all the locks I depend on are available,
- in which I return True, otherwise I return False
- """
- if not self.locks:
- return True
- for lock, access in self.locks:
- if not lock.isAvailable(self, access):
- return False
- return True
-
- def acquireLocks(self):
- """
- I am called when a build is preparing to run. I try to claim all
- the locks that are needed for a build to happen. If I can't, then
- my caller should give up the build and try to get another slave
- to look at it.
- """
- log.msg("acquireLocks(slave %s, locks %s)" % (self, self.locks))
- if not self.locksAvailable():
- log.msg("slave %s can't lock, giving up" % (self, ))
- return False
- # all locks are available, claim them all
- for lock, access in self.locks:
- lock.claim(self, access)
- return True
-
- def releaseLocks(self):
- """
- I am called to release any locks after a build has finished
- """
- log.msg("releaseLocks(%s): %s" % (self, self.locks))
- for lock, access in self.locks:
- lock.release(self, access)
-
- def _lockReleased(self):
- """One of the locks for this slave was released; try scheduling
- builds."""
- if not self.botmaster:
- return # oh well..
- self.botmaster.maybeStartBuildsForSlave(self.slavename)
-
- def setServiceParent(self, parent):
- # botmaster needs to set before setServiceParent which calls startService
- self.botmaster = parent
- self.master = parent.master
- service.MultiService.setServiceParent(self, parent)
-
- def startService(self):
- self.updateLocks()
- self.startMissingTimer()
- return service.MultiService.startService(self)
-
- @defer.inlineCallbacks
- def reconfigService(self, new_config):
- # Given a new BuildSlave, configure this one identically. Because
- # BuildSlave objects are remotely referenced, we can't replace them
- # without disconnecting the slave, yet there's no reason to do that.
- new = self.findNewSlaveInstance(new_config)
-
- assert self.slavename == new.slavename
-
- # do we need to re-register?
- if (not self.registration or
- self.password != new.password or
- new_config.slavePortnum != self.registered_port):
- if self.registration:
- yield self.registration.unregister()
- self.registration = None
- self.password = new.password
- self.registered_port = new_config.slavePortnum
- self.registration = self.master.pbmanager.register(
- self.registered_port, self.slavename,
- self.password, self.getPerspective)
-
- # adopt new instance's configuration parameters
- self.max_builds = new.max_builds
- self.access = new.access
- self.notify_on_missing = new.notify_on_missing
- self.keepalive_interval = new.keepalive_interval
-
- if self.missing_timeout != new.missing_timeout:
- running_missing_timer = self.missing_timer
- self.stopMissingTimer()
- self.missing_timeout = new.missing_timeout
- if running_missing_timer:
- self.startMissingTimer()
-
- properties = Properties()
- properties.updateFromProperties(new.properties)
- self.properties = properties
-
- self.updateLocks()
-
- # update the attached slave's notion of which builders are attached.
- # This assumes that the relevant builders have already been configured,
- # which is why the reconfig_priority is set low in this class.
- yield self.updateSlave()
-
- yield config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
- def stopService(self):
- if self.registration:
- self.registration.unregister()
- self.registration = None
- self.stopMissingTimer()
- return service.MultiService.stopService(self)
-
- def findNewSlaveInstance(self, new_config):
- # TODO: called multiple times per reconfig; use 1-element cache?
- for sl in new_config.slaves:
- if sl.slavename == self.slavename:
- return sl
- assert 0, "no new slave named '%s'" % self.slavename
-
- def startMissingTimer(self):
- if self.notify_on_missing and self.missing_timeout and self.parent:
- self.stopMissingTimer() # in case it's already running
- self.missing_timer = reactor.callLater(self.missing_timeout,
- self._missing_timer_fired)
-
- def stopMissingTimer(self):
- if self.missing_timer:
- self.missing_timer.cancel()
- self.missing_timer = None
-
- def getPerspective(self, mind, slavename):
- assert slavename == self.slavename
- metrics.MetricCountEvent.log("attached_slaves", 1)
-
- # record when this connection attempt occurred
- if self.slave_status:
- self.slave_status.recordConnectTime()
-
- # try to use TCP keepalives
- try:
- mind.broker.transport.setTcpKeepAlive(1)
- except:
- pass
-
- if self.isConnected():
- # duplicate slave - send it to arbitration
- arb = botmaster.DuplicateSlaveArbitrator(self)
- return arb.getPerspective(mind, slavename)
- else:
- log.msg("slave '%s' attaching from %s" % (slavename, mind.broker.transport.getPeer()))
- return self
-
- def doKeepalive(self):
- self.keepalive_timer = reactor.callLater(self.keepalive_interval,
- self.doKeepalive)
- if not self.slave:
- return
- d = self.slave.callRemote("print", "Received keepalive from master")
- d.addErrback(log.msg, "Keepalive failed for '%s'" % (self.slavename, ))
-
- def stopKeepaliveTimer(self):
- if self.keepalive_timer:
- self.keepalive_timer.cancel()
-
- def startKeepaliveTimer(self):
- assert self.keepalive_interval
- log.msg("Starting buildslave keepalive timer for '%s'" % \
- (self.slavename, ))
- self.doKeepalive()
-
- def isConnected(self):
- return self.slave
-
- def _missing_timer_fired(self):
- self.missing_timer = None
- # notify people, but only if we're still in the config
- if not self.parent:
- return
-
- buildmaster = self.botmaster.master
- status = buildmaster.getStatus()
- text = "The Buildbot working for '%s'\n" % status.getTitle()
- text += ("has noticed that the buildslave named %s went away\n" %
- self.slavename)
- text += "\n"
- text += ("It last disconnected at %s (buildmaster-local time)\n" %
- time.ctime(time.time() - self.missing_timeout)) # approx
- text += "\n"
- text += "The admin on record (as reported by BUILDSLAVE:info/admin)\n"
- text += "was '%s'.\n" % self.slave_status.getAdmin()
- text += "\n"
- text += "Sincerely,\n"
- text += " The Buildbot\n"
- text += " %s\n" % status.getTitleURL()
- text += "\n"
- text += "%s\n" % status.getURLForThing(self.slave_status)
- subject = "Buildbot: buildslave %s was lost" % self.slavename
- return self._mail_missing_message(subject, text)
-
-
- def updateSlave(self):
- """Called to add or remove builders after the slave has connected.
-
- @return: a Deferred that indicates when an attached slave has
- accepted the new builders and/or released the old ones."""
- if self.slave:
- return self.sendBuilderList()
- else:
- return defer.succeed(None)
-
- def updateSlaveStatus(self, buildStarted=None, buildFinished=None):
- if buildStarted:
- self.slave_status.buildStarted(buildStarted)
- if buildFinished:
- self.slave_status.buildFinished(buildFinished)
-
- @metrics.countMethod('AbstractBuildSlave.attached()')
- def attached(self, bot):
- """This is called when the slave connects.
-
- @return: a Deferred that fires when the attachment is complete
- """
-
- # the botmaster should ensure this.
- assert not self.isConnected()
-
- metrics.MetricCountEvent.log("AbstractBuildSlave.attached_slaves", 1)
-
- # set up the subscription point for eventual detachment
- self.detached_subs = subscription.SubscriptionPoint("detached")
-
- # now we go through a sequence of calls, gathering information, then
- # tell the Botmaster that it can finally give this slave to all the
- # Builders that care about it.
-
- # we accumulate slave information in this 'state' dictionary, then
- # set it atomically if we make it far enough through the process
- state = {}
-
- # Reset graceful shutdown status
- self.slave_status.setGraceful(False)
- # We want to know when the graceful shutdown flag changes
- self.slave_status.addGracefulWatcher(self._gracefulChanged)
-
- d = defer.succeed(None)
- def _log_attachment_on_slave(res):
- d1 = bot.callRemote("print", "attached")
- d1.addErrback(lambda why: None)
- return d1
- d.addCallback(_log_attachment_on_slave)
-
- def _get_info(res):
- d1 = bot.callRemote("getSlaveInfo")
- def _got_info(info):
- log.msg("Got slaveinfo from '%s'" % self.slavename)
- # TODO: info{} might have other keys
- state["admin"] = info.get("admin")
- state["host"] = info.get("host")
- state["access_uri"] = info.get("access_uri", None)
- state["slave_environ"] = info.get("environ", {})
- state["slave_basedir"] = info.get("basedir", None)
- state["slave_system"] = info.get("system", None)
- def _info_unavailable(why):
- why.trap(pb.NoSuchMethod)
- # maybe an old slave, doesn't implement remote_getSlaveInfo
- log.msg("BuildSlave.info_unavailable")
- log.err(why)
- d1.addCallbacks(_got_info, _info_unavailable)
- return d1
- d.addCallback(_get_info)
- self.startKeepaliveTimer()
-
- def _get_version(res):
- d = bot.callRemote("getVersion")
- def _got_version(version):
- state["version"] = version
- def _version_unavailable(why):
- why.trap(pb.NoSuchMethod)
- # probably an old slave
- state["version"] = '(unknown)'
- d.addCallbacks(_got_version, _version_unavailable)
- return d
- d.addCallback(_get_version)
-
- def _get_commands(res):
- d1 = bot.callRemote("getCommands")
- def _got_commands(commands):
- state["slave_commands"] = commands
- def _commands_unavailable(why):
- # probably an old slave
- if why.check(AttributeError):
- return
- log.msg("BuildSlave.getCommands is unavailable - ignoring")
- log.err(why)
- d1.addCallbacks(_got_commands, _commands_unavailable)
- return d1
- d.addCallback(_get_commands)
-
- def _accept_slave(res):
- self.slave_status.setAdmin(state.get("admin"))
- self.slave_status.setHost(state.get("host"))
- self.slave_status.setAccessURI(state.get("access_uri"))
- self.slave_status.setVersion(state.get("version"))
- self.slave_status.setConnected(True)
- self.slave_commands = state.get("slave_commands")
- self.slave_environ = state.get("slave_environ")
- self.slave_basedir = state.get("slave_basedir")
- self.slave_system = state.get("slave_system")
- self.slave = bot
- if self.slave_system == "nt":
- self.path_module = namedModule("ntpath")
- else:
- # most eveything accepts / as separator, so posix should be a
- # reasonable fallback
- self.path_module = namedModule("posixpath")
- log.msg("bot attached")
- self.messageReceivedFromSlave()
- self.stopMissingTimer()
- self.botmaster.master.status.slaveConnected(self.slavename)
-
- return self.updateSlave()
- d.addCallback(_accept_slave)
- d.addCallback(lambda _:
- self.botmaster.maybeStartBuildsForSlave(self.slavename))
-
- # Finally, the slave gets a reference to this BuildSlave. They
- # receive this later, after we've started using them.
- d.addCallback(lambda _: self)
- return d
-
- def messageReceivedFromSlave(self):
- now = time.time()
- self.lastMessageReceived = now
- self.slave_status.setLastMessageReceived(now)
-
- def detached(self, mind):
- metrics.MetricCountEvent.log("AbstractBuildSlave.attached_slaves", -1)
- self.slave = None
- self._old_builder_list = []
- self.slave_status.removeGracefulWatcher(self._gracefulChanged)
- self.slave_status.setConnected(False)
- log.msg("BuildSlave.detached(%s)" % self.slavename)
- self.botmaster.master.status.slaveDisconnected(self.slavename)
- self.stopKeepaliveTimer()
- self.releaseLocks()
-
- # notify watchers, but do so in the next reactor iteration so that
- # any further detached() action by subclasses happens first
- def notif():
- subs = self.detached_subs
- self.detached_subs = None
- subs.deliver()
- eventually(notif)
-
- def subscribeToDetach(self, callback):
- """
- Request that C{callable} be invoked with no arguments when the
- L{detached} method is invoked.
-
- @returns: L{Subscription}
- """
- assert self.detached_subs, "detached_subs is only set if attached"
- return self.detached_subs.subscribe(callback)
-
- def disconnect(self):
- """Forcibly disconnect the slave.
-
- This severs the TCP connection and returns a Deferred that will fire
- (with None) when the connection is probably gone.
-
- If the slave is still alive, they will probably try to reconnect
- again in a moment.
-
- This is called in two circumstances. The first is when a slave is
- removed from the config file. In this case, when they try to
- reconnect, they will be rejected as an unknown slave. The second is
- when we wind up with two connections for the same slave, in which
- case we disconnect the older connection.
- """
-
- if not self.slave:
- return defer.succeed(None)
- log.msg("disconnecting old slave %s now" % self.slavename)
- # When this Deferred fires, we'll be ready to accept the new slave
- return self._disconnect(self.slave)
-
- def _disconnect(self, slave):
- # all kinds of teardown will happen as a result of
- # loseConnection(), but it happens after a reactor iteration or
- # two. Hook the actual disconnect so we can know when it is safe
- # to connect the new slave. We have to wait one additional
- # iteration (with callLater(0)) to make sure the *other*
- # notifyOnDisconnect handlers have had a chance to run.
- d = defer.Deferred()
-
- # notifyOnDisconnect runs the callback with one argument, the
- # RemoteReference being disconnected.
- def _disconnected(rref):
- eventually(d.callback, None)
- slave.notifyOnDisconnect(_disconnected)
- tport = slave.broker.transport
- # this is the polite way to request that a socket be closed
- tport.loseConnection()
- try:
- # but really we don't want to wait for the transmit queue to
- # drain. The remote end is unlikely to ACK the data, so we'd
- # probably have to wait for a (20-minute) TCP timeout.
- #tport._closeSocket()
- # however, doing _closeSocket (whether before or after
- # loseConnection) somehow prevents the notifyOnDisconnect
- # handlers from being run. Bummer.
- tport.offset = 0
- tport.dataBuffer = ""
- except:
- # however, these hacks are pretty internal, so don't blow up if
- # they fail or are unavailable
- log.msg("failed to accelerate the shutdown process")
- log.msg("waiting for slave to finish disconnecting")
-
- return d
-
- def sendBuilderList(self):
- our_builders = self.botmaster.getBuildersForSlave(self.slavename)
- blist = [(b.name, b.config.slavebuilddir) for b in our_builders]
- if blist == self._old_builder_list:
- return defer.succeed(None)
-
- d = self.slave.callRemote("setBuilderList", blist)
- def sentBuilderList(ign):
- self._old_builder_list = blist
- return ign
- d.addCallback(sentBuilderList)
- return d
-
- def perspective_keepalive(self):
- self.messageReceivedFromSlave()
-
- def perspective_shutdown(self):
- log.msg("slave %s wants to shut down" % self.slavename)
- self.slave_status.setGraceful(True)
-
- def addSlaveBuilder(self, sb):
- self.slavebuilders[sb.builder_name] = sb
-
- def removeSlaveBuilder(self, sb):
- try:
- del self.slavebuilders[sb.builder_name]
- except KeyError:
- pass
-
- def buildFinished(self, sb):
- """This is called when a build on this slave is finished."""
- self.botmaster.maybeStartBuildsForSlave(self.slavename)
-
- def canStartBuild(self):
- """
- I am called when a build is requested to see if this buildslave
- can start a build. This function can be used to limit overall
- concurrency on the buildslave.
-
- Note for subclassers: if a slave can become willing to start a build
- without any action on that slave (for example, by a resource in use on
- another slave becoming available), then you must arrange for
- L{maybeStartBuildsForSlave} to be called at that time, or builds on
- this slave will not start.
- """
-
- if self.slave_status.isPaused():
- return False
-
- # If we're waiting to shutdown gracefully, then we shouldn't
- # accept any new jobs.
- if self.slave_status.getGraceful():
- return False
-
- if self.max_builds:
- active_builders = [sb for sb in self.slavebuilders.values()
- if sb.isBusy()]
- if len(active_builders) >= self.max_builds:
- return False
-
- if not self.locksAvailable():
- return False
-
- return True
-
- def _mail_missing_message(self, subject, text):
- # first, see if we have a MailNotifier we can use. This gives us a
- # fromaddr and a relayhost.
- buildmaster = self.botmaster.master
- for st in buildmaster.status:
- if isinstance(st, MailNotifier):
- break
- else:
- # if not, they get a default MailNotifier, which always uses SMTP
- # to localhost and uses a dummy fromaddr of "buildbot".
- log.msg("buildslave-missing msg using default MailNotifier")
- st = MailNotifier("buildbot")
- # now construct the mail
-
- m = Message()
- m.set_payload(text)
- m['Date'] = formatdate(localtime=True)
- m['Subject'] = subject
- m['From'] = st.fromaddr
- recipients = self.notify_on_missing
- m['To'] = ", ".join(recipients)
- d = st.sendMessage(m, recipients)
- # return the Deferred for testing purposes
- return d
-
- def _gracefulChanged(self, graceful):
- """This is called when our graceful shutdown setting changes"""
- self.maybeShutdown()
-
- @defer.inlineCallbacks
- def shutdown(self):
- """Shutdown the slave"""
- if not self.slave:
- log.msg("no remote; slave is already shut down")
- return
-
- # First, try the "new" way - calling our own remote's shutdown
- # method. The method was only added in 0.8.3, so ignore NoSuchMethod
- # failures.
- def new_way():
- d = self.slave.callRemote('shutdown')
- d.addCallback(lambda _ : True) # successful shutdown request
- def check_nsm(f):
- f.trap(pb.NoSuchMethod)
- return False # fall through to the old way
- d.addErrback(check_nsm)
- def check_connlost(f):
- f.trap(pb.PBConnectionLost)
- return True # the slave is gone, so call it finished
- d.addErrback(check_connlost)
- return d
-
- if (yield new_way()):
- return # done!
-
- # Now, the old way. Look for a builder with a remote reference to the
- # client side slave. If we can find one, then call "shutdown" on the
- # remote builder, which will cause the slave buildbot process to exit.
- def old_way():
- d = None
- for b in self.slavebuilders.values():
- if b.remote:
- d = b.remote.callRemote("shutdown")
- break
-
- if d:
- log.msg("Shutting down (old) slave: %s" % self.slavename)
- # The remote shutdown call will not complete successfully since the
- # buildbot process exits almost immediately after getting the
- # shutdown request.
- # Here we look at the reason why the remote call failed, and if
- # it's because the connection was lost, that means the slave
- # shutdown as expected.
- def _errback(why):
- if why.check(pb.PBConnectionLost):
- log.msg("Lost connection to %s" % self.slavename)
- else:
- log.err("Unexpected error when trying to shutdown %s" % self.slavename)
- d.addErrback(_errback)
- return d
- log.err("Couldn't find remote builder to shut down slave")
- return defer.succeed(None)
- yield old_way()
-
- def maybeShutdown(self):
- """Shut down this slave if it has been asked to shut down gracefully,
- and has no active builders."""
- if not self.slave_status.getGraceful():
- return
- active_builders = [sb for sb in self.slavebuilders.values()
- if sb.isBusy()]
- if active_builders:
- return
- d = self.shutdown()
- d.addErrback(log.err, 'error while shutting down slave')
-
- def pause(self):
- """Stop running new builds on the slave."""
- self.slave_status.setPaused(True)
-
- def unpause(self):
- """Restart running new builds on the slave."""
- self.slave_status.setPaused(False)
- self.botmaster.maybeStartBuildsForSlave(self.slavename)
-
- def isPaused(self):
- return self.paused
-
-class BuildSlave(AbstractBuildSlave):
-
- def sendBuilderList(self):
- d = AbstractBuildSlave.sendBuilderList(self)
- def _sent(slist):
- # Nothing has changed, so don't need to re-attach to everything
- if not slist:
- return
- dl = []
- for name, remote in slist.items():
- # use get() since we might have changed our mind since then
- b = self.botmaster.builders.get(name)
- if b:
- d1 = b.attached(self, remote, self.slave_commands)
- dl.append(d1)
- return defer.DeferredList(dl)
- def _set_failed(why):
- log.msg("BuildSlave.sendBuilderList (%s) failed" % self)
- log.err(why)
- # TODO: hang up on them?, without setBuilderList we can't use
- # them
- d.addCallbacks(_sent, _set_failed)
- return d
-
- def detached(self, mind):
- AbstractBuildSlave.detached(self, mind)
- self.botmaster.slaveLost(self)
- self.startMissingTimer()
-
- def buildFinished(self, sb):
- """This is called when a build on this slave is finished."""
- AbstractBuildSlave.buildFinished(self, sb)
-
- # If we're gracefully shutting down, and we have no more active
- # builders, then it's safe to disconnect
- self.maybeShutdown()
-
-class AbstractLatentBuildSlave(AbstractBuildSlave):
- """A build slave that will start up a slave instance when needed.
-
- To use, subclass and implement start_instance and stop_instance.
-
- See ec2buildslave.py for a concrete example. Also see the stub example in
- test/test_slaves.py.
- """
-
- implements(ILatentBuildSlave)
-
- substantiated = False
- substantiation_deferred = None
- substantiation_build = None
- insubstantiating = False
- build_wait_timer = None
- _shutdown_callback_handle = None
-
- def __init__(self, name, password, max_builds=None,
- notify_on_missing=[], missing_timeout=60*20,
- build_wait_timeout=60*10,
- properties={}, locks=None):
- AbstractBuildSlave.__init__(
- self, name, password, max_builds, notify_on_missing,
- missing_timeout, properties, locks)
- self.building = set()
- self.build_wait_timeout = build_wait_timeout
-
- def start_instance(self, build):
- # responsible for starting instance that will try to connect with this
- # master. Should return deferred with either True (instance started)
- # or False (instance not started, so don't run a build here). Problems
- # should use an errback.
- raise NotImplementedError
-
- def stop_instance(self, fast=False):
- # responsible for shutting down instance.
- raise NotImplementedError
-
- def substantiate(self, sb, build):
- if self.substantiated:
- self._clearBuildWaitTimer()
- self._setBuildWaitTimer()
- return defer.succeed(True)
- if self.substantiation_deferred is None:
- if self.parent and not self.missing_timer:
- # start timer. if timer times out, fail deferred
- self.missing_timer = reactor.callLater(
- self.missing_timeout,
- self._substantiation_failed, defer.TimeoutError())
- self.substantiation_deferred = defer.Deferred()
- self.substantiation_build = build
- if self.slave is None:
- d = self._substantiate(build) # start up instance
- d.addErrback(log.err, "while substantiating")
- # else: we're waiting for an old one to detach. the _substantiate
- # will be done in ``detached`` below.
- return self.substantiation_deferred
-
- def _substantiate(self, build):
- # register event trigger
- d = self.start_instance(build)
- self._shutdown_callback_handle = reactor.addSystemEventTrigger(
- 'before', 'shutdown', self._soft_disconnect, fast=True)
- def start_instance_result(result):
- # If we don't report success, then preparation failed.
- if not result:
- log.msg("Slave '%s' doesn not want to substantiate at this time" % (self.slavename,))
- d = self.substantiation_deferred
- self.substantiation_deferred = None
- d.callback(False)
- return result
- def clean_up(failure):
- if self.missing_timer is not None:
- self.missing_timer.cancel()
- self._substantiation_failed(failure)
- if self._shutdown_callback_handle is not None:
- handle = self._shutdown_callback_handle
- del self._shutdown_callback_handle
- reactor.removeSystemEventTrigger(handle)
- return failure
- d.addCallbacks(start_instance_result, clean_up)
- return d
-
- def attached(self, bot):
- if self.substantiation_deferred is None and self.build_wait_timeout >= 0:
- msg = 'Slave %s received connection while not trying to ' \
- 'substantiate. Disconnecting.' % (self.slavename,)
- log.msg(msg)
- self._disconnect(bot)
- return defer.fail(RuntimeError(msg))
- return AbstractBuildSlave.attached(self, bot)
-
- def detached(self, mind):
- AbstractBuildSlave.detached(self, mind)
- if self.substantiation_deferred is not None:
- d = self._substantiate(self.substantiation_build)
- d.addErrback(log.err, 'while re-substantiating')
-
- def _substantiation_failed(self, failure):
- self.missing_timer = None
- if self.substantiation_deferred:
- d = self.substantiation_deferred
- self.substantiation_deferred = None
- self.substantiation_build = None
- d.errback(failure)
- self.insubstantiate()
- # notify people, but only if we're still in the config
- if not self.parent or not self.notify_on_missing:
- return
-
- buildmaster = self.botmaster.master
- status = buildmaster.getStatus()
- text = "The Buildbot working for '%s'\n" % status.getTitle()
- text += ("has noticed that the latent buildslave named %s \n" %
- self.slavename)
- text += "never substantiated after a request\n"
- text += "\n"
- text += ("The request was made at %s (buildmaster-local time)\n" %
- time.ctime(time.time() - self.missing_timeout)) # approx
- text += "\n"
- text += "Sincerely,\n"
- text += " The Buildbot\n"
- text += " %s\n" % status.getTitleURL()
- subject = "Buildbot: buildslave %s never substantiated" % self.slavename
- return self._mail_missing_message(subject, text)
-
- def canStartBuild(self):
- if self.insubstantiating:
- return False
- return AbstractBuildSlave.canStartBuild(self)
-
- def buildStarted(self, sb):
- assert self.substantiated
- self._clearBuildWaitTimer()
- self.building.add(sb.builder_name)
-
- def buildFinished(self, sb):
- AbstractBuildSlave.buildFinished(self, sb)
-
- self.building.remove(sb.builder_name)
- if not self.building:
- if self.build_wait_timeout == 0:
- self.insubstantiate()
- else:
- self._setBuildWaitTimer()
-
- def _clearBuildWaitTimer(self):
- if self.build_wait_timer is not None:
- if self.build_wait_timer.active():
- self.build_wait_timer.cancel()
- self.build_wait_timer = None
-
- def _setBuildWaitTimer(self):
- self._clearBuildWaitTimer()
- if self.build_wait_timeout <= 0:
- return
- self.build_wait_timer = reactor.callLater(
- self.build_wait_timeout, self._soft_disconnect)
-
- @defer.inlineCallbacks
- def insubstantiate(self, fast=False):
- self.insubstantiating = True
- self._clearBuildWaitTimer()
- d = self.stop_instance(fast)
- if self._shutdown_callback_handle is not None:
- handle = self._shutdown_callback_handle
- del self._shutdown_callback_handle
- reactor.removeSystemEventTrigger(handle)
- self.substantiated = False
- self.building.clear() # just to be sure
- yield d
- self.insubstantiating = False
-
- @defer.inlineCallbacks
- def _soft_disconnect(self, fast=False):
- # a negative build_wait_timeout means the slave should never be shut
- # down, so just disconnect.
- if self.build_wait_timeout < 0:
- yield AbstractBuildSlave.disconnect(self)
- return
-
- if self.missing_timer:
- self.missing_timer.cancel()
- self.missing_timer = None
-
- if self.substantiation_deferred is not None:
- log.msg("Weird: Got request to stop before started. Allowing "
- "slave to start cleanly to avoid inconsistent state")
- yield self.substantiation_deferred
- self.substantiation_deferred = None
- self.substantiation_build = None
- log.msg("Substantiation complete, immediately terminating.")
-
- if self.slave is not None:
- # this could be called when the slave needs to shut down, such as
- # in BotMaster.removeSlave, *or* when a new slave requests a
- # connection when we already have a slave. It's not clear what to
- # do in the second case: this shouldn't happen, and if it
- # does...if it's a latent slave, shutting down will probably kill
- # something we want...but we can't know what the status is. So,
- # here, we just do what should be appropriate for the first case,
- # and put our heads in the sand for the second, at least for now.
- # The best solution to the odd situation is removing it as a
- # possibility: make the master in charge of connecting to the
- # slave, rather than vice versa. TODO.
- yield defer.DeferredList([
- AbstractBuildSlave.disconnect(self),
- self.insubstantiate(fast)
- ], consumeErrors=True, fireOnOneErrback=True)
- else:
- yield AbstractBuildSlave.disconnect(self)
- yield self.stop_instance(fast)
-
- def disconnect(self):
- # This returns a Deferred but we don't use it
- self._soft_disconnect()
- # this removes the slave from all builders. It won't come back
- # without a restart (or maybe a sighup)
- self.botmaster.slaveLost(self)
-
- def stopService(self):
- res = defer.maybeDeferred(AbstractBuildSlave.stopService, self)
- if self.slave is not None:
- d = self._soft_disconnect()
- res = defer.DeferredList([res, d])
- return res
-
- def updateSlave(self):
- """Called to add or remove builders after the slave has connected.
-
- Also called after botmaster's builders are initially set.
-
- @return: a Deferred that indicates when an attached slave has
- accepted the new builders and/or released the old ones."""
- for b in self.botmaster.getBuildersForSlave(self.slavename):
- if b.name not in self.slavebuilders:
- b.addLatentSlave(self)
- return AbstractBuildSlave.updateSlave(self)
-
- def sendBuilderList(self):
- d = AbstractBuildSlave.sendBuilderList(self)
- def _sent(slist):
- if not slist:
- return
- dl = []
- for name, remote in slist.items():
- # use get() since we might have changed our mind since then.
- # we're checking on the builder in addition to the
- # slavebuilders out of a bit of paranoia.
- b = self.botmaster.builders.get(name)
- sb = self.slavebuilders.get(name)
- if b and sb:
- d1 = sb.attached(self, remote, self.slave_commands)
- dl.append(d1)
- return defer.DeferredList(dl)
- def _set_failed(why):
- log.msg("BuildSlave.sendBuilderList (%s) failed" % self)
- log.err(why)
- # TODO: hang up on them?, without setBuilderList we can't use
- # them
- if self.substantiation_deferred:
- d = self.substantiation_deferred
- self.substantiation_deferred = None
- self.substantiation_build = None
- d.errback(why)
- if self.missing_timer:
- self.missing_timer.cancel()
- self.missing_timer = None
- # TODO: maybe log? send an email?
- return why
- d.addCallbacks(_sent, _set_failed)
- def _substantiated(res):
- log.msg("Slave %s substantiated \o/" % self.slavename)
- self.substantiated = True
- if not self.substantiation_deferred:
- log.msg("No substantiation deferred for %s" % self.slavename)
- if self.substantiation_deferred:
- log.msg("Firing %s substantiation deferred with success" % self.slavename)
- d = self.substantiation_deferred
- self.substantiation_deferred = None
- self.substantiation_build = None
- d.callback(True)
- # note that the missing_timer is already handled within
- # ``attached``
- if not self.building:
- self._setBuildWaitTimer()
- d.addCallback(_substantiated)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/ec2.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/ec2.py
deleted file mode 100644
index f144321b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/ec2.py
+++ /dev/null
@@ -1,319 +0,0 @@
-# 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.
-#
-# Portions Copyright Buildbot Team Members
-
-from __future__ import with_statement
-# Portions Copyright Canonical Ltd. 2009
-
-"""A LatentSlave that uses EC2 to instantiate the slaves on demand.
-
-Tested with Python boto 1.5c
-"""
-
-import os
-import re
-import time
-
-import boto
-import boto.ec2
-import boto.exception
-from twisted.internet import defer, threads
-from twisted.python import log
-
-from buildbot.buildslave.base import AbstractLatentBuildSlave
-from buildbot import interfaces
-
-PENDING = 'pending'
-RUNNING = 'running'
-SHUTTINGDOWN = 'shutting-down'
-TERMINATED = 'terminated'
-
-class EC2LatentBuildSlave(AbstractLatentBuildSlave):
-
- instance = image = None
- _poll_resolution = 5 # hook point for tests
-
- def __init__(self, name, password, instance_type, ami=None,
- valid_ami_owners=None, valid_ami_location_regex=None,
- elastic_ip=None, identifier=None, secret_identifier=None,
- aws_id_file_path=None, user_data=None, region=None,
- keypair_name='latent_buildbot_slave',
- security_name='latent_buildbot_slave',
- max_builds=None, notify_on_missing=[], missing_timeout=60*20,
- build_wait_timeout=60*10, properties={}, locks=None):
-
- AbstractLatentBuildSlave.__init__(
- self, name, password, max_builds, notify_on_missing,
- missing_timeout, build_wait_timeout, properties, locks)
- if not ((ami is not None) ^
- (valid_ami_owners is not None or
- valid_ami_location_regex is not None)):
- raise ValueError(
- 'You must provide either a specific ami, or one or both of '
- 'valid_ami_location_regex and valid_ami_owners')
- self.ami = ami
- if valid_ami_owners is not None:
- if isinstance(valid_ami_owners, (int, long)):
- valid_ami_owners = (valid_ami_owners,)
- else:
- for element in valid_ami_owners:
- if not isinstance(element, (int, long)):
- raise ValueError(
- 'valid_ami_owners should be int or iterable '
- 'of ints', element)
- if valid_ami_location_regex is not None:
- if not isinstance(valid_ami_location_regex, basestring):
- raise ValueError(
- 'valid_ami_location_regex should be a string')
- else:
- # verify that regex will compile
- re.compile(valid_ami_location_regex)
- self.valid_ami_owners = valid_ami_owners
- self.valid_ami_location_regex = valid_ami_location_regex
- self.instance_type = instance_type
- self.keypair_name = keypair_name
- self.security_name = security_name
- self.user_data = user_data
- if identifier is None:
- assert secret_identifier is None, (
- 'supply both or neither of identifier, secret_identifier')
- if aws_id_file_path is None:
- home = os.environ['HOME']
- aws_id_file_path = os.path.join(home, '.ec2', 'aws_id')
- if not os.path.exists(aws_id_file_path):
- raise ValueError(
- "Please supply your AWS access key identifier and secret "
- "access key identifier either when instantiating this %s "
- "or in the %s file (on two lines).\n" %
- (self.__class__.__name__, aws_id_file_path))
- with open(aws_id_file_path, 'r') as aws_file:
- identifier = aws_file.readline().strip()
- secret_identifier = aws_file.readline().strip()
- else:
- assert aws_id_file_path is None, \
- 'if you supply the identifier and secret_identifier, ' \
- 'do not specify the aws_id_file_path'
- assert secret_identifier is not None, \
- 'supply both or neither of identifier, secret_identifier'
-
- region_found = None
-
- # Make the EC2 connection.
- if region is not None:
- for r in boto.ec2.regions(aws_access_key_id=identifier,
- aws_secret_access_key=secret_identifier):
-
- if r.name == region:
- region_found = r
-
-
- if region_found is not None:
- self.conn = boto.ec2.connect_to_region(region,
- aws_access_key_id=identifier,
- aws_secret_access_key=secret_identifier)
- else:
- raise ValueError('The specified region does not exist: {0}'.format(region))
-
- else:
- self.conn = boto.connect_ec2(identifier, secret_identifier)
-
- # Make a keypair
- #
- # We currently discard the keypair data because we don't need it.
- # If we do need it in the future, we will always recreate the keypairs
- # because there is no way to
- # programmatically retrieve the private key component, unless we
- # generate it and store it on the filesystem, which is an unnecessary
- # usage requirement.
- try:
- key_pair = self.conn.get_all_key_pairs(keypair_name)[0]
- assert key_pair
- # key_pair.delete() # would be used to recreate
- except boto.exception.EC2ResponseError, e:
- if 'InvalidKeyPair.NotFound' not in e.body:
- if 'AuthFailure' in e.body:
- print ('POSSIBLE CAUSES OF ERROR:\n'
- ' Did you sign up for EC2?\n'
- ' Did you put a credit card number in your AWS '
- 'account?\n'
- 'Please doublecheck before reporting a problem.\n')
- raise
- # make one; we would always do this, and stash the result, if we
- # needed the key (for instance, to SSH to the box). We'd then
- # use paramiko to use the key to connect.
- self.conn.create_key_pair(keypair_name)
-
- # create security group
- try:
- group = self.conn.get_all_security_groups(security_name)[0]
- assert group
- except boto.exception.EC2ResponseError, e:
- if 'InvalidGroup.NotFound' in e.body:
- self.security_group = self.conn.create_security_group(
- security_name,
- 'Authorization to access the buildbot instance.')
- # Authorize the master as necessary
- # TODO this is where we'd open the hole to do the reverse pb
- # connect to the buildbot
- # ip = urllib.urlopen(
- # 'http://checkip.amazonaws.com').read().strip()
- # self.security_group.authorize('tcp', 22, 22, '%s/32' % ip)
- # self.security_group.authorize('tcp', 80, 80, '%s/32' % ip)
- else:
- raise
-
- # get the image
- if self.ami is not None:
- self.image = self.conn.get_image(self.ami)
- else:
- # verify we have access to at least one acceptable image
- discard = self.get_image()
- assert discard
-
- # get the specified elastic IP, if any
- if elastic_ip is not None:
- elastic_ip = self.conn.get_all_addresses([elastic_ip])[0]
- self.elastic_ip = elastic_ip
-
- def get_image(self):
- if self.image is not None:
- return self.image
- if self.valid_ami_location_regex:
- level = 0
- options = []
- get_match = re.compile(self.valid_ami_location_regex).match
- for image in self.conn.get_all_images(
- owners=self.valid_ami_owners):
- # gather sorting data
- match = get_match(image.location)
- if match:
- alpha_sort = int_sort = None
- if level < 2:
- try:
- alpha_sort = match.group(1)
- except IndexError:
- level = 2
- else:
- if level == 0:
- try:
- int_sort = int(alpha_sort)
- except ValueError:
- level = 1
- options.append([int_sort, alpha_sort,
- image.location, image.id, image])
- if level:
- log.msg('sorting images at level %d' % level)
- options = [candidate[level:] for candidate in options]
- else:
- options = [(image.location, image.id, image) for image
- in self.conn.get_all_images(
- owners=self.valid_ami_owners)]
- options.sort()
- log.msg('sorted images (last is chosen): %s' %
- (', '.join(
- ['%s (%s)' % (candidate[-1].id, candidate[-1].location)
- for candidate in options])))
- if not options:
- raise ValueError('no available images match constraints')
- return options[-1][-1]
-
- def dns(self):
- if self.instance is None:
- return None
- return self.instance.public_dns_name
- dns = property(dns)
-
- def start_instance(self, build):
- if self.instance is not None:
- raise ValueError('instance active')
- return threads.deferToThread(self._start_instance)
-
- def _start_instance(self):
- image = self.get_image()
- reservation = image.run(
- key_name=self.keypair_name, security_groups=[self.security_name],
- instance_type=self.instance_type, user_data=self.user_data)
- self.instance = reservation.instances[0]
- log.msg('%s %s starting instance %s' %
- (self.__class__.__name__, self.slavename, self.instance.id))
- duration = 0
- interval = self._poll_resolution
- while self.instance.state == PENDING:
- time.sleep(interval)
- duration += interval
- if duration % 60 == 0:
- log.msg('%s %s has waited %d minutes for instance %s' %
- (self.__class__.__name__, self.slavename, duration//60,
- self.instance.id))
- self.instance.update()
- if self.instance.state == RUNNING:
- self.output = self.instance.get_console_output()
- minutes = duration//60
- seconds = duration%60
- log.msg('%s %s instance %s started on %s '
- 'in about %d minutes %d seconds (%s)' %
- (self.__class__.__name__, self.slavename,
- self.instance.id, self.dns, minutes, seconds,
- self.output.output))
- if self.elastic_ip is not None:
- self.instance.use_ip(self.elastic_ip)
- return [self.instance.id,
- image.id,
- '%02d:%02d:%02d' % (minutes//60, minutes%60, seconds)]
- else:
- log.msg('%s %s failed to start instance %s (%s)' %
- (self.__class__.__name__, self.slavename,
- self.instance.id, self.instance.state))
- raise interfaces.LatentBuildSlaveFailedToSubstantiate(
- self.instance.id, self.instance.state)
-
- def stop_instance(self, fast=False):
- if self.instance is None:
- # be gentle. Something may just be trying to alert us that an
- # instance never attached, and it's because, somehow, we never
- # started.
- return defer.succeed(None)
- instance = self.instance
- self.output = self.instance = None
- return threads.deferToThread(
- self._stop_instance, instance, fast)
-
- def _stop_instance(self, instance, fast):
- if self.elastic_ip is not None:
- self.conn.disassociate_address(self.elastic_ip.public_ip)
- instance.update()
- if instance.state not in (SHUTTINGDOWN, TERMINATED):
- instance.terminate()
- log.msg('%s %s terminating instance %s' %
- (self.__class__.__name__, self.slavename, instance.id))
- duration = 0
- interval = self._poll_resolution
- if fast:
- goal = (SHUTTINGDOWN, TERMINATED)
- instance.update()
- else:
- goal = (TERMINATED,)
- while instance.state not in goal:
- time.sleep(interval)
- duration += interval
- if duration % 60 == 0:
- log.msg(
- '%s %s has waited %d minutes for instance %s to end' %
- (self.__class__.__name__, self.slavename, duration//60,
- instance.id))
- instance.update()
- log.msg('%s %s instance %s %s '
- 'after about %d minutes %d seconds' %
- (self.__class__.__name__, self.slavename,
- instance.id, goal, duration//60, duration%60))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/libvirt.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/libvirt.py
deleted file mode 100644
index 5776f10d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/libvirt.py
+++ /dev/null
@@ -1,302 +0,0 @@
-# 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.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright 2010 Isotoma Limited
-
-from __future__ import absolute_import
-import os
-
-from twisted.internet import defer, utils, threads
-from twisted.python import log, failure
-from buildbot.buildslave.base import AbstractBuildSlave, AbstractLatentBuildSlave
-from buildbot.util.eventual import eventually
-from buildbot import config
-
-try:
- import libvirt
- libvirt = libvirt
-except ImportError:
- libvirt = None
-
-
-class WorkQueue(object):
- """
- I am a class that turns parallel access into serial access.
-
- I exist because we want to run libvirt access in threads as we don't
- trust calls not to block, but under load libvirt doesn't seem to like
- this kind of threaded use.
- """
-
- def __init__(self):
- self.queue = []
-
- def _process(self):
- log.msg("Looking to start a piece of work now...")
-
- # Is there anything to do?
- if not self.queue:
- log.msg("_process called when there is no work")
- return
-
- # Peek at the top of the stack - get a function to call and
- # a deferred to fire when its all over
- d, next_operation, args, kwargs = self.queue[0]
-
- # Start doing some work - expects a deferred
- try:
- d2 = next_operation(*args, **kwargs)
- except:
- d2 = defer.fail()
-
- # Whenever a piece of work is done, whether it worked or not
- # call this to schedule the next piece of work
- def _work_done(res):
- log.msg("Completed a piece of work")
- self.queue.pop(0)
- if self.queue:
- log.msg("Preparing next piece of work")
- eventually(self._process)
- return res
- d2.addBoth(_work_done)
-
- # When the work is done, trigger d
- d2.chainDeferred(d)
-
- def execute(self, cb, *args, **kwargs):
- kickstart_processing = not self.queue
- d = defer.Deferred()
- self.queue.append((d, cb, args, kwargs))
- if kickstart_processing:
- self._process()
- return d
-
- def executeInThread(self, cb, *args, **kwargs):
- return self.execute(threads.deferToThread, cb, *args, **kwargs)
-
-
-# A module is effectively a singleton class, so this is OK
-queue = WorkQueue()
-
-
-class Domain(object):
-
- """
- I am a wrapper around a libvirt Domain object
- """
-
- def __init__(self, connection, domain):
- self.connection = connection
- self.domain = domain
-
- def name(self):
- return queue.executeInThread(self.domain.name)
-
- def create(self):
- return queue.executeInThread(self.domain.create)
-
- def shutdown(self):
- return queue.executeInThread(self.domain.shutdown)
-
- def destroy(self):
- return queue.executeInThread(self.domain.destroy)
-
-
-class Connection(object):
-
- """
- I am a wrapper around a libvirt Connection object.
- """
-
- DomainClass = Domain
-
- def __init__(self, uri):
- self.uri = uri
- self.connection = libvirt.open(uri)
-
- @defer.inlineCallbacks
- def lookupByName(self, name):
- """ I lookup an existing predefined domain """
- res = yield queue.executeInThread(self.connection.lookupByName, name)
- defer.returnValue(self.DomainClass(self, res))
-
- @defer.inlineCallbacks
- def create(self, xml):
- """ I take libvirt XML and start a new VM """
- res = yield queue.executeInThread(self.connection.createXML, xml, 0)
- defer.returnValue(self.DomainClass(self, res))
-
- @defer.inlineCallbacks
- def all(self):
- domains = []
- domain_ids = yield queue.executeInThread(self.connection.listDomainsID)
-
- for did in domain_ids:
- domain = yield queue.executeInThread(self.connection.lookupByID, did)
- domains.append(self.DomainClass(self, domain))
-
- defer.returnValue(domains)
-
-
-class LibVirtSlave(AbstractLatentBuildSlave):
-
- def __init__(self, name, password, connection, hd_image, base_image = None, xml=None, max_builds=None, notify_on_missing=[],
- missing_timeout=60*20, build_wait_timeout=60*10, properties={}, locks=None):
- AbstractLatentBuildSlave.__init__(self, name, password, max_builds, notify_on_missing,
- missing_timeout, build_wait_timeout, properties, locks)
-
- if not libvirt:
- config.error("The python module 'libvirt' is needed to use a LibVirtSlave")
-
- self.name = name
- self.connection = connection
- self.image = hd_image
- self.base_image = base_image
- self.xml = xml
-
- self.cheap_copy = True
- self.graceful_shutdown = False
-
- self.domain = None
-
- self.ready = False
- self._find_existing_deferred = self._find_existing_instance()
-
- @defer.inlineCallbacks
- def _find_existing_instance(self):
- """
- I find existing VMs that are already running that might be orphaned instances of this slave.
- """
- if not self.connection:
- defer.returnValue(None)
-
- domains = yield self.connection.all()
- for d in domains:
- name = yield d.name()
- if name.startswith(self.name):
- self.domain = d
- self.substantiated = True
- break
-
- self.ready = True
-
- def canStartBuild(self):
- if not self.ready:
- log.msg("Not accepting builds as existing domains not iterated")
- return False
-
- if self.domain and not self.isConnected():
- log.msg("Not accepting builds as existing domain but slave not connected")
- return False
-
- return AbstractLatentBuildSlave.canStartBuild(self)
-
- def _prepare_base_image(self):
- """
- I am a private method for creating (possibly cheap) copies of a
- base_image for start_instance to boot.
- """
- if not self.base_image:
- return defer.succeed(True)
-
- if self.cheap_copy:
- clone_cmd = "qemu-img"
- clone_args = "create -b %(base)s -f qcow2 %(image)s"
- else:
- clone_cmd = "cp"
- clone_args = "%(base)s %(image)s"
-
- clone_args = clone_args % {
- "base": self.base_image,
- "image": self.image,
- }
-
- log.msg("Cloning base image: %s %s'" % (clone_cmd, clone_args))
-
- def _log_result(res):
- log.msg("Cloning exit code was: %d" % res)
- return res
-
- d = utils.getProcessValue(clone_cmd, clone_args.split())
- d.addBoth(_log_result)
- return d
-
- @defer.inlineCallbacks
- def start_instance(self, build):
- """
- I start a new instance of a VM.
-
- If a base_image is specified, I will make a clone of that otherwise i will
- use image directly.
-
- If i'm not given libvirt domain definition XML, I will look for my name
- in the list of defined virtual machines and start that.
- """
- if self.domain is not None:
- log.msg("Cannot start_instance '%s' as already active" % self.name)
- defer.returnValue(False)
-
- yield self._prepare_base_image()
-
- try:
- if self.xml:
- self.domain = yield self.connection.create(self.xml)
- else:
- self.domain = yield self.connection.lookupByName(self.name)
- yield self.domain.create()
- except:
- log.err(failure.Failure(),
- "Cannot start a VM (%s), failing gracefully and triggering"
- "a new build check" % self.name)
- self.domain = None
- defer.returnValue(False)
-
- defer.returnValue(True)
-
- def stop_instance(self, fast=False):
- """
- I attempt to stop a running VM.
- I make sure any connection to the slave is removed.
- If the VM was using a cloned image, I remove the clone
- When everything is tidied up, I ask that bbot looks for work to do
- """
- log.msg("Attempting to stop '%s'" % self.name)
- if self.domain is None:
- log.msg("I don't think that domain is even running, aborting")
- return defer.succeed(None)
-
- domain = self.domain
- self.domain = None
-
- if self.graceful_shutdown and not fast:
- log.msg("Graceful shutdown chosen for %s" % self.name)
- d = domain.shutdown()
- else:
- d = domain.destroy()
-
- def _disconnect(res):
- log.msg("VM destroyed (%s): Forcing its connection closed." % self.name)
- return AbstractBuildSlave.disconnect(self)
- d.addCallback(_disconnect)
-
- def _disconnected(res):
- log.msg("We forced disconnection (%s), cleaning up and triggering new build" % self.name)
- if self.base_image:
- os.remove(self.image)
- self.botmaster.maybeStartBuildsForSlave(self.name)
- return res
- d.addBoth(_disconnected)
-
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/openstack.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/openstack.py
deleted file mode 100644
index ec5c4861..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/buildslave/openstack.py
+++ /dev/null
@@ -1,183 +0,0 @@
-# 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.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright 2013 Cray Inc.
-
-import time
-
-from twisted.internet import defer, threads
-from twisted.python import log
-
-from buildbot.buildslave.base import AbstractLatentBuildSlave
-from buildbot import config, interfaces
-
-try:
- import novaclient.exceptions as nce
- from novaclient.v1_1 import client
- _hush_pyflakes = [nce, client]
-except ImportError:
- nce = None
- client = None
-
-
-ACTIVE = 'ACTIVE'
-BUILD = 'BUILD'
-DELETED = 'DELETED'
-UNKNOWN = 'UNKNOWN'
-
-class OpenStackLatentBuildSlave(AbstractLatentBuildSlave):
-
- instance = None
- _poll_resolution = 5 # hook point for tests
-
- def __init__(self, name, password,
- flavor,
- image,
- os_username,
- os_password,
- os_tenant_name,
- os_auth_url,
- meta=None,
- max_builds=None, notify_on_missing=[], missing_timeout=60*20,
- build_wait_timeout=60*10, properties={}, locks=None):
-
- if not client or not nce:
- config.error("The python module 'novaclient' is needed "
- "to use a OpenStackLatentBuildSlave")
-
- AbstractLatentBuildSlave.__init__(
- self, name, password, max_builds, notify_on_missing,
- missing_timeout, build_wait_timeout, properties, locks)
- self.flavor = flavor
- self.image = image
- self.os_username = os_username
- self.os_password = os_password
- self.os_tenant_name = os_tenant_name
- self.os_auth_url = os_auth_url
- self.meta = meta
-
- def _getImage(self, os_client):
- # If self.image is a callable, then pass it the list of images. The
- # function should return the image's UUID to use.
- if callable(self.image):
- image_uuid = self.image(os_client.images.list())
- else:
- image_uuid = self.image
- return image_uuid
-
- def start_instance(self, build):
- if self.instance is not None:
- raise ValueError('instance active')
- return threads.deferToThread(self._start_instance)
-
- def _start_instance(self):
- # Authenticate to OpenStack.
- os_client = client.Client(self.os_username, self.os_password,
- self.os_tenant_name, self.os_auth_url)
- image_uuid = self._getImage(os_client)
- flavor_id = self.flavor
- boot_args = [self.slavename, image_uuid, flavor_id]
- boot_kwargs = {}
- if self.meta is not None:
- boot_kwargs['meta'] = self.meta
- self.instance = os_client.servers.create(*boot_args, **boot_kwargs)
- log.msg('%s %s starting instance %s (image %s)' %
- (self.__class__.__name__, self.slavename, self.instance.id,
- image_uuid))
- duration = 0
- interval = self._poll_resolution
- inst = self.instance
- while inst.status == BUILD:
- time.sleep(interval)
- duration += interval
- if duration % 60 == 0:
- log.msg('%s %s has waited %d minutes for instance %s' %
- (self.__class__.__name__, self.slavename, duration//60,
- self.instance.id))
- try:
- inst = os_client.servers.get(self.instance.id)
- except nce.NotFound:
- log.msg('%s %s instance %s (%s) went missing' %
- (self.__class__.__name__, self.slavename,
- self.instance.id, self.instance.name))
- raise interfaces.LatentBuildSlaveFailedToSubstantiate(
- self.instance.id, self.instance.status)
- if inst.status == ACTIVE:
- minutes = duration//60
- seconds = duration%60
- log.msg('%s %s instance %s (%s) started '
- 'in about %d minutes %d seconds' %
- (self.__class__.__name__, self.slavename,
- self.instance.id, self.instance.name, minutes, seconds))
- return [self.instance.id, image_uuid,
- '%02d:%02d:%02d' % (minutes//60, minutes%60, seconds)]
- else:
- log.msg('%s %s failed to start instance %s (%s)' %
- (self.__class__.__name__, self.slavename,
- self.instance.id, inst.status))
- raise interfaces.LatentBuildSlaveFailedToSubstantiate(
- self.instance.id, self.instance.status)
-
- def stop_instance(self, fast=False):
- if self.instance is None:
- # be gentle. Something may just be trying to alert us that an
- # instance never attached, and it's because, somehow, we never
- # started.
- return defer.succeed(None)
- instance = self.instance
- self.instance = None
- return threads.deferToThread(self._stop_instance, instance, fast)
-
- def _stop_instance(self, instance, fast):
- # Authenticate to OpenStack. This is needed since it seems the update
- # method doesn't do a whole lot of updating right now.
- os_client = client.Client(self.os_username, self.os_password,
- self.os_tenant_name, self.os_auth_url)
- # When the update method does work, replace the lines like below with
- # instance.update().
- try:
- inst = os_client.servers.get(instance.id)
- except nce.NotFound:
- # If can't find the instance, then it's already gone.
- log.msg('%s %s instance %s (%s) already terminated' %
- (self.__class__.__name__, self.slavename, instance.id,
- instance.name))
- return
- if inst.status not in (DELETED, UNKNOWN):
- inst.delete()
- log.msg('%s %s terminating instance %s (%s)' %
- (self.__class__.__name__, self.slavename, instance.id,
- instance.name))
- duration = 0
- interval = self._poll_resolution
- if fast:
- goal = (DELETED, UNKNOWN)
- else:
- goal = (DELETED,)
- while inst.status not in goal:
- time.sleep(interval)
- duration += interval
- if duration % 60 == 0:
- log.msg(
- '%s %s has waited %d minutes for instance %s to end' %
- (self.__class__.__name__, self.slavename, duration//60,
- instance.id))
- try:
- inst = os_client.servers.get(instance.id)
- except nce.NotFound:
- break
- log.msg('%s %s instance %s %s '
- 'after about %d minutes %d seconds' %
- (self.__class__.__name__, self.slavename,
- instance.id, goal, duration//60, duration%60))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/base.py
deleted file mode 100644
index 496f5787..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/base.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# 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
-
-from zope.interface import implements
-from twisted.application import service
-from twisted.internet import defer, task, reactor
-from twisted.python import log
-
-from buildbot.interfaces import IChangeSource
-from buildbot import util
-
-class ChangeSource(service.Service, util.ComparableMixin):
- implements(IChangeSource)
-
- master = None
- "if C{self.running} is true, then C{cs.master} points to the buildmaster."
-
- def describe(self):
- pass
-
-class PollingChangeSource(ChangeSource):
- """
- Utility subclass for ChangeSources that use some kind of periodic polling
- operation. Subclasses should define C{poll} and set C{self.pollInterval}.
- The rest is taken care of.
-
- Any subclass will be available via the "poller" webhook.
- """
-
- pollInterval = 60
- "time (in seconds) between calls to C{poll}"
-
- _loop = None
-
- def __init__(self, name=None, pollInterval=60*10):
- if name:
- self.setName(name)
- self.pollInterval = pollInterval
-
- self.doPoll = util.misc.SerializedInvocation(self.doPoll)
-
- def doPoll(self):
- """
- This is the method that is called by LoopingCall to actually poll.
- It may also be called by change hooks to request a poll.
- It is serialiazed - if you call it while a poll is in progress
- then the 2nd invocation won't start until the 1st has finished.
- """
- d = defer.maybeDeferred(self.poll)
- d.addErrback(log.err, 'while polling for changes')
- return d
-
- def poll(self):
- """
- Perform the polling operation, and return a deferred that will fire
- when the operation is complete. Failures will be logged, but the
- method will be called again after C{pollInterval} seconds.
- """
-
- def startLoop(self):
- self._loop = task.LoopingCall(self.doPoll)
- self._loop.start(self.pollInterval, now=False)
-
- def stopLoop(self):
- if self._loop and self._loop.running:
- self._loop.stop()
- self._loop = None
-
- def startService(self):
- ChangeSource.startService(self)
-
- # delay starting doing anything until the reactor is running - if
- # services are still starting up, they may miss an initial flood of
- # changes
- if self.pollInterval:
- reactor.callWhenRunning(self.startLoop)
- else:
- reactor.callWhenRunning(self.doPoll)
-
- def stopService(self):
- self.stopLoop()
- return ChangeSource.stopService(self)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/bonsaipoller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/bonsaipoller.py
deleted file mode 100644
index 76afcaa4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/bonsaipoller.py
+++ /dev/null
@@ -1,277 +0,0 @@
-# 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 time
-from xml.dom import minidom
-
-from twisted.python import log
-from twisted.internet import defer
-from twisted.web import client
-
-from buildbot.changes import base
-from buildbot.util import epoch2datetime
-
-class InvalidResultError(Exception):
- def __init__(self, value="InvalidResultError"):
- self.value = value
- def __str__(self):
- return repr(self.value)
-
-class EmptyResult(Exception):
- pass
-
-class NoMoreCiNodes(Exception):
- pass
-
-class NoMoreFileNodes(Exception):
- pass
-
-class BonsaiResult:
- """I hold a list of CiNodes"""
- def __init__(self, nodes=[]):
- self.nodes = nodes
-
- def __cmp__(self, other):
- if len(self.nodes) != len(other.nodes):
- return False
- for i in range(len(self.nodes)):
- if self.nodes[i].log != other.nodes[i].log \
- or self.nodes[i].who != other.nodes[i].who \
- or self.nodes[i].date != other.nodes[i].date \
- or len(self.nodes[i].files) != len(other.nodes[i].files):
- return -1
-
- for j in range(len(self.nodes[i].files)):
- if self.nodes[i].files[j].revision \
- != other.nodes[i].files[j].revision \
- or self.nodes[i].files[j].filename \
- != other.nodes[i].files[j].filename:
- return -1
-
- return 0
-
-class CiNode:
- """I hold information baout one <ci> node, including a list of files"""
- def __init__(self, log="", who="", date=0, files=[]):
- self.log = log
- self.who = who
- self.date = date
- self.files = files
-
-class FileNode:
- """I hold information about one <f> node"""
- def __init__(self, revision="", filename=""):
- self.revision = revision
- self.filename = filename
-
-class BonsaiParser:
- """I parse the XML result from a bonsai cvsquery."""
-
- def __init__(self, data):
- try:
- # this is a fix for non-ascii characters
- # because bonsai does not give us an encoding to work with
- # it impossible to be 100% sure what to decode it as but latin1 covers
- # the broadest base
- data = data.decode("latin1")
- data = data.encode("ascii", "replace")
- self.dom = minidom.parseString(data)
- log.msg(data)
- except:
- raise InvalidResultError("Malformed XML in result")
-
- self.ciNodes = self.dom.getElementsByTagName("ci")
- self.currentCiNode = None # filled in by _nextCiNode()
- self.fileNodes = None # filled in by _nextCiNode()
- self.currentFileNode = None # filled in by _nextFileNode()
- self.bonsaiResult = self._parseData()
-
- def getData(self):
- return self.bonsaiResult
-
- def _parseData(self):
- """Returns data from a Bonsai cvsquery in a BonsaiResult object"""
- nodes = []
- try:
- while self._nextCiNode():
- files = []
- try:
- while self._nextFileNode():
- files.append(FileNode(self._getRevision(),
- self._getFilename()))
- except NoMoreFileNodes:
- pass
- except InvalidResultError:
- raise
- cinode = CiNode(self._getLog(), self._getWho(),
- self._getDate(), files)
- # hack around bonsai xml output bug for empty check-in comments
- if not cinode.log and nodes and \
- not nodes[-1].log and \
- cinode.who == nodes[-1].who and \
- cinode.date == nodes[-1].date:
- nodes[-1].files += cinode.files
- else:
- nodes.append(cinode)
-
- except NoMoreCiNodes:
- pass
- except (InvalidResultError, EmptyResult):
- raise
-
- return BonsaiResult(nodes)
-
-
- def _nextCiNode(self):
- """Iterates to the next <ci> node and fills self.fileNodes with
- child <f> nodes"""
- try:
- self.currentCiNode = self.ciNodes.pop(0)
- if len(self.currentCiNode.getElementsByTagName("files")) > 1:
- raise InvalidResultError("Multiple <files> for one <ci>")
-
- self.fileNodes = self.currentCiNode.getElementsByTagName("f")
- except IndexError:
- # if there was zero <ci> nodes in the result
- if not self.currentCiNode:
- raise EmptyResult
- else:
- raise NoMoreCiNodes
-
- return True
-
- def _nextFileNode(self):
- """Iterates to the next <f> node"""
- try:
- self.currentFileNode = self.fileNodes.pop(0)
- except IndexError:
- raise NoMoreFileNodes
-
- return True
-
- def _getLog(self):
- """Returns the log of the current <ci> node"""
- logs = self.currentCiNode.getElementsByTagName("log")
- if len(logs) < 1:
- raise InvalidResultError("No log present")
- elif len(logs) > 1:
- raise InvalidResultError("Multiple logs present")
-
- # catch empty check-in comments
- if logs[0].firstChild:
- return logs[0].firstChild.data
- return ''
-
- def _getWho(self):
- """Returns the e-mail address of the commiter"""
- # convert unicode string to regular string
- return str(self.currentCiNode.getAttribute("who"))
-
- def _getDate(self):
- """Returns the date (unix time) of the commit"""
- # convert unicode number to regular one
- try:
- commitDate = int(self.currentCiNode.getAttribute("date"))
- except ValueError:
- raise InvalidResultError
-
- return commitDate
-
- def _getFilename(self):
- """Returns the filename of the current <f> node"""
- try:
- filename = self.currentFileNode.firstChild.data
- except AttributeError:
- raise InvalidResultError("Missing filename")
-
- return filename
-
- def _getRevision(self):
- return self.currentFileNode.getAttribute("rev")
-
-
-class BonsaiPoller(base.PollingChangeSource):
- compare_attrs = ["bonsaiURL", "pollInterval", "tree",
- "module", "branch", "cvsroot"]
-
- def __init__(self, bonsaiURL, module, branch, tree="default",
- cvsroot="/cvsroot", pollInterval=30, project=''):
-
- base.PollingChangeSource.__init__(self, name=bonsaiURL, pollInterval=pollInterval)
-
- self.bonsaiURL = bonsaiURL
- self.module = module
- self.branch = branch
- self.tree = tree
- self.cvsroot = cvsroot
- self.repository = module != 'all' and module or ''
- self.lastChange = time.time()
- self.lastPoll = time.time()
-
- def describe(self):
- str = ""
- str += "Getting changes from the Bonsai service running at %s " \
- % self.bonsaiURL
- str += "<br>Using tree: %s, branch: %s, and module: %s" % (self.tree, \
- self.branch, self.module)
- return str
-
- def poll(self):
- d = self._get_changes()
- d.addCallback(self._process_changes)
- return d
-
- def _make_url(self):
- args = ["treeid=%s" % self.tree, "module=%s" % self.module,
- "branch=%s" % self.branch, "branchtype=match",
- "sortby=Date", "date=explicit",
- "mindate=%d" % self.lastChange,
- "maxdate=%d" % int(time.time()),
- "cvsroot=%s" % self.cvsroot, "xml=1"]
- # build the bonsai URL
- url = self.bonsaiURL
- url += "/cvsquery.cgi?"
- url += "&".join(args)
-
- return url
-
- def _get_changes(self):
- url = self._make_url()
- log.msg("Polling Bonsai tree at %s" % url)
-
- self.lastPoll = time.time()
- # get the page, in XML format
- return client.getPage(url, timeout=self.pollInterval)
-
- @defer.inlineCallbacks
- def _process_changes(self, query):
- try:
- bp = BonsaiParser(query)
- result = bp.getData()
- except InvalidResultError, e:
- log.msg("Could not process Bonsai query: " + e.value)
- return
- except EmptyResult:
- return
-
- for cinode in result.nodes:
- files = [file.filename + ' (revision '+file.revision+')'
- for file in cinode.files]
- self.lastChange = self.lastPoll
- yield self.master.addChange(author = cinode.who,
- files = files,
- comments = cinode.log,
- when_timestamp = epoch2datetime(cinode.date),
- branch = self.branch)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/changes.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/changes.py
deleted file mode 100644
index 1bf9d51f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/changes.py
+++ /dev/null
@@ -1,289 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os, time
-from cPickle import dump
-
-from zope.interface import implements
-from twisted.python import log, runtime
-from twisted.internet import defer
-from twisted.web import html
-from buildbot.util import datetime2epoch
-
-from buildbot import interfaces, util
-from buildbot.process.properties import Properties
-
-class Change:
- """I represent a single change to the source tree. This may involve several
- files, but they are all changed by the same person, and there is a change
- comment for the group as a whole."""
-
- implements(interfaces.IStatusEvent)
-
- number = None
- branch = None
- category = None
- revision = None # used to create a source-stamp
- links = [] # links are gone, but upgrade code expects this attribute
-
- @classmethod
- def fromChdict(cls, master, chdict):
- """
- Class method to create a L{Change} from a dictionary as returned
- by L{ChangesConnectorComponent.getChange}.
-
- @param master: build master instance
- @param ssdict: change dictionary
-
- @returns: L{Change} via Deferred
- """
- cache = master.caches.get_cache("Changes", cls._make_ch)
- return cache.get(chdict['changeid'], chdict=chdict, master=master)
-
- @classmethod
- def _make_ch(cls, changeid, master, chdict):
- change = cls(None, None, None, _fromChdict=True)
- change.who = chdict['author']
- change.comments = chdict['comments']
- change.isdir = chdict['is_dir']
- change.revision = chdict['revision']
- change.branch = chdict['branch']
- change.category = chdict['category']
- change.revlink = chdict['revlink']
- change.repository = chdict['repository']
- change.codebase = chdict['codebase']
- change.project = chdict['project']
- change.number = chdict['changeid']
-
- when = chdict['when_timestamp']
- if when:
- when = datetime2epoch(when)
- change.when = when
-
- change.files = chdict['files'][:]
- change.files.sort()
-
- change.properties = Properties()
- for n, (v,s) in chdict['properties'].iteritems():
- change.properties.setProperty(n, v, s)
-
- return defer.succeed(change)
-
- def __init__(self, who, files, comments, isdir=0,
- revision=None, when=None, branch=None, category=None,
- revlink='', properties={}, repository='', codebase='',
- project='', _fromChdict=False):
- # skip all this madness if we're being built from the database
- if _fromChdict:
- return
-
- self.who = who
- self.comments = comments
- self.isdir = isdir
-
- def none_or_unicode(x):
- if x is None: return x
- return unicode(x)
-
- self.revision = none_or_unicode(revision)
- now = util.now()
- if when is None:
- self.when = now
- elif when > now:
- # this happens when the committing system has an incorrect clock, for example.
- # handle it gracefully
- log.msg("received a Change with when > now; assuming the change happened now")
- self.when = now
- else:
- self.when = when
- self.branch = none_or_unicode(branch)
- self.category = none_or_unicode(category)
- self.revlink = revlink
- self.properties = Properties()
- self.properties.update(properties, "Change")
- self.repository = repository
- self.codebase = codebase
- self.project = project
-
- # keep a sorted list of the files, for easier display
- self.files = (files or [])[:]
- self.files.sort()
-
- def __setstate__(self, dict):
- self.__dict__ = dict
- # Older Changes won't have a 'properties' attribute in them
- if not hasattr(self, 'properties'):
- self.properties = Properties()
- if not hasattr(self, 'revlink'):
- self.revlink = ""
-
- def __str__(self):
- return (u"Change(revision=%r, who=%r, branch=%r, comments=%r, " +
- u"when=%r, category=%r, project=%r, repository=%r, " +
- u"codebase=%r)") % (
- self.revision, self.who, self.branch, self.comments,
- self.when, self.category, self.project, self.repository,
- self.codebase)
-
- def __cmp__(self, other):
- return self.number - other.number
-
- def asText(self):
- data = ""
- data += self.getFileContents()
- if self.repository:
- data += "On: %s\n" % self.repository
- if self.project:
- data += "For: %s\n" % self.project
- data += "At: %s\n" % self.getTime()
- data += "Changed By: %s\n" % self.who
- data += "Comments: %s" % self.comments
- data += "Properties: \n%s\n\n" % self.getProperties()
- return data
-
- def asDict(self):
- '''returns a dictonary with suitable info for html/mail rendering'''
- result = {}
-
- files = [ dict(name=f) for f in self.files ]
- files.sort(cmp=lambda a, b: a['name'] < b['name'])
-
- # Constant
- result['number'] = self.number
- result['branch'] = self.branch
- result['category'] = self.category
- result['who'] = self.getShortAuthor()
- result['comments'] = self.comments
- result['revision'] = self.revision
- result['rev'] = self.revision
- result['when'] = self.when
- result['at'] = self.getTime()
- result['files'] = files
- result['revlink'] = getattr(self, 'revlink', None)
- result['properties'] = self.properties.asList()
- result['repository'] = getattr(self, 'repository', None)
- result['codebase'] = getattr(self, 'codebase', '')
- result['project'] = getattr(self, 'project', None)
- return result
-
- def getShortAuthor(self):
- return self.who
-
- def getTime(self):
- if not self.when:
- return "?"
- return time.strftime("%a %d %b %Y %H:%M:%S",
- time.localtime(self.when))
-
- def getTimes(self):
- return (self.when, None)
-
- def getText(self):
- return [html.escape(self.who)]
- def getLogs(self):
- return {}
-
- def getFileContents(self):
- data = ""
- if len(self.files) == 1:
- if self.isdir:
- data += "Directory: %s\n" % self.files[0]
- else:
- data += "File: %s\n" % self.files[0]
- else:
- data += "Files:\n"
- for f in self.files:
- data += " %s\n" % f
- return data
-
- def getProperties(self):
- data = ""
- for prop in self.properties.asList():
- data += " %s: %s" % (prop[0], prop[1])
- return data
-
-
-class ChangeMaster: # pragma: no cover
- # this is a stub, retained to allow the "buildbot upgrade-master" tool to
- # read old changes.pck pickle files and convert their contents into the
- # new database format. This is only instantiated by that tool, or by
- # test_db.py which tests that tool. The functionality that previously
- # lived here has been moved into buildbot.changes.manager.ChangeManager
-
- def __init__(self):
- self.changes = []
- # self.basedir must be filled in by the parent
- self.nextNumber = 1
-
- def saveYourself(self):
- filename = os.path.join(self.basedir, "changes.pck")
- tmpfilename = filename + ".tmp"
- try:
- with open(tmpfilename, "wb") as f:
- dump(self, f)
- if runtime.platformType == 'win32':
- # windows cannot rename a file on top of an existing one
- if os.path.exists(filename):
- os.unlink(filename)
- os.rename(tmpfilename, filename)
- except Exception:
- log.msg("unable to save changes")
- log.err()
-
- # This method is used by contrib/fix_changes_pickle_encoding.py to recode all
- # bytestrings in an old changes.pck into unicode strings
- def recode_changes(self, old_encoding, quiet=False):
- """Processes the list of changes, with the change attributes re-encoded
- unicode objects"""
- nconvert = 0
- for c in self.changes:
- # give revision special handling, in case it is an integer
- if isinstance(c.revision, int):
- c.revision = unicode(c.revision)
-
- for attr in ("who", "comments", "revlink", "category", "branch", "revision"):
- a = getattr(c, attr)
- if isinstance(a, str):
- try:
- setattr(c, attr, a.decode(old_encoding))
- nconvert += 1
- except UnicodeDecodeError:
- raise UnicodeError("Error decoding %s of change #%s as %s:\n%r" %
- (attr, c.number, old_encoding, a))
-
- # filenames are a special case, but in general they'll have the same encoding
- # as everything else on a system. If not, well, hack this script to do your
- # import!
- newfiles = []
- for filename in util.flatten(c.files):
- if isinstance(filename, str):
- try:
- filename = filename.decode(old_encoding)
- nconvert += 1
- except UnicodeDecodeError:
- raise UnicodeError("Error decoding filename '%s' of change #%s as %s:\n%r" %
- (filename.decode('ascii', 'replace'),
- c.number, old_encoding, a))
- newfiles.append(filename)
- c.files = newfiles
- if not quiet:
- print "converted %d strings" % nconvert
-
-class OldChangeMaster(ChangeMaster): # pragma: no cover
- # this is a reminder that the ChangeMaster class is old
- pass
-# vim: set ts=4 sts=4 sw=4 et:
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/filter.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/filter.py
deleted file mode 100644
index 30bdd83a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/filter.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# 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 re, types
-
-from buildbot.util import ComparableMixin, NotABranch
-
-class ChangeFilter(ComparableMixin):
-
- # NOTE: If users use a filter_fn, we have no way to determine whether it has
- # changed at reconfig, so the scheduler will always be restarted. That's as
- # good as Python can do.
- compare_attrs = ('filter_fn', 'checks')
-
- def __init__(self,
- # gets a Change object, returns boolean
- filter_fn=None,
- # change attribute comparisons: exact match to PROJECT, member of
- # list PROJECTS, regular expression match to PROJECT_RE, or
- # PROJECT_FN returns True when called with the project; repository,
- # branch, and so on are similar. Note that the regular expressions
- # are anchored to the first character of the string. For convenience,
- # a list can also be specified to the singular option (e.g,. PROJETS
- project=None, project_re=None, project_fn=None,
- repository=None, repository_re=None, repository_fn=None,
- branch=NotABranch, branch_re=None, branch_fn=None,
- category=None, category_re=None, category_fn=None,
- codebase=None, codebase_re=None, codebase_fn=None):
- def mklist(x):
- if x is not None and type(x) is not types.ListType:
- return [ x ]
- return x
- def mklist_br(x): # branch needs to be handled specially
- if x is NotABranch:
- return None
- if type(x) is not types.ListType:
- return [ x ]
- return x
- def mkre(r):
- if r is not None and not hasattr(r, 'match'):
- r = re.compile(r)
- return r
-
- self.filter_fn = filter_fn
- self.checks = [
- (mklist(project), mkre(project_re), project_fn, "project"),
- (mklist(repository), mkre(repository_re), repository_fn, "repository"),
- (mklist_br(branch), mkre(branch_re), branch_fn, "branch"),
- (mklist(category), mkre(category_re), category_fn, "category"),
- (mklist(codebase), mkre(codebase_re), codebase_fn, "codebase"),
- ]
-
- def filter_change(self, change):
- if self.filter_fn is not None and not self.filter_fn(change):
- return False
- for (filt_list, filt_re, filt_fn, chg_attr) in self.checks:
- chg_val = getattr(change, chg_attr, '')
- if filt_list is not None and chg_val not in filt_list:
- return False
- if filt_re is not None and (chg_val is None or not filt_re.match(chg_val)):
- return False
- if filt_fn is not None and not filt_fn(chg_val):
- return False
- return True
-
- def __repr__(self):
- checks = []
- for (filt_list, filt_re, filt_fn, chg_attr) in self.checks:
- if filt_list is not None and len(filt_list) == 1:
- checks.append('%s == %s' % (chg_attr, filt_list[0]))
- elif filt_list is not None:
- checks.append('%s in %r' % (chg_attr, filt_list))
- if filt_re is not None :
- checks.append('%s ~/%s/' % (chg_attr, filt_re))
- if filt_fn is not None :
- checks.append('%s(%s)' % (filt_fn.__name__, chg_attr))
-
- return "<%s on %s>" % (self.__class__.__name__, ' and '.join(checks))
-
- @staticmethod
- def fromSchedulerConstructorArgs(change_filter=None,
- branch=NotABranch, categories=None):
-
- """
- Static method to create a filter based on constructor args
- change_filter, branch, and categories; use default values @code{None},
- @code{NotABranch}, and @code{None}, respectively. These arguments are
- interpreted as documented for the
- L{buildbot.schedulers.basic.Scheduler} class.
-
- @returns: L{ChangeFilter} instance or None for not filtering
- """
-
- # use a change_filter, if given one
- if change_filter:
- if (branch is not NotABranch or categories is not None):
- raise RuntimeError("cannot specify both change_filter and "
- "branch or categories")
- return change_filter
- elif branch is not NotABranch or categories:
- # build a change filter from the deprecated category and branch args
- cfargs = {}
- if branch is not NotABranch: cfargs['branch'] = branch
- if categories: cfargs['category'] = categories
- return ChangeFilter(**cfargs)
- else:
- return None
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/gerritchangesource.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/gerritchangesource.py
deleted file mode 100644
index 62bf6a88..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/gerritchangesource.py
+++ /dev/null
@@ -1,204 +0,0 @@
-# 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
-
-from twisted.internet import reactor
-
-from buildbot.changes import base
-from buildbot.util import json
-from buildbot import util
-from twisted.python import log
-from twisted.internet import defer
-from twisted.internet.protocol import ProcessProtocol
-
-class GerritChangeSource(base.ChangeSource):
- """This source will maintain a connection to gerrit ssh server
- that will provide us gerrit events in json format."""
-
- compare_attrs = ["gerritserver", "gerritport"]
-
- STREAM_GOOD_CONNECTION_TIME = 120
- "(seconds) connections longer than this are considered good, and reset the backoff timer"
-
- STREAM_BACKOFF_MIN = 0.5
- "(seconds) minimum, but nonzero, time to wait before retrying a failed connection"
-
- STREAM_BACKOFF_EXPONENT = 1.5
- "multiplier used to increase the backoff from MIN to MAX on repeated failures"
-
- STREAM_BACKOFF_MAX = 60
- "(seconds) maximum time to wait before retrying a failed connection"
-
- def __init__(self, gerritserver, username, gerritport=29418, identity_file=None):
- """
- @type gerritserver: string
- @param gerritserver: the dns or ip that host the gerrit ssh server,
-
- @type gerritport: int
- @param gerritport: the port of the gerrit ssh server,
-
- @type username: string
- @param username: the username to use to connect to gerrit,
-
- @type identity_file: string
- @param identity_file: identity file to for authentication (optional).
-
- """
- # TODO: delete API comment when documented
-
- self.gerritserver = gerritserver
- self.gerritport = gerritport
- self.username = username
- self.identity_file = identity_file
- self.process = None
- self.wantProcess = False
- self.streamProcessTimeout = self.STREAM_BACKOFF_MIN
-
- class LocalPP(ProcessProtocol):
- def __init__(self, change_source):
- self.change_source = change_source
- self.data = ""
-
- @defer.inlineCallbacks
- def outReceived(self, data):
- """Do line buffering."""
- self.data += data
- lines = self.data.split("\n")
- self.data = lines.pop(-1) # last line is either empty or incomplete
- for line in lines:
- log.msg("gerrit: %s" % (line,))
- yield self.change_source.lineReceived(line)
-
- def errReceived(self, data):
- log.msg("gerrit stderr: %s" % (data,))
-
- def processEnded(self, status_object):
- self.change_source.streamProcessStopped()
-
- def lineReceived(self, line):
- try:
- event = json.loads(line.decode('utf-8'))
- except ValueError:
- log.msg("bad json line: %s" % (line,))
- return defer.succeed(None)
-
- if not(type(event) == type({}) and "type" in event):
- log.msg("no type in event %s" % (line,))
- return defer.succeed(None)
- func = getattr(self, "eventReceived_"+event["type"].replace("-","_"), None)
- if func == None:
- log.msg("unsupported event %s" % (event["type"],))
- return defer.succeed(None)
-
- # flatten the event dictionary, for easy access with WithProperties
- def flatten(properties, base, event):
- for k, v in event.items():
- if type(v) == dict:
- flatten(properties, base + "." + k, v)
- else: # already there
- properties[base + "." + k] = v
-
- properties = {}
- flatten(properties, "event", event)
- return func(properties,event)
- def addChange(self, chdict):
- d = self.master.addChange(**chdict)
- # eat failures..
- d.addErrback(log.err, 'error adding change from GerritChangeSource')
- return d
- def eventReceived_patchset_created(self, properties, event):
- change = event["change"]
- return self.addChange(dict(
- author="%s <%s>" % (change["owner"]["name"], change["owner"]["email"]),
- project=change["project"],
- repository="ssh://%s@%s:%s/%s" % (
- self.username, self.gerritserver, self.gerritport, change["project"]),
- branch=change["branch"]+"/"+change["number"],
- revision=event["patchSet"]["revision"],
- revlink=change["url"],
- comments=change["subject"],
- files=["unknown"],
- category=event["type"],
- properties=properties))
- def eventReceived_ref_updated(self, properties, event):
- ref = event["refUpdate"]
- author = "gerrit"
-
- if "submitter" in event:
- author="%s <%s>" % (event["submitter"]["name"], event["submitter"]["email"])
-
- return self.addChange(dict(
- author=author,
- project=ref["project"],
- repository="ssh://%s@%s:%s/%s" % (
- self.username, self.gerritserver, self.gerritport, ref["project"]),
- branch=ref["refName"],
- revision=ref["newRev"],
- comments="Gerrit: patchset(s) merged.",
- files=["unknown"],
- category=event["type"],
- properties=properties))
-
- def streamProcessStopped(self):
- self.process = None
-
- # if the service is stopped, don't try to restart the process
- if not self.wantProcess:
- log.msg("service is not running; not reconnecting")
- return
-
- now = util.now()
- if now - self.lastStreamProcessStart < self.STREAM_GOOD_CONNECTION_TIME:
- # bad startup; start the stream process again after a timeout, and then
- # increase the timeout
- log.msg("'gerrit stream-events' failed; restarting after %ds" % round(self.streamProcessTimeout))
- reactor.callLater(self.streamProcessTimeout, self.startStreamProcess)
- self.streamProcessTimeout *= self.STREAM_BACKOFF_EXPONENT
- if self.streamProcessTimeout > self.STREAM_BACKOFF_MAX:
- self.streamProcessTimeout = self.STREAM_BACKOFF_MAX
- else:
- # good startup, but lost connection; restart immediately, and set the timeout
- # to its minimum
- self.startStreamProcess()
- self.streamProcessTimeout = self.STREAM_BACKOFF_MIN
-
- def startStreamProcess(self):
- log.msg("starting 'gerrit stream-events'")
- self.lastStreamProcessStart = util.now()
- args = [ self.username+"@"+self.gerritserver,"-p", str(self.gerritport)]
- if self.identity_file is not None:
- args = args + [ '-i', self.identity_file ]
- self.process = reactor.spawnProcess(self.LocalPP(self), "ssh",
- [ "ssh" ] + args + [ "gerrit", "stream-events" ])
-
- def startService(self):
- self.wantProcess = True
- self.startStreamProcess()
-
- def stopService(self):
- self.wantProcess = False
- if self.process:
- self.process.signalProcess("KILL")
- # TODO: if this occurs while the process is restarting, some exceptions may
- # be logged, although things will settle down normally
- return base.ChangeSource.stopService(self)
-
- def describe(self):
- status = ""
- if not self.process:
- status = "[NOT CONNECTED - check log]"
- str = ('GerritChangeSource watching the remote Gerrit repository %s@%s %s' %
- (self.username, self.gerritserver, status))
- return str
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/gitpoller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/gitpoller.py
deleted file mode 100644
index 120253af..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/gitpoller.py
+++ /dev/null
@@ -1,244 +0,0 @@
-# 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 os
-import urllib
-from twisted.python import log
-from twisted.internet import defer, utils
-
-from buildbot.changes import base
-from buildbot.util import epoch2datetime
-from buildbot.util.state import StateMixin
-from buildbot import config
-
-class GitPoller(base.PollingChangeSource, StateMixin):
- """This source will poll a remote git repo for changes and submit
- them to the change master."""
-
- compare_attrs = ["repourl", "branches", "workdir",
- "pollInterval", "gitbin", "usetimestamps",
- "category", "project"]
-
- def __init__(self, repourl, branches=None, branch=None,
- workdir=None, pollInterval=10*60,
- gitbin='git', usetimestamps=True,
- category=None, project=None,
- pollinterval=-2, fetch_refspec=None,
- encoding='utf-8'):
-
- # for backward compatibility; the parameter used to be spelled with 'i'
- if pollinterval != -2:
- pollInterval = pollinterval
-
- base.PollingChangeSource.__init__(self, name=repourl,
- pollInterval=pollInterval)
-
- if project is None: project = ''
-
- if branch and branches:
- config.error("GitPoller: can't specify both branch and branches")
- elif branch:
- branches = [branch]
- elif not branches:
- branches = ['master']
-
- self.repourl = repourl
- self.branches = branches
- self.encoding = encoding
- self.gitbin = gitbin
- self.workdir = workdir
- self.usetimestamps = usetimestamps
- self.category = category
- self.project = project
- self.changeCount = 0
- self.lastRev = {}
-
- if fetch_refspec is not None:
- config.error("GitPoller: fetch_refspec is no longer supported. "
- "Instead, only the given branches are downloaded.")
-
- if self.workdir == None:
- self.workdir = 'gitpoller-work'
-
- def startService(self):
- # make our workdir absolute, relative to the master's basedir
- if not os.path.isabs(self.workdir):
- self.workdir = os.path.join(self.master.basedir, self.workdir)
- log.msg("gitpoller: using workdir '%s'" % self.workdir)
-
- d = self.getState('lastRev', {})
- def setLastRev(lastRev):
- self.lastRev = lastRev
- d.addCallback(setLastRev)
-
- d.addCallback(lambda _:
- base.PollingChangeSource.startService(self))
- d.addErrback(log.err, 'while initializing GitPoller repository')
-
- return d
-
- def describe(self):
- status = ""
- if not self.master:
- status = "[STOPPED - check log]"
- str = ('GitPoller watching the remote git repository %s, branches: %s %s'
- % (self.repourl, ', '.join(self.branches), status))
- return str
-
- @defer.inlineCallbacks
- def poll(self):
- yield self._dovccmd('init', ['--bare', self.workdir])
-
- refspecs = [
- '+%s:%s'% (branch, self._localBranch(branch))
- for branch in self.branches
- ]
- yield self._dovccmd('fetch',
- [self.repourl] + refspecs, path=self.workdir)
-
- revs = {}
- for branch in self.branches:
- try:
- revs[branch] = rev = yield self._dovccmd('rev-parse',
- [self._localBranch(branch)], path=self.workdir)
- yield self._process_changes(rev, branch)
- except:
- log.err(_why="trying to poll branch %s of %s"
- % (branch, self.repourl))
-
- self.lastRev.update(revs)
- yield self.setState('lastRev', self.lastRev)
-
- def _get_commit_comments(self, rev):
- args = ['--no-walk', r'--format=%s%n%b', rev, '--']
- d = self._dovccmd('log', args, path=self.workdir)
- def process(git_output):
- git_output = git_output.decode(self.encoding)
- if len(git_output) == 0:
- raise EnvironmentError('could not get commit comment for rev')
- return git_output
- d.addCallback(process)
- return d
-
- def _get_commit_timestamp(self, rev):
- # unix timestamp
- args = ['--no-walk', r'--format=%ct', rev, '--']
- d = self._dovccmd('log', args, path=self.workdir)
- def process(git_output):
- if self.usetimestamps:
- try:
- stamp = float(git_output)
- except Exception, e:
- log.msg('gitpoller: caught exception converting output \'%s\' to timestamp' % git_output)
- raise e
- return stamp
- else:
- return None
- d.addCallback(process)
- return d
-
- def _get_commit_files(self, rev):
- args = ['--name-only', '--no-walk', r'--format=%n', rev, '--']
- d = self._dovccmd('log', args, path=self.workdir)
- def process(git_output):
- fileList = git_output.split()
- return fileList
- d.addCallback(process)
- return d
-
- def _get_commit_author(self, rev):
- args = ['--no-walk', r'--format=%aN <%aE>', rev, '--']
- d = self._dovccmd('log', args, path=self.workdir)
- def process(git_output):
- git_output = git_output.decode(self.encoding)
- if len(git_output) == 0:
- raise EnvironmentError('could not get commit author for rev')
- return git_output
- d.addCallback(process)
- return d
-
- @defer.inlineCallbacks
- def _process_changes(self, newRev, branch):
- """
- Read changes since last change.
-
- - Read list of commit hashes.
- - Extract details from each commit.
- - Add changes to database.
- """
-
- lastRev = self.lastRev.get(branch)
- self.lastRev[branch] = newRev
- if not lastRev:
- return
-
- # get the change list
- revListArgs = [r'--format=%H', '%s..%s' % (lastRev, newRev), '--']
- self.changeCount = 0
- results = yield self._dovccmd('log', revListArgs, path=self.workdir)
-
-
- # process oldest change first
- revList = results.split()
- revList.reverse()
- self.changeCount = len(revList)
-
- log.msg('gitpoller: processing %d changes: %s from "%s"'
- % (self.changeCount, revList, self.repourl) )
-
- for rev in revList:
- dl = defer.DeferredList([
- self._get_commit_timestamp(rev),
- self._get_commit_author(rev),
- self._get_commit_files(rev),
- self._get_commit_comments(rev),
- ], consumeErrors=True)
-
- results = yield dl
-
- # check for failures
- failures = [ r[1] for r in results if not r[0] ]
- if failures:
- # just fail on the first error; they're probably all related!
- raise failures[0]
-
- timestamp, author, files, comments = [ r[1] for r in results ]
- yield self.master.addChange(
- author=author,
- revision=rev,
- files=files,
- comments=comments,
- when_timestamp=epoch2datetime(timestamp),
- branch=branch,
- category=self.category,
- project=self.project,
- repository=self.repourl,
- src='git')
-
- def _dovccmd(self, command, args, path=None):
- d = utils.getProcessOutputAndValue(self.gitbin,
- [command] + args, path=path, env=os.environ)
- def _convert_nonzero_to_failure(res):
- "utility to handle the result of getProcessOutputAndValue"
- (stdout, stderr, code) = res
- if code != 0:
- raise EnvironmentError('command failed with exit code %d: %s'
- % (code, stderr))
- return stdout.strip()
- d.addCallback(_convert_nonzero_to_failure)
- return d
-
- def _localBranch(self, branch):
- return "refs/buildbot/%s/%s" % (urllib.quote(self.repourl, ''), branch)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/hgbuildbot.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/hgbuildbot.py
deleted file mode 100644
index b01a13ca..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/hgbuildbot.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# 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.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright 2007 Frederic Leroy <fredo@starox.org>
-
-# hook extension to send change notifications to buildbot when a changeset is
-# brought into the repository from elsewhere.
-#
-# See the Buildbot manual for configuration instructions.
-
-import os
-
-from mercurial.node import bin, hex, nullid #@UnresolvedImport
-
-# mercurial's on-demand-importing hacks interfere with the:
-#from zope.interface import Interface
-# that Twisted needs to do, so disable it.
-try:
- from mercurial import demandimport
- demandimport.disable()
-except ImportError:
- pass
-
-# In Mercurial post-1.7, some strings might be stored as a
-# encoding.localstr class. encoding.fromlocal will translate
-# those back to UTF-8 strings.
-try:
- from mercurial.encoding import fromlocal
- _hush_pyflakes = [fromlocal]
- del _hush_pyflakes
-except ImportError:
- def fromlocal(s):
- return s
-
-def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
- # read config parameters
- baseurl = ui.config('hgbuildbot', 'baseurl',
- ui.config('web', 'baseurl', ''))
- masters = ui.configlist('hgbuildbot', 'master')
- if masters:
- branchtype = ui.config('hgbuildbot', 'branchtype', 'inrepo')
- branch = ui.config('hgbuildbot', 'branch')
- fork = ui.configbool('hgbuildbot', 'fork', False)
- # notify also has this setting
- stripcount = int(ui.config('notify','strip') or ui.config('hgbuildbot','strip',3))
- category = ui.config('hgbuildbot', 'category', None)
- project = ui.config('hgbuildbot', 'project', '')
- auth = ui.config('hgbuildbot', 'auth', None)
- else:
- ui.write("* You must add a [hgbuildbot] section to .hg/hgrc in "
- "order to use buildbot hook\n")
- return
-
- if hooktype != "changegroup":
- ui.status("hgbuildbot: hooktype %s not supported.\n" % hooktype)
- return
-
- if fork:
- child_pid = os.fork()
- if child_pid == 0:
- #child
- pass
- else:
- #parent
- ui.status("Notifying buildbot...\n")
- return
-
- # only import inside the fork if forked
- from buildbot.clients import sendchange
- from twisted.internet import defer, reactor
-
- if branch is None:
- if branchtype == 'dirname':
- branch = os.path.basename(repo.root)
-
- if not auth:
- auth = 'change:changepw'
- auth = auth.split(':', 1)
-
- # process changesets
- def _send(res, s, c):
- if not fork:
- ui.status("rev %s sent\n" % c['revision'])
- return s.send(c['branch'], c['revision'], c['comments'],
- c['files'], c['username'], category=category,
- repository=repository, project=project, vc='hg',
- properties=c['properties'])
-
- try: # first try Mercurial 1.1+ api
- start = repo[node].rev()
- end = len(repo)
- except TypeError: # else fall back to old api
- start = repo.changelog.rev(bin(node))
- end = repo.changelog.count()
-
- repository = strip(repo.root, stripcount)
- repository = baseurl + repository
-
- for master in masters:
- s = sendchange.Sender(master, auth=auth)
- d = defer.Deferred()
- reactor.callLater(0, d.callback, None)
-
- for rev in xrange(start, end):
- # send changeset
- node = repo.changelog.node(rev)
- manifest, user, (time, timezone), files, desc, extra = repo.changelog.read(node)
- parents = filter(lambda p: not p == nullid, repo.changelog.parents(node))
- if branchtype == 'inrepo':
- branch = extra['branch']
- is_merge = len(parents) > 1
- # merges don't always contain files, but at least one file is required by buildbot
- if is_merge and not files:
- files = ["merge"]
- properties = {'is_merge': is_merge}
- if branch:
- branch = fromlocal(branch)
- change = {
- 'master': master,
- 'username': fromlocal(user),
- 'revision': hex(node),
- 'comments': fromlocal(desc),
- 'files': files,
- 'branch': branch,
- 'properties':properties
- }
- d.addCallback(_send, s, change)
-
- def _printSuccess(res):
- ui.status(s.getSuccessString(res) + '\n')
-
- def _printFailure(why):
- ui.warn(s.getFailureString(why) + '\n')
-
- d.addCallbacks(_printSuccess, _printFailure)
- d.addBoth(lambda _ : reactor.stop())
- reactor.run()
-
- if fork:
- os._exit(os.EX_OK)
- else:
- return
-
-# taken from the mercurial notify extension
-def strip(path, count):
- '''Strip the count first slash of the path'''
-
- # First normalize it
- path = '/'.join(path.split(os.sep))
- # and strip it part after part
- while count > 0:
- c = path.find('/')
- if c == -1:
- break
- path = path[c + 1:]
- count -= 1
- return path
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/hgpoller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/hgpoller.py
deleted file mode 100644
index 373ce735..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/hgpoller.py
+++ /dev/null
@@ -1,305 +0,0 @@
-# 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 time
-import os
-from twisted.python import log
-from twisted.internet import defer, utils
-
-from buildbot import config
-from buildbot.util import deferredLocked
-from buildbot.changes import base
-from buildbot.util import epoch2datetime
-
-class HgPoller(base.PollingChangeSource):
- """This source will poll a remote hg repo for changes and submit
- them to the change master."""
-
- compare_attrs = ["repourl", "branch", "workdir",
- "pollInterval", "hgpoller", "usetimestamps",
- "category", "project"]
-
- db_class_name = 'HgPoller'
-
- def __init__(self, repourl, branch='default',
- workdir=None, pollInterval=10*60,
- hgbin='hg', usetimestamps=True,
- category=None, project='', pollinterval=-2,
- encoding='utf-8'):
-
- # for backward compatibility; the parameter used to be spelled with 'i'
- if pollinterval != -2:
- pollInterval = pollinterval
-
- self.repourl = repourl
- self.branch = branch
- base.PollingChangeSource.__init__(
- self, name=repourl, pollInterval=pollInterval)
- self.encoding = encoding
- self.lastChange = time.time()
- self.lastPoll = time.time()
- self.hgbin = hgbin
- self.workdir = workdir
- self.usetimestamps = usetimestamps
- self.category = category
- self.project = project
- self.commitInfo = {}
- self.initLock = defer.DeferredLock()
-
- if self.workdir == None:
- config.error("workdir is mandatory for now in HgPoller")
-
- def describe(self):
- status = ""
- if not self.master:
- status = "[STOPPED - check log]"
- return ("HgPoller watching the remote Mercurial repository %r, "
- "branch: %r, in workdir %r %s") % (self.repourl, self.branch,
- self.workdir, status)
-
- @deferredLocked('initLock')
- def poll(self):
- d = self._getChanges()
- d.addCallback(self._processChanges)
- d.addErrback(self._processChangesFailure)
- return d
-
- def _absWorkdir(self):
- workdir = self.workdir
- if os.path.isabs(workdir):
- return workdir
- return os.path.join(self.master.basedir, workdir)
-
- def _getRevDetails(self, rev):
- """Return a deferred for (date, author, files, comments) of given rev.
-
- Deferred will be in error if rev is unknown.
- """
- args = ['log', '-r', rev, os.linesep.join((
- '--template={date|hgdate}',
- '{author}',
- '{files}',
- '{desc|strip}'))]
- # Mercurial fails with status 255 if rev is unknown
- d = utils.getProcessOutput(self.hgbin, args, path=self._absWorkdir(),
- env=os.environ, errortoo=False )
- def process(output):
- # fortunately, Mercurial issues all filenames one one line
- date, author, files, comments = output.decode(self.encoding, "replace").split(
- os.linesep, 3)
-
- if not self.usetimestamps:
- stamp = None
- else:
- try:
- stamp = float(date.split()[0])
- except:
- log.msg('hgpoller: caught exception converting output %r '
- 'to timestamp' % date)
- raise
- return stamp, author.strip(), files.split(), comments.strip()
-
- d.addCallback(process)
- return d
-
- def _isRepositoryReady(self):
- """Easy to patch in tests."""
- return os.path.exists(os.path.join(self._absWorkdir(), '.hg'))
-
- def _initRepository(self):
- """Have mercurial init the workdir as a repository (hg init) if needed.
-
- hg init will also create all needed intermediate directories.
- """
- if self._isRepositoryReady():
- return defer.succeed(None)
- log.msg('hgpoller: initializing working dir from %s' % self.repourl)
- d = utils.getProcessOutputAndValue(self.hgbin,
- ['init', self._absWorkdir()],
- env=os.environ)
- d.addCallback(self._convertNonZeroToFailure)
- d.addErrback(self._stopOnFailure)
- d.addCallback(lambda _ : log.msg(
- "hgpoller: finished initializing working dir %r" % self.workdir))
- return d
-
- def _getChanges(self):
- self.lastPoll = time.time()
-
- d = self._initRepository()
- d.addCallback(lambda _ : log.msg(
- "hgpoller: polling hg repo at %s" % self.repourl))
-
- # get a deferred object that performs the fetch
- args = ['pull', '-b', self.branch, self.repourl]
-
- # This command always produces data on stderr, but we actually do not
- # care about the stderr or stdout from this command.
- # We set errortoo=True to avoid an errback from the deferred.
- # The callback which will be added to this
- # deferred will not use the response.
- d.addCallback(lambda _: utils.getProcessOutput(
- self.hgbin, args, path=self._absWorkdir(),
- env=os.environ, errortoo=True))
-
- return d
-
- def _getStateObjectId(self):
- """Return a deferred for object id in state db.
-
- Being unique among pollers, workdir is used with branch as instance
- name for db.
- """
- return self.master.db.state.getObjectId(
- '#'.join((self.workdir, self.branch)), self.db_class_name)
-
- def _getCurrentRev(self):
- """Return a deferred for object id in state db and current numeric rev.
-
- If never has been set, current rev is None.
- """
- d = self._getStateObjectId()
- def oid_cb(oid):
- d = self.master.db.state.getState(oid, 'current_rev', None)
- def addOid(cur):
- if cur is not None:
- return oid, int(cur)
- return oid, cur
- d.addCallback(addOid)
- return d
- d.addCallback(oid_cb)
- return d
-
- def _setCurrentRev(self, rev, oid=None):
- """Return a deferred to set current revision in persistent state.
-
- oid is self's id for state db. It can be passed to avoid a db lookup."""
- if oid is None:
- d = self._getStateObjectId()
- else:
- d = defer.succeed(oid)
-
- def set_in_state(obj_id):
- return self.master.db.state.setState(obj_id, 'current_rev', rev)
- d.addCallback(set_in_state)
-
- return d
-
- def _getHead(self):
- """Return a deferred for branch head revision or None.
-
- We'll get an error if there is no head for this branch, which is
- proabably a good thing, since it's probably a mispelling
- (if really buildbotting a branch that does not have any changeset
- yet, one shouldn't be surprised to get errors)
- """
- d = utils.getProcessOutput(self.hgbin,
- ['heads', self.branch, '--template={rev}' + os.linesep],
- path=self._absWorkdir(), env=os.environ, errortoo=False)
-
- def no_head_err(exc):
- log.err("hgpoller: could not find branch %r in repository %r" % (
- self.branch, self.repourl))
- d.addErrback(no_head_err)
-
- def results(heads):
- if not heads:
- return
-
- if len(heads.split()) > 1:
- log.err(("hgpoller: caught several heads in branch %r "
- "from repository %r. Staying at previous revision"
- "You should wait until the situation is normal again "
- "due to a merge or directly strip if remote repo "
- "gets stripped later.") % (self.branch, self.repourl))
- return
-
- # in case of whole reconstruction, are we sure that we'll get the
- # same node -> rev assignations ?
- return int(heads.strip())
-
- d.addCallback(results)
- return d
-
- @defer.inlineCallbacks
- def _processChanges(self, unused_output):
- """Send info about pulled changes to the master and record current.
-
- GitPoller does the recording by moving the working dir to the head
- of the branch.
- We don't update the tree (unnecessary treatment and waste of space)
- instead, we simply store the current rev number in a file.
- Recall that hg rev numbers are local and incremental.
- """
- oid, current = yield self._getCurrentRev()
- # hg log on a range of revisions is never empty
- # also, if a numeric revision does not exist, a node may match.
- # Therefore, we have to check explicitely that branch head > current.
- head = yield self._getHead()
- if head <= current:
- return
- if current is None:
- # we could have used current = -1 convention as well (as hg does)
- revrange = '%d:%d' % (head, head)
- else:
- revrange = '%d:%s' % (current + 1, head)
-
- # two passes for hg log makes parsing simpler (comments is multi-lines)
- revListArgs = ['log', '-b', self.branch, '-r', revrange,
- r'--template={rev}:{node}\n']
- results = yield utils.getProcessOutput(self.hgbin, revListArgs,
- path=self._absWorkdir(), env=os.environ, errortoo=False )
-
- revNodeList = [rn.split(':', 1) for rn in results.strip().split()]
-
- log.msg('hgpoller: processing %d changes: %r in %r'
- % (len(revNodeList), revNodeList, self._absWorkdir()))
- for rev, node in revNodeList:
- timestamp, author, files, comments = yield self._getRevDetails(
- node)
- yield self.master.addChange(
- author=author,
- revision=node,
- files=files,
- comments=comments,
- when_timestamp=epoch2datetime(timestamp),
- branch=self.branch,
- category=self.category,
- project=self.project,
- repository=self.repourl,
- src='hg')
- # writing after addChange so that a rev is never missed,
- # but at once to avoid impact from later errors
- yield self._setCurrentRev(rev, oid=oid)
-
- def _processChangesFailure(self, f):
- log.msg('hgpoller: repo poll failed')
- log.err(f)
- # eat the failure to continue along the defered chain - we still want to catch up
- return None
-
- def _convertNonZeroToFailure(self, res):
- "utility method to handle the result of getProcessOutputAndValue"
- (stdout, stderr, code) = res
- if code != 0:
- raise EnvironmentError('command failed with exit code %d: %s' % (code, stderr))
- return (stdout, stderr, code)
-
- def _stopOnFailure(self, f):
- "utility method to stop the service when a failure occurs"
- if self.running:
- d = defer.maybeDeferred(lambda : self.stopService())
- d.addErrback(log.err, 'while stopping broken HgPoller service')
- return f
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/mail.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/mail.py
deleted file mode 100644
index c8e0dd32..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/mail.py
+++ /dev/null
@@ -1,507 +0,0 @@
-# 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
-
-"""
-Parse various kinds of 'CVS notify' email.
-"""
-import re
-import time, calendar
-import datetime
-from email import message_from_file
-from email.Utils import parseaddr, parsedate_tz, mktime_tz
-from email.Iterators import body_line_iterator
-
-from zope.interface import implements
-from twisted.python import log
-from twisted.internet import defer
-from buildbot import util
-from buildbot.interfaces import IChangeSource
-from buildbot.util.maildir import MaildirService
-
-class MaildirSource(MaildirService, util.ComparableMixin):
- """Generic base class for Maildir-based change sources"""
- implements(IChangeSource)
-
- compare_attrs = ["basedir", "pollinterval", "prefix"]
-
- def __init__(self, maildir, prefix=None, category='', repository=''):
- MaildirService.__init__(self, maildir)
- self.prefix = prefix
- self.category = category
- self.repository = repository
- if prefix and not prefix.endswith("/"):
- log.msg("%s: you probably want your prefix=('%s') to end with "
- "a slash")
-
- def describe(self):
- return "%s watching maildir '%s'" % (self.__class__.__name__, self.basedir)
-
- def messageReceived(self, filename):
- d = defer.succeed(None)
- def parse_file(_):
- f = self.moveToCurDir(filename)
- return self.parse_file(f, self.prefix)
- d.addCallback(parse_file)
-
- def add_change(chtuple):
- src, chdict = None, None
- if chtuple:
- src, chdict = chtuple
- if chdict:
- return self.master.addChange(src=src, **chdict)
- else:
- log.msg("no change found in maildir file '%s'" % filename)
- d.addCallback(add_change)
-
- return d
-
- def parse_file(self, fd, prefix=None):
- m = message_from_file(fd)
- return self.parse(m, prefix)
-
-class CVSMaildirSource(MaildirSource):
- name = "CVSMaildirSource"
-
- def __init__(self, maildir, prefix=None, category='',
- repository='', properties={}):
- MaildirSource.__init__(self, maildir, prefix, category, repository)
- self.properties = properties
-
- def parse(self, m, prefix=None):
- """Parse messages sent by the 'buildbot-cvs-mail' program.
- """
- # The mail is sent from the person doing the checkin. Assume that the
- # local username is enough to identify them (this assumes a one-server
- # cvs-over-rsh environment rather than the server-dirs-shared-over-NFS
- # model)
- name, addr = parseaddr(m["from"])
- if not addr:
- return None # no From means this message isn't from buildbot-cvs-mail
- at = addr.find("@")
- if at == -1:
- author = addr # might still be useful
- else:
- author = addr[:at]
-
- # CVS accecpts RFC822 dates. buildbot-cvs-mail adds the date as
- # part of the mail header, so use that.
- # This assumes cvs is being access via ssh or pserver, so the time
- # will be the CVS server's time.
-
- # calculate a "revision" based on that timestamp, or the current time
- # if we're unable to parse the date.
- log.msg('Processing CVS mail')
- dateTuple = parsedate_tz(m["date"])
- if dateTuple == None:
- when = util.now()
- else:
- when = mktime_tz(dateTuple)
-
- theTime = datetime.datetime.utcfromtimestamp(float(when))
- rev = theTime.strftime('%Y-%m-%d %H:%M:%S')
-
- catRE = re.compile( '^Category:\s*(\S.*)')
- cvsRE = re.compile( '^CVSROOT:\s*(\S.*)')
- cvsmodeRE = re.compile( '^Cvsmode:\s*(\S.*)')
- filesRE = re.compile( '^Files:\s*(\S.*)')
- modRE = re.compile( '^Module:\s*(\S.*)')
- pathRE = re.compile( '^Path:\s*(\S.*)')
- projRE = re.compile( '^Project:\s*(\S.*)')
- singleFileRE = re.compile( '(.*) (NONE|\d(\.|\d)+) (NONE|\d(\.|\d)+)')
- tagRE = re.compile( '^\s+Tag:\s*(\S.*)')
- updateRE = re.compile( '^Update of:\s*(\S.*)')
- comments = ""
- branch = None
- cvsroot = None
- fileList = None
- files = []
- isdir = 0
- path = None
- project = None
-
- lines = list(body_line_iterator(m))
- while lines:
- line = lines.pop(0)
- m = catRE.match(line)
- if m:
- category = m.group(1)
- continue
- m = cvsRE.match(line)
- if m:
- cvsroot = m.group(1)
- continue
- m = cvsmodeRE.match(line)
- if m:
- cvsmode = m.group(1)
- continue
- m = filesRE.match(line)
- if m:
- fileList = m.group(1)
- continue
- m = modRE.match(line)
- if m:
- # We don't actually use this
- #module = m.group(1)
- continue
- m = pathRE.match(line)
- if m:
- path = m.group(1)
- continue
- m = projRE.match(line)
- if m:
- project = m.group(1)
- continue
- m = tagRE.match(line)
- if m:
- branch = m.group(1)
- continue
- m = updateRE.match(line)
- if m:
- # We don't actually use this
- #updateof = m.group(1)
- continue
- if line == "Log Message:\n":
- break
-
- # CVS 1.11 lists files as:
- # repo/path file,old-version,new-version file2,old-version,new-version
- # Version 1.12 lists files as:
- # file1 old-version new-version file2 old-version new-version
- #
- # files consists of tuples of 'file-name old-version new-version'
- # The versions are either dotted-decimal version numbers, ie 1.1
- # or NONE. New files are of the form 'NONE NUMBER', while removed
- # files are 'NUMBER NONE'. 'NONE' is a literal string
- # Parsing this instead of files list in 'Added File:' etc
- # makes it possible to handle files with embedded spaces, though
- # it could fail if the filename was 'bad 1.1 1.2'
- # For cvs version 1.11, we expect
- # my_module new_file.c,NONE,1.1
- # my_module removed.txt,1.2,NONE
- # my_module modified_file.c,1.1,1.2
- # While cvs version 1.12 gives us
- # new_file.c NONE 1.1
- # removed.txt 1.2 NONE
- # modified_file.c 1.1,1.2
-
- if fileList is None:
- log.msg('CVSMaildirSource Mail with no files. Ignoring')
- return None # We don't have any files. Email not from CVS
-
- if cvsmode == '1.11':
- # Please, no repo paths with spaces!
- m = re.search('([^ ]*) ', fileList)
- if m:
- path = m.group(1)
- else:
- log.msg('CVSMaildirSource can\'t get path from file list. Ignoring mail')
- return
- fileList = fileList[len(path):].strip()
- singleFileRE = re.compile( '(.+?),(NONE|(?:\d+\.(?:\d+\.\d+\.)*\d+)),(NONE|(?:\d+\.(?:\d+\.\d+\.)*\d+))(?: |$)')
- elif cvsmode == '1.12':
- singleFileRE = re.compile( '(.+?) (NONE|(?:\d+\.(?:\d+\.\d+\.)*\d+)) (NONE|(?:\d+\.(?:\d+\.\d+\.)*\d+))(?: |$)')
- if path is None:
- raise ValueError('CVSMaildirSource cvs 1.12 require path. Check cvs loginfo config')
- else:
- raise ValueError('Expected cvsmode 1.11 or 1.12. got: %s' % cvsmode)
-
- log.msg("CVSMaildirSource processing filelist: %s" % fileList)
- while(fileList):
- m = singleFileRE.match(fileList)
- if m:
- curFile = path + '/' + m.group(1)
- files.append( curFile )
- fileList = fileList[m.end():]
- else:
- log.msg('CVSMaildirSource no files matched regex. Ignoring')
- return None # bail - we couldn't parse the files that changed
- # Now get comments
- while lines:
- line = lines.pop(0)
- comments += line
-
- comments = comments.rstrip() + "\n"
- if comments == '\n':
- comments = None
- return ('cvs', dict(author=author, files=files, comments=comments,
- isdir=isdir, when=when, branch=branch,
- revision=rev, category=category,
- repository=cvsroot, project=project,
- properties=self.properties))
-
-# svn "commit-email.pl" handler. The format is very similar to freshcvs mail;
-# here's a sample:
-
-# From: username [at] apache.org [slightly obfuscated to avoid spam here]
-# To: commits [at] spamassassin.apache.org
-# Subject: svn commit: r105955 - in spamassassin/trunk: . lib/Mail
-# ...
-#
-# Author: username
-# Date: Sat Nov 20 00:17:49 2004 [note: TZ = local tz on server!]
-# New Revision: 105955
-#
-# Modified: [also Removed: and Added:]
-# [filename]
-# ...
-# Log:
-# [log message]
-# ...
-#
-#
-# Modified: spamassassin/trunk/lib/Mail/SpamAssassin.pm
-# [unified diff]
-#
-# [end of mail]
-
-class SVNCommitEmailMaildirSource(MaildirSource):
- name = "SVN commit-email.pl"
-
- def parse(self, m, prefix=None):
- """Parse messages sent by the svn 'commit-email.pl' trigger.
- """
-
- # The mail is sent from the person doing the checkin. Assume that the
- # local username is enough to identify them (this assumes a one-server
- # cvs-over-rsh environment rather than the server-dirs-shared-over-NFS
- # model)
- name, addr = parseaddr(m["from"])
- if not addr:
- return None # no From means this message isn't from svn
- at = addr.find("@")
- if at == -1:
- author = addr # might still be useful
- else:
- author = addr[:at]
-
- # we take the time of receipt as the time of checkin. Not correct (it
- # depends upon the email latency), but it avoids the
- # out-of-order-changes issue. Also syncmail doesn't give us anything
- # better to work with, unless you count pulling the v1-vs-v2
- # timestamp out of the diffs, which would be ugly. TODO: Pulling the
- # 'Date:' header from the mail is a possibility, and
- # email.Utils.parsedate_tz may be useful. It should be configurable,
- # however, because there are a lot of broken clocks out there.
- when = util.now()
-
- files = []
- comments = ""
- lines = list(body_line_iterator(m))
- rev = None
- while lines:
- line = lines.pop(0)
-
- # "Author: jmason"
- match = re.search(r"^Author: (\S+)", line)
- if match:
- author = match.group(1)
-
- # "New Revision: 105955"
- match = re.search(r"^New Revision: (\d+)", line)
- if match:
- rev = match.group(1)
-
- # possible TODO: use "Date: ..." data here instead of time of
- # commit message receipt, above. however, this timestamp is
- # specified *without* a timezone, in the server's local TZ, so to
- # be accurate buildbot would need a config setting to specify the
- # source server's expected TZ setting! messy.
-
- # this stanza ends with the "Log:"
- if (line == "Log:\n"):
- break
-
- # commit message is terminated by the file-listing section
- while lines:
- line = lines.pop(0)
- if (line == "Modified:\n" or
- line == "Added:\n" or
- line == "Removed:\n"):
- break
- comments += line
- comments = comments.rstrip() + "\n"
-
- while lines:
- line = lines.pop(0)
- if line == "\n":
- break
- if line.find("Modified:\n") == 0:
- continue # ignore this line
- if line.find("Added:\n") == 0:
- continue # ignore this line
- if line.find("Removed:\n") == 0:
- continue # ignore this line
- line = line.strip()
-
- thesefiles = line.split(" ")
- for f in thesefiles:
- if prefix:
- # insist that the file start with the prefix: we may get
- # changes we don't care about too
- if f.startswith(prefix):
- f = f[len(prefix):]
- else:
- log.msg("ignored file from svn commit: prefix '%s' "
- "does not match filename '%s'" % (prefix, f))
- continue
-
- # TODO: figure out how new directories are described, set
- # .isdir
- files.append(f)
-
- if not files:
- log.msg("no matching files found, ignoring commit")
- return None
-
- return ('svn', dict(author=author, files=files, comments=comments,
- when=when, revision=rev))
-
-# bzr Launchpad branch subscription mails. Sample mail:
-#
-# From: noreply@launchpad.net
-# Subject: [Branch ~knielsen/maria/tmp-buildbot-test] Rev 2701: test add file
-# To: Joe <joe@acme.com>
-# ...
-#
-# ------------------------------------------------------------
-# revno: 2701
-# committer: Joe <joe@acme.com>
-# branch nick: tmpbb
-# timestamp: Fri 2009-05-15 10:35:43 +0200
-# message:
-# test add file
-# added:
-# test-add-file
-#
-#
-# --
-#
-# https://code.launchpad.net/~knielsen/maria/tmp-buildbot-test
-#
-# You are subscribed to branch lp:~knielsen/maria/tmp-buildbot-test.
-# To unsubscribe from this branch go to https://code.launchpad.net/~knielsen/maria/tmp-buildbot-test/+edit-subscription.
-#
-# [end of mail]
-
-class BzrLaunchpadEmailMaildirSource(MaildirSource):
- name = "Launchpad"
-
- compare_attrs = MaildirSource.compare_attrs + ["branchMap", "defaultBranch"]
-
- def __init__(self, maildir, prefix=None, branchMap=None, defaultBranch=None, **kwargs):
- self.branchMap = branchMap
- self.defaultBranch = defaultBranch
- MaildirSource.__init__(self, maildir, prefix, **kwargs)
-
- def parse(self, m, prefix=None):
- """Parse branch notification messages sent by Launchpad.
- """
-
- subject = m["subject"]
- match = re.search(r"^\s*\[Branch\s+([^]]+)\]", subject)
- if match:
- repository = match.group(1)
- else:
- repository = None
-
- # Put these into a dictionary, otherwise we cannot assign them
- # from nested function definitions.
- d = { 'files': [], 'comments': u"" }
- gobbler = None
- rev = None
- author = None
- when = util.now()
- def gobble_comment(s):
- d['comments'] += s + "\n"
- def gobble_removed(s):
- d['files'].append('%s REMOVED' % s)
- def gobble_added(s):
- d['files'].append('%s ADDED' % s)
- def gobble_modified(s):
- d['files'].append('%s MODIFIED' % s)
- def gobble_renamed(s):
- match = re.search(r"^(.+) => (.+)$", s)
- if match:
- d['files'].append('%s RENAMED %s' % (match.group(1), match.group(2)))
- else:
- d['files'].append('%s RENAMED' % s)
-
- lines = list(body_line_iterator(m, True))
- rev = None
- while lines:
- line = unicode(lines.pop(0), "utf-8", errors="ignore")
-
- # revno: 101
- match = re.search(r"^revno: ([0-9.]+)", line)
- if match:
- rev = match.group(1)
-
- # committer: Joe <joe@acme.com>
- match = re.search(r"^committer: (.*)$", line)
- if match:
- author = match.group(1)
-
- # timestamp: Fri 2009-05-15 10:35:43 +0200
- # datetime.strptime() is supposed to support %z for time zone, but
- # it does not seem to work. So handle the time zone manually.
- match = re.search(r"^timestamp: [a-zA-Z]{3} (\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) ([-+])(\d{2})(\d{2})$", line)
- if match:
- datestr = match.group(1)
- tz_sign = match.group(2)
- tz_hours = match.group(3)
- tz_minutes = match.group(4)
- when = parseLaunchpadDate(datestr, tz_sign, tz_hours, tz_minutes)
-
- if re.search(r"^message:\s*$", line):
- gobbler = gobble_comment
- elif re.search(r"^removed:\s*$", line):
- gobbler = gobble_removed
- elif re.search(r"^added:\s*$", line):
- gobbler = gobble_added
- elif re.search(r"^renamed:\s*$", line):
- gobbler = gobble_renamed
- elif re.search(r"^modified:\s*$", line):
- gobbler = gobble_modified
- elif re.search(r"^ ", line) and gobbler:
- gobbler(line[2:-1]) # Use :-1 to gobble trailing newline
-
- # Determine the name of the branch.
- branch = None
- if self.branchMap and repository:
- if self.branchMap.has_key(repository):
- branch = self.branchMap[repository]
- elif self.branchMap.has_key('lp:' + repository):
- branch = self.branchMap['lp:' + repository]
- if not branch:
- if self.defaultBranch:
- branch = self.defaultBranch
- else:
- if repository:
- branch = 'lp:' + repository
- else:
- branch = None
-
- if rev and author:
- return ('bzr', dict(author=author, files=d['files'],
- comments=d['comments'],
- when=when, revision=rev,
- branch=branch, repository=repository or ''))
- else:
- return None
-
-def parseLaunchpadDate(datestr, tz_sign, tz_hours, tz_minutes):
- time_no_tz = calendar.timegm(time.strptime(datestr, "%Y-%m-%d %H:%M:%S"))
- tz_delta = 60 * 60 * int(tz_sign + tz_hours) + 60 * int(tz_minutes)
- return time_no_tz - tz_delta
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/manager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/manager.py
deleted file mode 100644
index 49eaa3bc..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/manager.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# 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
-
-from zope.interface import implements
-from twisted.python import log
-from twisted.internet import defer
-from twisted.application import service
-from buildbot import interfaces, config, util
-from buildbot.process import metrics
-
-class ChangeManager(config.ReconfigurableServiceMixin, service.MultiService):
- """
- This is the master-side service which receives file change notifications
- from version-control systems.
-
- It is a Twisted service, which has instances of
- L{buildbot.interfaces.IChangeSource} as child services. These are added by
- the master with C{addSource}.
- """
-
- implements(interfaces.IEventSource)
-
- name = "changemanager"
-
- def __init__(self, master):
- service.MultiService.__init__(self)
- self.setName('change_manager')
- self.master = master
-
- @defer.inlineCallbacks
- def reconfigService(self, new_config):
- timer = metrics.Timer("ChangeManager.reconfigService")
- timer.start()
-
- removed, added = util.diffSets(
- set(self),
- new_config.change_sources)
-
- if removed or added:
- log.msg("adding %d new changesources, removing %d" %
- (len(added), len(removed)))
-
- for src in removed:
- yield defer.maybeDeferred(
- src.disownServiceParent)
- src.master = None
-
- for src in added:
- src.master = self.master
- src.setServiceParent(self)
-
- num_sources = len(list(self))
- assert num_sources == len(new_config.change_sources)
- metrics.MetricCountEvent.log("num_sources", num_sources, absolute=True)
-
- # reconfig any newly-added change sources, as well as existing
- yield config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
- timer.stop()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/p4poller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/p4poller.py
deleted file mode 100644
index 4dbc56ec..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/p4poller.py
+++ /dev/null
@@ -1,192 +0,0 @@
-# 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.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright 2011 National Instruments
-
-
-# Many thanks to Dave Peticolas for contributing this module
-
-import re
-import time
-import os
-
-from twisted.python import log
-from twisted.internet import defer, utils
-
-from buildbot import util
-from buildbot.changes import base
-
-class P4PollerError(Exception):
- """Something went wrong with the poll. This is used as a distinctive
- exception type so that unit tests can detect and ignore it."""
-
-def get_simple_split(branchfile):
- """Splits the branchfile argument and assuming branch is
- the first path component in branchfile, will return
- branch and file else None."""
-
- index = branchfile.find('/')
- if index == -1: return None, None
- branch, file = branchfile.split('/', 1)
- return branch, file
-
-class P4Source(base.PollingChangeSource, util.ComparableMixin):
- """This source will poll a perforce repository for changes and submit
- them to the change master."""
-
- compare_attrs = ["p4port", "p4user", "p4passwd", "p4base",
- "p4bin", "pollInterval"]
-
- env_vars = ["P4CLIENT", "P4PORT", "P4PASSWD", "P4USER",
- "P4CHARSET" , "PATH"]
-
- changes_line_re = re.compile(
- r"Change (?P<num>\d+) on \S+ by \S+@\S+ '.*'$")
- describe_header_re = re.compile(
- r"Change \d+ by (?P<who>\S+)@\S+ on (?P<when>.+)$")
- file_re = re.compile(r"^\.\.\. (?P<path>[^#]+)#\d+ [/\w]+$")
- datefmt = '%Y/%m/%d %H:%M:%S'
-
- parent = None # filled in when we're added
- last_change = None
- loop = None
-
- def __init__(self, p4port=None, p4user=None, p4passwd=None,
- p4base='//', p4bin='p4',
- split_file=lambda branchfile: (None, branchfile),
- pollInterval=60 * 10, histmax=None, pollinterval=-2,
- encoding='utf8', project=None, name=None):
-
- # for backward compatibility; the parameter used to be spelled with 'i'
- if pollinterval != -2:
- pollInterval = pollinterval
-
- base.PollingChangeSource.__init__(self, name=name, pollInterval=pollInterval)
-
- if project is None:
- project = ''
-
- self.p4port = p4port
- self.p4user = p4user
- self.p4passwd = p4passwd
- self.p4base = p4base
- self.p4bin = p4bin
- self.split_file = split_file
- self.encoding = encoding
- self.project = project
-
- def describe(self):
- return "p4source %s %s" % (self.p4port, self.p4base)
-
- def poll(self):
- d = self._poll()
- d.addErrback(log.err, 'P4 poll failed')
- return d
-
- def _get_process_output(self, args):
- env = dict([(e, os.environ.get(e)) for e in self.env_vars if os.environ.get(e)])
- d = utils.getProcessOutput(self.p4bin, args, env)
- return d
-
- @defer.inlineCallbacks
- def _poll(self):
- args = []
- if self.p4port:
- args.extend(['-p', self.p4port])
- if self.p4user:
- args.extend(['-u', self.p4user])
- if self.p4passwd:
- args.extend(['-P', self.p4passwd])
- args.extend(['changes'])
- if self.last_change is not None:
- args.extend(['%s...@%d,now' % (self.p4base, self.last_change+1)])
- else:
- args.extend(['-m', '1', '%s...' % (self.p4base,)])
-
- result = yield self._get_process_output(args)
-
- last_change = self.last_change
- changelists = []
- for line in result.split('\n'):
- line = line.strip()
- if not line: continue
- m = self.changes_line_re.match(line)
- if not m:
- raise P4PollerError("Unexpected 'p4 changes' output: %r" % result)
- num = int(m.group('num'))
- if last_change is None:
- # first time through, the poller just gets a "baseline" for where to
- # start on the next poll
- log.msg('P4Poller: starting at change %d' % num)
- self.last_change = num
- return
- changelists.append(num)
- changelists.reverse() # oldest first
-
- # Retrieve each sequentially.
- for num in changelists:
- args = []
- if self.p4port:
- args.extend(['-p', self.p4port])
- if self.p4user:
- args.extend(['-u', self.p4user])
- if self.p4passwd:
- args.extend(['-P', self.p4passwd])
- args.extend(['describe', '-s', str(num)])
- result = yield self._get_process_output(args)
-
- # decode the result from its designated encoding
- result = result.decode(self.encoding)
-
- lines = result.split('\n')
- # SF#1555985: Wade Brainerd reports a stray ^M at the end of the date
- # field. The rstrip() is intended to remove that.
- lines[0] = lines[0].rstrip()
- m = self.describe_header_re.match(lines[0])
- if not m:
- raise P4PollerError("Unexpected 'p4 describe -s' result: %r" % result)
- who = m.group('who')
- when = time.mktime(time.strptime(m.group('when'), self.datefmt))
- comments = ''
- while not lines[0].startswith('Affected files'):
- comments += lines.pop(0) + '\n'
- lines.pop(0) # affected files
-
- branch_files = {} # dict for branch mapped to file(s)
- while lines:
- line = lines.pop(0).strip()
- if not line: continue
- m = self.file_re.match(line)
- if not m:
- raise P4PollerError("Invalid file line: %r" % line)
- path = m.group('path')
- if path.startswith(self.p4base):
- branch, file = self.split_file(path[len(self.p4base):])
- if (branch == None and file == None): continue
- if branch_files.has_key(branch):
- branch_files[branch].append(file)
- else:
- branch_files[branch] = [file]
-
- for branch in branch_files:
- yield self.master.addChange(
- author=who,
- files=branch_files[branch],
- comments=comments,
- revision=str(num),
- when_timestamp=util.epoch2datetime(when),
- branch=branch,
- project=self.project)
-
- self.last_change = num
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/pb.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/pb.py
deleted file mode 100644
index a73dca16..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/pb.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# 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
-
-
-from twisted.python import log
-from twisted.internet import defer
-
-from buildbot.pbutil import NewCredPerspective
-from buildbot.changes import base
-from buildbot.util import epoch2datetime
-from buildbot import config
-
-class ChangePerspective(NewCredPerspective):
-
- def __init__(self, master, prefix):
- self.master = master
- self.prefix = prefix
-
- def attached(self, mind):
- return self
- def detached(self, mind):
- pass
-
- def perspective_addChange(self, changedict):
- log.msg("perspective_addChange called")
-
- if 'revlink' in changedict and not changedict['revlink']:
- changedict['revlink'] = ''
- if 'repository' in changedict and not changedict['repository']:
- changedict['repository'] = ''
- if 'project' in changedict and not changedict['project']:
- changedict['project'] = ''
- if 'files' not in changedict or not changedict['files']:
- changedict['files'] = []
-
- # rename arguments to new names. Note that the client still uses the
- # "old" names (who, when, and isdir), as they are not deprecated yet,
- # although the master will accept the new names (author,
- # when_timestamp, and is_dir). After a few revisions have passed, we
- # can switch the client to use the new names.
- if 'isdir' in changedict:
- changedict['is_dir'] = changedict['isdir']
- del changedict['isdir']
- if 'who' in changedict:
- changedict['author'] = changedict['who']
- del changedict['who']
- if 'when' in changedict:
- when = None
- if changedict['when'] is not None:
- when = epoch2datetime(changedict['when'])
- changedict['when_timestamp'] = when
- del changedict['when']
-
- # turn any bytestring keys into unicode, assuming utf8 but just
- # replacing unknown characters. Ideally client would send us unicode
- # in the first place, but older clients do not, so this fallback is
- # useful.
- for key in changedict:
- if type(changedict[key]) == str:
- changedict[key] = changedict[key].decode('utf8', 'replace')
- changedict['files'] = list(changedict['files'])
- for i, file in enumerate(changedict.get('files', [])):
- if type(file) == str:
- changedict['files'][i] = file.decode('utf8', 'replace')
-
- files = []
- for path in changedict['files']:
- if self.prefix:
- if not path.startswith(self.prefix):
- # this file does not start with the prefix, so ignore it
- continue
- path = path[len(self.prefix):]
- files.append(path)
- changedict['files'] = files
-
- if not files:
- log.msg("No files listed in change... bit strange, but not fatal.")
-
- if changedict.has_key('links'):
- log.msg("Found links: "+repr(changedict['links']))
- del changedict['links']
-
- d = self.master.addChange(**changedict)
- # since this is a remote method, we can't return a Change instance, so
- # this just sets the return value to None:
- d.addCallback(lambda _ : None)
- return d
-
-class PBChangeSource(config.ReconfigurableServiceMixin, base.ChangeSource):
- compare_attrs = ["user", "passwd", "port", "prefix", "port"]
-
- def __init__(self, user="change", passwd="changepw", port=None,
- prefix=None):
-
- self.user = user
- self.passwd = passwd
- self.port = port
- self.prefix = prefix
- self.registration = None
- self.registered_port = None
-
- def describe(self):
- portname = self.registered_port
- d = "PBChangeSource listener on " + str(portname)
- if self.prefix is not None:
- d += " (prefix '%s')" % self.prefix
- return d
-
- @defer.inlineCallbacks
- def reconfigService(self, new_config):
- # calculate the new port
- port = self.port
- if port is None:
- port = new_config.slavePortnum
-
- # and, if it's changed, re-register
- if port != self.registered_port:
- yield self._unregister()
- self._register(port)
-
- yield config.ReconfigurableServiceMixin.reconfigService(
- self, new_config)
-
- def stopService(self):
- d = defer.maybeDeferred(base.ChangeSource.stopService, self)
- d.addCallback(lambda _ : self._unregister())
- return d
-
- def _register(self, port):
- if not port:
- log.msg("PBChangeSource has no port to listen on")
- return
- self.registered_port = port
- self.registration = self.master.pbmanager.register(
- port, self.user, self.passwd,
- self.getPerspective)
-
- def _unregister(self):
- self.registered_port = None
- if self.registration:
- reg = self.registration
- self.registration = None
- return reg.unregister()
- else:
- return defer.succeed(None)
-
- def getPerspective(self, mind, username):
- assert username == self.user
- return ChangePerspective(self.master, self.prefix)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/svnpoller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/svnpoller.py
deleted file mode 100644
index 1e2fde81..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/changes/svnpoller.py
+++ /dev/null
@@ -1,412 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-
-# Based on the work of Dave Peticolas for the P4poll
-# Changed to svn (using xml.dom.minidom) by Niklaus Giger
-# Hacked beyond recognition by Brian Warner
-
-from twisted.python import log
-from twisted.internet import defer, utils
-
-from buildbot import util
-from buildbot.changes import base
-
-import xml.dom.minidom
-import os, urllib
-
-# these split_file_* functions are available for use as values to the
-# split_file= argument.
-def split_file_alwaystrunk(path):
- return dict(path=path)
-
-def split_file_branches(path):
- # turn "trunk/subdir/file.c" into (None, "subdir/file.c")
- # and "trunk/subdir/" into (None, "subdir/")
- # and "trunk/" into (None, "")
- # and "branches/1.5.x/subdir/file.c" into ("branches/1.5.x", "subdir/file.c")
- # and "branches/1.5.x/subdir/" into ("branches/1.5.x", "subdir/")
- # and "branches/1.5.x/" into ("branches/1.5.x", "")
- pieces = path.split('/')
- if len(pieces) > 1 and pieces[0] == 'trunk':
- return (None, '/'.join(pieces[1:]))
- elif len(pieces) > 2 and pieces[0] == 'branches':
- return ('/'.join(pieces[0:2]), '/'.join(pieces[2:]))
- else:
- return None
-
-def split_file_projects_branches(path):
- # turn projectname/trunk/subdir/file.c into dict(project=projectname, branch=trunk, path=subdir/file.c)
- if not "/" in path:
- return None
- project, path = path.split("/", 1)
- f = split_file_branches(path)
- if f:
- info = dict(project=project, path=f[1])
- if f[0]:
- info['branch'] = f[0]
- return info
- return f
-
-class SVNPoller(base.PollingChangeSource, util.ComparableMixin):
- """
- Poll a Subversion repository for changes and submit them to the change
- master.
- """
-
- compare_attrs = ["svnurl", "split_file",
- "svnuser", "svnpasswd", "project",
- "pollInterval", "histmax",
- "svnbin", "category", "cachepath"]
-
- parent = None # filled in when we're added
- last_change = None
- loop = None
-
- def __init__(self, svnurl, split_file=None,
- svnuser=None, svnpasswd=None,
- pollInterval=10*60, histmax=100,
- svnbin='svn', revlinktmpl='', category=None,
- project='', cachepath=None, pollinterval=-2,
- extra_args=None):
-
- # for backward compatibility; the parameter used to be spelled with 'i'
- if pollinterval != -2:
- pollInterval = pollinterval
-
- base.PollingChangeSource.__init__(self, name=svnurl, pollInterval=pollInterval)
-
- if svnurl.endswith("/"):
- svnurl = svnurl[:-1] # strip the trailing slash
- self.svnurl = svnurl
- self.extra_args = extra_args
- self.split_file = split_file or split_file_alwaystrunk
- self.svnuser = svnuser
- self.svnpasswd = svnpasswd
-
- self.revlinktmpl = revlinktmpl
-
- self.environ = os.environ.copy() # include environment variables
- # required for ssh-agent auth
-
- self.svnbin = svnbin
- self.histmax = histmax
- self._prefix = None
- self.category = category
- self.project = project
-
- self.cachepath = cachepath
- if self.cachepath and os.path.exists(self.cachepath):
- try:
- with open(self.cachepath, "r") as f:
- self.last_change = int(f.read().strip())
- log.msg("SVNPoller: SVNPoller(%s) setting last_change to %s" % (self.svnurl, self.last_change))
- # try writing it, too
- with open(self.cachepath, "w") as f:
- f.write(str(self.last_change))
- except:
- self.cachepath = None
- log.msg(("SVNPoller: SVNPoller(%s) cache file corrupt or unwriteable; " +
- "skipping and not using") % self.svnurl)
- log.err()
-
- def describe(self):
- return "SVNPoller: watching %s" % self.svnurl
-
- def poll(self):
- # Our return value is only used for unit testing.
-
- # we need to figure out the repository root, so we can figure out
- # repository-relative pathnames later. Each SVNURL is in the form
- # (ROOT)/(PROJECT)/(BRANCH)/(FILEPATH), where (ROOT) is something
- # like svn://svn.twistedmatrix.com/svn/Twisted (i.e. there is a
- # physical repository at /svn/Twisted on that host), (PROJECT) is
- # something like Projects/Twisted (i.e. within the repository's
- # internal namespace, everything under Projects/Twisted/ has
- # something to do with Twisted, but these directory names do not
- # actually appear on the repository host), (BRANCH) is something like
- # "trunk" or "branches/2.0.x", and (FILEPATH) is a tree-relative
- # filename like "twisted/internet/defer.py".
-
- # our self.svnurl attribute contains (ROOT)/(PROJECT) combined
- # together in a way that we can't separate without svn's help. If the
- # user is not using the split_file= argument, then self.svnurl might
- # be (ROOT)/(PROJECT)/(BRANCH) . In any case, the filenames we will
- # get back from 'svn log' will be of the form
- # (PROJECT)/(BRANCH)/(FILEPATH), but we want to be able to remove
- # that (PROJECT) prefix from them. To do this without requiring the
- # user to tell us how svnurl is split into ROOT and PROJECT, we do an
- # 'svn info --xml' command at startup. This command will include a
- # <root> element that tells us ROOT. We then strip this prefix from
- # self.svnurl to determine PROJECT, and then later we strip the
- # PROJECT prefix from the filenames reported by 'svn log --xml' to
- # get a (BRANCH)/(FILEPATH) that can be passed to split_file() to
- # turn into separate BRANCH and FILEPATH values.
-
- # whew.
-
- if self.project:
- log.msg("SVNPoller: polling " + self.project)
- else:
- log.msg("SVNPoller: polling")
-
- d = defer.succeed(None)
- if not self._prefix:
- d.addCallback(lambda _ : self.get_prefix())
- def set_prefix(prefix):
- self._prefix = prefix
- d.addCallback(set_prefix)
-
- d.addCallback(self.get_logs)
- d.addCallback(self.parse_logs)
- d.addCallback(self.get_new_logentries)
- d.addCallback(self.create_changes)
- d.addCallback(self.submit_changes)
- d.addCallback(self.finished_ok)
- d.addErrback(log.err, 'SVNPoller: Error in while polling') # eat errors
- return d
-
- def getProcessOutput(self, args):
- # this exists so we can override it during the unit tests
- d = utils.getProcessOutput(self.svnbin, args, self.environ)
- return d
-
- def get_prefix(self):
- args = ["info", "--xml", "--non-interactive", self.svnurl]
- if self.svnuser:
- args.extend(["--username=%s" % self.svnuser])
- if self.svnpasswd:
- args.extend(["--password=%s" % self.svnpasswd])
- if self.extra_args:
- args.extend(self.extra_args)
- d = self.getProcessOutput(args)
- def determine_prefix(output):
- try:
- doc = xml.dom.minidom.parseString(output)
- except xml.parsers.expat.ExpatError:
- log.msg("SVNPoller: SVNPoller._determine_prefix_2: ExpatError in '%s'"
- % output)
- raise
- rootnodes = doc.getElementsByTagName("root")
- if not rootnodes:
- # this happens if the URL we gave was already the root. In this
- # case, our prefix is empty.
- self._prefix = ""
- return self._prefix
- rootnode = rootnodes[0]
- root = "".join([c.data for c in rootnode.childNodes])
- # root will be a unicode string
- if not self.svnurl.startswith(root):
- log.msg(format="svnurl='%(svnurl)s' doesn't start with <root>='%(root)s'",
- svnurl=self.svnurl, root=root)
- raise RuntimeError("Can't handle redirected svn connections!? "
- "This shouldn't happen.")
- prefix = self.svnurl[len(root):]
- if prefix.startswith("/"):
- prefix = prefix[1:]
- log.msg("SVNPoller: svnurl=%s, root=%s, so prefix=%s" %
- (self.svnurl, root, prefix))
- return prefix
- d.addCallback(determine_prefix)
- return d
-
- def get_logs(self, _):
- args = []
- args.extend(["log", "--xml", "--verbose", "--non-interactive"])
- if self.svnuser:
- args.extend(["--username=%s" % self.svnuser])
- if self.svnpasswd:
- args.extend(["--password=%s" % self.svnpasswd])
- if self.extra_args:
- args.extend(self.extra_args)
- args.extend(["--limit=%d" % (self.histmax), self.svnurl])
- d = self.getProcessOutput(args)
- return d
-
- def parse_logs(self, output):
- # parse the XML output, return a list of <logentry> nodes
- try:
- doc = xml.dom.minidom.parseString(output)
- except xml.parsers.expat.ExpatError:
- log.msg("SVNPoller: SVNPoller.parse_logs: ExpatError in '%s'" % output)
- raise
- logentries = doc.getElementsByTagName("logentry")
- return logentries
-
-
- def get_new_logentries(self, logentries):
- last_change = old_last_change = self.last_change
-
- # given a list of logentries, calculate new_last_change, and
- # new_logentries, where new_logentries contains only the ones after
- # last_change
-
- new_last_change = None
- new_logentries = []
- if logentries:
- new_last_change = int(logentries[0].getAttribute("revision"))
-
- if last_change is None:
- # if this is the first time we've been run, ignore any changes
- # that occurred before now. This prevents a build at every
- # startup.
- log.msg('SVNPoller: starting at change %s' % new_last_change)
- elif last_change == new_last_change:
- # an unmodified repository will hit this case
- log.msg('SVNPoller: no changes')
- else:
- for el in logentries:
- if last_change == int(el.getAttribute("revision")):
- break
- new_logentries.append(el)
- new_logentries.reverse() # return oldest first
-
- self.last_change = new_last_change
- log.msg('SVNPoller: _process_changes %s .. %s' %
- (old_last_change, new_last_change))
- return new_logentries
-
-
- def _get_text(self, element, tag_name):
- try:
- child_nodes = element.getElementsByTagName(tag_name)[0].childNodes
- text = "".join([t.data for t in child_nodes])
- except:
- text = "<unknown>"
- return text
-
- def _transform_path(self, path):
- if not path.startswith(self._prefix):
- log.msg(format="SVNPoller: ignoring path '%(path)s' which doesn't"
- "start with prefix '%(prefix)s'",
- path=path, prefix=self._prefix)
- return
- relative_path = path[len(self._prefix):]
- if relative_path.startswith("/"):
- relative_path = relative_path[1:]
- where = self.split_file(relative_path)
- # 'where' is either None, (branch, final_path) or a dict
- if not where:
- return
- if isinstance(where, tuple):
- where = dict(branch=where[0], path=where[1])
- return where
-
- def create_changes(self, new_logentries):
- changes = []
-
- for el in new_logentries:
- revision = str(el.getAttribute("revision"))
-
- revlink=''
-
- if self.revlinktmpl:
- if revision:
- revlink = self.revlinktmpl % urllib.quote_plus(revision)
-
- log.msg("Adding change revision %s" % (revision,))
- author = self._get_text(el, "author")
- comments = self._get_text(el, "msg")
- # there is a "date" field, but it provides localtime in the
- # repository's timezone, whereas we care about buildmaster's
- # localtime (since this will get used to position the boxes on
- # the Waterfall display, etc). So ignore the date field, and
- # addChange will fill in with the current time
- branches = {}
- try:
- pathlist = el.getElementsByTagName("paths")[0]
- except IndexError: # weird, we got an empty revision
- log.msg("ignoring commit with no paths")
- continue
-
- for p in pathlist.getElementsByTagName("path"):
- kind = p.getAttribute("kind")
- action = p.getAttribute("action")
- path = "".join([t.data for t in p.childNodes])
- # the rest of buildbot is certaily not yet ready to handle
- # unicode filenames, because they get put in RemoteCommands
- # which get sent via PB to the buildslave, and PB doesn't
- # handle unicode.
- path = path.encode("ascii")
- if path.startswith("/"):
- path = path[1:]
- if kind == "dir" and not path.endswith("/"):
- path += "/"
- where = self._transform_path(path)
-
- # if 'where' is None, the file was outside any project that
- # we care about and we should ignore it
- if where:
- branch = where.get("branch", None)
- filename = where["path"]
- if not branch in branches:
- branches[branch] = { 'files': [], 'number_of_directories': 0}
- if filename == "":
- # root directory of branch
- branches[branch]['files'].append(filename)
- branches[branch]['number_of_directories'] += 1
- elif filename.endswith("/"):
- # subdirectory of branch
- branches[branch]['files'].append(filename[:-1])
- branches[branch]['number_of_directories'] += 1
- else:
- branches[branch]['files'].append(filename)
-
- if not branches[branch].has_key('action'):
- branches[branch]['action'] = action
-
- for key in ("repository", "project", "codebase"):
- if key in where:
- branches[branch][key] = where[key]
-
- for branch in branches.keys():
- action = branches[branch]['action']
- files = branches[branch]['files']
-
- number_of_directories_changed = branches[branch]['number_of_directories']
- number_of_files_changed = len(files)
-
- if action == u'D' and number_of_directories_changed == 1 and number_of_files_changed == 1 and files[0] == '':
- log.msg("Ignoring deletion of branch '%s'" % branch)
- else:
- chdict = dict(
- author=author,
- files=files,
- comments=comments,
- revision=revision,
- branch=branch,
- revlink=revlink,
- category=self.category,
- repository=branches[branch].get('repository', self.svnurl),
- project=branches[branch].get('project', self.project),
- codebase=branches[branch].get('codebase', None))
- changes.append(chdict)
-
- return changes
-
- @defer.inlineCallbacks
- def submit_changes(self, changes):
- for chdict in changes:
- yield self.master.addChange(src='svn', **chdict)
-
- def finished_ok(self, res):
- if self.cachepath:
- with open(self.cachepath, "w") as f:
- f.write(str(self.last_change))
-
- log.msg("SVNPoller: finished polling %s" % res)
- return res
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/base.py
deleted file mode 100644
index 24e2cfd6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/base.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# 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
-
-
-from twisted.spread import pb
-
-class StatusClient(pb.Referenceable):
- """To use this, call my .connected method with a RemoteReference to the
- buildmaster's StatusClientPerspective object.
- """
-
- def __init__(self, events):
- self.builders = {}
- self.events = events
-
- def connected(self, remote):
- print "connected"
- self.remote = remote
- remote.callRemote("subscribe", self.events, 5, self)
-
- def remote_builderAdded(self, buildername, builder):
- print "builderAdded", buildername
-
- def remote_builderRemoved(self, buildername):
- print "builderRemoved", buildername
-
- def remote_builderChangedState(self, buildername, state, eta):
- print "builderChangedState", buildername, state, eta
-
- def remote_buildStarted(self, buildername, build):
- print "buildStarted", buildername
-
- def remote_buildFinished(self, buildername, build, results):
- print "buildFinished", results
-
- def remote_buildETAUpdate(self, buildername, build, eta):
- print "ETA", buildername, eta
-
- def remote_stepStarted(self, buildername, build, stepname, step):
- print "stepStarted", buildername, stepname
-
- def remote_stepFinished(self, buildername, build, stepname, step, results):
- print "stepFinished", buildername, stepname, results
-
- def remote_stepETAUpdate(self, buildername, build, stepname, step,
- eta, expectations):
- print "stepETA", buildername, stepname, eta
-
- def remote_logStarted(self, buildername, build, stepname, step,
- logname, log):
- print "logStarted", buildername, stepname
-
- def remote_logFinished(self, buildername, build, stepname, step,
- logname, log):
- print "logFinished", buildername, stepname
-
- def remote_logChunk(self, buildername, build, stepname, step, logname, log,
- channel, text):
- ChunkTypes = ["STDOUT", "STDERR", "HEADER"]
- print "logChunk[%s]: %s" % (ChunkTypes[channel], text)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/debug.glade b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/debug.glade
deleted file mode 100644
index 40468bb9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/debug.glade
+++ /dev/null
@@ -1,684 +0,0 @@
-<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
-<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
-
-<glade-interface>
-<requires lib="gnome"/>
-
-<widget class="GtkWindow" id="window1">
- <property name="visible">True</property>
- <property name="title" translatable="yes">Buildbot Debug Tool</property>
- <property name="type">GTK_WINDOW_TOPLEVEL</property>
- <property name="window_position">GTK_WIN_POS_NONE</property>
- <property name="modal">False</property>
- <property name="resizable">True</property>
- <property name="destroy_with_parent">False</property>
- <property name="decorated">True</property>
- <property name="skip_taskbar_hint">False</property>
- <property name="skip_pager_hint">False</property>
- <property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
- <property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
- <property name="focus_on_map">True</property>
- <property name="urgency_hint">False</property>
-
- <child>
- <widget class="GtkVBox" id="vbox1">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkHBox" id="connection">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkButton" id="connectbutton">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Connect</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_connect"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkLabel" id="connectlabel">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Disconnected</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="commands">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkButton" id="reload">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Reload .cfg</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_reload" last_modification_time="Wed, 24 Sep 2003 20:47:55 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="rebuild">
- <property name="visible">True</property>
- <property name="sensitive">False</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Rebuild .py</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_rebuild" last_modification_time="Wed, 24 Sep 2003 20:49:18 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="button7">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">poke IRC</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_poke_irc" last_modification_time="Wed, 14 Jan 2004 22:23:59 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox3">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkCheckButton" id="usebranch">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Branch:</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_usebranch_toggled" last_modification_time="Tue, 25 Oct 2005 01:42:45 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="branch">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox1">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkCheckButton" id="userevision">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Revision:</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <property name="active">False</property>
- <property name="inconsistent">False</property>
- <property name="draw_indicator">True</property>
- <signal name="toggled" handler="on_userevision_toggled" last_modification_time="Wed, 08 Sep 2004 17:58:33 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="revision">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes"></property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFrame" id="Commit">
- <property name="border_width">4</property>
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="label_yalign">0.5</property>
- <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-
- <child>
- <widget class="GtkAlignment" id="alignment1">
- <property name="visible">True</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xscale">1</property>
- <property name="yscale">1</property>
- <property name="top_padding">0</property>
- <property name="bottom_padding">0</property>
- <property name="left_padding">0</property>
- <property name="right_padding">0</property>
-
- <child>
- <widget class="GtkVBox" id="vbox3">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkHBox" id="commit">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkButton" id="button2">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">commit</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_commit"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="filename">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes">twisted/internet/app.py</property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="hbox2">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="label5">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Who: </property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="who">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes">bob</property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label4">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Commit</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">2</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkFrame" id="builderframe">
- <property name="border_width">4</property>
- <property name="visible">True</property>
- <property name="label_xalign">0</property>
- <property name="label_yalign">0.5</property>
- <property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
-
- <child>
- <widget class="GtkVBox" id="vbox2">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkHBox" id="builder">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">3</property>
-
- <child>
- <widget class="GtkLabel" id="label1">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Builder:</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">0</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkEntry" id="buildname">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="editable">True</property>
- <property name="visibility">True</property>
- <property name="max_length">0</property>
- <property name="text" translatable="yes">one</property>
- <property name="has_frame">True</property>
- <property name="invisible_char">*</property>
- <property name="activates_default">False</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="buildercontrol">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkButton" id="button1">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Request
-Build</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_build"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="button8">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">Ping
-Builder</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_ping" last_modification_time="Fri, 24 Nov 2006 05:18:51 GMT"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <placeholder/>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkHBox" id="status">
- <property name="visible">True</property>
- <property name="homogeneous">False</property>
- <property name="spacing">0</property>
-
- <child>
- <widget class="GtkLabel" id="label2">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Currently:</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_CENTER</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">7</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="button3">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">offline</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_current_offline"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="button4">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">idle</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_current_idle"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="button5">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">waiting</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_current_waiting"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
-
- <child>
- <widget class="GtkButton" id="button6">
- <property name="visible">True</property>
- <property name="can_focus">True</property>
- <property name="label" translatable="yes">building</property>
- <property name="use_underline">True</property>
- <property name="relief">GTK_RELIEF_NORMAL</property>
- <property name="focus_on_click">True</property>
- <signal name="clicked" handler="do_current_building"/>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">False</property>
- <property name="fill">False</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
-
- <child>
- <widget class="GtkLabel" id="label3">
- <property name="visible">True</property>
- <property name="label" translatable="yes">Builder</property>
- <property name="use_underline">False</property>
- <property name="use_markup">False</property>
- <property name="justify">GTK_JUSTIFY_LEFT</property>
- <property name="wrap">False</property>
- <property name="selectable">False</property>
- <property name="xalign">0.5</property>
- <property name="yalign">0.5</property>
- <property name="xpad">2</property>
- <property name="ypad">0</property>
- <property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
- <property name="width_chars">-1</property>
- <property name="single_line_mode">False</property>
- <property name="angle">0</property>
- </widget>
- <packing>
- <property name="type">label_item</property>
- </packing>
- </child>
- </widget>
- <packing>
- <property name="padding">0</property>
- <property name="expand">True</property>
- <property name="fill">True</property>
- </packing>
- </child>
- </widget>
- </child>
-</widget>
-
-</glade-interface>
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/debug.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/debug.py
deleted file mode 100644
index 5316d148..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/debug.py
+++ /dev/null
@@ -1,186 +0,0 @@
-# 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
-
-
-from twisted.internet import gtk2reactor
-gtk2reactor.install()
-from twisted.internet import reactor
-from twisted.python import util
-from twisted.spread import pb
-from twisted.cred import credentials
-import gtk.glade #@UnresolvedImport
-import re
-
-class DebugWidget:
- def __init__(self, master="localhost:8007", passwd="debugpw"):
- self.connected = 0
- try:
- host, port = re.search(r'(.+):(\d+)', master).groups()
- except:
- print "unparseable master location '%s'" % master
- print " expecting something more like localhost:8007"
- raise
- self.host = host
- self.port = int(port)
- self.passwd = passwd
- self.remote = None
- xml = self.xml = gtk.glade.XML(util.sibpath(__file__, "debug.glade"))
- g = xml.get_widget
- self.buildname = g('buildname')
- self.filename = g('filename')
- self.connectbutton = g('connectbutton')
- self.connectlabel = g('connectlabel')
- g('window1').connect('destroy', lambda win: gtk.main_quit())
- # put the master info in the window's titlebar
- g('window1').set_title("Buildbot Debug Tool: %s" % master)
- c = xml.signal_connect
- c('do_connect', self.do_connect)
- c('do_reload', self.do_reload)
- c('do_rebuild', self.do_rebuild)
- c('do_poke_irc', self.do_poke_irc)
- c('do_build', self.do_build)
- c('do_ping', self.do_ping)
- c('do_commit', self.do_commit)
- c('on_usebranch_toggled', self.usebranch_toggled)
- self.usebranch_toggled(g('usebranch'))
- c('on_userevision_toggled', self.userevision_toggled)
- self.userevision_toggled(g('userevision'))
- c('do_current_offline', self.do_current, "offline")
- c('do_current_idle', self.do_current, "idle")
- c('do_current_waiting', self.do_current, "waiting")
- c('do_current_building', self.do_current, "building")
-
- def do_connect(self, widget):
- if self.connected:
- self.connectlabel.set_text("Disconnecting...")
- if self.remote:
- self.remote.broker.transport.loseConnection()
- else:
- self.connectlabel.set_text("Connecting...")
- f = pb.PBClientFactory()
- creds = credentials.UsernamePassword("debug", self.passwd)
- d = f.login(creds)
- reactor.connectTCP(self.host, int(self.port), f)
- d.addCallbacks(self.connect_complete, self.connect_failed)
- def connect_complete(self, ref):
- self.connectbutton.set_label("Disconnect")
- self.connectlabel.set_text("Connected")
- self.connected = 1
- self.remote = ref
- self.remote.callRemote("print", "hello cleveland")
- self.remote.notifyOnDisconnect(self.disconnected)
- def connect_failed(self, why):
- self.connectlabel.set_text("Failed")
- print why
- def disconnected(self, ref):
- self.connectbutton.set_label("Connect")
- self.connectlabel.set_text("Disconnected")
- self.connected = 0
- self.remote = None
-
- def do_reload(self, widget):
- if not self.remote:
- return
- d = self.remote.callRemote("reload")
- d.addErrback(self.err)
- def do_rebuild(self, widget):
- print "Not yet implemented"
- return
- def do_poke_irc(self, widget):
- if not self.remote:
- return
- d = self.remote.callRemote("pokeIRC")
- d.addErrback(self.err)
-
- def do_build(self, widget):
- if not self.remote:
- return
- name = self.buildname.get_text()
- branch = None
- if self.xml.get_widget("usebranch").get_active():
- branch = self.xml.get_widget('branch').get_text()
- if branch == '':
- branch = None
- revision = None
- if self.xml.get_widget("userevision").get_active():
- revision = self.xml.get_widget('revision').get_text()
- if revision == '':
- revision = None
- reason = "debugclient 'Request Build' button pushed"
- properties = {}
- d = self.remote.callRemote("requestBuild",
- name, reason, branch, revision, properties)
- d.addErrback(self.err)
-
- def do_ping(self, widget):
- if not self.remote:
- return
- name = self.buildname.get_text()
- d = self.remote.callRemote("pingBuilder", name)
- d.addErrback(self.err)
-
- def usebranch_toggled(self, widget):
- rev = self.xml.get_widget('branch')
- if widget.get_active():
- rev.set_sensitive(True)
- else:
- rev.set_sensitive(False)
-
- def userevision_toggled(self, widget):
- rev = self.xml.get_widget('revision')
- if widget.get_active():
- rev.set_sensitive(True)
- else:
- rev.set_sensitive(False)
-
- def do_commit(self, widget):
- if not self.remote:
- return
- filename = self.filename.get_text()
- who = self.xml.get_widget("who").get_text()
-
- branch = None
- if self.xml.get_widget("usebranch").get_active():
- branch = self.xml.get_widget('branch').get_text()
- if branch == '':
- branch = None
-
- revision = None
- if self.xml.get_widget("userevision").get_active():
- revision = self.xml.get_widget('revision').get_text()
- try:
- revision = int(revision)
- except ValueError:
- pass
- if revision == '':
- revision = None
-
- kwargs = { 'revision': revision, 'who': who }
- if branch:
- kwargs['branch'] = branch
- d = self.remote.callRemote("fakeChange", filename, **kwargs)
- d.addErrback(self.err)
-
- def do_current(self, widget, state):
- if not self.remote:
- return
- name = self.buildname.get_text()
- d = self.remote.callRemote("setCurrentState", name, state)
- d.addErrback(self.err)
- def err(self, failure):
- print "received error:", failure
-
- def run(self):
- reactor.run()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/gtkPanes.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/gtkPanes.py
deleted file mode 100644
index d79bb0fe..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/gtkPanes.py
+++ /dev/null
@@ -1,551 +0,0 @@
-# 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
-
-
-from twisted.internet import gtk2reactor
-gtk2reactor.install() #@UndefinedVariable
-
-import sys, time
-
-import pygtk #@UnresolvedImport
-pygtk.require("2.0")
-import gobject, gtk #@UnresolvedImport
-assert(gtk.Window) # in gtk1 it's gtk.GtkWindow
-
-from twisted.spread import pb
-
-#from buildbot.clients.base import Builder, Client
-from buildbot.clients.base import StatusClient
-from buildbot.clients.text import TextClient
-from buildbot.util import now
-
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE, EXCEPTION
-
-'''
-class Pane:
- def __init__(self):
- pass
-
-class OneRow(Pane):
- """This is a one-row status bar. It has one square per Builder, and that
- square is either red, yellow, or green. """
-
- def __init__(self):
- Pane.__init__(self)
- self.widget = gtk.VBox(gtk.FALSE, 2)
- self.nameBox = gtk.HBox(gtk.TRUE)
- self.statusBox = gtk.HBox(gtk.TRUE)
- self.widget.add(self.nameBox)
- self.widget.add(self.statusBox)
- self.widget.show_all()
- self.builders = []
-
- def getWidget(self):
- return self.widget
- def addBuilder(self, builder):
- print "OneRow.addBuilder"
- # todo: ordering. Should follow the order in which they were added
- # to the original BotMaster
- self.builders.append(builder)
- # add the name to the left column, and a label (with background) to
- # the right
- name = gtk.Label(builder.name)
- status = gtk.Label('??')
- status.set_size_request(64,64)
- box = gtk.EventBox()
- box.add(status)
- name.show()
- box.show_all()
- self.nameBox.add(name)
- self.statusBox.add(box)
- builder.haveSomeWidgets([name, status, box])
-
-class R2Builder(Builder):
- def start(self):
- self.nameSquare.set_text(self.name)
- self.statusSquare.set_text("???")
- self.subscribe()
- def haveSomeWidgets(self, widgets):
- self.nameSquare, self.statusSquare, self.statusBox = widgets
-
- def remote_newLastBuildStatus(self, event):
- color = None
- if event:
- text = "\n".join(event.text)
- color = event.color
- else:
- text = "none"
- self.statusSquare.set_text(text)
- if color:
- print "color", color
- self.statusBox.modify_bg(gtk.STATE_NORMAL,
- gtk.gdk.color_parse(color))
-
- def remote_currentlyOffline(self):
- self.statusSquare.set_text("offline")
- def remote_currentlyIdle(self):
- self.statusSquare.set_text("idle")
- def remote_currentlyWaiting(self, seconds):
- self.statusSquare.set_text("waiting")
- def remote_currentlyInterlocked(self):
- self.statusSquare.set_text("interlocked")
- def remote_currentlyBuilding(self, eta):
- self.statusSquare.set_text("building")
-
-
-class CompactRow(Pane):
- def __init__(self):
- Pane.__init__(self)
- self.widget = gtk.VBox(gtk.FALSE, 3)
- self.nameBox = gtk.HBox(gtk.TRUE, 2)
- self.lastBuildBox = gtk.HBox(gtk.TRUE, 2)
- self.statusBox = gtk.HBox(gtk.TRUE, 2)
- self.widget.add(self.nameBox)
- self.widget.add(self.lastBuildBox)
- self.widget.add(self.statusBox)
- self.widget.show_all()
- self.builders = []
-
- def getWidget(self):
- return self.widget
-
- def addBuilder(self, builder):
- self.builders.append(builder)
-
- name = gtk.Label(builder.name)
- name.show()
- self.nameBox.add(name)
-
- last = gtk.Label('??')
- last.set_size_request(64,64)
- lastbox = gtk.EventBox()
- lastbox.add(last)
- lastbox.show_all()
- self.lastBuildBox.add(lastbox)
-
- status = gtk.Label('??')
- status.set_size_request(64,64)
- statusbox = gtk.EventBox()
- statusbox.add(status)
- statusbox.show_all()
- self.statusBox.add(statusbox)
-
- builder.haveSomeWidgets([name, last, lastbox, status, statusbox])
-
- def removeBuilder(self, name, builder):
- self.nameBox.remove(builder.nameSquare)
- self.lastBuildBox.remove(builder.lastBuildBox)
- self.statusBox.remove(builder.statusBox)
- self.builders.remove(builder)
-
-class CompactBuilder(Builder):
- def setup(self):
- self.timer = None
- self.text = []
- self.eta = None
- def start(self):
- self.nameSquare.set_text(self.name)
- self.statusSquare.set_text("???")
- self.subscribe()
- def haveSomeWidgets(self, widgets):
- (self.nameSquare,
- self.lastBuildSquare, self.lastBuildBox,
- self.statusSquare, self.statusBox) = widgets
-
- def remote_currentlyOffline(self):
- self.eta = None
- self.stopTimer()
- self.statusSquare.set_text("offline")
- self.statusBox.modify_bg(gtk.STATE_NORMAL,
- gtk.gdk.color_parse("red"))
- def remote_currentlyIdle(self):
- self.eta = None
- self.stopTimer()
- self.statusSquare.set_text("idle")
- def remote_currentlyWaiting(self, seconds):
- self.nextBuild = now() + seconds
- self.startTimer(self.updateWaiting)
- def remote_currentlyInterlocked(self):
- self.stopTimer()
- self.statusSquare.set_text("interlocked")
- def startTimer(self, func):
- # the func must clear self.timer and return gtk.FALSE when the event
- # has arrived
- self.stopTimer()
- self.timer = gtk.timeout_add(1000, func)
- func()
- def stopTimer(self):
- if self.timer:
- gtk.timeout_remove(self.timer)
- self.timer = None
- def updateWaiting(self):
- when = self.nextBuild
- if now() < when:
- next = time.strftime("%H:%M:%S", time.localtime(when))
- secs = "[%d seconds]" % (when - now())
- self.statusSquare.set_text("waiting\n%s\n%s" % (next, secs))
- return gtk.TRUE # restart timer
- else:
- # done
- self.statusSquare.set_text("waiting\n[RSN]")
- self.timer = None
- return gtk.FALSE
-
- def remote_currentlyBuilding(self, eta):
- self.stopTimer()
- self.statusSquare.set_text("building")
- if eta:
- d = eta.callRemote("subscribe", self, 5)
-
- def remote_newLastBuildStatus(self, event):
- color = None
- if event:
- text = "\n".join(event.text)
- color = event.color
- else:
- text = "none"
- if not color: color = "gray"
- self.lastBuildSquare.set_text(text)
- self.lastBuildBox.modify_bg(gtk.STATE_NORMAL,
- gtk.gdk.color_parse(color))
-
- def remote_newEvent(self, event):
- assert(event.__class__ == GtkUpdatingEvent)
- self.current = event
- event.builder = self
- self.text = event.text
- if not self.text: self.text = ["idle"]
- self.eta = None
- self.stopTimer()
- self.updateText()
- color = event.color
- if not color: color = "gray"
- self.statusBox.modify_bg(gtk.STATE_NORMAL,
- gtk.gdk.color_parse(color))
-
- def updateCurrent(self):
- text = self.current.text
- if text:
- self.text = text
- self.updateText()
- color = self.current.color
- if color:
- self.statusBox.modify_bg(gtk.STATE_NORMAL,
- gtk.gdk.color_parse(color))
- def updateText(self):
- etatext = []
- if self.eta:
- etatext = [time.strftime("%H:%M:%S", time.localtime(self.eta))]
- if now() > self.eta:
- etatext += ["RSN"]
- else:
- seconds = self.eta - now()
- etatext += ["[%d secs]" % seconds]
- text = "\n".join(self.text + etatext)
- self.statusSquare.set_text(text)
- def updateTextTimer(self):
- self.updateText()
- return gtk.TRUE # restart timer
-
- def remote_progress(self, seconds):
- if seconds == None:
- self.eta = None
- else:
- self.eta = now() + seconds
- self.startTimer(self.updateTextTimer)
- self.updateText()
- def remote_finished(self, eta):
- self.eta = None
- self.stopTimer()
- self.updateText()
- eta.callRemote("unsubscribe", self)
-'''
-
-class Box:
- def __init__(self, text="?"):
- self.text = text
- self.box = gtk.EventBox()
- self.label = gtk.Label(text)
- self.box.add(self.label)
- self.box.set_size_request(64,64)
- self.timer = None
-
- def getBox(self):
- return self.box
-
- def setText(self, text):
- self.text = text
- self.label.set_text(text)
-
- def setColor(self, color):
- if not color:
- return
- self.box.modify_bg(gtk.STATE_NORMAL, gtk.gdk.color_parse(color))
-
- def setETA(self, eta):
- if eta:
- self.when = now() + eta
- self.startTimer()
- else:
- self.stopTimer()
-
- def startTimer(self):
- self.stopTimer()
- self.timer = gobject.timeout_add(1000, self.update)
- self.update()
-
- def stopTimer(self):
- if self.timer:
- gobject.source_remove(self.timer)
- self.timer = None
- self.label.set_text(self.text)
-
- def update(self):
- if now() < self.when:
- next = time.strftime("%H:%M:%S", time.localtime(self.when))
- secs = "[%d secs]" % (self.when - now())
- self.label.set_text("%s\n%s\n%s" % (self.text, next, secs))
- return True # restart timer
- else:
- # done
- self.label.set_text("%s\n[soon]\n[overdue]" % (self.text,))
- self.timer = None
- return False
-
-
-
-class ThreeRowBuilder:
- def __init__(self, name, ref):
- self.name = name
-
- self.last = Box()
- self.current = Box()
- self.step = Box("idle")
- self.step.setColor("white")
-
- self.ref = ref
-
- def getBoxes(self):
- return self.last.getBox(), self.current.getBox(), self.step.getBox()
-
- def getLastBuild(self):
- d = self.ref.callRemote("getLastFinishedBuild")
- d.addCallback(self.gotLastBuild)
- def gotLastBuild(self, build):
- if build:
- build.callRemote("getText").addCallback(self.gotLastText)
- build.callRemote("getResults").addCallback(self.gotLastResult)
-
- def gotLastText(self, text):
- print "Got text", text
- self.last.setText("\n".join(text))
-
- def gotLastResult(self, result):
- colormap = {SUCCESS: 'green',
- FAILURE: 'red',
- WARNINGS: 'orange',
- EXCEPTION: 'purple',
- }
- self.last.setColor(colormap[result])
-
- def getState(self):
- self.ref.callRemote("getState").addCallback(self.gotState)
- def gotState(self, res):
- state, ETA, builds = res
- # state is one of: offline, idle, waiting, interlocked, building
- # TODO: ETA is going away, you have to look inside the builds to get
- # that value
- currentmap = {"offline": "red",
- "idle": "white",
- "waiting": "yellow",
- "interlocked": "yellow",
- "building": "yellow",}
- text = state
- self.current.setColor(currentmap[state])
- if ETA is not None:
- text += "\nETA=%s secs" % ETA
- self.current.setText(state)
-
- def buildStarted(self, build):
- print "[%s] buildStarted" % (self.name,)
- self.current.setColor("yellow")
-
- def buildFinished(self, build, results):
- print "[%s] buildFinished: %s" % (self.name, results)
- self.gotLastBuild(build)
- self.current.setColor("white")
- self.current.stopTimer()
-
- def buildETAUpdate(self, eta):
- print "[%s] buildETAUpdate: %s" % (self.name, eta)
- self.current.setETA(eta)
-
-
- def stepStarted(self, stepname, step):
- print "[%s] stepStarted: %s" % (self.name, stepname)
- self.step.setText(stepname)
- self.step.setColor("yellow")
- def stepFinished(self, stepname, step, results):
- print "[%s] stepFinished: %s %s" % (self.name, stepname, results)
- self.step.setText("idle")
- self.step.setColor("white")
- self.step.stopTimer()
- def stepETAUpdate(self, stepname, eta):
- print "[%s] stepETAUpdate: %s %s" % (self.name, stepname, eta)
- self.step.setETA(eta)
-
-
-class ThreeRowClient(pb.Referenceable):
- def __init__(self, window):
- self.window = window
- self.buildernames = []
- self.builders = {}
-
- def connected(self, ref):
- print "connected"
- self.ref = ref
- self.pane = gtk.VBox(False, 2)
- self.table = gtk.Table(1+3, 1)
- self.pane.add(self.table)
- self.window.vb.add(self.pane)
- self.pane.show_all()
- ref.callRemote("subscribe", "logs", 5, self)
-
- def removeTable(self):
- for child in self.table.get_children():
- self.table.remove(child)
- self.pane.remove(self.table)
-
- def makeTable(self):
- columns = len(self.builders)
- self.table = gtk.Table(2, columns)
- self.pane.add(self.table)
- for i in range(len(self.buildernames)):
- name = self.buildernames[i]
- b = self.builders[name]
- last,current,step = b.getBoxes()
- self.table.attach(gtk.Label(name), i, i+1, 0, 1)
- self.table.attach(last, i, i+1, 1, 2,
- xpadding=1, ypadding=1)
- self.table.attach(current, i, i+1, 2, 3,
- xpadding=1, ypadding=1)
- self.table.attach(step, i, i+1, 3, 4,
- xpadding=1, ypadding=1)
- self.table.show_all()
-
- def rebuildTable(self):
- self.removeTable()
- self.makeTable()
-
- def remote_builderAdded(self, buildername, builder):
- print "builderAdded", buildername
- assert buildername not in self.buildernames
- self.buildernames.append(buildername)
-
- b = ThreeRowBuilder(buildername, builder)
- self.builders[buildername] = b
- self.rebuildTable()
- b.getLastBuild()
- b.getState()
-
- def remote_builderRemoved(self, buildername):
- del self.builders[buildername]
- self.buildernames.remove(buildername)
- self.rebuildTable()
-
- def remote_builderChangedState(self, name, state, eta):
- self.builders[name].gotState((state, eta, None))
- def remote_buildStarted(self, name, build):
- self.builders[name].buildStarted(build)
- def remote_buildFinished(self, name, build, results):
- self.builders[name].buildFinished(build, results)
-
- def remote_buildETAUpdate(self, name, build, eta):
- self.builders[name].buildETAUpdate(eta)
- def remote_stepStarted(self, name, build, stepname, step):
- self.builders[name].stepStarted(stepname, step)
- def remote_stepFinished(self, name, build, stepname, step, results):
- self.builders[name].stepFinished(stepname, step, results)
-
- def remote_stepETAUpdate(self, name, build, stepname, step,
- eta, expectations):
- # expectations is a list of (metricname, current_value,
- # expected_value) tuples, so that we could show individual progress
- # meters for each metric
- self.builders[name].stepETAUpdate(stepname, eta)
-
- def remote_logStarted(self, buildername, build, stepname, step,
- logname, log):
- pass
-
- def remote_logFinished(self, buildername, build, stepname, step,
- logname, log):
- pass
-
-
-class GtkClient(TextClient):
- ClientClass = ThreeRowClient
-
- def __init__(self, master, events="steps", username="statusClient", passwd="clientpw"):
- self.master = master
- self.username = username
- self.passwd = passwd
- self.listener = StatusClient(events)
-
- w = gtk.Window()
- self.w = w
- #w.set_size_request(64,64)
- w.connect('destroy', lambda win: gtk.main_quit())
- self.vb = gtk.VBox(False, 2)
- self.status = gtk.Label("unconnected")
- self.vb.add(self.status)
- self.listener = self.ClientClass(self)
- w.add(self.vb)
- w.show_all()
-
- def connected(self, ref):
- self.status.set_text("connected")
- TextClient.connected(self, ref)
-
-"""
- def addBuilder(self, name, builder):
- Client.addBuilder(self, name, builder)
- self.pane.addBuilder(builder)
- def removeBuilder(self, name):
- self.pane.removeBuilder(name, self.builders[name])
- Client.removeBuilder(self, name)
-
- def startConnecting(self, master):
- self.master = master
- Client.startConnecting(self, master)
- self.status.set_text("connecting to %s.." % master)
- def connected(self, remote):
- Client.connected(self, remote)
- self.status.set_text(self.master)
- remote.notifyOnDisconnect(self.disconnected)
- def disconnected(self, remote):
- self.status.set_text("disconnected, will retry")
-"""
-
-def main():
- master = "localhost:8007"
- if len(sys.argv) > 1:
- master = sys.argv[1]
- c = GtkClient(master)
- c.run()
-
-if __name__ == '__main__':
- main()
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/sendchange.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/sendchange.py
deleted file mode 100644
index daae63b5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/sendchange.py
+++ /dev/null
@@ -1,59 +0,0 @@
-# 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
-
-
-from twisted.spread import pb
-from twisted.cred import credentials
-from twisted.internet import reactor
-
-class Sender:
- def __init__(self, master, auth=('change','changepw'), encoding='utf8'):
- self.username, self.password = auth
- self.host, self.port = master.split(":")
- self.port = int(self.port)
- self.encoding = encoding
-
- def send(self, branch, revision, comments, files, who=None, category=None,
- when=None, properties={}, repository='', vc=None, project='',
- revlink='', codebase=None):
- change = {'project': project, 'repository': repository, 'who': who,
- 'files': files, 'comments': comments, 'branch': branch,
- 'revision': revision, 'category': category, 'when': when,
- 'properties': properties, 'revlink': revlink, 'src': vc}
-
- # codebase is only sent if set; this won't work with masters older than
- # 0.8.7
- if codebase:
- change['codebase'] = codebase
-
- for key in change:
- if type(change[key]) == str:
- change[key] = change[key].decode(self.encoding, 'replace')
- change['files'] = list(change['files'])
- for i, file in enumerate(change.get('files', [])):
- if type(file) == str:
- change['files'][i] = file.decode(self.encoding, 'replace')
-
- f = pb.PBClientFactory()
- d = f.login(credentials.UsernamePassword(self.username, self.password))
- reactor.connectTCP(self.host, self.port, f)
-
- def call_addChange(remote):
- d = remote.callRemote('addChange', change)
- d.addCallback(lambda res: remote.broker.transport.loseConnection())
- return d
- d.addCallback(call_addChange)
-
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/text.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/text.py
deleted file mode 100644
index 77a430ee..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/text.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# 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 re
-
-from twisted.spread import pb
-from twisted.cred import credentials, error
-from twisted.internet import reactor
-from buildbot.clients import base
-
-class TextClient:
- def __init__(self, master, events="steps", username="statusClient", passwd="clientpw"):
- """
- @type master: string
- @param master: a host:port string to masters L{buildbot.status.client.PBListener}
-
- @type username: string
- @param username:
-
- @type passwd: string
- @param passwd:
-
- @type events: string, one of builders, builds, steps, logs, full
- @param events: specify what level of detail should be reported.
- - 'builders': only announce new/removed Builders
- - 'builds': also announce builderChangedState, buildStarted, and
- buildFinished
- - 'steps': also announce buildETAUpdate, stepStarted, stepFinished
- - 'logs': also announce stepETAUpdate, logStarted, logFinished
- - 'full': also announce log contents
- """
- self.master = master
- self.username = username
- self.passwd = passwd
- self.listener = base.StatusClient(events)
-
- def run(self):
- """Start the TextClient."""
- self.startConnecting()
- reactor.run()
-
- def startConnecting(self):
- try:
- host, port = re.search(r'(.+):(\d+)', self.master).groups()
- port = int(port)
- except:
- print "unparseable master location '%s'" % self.master
- print " expecting something more like localhost:8007"
- raise
- cf = pb.PBClientFactory()
- creds = credentials.UsernamePassword(self.username, self.passwd)
- d = cf.login(creds)
- reactor.connectTCP(host, port, cf)
- d.addCallbacks(self.connected, self.not_connected)
- return d
- def connected(self, ref):
- ref.notifyOnDisconnect(self.disconnected)
- self.listener.connected(ref)
- def not_connected(self, why):
- if why.check(error.UnauthorizedLogin):
- print """
-Unable to login.. are you sure we are connecting to a
-buildbot.status.client.PBListener port and not to the slaveport?
-"""
- reactor.stop()
- return why
- def disconnected(self, ref):
- print "lost connection"
- # we can get here in one of two ways: the buildmaster has
- # disconnected us (probably because it shut itself down), or because
- # we've been SIGINT'ed. In the latter case, our reactor is already
- # shut down, but we have no easy way of detecting that. So protect
- # our attempt to shut down the reactor.
- try:
- reactor.stop()
- except RuntimeError:
- pass
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/tryclient.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/tryclient.py
deleted file mode 100644
index d48f8088..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/tryclient.py
+++ /dev/null
@@ -1,891 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-
-import os
-import random
-import re
-import sys
-import time
-
-from twisted.cred import credentials
-from twisted.internet import defer
-from twisted.internet import protocol
-from twisted.internet import reactor
-from twisted.internet import task
-from twisted.internet import utils
-from twisted.python import log
-from twisted.python.procutils import which
-from twisted.spread import pb
-
-from buildbot.sourcestamp import SourceStamp
-from buildbot.status import builder
-from buildbot.util import json
-from buildbot.util import now
-from buildbot.util.eventual import fireEventually
-
-
-class SourceStampExtractor:
-
- def __init__(self, treetop, branch, repository):
- self.treetop = treetop
- self.repository = repository
- self.branch = branch
- exes = which(self.vcexe)
- if not exes:
- print "Could not find executable '%s'." % self.vcexe
- sys.exit(1)
- self.exe = exes[0]
-
- def dovc(self, cmd):
- """This accepts the arguments of a command, without the actual
- command itself."""
- env = os.environ.copy()
- env['LC_ALL'] = "C"
- d = utils.getProcessOutputAndValue(self.exe, cmd, env=env,
- path=self.treetop)
- d.addCallback(self._didvc, cmd)
- return d
-
- def _didvc(self, res, cmd):
- (stdout, stderr, code) = res
- # 'bzr diff' sets rc=1 if there were any differences.
- # cvs does something similar, so don't bother requring rc=0.
- return stdout
-
- def get(self):
- """Return a Deferred that fires with a SourceStamp instance."""
- d = self.getBaseRevision()
- d.addCallback(self.getPatch)
- d.addCallback(self.done)
- return d
-
- def readPatch(self, diff, patchlevel):
- if not diff:
- diff = None
- self.patch = (patchlevel, diff)
-
- def done(self, res):
- if not self.repository:
- self.repository = self.treetop
- # TODO: figure out the branch and project too
- ss = SourceStamp(self.branch, self.baserev, self.patch,
- repository=self.repository)
- return ss
-
-
-class CVSExtractor(SourceStampExtractor):
- patchlevel = 0
- vcexe = "cvs"
-
- def getBaseRevision(self):
- # this depends upon our local clock and the repository's clock being
- # reasonably synchronized with each other. We express everything in
- # UTC because the '%z' format specifier for strftime doesn't always
- # work.
- self.baserev = time.strftime("%Y-%m-%d %H:%M:%S +0000",
- time.gmtime(now()))
- return defer.succeed(None)
-
- def getPatch(self, res):
- # the -q tells CVS to not announce each directory as it works
- if self.branch is not None:
- # 'cvs diff' won't take both -r and -D at the same time (it
- # ignores the -r). As best I can tell, there is no way to make
- # cvs give you a diff relative to a timestamp on the non-trunk
- # branch. A bare 'cvs diff' will tell you about the changes
- # relative to your checked-out versions, but I know of no way to
- # find out what those checked-out versions are.
- print "Sorry, CVS 'try' builds don't work with branches"
- sys.exit(1)
- args = ['-q', 'diff', '-u', '-D', self.baserev]
- d = self.dovc(args)
- d.addCallback(self.readPatch, self.patchlevel)
- return d
-
-
-class SVNExtractor(SourceStampExtractor):
- patchlevel = 0
- vcexe = "svn"
-
- def getBaseRevision(self):
- d = self.dovc(["status", "-u"])
- d.addCallback(self.parseStatus)
- return d
-
- def parseStatus(self, res):
- # svn shows the base revision for each file that has been modified or
- # which needs an update. You can update each file to a different
- # version, so each file is displayed with its individual base
- # revision. It also shows the repository-wide latest revision number
- # on the last line ("Status against revision: \d+").
-
- # for our purposes, we use the latest revision number as the "base"
- # revision, and get a diff against that. This means we will get
- # reverse-diffs for local files that need updating, but the resulting
- # tree will still be correct. The only weirdness is that the baserev
- # that we emit may be different than the version of the tree that we
- # first checked out.
-
- # to do this differently would probably involve scanning the revision
- # numbers to find the max (or perhaps the min) revision, and then
- # using that as a base.
-
- for line in res.split("\n"):
- m = re.search(r'^Status against revision:\s+(\d+)', line)
- if m:
- self.baserev = int(m.group(1))
- return
- print "Could not find 'Status against revision' in SVN output: %s" % res
- sys.exit(1)
-
- def getPatch(self, res):
- d = self.dovc(["diff", "-r%d" % self.baserev])
- d.addCallback(self.readPatch, self.patchlevel)
- return d
-
-
-class BzrExtractor(SourceStampExtractor):
- patchlevel = 0
- vcexe = "bzr"
-
- def getBaseRevision(self):
- d = self.dovc(["revision-info", "-rsubmit:"])
- d.addCallback(self.get_revision_number)
- return d
-
- def get_revision_number(self, out):
- revno, revid = out.split()
- self.baserev = 'revid:' + revid
- return
-
- def getPatch(self, res):
- d = self.dovc(["diff", "-r%s.." % self.baserev])
- d.addCallback(self.readPatch, self.patchlevel)
- return d
-
-
-class MercurialExtractor(SourceStampExtractor):
- patchlevel = 1
- vcexe = "hg"
-
- def getBaseRevision(self):
- upstream = ""
- if self.repository:
- upstream = "r'%s'" % self.repository
- d = self.dovc(["log", "--template", "{node}\\n", "-r", "limit(parents(outgoing(%s) and branch(parents())) or parents(), 1)" % upstream])
- d.addCallback(self.parseStatus)
- return d
-
- def parseStatus(self, output):
- m = re.search(r'^(\w+)', output)
- self.baserev = m.group(0)
-
- def getPatch(self, res):
- d = self.dovc(["diff", "-r", self.baserev])
- d.addCallback(self.readPatch, self.patchlevel)
- return d
-
-
-class PerforceExtractor(SourceStampExtractor):
- patchlevel = 0
- vcexe = "p4"
-
- def getBaseRevision(self):
- d = self.dovc(["changes", "-m1", "..."])
- d.addCallback(self.parseStatus)
- return d
-
- def parseStatus(self, res):
- #
- # extract the base change number
- #
- m = re.search(r'Change (\d+)', res)
- if m:
- self.baserev = m.group(1)
- return
-
- print "Could not find change number in output: %s" % res
- sys.exit(1)
-
- def readPatch(self, res, patchlevel):
- #
- # extract the actual patch from "res"
- #
- if not self.branch:
- print "you must specify a branch"
- sys.exit(1)
- mpatch = ""
- found = False
- for line in res.split("\n"):
- m = re.search('==== //depot/' + self.branch
- + r'/([\w\/\.\d\-\_]+)#(\d+) -', line)
- if m:
- mpatch += "--- %s#%s\n" % (m.group(1), m.group(2))
- mpatch += "+++ %s\n" % (m.group(1))
- found = True
- else:
- mpatch += line
- mpatch += "\n"
- if not found:
- print "could not parse patch file"
- sys.exit(1)
- self.patch = (patchlevel, mpatch)
-
- def getPatch(self, res):
- d = self.dovc(["diff"])
- d.addCallback(self.readPatch, self.patchlevel)
- return d
-
-
-class DarcsExtractor(SourceStampExtractor):
- patchlevel = 1
- vcexe = "darcs"
-
- def getBaseRevision(self):
- d = self.dovc(["changes", "--context"])
- d.addCallback(self.parseStatus)
- return d
-
- def parseStatus(self, res):
- self.baserev = res # the whole context file
-
- def getPatch(self, res):
- d = self.dovc(["diff", "-u"])
- d.addCallback(self.readPatch, self.patchlevel)
- return d
-
-
-class GitExtractor(SourceStampExtractor):
- patchlevel = 1
- vcexe = "git"
- config = None
-
- def getBaseRevision(self):
- # If a branch is specified, parse out the rev it points to
- # and extract the local name (assuming it has a slash).
- # This may break if someone specifies the name of a local
- # branch that has a slash in it and has no corresponding
- # remote branch (or something similarly contrived).
- if self.branch:
- d = self.dovc(["rev-parse", self.branch])
- if '/' in self.branch:
- self.branch = self.branch.split('/', 1)[1]
- d.addCallback(self.override_baserev)
- return d
- d = self.dovc(["branch", "--no-color", "-v", "--no-abbrev"])
- d.addCallback(self.parseStatus)
- return d
-
- def readConfig(self):
- if self.config:
- return defer.succeed(self.config)
- d = self.dovc(["config", "-l"])
- d.addCallback(self.parseConfig)
- return d
-
- def parseConfig(self, res):
- self.config = {}
- for l in res.split("\n"):
- if l.strip():
- parts = l.strip().split("=", 2)
- self.config[parts[0]] = parts[1]
- return self.config
-
- def parseTrackingBranch(self, res):
- # If we're tracking a remote, consider that the base.
- remote = self.config.get("branch." + self.branch + ".remote")
- ref = self.config.get("branch." + self.branch + ".merge")
- if remote and ref:
- remote_branch = ref.split("/", 3)[-1]
- d = self.dovc(["rev-parse", remote + "/" + remote_branch])
- d.addCallback(self.override_baserev)
- return d
-
- def override_baserev(self, res):
- self.baserev = res.strip()
-
- def parseStatus(self, res):
- # The current branch is marked by '*' at the start of the
- # line, followed by the branch name and the SHA1.
- #
- # Branch names may contain pretty much anything but whitespace.
- m = re.search(r'^\* (\S+)\s+([0-9a-f]{40})', res, re.MULTILINE)
- if m:
- self.baserev = m.group(2)
- self.branch = m.group(1)
- d = self.readConfig()
- d.addCallback(self.parseTrackingBranch)
- return d
- print "Could not find current GIT branch: %s" % res
- sys.exit(1)
-
- def getPatch(self, res):
- d = self.dovc(["diff", self.baserev])
- d.addCallback(self.readPatch, self.patchlevel)
- return d
-
-
-class MonotoneExtractor(SourceStampExtractor):
- patchlevel = 0
- vcexe = "mtn"
-
- def getBaseRevision(self):
- d = self.dovc(["automate", "get_base_revision_id"])
- d.addCallback(self.parseStatus)
- return d
-
- def parseStatus(self, output):
- hash = output.strip()
- if len(hash) != 40:
- self.baserev = None
- self.baserev = hash
-
- def getPatch(self, res):
- d = self.dovc(["diff"])
- d.addCallback(self.readPatch, self.patchlevel)
- return d
-
-
-def getSourceStamp(vctype, treetop, branch=None, repository=None):
- if vctype == "cvs":
- cls = CVSExtractor
- elif vctype == "svn":
- cls = SVNExtractor
- elif vctype == "bzr":
- cls = BzrExtractor
- elif vctype == "hg":
- cls = MercurialExtractor
- elif vctype == "p4":
- cls = PerforceExtractor
- elif vctype == "darcs":
- cls = DarcsExtractor
- elif vctype == "git":
- cls = GitExtractor
- elif vctype == "mtn":
- cls = MonotoneExtractor
- else:
- print "unknown vctype '%s'" % vctype
- sys.exit(1)
- return cls(treetop, branch, repository).get()
-
-
-def ns(s):
- return "%d:%s," % (len(s), s)
-
-
-def createJobfile(jobid, branch, baserev, patch_level, patch_body, repository,
- project, who, comment, builderNames, properties):
- #Determine job file version from provided arguments
- if properties:
- version = 5
- elif comment:
- version = 4
- elif who:
- version = 3
- else:
- version = 2
- job = ""
- job += ns(str(version))
- if version < 5:
- job += ns(jobid)
- job += ns(branch)
- job += ns(str(baserev))
- job += ns("%d" % patch_level)
- job += ns(patch_body)
- job += ns(repository)
- job += ns(project)
- if (version >= 3):
- job += ns(who)
- if (version >= 4):
- job += ns(comment)
- for bn in builderNames:
- job += ns(bn)
- else:
- job += ns(
- json.dumps({
- 'jobid': jobid, 'branch': branch, 'baserev': str(baserev),
- 'patch_level': patch_level, 'patch_body': patch_body,
- 'repository': repository, 'project': project, 'who': who,
- 'comment': comment, 'builderNames': builderNames,
- 'properties': properties,
- }))
- return job
-
-
-def getTopdir(topfile, start=None):
- """walk upwards from the current directory until we find this topfile"""
- if not start:
- start = os.getcwd()
- here = start
- toomany = 20
- while toomany > 0:
- if os.path.exists(os.path.join(here, topfile)):
- return here
- next = os.path.dirname(here)
- if next == here:
- break # we've hit the root
- here = next
- toomany -= 1
- print ("Unable to find topfile '%s' anywhere from %s upwards"
- % (topfile, start))
- sys.exit(1)
-
-
-class RemoteTryPP(protocol.ProcessProtocol):
- def __init__(self, job):
- self.job = job
- self.d = defer.Deferred()
-
- def connectionMade(self):
- self.transport.write(self.job)
- self.transport.closeStdin()
-
- def outReceived(self, data):
- sys.stdout.write(data)
-
- def errReceived(self, data):
- sys.stderr.write(data)
-
- def processEnded(self, status_object):
- sig = status_object.value.signal
- rc = status_object.value.exitCode
- if sig != None or rc != 0:
- self.d.errback(RuntimeError("remote 'buildbot tryserver' failed"
- ": sig=%s, rc=%s" % (sig, rc)))
- return
- self.d.callback((sig, rc))
-
-
-class BuildSetStatusGrabber:
- retryCount = 5 # how many times to we try to grab the BuildSetStatus?
- retryDelay = 3 # seconds to wait between attempts
-
- def __init__(self, status, bsid):
- self.status = status
- self.bsid = bsid
-
- def grab(self):
- # return a Deferred that either fires with the BuildSetStatus
- # reference or errbacks because we were unable to grab it
- self.d = defer.Deferred()
- # wait a second before querying to give the master's maildir watcher
- # a chance to see the job
- reactor.callLater(1, self.go)
- return self.d
-
- def go(self, dummy=None):
- if self.retryCount == 0:
- print "couldn't find matching buildset"
- sys.exit(1)
- self.retryCount -= 1
- d = self.status.callRemote("getBuildSets")
- d.addCallback(self._gotSets)
-
- def _gotSets(self, buildsets):
- for bs, bsid in buildsets:
- if bsid == self.bsid:
- # got it
- self.d.callback(bs)
- return
- d = defer.Deferred()
- d.addCallback(self.go)
- reactor.callLater(self.retryDelay, d.callback, None)
-
-
-class Try(pb.Referenceable):
- buildsetStatus = None
- quiet = False
- printloop = False
-
- def __init__(self, config):
- self.config = config
- self.connect = self.getopt('connect')
- if self.connect not in ['ssh', 'pb']:
- print "you must specify a connect style: ssh or pb"
- sys.exit(1)
- self.builderNames = self.getopt('builders')
- self.project = self.getopt('project', '')
- self.who = self.getopt('who')
- self.comment = self.getopt('comment')
-
- def getopt(self, config_name, default=None):
- value = self.config.get(config_name)
- if value is None or value == []:
- value = default
- return value
-
- def createJob(self):
- # returns a Deferred which fires when the job parameters have been
- # created
-
- # generate a random (unique) string. It would make sense to add a
- # hostname and process ID here, but a) I suspect that would cause
- # windows portability problems, and b) really this is good enough
- self.bsid = "%d-%s" % (time.time(), random.randint(0, 1000000))
-
- # common options
- branch = self.getopt("branch")
-
- difffile = self.config.get("diff")
- if difffile:
- baserev = self.config.get("baserev")
- if difffile == "-":
- diff = sys.stdin.read()
- else:
- with open(difffile, "r") as f:
- diff = f.read()
- if not diff:
- diff = None
- patch = (self.config['patchlevel'], diff)
- ss = SourceStamp(
- branch, baserev, patch, repository=self.getopt("repository"))
- d = defer.succeed(ss)
- else:
- vc = self.getopt("vc")
- if vc in ("cvs", "svn"):
- # we need to find the tree-top
- topdir = self.getopt("topdir")
- if topdir:
- treedir = os.path.expanduser(topdir)
- else:
- topfile = self.getopt("topfile")
- if topfile:
- treedir = getTopdir(topfile)
- else:
- print "Must specify topdir or topfile."
- sys.exit(1)
- else:
- treedir = os.getcwd()
- d = getSourceStamp(vc, treedir, branch, self.getopt("repository"))
- d.addCallback(self._createJob_1)
- return d
-
- def _createJob_1(self, ss):
- self.sourcestamp = ss
- if self.connect == "ssh":
- patchlevel, diff = ss.patch
- revspec = ss.revision
- if revspec is None:
- revspec = ""
- self.jobfile = createJobfile(
- self.bsid, ss.branch or "", revspec, patchlevel, diff,
- ss.repository, self.project, self.who, self.comment,
- self.builderNames, self.config.get('properties', {}))
-
- def fakeDeliverJob(self):
- # Display the job to be delivered, but don't perform delivery.
- ss = self.sourcestamp
- print ("Job:\n\tRepository: %s\n\tProject: %s\n\tBranch: %s\n\t"
- "Revision: %s\n\tBuilders: %s\n%s"
- % (ss.repository, self.project, ss.branch,
- ss.revision,
- self.builderNames,
- ss.patch[1]))
- d = defer.Deferred()
- d.callback(True)
- return d
-
- def deliverJob(self):
- # returns a Deferred that fires when the job has been delivered
- if self.connect == "ssh":
- tryhost = self.getopt("host")
- tryuser = self.getopt("username")
- trydir = self.getopt("jobdir")
- buildbotbin = self.getopt("buildbotbin")
- argv = ["ssh", "-l", tryuser, tryhost,
- buildbotbin, "tryserver", "--jobdir", trydir]
- pp = RemoteTryPP(self.jobfile)
- reactor.spawnProcess(pp, argv[0], argv, os.environ)
- d = pp.d
- return d
- if self.connect == "pb":
- user = self.getopt("username")
- passwd = self.getopt("passwd")
- master = self.getopt("master")
- tryhost, tryport = master.split(":")
- tryport = int(tryport)
- f = pb.PBClientFactory()
- d = f.login(credentials.UsernamePassword(user, passwd))
- reactor.connectTCP(tryhost, tryport, f)
- d.addCallback(self._deliverJob_pb)
- return d
- raise RuntimeError("unknown connecttype '%s', should be 'ssh' or 'pb'"
- % self.connect)
-
- def _deliverJob_pb(self, remote):
- ss = self.sourcestamp
- print "Delivering job; comment=", self.comment
-
- d = remote.callRemote("try",
- ss.branch,
- ss.revision,
- ss.patch,
- ss.repository,
- self.project,
- self.builderNames,
- self.who,
- self.comment,
- self.config.get('properties', {}))
- d.addCallback(self._deliverJob_pb2)
- return d
-
- def _deliverJob_pb2(self, status):
- self.buildsetStatus = status
- return status
-
- def getStatus(self):
- # returns a Deferred that fires when the builds have finished, and
- # may emit status messages while we wait
- wait = bool(self.getopt("wait"))
- if not wait:
- # TODO: emit the URL where they can follow the builds. This
- # requires contacting the Status server over PB and doing
- # getURLForThing() on the BuildSetStatus. To get URLs for
- # individual builds would require we wait for the builds to
- # start.
- print "not waiting for builds to finish"
- return
- d = self.running = defer.Deferred()
- if self.buildsetStatus:
- self._getStatus_1()
- return self.running
- # contact the status port
- # we're probably using the ssh style
- master = self.getopt("master")
- host, port = master.split(":")
- port = int(port)
- self.announce("contacting the status port at %s:%d" % (host, port))
- f = pb.PBClientFactory()
- creds = credentials.UsernamePassword("statusClient", "clientpw")
- d = f.login(creds)
- reactor.connectTCP(host, port, f)
- d.addCallback(self._getStatus_ssh_1)
- return self.running
-
- def _getStatus_ssh_1(self, remote):
- # find a remotereference to the corresponding BuildSetStatus object
- self.announce("waiting for job to be accepted")
- g = BuildSetStatusGrabber(remote, self.bsid)
- d = g.grab()
- d.addCallback(self._getStatus_1)
- return d
-
- def _getStatus_1(self, res=None):
- if res:
- self.buildsetStatus = res
- # gather the set of BuildRequests
- d = self.buildsetStatus.callRemote("getBuildRequests")
- d.addCallback(self._getStatus_2)
-
- def _getStatus_2(self, brs):
- self.builderNames = []
- self.buildRequests = {}
-
- # self.builds holds the current BuildStatus object for each one
- self.builds = {}
-
- # self.outstanding holds the list of builderNames which haven't
- # finished yet
- self.outstanding = []
-
- # self.results holds the list of build results. It holds a tuple of
- # (result, text)
- self.results = {}
-
- # self.currentStep holds the name of the Step that each build is
- # currently running
- self.currentStep = {}
-
- # self.ETA holds the expected finishing time (absolute time since
- # epoch)
- self.ETA = {}
-
- for n, br in brs:
- self.builderNames.append(n)
- self.buildRequests[n] = br
- self.builds[n] = None
- self.outstanding.append(n)
- self.results[n] = [None, None]
- self.currentStep[n] = None
- self.ETA[n] = None
- # get new Builds for this buildrequest. We follow each one until
- # it finishes or is interrupted.
- br.callRemote("subscribe", self)
-
- # now that those queries are in transit, we can start the
- # display-status-every-30-seconds loop
- if not self.getopt("quiet"):
- self.printloop = task.LoopingCall(self.printStatus)
- self.printloop.start(3, now=False)
-
- # these methods are invoked by the status objects we've subscribed to
-
- def remote_newbuild(self, bs, builderName):
- if self.builds[builderName]:
- self.builds[builderName].callRemote("unsubscribe", self)
- self.builds[builderName] = bs
- bs.callRemote("subscribe", self, 20)
- d = bs.callRemote("waitUntilFinished")
- d.addCallback(self._build_finished, builderName)
-
- def remote_stepStarted(self, buildername, build, stepname, step):
- self.currentStep[buildername] = stepname
-
- def remote_stepFinished(self, buildername, build, stepname, step, results):
- pass
-
- def remote_buildETAUpdate(self, buildername, build, eta):
- self.ETA[buildername] = now() + eta
-
- def _build_finished(self, bs, builderName):
- # we need to collect status from the newly-finished build. We don't
- # remove the build from self.outstanding until we've collected
- # everything we want.
- self.builds[builderName] = None
- self.ETA[builderName] = None
- self.currentStep[builderName] = "finished"
- d = bs.callRemote("getResults")
- d.addCallback(self._build_finished_2, bs, builderName)
- return d
-
- def _build_finished_2(self, results, bs, builderName):
- self.results[builderName][0] = results
- d = bs.callRemote("getText")
- d.addCallback(self._build_finished_3, builderName)
- return d
-
- def _build_finished_3(self, text, builderName):
- self.results[builderName][1] = text
-
- self.outstanding.remove(builderName)
- if not self.outstanding:
- # all done
- return self.statusDone()
-
- def printStatus(self):
- try:
- names = self.buildRequests.keys()
- names.sort()
- for n in names:
- if n not in self.outstanding:
- # the build is finished, and we have results
- code, text = self.results[n]
- t = builder.Results[code]
- if text:
- t += " (%s)" % " ".join(text)
- elif self.builds[n]:
- t = self.currentStep[n] or "building"
- if self.ETA[n]:
- t += " [ETA %ds]" % (self.ETA[n] - now())
- else:
- t = "no build"
- self.announce("%s: %s" % (n, t))
- self.announce("")
- except Exception:
- log.err(None, "printing status")
-
- def statusDone(self):
- if self.printloop:
- self.printloop.stop()
- print "All Builds Complete"
- # TODO: include a URL for all failing builds
- names = self.buildRequests.keys()
- names.sort()
- happy = True
- for n in names:
- code, text = self.results[n]
- t = "%s: %s" % (n, builder.Results[code])
- if text:
- t += " (%s)" % " ".join(text)
- print t
- if code != builder.SUCCESS:
- happy = False
-
- if happy:
- self.exitcode = 0
- else:
- self.exitcode = 1
- self.running.callback(self.exitcode)
-
- def getAvailableBuilderNames(self):
- # This logs into the master using the PB protocol to
- # get the names of the configured builders that can
- # be used for the --builder argument
- if self.connect == "pb":
- user = self.getopt("username")
- passwd = self.getopt("passwd")
- master = self.getopt("master")
- tryhost, tryport = master.split(":")
- tryport = int(tryport)
- f = pb.PBClientFactory()
- d = f.login(credentials.UsernamePassword(user, passwd))
- reactor.connectTCP(tryhost, tryport, f)
- d.addCallback(self._getBuilderNames, self._getBuilderNames2)
- return d
- if self.connect == "ssh":
- print "Cannot get availble builders over ssh."
- sys.exit(1)
- raise RuntimeError(
- "unknown connecttype '%s', should be 'pb'" % self.connect)
-
- def _getBuilderNames(self, remote, output):
- d = remote.callRemote("getAvailableBuilderNames")
- d.addCallback(self._getBuilderNames2)
- return d
-
- def _getBuilderNames2(self, buildernames):
- print "The following builders are available for the try scheduler: "
- for buildername in buildernames:
- print buildername
-
- def announce(self, message):
- if not self.quiet:
- print message
-
- def run(self):
- # we can't do spawnProcess until we're inside reactor.run(), so get
- # funky
- print "using '%s' connect method" % self.connect
- self.exitcode = 0
- d = fireEventually(None)
- if bool(self.config.get("get-builder-names")):
- d.addCallback(lambda res: self.getAvailableBuilderNames())
- else:
- d.addCallback(lambda res: self.createJob())
- d.addCallback(lambda res: self.announce("job created"))
- deliver = self.deliverJob
- if bool(self.config.get("dryrun")):
- deliver = self.fakeDeliverJob
- d.addCallback(lambda res: deliver())
- d.addCallback(lambda res: self.announce("job has been delivered"))
- d.addCallback(lambda res: self.getStatus())
- d.addErrback(self.trapSystemExit)
- d.addErrback(log.err)
- d.addCallback(self.cleanup)
- d.addCallback(lambda res: reactor.stop())
-
- reactor.run()
- sys.exit(self.exitcode)
-
- def trapSystemExit(self, why):
- why.trap(SystemExit)
- self.exitcode = why.value.code
-
- def cleanup(self, res=None):
- if self.buildsetStatus:
- self.buildsetStatus.broker.transport.loseConnection()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/usersclient.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/usersclient.py
deleted file mode 100644
index 45ca62d5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/clients/usersclient.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# 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
-
-# this class is known to contain cruft and will be looked at later, so
-# no current implementation utilizes it aside from scripts.runner.
-
-from twisted.spread import pb
-from twisted.cred import credentials
-from twisted.internet import reactor
-
-class UsersClient(object):
- """
- Client set up in buildbot.scripts.runner to send `buildbot user` args
- over a PB connection to perspective_commandline that will execute the
- args on the database.
- """
-
- def __init__(self, master, username, password, port):
- self.host = master
- self.username = username
- self.password = password
- self.port = int(port)
-
- def send(self, op, bb_username, bb_password, ids, info):
- f = pb.PBClientFactory()
- d = f.login(credentials.UsernamePassword(self.username, self.password))
- reactor.connectTCP(self.host, self.port, f)
-
- def call_commandline(remote):
- d = remote.callRemote("commandline", op, bb_username,
- bb_password, ids, info)
- def returnAndLose(res):
- remote.broker.transport.loseConnection()
- return res
- d.addCallback(returnAndLose)
- return d
- d.addCallback(call_commandline)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/config.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/config.py
deleted file mode 100644
index e8632b2e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/config.py
+++ /dev/null
@@ -1,730 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os
-import re
-import sys
-import warnings
-from buildbot.util import safeTranslate
-from buildbot import interfaces
-from buildbot import locks
-from buildbot.revlinks import default_revlink_matcher
-from twisted.python import log, failure
-from twisted.internet import defer
-from twisted.application import service
-
-class ConfigErrors(Exception):
-
- def __init__(self, errors=[]):
- self.errors = errors[:]
-
- def __str__(self):
- return "\n".join(self.errors)
-
- def addError(self, msg):
- self.errors.append(msg)
-
- def __nonzero__(self):
- return len(self.errors)
-
-_errors = None
-def error(error):
- if _errors is not None:
- _errors.addError(error)
- else:
- raise ConfigErrors([error])
-
-class MasterConfig(object):
-
- def __init__(self):
- # local import to avoid circular imports
- from buildbot.process import properties
- # default values for all attributes
-
- # global
- self.title = 'Buildbot'
- self.titleURL = 'http://buildbot.net'
- self.buildbotURL = 'http://localhost:8080/'
- self.changeHorizon = None
- self.eventHorizon = 50
- self.logHorizon = None
- self.buildHorizon = None
- self.logCompressionLimit = 4*1024
- self.logCompressionMethod = 'bz2'
- self.logMaxTailSize = None
- self.logMaxSize = None
- self.properties = properties.Properties()
- self.mergeRequests = None
- self.codebaseGenerator = None
- self.prioritizeBuilders = None
- self.slavePortnum = None
- self.multiMaster = False
- self.debugPassword = None
- self.manhole = None
-
- self.validation = dict(
- branch=re.compile(r'^[\w.+/~-]*$'),
- revision=re.compile(r'^[ \w\.\-\/]*$'),
- property_name=re.compile(r'^[\w\.\-\/\~:]*$'),
- property_value=re.compile(r'^[\w\.\-\/\~:]*$'),
- )
- self.db = dict(
- db_url='sqlite:///state.sqlite',
- db_poll_interval=None,
- )
- self.metrics = None
- self.caches = dict(
- Builds=15,
- Changes=10,
- )
- self.schedulers = {}
- self.builders = []
- self.slaves = []
- self.change_sources = []
- self.status = []
- self.user_managers = []
- self.revlink = default_revlink_matcher
-
- _known_config_keys = set([
- "buildbotURL", "buildCacheSize", "builders", "buildHorizon", "caches",
- "change_source", "codebaseGenerator", "changeCacheSize", "changeHorizon",
- 'db', "db_poll_interval", "db_url", "debugPassword", "eventHorizon",
- "logCompressionLimit", "logCompressionMethod", "logHorizon",
- "logMaxSize", "logMaxTailSize", "manhole", "mergeRequests", "metrics",
- "multiMaster", "prioritizeBuilders", "projectName", "projectURL",
- "properties", "revlink", "schedulers", "slavePortnum", "slaves",
- "status", "title", "titleURL", "user_managers", "validation"
- ])
-
- @classmethod
- def loadConfig(cls, basedir, filename):
- if not os.path.isdir(basedir):
- raise ConfigErrors([
- "basedir '%s' does not exist" % (basedir,),
- ])
- filename = os.path.join(basedir, filename)
- if not os.path.exists(filename):
- raise ConfigErrors([
- "configuration file '%s' does not exist" % (filename,),
- ])
-
- try:
- f = open(filename, "r")
- except IOError, e:
- raise ConfigErrors([
- "unable to open configuration file %r: %s" % (filename, e),
- ])
-
- log.msg("Loading configuration from %r" % (filename,))
-
- # execute the config file
- localDict = {
- 'basedir': os.path.expanduser(basedir),
- '__file__': os.path.abspath(filename),
- }
-
- # from here on out we can batch errors together for the user's
- # convenience
- global _errors
- _errors = errors = ConfigErrors()
-
- old_sys_path = sys.path[:]
- sys.path.append(basedir)
- try:
- try:
- exec f in localDict
- except ConfigErrors, e:
- for err in e.errors:
- error(err)
- raise errors
- except:
- log.err(failure.Failure(), 'error while parsing config file:')
- error("error while parsing config file: %s (traceback in logfile)" %
- (sys.exc_info()[1],),
- )
- raise errors
- finally:
- f.close()
- sys.path[:] = old_sys_path
- _errors = None
-
- if 'BuildmasterConfig' not in localDict:
- error("Configuration file %r does not define 'BuildmasterConfig'"
- % (filename,),
- )
-
- config_dict = localDict['BuildmasterConfig']
-
- # check for unknown keys
- unknown_keys = set(config_dict.keys()) - cls._known_config_keys
- if unknown_keys:
- if len(unknown_keys) == 1:
- error('Unknown BuildmasterConfig key %s' %
- (unknown_keys.pop()))
- else:
- error('Unknown BuildmasterConfig keys %s' %
- (', '.join(sorted(unknown_keys))))
-
- # instantiate a new config object, which will apply defaults
- # automatically
- config = cls()
-
- _errors = errors
- # and defer the rest to sub-functions, for code clarity
- try:
- config.load_global(filename, config_dict)
- config.load_validation(filename, config_dict)
- config.load_db(filename, config_dict)
- config.load_metrics(filename, config_dict)
- config.load_caches(filename, config_dict)
- config.load_schedulers(filename, config_dict)
- config.load_builders(filename, config_dict)
- config.load_slaves(filename, config_dict)
- config.load_change_sources(filename, config_dict)
- config.load_status(filename, config_dict)
- config.load_user_managers(filename, config_dict)
-
- # run some sanity checks
- config.check_single_master()
- config.check_schedulers()
- config.check_locks()
- config.check_builders()
- config.check_status()
- config.check_horizons()
- config.check_slavePortnum()
- finally:
- _errors = None
-
- if errors:
- raise errors
-
- return config
-
- def load_global(self, filename, config_dict):
- def copy_param(name, alt_key=None,
- check_type=None, check_type_name=None):
- if name in config_dict:
- v = config_dict[name]
- elif alt_key and alt_key in config_dict:
- v = config_dict[alt_key]
- else:
- return
- if v is not None and check_type and not isinstance(v, check_type):
- error("c['%s'] must be %s" %
- (name, check_type_name))
- else:
- setattr(self, name, v)
-
- def copy_int_param(name, alt_key=None):
- copy_param(name, alt_key=alt_key,
- check_type=int, check_type_name='an int')
-
- def copy_str_param(name, alt_key=None):
- copy_param(name, alt_key=alt_key,
- check_type=basestring, check_type_name='a string')
-
- copy_str_param('title', alt_key='projectName')
- copy_str_param('titleURL', alt_key='projectURL')
- copy_str_param('buildbotURL')
-
- copy_int_param('changeHorizon')
- copy_int_param('eventHorizon')
- copy_int_param('logHorizon')
- copy_int_param('buildHorizon')
-
- copy_int_param('logCompressionLimit')
-
- if 'logCompressionMethod' in config_dict:
- logCompressionMethod = config_dict.get('logCompressionMethod')
- if logCompressionMethod not in ('bz2', 'gz'):
- error("c['logCompressionMethod'] must be 'bz2' or 'gz'")
- self.logCompressionMethod = logCompressionMethod
-
- copy_int_param('logMaxSize')
- copy_int_param('logMaxTailSize')
-
- properties = config_dict.get('properties', {})
- if not isinstance(properties, dict):
- error("c['properties'] must be a dictionary")
- else:
- self.properties.update(properties, filename)
-
- mergeRequests = config_dict.get('mergeRequests')
- if (mergeRequests not in (None, True, False)
- and not callable(mergeRequests)):
- error("mergeRequests must be a callable, True, or False")
- else:
- self.mergeRequests = mergeRequests
-
- codebaseGenerator = config_dict.get('codebaseGenerator')
- if (codebaseGenerator is not None and
- not callable(codebaseGenerator)):
- error("codebaseGenerator must be a callable accepting a dict and returning a str")
- else:
- self.codebaseGenerator = codebaseGenerator
-
- prioritizeBuilders = config_dict.get('prioritizeBuilders')
- if prioritizeBuilders is not None and not callable(prioritizeBuilders):
- error("prioritizeBuilders must be a callable")
- else:
- self.prioritizeBuilders = prioritizeBuilders
-
- if 'slavePortnum' in config_dict:
- slavePortnum = config_dict.get('slavePortnum')
- if isinstance(slavePortnum, int):
- slavePortnum = "tcp:%d" % slavePortnum
- self.slavePortnum = slavePortnum
-
- if 'multiMaster' in config_dict:
- self.multiMaster = config_dict["multiMaster"]
-
- copy_str_param('debugPassword')
-
- if 'manhole' in config_dict:
- # we don't check that this is a manhole instance, since that
- # requires importing buildbot.manhole for every user, and currently
- # that will fail if pycrypto isn't installed
- self.manhole = config_dict['manhole']
-
- if 'revlink' in config_dict:
- revlink = config_dict['revlink']
- if not callable(revlink):
- error("revlink must be a callable")
- else:
- self.revlink = revlink
-
- def load_validation(self, filename, config_dict):
- validation = config_dict.get("validation", {})
- if not isinstance(validation, dict):
- error("c['validation'] must be a dictionary")
- else:
- unknown_keys = (
- set(validation.keys()) - set(self.validation.keys()))
- if unknown_keys:
- error("unrecognized validation key(s): %s" %
- (", ".join(unknown_keys)))
- else:
- self.validation.update(validation)
-
-
- def load_db(self, filename, config_dict):
- if 'db' in config_dict:
- db = config_dict['db']
- if set(db.keys()) > set(['db_url', 'db_poll_interval']):
- error("unrecognized keys in c['db']")
- self.db.update(db)
- if 'db_url' in config_dict:
- self.db['db_url'] = config_dict['db_url']
- if 'db_poll_interval' in config_dict:
- self.db['db_poll_interval'] = config_dict["db_poll_interval"]
-
- # we don't attempt to parse db URLs here - the engine strategy will do so
-
- # check the db_poll_interval
- db_poll_interval = self.db['db_poll_interval']
- if db_poll_interval is not None and \
- not isinstance(db_poll_interval, int):
- error("c['db_poll_interval'] must be an int")
- else:
- self.db['db_poll_interval'] = db_poll_interval
-
-
- def load_metrics(self, filename, config_dict):
- # we don't try to validate metrics keys
- if 'metrics' in config_dict:
- metrics = config_dict["metrics"]
- if not isinstance(metrics, dict):
- error("c['metrics'] must be a dictionary")
- else:
- self.metrics = metrics
-
-
- def load_caches(self, filename, config_dict):
- explicit = False
- if 'caches' in config_dict:
- explicit = True
- caches = config_dict['caches']
- if not isinstance(caches, dict):
- error("c['caches'] must be a dictionary")
- else:
- valPairs = caches.items()
- for (x, y) in valPairs:
- if not isinstance(y, int):
- error("value for cache size '%s' must be an integer" % x)
- self.caches.update(caches)
-
- if 'buildCacheSize' in config_dict:
- if explicit:
- msg = "cannot specify c['caches'] and c['buildCacheSize']"
- error(msg)
- self.caches['Builds'] = config_dict['buildCacheSize']
- if 'changeCacheSize' in config_dict:
- if explicit:
- msg = "cannot specify c['caches'] and c['changeCacheSize']"
- error(msg)
- self.caches['Changes'] = config_dict['changeCacheSize']
-
-
- def load_schedulers(self, filename, config_dict):
- if 'schedulers' not in config_dict:
- return
- schedulers = config_dict['schedulers']
-
- ok = True
- if not isinstance(schedulers, (list, tuple)):
- ok = False
- else:
- for s in schedulers:
- if not interfaces.IScheduler.providedBy(s):
- ok = False
- if not ok:
- msg="c['schedulers'] must be a list of Scheduler instances"
- error(msg)
-
- # convert from list to dict, first looking for duplicates
- seen_names = set()
- for s in schedulers:
- if s.name in seen_names:
- error("scheduler name '%s' used multiple times" %
- s.name)
- seen_names.add(s.name)
-
- self.schedulers = dict((s.name, s) for s in schedulers)
-
-
- def load_builders(self, filename, config_dict):
- if 'builders' not in config_dict:
- return
- builders = config_dict['builders']
-
- if not isinstance(builders, (list, tuple)):
- error("c['builders'] must be a list")
- return
-
- # convert all builder configs to BuilderConfig instances
- def mapper(b):
- if isinstance(b, BuilderConfig):
- return b
- elif isinstance(b, dict):
- return BuilderConfig(**b)
- else:
- error("%r is not a builder config (in c['builders']" % (b,))
- builders = [ mapper(b) for b in builders ]
-
- for builder in builders:
- if builder and os.path.isabs(builder.builddir):
- warnings.warn("Absolute path '%s' for builder may cause "
- "mayhem. Perhaps you meant to specify slavebuilddir "
- "instead.")
-
- self.builders = builders
-
-
- def load_slaves(self, filename, config_dict):
- if 'slaves' not in config_dict:
- return
- slaves = config_dict['slaves']
-
- if not isinstance(slaves, (list, tuple)):
- error("c['slaves'] must be a list")
- return
-
- for sl in slaves:
- if not interfaces.IBuildSlave.providedBy(sl):
- msg = "c['slaves'] must be a list of BuildSlave instances"
- error(msg)
- return
-
- if sl.slavename in ("debug", "change", "status"):
- msg = "slave name '%s' is reserved" % sl.slavename
- error(msg)
-
- self.slaves = config_dict['slaves']
-
-
- def load_change_sources(self, filename, config_dict):
- change_source = config_dict.get('change_source', [])
- if isinstance(change_source, (list, tuple)):
- change_sources = change_source
- else:
- change_sources = [change_source]
-
- for s in change_sources:
- if not interfaces.IChangeSource.providedBy(s):
- msg = "c['change_source'] must be a list of change sources"
- error(msg)
- return
-
- self.change_sources = change_sources
-
- def load_status(self, filename, config_dict):
- if 'status' not in config_dict:
- return
- status = config_dict.get('status', [])
-
- msg = "c['status'] must be a list of status receivers"
- if not isinstance(status, (list, tuple)):
- error(msg)
- return
-
- for s in status:
- if not interfaces.IStatusReceiver.providedBy(s):
- error(msg)
- return
-
- self.status = status
-
-
- def load_user_managers(self, filename, config_dict):
- if 'user_managers' not in config_dict:
- return
- user_managers = config_dict['user_managers']
-
- msg = "c['user_managers'] must be a list of user managers"
- if not isinstance(user_managers, (list, tuple)):
- error(msg)
- return
-
- self.user_managers = user_managers
-
-
- def check_single_master(self):
- # check additional problems that are only valid in a single-master
- # installation
- if self.multiMaster:
- return
-
- if not self.slaves:
- error("no slaves are configured")
-
- if not self.builders:
- error("no builders are configured")
-
- # check that all builders are implemented on this master
- unscheduled_buildernames = set([ b.name for b in self.builders ])
- for s in self.schedulers.itervalues():
- for n in s.listBuilderNames():
- if n in unscheduled_buildernames:
- unscheduled_buildernames.remove(n)
- if unscheduled_buildernames:
- error("builder(s) %s have no schedulers to drive them"
- % (', '.join(unscheduled_buildernames),))
-
-
- def check_schedulers(self):
- # don't perform this check in multiMaster mode
- if self.multiMaster:
- return
-
- all_buildernames = set([ b.name for b in self.builders ])
-
- for s in self.schedulers.itervalues():
- for n in s.listBuilderNames():
- if n not in all_buildernames:
- error("Unknown builder '%s' in scheduler '%s'"
- % (n, s.name))
-
-
- def check_locks(self):
- # assert that all locks used by the Builds and their Steps are
- # uniquely named.
- lock_dict = {}
- def check_lock(l):
- if isinstance(l, locks.LockAccess):
- l = l.lockid
- if lock_dict.has_key(l.name):
- if lock_dict[l.name] is not l:
- msg = "Two locks share the same name, '%s'" % l.name
- error(msg)
- else:
- lock_dict[l.name] = l
-
- for b in self.builders:
- if b.locks:
- for l in b.locks:
- check_lock(l)
-
- def check_builders(self):
- # look both for duplicate builder names, and for builders pointing
- # to unknown slaves
- slavenames = set([ s.slavename for s in self.slaves ])
- seen_names = set()
- seen_builddirs = set()
-
- for b in self.builders:
- unknowns = set(b.slavenames) - slavenames
- if unknowns:
- error("builder '%s' uses unknown slaves %s" %
- (b.name, ", ".join(`u` for u in unknowns)))
- if b.name in seen_names:
- error("duplicate builder name '%s'" % b.name)
- seen_names.add(b.name)
-
- if b.builddir in seen_builddirs:
- error("duplicate builder builddir '%s'" % b.builddir)
- seen_builddirs.add(b.builddir)
-
-
- def check_status(self):
- # allow status receivers to check themselves against the rest of the
- # receivers
- for s in self.status:
- s.checkConfig(self.status)
-
-
- def check_horizons(self):
- if self.logHorizon is not None and self.buildHorizon is not None:
- if self.logHorizon > self.buildHorizon:
- error("logHorizon must be less than or equal to buildHorizon")
-
- def check_slavePortnum(self):
- if self.slavePortnum:
- return
-
- if self.slaves:
- error("slaves are configured, but no slavePortnum is set")
- if self.debugPassword:
- error("debug client is configured, but no slavePortnum is set")
-
-
-class BuilderConfig:
-
- def __init__(self, name=None, slavename=None, slavenames=None,
- builddir=None, slavebuilddir=None, factory=None, category=None,
- nextSlave=None, nextBuild=None, locks=None, env=None,
- properties=None, mergeRequests=None, description=None,
- canStartBuild=None):
-
- # name is required, and can't start with '_'
- if not name or type(name) not in (str, unicode):
- error("builder's name is required")
- name = '<unknown>'
- elif name[0] == '_':
- error("builder names must not start with an underscore: '%s'" % name)
- self.name = name
-
- # factory is required
- if factory is None:
- error("builder '%s' has no factory" % name)
- from buildbot.process.factory import BuildFactory
- if factory is not None and not isinstance(factory, BuildFactory):
- error("builder '%s's factory is not a BuildFactory instance" % name)
- self.factory = factory
-
- # slavenames can be a single slave name or a list, and should also
- # include slavename, if given
- if type(slavenames) is str:
- slavenames = [ slavenames ]
- if slavenames:
- if not isinstance(slavenames, list):
- error("builder '%s': slavenames must be a list or a string" %
- (name,))
- else:
- slavenames = []
-
- if slavename:
- if type(slavename) != str:
- error("builder '%s': slavename must be a string" % (name,))
- slavenames = slavenames + [ slavename ]
- if not slavenames:
- error("builder '%s': at least one slavename is required" % (name,))
-
- self.slavenames = slavenames
-
- # builddir defaults to name
- if builddir is None:
- builddir = safeTranslate(name)
- self.builddir = builddir
-
- # slavebuilddir defaults to builddir
- if slavebuilddir is None:
- slavebuilddir = builddir
- self.slavebuilddir = slavebuilddir
-
- # remainder are optional
- if category is not None and not isinstance(category, str):
- error("builder '%s': category must be a string" % (name,))
-
- self.category = category or ''
- self.nextSlave = nextSlave
- if nextSlave and not callable(nextSlave):
- error('nextSlave must be a callable')
- self.nextBuild = nextBuild
- if nextBuild and not callable(nextBuild):
- error('nextBuild must be a callable')
- self.canStartBuild = canStartBuild
- if canStartBuild and not callable(canStartBuild):
- error('canStartBuild must be a callable')
-
- self.locks = locks or []
- self.env = env or {}
- if not isinstance(self.env, dict):
- error("builder's env must be a dictionary")
- self.properties = properties or {}
- self.mergeRequests = mergeRequests
-
- self.description = description
-
-
- def getConfigDict(self):
- # note: this method will disappear eventually - put your smarts in the
- # constructor!
- rv = {
- 'name': self.name,
- 'slavenames': self.slavenames,
- 'factory': self.factory,
- 'builddir': self.builddir,
- 'slavebuilddir': self.slavebuilddir,
- }
- if self.category:
- rv['category'] = self.category
- if self.nextSlave:
- rv['nextSlave'] = self.nextSlave
- if self.nextBuild:
- rv['nextBuild'] = self.nextBuild
- if self.locks:
- rv['locks'] = self.locks
- if self.env:
- rv['env'] = self.env
- if self.properties:
- rv['properties'] = self.properties
- if self.mergeRequests:
- rv['mergeRequests'] = self.mergeRequests
- if self.description:
- rv['description'] = self.description
- return rv
-
-
-class ReconfigurableServiceMixin:
-
- reconfig_priority = 128
-
- @defer.inlineCallbacks
- def reconfigService(self, new_config):
- if not service.IServiceCollection.providedBy(self):
- return
-
- # get a list of child services to reconfigure
- reconfigurable_services = [ svc
- for svc in self
- if isinstance(svc, ReconfigurableServiceMixin) ]
-
- # sort by priority
- reconfigurable_services.sort(key=lambda svc : -svc.reconfig_priority)
-
- for svc in reconfigurable_services:
- yield svc.reconfigService(new_config)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/__init__.py
deleted file mode 100644
index 2789d676..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/__init__.py
+++ /dev/null
@@ -1,14 +0,0 @@
-# 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
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/base.py
deleted file mode 100644
index 78f88889..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/base.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# 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
-
-class DBConnectorComponent(object):
- # A fixed component of the DBConnector, handling one particular aspect of
- # the database. Instances of subclasses are assigned to attributes of the
- # DBConnector object, so that they are available at e.g.,
- # C{master.db.model} or C{master.db.changes}. This parent class takes care
- # of the necessary backlinks and other housekeeping.
-
- connector = None
-
- def __init__(self, connector):
- self.db = connector
-
- # set up caches
- for method in dir(self.__class__):
- o = getattr(self, method)
- if isinstance(o, CachedMethod):
- setattr(self, method, o.get_cached_method(self))
-
- _is_check_length_necessary = None
- def check_length(self, col, value):
- # for use by subclasses to check that 'value' will fit in 'col', where
- # 'col' is a table column from the model.
-
- # ignore this check for database engines that either provide this error
- # themselves (postgres) or that do not enforce maximum-length
- # restrictions (sqlite)
- if not self._is_check_length_necessary:
- if self.db.pool.engine.dialect.name == 'mysql':
- self._is_check_length_necessary = True
- else:
- # not necessary, so just stub out the method
- self.check_length = lambda col, value : None
- return
-
- assert col.type.length, "column %s does not have a length" % (col,)
- if value and len(value) > col.type.length:
- raise RuntimeError(
- "value for column %s is greater than max of %d characters: %s"
- % (col, col.type.length, value))
-
-
-class CachedMethod(object):
- def __init__(self, cache_name, method):
- self.cache_name = cache_name
- self.method = method
-
- def get_cached_method(self, component):
- meth = self.method
-
- meth_name = meth.__name__
- cache = component.db.master.caches.get_cache(self.cache_name,
- lambda key : meth(component, key))
- def wrap(key, no_cache=0):
- if no_cache:
- return meth(component, key)
- return cache.get(key)
- wrap.__name__ = meth_name + " (wrapped)"
- wrap.__module__ = meth.__module__
- wrap.__doc__ = meth.__doc__
- wrap.cache = cache
- return wrap
-
-def cached(cache_name):
- return lambda method : CachedMethod(cache_name, method)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/buildrequests.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/buildrequests.py
deleted file mode 100644
index 33091c90..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/buildrequests.py
+++ /dev/null
@@ -1,284 +0,0 @@
-# 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 itertools
-import sqlalchemy as sa
-from twisted.internet import reactor
-from twisted.python import log
-from buildbot.db import base
-from buildbot.util import epoch2datetime, datetime2epoch
-
-class AlreadyClaimedError(Exception):
- pass
-
-class NotClaimedError(Exception):
- pass
-
-class BrDict(dict):
- pass
-
-# private decorator to add a _master_objectid keyword argument, querying from
-# the master
-def with_master_objectid(fn):
- def wrap(self, *args, **kwargs):
- d = self.db.master.getObjectId()
- d.addCallback(lambda master_objectid :
- fn(self, _master_objectid=master_objectid, *args, **kwargs))
- return d
- wrap.__name__ = fn.__name__
- wrap.__doc__ = fn.__doc__
- return wrap
-
-class BuildRequestsConnectorComponent(base.DBConnectorComponent):
- # Documentation is in developer/database.rst
-
- @with_master_objectid
- def getBuildRequest(self, brid, _master_objectid=None):
- def thd(conn):
- reqs_tbl = self.db.model.buildrequests
- claims_tbl = self.db.model.buildrequest_claims
- res = conn.execute(sa.select([
- reqs_tbl.outerjoin(claims_tbl,
- (reqs_tbl.c.id == claims_tbl.c.brid)) ],
- whereclause=(reqs_tbl.c.id == brid)), use_labels=True)
- row = res.fetchone()
-
- rv = None
- if row:
- rv = self._brdictFromRow(row, _master_objectid)
- res.close()
- return rv
- return self.db.pool.do(thd)
-
- @with_master_objectid
- def getBuildRequests(self, buildername=None, complete=None, claimed=None,
- bsid=None, _master_objectid=None, branch=None, repository=None):
- def thd(conn):
- reqs_tbl = self.db.model.buildrequests
- claims_tbl = self.db.model.buildrequest_claims
- bsets_tbl = self.db.model.buildsets
- sstamps_tbls = self.db.model.sourcestamps
-
- from_clause = reqs_tbl.outerjoin(claims_tbl,
- reqs_tbl.c.id == claims_tbl.c.brid)
-
- if branch or repository:
- from_clause = from_clause.join(bsets_tbl,
- reqs_tbl.c.buildsetid ==
- bsets_tbl.c.id)
- from_clause = from_clause.join(sstamps_tbls,
- bsets_tbl.c.sourcestampsetid ==
- sstamps_tbls.c.sourcestampsetid)
-
- q = sa.select([ reqs_tbl, claims_tbl ]).select_from(from_clause)
- if claimed is not None:
- if not claimed:
- q = q.where(
- (claims_tbl.c.claimed_at == None) &
- (reqs_tbl.c.complete == 0))
- elif claimed == "mine":
- q = q.where(
- (claims_tbl.c.objectid == _master_objectid))
- else:
- q = q.where(
- (claims_tbl.c.claimed_at != None))
- if buildername is not None:
- q = q.where(reqs_tbl.c.buildername == buildername)
- if complete is not None:
- if complete:
- q = q.where(reqs_tbl.c.complete != 0)
- else:
- q = q.where(reqs_tbl.c.complete == 0)
- if bsid is not None:
- q = q.where(reqs_tbl.c.buildsetid == bsid)
-
- if branch is not None:
- q = q.where(sstamps_tbls.c.branch == branch)
- if repository is not None:
- q = q.where(sstamps_tbls.c.repository == repository)
-
- res = conn.execute(q)
-
- return [ self._brdictFromRow(row, _master_objectid)
- for row in res.fetchall() ]
- return self.db.pool.do(thd)
-
- @with_master_objectid
- def claimBuildRequests(self, brids, claimed_at=None, _reactor=reactor,
- _master_objectid=None):
- if claimed_at is not None:
- claimed_at = datetime2epoch(claimed_at)
- else:
- claimed_at = _reactor.seconds()
-
- def thd(conn):
- transaction = conn.begin()
- tbl = self.db.model.buildrequest_claims
-
- try:
- q = tbl.insert()
- conn.execute(q, [ dict(brid=id, objectid=_master_objectid,
- claimed_at=claimed_at)
- for id in brids ])
- except (sa.exc.IntegrityError, sa.exc.ProgrammingError):
- transaction.rollback()
- raise AlreadyClaimedError
-
- transaction.commit()
-
- return self.db.pool.do(thd)
-
- @with_master_objectid
- def reclaimBuildRequests(self, brids, _reactor=reactor,
- _master_objectid=None):
- def thd(conn):
- transaction = conn.begin()
- tbl = self.db.model.buildrequest_claims
- claimed_at = _reactor.seconds()
-
- # we'll need to batch the brids into groups of 100, so that the
- # parameter lists supported by the DBAPI aren't exhausted
- iterator = iter(brids)
-
- while 1:
- batch = list(itertools.islice(iterator, 100))
- if not batch:
- break # success!
-
- q = tbl.update(tbl.c.brid.in_(batch)
- & (tbl.c.objectid==_master_objectid))
- res = conn.execute(q, claimed_at=claimed_at)
-
- # if fewer rows were updated than expected, then something
- # went wrong
- if res.rowcount != len(batch):
- transaction.rollback()
- raise AlreadyClaimedError
-
- transaction.commit()
- return self.db.pool.do(thd)
-
- @with_master_objectid
- def unclaimBuildRequests(self, brids, _master_objectid=None):
- def thd(conn):
- transaction = conn.begin()
- claims_tbl = self.db.model.buildrequest_claims
-
- # we'll need to batch the brids into groups of 100, so that the
- # parameter lists supported by the DBAPI aren't exhausted
- iterator = iter(brids)
-
- while 1:
- batch = list(itertools.islice(iterator, 100))
- if not batch:
- break # success!
-
- try:
- q = claims_tbl.delete(
- (claims_tbl.c.brid.in_(batch))
- & (claims_tbl.c.objectid == _master_objectid))
- conn.execute(q)
- except:
- transaction.rollback()
- raise
-
- transaction.commit()
- return self.db.pool.do(thd)
-
- @with_master_objectid
- def completeBuildRequests(self, brids, results, complete_at=None,
- _reactor=reactor, _master_objectid=None):
- if complete_at is not None:
- complete_at = datetime2epoch(complete_at)
- else:
- complete_at = _reactor.seconds()
-
- def thd(conn):
- transaction = conn.begin()
-
- # the update here is simple, but a number of conditions are
- # attached to ensure that we do not update a row inappropriately,
- # Note that checking that the request is mine would require a
- # subquery, so for efficiency that is not checed.
-
- reqs_tbl = self.db.model.buildrequests
-
- # we'll need to batch the brids into groups of 100, so that the
- # parameter lists supported by the DBAPI aren't exhausted
- iterator = iter(brids)
-
- while 1:
- batch = list(itertools.islice(iterator, 100))
- if not batch:
- break # success!
-
- q = reqs_tbl.update()
- q = q.where(reqs_tbl.c.id.in_(batch))
- q = q.where(reqs_tbl.c.complete != 1)
- res = conn.execute(q,
- complete=1,
- results=results,
- complete_at=complete_at)
-
- # if an incorrect number of rows were updated, then we failed.
- if res.rowcount != len(batch):
- log.msg("tried to complete %d buildreqests, "
- "but only completed %d" % (len(batch), res.rowcount))
- transaction.rollback()
- raise NotClaimedError
- transaction.commit()
- return self.db.pool.do(thd)
-
- def unclaimExpiredRequests(self, old, _reactor=reactor):
- def thd(conn):
- reqs_tbl = self.db.model.buildrequests
- claims_tbl = self.db.model.buildrequest_claims
- old_epoch = _reactor.seconds() - old
-
- # select any expired requests, and delete each one individually
- expired_brids = sa.select([ reqs_tbl.c.id ],
- whereclause=(reqs_tbl.c.complete != 1))
- res = conn.execute(claims_tbl.delete(
- (claims_tbl.c.claimed_at < old_epoch) &
- claims_tbl.c.brid.in_(expired_brids)))
- return res.rowcount
- d = self.db.pool.do(thd)
- def log_nonzero_count(count):
- if count != 0:
- log.msg("unclaimed %d expired buildrequests (over %d seconds "
- "old)" % (count, old))
- d.addCallback(log_nonzero_count)
- return d
-
- def _brdictFromRow(self, row, master_objectid):
- claimed = mine = False
- claimed_at = None
- if row.claimed_at is not None:
- claimed_at = row.claimed_at
- claimed = True
- mine = row.objectid == master_objectid
-
- def mkdt(epoch):
- if epoch:
- return epoch2datetime(epoch)
- submitted_at = mkdt(row.submitted_at)
- complete_at = mkdt(row.complete_at)
- claimed_at = mkdt(row.claimed_at)
-
- return BrDict(brid=row.id, buildsetid=row.buildsetid,
- buildername=row.buildername, priority=row.priority,
- claimed=claimed, claimed_at=claimed_at, mine=mine,
- complete=bool(row.complete), results=row.results,
- submitted_at=submitted_at, complete_at=complete_at)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/builds.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/builds.py
deleted file mode 100644
index 8c25f078..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/builds.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# 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
-
-from twisted.internet import reactor
-from buildbot.db import base
-from buildbot.util import epoch2datetime
-
-class BuildsConnectorComponent(base.DBConnectorComponent):
- # Documentation is in developer/database.rst
-
- def getBuild(self, bid):
- def thd(conn):
- tbl = self.db.model.builds
- res = conn.execute(tbl.select(whereclause=(tbl.c.id == bid)))
- row = res.fetchone()
-
- rv = None
- if row:
- rv = self._bdictFromRow(row)
- res.close()
- return rv
- return self.db.pool.do(thd)
-
- def getBuildsForRequest(self, brid):
- def thd(conn):
- tbl = self.db.model.builds
- q = tbl.select(whereclause=(tbl.c.brid == brid))
- res = conn.execute(q)
- return [ self._bdictFromRow(row) for row in res.fetchall() ]
- return self.db.pool.do(thd)
-
- def addBuild(self, brid, number, _reactor=reactor):
- def thd(conn):
- start_time = _reactor.seconds()
- r = conn.execute(self.db.model.builds.insert(),
- dict(number=number, brid=brid, start_time=start_time,
- finish_time=None))
- return r.inserted_primary_key[0]
- return self.db.pool.do(thd)
-
- def finishBuilds(self, bids, _reactor=reactor):
- def thd(conn):
- transaction = conn.begin()
- tbl = self.db.model.builds
- now = _reactor.seconds()
-
- # split the bids into batches, so as not to overflow the parameter
- # lists of the database interface
- remaining = bids
- while remaining:
- batch, remaining = remaining[:100], remaining[100:]
- q = tbl.update(whereclause=(tbl.c.id.in_(batch)))
- conn.execute(q, finish_time=now)
-
- transaction.commit()
- return self.db.pool.do(thd)
-
- def _bdictFromRow(self, row):
- def mkdt(epoch):
- if epoch:
- return epoch2datetime(epoch)
-
- return dict(
- bid=row.id,
- brid=row.brid,
- number=row.number,
- start_time=mkdt(row.start_time),
- finish_time=mkdt(row.finish_time))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/buildsets.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/buildsets.py
deleted file mode 100644
index b379198e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/buildsets.py
+++ /dev/null
@@ -1,202 +0,0 @@
-# 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
-
-"""
-Support for buildsets in the database
-"""
-
-import sqlalchemy as sa
-from twisted.internet import reactor
-from buildbot.util import json
-from buildbot.db import base
-from buildbot.util import epoch2datetime, datetime2epoch
-
-class BsDict(dict):
- pass
-
-class BuildsetsConnectorComponent(base.DBConnectorComponent):
- # Documentation is in developer/database.rst
-
- def addBuildset(self, sourcestampsetid, reason, properties, builderNames,
- external_idstring=None, _reactor=reactor):
- def thd(conn):
- buildsets_tbl = self.db.model.buildsets
- submitted_at = _reactor.seconds()
-
- self.check_length(buildsets_tbl.c.reason, reason)
- self.check_length(buildsets_tbl.c.external_idstring,
- external_idstring)
-
- transaction = conn.begin()
-
- # insert the buildset itself
- r = conn.execute(buildsets_tbl.insert(), dict(
- sourcestampsetid=sourcestampsetid, submitted_at=submitted_at,
- reason=reason, complete=0, complete_at=None, results=-1,
- external_idstring=external_idstring))
- bsid = r.inserted_primary_key[0]
-
- # add any properties
- if properties:
- bs_props_tbl = self.db.model.buildset_properties
-
- inserts = [
- dict(buildsetid=bsid, property_name=k,
- property_value=json.dumps([v,s]))
- for k,(v,s) in properties.iteritems() ]
- for i in inserts:
- self.check_length(bs_props_tbl.c.property_name,
- i['property_name'])
- self.check_length(bs_props_tbl.c.property_value,
- i['property_value'])
-
- conn.execute(bs_props_tbl.insert(), inserts)
-
- # and finish with a build request for each builder. Note that
- # sqlalchemy and the Python DBAPI do not provide a way to recover
- # inserted IDs from a multi-row insert, so this is done one row at
- # a time.
- brids = {}
- br_tbl = self.db.model.buildrequests
- ins = br_tbl.insert()
- for buildername in builderNames:
- self.check_length(br_tbl.c.buildername, buildername)
- r = conn.execute(ins,
- dict(buildsetid=bsid, buildername=buildername, priority=0,
- claimed_at=0, claimed_by_name=None,
- claimed_by_incarnation=None, complete=0, results=-1,
- submitted_at=submitted_at, complete_at=None))
-
- brids[buildername] = r.inserted_primary_key[0]
-
- transaction.commit()
-
- return (bsid, brids)
- return self.db.pool.do(thd)
-
- def completeBuildset(self, bsid, results, complete_at=None,
- _reactor=reactor):
- if complete_at is not None:
- complete_at = datetime2epoch(complete_at)
- else:
- complete_at = _reactor.seconds()
-
- def thd(conn):
- tbl = self.db.model.buildsets
-
- q = tbl.update(whereclause=(
- (tbl.c.id == bsid) &
- ((tbl.c.complete == None) | (tbl.c.complete != 1))))
- res = conn.execute(q,
- complete=1,
- results=results,
- complete_at=complete_at)
-
- if res.rowcount != 1:
- raise KeyError
- return self.db.pool.do(thd)
-
- def getBuildset(self, bsid):
- def thd(conn):
- bs_tbl = self.db.model.buildsets
- q = bs_tbl.select(whereclause=(bs_tbl.c.id == bsid))
- res = conn.execute(q)
- row = res.fetchone()
- if not row:
- return None
- return self._row2dict(row)
- return self.db.pool.do(thd)
-
- def getBuildsets(self, complete=None):
- def thd(conn):
- bs_tbl = self.db.model.buildsets
- q = bs_tbl.select()
- if complete is not None:
- if complete:
- q = q.where(bs_tbl.c.complete != 0)
- else:
- q = q.where((bs_tbl.c.complete == 0) |
- (bs_tbl.c.complete == None))
- res = conn.execute(q)
- return [ self._row2dict(row) for row in res.fetchall() ]
- return self.db.pool.do(thd)
-
- def getRecentBuildsets(self, count, branch=None, repository=None,
- complete=None):
- def thd(conn):
- bs_tbl = self.db.model.buildsets
- ss_tbl = self.db.model.sourcestamps
- j = sa.join(self.db.model.buildsets,
- self.db.model.sourcestampsets)
- j = j.join(self.db.model.sourcestamps)
- q = sa.select(columns=[bs_tbl], from_obj=[j],
- distinct=True)
- q = q.order_by(sa.desc(bs_tbl.c.submitted_at))
- q = q.limit(count)
-
- if complete is not None:
- if complete:
- q = q.where(bs_tbl.c.complete != 0)
- else:
- q = q.where((bs_tbl.c.complete == 0) |
- (bs_tbl.c.complete == None))
- if branch:
- q = q.where(ss_tbl.c.branch == branch)
- if repository:
- q = q.where(ss_tbl.c.repository == repository)
- res = conn.execute(q)
- return list(reversed([ self._row2dict(row)
- for row in res.fetchall() ]))
- return self.db.pool.do(thd)
-
- def getBuildsetProperties(self, buildsetid):
- """
- Return the properties for a buildset, in the same format they were
- given to L{addBuildset}.
-
- Note that this method does not distinguish a nonexistent buildset from
- a buildset with no properties, and returns C{{}} in either case.
-
- @param buildsetid: buildset ID
-
- @returns: dictionary mapping property name to (value, source), via
- Deferred
- """
- def thd(conn):
- bsp_tbl = self.db.model.buildset_properties
- q = sa.select(
- [ bsp_tbl.c.property_name, bsp_tbl.c.property_value ],
- whereclause=(bsp_tbl.c.buildsetid == buildsetid))
- l = []
- for row in conn.execute(q):
- try:
- properties = json.loads(row.property_value)
- l.append((row.property_name,
- tuple(properties)))
- except ValueError:
- pass
- return dict(l)
- return self.db.pool.do(thd)
-
- def _row2dict(self, row):
- def mkdt(epoch):
- if epoch:
- return epoch2datetime(epoch)
- return BsDict(external_idstring=row.external_idstring,
- reason=row.reason, sourcestampsetid=row.sourcestampsetid,
- submitted_at=mkdt(row.submitted_at),
- complete=bool(row.complete),
- complete_at=mkdt(row.complete_at), results=row.results,
- bsid=row.id)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/changes.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/changes.py
deleted file mode 100644
index 4288be53..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/changes.py
+++ /dev/null
@@ -1,257 +0,0 @@
-# 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
-
-"""
-Support for changes in the database
-"""
-
-from buildbot.util import json
-import sqlalchemy as sa
-from twisted.internet import defer, reactor
-from buildbot.db import base
-from buildbot.util import epoch2datetime, datetime2epoch
-
-class ChDict(dict):
- pass
-
-class ChangesConnectorComponent(base.DBConnectorComponent):
- # Documentation is in developer/database.rst
-
- def addChange(self, author=None, files=None, comments=None, is_dir=0,
- revision=None, when_timestamp=None, branch=None,
- category=None, revlink='', properties={}, repository='', codebase='',
- project='', uid=None, _reactor=reactor):
- assert project is not None, "project must be a string, not None"
- assert repository is not None, "repository must be a string, not None"
-
- if when_timestamp is None:
- when_timestamp = epoch2datetime(_reactor.seconds())
-
- # verify that source is 'Change' for each property
- for pv in properties.values():
- assert pv[1] == 'Change', ("properties must be qualified with"
- "source 'Change'")
-
- def thd(conn):
- # note that in a read-uncommitted database like SQLite this
- # transaction does not buy atomicitiy - other database users may
- # still come across a change without its files, properties,
- # etc. That's OK, since we don't announce the change until it's
- # all in the database, but beware.
-
- transaction = conn.begin()
-
- ch_tbl = self.db.model.changes
-
- self.check_length(ch_tbl.c.author, author)
- self.check_length(ch_tbl.c.comments, comments)
- self.check_length(ch_tbl.c.branch, branch)
- self.check_length(ch_tbl.c.revision, revision)
- self.check_length(ch_tbl.c.revlink, revlink)
- self.check_length(ch_tbl.c.category, category)
- self.check_length(ch_tbl.c.repository, repository)
- self.check_length(ch_tbl.c.project, project)
-
- r = conn.execute(ch_tbl.insert(), dict(
- author=author,
- comments=comments,
- is_dir=is_dir,
- branch=branch,
- revision=revision,
- revlink=revlink,
- when_timestamp=datetime2epoch(when_timestamp),
- category=category,
- repository=repository,
- codebase=codebase,
- project=project))
- changeid = r.inserted_primary_key[0]
- if files:
- tbl = self.db.model.change_files
- for f in files:
- self.check_length(tbl.c.filename, f)
- conn.execute(tbl.insert(), [
- dict(changeid=changeid, filename=f)
- for f in files
- ])
- if properties:
- tbl = self.db.model.change_properties
- inserts = [
- dict(changeid=changeid,
- property_name=k,
- property_value=json.dumps(v))
- for k,v in properties.iteritems()
- ]
- for i in inserts:
- self.check_length(tbl.c.property_name,
- i['property_name'])
- self.check_length(tbl.c.property_value,
- i['property_value'])
-
- conn.execute(tbl.insert(), inserts)
- if uid:
- ins = self.db.model.change_users.insert()
- conn.execute(ins, dict(changeid=changeid, uid=uid))
-
- transaction.commit()
-
- return changeid
- d = self.db.pool.do(thd)
- return d
-
- @base.cached("chdicts")
- def getChange(self, changeid):
- assert changeid >= 0
- def thd(conn):
- # get the row from the 'changes' table
- changes_tbl = self.db.model.changes
- q = changes_tbl.select(whereclause=(changes_tbl.c.changeid == changeid))
- rp = conn.execute(q)
- row = rp.fetchone()
- if not row:
- return None
- # and fetch the ancillary data (files, properties)
- return self._chdict_from_change_row_thd(conn, row)
- d = self.db.pool.do(thd)
- return d
-
- def getChangeUids(self, changeid):
- assert changeid >= 0
- def thd(conn):
- cu_tbl = self.db.model.change_users
- q = cu_tbl.select(whereclause=(cu_tbl.c.changeid == changeid))
- res = conn.execute(q)
- rows = res.fetchall()
- row_uids = [ row.uid for row in rows ]
- return row_uids
- d = self.db.pool.do(thd)
- return d
-
- def getRecentChanges(self, count):
- def thd(conn):
- # get the changeids from the 'changes' table
- changes_tbl = self.db.model.changes
- q = sa.select([changes_tbl.c.changeid],
- order_by=[sa.desc(changes_tbl.c.changeid)],
- limit=count)
- rp = conn.execute(q)
- changeids = [ row.changeid for row in rp ]
- rp.close()
- return list(reversed(changeids))
- d = self.db.pool.do(thd)
-
- # then turn those into changes, using the cache
- def get_changes(changeids):
- return defer.gatherResults([ self.getChange(changeid)
- for changeid in changeids ])
- d.addCallback(get_changes)
- return d
-
- def getLatestChangeid(self):
- def thd(conn):
- changes_tbl = self.db.model.changes
- q = sa.select([ changes_tbl.c.changeid ],
- order_by=sa.desc(changes_tbl.c.changeid),
- limit=1)
- return conn.scalar(q)
- d = self.db.pool.do(thd)
- return d
-
- # utility methods
-
- def pruneChanges(self, changeHorizon):
- """
- Called periodically by DBConnector, this method deletes changes older
- than C{changeHorizon}.
- """
-
- if not changeHorizon:
- return defer.succeed(None)
- def thd(conn):
- changes_tbl = self.db.model.changes
-
- # First, get the list of changes to delete. This could be written
- # as a subquery but then that subquery would be run for every
- # table, which is very inefficient; also, MySQL's subquery support
- # leaves much to be desired, and doesn't support this particular
- # form.
- q = sa.select([changes_tbl.c.changeid],
- order_by=[sa.desc(changes_tbl.c.changeid)],
- offset=changeHorizon)
- res = conn.execute(q)
- ids_to_delete = [ r.changeid for r in res ]
-
- # and delete from all relevant tables, in dependency order
- for table_name in ('scheduler_changes', 'sourcestamp_changes',
- 'change_files', 'change_properties', 'changes',
- 'change_users'):
- remaining = ids_to_delete[:]
- while remaining:
- batch, remaining = remaining[:100], remaining[100:]
- table = self.db.model.metadata.tables[table_name]
- conn.execute(
- table.delete(table.c.changeid.in_(batch)))
- return self.db.pool.do(thd)
-
- def _chdict_from_change_row_thd(self, conn, ch_row):
- # This method must be run in a db.pool thread, and returns a chdict
- # given a row from the 'changes' table
- change_files_tbl = self.db.model.change_files
- change_properties_tbl = self.db.model.change_properties
-
- chdict = ChDict(
- changeid=ch_row.changeid,
- author=ch_row.author,
- files=[], # see below
- comments=ch_row.comments,
- is_dir=ch_row.is_dir,
- revision=ch_row.revision,
- when_timestamp=epoch2datetime(ch_row.when_timestamp),
- branch=ch_row.branch,
- category=ch_row.category,
- revlink=ch_row.revlink,
- properties={}, # see below
- repository=ch_row.repository,
- codebase=ch_row.codebase,
- project=ch_row.project)
-
- query = change_files_tbl.select(
- whereclause=(change_files_tbl.c.changeid == ch_row.changeid))
- rows = conn.execute(query)
- for r in rows:
- chdict['files'].append(r.filename)
-
- # and properties must be given without a source, so strip that, but
- # be flexible in case users have used a development version where the
- # change properties were recorded incorrectly
- def split_vs(vs):
- try:
- v,s = vs
- if s != "Change":
- v,s = vs, "Change"
- except:
- v,s = vs, "Change"
- return v, s
-
- query = change_properties_tbl.select(
- whereclause=(change_properties_tbl.c.changeid == ch_row.changeid))
- rows = conn.execute(query)
- for r in rows:
- try:
- v, s = split_vs(json.loads(r.property_value))
- chdict['properties'][r.property_name] = (v,s)
- except ValueError:
- pass
-
- return chdict
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/connector.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/connector.py
deleted file mode 100644
index bc571649..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/connector.py
+++ /dev/null
@@ -1,125 +0,0 @@
-# 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 textwrap
-from twisted.internet import defer
-from twisted.python import log
-from twisted.application import internet, service
-from buildbot import config
-from buildbot.db import enginestrategy
-from buildbot.db import pool, model, changes, schedulers, sourcestamps, sourcestampsets
-from buildbot.db import state, buildsets, buildrequests, builds, users
-
-class DatabaseNotReadyError(Exception):
- pass
-
-upgrade_message = textwrap.dedent("""\
-
- The Buildmaster database needs to be upgraded before this version of
- buildbot can run. Use the following command-line
-
- buildbot upgrade-master path/to/master
-
- to upgrade the database, and try starting the buildmaster again. You may
- want to make a backup of your buildmaster before doing so.
- """).strip()
-
-class DBConnector(config.ReconfigurableServiceMixin, service.MultiService):
- # The connection between Buildbot and its backend database. This is
- # generally accessible as master.db, but is also used during upgrades.
- #
- # Most of the interesting operations available via the connector are
- # implemented in connector components, available as attributes of this
- # object, and listed below.
-
- # Period, in seconds, of the cleanup task. This master will perform
- # periodic cleanup actions on this schedule.
- CLEANUP_PERIOD = 3600
-
- def __init__(self, master, basedir):
- service.MultiService.__init__(self)
- self.setName('db')
- self.master = master
- self.basedir = basedir
-
- # not configured yet - we don't build an engine until the first
- # reconfig
- self.configured_url = None
-
- # set up components
- self._engine = None # set up in reconfigService
- self.pool = None # set up in reconfigService
- self.model = model.Model(self)
- self.changes = changes.ChangesConnectorComponent(self)
- self.schedulers = schedulers.SchedulersConnectorComponent(self)
- self.sourcestamps = sourcestamps.SourceStampsConnectorComponent(self)
- self.sourcestampsets = sourcestampsets.SourceStampSetsConnectorComponent(self)
- self.buildsets = buildsets.BuildsetsConnectorComponent(self)
- self.buildrequests = buildrequests.BuildRequestsConnectorComponent(self)
- self.state = state.StateConnectorComponent(self)
- self.builds = builds.BuildsConnectorComponent(self)
- self.users = users.UsersConnectorComponent(self)
-
- self.cleanup_timer = internet.TimerService(self.CLEANUP_PERIOD,
- self._doCleanup)
- self.cleanup_timer.setServiceParent(self)
-
-
- def setup(self, check_version=True, verbose=True):
- db_url = self.configured_url = self.master.config.db['db_url']
-
- log.msg("Setting up database with URL %r" % (db_url,))
-
- # set up the engine and pool
- self._engine = enginestrategy.create_engine(db_url,
- basedir=self.basedir)
- self.pool = pool.DBThreadPool(self._engine, verbose=verbose)
-
- # make sure the db is up to date, unless specifically asked not to
- if check_version:
- d = self.model.is_current()
- def check_current(res):
- if not res:
- for l in upgrade_message.split('\n'):
- log.msg(l)
- raise DatabaseNotReadyError()
- d.addCallback(check_current)
- else:
- d = defer.succeed(None)
-
- return d
-
-
- def reconfigService(self, new_config):
- # double-check -- the master ensures this in config checks
- assert self.configured_url == new_config.db['db_url']
-
- return config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
-
- def _doCleanup(self):
- """
- Perform any periodic database cleanup tasks.
-
- @returns: Deferred
- """
- # pass on this if we're not configured yet
- if not self.configured_url:
- return
-
- d = self.changes.pruneChanges(self.master.config.changeHorizon)
- d.addErrback(log.err, 'while pruning changes')
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/enginestrategy.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/enginestrategy.py
deleted file mode 100644
index 2be80f9a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/enginestrategy.py
+++ /dev/null
@@ -1,206 +0,0 @@
-# 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
-
-"""
-A wrapper around `sqlalchemy.create_engine` that handles all of the
-special cases that Buildbot needs. Those include:
-
- - pool_recycle for MySQL
- - %(basedir) substitution
- - optimal thread pool size calculation
-
-"""
-
-import os
-import sqlalchemy as sa
-from twisted.python import log
-from sqlalchemy.engine import strategies, url
-from sqlalchemy.pool import NullPool
-from buildbot.util import sautils
-
-# from http://www.mail-archive.com/sqlalchemy@googlegroups.com/msg15079.html
-class ReconnectingListener(object):
- def __init__(self):
- self.retried = False
-
-class BuildbotEngineStrategy(strategies.ThreadLocalEngineStrategy):
- # A subclass of the ThreadLocalEngineStrategy that can effectively interact
- # with Buildbot.
- #
- # This adjusts the passed-in parameters to ensure that we get the behaviors
- # Buildbot wants from particular drivers, and wraps the outgoing Engine
- # object so that its methods run in threads and return deferreds.
-
- name = 'buildbot'
-
- def special_case_sqlite(self, u, kwargs):
- """For sqlite, percent-substitute %(basedir)s and use a full
- path to the basedir. If using a memory database, force the
- pool size to be 1."""
- max_conns = None
-
- # when given a database path, stick the basedir in there
- if u.database:
-
- # Use NullPool instead of the sqlalchemy-0.6.8-default
- # SingletonThreadpool for sqlite to suppress the error in
- # http://groups.google.com/group/sqlalchemy/msg/f8482e4721a89589,
- # which also explains that NullPool is the new default in
- # sqlalchemy 0.7 for non-memory SQLite databases.
- kwargs.setdefault('poolclass', NullPool)
-
- u.database = u.database % dict(basedir = kwargs['basedir'])
- if not os.path.isabs(u.database[0]):
- u.database = os.path.join(kwargs['basedir'], u.database)
-
- # in-memory databases need exactly one connection
- if not u.database:
- kwargs['pool_size'] = 1
- max_conns = 1
-
- # allow serializing access to the db
- if 'serialize_access' in u.query:
- u.query.pop('serialize_access')
- max_conns = 1
-
- return u, kwargs, max_conns
-
- def set_up_sqlite_engine(self, u, engine):
- """Special setup for sqlite engines"""
- # try to enable WAL logging
- if u.database:
- def connect_listener(connection, record):
- connection.execute("pragma checkpoint_fullfsync = off")
-
- if sautils.sa_version() < (0,7,0):
- class CheckpointFullfsyncDisabler(object):
- pass
- disabler = CheckpointFullfsyncDisabler()
- disabler.connect = connect_listener
- engine.pool.add_listener(disabler)
- else:
- sa.event.listen(engine.pool, 'connect', connect_listener)
-
- log.msg("setting database journal mode to 'wal'")
- try:
- engine.execute("pragma journal_mode = wal")
- except:
- log.msg("failed to set journal mode - database may fail")
-
- def special_case_mysql(self, u, kwargs):
- """For mysql, take max_idle out of the query arguments, and
- use its value for pool_recycle. Also, force use_unicode and
- charset to be True and 'utf8', failing if they were set to
- anything else."""
-
- kwargs['pool_recycle'] = int(u.query.pop('max_idle', 3600))
-
- # default to the InnoDB storage engine
- storage_engine = u.query.pop('storage_engine', 'MyISAM')
- kwargs['connect_args'] = {
- 'init_command' : 'SET storage_engine=%s' % storage_engine,
- }
-
- if 'use_unicode' in u.query:
- if u.query['use_unicode'] != "True":
- raise TypeError("Buildbot requires use_unicode=True " +
- "(and adds it automatically)")
- else:
- u.query['use_unicode'] = True
-
- if 'charset' in u.query:
- if u.query['charset'] != "utf8":
- raise TypeError("Buildbot requires charset=utf8 " +
- "(and adds it automatically)")
- else:
- u.query['charset'] = 'utf8'
-
- return u, kwargs, None
-
- def set_up_mysql_engine(self, u, engine):
- """Special setup for mysql engines"""
- # add the reconnecting PoolListener that will detect a
- # disconnected connection and automatically start a new
- # one. This provides a measure of additional safety over
- # the pool_recycle parameter, and is useful when e.g., the
- # mysql server goes away
- def checkout_listener(dbapi_con, con_record, con_proxy):
- try:
- cursor = dbapi_con.cursor()
- cursor.execute("SELECT 1")
- except dbapi_con.OperationalError, ex:
- if ex.args[0] in (2006, 2013, 2014, 2045, 2055):
- # sqlalchemy will re-create the connection
- raise sa.exc.DisconnectionError()
- raise
-
- # older versions of sqlalchemy require the listener to be specified
- # in the kwargs, in a class instance
- if sautils.sa_version() < (0,7,0):
- class ReconnectingListener(object):
- pass
- rcl = ReconnectingListener()
- rcl.checkout = checkout_listener
- engine.pool.add_listener(rcl)
- else:
- sa.event.listen(engine.pool, 'checkout', checkout_listener)
-
- def create(self, name_or_url, **kwargs):
- if 'basedir' not in kwargs:
- raise TypeError('no basedir supplied to create_engine')
-
- max_conns = None
-
- # apply special cases
- u = url.make_url(name_or_url)
- if u.drivername.startswith('sqlite'):
- u, kwargs, max_conns = self.special_case_sqlite(u, kwargs)
- elif u.drivername.startswith('mysql'):
- u, kwargs, max_conns = self.special_case_mysql(u, kwargs)
-
- # remove the basedir as it may confuse sqlalchemy
- basedir = kwargs.pop('basedir')
-
- # calculate the maximum number of connections from the pool parameters,
- # if it hasn't already been specified
- if max_conns is None:
- max_conns = kwargs.get('pool_size', 5) + kwargs.get('max_overflow', 10)
-
- engine = strategies.ThreadLocalEngineStrategy.create(self,
- u, **kwargs)
-
- # annotate the engine with the optimal thread pool size; this is used
- # by DBConnector to configure the surrounding thread pool
- engine.optimal_thread_pool_size = max_conns
-
- # keep the basedir
- engine.buildbot_basedir = basedir
-
- if u.drivername.startswith('sqlite'):
- self.set_up_sqlite_engine(u, engine)
- elif u.drivername.startswith('mysql'):
- self.set_up_mysql_engine(u, engine)
-
- return engine
-
-BuildbotEngineStrategy()
-
-# this module is really imported for the side-effects, but pyflakes will like
-# us to use something from the module -- so offer a copy of create_engine,
-# which explicitly adds the strategy argument
-def create_engine(*args, **kwargs):
- kwargs['strategy'] = 'buildbot'
-
- return sa.create_engine(*args, **kwargs)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/exceptions.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/exceptions.py
deleted file mode 100644
index c8fbd6d6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/exceptions.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# 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
-
-class DatabaseNotReadyError(Exception):
- pass
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/migrate.cfg b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/migrate.cfg
deleted file mode 100644
index d63b6835..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/migrate.cfg
+++ /dev/null
@@ -1,20 +0,0 @@
-[db_settings]
-# Used to identify which repository this database is versioned under.
-# You can use the name of your project.
-repository_id=Buildbot
-
-# The name of the database table used to track the schema version.
-# This name shouldn't already be used by your project.
-# If this is changed once a database is under version control, you'll need to
-# change the table name in each database too.
-version_table=migrate_version
-
-# When committing a change script, Migrate will attempt to generate the
-# sql for all supported databases; normally, if one of them fails - probably
-# because you don't have that database installed - it is ignored and the
-# commit continues, perhaps ending successfully.
-# Databases in this list MUST compile successfully during a commit, or the
-# entire commit will fail. List the databases your application will actually
-# be using to ensure your updates to that database work properly.
-# This must be a list; example: ['postgres','sqlite']
-required_dbs=[]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/001_initial.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/001_initial.py
deleted file mode 100644
index 297d7a2c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/001_initial.py
+++ /dev/null
@@ -1,283 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os
-import cPickle
-from twisted.persisted import styles
-from buildbot.util import json
-import sqlalchemy as sa
-
-metadata = sa.MetaData()
-
-last_access = sa.Table('last_access', metadata,
- sa.Column('who', sa.String(256), nullable=False),
- sa.Column('writing', sa.Integer, nullable=False),
- sa.Column('last_access', sa.Integer, nullable=False),
-)
-
-changes_nextid = sa.Table('changes_nextid', metadata,
- sa.Column('next_changeid', sa.Integer),
-)
-
-changes = sa.Table('changes', metadata,
- sa.Column('changeid', sa.Integer, autoincrement=False, primary_key=True),
- sa.Column('author', sa.String(256), nullable=False),
- sa.Column('comments', sa.String(1024), nullable=False),
- sa.Column('is_dir', sa.SmallInteger, nullable=False),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('revlink', sa.String(256)),
- sa.Column('when_timestamp', sa.Integer, nullable=False),
- sa.Column('category', sa.String(256)),
-)
-
-change_links = sa.Table('change_links', metadata,
- sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid'), nullable=False),
- sa.Column('link', sa.String(1024), nullable=False),
-)
-
-change_files = sa.Table('change_files', metadata,
- sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid'), nullable=False),
- sa.Column('filename', sa.String(1024), nullable=False),
-)
-
-change_properties = sa.Table('change_properties', metadata,
- sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid'), nullable=False),
- sa.Column('property_name', sa.String(256), nullable=False),
- sa.Column('property_value', sa.String(1024), nullable=False),
-)
-
-schedulers = sa.Table("schedulers", metadata,
- sa.Column('schedulerid', sa.Integer, autoincrement=False, primary_key=True),
- sa.Column('name', sa.String(128), nullable=False),
- sa.Column('state', sa.String(1024), nullable=False),
-)
-
-scheduler_changes = sa.Table('scheduler_changes', metadata,
- sa.Column('schedulerid', sa.Integer, sa.ForeignKey('schedulers.schedulerid')),
- sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid')),
- sa.Column('important', sa.SmallInteger),
-)
-
-scheduler_upstream_buildsets = sa.Table('scheduler_upstream_buildsets', metadata,
- sa.Column('buildsetid', sa.Integer, sa.ForeignKey('buildsets.id')),
- sa.Column('schedulerid', sa.Integer, sa.ForeignKey('schedulers.schedulerid')),
- sa.Column('active', sa.SmallInteger),
-)
-
-sourcestamps = sa.Table('sourcestamps', metadata,
- sa.Column('id', sa.Integer, autoincrement=False, primary_key=True),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('patchid', sa.Integer, sa.ForeignKey('patches.id')),
-)
-
-patches = sa.Table('patches', metadata,
- sa.Column('id', sa.Integer, autoincrement=False, primary_key=True),
- sa.Column('patchlevel', sa.Integer, nullable=False),
- sa.Column('patch_base64', sa.Text, nullable=False),
- sa.Column('subdir', sa.Text),
-)
-
-sourcestamp_changes = sa.Table('sourcestamp_changes', metadata,
- sa.Column('sourcestampid', sa.Integer, sa.ForeignKey('sourcestamps.id'), nullable=False),
- sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid'), nullable=False),
-)
-
-buildsets = sa.Table('buildsets', metadata,
- sa.Column('id', sa.Integer, autoincrement=False, primary_key=True),
- sa.Column('external_idstring', sa.String(256)),
- sa.Column('reason', sa.String(256)),
- sa.Column('sourcestampid', sa.Integer, sa.ForeignKey('sourcestamps.id'), nullable=False),
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete', sa.SmallInteger, nullable=False, server_default=sa.DefaultClause("0")),
- sa.Column('complete_at', sa.Integer),
- sa.Column('results', sa.SmallInteger),
-)
-
-buildset_properties = sa.Table('buildset_properties', metadata,
- sa.Column('buildsetid', sa.Integer, sa.ForeignKey('buildsets.id'), nullable=False),
- sa.Column('property_name', sa.String(256), nullable=False),
- sa.Column('property_value', sa.String(1024), nullable=False),
-)
-
-buildrequests = sa.Table('buildrequests', metadata,
- sa.Column('id', sa.Integer, autoincrement=False, primary_key=True),
- sa.Column('buildsetid', sa.Integer, sa.ForeignKey("buildsets.id"), nullable=False),
- sa.Column('buildername', sa.String(length=256), nullable=False),
- sa.Column('priority', sa.Integer, nullable=False, server_default=sa.DefaultClause("0")),
- sa.Column('claimed_at', sa.Integer, server_default=sa.DefaultClause("0")),
- sa.Column('claimed_by_name', sa.String(length=256)),
- sa.Column('claimed_by_incarnation', sa.String(length=256)),
- sa.Column('complete', sa.Integer, server_default=sa.DefaultClause("0")),
- sa.Column('results', sa.SmallInteger),
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete_at', sa.Integer),
-)
-
-builds = sa.Table('builds', metadata,
- sa.Column('id', sa.Integer, autoincrement=False, primary_key=True),
- sa.Column('number', sa.Integer, nullable=False),
- sa.Column('brid', sa.Integer, sa.ForeignKey('buildrequests.id'), nullable=False),
- sa.Column('start_time', sa.Integer, nullable=False),
- sa.Column('finish_time', sa.Integer),
-)
-
-def test_unicode(migrate_engine):
- """Test that the database can handle inserting and selecting Unicode"""
- # set up a subsidiary MetaData object to hold this temporary table
- submeta = sa.MetaData()
- submeta.bind = migrate_engine
-
- test_unicode = sa.Table('test_unicode', submeta,
- sa.Column('u', sa.Unicode(length=100)),
- sa.Column('b', sa.LargeBinary),
- )
- test_unicode.create()
-
- # insert a unicode value in there
- u = u"Frosty the \N{SNOWMAN}"
- b='\xff\xff\x00'
- ins = test_unicode.insert().values(u=u, b=b)
- migrate_engine.execute(ins)
-
- # see if the data is intact
- row = migrate_engine.execute(sa.select([test_unicode])).fetchall()[0]
- assert type(row['u']) is unicode
- assert row['u'] == u
- assert type(row['b']) is str
- assert row['b'] == b
-
- # drop the test table
- test_unicode.drop()
-
-def import_changes(migrate_engine):
- # get the basedir from the engine - see model.py if you're wondering
- # how it got there
- basedir = migrate_engine.buildbot_basedir
-
- # strip None from any of these values, just in case
- def remove_none(x):
- if x is None: return u""
- elif isinstance(x, str):
- return x.decode("utf8")
- else:
- return x
-
- # if we still have a changes.pck, then we need to migrate it
- changes_pickle = os.path.join(basedir, "changes.pck")
- if not os.path.exists(changes_pickle):
- migrate_engine.execute(changes_nextid.insert(),
- next_changeid=1)
- return
-
- #if not quiet: print "migrating changes.pck to database"
-
- # 'source' will be an old b.c.changes.ChangeMaster instance, with a
- # .changes attribute. Note that we use 'r', and not 'rb', because these
- # pickles were written using the old text pickle format, which requires
- # newline translation
- with open(changes_pickle,"r") as f:
- source = cPickle.load(f)
- styles.doUpgrade()
-
- #if not quiet: print " (%d Change objects)" % len(source.changes)
-
- # first, scan for changes without a number. If we find any, then we'll
- # renumber the changes sequentially
- have_unnumbered = False
- for c in source.changes:
- if c.revision and c.number is None:
- have_unnumbered = True
- break
- if have_unnumbered:
- n = 1
- for c in source.changes:
- if c.revision:
- c.number = n
- n = n + 1
-
- # insert the changes
- for c in source.changes:
- if not c.revision:
- continue
- try:
- values = dict(
- changeid=c.number,
- author=c.who,
- comments=c.comments,
- is_dir=c.isdir,
- branch=c.branch,
- revision=c.revision,
- revlink=c.revlink,
- when_timestamp=c.when,
- category=c.category)
- values = dict([ (k, remove_none(v)) for k, v in values.iteritems() ])
- except UnicodeDecodeError, e:
- raise UnicodeError("Trying to import change data as UTF-8 failed. Please look at contrib/fix_changes_pickle_encoding.py: %s" % str(e))
-
- migrate_engine.execute(changes.insert(), **values)
-
- # NOTE: change_links is not populated, since it is deleted in db
- # version 20. The table is still created, though.
-
- # sometimes c.files contains nested lists -- why, I do not know! But we deal with
- # it all the same - see bug #915. We'll assume for now that c.files contains *either*
- # lists of filenames or plain filenames, not both.
- def flatten(l):
- if l and type(l[0]) == list:
- rv = []
- for e in l:
- if type(e) == list:
- rv.extend(e)
- else:
- rv.append(e)
- return rv
- else:
- return l
- for filename in flatten(c.files):
- migrate_engine.execute(change_files.insert(),
- changeid=c.number,
- filename=filename)
-
- for propname,propvalue in c.properties.properties.items():
- encoded_value = json.dumps(propvalue)
- migrate_engine.execute(change_properties.insert(),
- changeid=c.number,
- property_name=propname,
- property_value=encoded_value)
-
- # update next_changeid
- max_changeid = max([ c.number for c in source.changes if c.revision ] + [ 0 ])
- migrate_engine.execute(changes_nextid.insert(),
- next_changeid=max_changeid+1)
-
- #if not quiet:
- # print "moving changes.pck to changes.pck.old; delete it or keep it as a backup"
- os.rename(changes_pickle, changes_pickle+".old")
-
-def upgrade(migrate_engine):
- metadata.bind = migrate_engine
-
- # do some tests before getting started
- test_unicode(migrate_engine)
-
- # create the initial schema
- metadata.create_all()
-
- # and import some changes
- import_changes(migrate_engine)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/002_add_proj_repo.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/002_add_proj_repo.py
deleted file mode 100644
index ad221553..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/002_add_proj_repo.py
+++ /dev/null
@@ -1,30 +0,0 @@
-# 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
-
- # add project and repository columns to 'changes' an 'sourcestamps'
- def add_cols(table):
- repository = sa.Column('repository', sa.String(512), nullable=False, server_default=sa.DefaultClause(''))
- repository.create(table, populate_default=True)
- project = sa.Column('project', sa.String(512), nullable=False, server_default=sa.DefaultClause(''))
- project.create(table, populate_default=True)
-
- add_cols(sa.Table('changes', metadata, autoload=True))
- add_cols(sa.Table('sourcestamps', metadata, autoload=True))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/003_scheduler_class_name.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/003_scheduler_class_name.py
deleted file mode 100644
index 0a3a4f36..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/003_scheduler_class_name.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# 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
-
- # add an empty class_name to the schedulers table
- schedulers = sa.Table('schedulers', metadata, autoload=True)
- class_name = sa.Column('class_name', sa.String(length=128), nullable=False, server_default=sa.DefaultClause(''))
- class_name.create(schedulers, populate_default=True)
-
- # and an index since we'll be selecting with (name= AND class=)
- idx = sa.Index('name_and_class', schedulers.c.name, schedulers.c.class_name)
- idx.create(migrate_engine)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/004_add_autoincrement.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/004_add_autoincrement.py
deleted file mode 100644
index c0ec66e6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/004_add_autoincrement.py
+++ /dev/null
@@ -1,139 +0,0 @@
-# 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
-
- # re-include some of the relevant tables, as they were in version 3, since
- # sqlalchemy's reflection doesn't work very well for defaults. These must
- # be complete table specifications as for some dialects sqlalchemy will
- # create a brand new, temporary table, and copy data over
-
- sa.Table("schedulers", metadata,
- sa.Column('schedulerid', sa.Integer, autoincrement=False,
- primary_key=True),
- sa.Column('name', sa.String(128), nullable=False),
- sa.Column('state', sa.String(1024), nullable=False),
- sa.Column('class_name', sa.String(128), nullable=False),
- )
-
- sa.Table('changes', metadata,
- sa.Column('changeid', sa.Integer, autoincrement=False,
- primary_key=True),
- sa.Column('author', sa.String(256), nullable=False),
- sa.Column('comments', sa.String(1024), nullable=False),
- sa.Column('is_dir', sa.SmallInteger, nullable=False),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('revlink', sa.String(256)),
- sa.Column('when_timestamp', sa.Integer, nullable=False),
- sa.Column('category', sa.String(256)),
- sa.Column('repository', sa.Text, nullable=False, server_default=''),
- sa.Column('project', sa.Text, nullable=False, server_default=''),
- )
-
- sa.Table('patches', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('patchlevel', sa.Integer, nullable=False),
- sa.Column('patch_base64', sa.Text, nullable=False),
- sa.Column('subdir', sa.Text),
- )
-
- sa.Table('sourcestamps', metadata,
- sa.Column('id', sa.Integer, autoincrement=True, primary_key=True),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('patchid', sa.Integer, sa.ForeignKey('patches.id')),
- sa.Column('repository', sa.Text(length=None), nullable=False,
- server_default=''),
- sa.Column('project', sa.Text(length=None), nullable=False,
- server_default=''),
- )
-
- sa.Table('buildsets', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('external_idstring', sa.String(256)),
- sa.Column('reason', sa.String(256)),
- sa.Column('sourcestampid', sa.Integer,
- sa.ForeignKey('sourcestamps.id'), nullable=False),
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete', sa.SmallInteger, nullable=False,
- server_default=sa.DefaultClause("0")),
- sa.Column('complete_at', sa.Integer),
- sa.Column('results', sa.SmallInteger),
- )
-
- sa.Table('buildrequests', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('buildsetid', sa.Integer, sa.ForeignKey("buildsets.id"),
- nullable=False),
- sa.Column('buildername', sa.String(length=None), nullable=False),
- sa.Column('priority', sa.Integer, nullable=False,
- server_default=sa.DefaultClause("0")),
- sa.Column('claimed_at', sa.Integer,
- server_default=sa.DefaultClause("0")),
- sa.Column('claimed_by_name', sa.String(length=None)),
- sa.Column('claimed_by_incarnation', sa.String(length=None)),
- sa.Column('complete', sa.Integer,
- server_default=sa.DefaultClause("0")),
- sa.Column('results', sa.SmallInteger),
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete_at', sa.Integer),
- )
-
- sa.Table('builds', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('number', sa.Integer, nullable=False),
- sa.Column('brid', sa.Integer, sa.ForeignKey('buildrequests.id'),
- nullable=False),
- sa.Column('start_time', sa.Integer, nullable=False),
- sa.Column('finish_time', sa.Integer),
- )
-
- to_autoinc = [ s.split(".") for s in
- "schedulers.schedulerid",
- "builds.id",
- "changes.changeid",
- "buildrequests.id",
- "buildsets.id",
- "patches.id",
- "sourcestamps.id",
- ]
-
- # It seems that SQLAlchemy's ALTER TABLE doesn't work when migrating from
- # INTEGER to PostgreSQL's SERIAL data type (which is just pseudo data type
- # for INTEGER with SEQUENCE), so we have to work-around this with raw SQL.
- if migrate_engine.dialect.name in ('postgres', 'postgresql'):
- for table_name, col_name in to_autoinc:
- migrate_engine.execute("CREATE SEQUENCE %s_%s_seq"
- % (table_name, col_name))
- migrate_engine.execute("ALTER TABLE %s ALTER COLUMN %s SET DEFAULT nextval('%s_%s_seq'::regclass)"
- % (table_name, col_name, table_name, col_name))
- migrate_engine.execute("ALTER SEQUENCE %s_%s_seq OWNED BY %s.%s"
- % (table_name, col_name, table_name, col_name))
- else:
- for table_name, col_name in to_autoinc:
- table = metadata.tables[table_name]
- col = table.c[col_name]
- col.alter(autoincrement=True)
-
-
- # also drop the changes_nextid table here (which really should have been a
- # sequence..)
- table = sa.Table('changes_nextid', metadata, autoload=True)
- table.drop()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/005_add_indexes.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/005_add_indexes.py
deleted file mode 100644
index bb0a3d65..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/005_add_indexes.py
+++ /dev/null
@@ -1,144 +0,0 @@
-# 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
-
- # note that all of the tables defined here omit the ForeignKey constraints;
- # this just lets this code specify the tables in any order; the tables are
- # not re-created here, so this omission causes no problems - the key
- # constraints are still defined in the table
-
- def add_index(table_name, col_name):
- idx_name = "%s_%s" % (table_name, col_name)
- idx = sa.Index(idx_name, metadata.tables[table_name].c[col_name])
- idx.create(migrate_engine)
-
- sa.Table('buildrequests', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('buildsetid', sa.Integer, nullable=False),
- sa.Column('buildername', sa.String(length=None), nullable=False),
- sa.Column('priority', sa.Integer, nullable=False),
- sa.Column('claimed_at', sa.Integer, server_default=sa.DefaultClause("0")),
- sa.Column('claimed_by_name', sa.String(length=None)),
- sa.Column('claimed_by_incarnation', sa.String(length=None)),
- sa.Column('complete', sa.Integer, server_default=sa.DefaultClause("0")),
- sa.Column('results', sa.SmallInteger),
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete_at', sa.Integer),
- )
- add_index("buildrequests", "buildsetid")
- add_index("buildrequests", "buildername")
- add_index("buildrequests", "complete")
- add_index("buildrequests", "claimed_at")
- add_index("buildrequests", "claimed_by_name")
-
- sa.Table('builds', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('number', sa.Integer, nullable=False),
- sa.Column('brid', sa.Integer, nullable=False),
- sa.Column('start_time', sa.Integer, nullable=False),
- sa.Column('finish_time', sa.Integer),
- )
- add_index("builds", "number")
- add_index("builds", "brid")
-
- sa.Table('buildsets', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('external_idstring', sa.String(256)),
- sa.Column('reason', sa.String(256)),
- sa.Column('sourcestampid', sa.Integer, nullable=False),
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete', sa.SmallInteger, nullable=False, server_default=sa.DefaultClause("0")),
- sa.Column('complete_at', sa.Integer),
- sa.Column('results', sa.SmallInteger),
- )
- add_index("buildsets", "complete")
- add_index("buildsets", "submitted_at")
-
- sa.Table('buildset_properties', metadata,
- sa.Column('buildsetid', sa.Integer, nullable=False),
- sa.Column('property_name', sa.String(256), nullable=False),
- sa.Column('property_value', sa.String(1024), nullable=False),
- )
- add_index("buildset_properties", "buildsetid")
-
- sa.Table('changes', metadata,
- sa.Column('changeid', sa.Integer, primary_key=True),
- sa.Column('author', sa.String(256), nullable=False),
- sa.Column('comments', sa.String(1024), nullable=False),
- sa.Column('is_dir', sa.SmallInteger, nullable=False),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('revlink', sa.String(256)),
- sa.Column('when_timestamp', sa.Integer, nullable=False),
- sa.Column('category', sa.String(256)),
- sa.Column('repository', sa.Text, nullable=False, server_default=''),
- sa.Column('project', sa.Text, nullable=False, server_default=''),
- )
- add_index("changes", "branch")
- add_index("changes", "revision")
- add_index("changes", "author")
- add_index("changes", "category")
- add_index("changes", "when_timestamp")
-
- sa.Table('change_files', metadata,
- sa.Column('changeid', sa.Integer, nullable=False),
- sa.Column('filename', sa.String(1024), nullable=False),
- )
- add_index("change_files", "changeid")
-
- sa.Table('change_links', metadata,
- sa.Column('changeid', sa.Integer, nullable=False),
- sa.Column('link', sa.String(1024), nullable=False),
- )
- add_index("change_links", "changeid")
-
- sa.Table('change_properties', metadata,
- sa.Column('changeid', sa.Integer, nullable=False),
- sa.Column('property_name', sa.String(256), nullable=False),
- sa.Column('property_value', sa.String(1024), nullable=False),
- )
- add_index("change_properties", "changeid")
-
- # schedulers already has an index
-
- sa.Table('scheduler_changes', metadata,
- sa.Column('schedulerid', sa.Integer),
- sa.Column('changeid', sa.Integer),
- sa.Column('important', sa.SmallInteger),
- )
- add_index("scheduler_changes", "schedulerid")
- add_index("scheduler_changes", "changeid")
-
- sa.Table('scheduler_upstream_buildsets', metadata,
- sa.Column('buildsetid', sa.Integer),
- sa.Column('schedulerid', sa.Integer),
- sa.Column('active', sa.SmallInteger),
- )
- add_index("scheduler_upstream_buildsets", "buildsetid")
- add_index("scheduler_upstream_buildsets", "schedulerid")
- add_index("scheduler_upstream_buildsets", "active")
-
- # sourcestamps are only queried by id, no need for additional indexes
-
- sa.Table('sourcestamp_changes', metadata,
- sa.Column('sourcestampid', sa.Integer, nullable=False),
- sa.Column('changeid', sa.Integer, nullable=False),
- )
- add_index("sourcestamp_changes", "sourcestampid")
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/006_drop_last_access.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/006_drop_last_access.py
deleted file mode 100644
index fc807714..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/006_drop_last_access.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# 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
-
- table = sa.Table('last_access', metadata, autoload=True)
- table.drop()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/007_add_object_tables.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/007_add_object_tables.py
deleted file mode 100644
index e09b0c8c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/007_add_object_tables.py
+++ /dev/null
@@ -1,37 +0,0 @@
-# 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
-
- objects = sa.Table("objects", metadata,
- sa.Column("id", sa.Integer, primary_key=True),
- sa.Column('name', sa.String(128), nullable=False),
- sa.Column('class_name', sa.String(128), nullable=False),
- sa.UniqueConstraint('name', 'class_name', name='object_identity'),
- )
- objects.create()
-
- object_state = sa.Table("object_state", metadata,
- sa.Column("objectid", sa.Integer, sa.ForeignKey('objects.id'),
- nullable=False),
- sa.Column("name", sa.String(length=256), nullable=False),
- sa.Column("value_json", sa.Text, nullable=False),
- sa.UniqueConstraint('objectid', 'name', name='name_per_object'),
- )
- object_state.create()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/008_add_scheduler_changes_index.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/008_add_scheduler_changes_index.py
deleted file mode 100644
index e758576b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/008_add_scheduler_changes_index.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# 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
-
- scheduler_changes = sa.Table('scheduler_changes', metadata,
- sa.Column('schedulerid', sa.Integer),
- sa.Column('changeid', sa.Integer),
- sa.Column('important', sa.SmallInteger),
- )
-
- idx = sa.Index('scheduler_changes_unique',
- scheduler_changes.c.schedulerid,
- scheduler_changes.c.changeid, unique=True)
- idx.create(migrate_engine)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/009_add_patch_author.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/009_add_patch_author.py
deleted file mode 100644
index fc1771c2..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/009_add_patch_author.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# 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
-
- # add patch_author and patch_comment to the patches table
-
- # mysql doesn't like default values on these columns
- defaults = {}
- if migrate_engine.dialect.name != "mysql":
- defaults['server_default'] = sa.DefaultClause('')
-
- patches = sa.Table('patches', metadata, autoload=True)
- patch_author= sa.Column('patch_author', sa.Text, nullable=False,
- **defaults)
- patch_author.create(patches, populate_default=True)
-
- patch_author= sa.Column('patch_comment', sa.Text, nullable=False,
- **defaults)
- patch_author.create(patches, populate_default=True)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/010_fix_column_lengths.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/010_fix_column_lengths.py
deleted file mode 100644
index a3ae3e14..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/010_fix_column_lengths.py
+++ /dev/null
@@ -1,63 +0,0 @@
-# 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
-from migrate import changeset
-
-def upgrade(migrate_engine):
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- # the old (non-sqlalchemy-migrate) migration scripts messed up the
- # lengths of these columns, so fix them here.
- changeset.alter_column(
- sa.Column('class_name', sa.String(128), nullable=False),
- table="schedulers",
- metadata=metadata,
- engine=migrate_engine)
-
- changeset.alter_column(
- sa.Column('name', sa.String(128), nullable=False),
- table="schedulers",
- metadata=metadata,
- engine=migrate_engine)
-
- # sqlalchemy's reflection gets the server_defaults wrong, so this
- # table has to be included here.
- changes = sa.Table('changes', metadata,
- sa.Column('changeid', sa.Integer, primary_key=True),
- sa.Column('author', sa.String(256), nullable=False),
- sa.Column('comments', sa.String(1024), nullable=False),
- sa.Column('is_dir', sa.SmallInteger, nullable=False),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('revlink', sa.String(256)),
- sa.Column('when_timestamp', sa.Integer, nullable=False),
- sa.Column('category', sa.String(256)),
- sa.Column('repository', sa.String(length=512), nullable=False,
- server_default=''),
- sa.Column('project', sa.String(length=512), nullable=False,
- server_default=''),
- )
- changeset.alter_column(
- sa.Column('author', sa.String(256), nullable=False),
- table=changes,
- metadata=metadata,
- engine=migrate_engine)
- changeset.alter_column(
- sa.Column('branch', sa.String(256)),
- table=changes,
- metadata=metadata,
- engine=migrate_engine)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/011_add_buildrequest_claims.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/011_add_buildrequest_claims.py
deleted file mode 100644
index 21e93c01..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/011_add_buildrequest_claims.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# 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
-import migrate
-from buildbot.util import sautils
-
-def migrate_claims(migrate_engine, metadata, buildrequests, objects,
- buildrequest_claims):
-
- # First, ensure there is an object row for each master
- null_id = sa.null().label('id')
- if migrate_engine.dialect.name == 'postgresql':
- # postgres needs NULL cast to an integer:
- null_id = sa.cast(null_id, sa.INTEGER)
- new_objects = sa.select([
- null_id,
- buildrequests.c.claimed_by_name.label("name"),
- sa.literal_column("'BuildMaster'").label("class_name"),
- ],
- whereclause=buildrequests.c.claimed_by_name != None,
- distinct=True)
-
- # this doesn't seem to work without str() -- verified in sqla 0.6.0 - 0.7.1
- migrate_engine.execute(
- str(sautils.InsertFromSelect(objects, new_objects)))
-
- # now make a buildrequest_claims row for each claimed build request
- join = buildrequests.join(objects,
- (buildrequests.c.claimed_by_name == objects.c.name)
- # (have to use sa.text because str, below, doesn't work
- # with placeholders)
- & (objects.c.class_name == sa.text("'BuildMaster'")))
- claims = sa.select([
- buildrequests.c.id.label('brid'),
- objects.c.id.label('objectid'),
- buildrequests.c.claimed_at,
- ], from_obj=[ join ],
- whereclause=buildrequests.c.claimed_by_name != None)
- migrate_engine.execute(
- str(sautils.InsertFromSelect(buildrequest_claims, claims)))
-
-def drop_columns(metadata, buildrequests):
- # sqlalchemy-migrate <0.7.0 has a bug with sqlalchemy >=0.7.0, where
- # it tries to change an immutable column; this is the workaround, from
- # http://code.google.com/p/sqlalchemy-migrate/issues/detail?id=112
- if not sa.__version__.startswith('0.6.'):
- if not hasattr(migrate, '__version__'): # that is, older than 0.7
- buildrequests.columns = buildrequests._columns
-
- buildrequests.c.claimed_at.drop()
- buildrequests.c.claimed_by_name.drop()
- buildrequests.c.claimed_by_incarnation.drop()
-
-def upgrade(migrate_engine):
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- # a copy of the buildrequests table, but with the foreign keys stripped
- buildrequests = sa.Table('buildrequests', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('buildsetid', sa.Integer, nullable=False),
- sa.Column('buildername', sa.String(length=256), nullable=False),
- sa.Column('priority', sa.Integer, nullable=False,
- server_default=sa.DefaultClause("0")),
- sa.Column('claimed_at', sa.Integer,
- server_default=sa.DefaultClause("0")),
- sa.Column('claimed_by_name', sa.String(length=256)),
- sa.Column('claimed_by_incarnation', sa.String(length=256)),
- sa.Column('complete', sa.Integer,
- server_default=sa.DefaultClause("0")),
- sa.Column('results', sa.SmallInteger),
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete_at', sa.Integer),
- )
-
- # existing objects table, used as a foreign key
- objects = sa.Table("objects", metadata,
- # unique ID for this object
- sa.Column("id", sa.Integer, primary_key=True),
- # object's user-given name
- sa.Column('name', sa.String(128), nullable=False),
- # object's class name, basically representing a "type" for the state
- sa.Column('class_name', sa.String(128), nullable=False),
-
- # prohibit multiple id's for the same object
- sa.UniqueConstraint('name', 'class_name', name='object_identity'),
- )
-
- # and a new buildrequest_claims table
- buildrequest_claims = sa.Table('buildrequest_claims', metadata,
- sa.Column('brid', sa.Integer, sa.ForeignKey('buildrequests.id'),
- index=True, unique=True),
- sa.Column('objectid', sa.Integer, sa.ForeignKey('objects.id'),
- index=True, nullable=True),
- sa.Column('claimed_at', sa.Integer, nullable=False),
- )
-
- # create the new table
- buildrequest_claims.create()
-
- # migrate the claims into that table
- migrate_claims(migrate_engine, metadata, buildrequests,
- objects, buildrequest_claims)
-
- # and drop the claim-related columns in buildrequests
- drop_columns(metadata, buildrequests)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/012_add_users_table.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/012_add_users_table.py
deleted file mode 100644
index a485bcb1..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/012_add_users_table.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# 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
-
- # what defines a user
- users = sa.Table("users", metadata,
- sa.Column("uid", sa.Integer, primary_key=True),
- sa.Column("identifier", sa.String(256), nullable=False),
- )
- users.create()
-
- idx = sa.Index('users_identifier', users.c.identifier)
- idx.create()
-
- # ways buildbot knows about users
- users_info = sa.Table("users_info", metadata,
- sa.Column("uid", sa.Integer, sa.ForeignKey('users.uid'),
- nullable=False),
- sa.Column("attr_type", sa.String(128), nullable=False),
- sa.Column("attr_data", sa.String(128), nullable=False)
- )
- users_info.create()
-
- idx = sa.Index('users_info_uid', users_info.c.uid)
- idx.create()
- idx = sa.Index('users_info_uid_attr_type', users_info.c.uid,
- users_info.c.attr_type, unique=True)
- idx.create()
- idx = sa.Index('users_info_attrs', users_info.c.attr_type,
- users_info.c.attr_data, unique=True)
- idx.create()
-
- # correlates change authors and user uids
- sa.Table('changes', metadata, autoload=True)
- change_users = sa.Table("change_users", metadata,
- sa.Column("changeid", sa.Integer, sa.ForeignKey('changes.changeid'),
- nullable=False),
- sa.Column("uid", sa.Integer, sa.ForeignKey('users.uid'),
- nullable=False)
- )
- change_users.create()
-
- idx = sa.Index('change_users_changeid', change_users.c.changeid)
- idx.create()
-
- # note that existing changes are not added to the users table; this would
- # be *very* time-consuming and would not be helpful to the vast majority of
- # users.
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/013_remove_schedulers_state_column.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/013_remove_schedulers_state_column.py
deleted file mode 100644
index 0bce4d47..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/013_remove_schedulers_state_column.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# 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
-from migrate import changeset
-
-def upgrade(migrate_engine):
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- # Specify what the new table should look like
- schedulers = sa.Table("schedulers", metadata,
- # unique ID for scheduler
- sa.Column('schedulerid', sa.Integer, primary_key=True), # TODO: rename to id
- # scheduler's name in master.cfg
- sa.Column('name', sa.String(128), nullable=False),
- # scheduler's class name, basically representing a "type" for the state
- sa.Column('class_name', sa.String(128), nullable=False),
- )
-
- # Now drop column
- changeset.drop_column(
- sa.Column('state', sa.String(128), nullable=False),
- table=schedulers,
- metadata=metadata,
- engine=migrate_engine)
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/014_add_users_userpass_columns.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/014_add_users_userpass_columns.py
deleted file mode 100644
index b115a1e9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/014_add_users_userpass_columns.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# 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
-
- users_table = sa.Table('users', metadata, autoload=True)
-
- username = sa.Column('bb_username', sa.String(128))
- username.create(users_table)
- password = sa.Column('bb_password', sa.String(128))
- password.create(users_table)
-
- idx = sa.Index('users_bb_user', users_table.c.bb_username, unique=True)
- idx.create()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/015_remove_bad_master_objectid.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/015_remove_bad_master_objectid.py
deleted file mode 100644
index 4f17f719..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/015_remove_bad_master_objectid.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# 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
-
- # older build masters stored some of their state with an object named
- # 'master' with class 'buildbot.master.BuildMaster', while other state was
- # stored with objects named after each master itself, with class
- # BuildMaster.
-
- objects_table = sa.Table('objects', metadata, autoload=True)
- object_state_table = sa.Table('object_state', metadata, autoload=True)
-
- # get the old, unwanted ID
- q = sa.select([ objects_table.c.id ],
- whereclause=(objects_table.c.name=='master')
- & (objects_table.c.class_name == 'buildbot.master.BuildMaster'))
- res = q.execute()
- old_id = res.scalar()
-
- # if there's no such ID, there's nothing to change
- if old_id is not None:
-
- # get the new ID
- q = sa.select([ objects_table.c.id ],
- whereclause=objects_table.c.class_name == 'BuildMaster')
- res = q.execute()
- ids = res.fetchall()
-
- # if there is exactly one ID, update the existing object_states. If
- # there are zero or multiple object_states, then we do not know which
- # master to assign last_processed_change to, so we just delete it.
- # This indicates to the master that it has processed all changes, which
- # is probably accurate.
- if len(ids) == 1:
- new_id = ids[0][0]
-
- # update rows with the old id to use the new id
- q = object_state_table.update(
- whereclause=(object_state_table.c.objectid == old_id))
- q.execute(objectid=new_id)
- else:
- q = object_state_table.delete(
- whereclause=(object_state_table.c.objectid == old_id))
- q.execute()
-
- # in either case, delete the old object row
- q = objects_table.delete(
- whereclause=(objects_table.c.id == old_id))
- q.execute()
-
- # and update the class name for the new rows
- q = objects_table.update(
- whereclause=(objects_table.c.class_name == 'BuildMaster'))
- q.execute(class_name='buildbot.master.BuildMaster')
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/016_restore_buildrequest_indices.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/016_restore_buildrequest_indices.py
deleted file mode 100644
index 78d60051..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/016_restore_buildrequest_indices.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# 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
-
- # the column drops in 011_add_buildrequest_claims.py unfortunately
- # also drop a great deal of other stuff on sqlite. In particular, all
- # indexes and foreign keys.
- #
- # The foreign keys do not matter anyway - SQLite tracks them but ignores
- # them. The indices, however, are important, so they are re-added here,
- # but only for the sqlite dialect.
-
- if migrate_engine.dialect.name != 'sqlite':
- return
-
- buildrequests = sa.Table('buildrequests', metadata, autoload=True)
- sa.Index('buildrequests_buildsetid', buildrequests.c.buildsetid).create()
- sa.Index('buildrequests_buildername', buildrequests.c.buildername).create()
- sa.Index('buildrequests_complete', buildrequests.c.complete).create()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/017_restore_other_indices.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/017_restore_other_indices.py
deleted file mode 100644
index 59d2f8aa..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/017_restore_other_indices.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# 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
-
- # the column changes in 010_fix_column_lengths.py unfortunately also drop a
- # great deal of other stuff on sqlite. In particular, all indexes and
- # foreign keys on the 'changes' and 'schedulers' tables.
- #
- # The foreign keys do not matter anyway - SQLite tracks them but ignores
- # them. The indices, however, are important, so they are re-added here,
- # but only for the sqlite dialect.
-
- if migrate_engine.dialect.name == 'sqlite':
- schedulers = sa.Table('schedulers', metadata, autoload=True)
-
- sa.Index('name_and_class',
- schedulers.c.name, schedulers.c.class_name).create()
-
- changes = sa.Table('changes', metadata, autoload=True)
-
- sa.Index('changes_branch', changes.c.branch).create()
- sa.Index('changes_revision', changes.c.revision).create()
- sa.Index('changes_author', changes.c.author).create()
- sa.Index('changes_category', changes.c.category).create()
- sa.Index('changes_when_timestamp', changes.c.when_timestamp).create()
-
- # These were implemented as UniqueConstraint objects, which are
- # recognized as indexes on non-sqlite DB's. So add them as explicit
- # indexes on sqlite.
-
- objects = sa.Table('objects', metadata, autoload=True)
- sa.Index('object_identity', objects.c.name, objects.c.class_name,
- unique=True).create()
-
- object_state = sa.Table('object_state', metadata, autoload=True)
- sa.Index('name_per_object', object_state.c.objectid,
- object_state.c.name, unique=True).create()
-
- # Due to a coding bug in version 012, the users_identifier index is not
- # unique (on any DB). SQLAlchemy-migrate does not provide an interface to
- # drop columns, so we fake it here.
-
- users = sa.Table('users', metadata, autoload=True)
-
- dialect = migrate_engine.dialect.name
- if dialect in ('sqlite', 'postgresql'):
- migrate_engine.execute("DROP INDEX users_identifier")
- elif dialect == 'mysql':
- migrate_engine.execute("DROP INDEX users_identifier ON users")
-
- sa.Index('users_identifier', users.c.identifier, unique=True).create()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/018_add_sourcestampset.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/018_add_sourcestampset.py
deleted file mode 100644
index b8de49cb..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/018_add_sourcestampset.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# 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
-from migrate.changeset import constraint
-from buildbot.util import sautils
-
-def upgrade(migrate_engine):
-
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- sourcestamps_table = sa.Table('sourcestamps', metadata, autoload=True)
- buildsets_table = sa.Table('buildsets', metadata, autoload=True)
-
- # Create the sourcestampset table
- # that defines a sourcestampset
- sourcestampsets_table = sa.Table("sourcestampsets", metadata,
- sa.Column("id", sa.Integer, primary_key=True),
- )
- sourcestampsets_table.create()
-
- # All current sourcestampid's are migrated to sourcestampsetid
- # Insert all sourcestampid's as setid's into sourcestampsets table
- sourcestampsetids = sa.select([sourcestamps_table.c.id])
- # this doesn't seem to work without str() -- verified in sqla 0.6.0 - 0.7.1
- migrate_engine.execute(str(sautils.InsertFromSelect(sourcestampsets_table, sourcestampsetids)))
-
- # rename the buildsets table column
- buildsets_table.c.sourcestampid.alter(name='sourcestampsetid')
-
- metadata.remove(buildsets_table)
- buildsets_table = sa.Table('buildsets', metadata, autoload=True)
-
- cons = constraint.ForeignKeyConstraint([buildsets_table.c.sourcestampsetid], [sourcestampsets_table.c.id])
- cons.create()
-
- # Add sourcestampsetid including index to sourcestamps table
- ss_sourcestampsetid = sa.Column('sourcestampsetid', sa.Integer)
- ss_sourcestampsetid.create(sourcestamps_table)
-
- # Update the setid to the same value as sourcestampid
- migrate_engine.execute(str(sourcestamps_table.update().values(sourcestampsetid=sourcestamps_table.c.id)))
- ss_sourcestampsetid.alter(nullable=False)
-
- # Data is up to date, now force integrity
- cons = constraint.ForeignKeyConstraint([sourcestamps_table.c.sourcestampsetid], [sourcestampsets_table.c.id])
- cons.create()
-
- # Add index for performance reasons to find all sourcestamps in a set quickly
- idx = sa.Index('sourcestamps_sourcestampsetid', sourcestamps_table.c.sourcestampsetid, unique=False)
- idx.create()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/019_merge_schedulers_to_objects.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/019_merge_schedulers_to_objects.py
deleted file mode 100644
index bd2cc5c7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/019_merge_schedulers_to_objects.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# 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
-
- # autoload the tables that are only referenced here
- sa.Table('changes', metadata, autoload=True)
- sa.Table('buildsets', metadata, autoload=True)
- sa.Table("objects", metadata, autoload=True)
-
- # drop all tables. Schedulers will re-populate on startup
-
- scheduler_changes_tbl = sa.Table('scheduler_changes', metadata,
- sa.Column('schedulerid', sa.Integer),
- # ...
- )
- scheduler_changes_tbl.drop()
- metadata.remove(scheduler_changes_tbl)
-
- scheduler_upstream_buildsets_tbl = sa.Table('scheduler_upstream_buildsets',
- metadata,
- sa.Column('buildsetid', sa.Integer),
- # ...
- )
- scheduler_upstream_buildsets_tbl.drop()
- metadata.remove(scheduler_upstream_buildsets_tbl)
-
- schedulers_tbl = sa.Table("schedulers", metadata,
- sa.Column('schedulerid', sa.Integer),
- # ...
- )
- schedulers_tbl.drop()
- metadata.remove(schedulers_tbl)
-
- # schedulers and scheduler_upstream_buildsets aren't coming back, but
- # scheduler_changes is -- along with its indexes
-
- scheduler_changes_tbl = sa.Table('scheduler_changes', metadata,
- sa.Column('objectid', sa.Integer,
- sa.ForeignKey('objects.id')),
- sa.Column('changeid', sa.Integer,
- sa.ForeignKey('changes.changeid')),
- sa.Column('important', sa.Integer),
- )
- scheduler_changes_tbl.create()
-
- idx = sa.Index('scheduler_changes_objectid',
- scheduler_changes_tbl.c.objectid)
- idx.create()
-
- idx = sa.Index('scheduler_changes_changeid',
- scheduler_changes_tbl.c.changeid)
- idx.create()
-
- idx = sa.Index('scheduler_changes_unique',
- scheduler_changes_tbl.c.objectid,
- scheduler_changes_tbl.c.changeid, unique=True)
- idx.create()
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/020_remove_change_links.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/020_remove_change_links.py
deleted file mode 100644
index a955b4c5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/020_remove_change_links.py
+++ /dev/null
@@ -1,23 +0,0 @@
-# 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
-
- tbl = sa.Table('change_links', metadata, autoload=True)
- tbl.drop()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/021_fix_postgres_sequences.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/021_fix_postgres_sequences.py
deleted file mode 100644
index f412073d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/021_fix_postgres_sequences.py
+++ /dev/null
@@ -1,52 +0,0 @@
-# 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):
- # see bug #2119
-
- # this only applies to postgres
- if migrate_engine.dialect.name != 'postgresql':
- return
-
- metadata = sa.MetaData()
- metadata.bind = migrate_engine
-
- to_fix = [
- 'buildrequests.id',
- 'builds.id',
- 'buildsets.id',
- 'changes.changeid',
- 'patches.id',
- 'sourcestampsets.id',
- 'sourcestamps.id',
- 'objects.id',
- 'users.uid',
- ]
-
- for col in to_fix:
- tbl_name, col_name = col.split('.')
- tbl = sa.Table(tbl_name, metadata, autoload=True)
- col = tbl.c[col_name]
-
- res = migrate_engine.execute(sa.select([ sa.func.max(col) ]))
- max = res.fetchall()[0][0]
-
- if max:
- seq_name = "%s_%s_seq" % (tbl_name, col_name)
- r = migrate_engine.execute("SELECT setval('%s', %d)"
- % (seq_name, max))
- r.close()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/022_add_codebase.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/022_add_codebase.py
deleted file mode 100644
index 7f03efc0..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/022_add_codebase.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# 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
-
- sourcestamps_table = sa.Table('sourcestamps', metadata, autoload=True)
- changes_table = sa.Table('changes', metadata, autoload=True)
-
-
- # Add codebase to tables
- ss_codebase = sa.Column('codebase', sa.String(length=256), nullable=False,
- server_default=sa.DefaultClause(""))
- ss_codebase.create(sourcestamps_table)
-
- c_codebase = sa.Column('codebase', sa.String(length=256), nullable=False,
- server_default=sa.DefaultClause(""))
- c_codebase.create(changes_table)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/migrate/versions/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/model.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/model.py
deleted file mode 100644
index 263e9cfb..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/model.py
+++ /dev/null
@@ -1,539 +0,0 @@
-# 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
-import migrate
-import migrate.versioning.schema
-import migrate.versioning.repository
-from twisted.python import util, log
-from buildbot.db import base
-
-try:
- from migrate.versioning import exceptions
- _hush_pyflakes = exceptions
-except ImportError:
- from migrate import exceptions
-
-class Model(base.DBConnectorComponent):
- #
- # schema
- #
-
- metadata = sa.MetaData()
-
- # NOTES
-
- # * server_defaults here are included to match those added by the migration
- # scripts, but they should not be depended on - all code accessing these
- # tables should supply default values as necessary. The defaults are
- # required during migration when adding non-nullable columns to existing
- # tables.
- #
- # * dates are stored as unix timestamps (UTC-ish epoch time)
- #
- # * sqlalchemy does not handle sa.Boolean very well on MySQL or Postgres;
- # use sa.Integer instead
-
- # build requests
-
- # A BuildRequest is a request for a particular build to be performed. Each
- # BuildRequest is a part of a Buildset. BuildRequests are claimed by
- # masters, to avoid multiple masters running the same build.
- buildrequests = sa.Table('buildrequests', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('buildsetid', sa.Integer, sa.ForeignKey("buildsets.id"),
- nullable=False),
- sa.Column('buildername', sa.String(length=256), nullable=False),
- sa.Column('priority', sa.Integer, nullable=False,
- server_default=sa.DefaultClause("0")),
-
- # if this is zero, then the build is still pending
- sa.Column('complete', sa.Integer,
- server_default=sa.DefaultClause("0")),
-
- # results is only valid when complete == 1; 0 = SUCCESS, 1 = WARNINGS,
- # etc - see master/buildbot/status/builder.py
- sa.Column('results', sa.SmallInteger),
-
- # time the buildrequest was created
- sa.Column('submitted_at', sa.Integer, nullable=False),
-
- # time the buildrequest was completed, or NULL
- sa.Column('complete_at', sa.Integer),
- )
-
- # Each row in this table represents a claimed build request, where the
- # claim is made by the object referenced by objectid.
- buildrequest_claims = sa.Table('buildrequest_claims', metadata,
- sa.Column('brid', sa.Integer, sa.ForeignKey('buildrequests.id'),
- index=True, unique=True),
- sa.Column('objectid', sa.Integer, sa.ForeignKey('objects.id'),
- index=True, nullable=True),
- sa.Column('claimed_at', sa.Integer, nullable=False),
- )
-
- # builds
-
- # This table contains basic information about each build. Note that most
- # data about a build is still stored in on-disk pickles.
- builds = sa.Table('builds', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('number', sa.Integer, nullable=False),
- sa.Column('brid', sa.Integer, sa.ForeignKey('buildrequests.id'),
- nullable=False),
- sa.Column('start_time', sa.Integer, nullable=False),
- sa.Column('finish_time', sa.Integer),
- )
-
- # buildsets
-
- # This table contains input properties for buildsets
- buildset_properties = sa.Table('buildset_properties', metadata,
- sa.Column('buildsetid', sa.Integer, sa.ForeignKey('buildsets.id'),
- nullable=False),
- sa.Column('property_name', sa.String(256), nullable=False),
- # JSON-encoded tuple of (value, source)
- sa.Column('property_value', sa.String(1024), nullable=False),
- )
-
- # This table represents Buildsets - sets of BuildRequests that share the
- # same original cause and source information.
- buildsets = sa.Table('buildsets', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
-
- # a simple external identifier to track down this buildset later, e.g.,
- # for try requests
- sa.Column('external_idstring', sa.String(256)),
-
- # a short string giving the reason the buildset was created
- sa.Column('reason', sa.String(256)),
- sa.Column('submitted_at', sa.Integer, nullable=False),
-
- # if this is zero, then the build set is still pending
- sa.Column('complete', sa.SmallInteger, nullable=False,
- server_default=sa.DefaultClause("0")),
- sa.Column('complete_at', sa.Integer),
-
- # results is only valid when complete == 1; 0 = SUCCESS, 1 = WARNINGS,
- # etc - see master/buildbot/status/builder.py
- sa.Column('results', sa.SmallInteger),
-
- # buildset belongs to all sourcestamps with setid
- sa.Column('sourcestampsetid', sa.Integer,
- sa.ForeignKey('sourcestampsets.id')),
- )
-
- # changes
-
- # Files touched in changes
- change_files = sa.Table('change_files', metadata,
- sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid'),
- nullable=False),
- sa.Column('filename', sa.String(1024), nullable=False),
- )
-
- # Properties for changes
- change_properties = sa.Table('change_properties', metadata,
- sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid'),
- nullable=False),
- sa.Column('property_name', sa.String(256), nullable=False),
- # JSON-encoded tuple of (value, source)
- sa.Column('property_value', sa.String(1024), nullable=False),
- )
-
- # users associated with this change; this allows multiple users for
- # situations where a version-control system can represent both an author
- # and committer, for example.
- change_users = sa.Table("change_users", metadata,
- sa.Column("changeid", sa.Integer, sa.ForeignKey('changes.changeid'),
- nullable=False),
- # uid for the author of the change with the given changeid
- sa.Column("uid", sa.Integer, sa.ForeignKey('users.uid'),
- nullable=False)
- )
-
- # Changes to the source code, produced by ChangeSources
- changes = sa.Table('changes', metadata,
- # changeid also serves as 'change number'
- sa.Column('changeid', sa.Integer, primary_key=True),
-
- # author's name (usually an email address)
- sa.Column('author', sa.String(256), nullable=False),
-
- # commit comment
- sa.Column('comments', sa.String(1024), nullable=False),
-
- # old, CVS-related boolean
- sa.Column('is_dir', sa.SmallInteger, nullable=False), # old, for CVS
-
- # The branch where this change occurred. When branch is NULL, that
- # means the main branch (trunk, master, etc.)
- sa.Column('branch', sa.String(256)),
-
- # revision identifier for this change
- sa.Column('revision', sa.String(256)), # CVS uses NULL
-
- sa.Column('revlink', sa.String(256)),
-
- # this is the timestamp of the change - it is usually copied from the
- # version-control system, and may be long in the past or even in the
- # future!
- sa.Column('when_timestamp', sa.Integer, nullable=False),
-
- # an arbitrary string used for filtering changes
- sa.Column('category', sa.String(256)),
-
- # repository specifies, along with revision and branch, the
- # source tree in which this change was detected.
- sa.Column('repository', sa.String(length=512), nullable=False,
- server_default=''),
-
- # codebase is a logical name to specify what is in the repository
- sa.Column('codebase', sa.String(256), nullable=False,
- server_default=sa.DefaultClause("")),
-
- # project names the project this source code represents. It is used
- # later to filter changes
- sa.Column('project', sa.String(length=512), nullable=False,
- server_default=''),
- )
-
- # sourcestamps
-
- # Patches for SourceStamps that were generated through the try mechanism
- patches = sa.Table('patches', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
-
- # number of directory levels to strip off (patch -pN)
- sa.Column('patchlevel', sa.Integer, nullable=False),
-
- # base64-encoded version of the patch file
- sa.Column('patch_base64', sa.Text, nullable=False),
-
- # patch author, if known
- sa.Column('patch_author', sa.Text, nullable=False),
-
- # patch comment
- sa.Column('patch_comment', sa.Text, nullable=False),
-
- # subdirectory in which the patch should be applied; NULL for top-level
- sa.Column('subdir', sa.Text),
- )
-
- # The changes that led up to a particular source stamp.
- sourcestamp_changes = sa.Table('sourcestamp_changes', metadata,
- sa.Column('sourcestampid', sa.Integer,
- sa.ForeignKey('sourcestamps.id'), nullable=False),
- sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid'),
- nullable=False),
- )
-
- # A sourcestampset identifies a set of sourcestamps. A sourcestamp belongs
- # to a particular set if the sourcestamp has the same setid
- sourcestampsets = sa.Table('sourcestampsets', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- )
-
- # A sourcestamp identifies a particular instance of the source code.
- # Ideally, this would always be absolute, but in practice source stamps can
- # also mean "latest" (when revision is NULL), which is of course a
- # time-dependent definition.
- sourcestamps = sa.Table('sourcestamps', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
-
- # the branch to check out. When branch is NULL, that means
- # the main branch (trunk, master, etc.)
- sa.Column('branch', sa.String(256)),
-
- # the revision to check out, or the latest if NULL
- sa.Column('revision', sa.String(256)),
-
- # the patch to apply to generate this source code
- sa.Column('patchid', sa.Integer, sa.ForeignKey('patches.id')),
-
- # the repository from which this source should be checked out
- sa.Column('repository', sa.String(length=512), nullable=False,
- server_default=''),
-
- # codebase is a logical name to specify what is in the repository
- sa.Column('codebase', sa.String(256), nullable=False,
- server_default=sa.DefaultClause("")),
-
- # the project this source code represents
- sa.Column('project', sa.String(length=512), nullable=False,
- server_default=''),
-
- # each sourcestamp belongs to a set of sourcestamps
- sa.Column('sourcestampsetid', sa.Integer,
- sa.ForeignKey('sourcestampsets.id')),
- )
-
- # schedulers
-
- # This table references "classified" changes that have not yet been
- # "processed". That is, the scheduler has looked at these changes and
- # determined that something should be done, but that hasn't happened yet.
- # Rows are deleted from this table as soon as the scheduler is done with
- # the change.
- scheduler_changes = sa.Table('scheduler_changes', metadata,
- sa.Column('objectid', sa.Integer, sa.ForeignKey('objects.id')),
- sa.Column('changeid', sa.Integer, sa.ForeignKey('changes.changeid')),
- # true (nonzero) if this change is important to this scheduler
- sa.Column('important', sa.Integer),
- )
-
- # objects
-
- # This table uniquely identifies objects that need to maintain state across
- # invocations.
- objects = sa.Table("objects", metadata,
- # unique ID for this object
- sa.Column("id", sa.Integer, primary_key=True),
- # object's user-given name
- sa.Column('name', sa.String(128), nullable=False),
- # object's class name, basically representing a "type" for the state
- sa.Column('class_name', sa.String(128), nullable=False),
- )
-
- # This table stores key/value pairs for objects, where the key is a string
- # and the value is a JSON string.
- object_state = sa.Table("object_state", metadata,
- # object for which this value is set
- sa.Column("objectid", sa.Integer, sa.ForeignKey('objects.id'),
- nullable=False),
- # name for this value (local to the object)
- sa.Column("name", sa.String(length=256), nullable=False),
- # value, as a JSON string
- sa.Column("value_json", sa.Text, nullable=False),
- )
-
- #users
-
- # This table identifies individual users, and contains buildbot-specific
- # information about those users.
- users = sa.Table("users", metadata,
- # unique user id number
- sa.Column("uid", sa.Integer, primary_key=True),
-
- # identifier (nickname) for this user; used for display
- sa.Column("identifier", sa.String(256), nullable=False),
-
- # username portion of user credentials for authentication
- sa.Column("bb_username", sa.String(128)),
-
- # password portion of user credentials for authentication
- sa.Column("bb_password", sa.String(128)),
- )
-
- # This table stores information identifying a user that's related to a
- # particular interface - a version-control system, status plugin, etc.
- users_info = sa.Table("users_info", metadata,
- # unique user id number
- sa.Column("uid", sa.Integer, sa.ForeignKey('users.uid'),
- nullable=False),
-
- # type of user attribute, such as 'git'
- sa.Column("attr_type", sa.String(128), nullable=False),
-
- # data for given user attribute, such as a commit string or password
- sa.Column("attr_data", sa.String(128), nullable=False),
- )
-
-
- # indexes
-
- sa.Index('buildrequests_buildsetid', buildrequests.c.buildsetid)
- sa.Index('buildrequests_buildername', buildrequests.c.buildername)
- sa.Index('buildrequests_complete', buildrequests.c.complete)
- sa.Index('builds_number', builds.c.number)
- sa.Index('builds_brid', builds.c.brid)
- sa.Index('buildsets_complete', buildsets.c.complete)
- sa.Index('buildsets_submitted_at', buildsets.c.submitted_at)
- sa.Index('buildset_properties_buildsetid',
- buildset_properties.c.buildsetid)
- sa.Index('changes_branch', changes.c.branch)
- sa.Index('changes_revision', changes.c.revision)
- sa.Index('changes_author', changes.c.author)
- sa.Index('changes_category', changes.c.category)
- sa.Index('changes_when_timestamp', changes.c.when_timestamp)
- sa.Index('change_files_changeid', change_files.c.changeid)
- sa.Index('change_properties_changeid', change_properties.c.changeid)
- sa.Index('scheduler_changes_objectid', scheduler_changes.c.objectid)
- sa.Index('scheduler_changes_changeid', scheduler_changes.c.changeid)
- sa.Index('scheduler_changes_unique', scheduler_changes.c.objectid,
- scheduler_changes.c.changeid, unique=True)
- sa.Index('sourcestamp_changes_sourcestampid',
- sourcestamp_changes.c.sourcestampid)
- sa.Index('sourcestamps_sourcestampsetid', sourcestamps.c.sourcestampsetid,
- unique=False)
- sa.Index('users_identifier', users.c.identifier, unique=True)
- sa.Index('users_info_uid', users_info.c.uid)
- sa.Index('users_info_uid_attr_type', users_info.c.uid,
- users_info.c.attr_type, unique=True)
- sa.Index('users_info_attrs', users_info.c.attr_type,
- users_info.c.attr_data, unique=True)
- sa.Index('change_users_changeid', change_users.c.changeid)
- sa.Index('users_bb_user', users.c.bb_username, unique=True)
- sa.Index('object_identity', objects.c.name, objects.c.class_name,
- unique=True)
- sa.Index('name_per_object', object_state.c.objectid, object_state.c.name,
- unique=True)
-
- # MySQl creates indexes for foreign keys, and these appear in the
- # reflection. This is a list of (table, index) names that should be
- # expected on this platform
-
- implied_indexes = [
- ('change_users',
- dict(unique=False, column_names=['uid'], name='uid')),
- ('sourcestamps',
- dict(unique=False, column_names=['patchid'], name='patchid')),
- ('sourcestamp_changes',
- dict(unique=False, column_names=['changeid'], name='changeid')),
- ('buildsets',
- dict(unique=False, column_names=['sourcestampsetid'],
- name='buildsets_sourcestampsetid_fkey')),
- ]
-
- #
- # migration support
- #
-
- # this is a bit more complicated than might be expected because the first
- # seven database versions were once implemented using a homespun migration
- # system, and we need to support upgrading masters from that system. The
- # old system used a 'version' table, where SQLAlchemy-Migrate uses
- # 'migrate_version'
-
- repo_path = util.sibpath(__file__, "migrate")
-
- def is_current(self):
- def thd(engine):
- # we don't even have to look at the old version table - if there's
- # no migrate_version, then we're not up to date.
- repo = migrate.versioning.repository.Repository(self.repo_path)
- repo_version = repo.latest
- try:
- # migrate.api doesn't let us hand in an engine
- schema = migrate.versioning.schema.ControlledSchema(engine,
- self.repo_path)
- db_version = schema.version
- except exceptions.DatabaseNotControlledError:
- return False
-
- return db_version == repo_version
- return self.db.pool.do_with_engine(thd)
-
- def upgrade(self):
-
- # here, things are a little tricky. If we have a 'version' table, then
- # we need to version_control the database with the proper version
- # number, drop 'version', and then upgrade. If we have no 'version'
- # table and no 'migrate_version' table, then we need to version_control
- # the database. Otherwise, we just need to upgrade it.
-
- def table_exists(engine, tbl):
- try:
- r = engine.execute("select * from %s limit 1" % tbl)
- r.close()
- return True
- except:
- return False
-
- # http://code.google.com/p/sqlalchemy-migrate/issues/detail?id=100
- # means we cannot use the migrate.versioning.api module. So these
- # methods perform similar wrapping functions to what is done by the API
- # functions, but without disposing of the engine.
- def upgrade(engine):
- schema = migrate.versioning.schema.ControlledSchema(engine,
- self.repo_path)
- changeset = schema.changeset(None)
- for version, change in changeset:
- log.msg('migrating schema version %s -> %d'
- % (version, version + 1))
- schema.runchange(version, change, 1)
-
- def check_sqlalchemy_migrate_version():
- # sqlalchemy-migrate started including a version number in 0.7; we
- # support back to 0.6.1, but not 0.6. We'll use some discovered
- # differences between 0.6.1 and 0.6 to get that resolution.
- version = getattr(migrate, '__version__', 'old')
- if version == 'old':
- try:
- from migrate.versioning import schemadiff
- if hasattr(schemadiff, 'ColDiff'):
- version = "0.6.1"
- else:
- version = "0.6"
- except:
- version = "0.0"
- version_tup = tuple(map(int, version.split('.')))
- log.msg("using SQLAlchemy-Migrate version %s" % (version,))
- if version_tup < (0,6,1):
- raise RuntimeError("You are using SQLAlchemy-Migrate %s. "
- "The minimum version is 0.6.1." % (version,))
-
- def version_control(engine, version=None):
- migrate.versioning.schema.ControlledSchema.create(engine,
- self.repo_path, version)
-
- # the upgrade process must run in a db thread
- def thd(engine):
- # if the migrate_version table exists, we can just let migrate
- # take care of this process.
- if table_exists(engine, 'migrate_version'):
- upgrade(engine)
-
- # if the version table exists, then we can version_control things
- # at that version, drop the version table, and let migrate take
- # care of the rest.
- elif table_exists(engine, 'version'):
- # get the existing version
- r = engine.execute("select version from version limit 1")
- old_version = r.scalar()
-
- # set up migrate at the same version
- version_control(engine, old_version)
-
- # drop the no-longer-required version table, using a dummy
- # metadata entry
- table = sa.Table('version', self.metadata,
- sa.Column('x', sa.Integer))
- table.drop(bind=engine)
-
- # clear the dummy metadata entry
- self.metadata.remove(table)
-
- # and, finally, upgrade using migrate
- upgrade(engine)
-
- # otherwise, this db is uncontrolled, so we just version control it
- # and update it.
- else:
- version_control(engine)
- upgrade(engine)
-
- check_sqlalchemy_migrate_version()
- return self.db.pool.do_with_engine(thd)
-
-# migrate has a bug in one of its warnings; this is fixed in version control
-# (3ba66abc4d), but not yet released. It can't hurt to fix it here, too, so we
-# get realistic tracebacks
-try:
- import migrate.versioning.exceptions as ex1
- import migrate.changeset.exceptions as ex2
- ex1.MigrateDeprecationWarning = ex2.MigrateDeprecationWarning
-except (ImportError,AttributeError):
- pass
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/pool.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/pool.py
deleted file mode 100644
index 03c6f940..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/pool.py
+++ /dev/null
@@ -1,288 +0,0 @@
-# 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 time
-import traceback
-import inspect
-import shutil
-import os
-import sqlalchemy as sa
-import tempfile
-from buildbot.process import metrics
-from twisted.internet import reactor, threads
-from twisted.python import threadpool, log
-
-# set this to True for *very* verbose query debugging output; this can
-# be monkey-patched from master.cfg, too:
-# from buildbot.db import pool
-# pool.debug = True
-debug = False
-_debug_id = 1
-
-def timed_do_fn(f):
- """Decorate a do function to log before, after, and elapsed time,
- with the name of the calling function. This is not speedy!"""
- def wrap(callable, *args, **kwargs):
- global _debug_id
-
- # get a description of the function that called us
- st = traceback.extract_stack(limit=2)
- file, line, name, _ = st[0]
-
- # and its locals
- frame = inspect.currentframe(1)
- locals = frame.f_locals
-
- # invent a unique ID for the description
- id, _debug_id = _debug_id, _debug_id+1
-
- descr = "%s-%08x" % (name, id)
-
- start_time = time.time()
- log.msg("%s - before ('%s' line %d)" % (descr, file, line))
- for name in locals:
- if name in ('self', 'thd'):
- continue
- log.msg("%s - %s = %r" % (descr, name, locals[name]))
-
- # wrap the callable to log the begin and end of the actual thread
- # function
- def callable_wrap(*args, **kargs):
- log.msg("%s - thd start" % (descr,))
- try:
- return callable(*args, **kwargs)
- finally:
- log.msg("%s - thd end" % (descr,))
- d = f(callable_wrap, *args, **kwargs)
-
- def after(x):
- end_time = time.time()
- elapsed = (end_time - start_time) * 1000
- log.msg("%s - after (%0.2f ms elapsed)" % (descr, elapsed))
- return x
- d.addBoth(after)
- return d
- wrap.__name__ = f.__name__
- wrap.__doc__ = f.__doc__
- return wrap
-
-class DBThreadPool(threadpool.ThreadPool):
-
- running = False
-
- # Some versions of SQLite incorrectly cache metadata about which tables are
- # and are not present on a per-connection basis. This cache can be flushed
- # by querying the sqlite_master table. We currently assume all versions of
- # SQLite have this bug, although it has only been observed in 3.4.2. A
- # dynamic check for this bug would be more appropriate. This is documented
- # in bug #1810.
- __broken_sqlite = None
-
- def __init__(self, engine, verbose=False):
- # verbose is used by upgrade scripts, and if it is set we should print
- # messages about versions and other warnings
- log_msg = log.msg
- if verbose:
- def log_msg(m):
- print m
-
- pool_size = 5
-
- # If the engine has an C{optimal_thread_pool_size} attribute, then the
- # maxthreads of the thread pool will be set to that value. This is
- # most useful for SQLite in-memory connections, where exactly one
- # connection (and thus thread) should be used.
- if hasattr(engine, 'optimal_thread_pool_size'):
- pool_size = engine.optimal_thread_pool_size
-
- threadpool.ThreadPool.__init__(self,
- minthreads=1,
- maxthreads=pool_size,
- name='DBThreadPool')
- self.engine = engine
- if engine.dialect.name == 'sqlite':
- vers = self.get_sqlite_version()
- if vers < (3,7):
- log_msg("Using SQLite Version %s" % (vers,))
- log_msg("NOTE: this old version of SQLite does not support "
- "WAL journal mode; a busy master may encounter "
- "'Database is locked' errors. Consider upgrading.")
- if vers < (3,4):
- log_msg("NOTE: this old version of SQLite is not "
- "supported.")
- raise RuntimeError("unsupported SQLite version")
- if self.__broken_sqlite is None:
- self.__class__.__broken_sqlite = self.detect_bug1810()
- brkn = self.__broken_sqlite
- if brkn:
- log_msg("Applying SQLite workaround from Buildbot bug #1810")
- self._start_evt = reactor.callWhenRunning(self._start)
-
- # patch the do methods to do verbose logging if necessary
- if debug:
- self.do = timed_do_fn(self.do)
- self.do_with_engine = timed_do_fn(self.do_with_engine)
-
- def _start(self):
- self._start_evt = None
- if not self.running:
- self.start()
- self._stop_evt = reactor.addSystemEventTrigger(
- 'during', 'shutdown', self._stop)
- self.running = True
-
- def _stop(self):
- self._stop_evt = None
- self.stop()
- self.engine.dispose()
- self.running = False
-
- def shutdown(self):
- """Manually stop the pool. This is only necessary from tests, as the
- pool will stop itself when the reactor stops under normal
- circumstances."""
- if not self._stop_evt:
- return # pool is already stopped
- reactor.removeSystemEventTrigger(self._stop_evt)
- self._stop()
-
- # Try about 170 times over the space of a day, with the last few tries
- # being about an hour apart. This is designed to span a reasonable amount
- # of time for repairing a broken database server, while still failing
- # actual problematic queries eventually
- BACKOFF_START = 1.0
- BACKOFF_MULT = 1.05
- MAX_OPERATIONALERROR_TIME = 3600*24 # one day
- def __thd(self, with_engine, callable, args, kwargs):
- # try to call callable(arg, *args, **kwargs) repeatedly until no
- # OperationalErrors occur, where arg is either the engine (with_engine)
- # or a connection (not with_engine)
- backoff = self.BACKOFF_START
- start = time.time()
- while True:
- if with_engine:
- arg = self.engine
- else:
- arg = self.engine.contextual_connect()
-
- if self.__broken_sqlite: # see bug #1810
- arg.execute("select * from sqlite_master")
- try:
- try:
- rv = callable(arg, *args, **kwargs)
- assert not isinstance(rv, sa.engine.ResultProxy), \
- "do not return ResultProxy objects!"
- except sa.exc.OperationalError, e:
- text = e.orig.args[0]
- if not isinstance(text, basestring):
- raise
- if "Lost connection" in text \
- or "database is locked" in text:
-
- # see if we've retried too much
- elapsed = time.time() - start
- if elapsed > self.MAX_OPERATIONALERROR_TIME:
- raise
-
- metrics.MetricCountEvent.log(
- "DBThreadPool.retry-on-OperationalError")
- log.msg("automatically retrying query after "
- "OperationalError (%ss sleep)" % backoff)
-
- # sleep (remember, we're in a thread..)
- time.sleep(backoff)
- backoff *= self.BACKOFF_MULT
-
- # and re-try
- continue
- else:
- raise
- finally:
- if not with_engine:
- arg.close()
- break
- return rv
-
- def do(self, callable, *args, **kwargs):
- return threads.deferToThreadPool(reactor, self,
- self.__thd, False, callable, args, kwargs)
-
- def do_with_engine(self, callable, *args, **kwargs):
- return threads.deferToThreadPool(reactor, self,
- self.__thd, True, callable, args, kwargs)
-
- def detect_bug1810(self):
- # detect buggy SQLite implementations; call only for a known-sqlite
- # dialect
- try:
- import pysqlite2.dbapi2 as sqlite
- sqlite = sqlite
- except ImportError:
- import sqlite3 as sqlite
-
- tmpdir = tempfile.mkdtemp()
- dbfile = os.path.join(tmpdir, "detect_bug1810.db")
- def test(select_from_sqlite_master=False):
- conn1 = None
- conn2 = None
- try:
- conn1 = sqlite.connect(dbfile)
- curs1 = conn1.cursor()
- curs1.execute("PRAGMA table_info('foo')")
-
- conn2 = sqlite.connect(dbfile)
- curs2 = conn2.cursor()
- curs2.execute("CREATE TABLE foo ( a integer )")
-
- if select_from_sqlite_master:
- curs1.execute("SELECT * from sqlite_master")
- curs1.execute("SELECT * from foo")
- finally:
- if conn1:
- conn1.close()
- if conn2:
- conn2.close()
- os.unlink(dbfile)
-
- try:
- test()
- except sqlite.OperationalError:
- # this is the expected error indicating it's broken
- shutil.rmtree(tmpdir)
- return True
-
- # but this version should not fail..
- test(select_from_sqlite_master=True)
- shutil.rmtree(tmpdir)
- return False # not broken - no workaround required
-
- def get_sqlite_version(self):
- engine = sa.create_engine('sqlite://')
- conn = engine.contextual_connect()
-
- try:
- r = conn.execute("SELECT sqlite_version()")
- vers_row = r.fetchone()
- r.close()
- except:
- return (0,)
-
- if vers_row:
- try:
- return tuple(map(int, vers_row[0].split('.')))
- except (TypeError, ValueError):
- return (0,)
- else:
- return (0,)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/schedulers.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/schedulers.py
deleted file mode 100644
index 0e845da3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/schedulers.py
+++ /dev/null
@@ -1,93 +0,0 @@
-# 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
-import sqlalchemy.exc
-from buildbot.db import base
-
-class SchedulersConnectorComponent(base.DBConnectorComponent):
- # Documentation is in developer/database.rst
-
- def classifyChanges(self, objectid, classifications):
- def thd(conn):
- transaction = conn.begin()
- tbl = self.db.model.scheduler_changes
- ins_q = tbl.insert()
- upd_q = tbl.update(
- ((tbl.c.objectid == objectid)
- & (tbl.c.changeid == sa.bindparam('wc_changeid'))))
- for changeid, important in classifications.items():
- # convert the 'important' value into an integer, since that
- # is the column type
- imp_int = important and 1 or 0
- try:
- conn.execute(ins_q,
- objectid=objectid,
- changeid=changeid,
- important=imp_int)
- except (sqlalchemy.exc.ProgrammingError,
- sqlalchemy.exc.IntegrityError):
- # insert failed, so try an update
- conn.execute(upd_q,
- wc_changeid=changeid,
- important=imp_int)
-
- transaction.commit()
- return self.db.pool.do(thd)
-
- def flushChangeClassifications(self, objectid, less_than=None):
- def thd(conn):
- sch_ch_tbl = self.db.model.scheduler_changes
- wc = (sch_ch_tbl.c.objectid == objectid)
- if less_than is not None:
- wc = wc & (sch_ch_tbl.c.changeid < less_than)
- q = sch_ch_tbl.delete(whereclause=wc)
- conn.execute(q)
- return self.db.pool.do(thd)
-
- class Thunk: pass
- def getChangeClassifications(self, objectid, branch=Thunk,
- repository=Thunk, project=Thunk,
- codebase=Thunk):
- def thd(conn):
- sch_ch_tbl = self.db.model.scheduler_changes
- ch_tbl = self.db.model.changes
-
- wc = (sch_ch_tbl.c.objectid == objectid)
-
- # may need to filter further based on branch, etc
- extra_wheres = []
- if branch is not self.Thunk:
- extra_wheres.append(ch_tbl.c.branch == branch)
- if repository is not self.Thunk:
- extra_wheres.append(ch_tbl.c.repository == repository)
- if project is not self.Thunk:
- extra_wheres.append(ch_tbl.c.project == project)
- if codebase is not self.Thunk:
- extra_wheres.append(ch_tbl.c.codebase == codebase)
-
- # if we need to filter further append those, as well as a join
- # on changeid (but just once for that one)
- if extra_wheres:
- wc &= (sch_ch_tbl.c.changeid == ch_tbl.c.changeid)
- for w in extra_wheres:
- wc &= w
-
- q = sa.select(
- [ sch_ch_tbl.c.changeid, sch_ch_tbl.c.important ],
- whereclause=wc)
- return dict([ (r.changeid, [False,True][r.important])
- for r in conn.execute(q) ])
- return self.db.pool.do(thd)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/sourcestamps.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/sourcestamps.py
deleted file mode 100644
index 741fdee9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/sourcestamps.py
+++ /dev/null
@@ -1,145 +0,0 @@
-# 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 base64
-import sqlalchemy as sa
-from twisted.internet import defer
-from twisted.python import log
-from buildbot.db import base
-
-class SsDict(dict):
- pass
-
-class SsList(list):
- pass
-
-class SourceStampsConnectorComponent(base.DBConnectorComponent):
- # Documentation is in developer/database.rst
-
- def addSourceStamp(self, branch, revision, repository,
- project, sourcestampsetid, codebase='',
- patch_body=None, patch_level=0, patch_author="",
- patch_comment="", patch_subdir=None, changeids=[]):
- def thd(conn):
- transaction = conn.begin()
-
- # handle inserting a patch
- patchid = None
- if patch_body is not None:
- ins = self.db.model.patches.insert()
- r = conn.execute(ins, dict(
- patchlevel=patch_level,
- patch_base64=base64.b64encode(patch_body),
- patch_author=patch_author,
- patch_comment=patch_comment,
- subdir=patch_subdir))
- patchid = r.inserted_primary_key[0]
-
- # insert the sourcestamp itself
- tbl = self.db.model.sourcestamps
- self.check_length(tbl.c.branch, branch)
- self.check_length(tbl.c.revision, revision)
- self.check_length(tbl.c.repository, repository)
- self.check_length(tbl.c.project, project)
-
- r = conn.execute(tbl.insert(), dict(
- branch=branch,
- revision=revision,
- patchid=patchid,
- repository=repository,
- codebase=codebase,
- project=project,
- sourcestampsetid=sourcestampsetid))
- ssid = r.inserted_primary_key[0]
-
- # handle inserting change ids
- if changeids:
- ins = self.db.model.sourcestamp_changes.insert()
- conn.execute(ins, [
- dict(sourcestampid=ssid, changeid=changeid)
- for changeid in changeids ])
-
- transaction.commit()
-
- # and return the new ssid
- return ssid
- return self.db.pool.do(thd)
-
- @base.cached("sssetdicts")
- @defer.inlineCallbacks
- def getSourceStamps(self,sourcestampsetid):
- def getSourceStampIds(sourcestampsetid):
- def thd(conn):
- tbl = self.db.model.sourcestamps
- q = sa.select([tbl.c.id],
- whereclause=(tbl.c.sourcestampsetid == sourcestampsetid))
- res = conn.execute(q)
- return [ row.id for row in res.fetchall() ]
- return self.db.pool.do(thd)
- ssids = yield getSourceStampIds(sourcestampsetid)
-
- sslist=SsList()
- for ssid in ssids:
- sourcestamp = yield self.getSourceStamp(ssid)
- sslist.append(sourcestamp)
- defer.returnValue(sslist)
-
- @base.cached("ssdicts")
- def getSourceStamp(self, ssid):
- def thd(conn):
- tbl = self.db.model.sourcestamps
- q = tbl.select(whereclause=(tbl.c.id == ssid))
- res = conn.execute(q)
- row = res.fetchone()
- if not row:
- return None
- ssdict = SsDict(ssid=ssid, branch=row.branch, sourcestampsetid=row.sourcestampsetid,
- revision=row.revision, patch_body=None, patch_level=None,
- patch_author=None, patch_comment=None, patch_subdir=None,
- repository=row.repository, codebase=row.codebase,
- project=row.project,
- changeids=set([]))
- patchid = row.patchid
- res.close()
-
- # fetch the patch, if necessary
- if patchid is not None:
- tbl = self.db.model.patches
- q = tbl.select(whereclause=(tbl.c.id == patchid))
- res = conn.execute(q)
- row = res.fetchone()
- if row:
- # note the subtle renaming here
- ssdict['patch_level'] = row.patchlevel
- ssdict['patch_subdir'] = row.subdir
- ssdict['patch_author'] = row.patch_author
- ssdict['patch_comment'] = row.patch_comment
- body = base64.b64decode(row.patch_base64)
- ssdict['patch_body'] = body
- else:
- log.msg('patchid %d, referenced from ssid %d, not found'
- % (patchid, ssid))
- res.close()
-
- # fetch change ids
- tbl = self.db.model.sourcestamp_changes
- q = tbl.select(whereclause=(tbl.c.sourcestampid == ssid))
- res = conn.execute(q)
- for row in res:
- ssdict['changeids'].add(row.changeid)
- res.close()
-
- return ssdict
- return self.db.pool.do(thd)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/sourcestampsets.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/sourcestampsets.py
deleted file mode 100644
index 9210c69c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/sourcestampsets.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# 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
-
-from buildbot.db import base
-
-class SourceStampSetsConnectorComponent(base.DBConnectorComponent):
- # Documentation is in developer/database.rst
-
- def addSourceStampSet(self):
- def thd(conn):
- # insert the sourcestampset. sourcestampset has no attributes, but
- # inserting a new row results in a new setid
- r = conn.execute(self.db.model.sourcestampsets.insert(), dict())
- sourcestampsetid = r.inserted_primary_key[0]
-
- return sourcestampsetid
- return self.db.pool.do(thd)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/state.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/state.py
deleted file mode 100644
index 52fdd68b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/state.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# 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
-
-from buildbot.util import json
-import sqlalchemy as sa
-import sqlalchemy.exc
-from buildbot.db import base
-
-class _IdNotFoundError(Exception):
- pass # used internally
-
-class ObjDict(dict):
- pass
-
-class StateConnectorComponent(base.DBConnectorComponent):
- # Documentation is in developer/database.rst
-
- def getObjectId(self, name, class_name):
- # defer to a cached method that only takes one parameter (a tuple)
- return self._getObjectId((name, class_name)
- ).addCallback(lambda objdict : objdict['id'])
-
- @base.cached('objectids')
- def _getObjectId(self, name_class_name_tuple):
- name, class_name = name_class_name_tuple
- def thd(conn):
- objects_tbl = self.db.model.objects
-
- self.check_length(objects_tbl.c.name, name)
- self.check_length(objects_tbl.c.class_name, class_name)
-
- def select():
- q = sa.select([ objects_tbl.c.id ],
- whereclause=((objects_tbl.c.name == name)
- & (objects_tbl.c.class_name == class_name)))
- res = conn.execute(q)
- row = res.fetchone()
- res.close()
- if not row:
- raise _IdNotFoundError
- return row.id
-
- def insert():
- res = conn.execute(objects_tbl.insert(),
- name=name,
- class_name=class_name)
- return res.inserted_primary_key[0]
-
- # we want to try selecting, then inserting, but if the insert fails
- # then try selecting again. We include an invocation of a hook
- # method to allow tests to exercise this particular behavior
- try:
- return ObjDict(id=select())
- except _IdNotFoundError:
- pass
-
- self._test_timing_hook(conn)
-
- try:
- return ObjDict(id=insert())
- except (sqlalchemy.exc.IntegrityError,
- sqlalchemy.exc.ProgrammingError):
- pass
-
- return ObjDict(id=select())
-
- return self.db.pool.do(thd)
-
- class Thunk: pass
- def getState(self, objectid, name, default=Thunk):
- def thd(conn):
- object_state_tbl = self.db.model.object_state
-
- q = sa.select([ object_state_tbl.c.value_json ],
- whereclause=((object_state_tbl.c.objectid == objectid)
- & (object_state_tbl.c.name == name)))
- res = conn.execute(q)
- row = res.fetchone()
- res.close()
-
- if not row:
- if default is self.Thunk:
- raise KeyError("no such state value '%s' for object %d" %
- (name, objectid))
- return default
- try:
- return json.loads(row.value_json)
- except:
- raise TypeError("JSON error loading state value '%s' for %d" %
- (name, objectid))
- return self.db.pool.do(thd)
-
- def setState(self, objectid, name, value):
- def thd(conn):
- object_state_tbl = self.db.model.object_state
-
- try:
- value_json = json.dumps(value)
- except:
- raise TypeError("Error encoding JSON for %r" % (value,))
-
- self.check_length(object_state_tbl.c.name, name)
-
- def update():
- q = object_state_tbl.update(
- whereclause=((object_state_tbl.c.objectid == objectid)
- & (object_state_tbl.c.name == name)))
- res = conn.execute(q, value_json=value_json)
-
- # check whether that worked
- return res.rowcount > 0
-
- def insert():
- conn.execute(object_state_tbl.insert(),
- objectid=objectid,
- name=name,
- value_json=value_json)
-
- # try updating; if that fails, try inserting; if that fails, then
- # we raced with another instance to insert, so let that instance
- # win.
-
- if update():
- return
-
- self._test_timing_hook(conn)
-
- try:
- insert()
- except (sqlalchemy.exc.IntegrityError, sqlalchemy.exc.ProgrammingError):
- pass # someone beat us to it - oh well
-
- return self.db.pool.do(thd)
-
- def _test_timing_hook(self, conn):
- # called so tests can simulate another process inserting a database row
- # at an inopportune moment
- pass
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/users.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/users.py
deleted file mode 100644
index 7e32902c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/db/users.py
+++ /dev/null
@@ -1,233 +0,0 @@
-# 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
-from sqlalchemy.sql.expression import and_
-
-from buildbot.db import base
-
-class UsDict(dict):
- pass
-
-class UsersConnectorComponent(base.DBConnectorComponent):
- # Documentation is in developer/database.rst
-
- def findUserByAttr(self, identifier, attr_type, attr_data, _race_hook=None):
- def thd(conn, no_recurse=False):
- tbl = self.db.model.users
- tbl_info = self.db.model.users_info
-
- self.check_length(tbl.c.identifier, identifier)
- self.check_length(tbl_info.c.attr_type, attr_type)
- self.check_length(tbl_info.c.attr_data, attr_data)
-
- # try to find the user
- q = sa.select([ tbl_info.c.uid ],
- whereclause=and_(tbl_info.c.attr_type == attr_type,
- tbl_info.c.attr_data == attr_data))
- rows = conn.execute(q).fetchall()
-
- if rows:
- return rows[0].uid
-
- _race_hook and _race_hook(conn)
-
- # try to do both of these inserts in a transaction, so that both
- # the new user and the corresponding attributes appear at the same
- # time from the perspective of other masters.
- transaction = conn.begin()
- try:
- r = conn.execute(tbl.insert(), dict(identifier=identifier))
- uid = r.inserted_primary_key[0]
-
- conn.execute(tbl_info.insert(),
- dict(uid=uid, attr_type=attr_type,
- attr_data=attr_data))
-
- transaction.commit()
- except (sa.exc.IntegrityError, sa.exc.ProgrammingError):
- transaction.rollback()
-
- # try it all over again, in case there was an overlapping,
- # identical call to findUserByAttr, but only retry once.
- if no_recurse:
- raise
- return thd(conn, no_recurse=True)
-
- return uid
- d = self.db.pool.do(thd)
- return d
-
- @base.cached("usdicts")
- def getUser(self, uid):
- def thd(conn):
- tbl = self.db.model.users
- tbl_info = self.db.model.users_info
-
- q = tbl.select(whereclause=(tbl.c.uid == uid))
- users_row = conn.execute(q).fetchone()
-
- if not users_row:
- return None
-
- # make UsDict to return
- usdict = UsDict()
-
- # gather all attr_type and attr_data entries from users_info table
- q = tbl_info.select(whereclause=(tbl_info.c.uid == uid))
- rows = conn.execute(q).fetchall()
- for row in rows:
- usdict[row.attr_type] = row.attr_data
-
- # add the users_row data *after* the attributes in case attr_type
- # matches one of these keys.
- usdict['uid'] = users_row.uid
- usdict['identifier'] = users_row.identifier
- usdict['bb_username'] = users_row.bb_username
- usdict['bb_password'] = users_row.bb_password
-
- return usdict
- d = self.db.pool.do(thd)
- return d
-
- def getUserByUsername(self, username):
- def thd(conn):
- tbl = self.db.model.users
- tbl_info = self.db.model.users_info
-
- q = tbl.select(whereclause=(tbl.c.bb_username == username))
- users_row = conn.execute(q).fetchone()
-
- if not users_row:
- return None
-
- # make UsDict to return
- usdict = UsDict()
-
- # gather all attr_type and attr_data entries from users_info table
- q = tbl_info.select(whereclause=(tbl_info.c.uid == users_row.uid))
- rows = conn.execute(q).fetchall()
- for row in rows:
- usdict[row.attr_type] = row.attr_data
-
- # add the users_row data *after* the attributes in case attr_type
- # matches one of these keys.
- usdict['uid'] = users_row.uid
- usdict['identifier'] = users_row.identifier
- usdict['bb_username'] = users_row.bb_username
- usdict['bb_password'] = users_row.bb_password
-
- return usdict
- d = self.db.pool.do(thd)
- return d
-
- def getUsers(self):
- def thd(conn):
- tbl = self.db.model.users
- rows = conn.execute(tbl.select()).fetchall()
-
- dicts = []
- if rows:
- for row in rows:
- ud = dict(uid=row.uid, identifier=row.identifier)
- dicts.append(ud)
- return dicts
- d = self.db.pool.do(thd)
- return d
-
- def updateUser(self, uid=None, identifier=None, bb_username=None,
- bb_password=None, attr_type=None, attr_data=None,
- _race_hook=None):
- def thd(conn):
- transaction = conn.begin()
- tbl = self.db.model.users
- tbl_info = self.db.model.users_info
- update_dict = {}
-
- # first, add the identifier is it exists
- if identifier is not None:
- self.check_length(tbl.c.identifier, identifier)
- update_dict['identifier'] = identifier
-
- # then, add the creds if they exist
- if bb_username is not None:
- assert bb_password is not None
- self.check_length(tbl.c.bb_username, bb_username)
- self.check_length(tbl.c.bb_password, bb_password)
- update_dict['bb_username'] = bb_username
- update_dict['bb_password'] = bb_password
-
- # update the users table if it needs to be updated
- if update_dict:
- q = tbl.update(whereclause=(tbl.c.uid == uid))
- res = conn.execute(q, update_dict)
-
- # then, update the attributes, carefully handling the potential
- # update-or-insert race condition.
- if attr_type is not None:
- assert attr_data is not None
-
- self.check_length(tbl_info.c.attr_type, attr_type)
- self.check_length(tbl_info.c.attr_data, attr_data)
-
- # first update, then insert
- q = tbl_info.update(
- whereclause=(tbl_info.c.uid == uid)
- & (tbl_info.c.attr_type == attr_type))
- res = conn.execute(q, attr_data=attr_data)
- if res.rowcount == 0:
- _race_hook and _race_hook(conn)
-
- # the update hit 0 rows, so try inserting a new one
- try:
- q = tbl_info.insert()
- res = conn.execute(q,
- uid=uid,
- attr_type=attr_type,
- attr_data=attr_data)
- except (sa.exc.IntegrityError, sa.exc.ProgrammingError):
- # someone else beat us to the punch inserting this row;
- # let them win.
- transaction.rollback()
- return
-
- transaction.commit()
- d = self.db.pool.do(thd)
- return d
-
- def removeUser(self, uid):
- def thd(conn):
- # delete from dependent tables first, followed by 'users'
- for tbl in [
- self.db.model.change_users,
- self.db.model.users_info,
- self.db.model.users,
- ]:
- conn.execute(tbl.delete(whereclause=(tbl.c.uid==uid)))
- d = self.db.pool.do(thd)
- return d
-
- def identifierToUid(self, identifier):
- def thd(conn):
- tbl = self.db.model.users
-
- q = tbl.select(whereclause=(tbl.c.identifier == identifier))
- row = conn.execute(q).fetchone()
- if not row:
- return None
-
- return row.uid
- d = self.db.pool.do(thd)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/ec2buildslave.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/ec2buildslave.py
deleted file mode 100644
index 085cb3dd..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/ec2buildslave.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# 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
-
-from twisted.python.deprecate import deprecatedModuleAttribute
-from twisted.python.versions import Version
-
-from buildbot.buildslave.libvirt import (
- EC2LatentBuildSlave)
-
-deprecatedModuleAttribute(Version("Buildbot", 0, 8, 8),
- "It has been moved to buildbot.buildslave.ec2",
- "buildbot.libvirtbuildslave", "EC2LatentBuildSlave")
-
-_hush_pyflakes = [
- EC2LatentBuildSlave]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/interfaces.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/interfaces.py
deleted file mode 100644
index ecbf6a4a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/interfaces.py
+++ /dev/null
@@ -1,1216 +0,0 @@
-# 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
-
-"""Interface documentation.
-
-Define the interfaces that are implemented by various buildbot classes.
-"""
-# E0211: Method has no argument
-# E0213: Method should have "self" as first argument
-# pylint: disable-msg=E0211,E0213
-
-from zope.interface import Interface, Attribute
-
-# exceptions that can be raised while trying to start a build
-class NoSlaveError(Exception):
- pass
-class BuilderInUseError(Exception):
- pass
-class BuildSlaveTooOldError(Exception):
- pass
-class LatentBuildSlaveFailedToSubstantiate(Exception):
- pass
-
-class IChangeSource(Interface):
- """
- Service which feeds Change objects to the changemaster. When files or
- directories are changed in version control, this object should represent
- the changes as a change dictionary and call::
-
- self.master.addChange(who=.., rev=.., ..)
-
- See 'Writing Change Sources' in the manual for more information.
- """
- master = Attribute('master',
- 'Pointer to BuildMaster, automatically set when started.')
-
- def describe():
- """Return a string which briefly describes this source."""
-
-class ISourceStamp(Interface):
- """
- @cvar branch: branch from which source was drawn
- @type branch: string or None
-
- @cvar revision: revision of the source, or None to use CHANGES
- @type revision: varies depending on VC
-
- @cvar patch: patch applied to the source, or None if no patch
- @type patch: None or tuple (level diff)
-
- @cvar changes: the source step should check out the latest revision
- in the given changes
- @type changes: tuple of L{buildbot.changes.changes.Change} instances,
- all of which are on the same branch
-
- @cvar project: project this source code represents
- @type project: string
-
- @cvar repository: repository from which source was drawn
- @type repository: string
- """
-
- def canBeMergedWith(self, other):
- """
- Can this SourceStamp be merged with OTHER?
- """
-
- def mergeWith(self, others):
- """Generate a SourceStamp for the merger of me and all the other
- SourceStamps. This is called by a Build when it starts, to figure
- out what its sourceStamp should be."""
-
- def getAbsoluteSourceStamp(self, got_revision):
- """Get a new SourceStamp object reflecting the actual revision found
- by a Source step."""
-
- def getText(self):
- """Returns a list of strings to describe the stamp. These are
- intended to be displayed in a narrow column. If more space is
- available, the caller should join them together with spaces before
- presenting them to the user."""
-
-class IEmailSender(Interface):
- """I know how to send email, and can be used by other parts of the
- Buildbot to contact developers."""
- pass
-
-class IEmailLookup(Interface):
- def getAddress(user):
- """Turn a User-name string into a valid email address. Either return
- a string (with an @ in it), None (to indicate that the user cannot
- be reached by email), or a Deferred which will fire with the same."""
-
-class IStatus(Interface):
- """I am an object, obtainable from the buildmaster, which can provide
- status information."""
-
- def getTitle():
- """Return the name of the project that this Buildbot is working
- for."""
- def getTitleURL():
- """Return the URL of this Buildbot's project."""
- def getBuildbotURL():
- """Return the URL of the top-most Buildbot status page, or None if
- this Buildbot does not provide a web status page."""
- def getURLForThing(thing):
- """Return the URL of a page which provides information on 'thing',
- which should be an object that implements one of the status
- interfaces defined in L{buildbot.interfaces}. Returns None if no
- suitable page is available (or if no Waterfall is running)."""
-
- def getChangeSources():
- """Return a list of IChangeSource objects."""
-
- def getChange(number):
- """Return an IChange object."""
-
- def getSchedulers():
- """Return a list of ISchedulerStatus objects for all
- currently-registered Schedulers."""
-
- def getBuilderNames(categories=None):
- """Return a list of the names of all current Builders."""
- def getBuilder(name):
- """Return the IBuilderStatus object for a given named Builder. Raises
- KeyError if there is no Builder by that name."""
-
- def getSlaveNames():
- """Return a list of buildslave names, suitable for passing to
- getSlave()."""
- def getSlave(name):
- """Return the ISlaveStatus object for a given named buildslave."""
-
- def getBuildSets():
- """
- Return a list of un-completed build sets.
-
- @returns: list of L{IBuildSetStatus} implementations, via Deferred.
- """
-
- def generateFinishedBuilds(builders=[], branches=[],
- num_builds=None, finished_before=None,
- max_search=200):
- """Return a generator that will produce IBuildStatus objects each
- time you invoke its .next() method, starting with the most recent
- finished build and working backwards.
-
- @param builders: this is a list of Builder names, and the generator
- will only produce builds that ran on the given
- Builders. If the list is empty, produce builds from
- all Builders.
-
- @param branches: this is a list of branch names, and the generator
- will only produce builds that used the given
- branches. If the list is empty, produce builds from
- all branches.
-
- @param num_builds: the generator will stop after providing this many
- builds. The default of None means to produce as
- many builds as possible.
-
- @type finished_before: int: a timestamp, seconds since the epoch
- @param finished_before: if provided, do not produce any builds that
- finished after the given timestamp.
-
- @type max_search: int
- @param max_search: this method may have to examine a lot of builds
- to find some that match the search parameters,
- especially if there aren't any matching builds.
- This argument imposes a hard limit on the number
- of builds that will be examined within any given
- Builder.
- """
-
- def subscribe(receiver):
- """Register an IStatusReceiver to receive new status events. The
- receiver will immediately be sent a set of 'builderAdded' messages
- for all current builders. It will receive further 'builderAdded' and
- 'builderRemoved' messages as the config file is reloaded and builders
- come and go. It will also receive 'buildsetSubmitted' messages for
- all outstanding BuildSets (and each new BuildSet that gets
- submitted). No additional messages will be sent unless the receiver
- asks for them by calling .subscribe on the IBuilderStatus objects
- which accompany the addedBuilder message."""
-
- def unsubscribe(receiver):
- """Unregister an IStatusReceiver. No further status messgaes will be
- delivered."""
-
-class IBuildSetStatus(Interface):
- """I represent a set of Builds, each run on a separate Builder but all
- using the same source tree."""
-
- def getReason():
- pass
- def getID():
- """Return the BuildSet's ID string, if any. The 'try' feature uses a
- random string as a BuildSetID to relate submitted jobs with the
- resulting BuildSet."""
- def getResponsibleUsers():
- pass # not implemented
- def getInterestedUsers():
- pass # not implemented
- def getBuilderNames():
- """Return a list of the names of all Builders on which this set will
- do builds.
-
- @returns: list of names via Deferred"""
- def isFinished():
- pass
- def waitUntilFinished():
- """Return a Deferred that fires (with this IBuildSetStatus object)
- when all builds have finished."""
- def getResults():
- """Return SUCCESS/FAILURE, or None if the buildset is not finished
- yet"""
-
-
-class IBuildRequestStatus(Interface):
- """I represent a request to build a particular set of source code on a
- particular Builder. These requests may be merged by the time they are
- finally turned into a Build."""
-
- def getSourceStamp():
- """
- Get a SourceStamp object which can be used to re-create the source tree
- that this build used. This method will return an absolute SourceStamp
- if possible, and its results may change as the build progresses.
- Specifically, a "HEAD" build may later be more accurately specified by
- an absolute SourceStamp with the specific revision information.
-
- This method will return None if the source information is no longer
- available.
-
- @returns: SourceStamp via Deferred
- """
-
- def getBuilds():
- """Return a list of IBuildStatus objects for each Build that has been
- started in an attempt to satify this BuildRequest."""
-
- def subscribe(observer):
- """Register a callable that will be invoked (with a single
- IBuildStatus object) for each Build that is created to satisfy this
- request. There may be multiple Builds created in an attempt to handle
- the request: they may be interrupted by the user or abandoned due to
- a lost slave. The last Build (the one which actually gets to run to
- completion) is said to 'satisfy' the BuildRequest. The observer will
- be called once for each of these Builds, both old and new."""
- def unsubscribe(observer):
- """Unregister the callable that was registered with subscribe()."""
- def getSubmitTime():
- """Return the time when this request was submitted. Returns a
- Deferred."""
-
-
-class ISlaveStatus(Interface):
- def getName():
- """Return the name of the build slave."""
-
- def getAdmin():
- """Return a string with the slave admin's contact data."""
-
- def getHost():
- """Return a string with the slave host info."""
-
- def isConnected():
- """Return True if the slave is currently online, False if not."""
-
- def lastMessageReceived():
- """Return a timestamp (seconds since epoch) indicating when the most
- recent message was received from the buildslave."""
-
-class ISchedulerStatus(Interface):
- def getName():
- """Return the name of this Scheduler (a string)."""
-
- def getPendingBuildsets():
- """Return an IBuildSet for all BuildSets that are pending. These
- BuildSets are waiting for their tree-stable-timers to expire."""
- # TODO: this is not implemented anywhere
-
-
-class IBuilderStatus(Interface):
- def getName():
- """Return the name of this Builder (a string)."""
-
- def getCategory():
- """Return the category of this builder (a string)."""
-
- def getDescription():
- """Return the description of this builder (a string)."""
-
- def getState():
- # TODO: this isn't nearly as meaningful as it used to be
- """Return a tuple (state, builds) for this Builder. 'state' is the
- so-called 'big-status', indicating overall status (as opposed to
- which step is currently running). It is a string, one of 'offline',
- 'idle', or 'building'. 'builds' is a list of IBuildStatus objects
- (possibly empty) representing the currently active builds."""
-
- def getSlaves():
- """Return a list of ISlaveStatus objects for the buildslaves that are
- used by this builder."""
-
- def getPendingBuildRequestStatuses():
- """
- Get a L{IBuildRequestStatus} implementations for all unclaimed build
- requests.
-
- @returns: list of objects via Deferred
- """
-
- def getCurrentBuilds():
- """Return a list containing an IBuildStatus object for each build
- currently in progress."""
- # again, we could probably provide an object for 'waiting' and
- # 'interlocked' too, but things like the Change list might still be
- # subject to change
-
- def getLastFinishedBuild():
- """Return the IBuildStatus object representing the last finished
- build, which may be None if the builder has not yet finished any
- builds."""
-
- def getBuild(number):
- """Return an IBuildStatus object for a historical build. Each build
- is numbered (starting at 0 when the Builder is first added),
- getBuild(n) will retrieve the Nth such build. getBuild(-n) will
- retrieve a recent build, with -1 being the most recent build
- started. If the Builder is idle, this will be the same as
- getLastFinishedBuild(). If the Builder is active, it will be an
- unfinished build. This method will return None if the build is no
- longer available. Older builds are likely to have less information
- stored: Logs are the first to go, then Steps."""
-
- def getEvent(number):
- """Return an IStatusEvent object for a recent Event. Builders
- connecting and disconnecting are events, as are ping attempts.
- getEvent(-1) will return the most recent event. Events are numbered,
- but it probably doesn't make sense to ever do getEvent(+n)."""
-
- def generateFinishedBuilds(branches=[],
- num_builds=None,
- max_buildnum=None, finished_before=None,
- max_search=200,
- ):
- """Return a generator that will produce IBuildStatus objects each
- time you invoke its .next() method, starting with the most recent
- finished build, then the previous build, and so on back to the oldest
- build available.
-
- @param branches: this is a list of branch names, and the generator
- will only produce builds that involve the given
- branches. If the list is empty, the generator will
- produce all builds regardless of what branch they
- used.
-
- @param num_builds: if provided, the generator will stop after
- providing this many builds. The default of None
- means to produce as many builds as possible.
-
- @param max_buildnum: if provided, the generator will start by
- providing the build with this number, or the
- highest-numbered preceding build (i.e. the
- generator will not produce any build numbered
- *higher* than max_buildnum). The default of None
- means to start with the most recent finished
- build. -1 means the same as None. -2 means to
- start with the next-most-recent completed build,
- etc.
-
- @type finished_before: int: a timestamp, seconds since the epoch
- @param finished_before: if provided, do not produce any builds that
- finished after the given timestamp.
-
- @type max_search: int
- @param max_search: this method may have to examine a lot of builds
- to find some that match the search parameters,
- especially if there aren't any matching builds.
- This argument imposes a hard limit on the number
- of builds that will be examined.
- """
-
- def subscribe(receiver):
- """Register an IStatusReceiver to receive new status events. The
- receiver will be given builderChangedState, buildStarted, and
- buildFinished messages."""
-
- def unsubscribe(receiver):
- """Unregister an IStatusReceiver. No further status messgaes will be
- delivered."""
-
-class IEventSource(Interface):
- def eventGenerator(branches=[], categories=[], committers=[], minTime=0):
- """This function creates a generator which will yield all of this
- object's status events, starting with the most recent and progressing
- backwards in time. These events provide the IStatusEvent interface.
- At the moment they are all instances of buildbot.status.builder.Event
- or buildbot.status.builder.BuildStepStatus .
-
- @param branches: a list of branch names. The generator should only
- return events that are associated with these branches. If the list is
- empty, events for all branches should be returned (i.e. an empty list
- means 'accept all' rather than 'accept none').
-
- @param categories: a list of category names. The generator
- should only return events that are categorized within the
- given category. If the list is empty, events for all
- categories should be returned.
-
- @param comitters: a list of committers. The generator should only
- return events caused by one of the listed committers. If the list is
- empty or None, events from every committers should be returned.
-
- @param minTime: a timestamp. Do not generate events occuring prior to
- this timestamp.
- """
-
-class IBuildStatus(Interface):
- """I represent the status of a single Build/BuildRequest. It could be
- in-progress or finished."""
-
- def getBuilder():
- """
- Return the BuilderStatus that owns this build.
-
- @rtype: implementor of L{IBuilderStatus}
- """
-
- def isFinished():
- """Return a boolean. True means the build has finished, False means
- it is still running."""
-
- def waitUntilFinished():
- """Return a Deferred that will fire when the build finishes. If the
- build has already finished, this deferred will fire right away. The
- callback is given this IBuildStatus instance as an argument."""
-
- def getReason():
- """Return a string that indicates why the build was run. 'changes',
- 'forced', and 'periodic' are the most likely values. 'try' will be
- added in the future."""
-
- def getSourceStamps():
- """Return a list of SourceStamp objects which can be used to re-create
- the source tree that this build used.
-
- This method will return None if the source information is no longer
- available."""
- # TODO: it should be possible to expire the patch but still remember
- # that the build was r123+something.
-
- def getChanges():
- """Return a list of Change objects which represent which source
- changes went into the build."""
-
- def getRevisions():
- """Returns a string representing the list of revisions that led to
- the build, rendered from each Change.revision"""
-
- def getResponsibleUsers():
- """Return a list of Users who are to blame for the changes that went
- into this build. If anything breaks (at least anything that wasn't
- already broken), blame them. Specifically, this is the set of users
- who were responsible for the Changes that went into this build. Each
- User is a string, corresponding to their name as known by the VC
- repository."""
-
- def getInterestedUsers():
- """Return a list of Users who will want to know about the results of
- this build but who did not actually make the Changes that went into it
- (build sheriffs, code-domain owners)."""
-
- def getNumber():
- """Within each builder, each Build has a number. Return it."""
-
- def getPreviousBuild():
- """Convenience method. Returns None if the previous build is
- unavailable."""
-
- def getSteps():
- """Return a list of IBuildStepStatus objects. For invariant builds
- (those which always use the same set of Steps), this should always
- return the complete list, however some of the steps may not have
- started yet (step.getTimes()[0] will be None). For variant builds,
- this may not be complete (asking again later may give you more of
- them)."""
-
- def getTimes():
- """Returns a tuple of (start, end). 'start' and 'end' are the times
- (seconds since the epoch) when the Build started and finished. If
- the build is still running, 'end' will be None."""
-
- # while the build is running, the following methods make sense.
- # Afterwards they return None
-
- def getETA():
- """Returns the number of seconds from now in which the build is
- expected to finish, or None if we can't make a guess. This guess will
- be refined over time."""
-
- def getCurrentStep():
- """Return an IBuildStepStatus object representing the currently
- active step."""
-
- # Once you know the build has finished, the following methods are legal.
- # Before ths build has finished, they all return None.
-
- def getSlavename():
- """Return the name of the buildslave which handled this build."""
-
- def getText():
- """Returns a list of strings to describe the build. These are
- intended to be displayed in a narrow column. If more space is
- available, the caller should join them together with spaces before
- presenting them to the user."""
-
- def getResults():
- """Return a constant describing the results of the build: one of the
- constants in buildbot.status.builder: SUCCESS, WARNINGS,
- FAILURE, SKIPPED or EXCEPTION."""
-
- def getLogs():
- """Return a list of logs that describe the build as a whole. Some
- steps will contribute their logs, while others are are less important
- and will only be accessible through the IBuildStepStatus objects.
- Each log is an object which implements the IStatusLog interface."""
-
- def getTestResults():
- """Return a dictionary that maps test-name tuples to ITestResult
- objects. This may return an empty or partially-filled dictionary
- until the build has completed."""
-
- # subscription interface
-
- def subscribe(receiver, updateInterval=None):
- """Register an IStatusReceiver to receive new status events. The
- receiver will be given stepStarted and stepFinished messages. If
- 'updateInterval' is non-None, buildETAUpdate messages will be sent
- every 'updateInterval' seconds."""
-
- def unsubscribe(receiver):
- """Unregister an IStatusReceiver. No further status messgaes will be
- delivered."""
-
-class ITestResult(Interface):
- """I describe the results of a single unit test."""
-
- def getName():
- """Returns a tuple of strings which make up the test name. Tests may
- be arranged in a hierarchy, so looking for common prefixes may be
- useful."""
-
- def getResults():
- """Returns a constant describing the results of the test: SUCCESS,
- WARNINGS, FAILURE."""
-
- def getText():
- """Returns a list of short strings which describe the results of the
- test in slightly more detail. Suggested components include
- 'failure', 'error', 'passed', 'timeout'."""
-
- def getLogs():
- # in flux, it may be possible to provide more structured information
- # like python Failure instances
- """Returns a dictionary of test logs. The keys are strings like
- 'stdout', 'log', 'exceptions'. The values are strings."""
-
-
-class IBuildStepStatus(Interface):
- """I hold status for a single BuildStep."""
-
- def getName():
- """Returns a short string with the name of this step. This string
- may have spaces in it."""
-
- def getBuild():
- """Returns the IBuildStatus object which contains this step."""
-
- def getTimes():
- """Returns a tuple of (start, end). 'start' and 'end' are the times
- (seconds since the epoch) when the Step started and finished. If the
- step has not yet started, 'start' will be None. If the step is still
- running, 'end' will be None."""
-
- def getExpectations():
- """Returns a list of tuples (name, current, target). Each tuple
- describes a single axis along which the step's progress can be
- measured. 'name' is a string which describes the axis itself, like
- 'filesCompiled' or 'tests run' or 'bytes of output'. 'current' is a
- number with the progress made so far, while 'target' is the value
- that we expect (based upon past experience) to get to when the build
- is finished.
-
- 'current' will change over time until the step is finished. It is
- 'None' until the step starts. When the build is finished, 'current'
- may or may not equal 'target' (which is merely the expectation based
- upon previous builds)."""
-
- def getURLs():
- """Returns a dictionary of URLs. Each key is a link name (a short
- string, like 'results' or 'coverage'), and each value is a URL. These
- links will be displayed along with the LogFiles.
- """
-
- def getLogs():
- """Returns a list of IStatusLog objects. If the step has not yet
- finished, this list may be incomplete (asking again later may give
- you more of them)."""
-
-
- def isFinished():
- """Return a boolean. True means the step has finished, False means it
- is still running."""
-
- def waitUntilFinished():
- """Return a Deferred that will fire when the step finishes. If the
- step has already finished, this deferred will fire right away. The
- callback is given this IBuildStepStatus instance as an argument."""
-
- # while the step is running, the following methods make sense.
- # Afterwards they return None
-
- def getETA():
- """Returns the number of seconds from now in which the step is
- expected to finish, or None if we can't make a guess. This guess will
- be refined over time."""
-
- # Once you know the step has finished, the following methods are legal.
- # Before ths step has finished, they all return None.
-
- def getText():
- """Returns a list of strings which describe the step. These are
- intended to be displayed in a narrow column. If more space is
- available, the caller should join them together with spaces before
- presenting them to the user."""
-
- def getResults():
- """Return a tuple describing the results of the step: (result,
- strings). 'result' is one of the constants in
- buildbot.status.builder: SUCCESS, WARNINGS, FAILURE, or SKIPPED.
- 'strings' is an optional list of strings that the step wants to
- append to the overall build's results. These strings are usually
- more terse than the ones returned by getText(): in particular,
- successful Steps do not usually contribute any text to the overall
- build."""
-
- # subscription interface
-
- def subscribe(receiver, updateInterval=10):
- """Register an IStatusReceiver to receive new status events. The
- receiver will be given logStarted and logFinished messages. It will
- also be given a ETAUpdate message every 'updateInterval' seconds."""
-
- def unsubscribe(receiver):
- """Unregister an IStatusReceiver. No further status messgaes will be
- delivered."""
-
-class IStatusEvent(Interface):
- """I represent a Builder Event, something non-Build related that can
- happen to a Builder."""
-
- def getTimes():
- """Returns a tuple of (start, end) like IBuildStepStatus, but end==0
- indicates that this is a 'point event', which has no duration.
- SlaveConnect/Disconnect are point events. Ping is not: it starts
- when requested and ends when the response (positive or negative) is
- returned"""
-
- def getText():
- """Returns a list of strings which describe the event. These are
- intended to be displayed in a narrow column. If more space is
- available, the caller should join them together with spaces before
- presenting them to the user."""
-
-
-LOG_CHANNEL_STDOUT = 0
-LOG_CHANNEL_STDERR = 1
-LOG_CHANNEL_HEADER = 2
-
-class IStatusLog(Interface):
- """I represent a single Log, which is a growing list of text items that
- contains some kind of output for a single BuildStep. I might be finished,
- in which case this list has stopped growing.
-
- Each Log has a name, usually something boring like 'log' or 'output'.
- These names are not guaranteed to be unique, however they are usually
- chosen to be useful within the scope of a single step (i.e. the Compile
- step might produce both 'log' and 'warnings'). The name may also have
- spaces. If you want something more globally meaningful, at least within a
- given Build, try::
-
- '%s.%s' % (log.getStep.getName(), log.getName())
-
- The Log can be presented as plain text, or it can be accessed as a list
- of items, each of which has a channel indicator (header, stdout, stderr)
- and a text chunk. An HTML display might represent the interleaved
- channels with different styles, while a straight download-the-text
- interface would just want to retrieve a big string.
-
- The 'header' channel is used by ShellCommands to prepend a note about
- which command is about to be run ('running command FOO in directory
- DIR'), and append another note giving the exit code of the process.
-
- Logs can be streaming: if the Log has not yet finished, you can
- subscribe to receive new chunks as they are added.
-
- A ShellCommand will have a Log associated with it that gathers stdout
- and stderr. Logs may also be created by parsing command output or
- through other synthetic means (grepping for all the warnings in a
- compile log, or listing all the test cases that are going to be run).
- Such synthetic Logs are usually finished as soon as they are created."""
-
-
- def getName():
- """Returns a short string with the name of this log, probably 'log'.
- """
-
- def getStep():
- """Returns the IBuildStepStatus which owns this log."""
- # TODO: can there be non-Step logs?
-
- def isFinished():
- """Return a boolean. True means the log has finished and is closed,
- False means it is still open and new chunks may be added to it."""
-
- def waitUntilFinished():
- """Return a Deferred that will fire when the log is closed. If the
- log has already finished, this deferred will fire right away. The
- callback is given this IStatusLog instance as an argument."""
-
- def subscribe(receiver, catchup):
- """Register an IStatusReceiver to receive chunks (with logChunk) as
- data is added to the Log. If you use this, you will also want to use
- waitUntilFinished to find out when the listener can be retired.
- Subscribing to a closed Log is a no-op.
-
- If 'catchup' is True, the receiver will immediately be sent a series
- of logChunk messages to bring it up to date with the partially-filled
- log. This allows a status client to join a Log already in progress
- without missing any data. If the Log has already finished, it is too
- late to catch up: just do getText() instead.
-
- If the Log is very large, the receiver will be called many times with
- a lot of data. There is no way to throttle this data. If the receiver
- is planning on sending the data on to somewhere else, over a narrow
- connection, you can get a throttleable subscription by using
- C{subscribeConsumer} instead."""
-
- def unsubscribe(receiver):
- """Remove a receiver previously registered with subscribe(). Attempts
- to remove a receiver which was not previously registered is a no-op.
- """
-
- def subscribeConsumer(consumer):
- """Register an L{IStatusLogConsumer} to receive all chunks of the
- logfile, including all the old entries and any that will arrive in
- the future. The consumer will first have their C{registerProducer}
- method invoked with a reference to an object that can be told
- C{pauseProducing}, C{resumeProducing}, and C{stopProducing}. Then the
- consumer's C{writeChunk} method will be called repeatedly with each
- (channel, text) tuple in the log, starting with the very first. The
- consumer will be notified with C{finish} when the log has been
- exhausted (which can only happen when the log is finished). Note that
- a small amount of data could be written via C{writeChunk} even after
- C{pauseProducing} has been called.
-
- To unsubscribe the consumer, use C{producer.stopProducing}."""
-
- # once the log has finished, the following methods make sense. They can
- # be called earlier, but they will only return the contents of the log up
- # to the point at which they were called. You will lose items that are
- # added later. Use C{subscribe} or C{subscribeConsumer} to avoid missing
- # anything.
-
- def hasContents():
- """Returns True if the LogFile still has contents available. Returns
- False for logs that have been pruned. Clients should test this before
- offering to show the contents of any log."""
-
- def getText():
- """Return one big string with the contents of the Log. This merges
- all non-header chunks together."""
-
- def readlines(channel=LOG_CHANNEL_STDOUT):
- """Read lines from one channel of the logfile. This returns an
- iterator that will provide single lines of text (including the
- trailing newline).
- """
-
- def getTextWithHeaders():
- """Return one big string with the contents of the Log. This merges
- all chunks (including headers) together."""
-
- def getChunks():
- """Generate a list of (channel, text) tuples. 'channel' is a number,
- 0 for stdout, 1 for stderr, 2 for header. (note that stderr is merged
- into stdout if PTYs are in use)."""
-
-class IStatusLogConsumer(Interface):
- """I am an object which can be passed to IStatusLog.subscribeConsumer().
- I represent a target for writing the contents of an IStatusLog. This
- differs from a regular IStatusReceiver in that it can pause the producer.
- This makes it more suitable for use in streaming data over network
- sockets, such as an HTTP request. Note that the consumer can only pause
- the producer until it has caught up with all the old data. After that
- point, C{pauseProducing} is ignored and all new output from the log is
- sent directoy to the consumer."""
-
- def registerProducer(producer, streaming):
- """A producer is being hooked up to this consumer. The consumer only
- has to handle a single producer. It should send .pauseProducing and
- .resumeProducing messages to the producer when it wants to stop or
- resume the flow of data. 'streaming' will be set to True because the
- producer is always a PushProducer.
- """
-
- def unregisterProducer():
- """The previously-registered producer has been removed. No further
- pauseProducing or resumeProducing calls should be made. The consumer
- should delete its reference to the Producer so it can be released."""
-
- def writeChunk(chunk):
- """A chunk (i.e. a tuple of (channel, text)) is being written to the
- consumer."""
-
- def finish():
- """The log has finished sending chunks to the consumer."""
-
-class IStatusReceiver(Interface):
- """I am an object which can receive build status updates. I may be
- subscribed to an IStatus, an IBuilderStatus, or an IBuildStatus."""
-
- def buildsetSubmitted(buildset):
- """A new BuildSet has been submitted to the buildmaster.
-
- @type buildset: implementor of L{IBuildSetStatus}
- """
-
- def requestSubmitted(request):
- """A new BuildRequest has been submitted to the buildmaster.
-
- @type request: implementor of L{IBuildRequestStatus}
- """
-
- def requestCancelled(builder, request):
- """A BuildRequest has been cancelled on the given Builder.
-
- @type builder: L{buildbot.status.builder.BuilderStatus}
- @type request: implementor of L{IBuildRequestStatus}
- """
-
- def builderAdded(builderName, builder):
- """
- A new Builder has just been added. This method may return an
- IStatusReceiver (probably 'self') which will be subscribed to receive
- builderChangedState and buildStarted/Finished events.
-
- @type builderName: string
- @type builder: L{buildbot.status.builder.BuilderStatus}
- @rtype: implementor of L{IStatusReceiver}
- """
-
- def builderChangedState(builderName, state):
- """Builder 'builderName' has changed state. The possible values for
- 'state' are 'offline', 'idle', and 'building'."""
-
- def buildStarted(builderName, build):
- """Builder 'builderName' has just started a build. The build is an
- object which implements IBuildStatus, and can be queried for more
- information.
-
- This method may return an IStatusReceiver (it could even return
- 'self'). If it does so, stepStarted and stepFinished methods will be
- invoked on the object for the steps of this one build. This is a
- convenient way to subscribe to all build steps without missing any.
- This receiver will automatically be unsubscribed when the build
- finishes.
-
- It can also return a tuple of (IStatusReceiver, interval), in which
- case buildETAUpdate messages are sent ever 'interval' seconds, in
- addition to the stepStarted and stepFinished messages."""
-
- def buildETAUpdate(build, ETA):
- """This is a periodic update on the progress this Build has made
- towards completion."""
-
- def changeAdded(change):
- """A new Change was added to the ChangeMaster. By the time this event
- is received, all schedulers have already received the change."""
-
- def stepStarted(build, step):
- """A step has just started. 'step' is the IBuildStepStatus which
- represents the step: it can be queried for more information.
-
- This method may return an IStatusReceiver (it could even return
- 'self'). If it does so, logStarted and logFinished methods will be
- invoked on the object for logs created by this one step. This
- receiver will be automatically unsubscribed when the step finishes.
-
- Alternatively, the method may return a tuple of an IStatusReceiver
- and an integer named 'updateInterval'. In addition to
- logStarted/logFinished messages, it will also receive stepETAUpdate
- messages about every updateInterval seconds."""
-
- def stepTextChanged(build, step, text):
- """The text for a step has been updated.
-
- This is called when calling setText() on the step status, and
- hands in the text list."""
-
- def stepText2Changed(build, step, text2):
- """The text2 for a step has been updated.
-
- This is called when calling setText2() on the step status, and
- hands in text2 list."""
-
- def stepETAUpdate(build, step, ETA, expectations):
- """This is a periodic update on the progress this Step has made
- towards completion. It gets an ETA (in seconds from the present) of
- when the step ought to be complete, and a list of expectation tuples
- (as returned by IBuildStepStatus.getExpectations) with more detailed
- information."""
-
- def logStarted(build, step, log):
- """A new Log has been started, probably because a step has just
- started running a shell command. 'log' is the IStatusLog object
- which can be queried for more information.
-
- This method may return an IStatusReceiver (such as 'self'), in which
- case the target's logChunk method will be invoked as text is added to
- the logfile. This receiver will automatically be unsubsribed when the
- log finishes."""
-
- def logChunk(build, step, log, channel, text):
- """Some text has been added to this log. 'channel' is one of
- LOG_CHANNEL_STDOUT, LOG_CHANNEL_STDERR, or LOG_CHANNEL_HEADER, as
- defined in IStatusLog.getChunks."""
-
- def logFinished(build, step, log):
- """A Log has been closed."""
-
- def stepFinished(build, step, results):
- """A step has just finished. 'results' is the result tuple described
- in IBuildStepStatus.getResults."""
-
- def buildFinished(builderName, build, results):
- """
- A build has just finished. 'results' is the result tuple described
- in L{IBuildStatus.getResults}.
-
- @type builderName: string
- @type build: L{buildbot.status.build.BuildStatus}
- @type results: tuple
- """
-
- def builderRemoved(builderName):
- """The Builder has been removed."""
-
- def slaveConnected(slaveName):
- """The slave has connected."""
-
- def slaveDisconnected(slaveName):
- """The slave has disconnected."""
-
- def checkConfig(otherStatusReceivers):
- """Verify that there are no other status receivers which conflict with
- the current one.
-
- @type otherStatusReceivers: A list of L{IStatusReceiver} objects which
- will contain self.
- """
-
-
-class IControl(Interface):
- def addChange(change):
- """Add a change to the change queue, for analysis by schedulers."""
-
- def getBuilder(name):
- """Retrieve the IBuilderControl object for the given Builder."""
-
-class IBuilderControl(Interface):
- def submitBuildRequest(ss, reason, props=None):
- """Create a BuildRequest, which will eventually cause a build of the
- given SourceStamp to be run on this builder. This returns a
- BuildRequestStatus object via a Deferred, which can be used to keep
- track of the builds that are performed."""
-
- def rebuildBuild(buildStatus, reason="<rebuild, no reason given>"):
- """Rebuild something we've already built before. This submits a
- BuildRequest to our Builder using the same SourceStamp as the earlier
- build. This has no effect (but may eventually raise an exception) if
- this Build has not yet finished."""
-
- def getPendingBuildRequestControls():
- """
- Get a list of L{IBuildRequestControl} objects for this Builder.
- Each one corresponds to an unclaimed build request.
-
- @returns: list of objects via Deferred
- """
-
- def getBuild(number):
- """Attempt to return an IBuildControl object for the given build.
- Returns None if no such object is available. This will only work for
- the build that is currently in progress: once the build finishes,
- there is nothing to control anymore."""
-
- def ping():
- """Attempt to contact the slave and see if it is still alive. This
- returns a Deferred which fires with either True (the slave is still
- alive) or False (the slave did not respond). As a side effect, adds an
- event to this builder's column in the waterfall display containing the
- results of the ping. Note that this may not fail for a long time, it is
- implemented in terms of the timeout on the underlying TCP connection."""
- # TODO: this ought to live in ISlaveControl, maybe with disconnect()
- # or something. However the event that is emitted is most useful in
- # the Builder column, so it kinda fits here too.
-
-class IBuildRequestControl(Interface):
- def subscribe(observer):
- """Register a callable that will be invoked (with a single
- IBuildControl object) for each Build that is created to satisfy this
- request. There may be multiple Builds created in an attempt to handle
- the request: they may be interrupted by the user or abandoned due to
- a lost slave. The last Build (the one which actually gets to run to
- completion) is said to 'satisfy' the BuildRequest. The observer will
- be called once for each of these Builds, both old and new."""
- def unsubscribe(observer):
- """Unregister the callable that was registered with subscribe()."""
- def cancel():
- """Remove the build from the pending queue. Has no effect if the
- build has already been started."""
-
-class IBuildControl(Interface):
- def getStatus():
- """Return an IBuildStatus object for the Build that I control."""
- def stopBuild(reason="<no reason given>"):
- """Halt the build. This has no effect if the build has already
- finished."""
-
-class ILogFile(Interface):
- """This is the internal interface to a LogFile, used by the BuildStep to
- write data into the log.
- """
- def addStdout(data):
- pass
- def addStderr(data):
- pass
- def addHeader(data):
- pass
- def finish():
- """The process that is feeding the log file has finished, and no
- further data will be added. This closes the logfile."""
-
-class ILogObserver(Interface):
- """Objects which provide this interface can be used in a BuildStep to
- watch the output of a LogFile and parse it incrementally.
- """
-
- # internal methods
- def setStep(step):
- pass
- def setLog(log):
- pass
-
- # methods called by the LogFile
- def logChunk(build, step, log, channel, text):
- pass
-
-class IBuildSlave(Interface):
- # this is a marker interface for the BuildSlave class
- pass
-
-class ILatentBuildSlave(IBuildSlave):
- """A build slave that is not always running, but can run when requested.
- """
- substantiated = Attribute('Substantiated',
- 'Whether the latent build slave is currently '
- 'substantiated with a real instance.')
-
- def substantiate():
- """Request that the slave substantiate with a real instance.
-
- Returns a deferred that will callback when a real instance has
- attached."""
-
- # there is an insubstantiate too, but that is not used externally ATM.
-
- def buildStarted(sb):
- """Inform the latent build slave that a build has started.
-
- @param sb: a L{LatentSlaveBuilder}. The sb is the one for whom the
- build finished.
- """
-
- def buildFinished(sb):
- """Inform the latent build slave that a build has finished.
-
- @param sb: a L{LatentSlaveBuilder}. The sb is the one for whom the
- build finished.
- """
-
-class IRenderable(Interface):
- """An object that can be interpolated with properties from a build.
- """
-
- def getRenderingFor(iprops):
- """Return a deferred that fires with interpolation with the given properties
-
- @param iprops: the L{IProperties} provider supplying the properties.
- """
-class IProperties(Interface):
- """
- An object providing access to build properties
- """
-
- def getProperty(name, default=None):
- """Get the named property, returning the default if the property does
- not exist.
-
- @param name: property name
- @type name: string
-
- @param default: default value (default: @code{None})
-
- @returns: property value
- """
-
- def hasProperty(name):
- """Return true if the named property exists.
-
- @param name: property name
- @type name: string
- @returns: boolean
- """
-
- def has_key(name):
- """Deprecated name for L{hasProperty}."""
-
- def setProperty(name, value, source, runtime=False):
- """Set the given property, overwriting any existing value. The source
- describes the source of the value for human interpretation.
-
- @param name: property name
- @type name: string
-
- @param value: property value
- @type value: JSON-able value
-
- @param source: property source
- @type source: string
-
- @param runtime: (optional) whether this property was set during the
- build's runtime: usually left at its default value
- @type runtime: boolean
- """
-
- def getProperties():
- """Get the L{buildbot.process.properties.Properties} instance storing
- these properties. Note that the interface for this class is not
- stable, so where possible the other methods of this interface should be
- used.
-
- @returns: L{buildbot.process.properties.Properties} instance
- """
-
- def getBuild():
- """Get the L{buildbot.process.build.Build} instance for the current
- build. Note that this object is not available after the build is
- complete, at which point this method will return None.
-
- Try to avoid using this method, as the API of L{Build} instances is not
- well-defined.
-
- @returns L{buildbot.process.build.Build} instance
- """
-
- def render(value):
- """Render @code{value} as an L{IRenderable}. This essentially coerces
- @code{value} to an L{IRenderable} and calls its @L{getRenderingFor}
- method.
-
- @name value: value to render
- @returns: rendered value
- """
-
-class IScheduler(Interface):
- pass
-
-class ITriggerableScheduler(Interface):
- """
- A scheduler that can be triggered by buildsteps.
- """
-
- def trigger(sourcestamps, set_props=None):
- """Trigger a build with the given source stamp and properties.
- """
-
-class IBuildStepFactory(Interface):
- def buildStep():
- """
- """
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/libvirtbuildslave.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/libvirtbuildslave.py
deleted file mode 100644
index ab9b2730..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/libvirtbuildslave.py
+++ /dev/null
@@ -1,29 +0,0 @@
-
-# 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
-
-from twisted.python.deprecate import deprecatedModuleAttribute
-from twisted.python.versions import Version
-
-from buildbot.buildslave.libvirt import (
- LibVirtSlave, Domain, Connection)
-
-for _attr in ["LibVirtSlave", "Connection", "Domain"]:
- deprecatedModuleAttribute(Version("Buildbot", 0, 8, 8),
- "It has been moved to buildbot.buildslave.libvirt",
- "buildbot.libvirtbuildslave", _attr)
-
-_hush_pyflakes = [
- LibVirtSlave, Domain, Connection]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/locks.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/locks.py
deleted file mode 100644
index 0f6941d4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/locks.py
+++ /dev/null
@@ -1,310 +0,0 @@
-# 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
-
-
-from twisted.python import log
-from twisted.internet import defer
-from buildbot import util
-from buildbot.util import subscription
-from buildbot.util.eventual import eventually
-
-if False: # for debugging
- debuglog = log.msg
-else:
- debuglog = lambda m: None
-
-class BaseLock:
- """
- Class handling claiming and releasing of L{self}, and keeping track of
- current and waiting owners.
-
- We maintain the wait queue in FIFO order, and ensure that counting waiters
- in the queue behind exclusive waiters cannot acquire the lock. This ensures
- that exclusive waiters are not starved.
- """
- description = "<BaseLock>"
-
- def __init__(self, name, maxCount=1):
- self.name = name # Name of the lock
- self.waiting = [] # Current queue, tuples (waiter, LockAccess,
- # deferred)
- self.owners = [] # Current owners, tuples (owner, LockAccess)
- self.maxCount = maxCount # maximal number of counting owners
-
- # subscriptions to this lock being released
- self.release_subs = subscription.SubscriptionPoint("%r releases"
- % (self,))
-
- def __repr__(self):
- return self.description
-
- def _getOwnersCount(self):
- """ Return the number of current exclusive and counting owners.
-
- @return: Tuple (number exclusive owners, number counting owners)
- """
- num_excl, num_counting = 0, 0
- for owner in self.owners:
- if owner[1].mode == 'exclusive':
- num_excl = num_excl + 1
- else: # mode == 'counting'
- num_counting = num_counting + 1
-
- assert (num_excl == 1 and num_counting == 0) \
- or (num_excl == 0 and num_counting <= self.maxCount)
- return num_excl, num_counting
-
-
- def isAvailable(self, requester, access):
- """ Return a boolean whether the lock is available for claiming """
- debuglog("%s isAvailable(%s, %s): self.owners=%r"
- % (self, requester, access, self.owners))
- num_excl, num_counting = self._getOwnersCount()
-
- # Find all waiters ahead of the requester in the wait queue
- for idx, waiter in enumerate(self.waiting):
- if waiter[0] == requester:
- w_index = idx
- break
- else:
- w_index = len(self.waiting)
- ahead = self.waiting[:w_index]
-
- if access.mode == 'counting':
- # Wants counting access
- return num_excl == 0 and num_counting + len(ahead) < self.maxCount \
- and all([w[1].mode == 'counting' for w in ahead])
- else:
- # Wants exclusive access
- return num_excl == 0 and num_counting == 0 and len(ahead) == 0
-
- def claim(self, owner, access):
- """ Claim the lock (lock must be available) """
- debuglog("%s claim(%s, %s)" % (self, owner, access.mode))
- assert owner is not None
- assert self.isAvailable(owner, access), "ask for isAvailable() first"
-
- assert isinstance(access, LockAccess)
- assert access.mode in ['counting', 'exclusive']
- self.waiting = [w for w in self.waiting if w[0] != owner]
- self.owners.append((owner, access))
- debuglog(" %s is claimed '%s'" % (self, access.mode))
-
- def subscribeToReleases(self, callback):
- """Schedule C{callback} to be invoked every time this lock is
- released. Returns a L{Subscription}."""
- return self.release_subs.subscribe(callback)
-
- def release(self, owner, access):
- """ Release the lock """
- assert isinstance(access, LockAccess)
-
- debuglog("%s release(%s, %s)" % (self, owner, access.mode))
- entry = (owner, access)
- if not entry in self.owners:
- debuglog("%s already released" % self)
- return
- self.owners.remove(entry)
- # who can we wake up?
- # After an exclusive access, we may need to wake up several waiting.
- # Break out of the loop when the first waiting client should not be awakened.
- num_excl, num_counting = self._getOwnersCount()
- for i, (w_owner, w_access, d) in enumerate(self.waiting):
- if w_access.mode == 'counting':
- if num_excl > 0 or num_counting == self.maxCount:
- break
- else:
- num_counting = num_counting + 1
- else:
- # w_access.mode == 'exclusive'
- if num_excl > 0 or num_counting > 0:
- break
- else:
- num_excl = num_excl + 1
-
- # If the waiter has a deferred, wake it up and clear the deferred
- # from the wait queue entry to indicate that it has been woken.
- if d:
- self.waiting[i] = (w_owner, w_access, None)
- eventually(d.callback, self)
-
- # notify any listeners
- self.release_subs.deliver()
-
- def waitUntilMaybeAvailable(self, owner, access):
- """Fire when the lock *might* be available. The caller will need to
- check with isAvailable() when the deferred fires. This loose form is
- used to avoid deadlocks. If we were interested in a stronger form,
- this would be named 'waitUntilAvailable', and the deferred would fire
- after the lock had been claimed.
- """
- debuglog("%s waitUntilAvailable(%s)" % (self, owner))
- assert isinstance(access, LockAccess)
- if self.isAvailable(owner, access):
- return defer.succeed(self)
- d = defer.Deferred()
-
- # Are we already in the wait queue?
- w = [i for i, w in enumerate(self.waiting) if w[0] == owner]
- if w:
- self.waiting[w[0]] = (owner, access, d)
- else:
- self.waiting.append((owner, access, d))
- return d
-
- def stopWaitingUntilAvailable(self, owner, access, d):
- debuglog("%s stopWaitingUntilAvailable(%s)" % (self, owner))
- assert isinstance(access, LockAccess)
- assert (owner, access, d) in self.waiting
- self.waiting = [w for w in self.waiting if w[0] != owner]
-
- def isOwner(self, owner, access):
- return (owner, access) in self.owners
-
-
-class RealMasterLock(BaseLock):
- def __init__(self, lockid):
- BaseLock.__init__(self, lockid.name, lockid.maxCount)
- self.description = "<MasterLock(%s, %s)>" % (self.name, self.maxCount)
-
- def getLock(self, slave):
- return self
-
-class RealSlaveLock:
- def __init__(self, lockid):
- self.name = lockid.name
- self.maxCount = lockid.maxCount
- self.maxCountForSlave = lockid.maxCountForSlave
- self.description = "<SlaveLock(%s, %s, %s)>" % (self.name,
- self.maxCount,
- self.maxCountForSlave)
- self.locks = {}
-
- def __repr__(self):
- return self.description
-
- def getLock(self, slave):
- slavename = slave.slavename
- if not self.locks.has_key(slavename):
- maxCount = self.maxCountForSlave.get(slavename,
- self.maxCount)
- lock = self.locks[slavename] = BaseLock(self.name, maxCount)
- desc = "<SlaveLock(%s, %s)[%s] %d>" % (self.name, maxCount,
- slavename, id(lock))
- lock.description = desc
- self.locks[slavename] = lock
- return self.locks[slavename]
-
-
-class LockAccess(util.ComparableMixin):
- """ I am an object representing a way to access a lock.
-
- @param lockid: LockId instance that should be accessed.
- @type lockid: A MasterLock or SlaveLock instance.
-
- @param mode: Mode of accessing the lock.
- @type mode: A string, either 'counting' or 'exclusive'.
- """
-
- compare_attrs = ['lockid', 'mode']
- def __init__(self, lockid, mode, _skipChecks=False):
- self.lockid = lockid
- self.mode = mode
-
- if not _skipChecks:
- # these checks fail with mock < 0.8.0 when lockid is a Mock
- # TODO: remove this in Buildbot-0.9.0+
- assert isinstance(lockid, (MasterLock, SlaveLock))
- assert mode in ['counting', 'exclusive']
-
-
-class BaseLockId(util.ComparableMixin):
- """ Abstract base class for LockId classes.
-
- Sets up the 'access()' function for the LockId's available to the user
- (MasterLock and SlaveLock classes).
- Derived classes should add
- - Comparison with the L{util.ComparableMixin} via the L{compare_attrs}
- class variable.
- - Link to the actual lock class should be added with the L{lockClass}
- class variable.
- """
- def access(self, mode):
- """ Express how the lock should be accessed """
- assert mode in ['counting', 'exclusive']
- return LockAccess(self, mode)
-
- def defaultAccess(self):
- """ For buildbot 0.7.7 compability: When user doesn't specify an access
- mode, this one is chosen.
- """
- return self.access('counting')
-
-
-
-# master.cfg should only reference the following MasterLock and SlaveLock
-# classes. They are identifiers that will be turned into real Locks later,
-# via the BotMaster.getLockByID method.
-
-class MasterLock(BaseLockId):
- """I am a semaphore that limits the number of simultaneous actions.
-
- Builds and BuildSteps can declare that they wish to claim me as they run.
- Only a limited number of such builds or steps will be able to run
- simultaneously. By default this number is one, but my maxCount parameter
- can be raised to allow two or three or more operations to happen at the
- same time.
-
- Use this to protect a resource that is shared among all builders and all
- slaves, for example to limit the load on a common SVN repository.
- """
-
- compare_attrs = ['name', 'maxCount']
- lockClass = RealMasterLock
- def __init__(self, name, maxCount=1):
- self.name = name
- self.maxCount = maxCount
-
-class SlaveLock(BaseLockId):
- """I am a semaphore that limits simultaneous actions on each buildslave.
-
- Builds and BuildSteps can declare that they wish to claim me as they run.
- Only a limited number of such builds or steps will be able to run
- simultaneously on any given buildslave. By default this number is one,
- but my maxCount parameter can be raised to allow two or three or more
- operations to happen on a single buildslave at the same time.
-
- Use this to protect a resource that is shared among all the builds taking
- place on each slave, for example to limit CPU or memory load on an
- underpowered machine.
-
- Each buildslave will get an independent copy of this semaphore. By
- default each copy will use the same owner count (set with maxCount), but
- you can provide maxCountForSlave with a dictionary that maps slavename to
- owner count, to allow some slaves more parallelism than others.
-
- """
-
- compare_attrs = ['name', 'maxCount', '_maxCountForSlaveList']
- lockClass = RealSlaveLock
- def __init__(self, name, maxCount=1, maxCountForSlave={}):
- self.name = name
- self.maxCount = maxCount
- self.maxCountForSlave = maxCountForSlave
- # for comparison purposes, turn this dictionary into a stably-sorted
- # list of tuples
- self._maxCountForSlaveList = self.maxCountForSlave.items()
- self._maxCountForSlaveList.sort()
- self._maxCountForSlaveList = tuple(self._maxCountForSlaveList)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/manhole.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/manhole.py
deleted file mode 100644
index 2e20084b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/manhole.py
+++ /dev/null
@@ -1,323 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-
-import os
-import types
-import binascii
-import base64
-from twisted.python import log
-from twisted.application import service, strports
-from twisted.cred import checkers, portal
-from twisted.conch import manhole, telnet
-try:
- from twisted.conch import checkers as conchc, manhole_ssh
- _hush_pyflakes = [manhole_ssh, conchc]
- del _hush_pyflakes
-except ImportError:
- manhole_ssh = None
- conchc = None
-from twisted.conch.insults import insults
-from twisted.internet import protocol
-
-from buildbot import config
-from buildbot.util import ComparableMixin
-from zope.interface import implements # requires Twisted-2.0 or later
-
-# makeTelnetProtocol and _TelnetRealm are for the TelnetManhole
-
-class makeTelnetProtocol:
- # this curries the 'portal' argument into a later call to
- # TelnetTransport()
- def __init__(self, portal):
- self.portal = portal
-
- def __call__(self):
- auth = telnet.AuthenticatingTelnetProtocol
- return telnet.TelnetTransport(auth, self.portal)
-
-class _TelnetRealm:
- implements(portal.IRealm)
-
- def __init__(self, namespace_maker):
- self.namespace_maker = namespace_maker
-
- def requestAvatar(self, avatarId, *interfaces):
- if telnet.ITelnetProtocol in interfaces:
- namespace = self.namespace_maker()
- p = telnet.TelnetBootstrapProtocol(insults.ServerProtocol,
- manhole.ColoredManhole,
- namespace)
- return (telnet.ITelnetProtocol, p, lambda: None)
- raise NotImplementedError()
-
-
-class chainedProtocolFactory:
- # this curries the 'namespace' argument into a later call to
- # chainedProtocolFactory()
- def __init__(self, namespace):
- self.namespace = namespace
-
- def __call__(self):
- return insults.ServerProtocol(manhole.ColoredManhole, self.namespace)
-
-if conchc:
- class AuthorizedKeysChecker(conchc.SSHPublicKeyDatabase):
- """Accept connections using SSH keys from a given file.
-
- SSHPublicKeyDatabase takes the username that the prospective client has
- requested and attempts to get a ~/.ssh/authorized_keys file for that
- username. This requires root access, so it isn't as useful as you'd
- like.
-
- Instead, this subclass looks for keys in a single file, given as an
- argument. This file is typically kept in the buildmaster's basedir. The
- file should have 'ssh-dss ....' lines in it, just like authorized_keys.
- """
-
- def __init__(self, authorized_keys_file):
- self.authorized_keys_file = os.path.expanduser(authorized_keys_file)
-
- def checkKey(self, credentials):
- with open(self.authorized_keys_file) as f:
- for l in f.readlines():
- l2 = l.split()
- if len(l2) < 2:
- continue
- try:
- if base64.decodestring(l2[1]) == credentials.blob:
- return 1
- except binascii.Error:
- continue
- return 0
-
-
-class _BaseManhole(service.MultiService):
- """This provides remote access to a python interpreter (a read/exec/print
- loop) embedded in the buildmaster via an internal SSH server. This allows
- detailed inspection of the buildmaster state. It is of most use to
- buildbot developers. Connect to this by running an ssh client.
- """
-
- def __init__(self, port, checker, using_ssh=True):
- """
- @type port: string or int
- @param port: what port should the Manhole listen on? This is a
- strports specification string, like 'tcp:12345' or
- 'tcp:12345:interface=127.0.0.1'. Bare integers are treated as a
- simple tcp port.
-
- @type checker: an object providing the
- L{twisted.cred.checkers.ICredentialsChecker} interface
- @param checker: if provided, this checker is used to authenticate the
- client instead of using the username/password scheme. You must either
- provide a username/password or a Checker. Some useful values are::
- import twisted.cred.checkers as credc
- import twisted.conch.checkers as conchc
- c = credc.AllowAnonymousAccess # completely open
- c = credc.FilePasswordDB(passwd_filename) # file of name:passwd
- c = conchc.UNIXPasswordDatabase # getpwnam() (probably /etc/passwd)
-
- @type using_ssh: bool
- @param using_ssh: If True, accept SSH connections. If False, accept
- regular unencrypted telnet connections.
- """
-
- # unfortunately, these don't work unless we're running as root
- #c = credc.PluggableAuthenticationModulesChecker: PAM
- #c = conchc.SSHPublicKeyDatabase() # ~/.ssh/authorized_keys
- # and I can't get UNIXPasswordDatabase to work
-
- service.MultiService.__init__(self)
- if type(port) is int:
- port = "tcp:%d" % port
- self.port = port # for comparison later
- self.checker = checker # to maybe compare later
-
- def makeNamespace():
- master = self.master
- namespace = {
- 'master': master,
- 'status': master.getStatus(),
- 'show': show,
- }
- return namespace
-
- def makeProtocol():
- namespace = makeNamespace()
- p = insults.ServerProtocol(manhole.ColoredManhole, namespace)
- return p
-
- self.using_ssh = using_ssh
- if using_ssh:
- r = manhole_ssh.TerminalRealm()
- r.chainedProtocolFactory = makeProtocol
- p = portal.Portal(r, [self.checker])
- f = manhole_ssh.ConchFactory(p)
- else:
- r = _TelnetRealm(makeNamespace)
- p = portal.Portal(r, [self.checker])
- f = protocol.ServerFactory()
- f.protocol = makeTelnetProtocol(p)
- s = strports.service(self.port, f)
- s.setServiceParent(self)
-
-
- def startService(self):
- service.MultiService.startService(self)
- if self.using_ssh:
- via = "via SSH"
- else:
- via = "via telnet"
- log.msg("Manhole listening %s on port %s" % (via, self.port))
-
-
-class TelnetManhole(_BaseManhole, ComparableMixin):
- """This Manhole accepts unencrypted (telnet) connections, and requires a
- username and password authorize access. You are encouraged to use the
- encrypted ssh-based manhole classes instead."""
-
- compare_attrs = ["port", "username", "password"]
-
- def __init__(self, port, username, password):
- """
- @type port: string or int
- @param port: what port should the Manhole listen on? This is a
- strports specification string, like 'tcp:12345' or
- 'tcp:12345:interface=127.0.0.1'. Bare integers are treated as a
- simple tcp port.
-
- @param username:
- @param password: username= and password= form a pair of strings to
- use when authenticating the remote user.
- """
-
- self.username = username
- self.password = password
-
- c = checkers.InMemoryUsernamePasswordDatabaseDontUse()
- c.addUser(username, password)
-
- _BaseManhole.__init__(self, port, c, using_ssh=False)
-
-class PasswordManhole(_BaseManhole, ComparableMixin):
- """This Manhole accepts encrypted (ssh) connections, and requires a
- username and password to authorize access.
- """
-
- compare_attrs = ["port", "username", "password"]
-
- def __init__(self, port, username, password):
- """
- @type port: string or int
- @param port: what port should the Manhole listen on? This is a
- strports specification string, like 'tcp:12345' or
- 'tcp:12345:interface=127.0.0.1'. Bare integers are treated as a
- simple tcp port.
-
- @param username:
- @param password: username= and password= form a pair of strings to
- use when authenticating the remote user.
- """
-
- if not manhole_ssh:
- config.error("pycrypto required for ssh mahole.")
- self.username = username
- self.password = password
-
- c = checkers.InMemoryUsernamePasswordDatabaseDontUse()
- c.addUser(username, password)
-
- _BaseManhole.__init__(self, port, c)
-
-class AuthorizedKeysManhole(_BaseManhole, ComparableMixin):
- """This Manhole accepts ssh connections, and requires that the
- prospective client have an ssh private key that matches one of the public
- keys in our authorized_keys file. It is created with the name of a file
- that contains the public keys that we will accept."""
-
- compare_attrs = ["port", "keyfile"]
-
- def __init__(self, port, keyfile):
- """
- @type port: string or int
- @param port: what port should the Manhole listen on? This is a
- strports specification string, like 'tcp:12345' or
- 'tcp:12345:interface=127.0.0.1'. Bare integers are treated as a
- simple tcp port.
-
- @param keyfile: the name of a file (relative to the buildmaster's
- basedir) that contains SSH public keys of authorized
- users, one per line. This is the exact same format
- as used by sshd in ~/.ssh/authorized_keys .
- """
-
- if not manhole_ssh:
- config.error("pycrypto required for ssh mahole.")
-
- # TODO: expanduser this, and make it relative to the buildmaster's
- # basedir
- self.keyfile = keyfile
- c = AuthorizedKeysChecker(keyfile)
- _BaseManhole.__init__(self, port, c)
-
-class ArbitraryCheckerManhole(_BaseManhole, ComparableMixin):
- """This Manhole accepts ssh connections, but uses an arbitrary
- user-supplied 'checker' object to perform authentication."""
-
- compare_attrs = ["port", "checker"]
-
- def __init__(self, port, checker):
- """
- @type port: string or int
- @param port: what port should the Manhole listen on? This is a
- strports specification string, like 'tcp:12345' or
- 'tcp:12345:interface=127.0.0.1'. Bare integers are treated as a
- simple tcp port.
-
- @param checker: an instance of a twisted.cred 'checker' which will
- perform authentication
- """
-
- if not manhole_ssh:
- config.error("pycrypto required for ssh mahole.")
-
- _BaseManhole.__init__(self, port, checker)
-
-## utility functions for the manhole
-
-def show(x):
- """Display the data attributes of an object in a readable format"""
- print "data attributes of %r" % (x,)
- names = dir(x)
- maxlen = max([0] + [len(n) for n in names])
- for k in names:
- v = getattr(x,k)
- t = type(v)
- if t == types.MethodType: continue
- if k[:2] == '__' and k[-2:] == '__': continue
- if t is types.StringType or t is types.UnicodeType:
- if len(v) > 80 - maxlen - 5:
- v = `v[:80 - maxlen - 5]` + "..."
- elif t in (types.IntType, types.NoneType):
- v = str(v)
- elif v in (types.ListType, types.TupleType, types.DictType):
- v = "%s (%d elements)" % (v, len(v))
- else:
- v = str(t)
- print "%*s : %s" % (maxlen, k, v)
- return x
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/master.py
deleted file mode 100644
index 63c784fa..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/master.py
+++ /dev/null
@@ -1,779 +0,0 @@
-# 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 os
-import signal
-import socket
-
-from zope.interface import implements
-from twisted.python import log, components, failure
-from twisted.internet import defer, reactor, task
-from twisted.application import service
-
-import buildbot
-import buildbot.pbmanager
-from buildbot.util import subscription, epoch2datetime
-from buildbot.status.master import Status
-from buildbot.changes import changes
-from buildbot.changes.manager import ChangeManager
-from buildbot import interfaces
-from buildbot.process.builder import BuilderControl
-from buildbot.db import connector
-from buildbot.schedulers.manager import SchedulerManager
-from buildbot.process.botmaster import BotMaster
-from buildbot.process import debug
-from buildbot.process import metrics
-from buildbot.process import cache
-from buildbot.process.users import users
-from buildbot.process.users.manager import UserManagerManager
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE
-from buildbot.util.eventual import eventually
-from buildbot import monkeypatches
-from buildbot import config
-
-########################################
-
-class LogRotation(object):
- def __init__(self):
- self.rotateLength = 1 * 1000 * 1000
- self.maxRotatedFiles = 10
-
-class BuildMaster(config.ReconfigurableServiceMixin, service.MultiService):
-
- # frequency with which to reclaim running builds; this should be set to
- # something fairly long, to avoid undue database load
- RECLAIM_BUILD_INTERVAL = 10*60
-
- # multiplier on RECLAIM_BUILD_INTERVAL at which a build is considered
- # unclaimed; this should be at least 2 to avoid false positives
- UNCLAIMED_BUILD_FACTOR = 6
-
- # if this quantity of unclaimed build requests are present in the table,
- # then something is probably wrong! The master will log a WARNING on every
- # database poll operation.
- WARNING_UNCLAIMED_COUNT = 10000
-
- def __init__(self, basedir, configFileName="master.cfg", umask=None):
- service.MultiService.__init__(self)
- self.setName("buildmaster")
-
- self.umask = umask
-
- self.basedir = basedir
- assert os.path.isdir(self.basedir)
- self.configFileName = configFileName
-
- # set up child services
- self.create_child_services()
-
- # loop for polling the db
- self.db_loop = None
- # db configured values
- self.configured_db_url = None
- self.configured_poll_interval = None
-
- # configuration / reconfiguration handling
- self.config = config.MasterConfig()
- self.reconfig_active = False
- self.reconfig_requested = False
- self.reconfig_notifier = None
-
- # this stores parameters used in the tac file, and is accessed by the
- # WebStatus to duplicate those values.
- self.log_rotation = LogRotation()
-
- # subscription points
- self._change_subs = \
- subscription.SubscriptionPoint("changes")
- self._new_buildrequest_subs = \
- subscription.SubscriptionPoint("buildrequest_additions")
- self._new_buildset_subs = \
- subscription.SubscriptionPoint("buildset_additions")
- self._complete_buildset_subs = \
- subscription.SubscriptionPoint("buildset_completion")
-
- # local cache for this master's object ID
- self._object_id = None
-
-
- def create_child_services(self):
- # note that these are order-dependent. If you get the order wrong,
- # you'll know it, as the master will fail to start.
-
- self.metrics = metrics.MetricLogObserver()
- self.metrics.setServiceParent(self)
-
- self.caches = cache.CacheManager()
- self.caches.setServiceParent(self)
-
- self.pbmanager = buildbot.pbmanager.PBManager()
- self.pbmanager.setServiceParent(self)
-
- self.change_svc = ChangeManager(self)
- self.change_svc.setServiceParent(self)
-
- self.botmaster = BotMaster(self)
- self.botmaster.setServiceParent(self)
-
- self.scheduler_manager = SchedulerManager(self)
- self.scheduler_manager.setServiceParent(self)
-
- self.user_manager = UserManagerManager(self)
- self.user_manager.setServiceParent(self)
-
- self.db = connector.DBConnector(self, self.basedir)
- self.db.setServiceParent(self)
-
- self.debug = debug.DebugServices(self)
- self.debug.setServiceParent(self)
-
- self.status = Status(self)
- self.status.setServiceParent(self)
-
- # setup and reconfig handling
-
- _already_started = False
- @defer.inlineCallbacks
- def startService(self, _reactor=reactor):
- assert not self._already_started, "can only start the master once"
- self._already_started = True
-
- log.msg("Starting BuildMaster -- buildbot.version: %s" %
- buildbot.version)
-
- # Set umask
- if self.umask is not None:
- os.umask(self.umask)
-
- # first, apply all monkeypatches
- monkeypatches.patch_all()
-
- # we want to wait until the reactor is running, so we can call
- # reactor.stop() for fatal errors
- d = defer.Deferred()
- _reactor.callWhenRunning(d.callback, None)
- yield d
-
- try:
- # load the configuration file, treating errors as fatal
- try:
- self.config = config.MasterConfig.loadConfig(self.basedir,
- self.configFileName)
-
- except config.ConfigErrors, e:
- log.msg("Configuration Errors:")
- for msg in e.errors:
- log.msg(" " + msg)
- log.msg("Halting master.")
- _reactor.stop()
- return
- except:
- log.err(failure.Failure(), 'while starting BuildMaster')
- _reactor.stop()
- return
-
- # set up services that need access to the config before everything else
- # gets told to reconfig
- try:
- yield self.db.setup()
- except connector.DatabaseNotReadyError:
- # (message was already logged)
- _reactor.stop()
- return
-
- if hasattr(signal, "SIGHUP"):
- def sighup(*args):
- eventually(self.reconfig)
- signal.signal(signal.SIGHUP, sighup)
-
- if hasattr(signal, "SIGUSR1"):
- def sigusr1(*args):
- _reactor.callLater(0, self.botmaster.cleanShutdown)
- signal.signal(signal.SIGUSR1, sigusr1)
-
- # call the parent method
- yield defer.maybeDeferred(lambda :
- service.MultiService.startService(self))
-
- # give all services a chance to load the new configuration, rather than
- # the base configuration
- yield self.reconfigService(self.config)
- except:
- f = failure.Failure()
- log.err(f, 'while starting BuildMaster')
- _reactor.stop()
-
- log.msg("BuildMaster is running")
-
- @defer.inlineCallbacks
- def stopService(self):
- if self.running:
- yield service.MultiService.stopService(self)
- if self.db_loop:
- self.db_loop.stop()
- self.db_loop = None
-
-
- def reconfig(self):
- # this method wraps doConfig, ensuring it is only ever called once at
- # a time, and alerting the user if the reconfig takes too long
- if self.reconfig_active:
- log.msg("reconfig already active; will reconfig again after")
- self.reconfig_requested = True
- return
-
- self.reconfig_active = reactor.seconds()
- metrics.MetricCountEvent.log("loaded_config", 1)
-
- # notify every 10 seconds that the reconfig is still going on, although
- # reconfigs should not take that long!
- self.reconfig_notifier = task.LoopingCall(lambda :
- log.msg("reconfig is ongoing for %d s" %
- (reactor.seconds() - self.reconfig_active)))
- self.reconfig_notifier.start(10, now=False)
-
- timer = metrics.Timer("BuildMaster.reconfig")
- timer.start()
-
- d = self.doReconfig()
-
- @d.addBoth
- def cleanup(res):
- timer.stop()
- self.reconfig_notifier.stop()
- self.reconfig_notifier = None
- self.reconfig_active = False
- if self.reconfig_requested:
- self.reconfig_requested = False
- self.reconfig()
- return res
-
- d.addErrback(log.err, 'while reconfiguring')
-
- return d # for tests
-
-
- @defer.inlineCallbacks
- def doReconfig(self):
- log.msg("beginning configuration update")
- changes_made = False
- failed = False
- try:
- new_config = config.MasterConfig.loadConfig(self.basedir,
- self.configFileName)
- changes_made = True
- self.config = new_config
- yield self.reconfigService(new_config)
-
- except config.ConfigErrors, e:
- for msg in e.errors:
- log.msg(msg)
- failed = True
-
- except:
- log.err(failure.Failure(), 'during reconfig:')
- failed = True
-
- if failed:
- if changes_made:
- log.msg("WARNING: reconfig partially applied; master "
- "may malfunction")
- else:
- log.msg("reconfig aborted without making any changes")
- else:
- log.msg("configuration update complete")
-
-
- def reconfigService(self, new_config):
- if self.configured_db_url is None:
- self.configured_db_url = new_config.db['db_url']
- elif (self.configured_db_url != new_config.db['db_url']):
- config.error(
- "Cannot change c['db']['db_url'] after the master has started",
- )
-
- # adjust the db poller
- if (self.configured_poll_interval
- != new_config.db['db_poll_interval']):
- if self.db_loop:
- self.db_loop.stop()
- self.db_loop = None
- self.configured_poll_interval = new_config.db['db_poll_interval']
- if self.configured_poll_interval:
- self.db_loop = task.LoopingCall(self.pollDatabase)
- self.db_loop.start(self.configured_poll_interval, now=False)
-
- return config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
-
- ## informational methods
-
- def allSchedulers(self):
- return list(self.scheduler_manager)
-
- def getStatus(self):
- """
- @rtype: L{buildbot.status.builder.Status}
- """
- return self.status
-
- def getObjectId(self):
- """
- Return the obejct id for this master, for associating state with the
- master.
-
- @returns: ID, via Deferred
- """
- # try to get the cached value
- if self._object_id is not None:
- return defer.succeed(self._object_id)
-
- # failing that, get it from the DB; multiple calls to this function
- # at the same time will not hurt
- try:
- hostname = os.uname()[1] # only on unix
- except AttributeError:
- hostname = socket.getfqdn()
- master_name = "%s:%s" % (hostname, os.path.abspath(self.basedir))
-
- d = self.db.state.getObjectId(master_name,
- "buildbot.master.BuildMaster")
- def keep(id):
- self._object_id = id
- return id
- d.addCallback(keep)
- return d
-
-
- ## triggering methods and subscriptions
-
- def addChange(self, who=None, files=None, comments=None, author=None,
- isdir=None, is_dir=None, revision=None, when=None,
- when_timestamp=None, branch=None, category=None, revlink='',
- properties={}, repository='', codebase=None, project='', src=None):
- """
- Add a change to the buildmaster and act on it.
-
- This is a wrapper around L{ChangesConnectorComponent.addChange} which
- also acts on the resulting change and returns a L{Change} instance.
-
- Note that all parameters are keyword arguments, although C{who},
- C{files}, and C{comments} can be specified positionally for
- backward-compatibility.
-
- @param author: the author of this change
- @type author: unicode string
-
- @param who: deprecated name for C{author}
-
- @param files: a list of filenames that were changed
- @type branch: list of unicode strings
-
- @param comments: user comments on the change
- @type branch: unicode string
-
- @param is_dir: deprecated
-
- @param isdir: deprecated name for C{is_dir}
-
- @param revision: the revision identifier for this change
- @type revision: unicode string
-
- @param when_timestamp: when this change occurred, or the current time
- if None
- @type when_timestamp: datetime instance or None
-
- @param when: deprecated name and type for C{when_timestamp}
- @type when: integer (UNIX epoch time) or None
-
- @param branch: the branch on which this change took place
- @type branch: unicode string
-
- @param category: category for this change (arbitrary use by Buildbot
- users)
- @type category: unicode string
-
- @param revlink: link to a web view of this revision
- @type revlink: unicode string
-
- @param properties: properties to set on this change
- @type properties: dictionary with string keys and simple values
- (JSON-able). Note that the property source is I{not} included
- in this dictionary.
-
- @param repository: the repository in which this change took place
- @type repository: unicode string
-
- @param project: the project this change is a part of
- @type project: unicode string
-
- @param src: source of the change (vcs or other)
- @type src: string
-
- @returns: L{Change} instance via Deferred
- """
- metrics.MetricCountEvent.log("added_changes", 1)
-
- # handle translating deprecated names into new names for db.changes
- def handle_deprec(oldname, old, newname, new, default=None,
- converter = lambda x:x):
- if old is not None:
- if new is None:
- log.msg("WARNING: change source is using deprecated "
- "addChange parameter '%s'" % oldname)
- return converter(old)
- raise TypeError("Cannot provide '%s' and '%s' to addChange"
- % (oldname, newname))
- if new is None:
- new = default
- return new
-
- author = handle_deprec("who", who, "author", author)
- is_dir = handle_deprec("isdir", isdir, "is_dir", is_dir,
- default=0)
- when_timestamp = handle_deprec("when", when,
- "when_timestamp", when_timestamp,
- converter=epoch2datetime)
-
- # add a source to each property
- for n in properties:
- properties[n] = (properties[n], 'Change')
-
- if codebase is None:
- if self.config.codebaseGenerator is not None:
- chdict = {
- 'changeid': None,
- 'author': author,
- 'files': files,
- 'comments': comments,
- 'is_dir': is_dir,
- 'revision': revision,
- 'when_timestamp': when_timestamp,
- 'branch': branch,
- 'category': category,
- 'revlink': revlink,
- 'properties': properties,
- 'repository': repository,
- 'project': project,
- }
- codebase = self.config.codebaseGenerator(chdict)
- else:
- codebase = ''
-
- d = defer.succeed(None)
- if src:
- # create user object, returning a corresponding uid
- d.addCallback(lambda _ : users.createUserObject(self, author, src))
-
- # add the Change to the database
- d.addCallback(lambda uid :
- self.db.changes.addChange(author=author, files=files,
- comments=comments, is_dir=is_dir,
- revision=revision,
- when_timestamp=when_timestamp,
- branch=branch, category=category,
- revlink=revlink, properties=properties,
- repository=repository, codebase=codebase,
- project=project, uid=uid))
-
- # convert the changeid to a Change instance
- d.addCallback(lambda changeid :
- self.db.changes.getChange(changeid))
- d.addCallback(lambda chdict :
- changes.Change.fromChdict(self, chdict))
-
- def notify(change):
- msg = u"added change %s to database" % change
- log.msg(msg.encode('utf-8', 'replace'))
- # only deliver messages immediately if we're not polling
- if not self.config.db['db_poll_interval']:
- self._change_subs.deliver(change)
- return change
- d.addCallback(notify)
- return d
-
- def subscribeToChanges(self, callback):
- """
- Request that C{callback} be called with each Change object added to the
- cluster.
-
- Note: this method will go away in 0.9.x
- """
- return self._change_subs.subscribe(callback)
-
- def addBuildset(self, **kwargs):
- """
- Add a buildset to the buildmaster and act on it. Interface is
- identical to
- L{buildbot.db.buildsets.BuildsetConnectorComponent.addBuildset},
- including returning a Deferred, but also potentially triggers the
- resulting builds.
- """
- d = self.db.buildsets.addBuildset(**kwargs)
- def notify((bsid,brids)):
- log.msg("added buildset %d to database" % bsid)
- # note that buildset additions are only reported on this master
- self._new_buildset_subs.deliver(bsid=bsid, **kwargs)
- # only deliver messages immediately if we're not polling
- if not self.config.db['db_poll_interval']:
- for bn, brid in brids.iteritems():
- self.buildRequestAdded(bsid=bsid, brid=brid,
- buildername=bn)
- return (bsid,brids)
- d.addCallback(notify)
- return d
-
- def subscribeToBuildsets(self, callback):
- """
- Request that C{callback(bsid=bsid, ssid=ssid, reason=reason,
- properties=properties, builderNames=builderNames,
- external_idstring=external_idstring)} be called whenever a buildset is
- added. Properties is a dictionary as expected for
- L{BuildsetsConnectorComponent.addBuildset}.
-
- Note that this only works for buildsets added on this master.
-
- Note: this method will go away in 0.9.x
- """
- return self._new_buildset_subs.subscribe(callback)
-
- @defer.inlineCallbacks
- def maybeBuildsetComplete(self, bsid):
- """
- Instructs the master to check whether the buildset is complete,
- and notify appropriately if it is.
-
- Note that buildset completions are only reported on the master
- on which the last build request completes.
- """
- brdicts = yield self.db.buildrequests.getBuildRequests(
- bsid=bsid, complete=False)
-
- # if there are incomplete buildrequests, bail out
- if brdicts:
- return
-
- brdicts = yield self.db.buildrequests.getBuildRequests(bsid=bsid)
-
- # figure out the overall results of the buildset
- cumulative_results = SUCCESS
- for brdict in brdicts:
- if brdict['results'] not in (SUCCESS, WARNINGS):
- cumulative_results = FAILURE
-
- # mark it as completed in the database
- yield self.db.buildsets.completeBuildset(bsid, cumulative_results)
-
- # and deliver to any listeners
- self._buildsetComplete(bsid, cumulative_results)
-
- def _buildsetComplete(self, bsid, results):
- self._complete_buildset_subs.deliver(bsid, results)
-
- def subscribeToBuildsetCompletions(self, callback):
- """
- Request that C{callback(bsid, result)} be called whenever a
- buildset is complete.
-
- Note: this method will go away in 0.9.x
- """
- return self._complete_buildset_subs.subscribe(callback)
-
- def buildRequestAdded(self, bsid, brid, buildername):
- """
- Notifies the master that a build request is available to be claimed;
- this may be a brand new build request, or a build request that was
- previously claimed and unclaimed through a timeout or other calamity.
-
- @param bsid: containing buildset id
- @param brid: buildrequest ID
- @param buildername: builder named by the build request
- """
- self._new_buildrequest_subs.deliver(
- dict(bsid=bsid, brid=brid, buildername=buildername))
-
- def subscribeToBuildRequests(self, callback):
- """
- Request that C{callback} be invoked with a dictionary with keys C{brid}
- (the build request id), C{bsid} (buildset id) and C{buildername}
- whenever a new build request is added to the database. Note that, due
- to the delayed nature of subscriptions, the build request may already
- be claimed by the time C{callback} is invoked.
-
- Note: this method will go away in 0.9.x
- """
- return self._new_buildrequest_subs.subscribe(callback)
-
-
- ## database polling
-
- def pollDatabase(self):
- # poll each of the tables that can indicate new, actionable stuff for
- # this buildmaster to do. This is used in a TimerService, so returning
- # a Deferred means that we won't run two polling operations
- # simultaneously. Each particular poll method handles errors itself,
- # although catastrophic errors are handled here
- d = defer.gatherResults([
- self.pollDatabaseChanges(),
- self.pollDatabaseBuildRequests(),
- # also unclaim
- ])
- d.addErrback(log.err, 'while polling database')
- return d
-
- _last_processed_change = None
- @defer.inlineCallbacks
- def pollDatabaseChanges(self):
- # Older versions of Buildbot had each scheduler polling the database
- # independently, and storing a "last_processed" state indicating the
- # last change it had processed. This had the advantage of allowing
- # schedulers to pick up changes that arrived in the database while
- # the scheduler was not running, but was horribly inefficient.
-
- # This version polls the database on behalf of the schedulers, using a
- # similar state at the master level.
-
- timer = metrics.Timer("BuildMaster.pollDatabaseChanges()")
- timer.start()
-
- need_setState = False
-
- # get the last processed change id
- if self._last_processed_change is None:
- self._last_processed_change = \
- yield self._getState('last_processed_change')
-
- # if it's still None, assume we've processed up to the latest changeid
- if self._last_processed_change is None:
- lpc = yield self.db.changes.getLatestChangeid()
- # if there *are* no changes, count the last as '0' so that we don't
- # skip the first change
- if lpc is None:
- lpc = 0
- self._last_processed_change = lpc
-
- need_setState = True
-
- if self._last_processed_change is None:
- timer.stop()
- return
-
- while True:
- changeid = self._last_processed_change + 1
- chdict = yield self.db.changes.getChange(changeid)
-
- # if there's no such change, we've reached the end and can
- # stop polling
- if not chdict:
- break
-
- change = yield changes.Change.fromChdict(self, chdict)
-
- self._change_subs.deliver(change)
-
- self._last_processed_change = changeid
- need_setState = True
-
- # write back the updated state, if it's changed
- if need_setState:
- yield self._setState('last_processed_change',
- self._last_processed_change)
- timer.stop()
-
- _last_unclaimed_brids_set = None
- _last_claim_cleanup = 0
- @defer.inlineCallbacks
- def pollDatabaseBuildRequests(self):
- # deal with cleaning up unclaimed requests, and (if necessary)
- # requests from a previous instance of this master
- timer = metrics.Timer("BuildMaster.pollDatabaseBuildRequests()")
- timer.start()
-
- # cleanup unclaimed builds
- since_last_cleanup = reactor.seconds() - self._last_claim_cleanup
- if since_last_cleanup < self.RECLAIM_BUILD_INTERVAL:
- unclaimed_age = (self.RECLAIM_BUILD_INTERVAL
- * self.UNCLAIMED_BUILD_FACTOR)
- yield self.db.buildrequests.unclaimExpiredRequests(unclaimed_age)
-
- self._last_claim_cleanup = reactor.seconds()
-
- # _last_unclaimed_brids_set tracks the state of unclaimed build
- # requests; whenever it sees a build request which was not claimed on
- # the last poll, it notifies the subscribers. It only tracks that
- # state within the master instance, though; on startup, it notifies for
- # all unclaimed requests in the database.
-
- last_unclaimed = self._last_unclaimed_brids_set or set()
- if len(last_unclaimed) > self.WARNING_UNCLAIMED_COUNT:
- log.msg("WARNING: %d unclaimed buildrequests - is a scheduler "
- "producing builds for which no builder is running?"
- % len(last_unclaimed))
-
- # get the current set of unclaimed buildrequests
- now_unclaimed_brdicts = \
- yield self.db.buildrequests.getBuildRequests(claimed=False)
- now_unclaimed = set([ brd['brid'] for brd in now_unclaimed_brdicts ])
-
- # and store that for next time
- self._last_unclaimed_brids_set = now_unclaimed
-
- # see what's new, and notify if anything is
- new_unclaimed = now_unclaimed - last_unclaimed
- if new_unclaimed:
- brdicts = dict((brd['brid'], brd) for brd in now_unclaimed_brdicts)
- for brid in new_unclaimed:
- brd = brdicts[brid]
- self.buildRequestAdded(brd['buildsetid'], brd['brid'],
- brd['buildername'])
- timer.stop()
-
- ## state maintenance (private)
-
- def _getState(self, name, default=None):
- "private wrapper around C{self.db.state.getState}"
- d = self.getObjectId()
- def get(objectid):
- return self.db.state.getState(objectid, name, default)
- d.addCallback(get)
- return d
-
- def _setState(self, name, value):
- "private wrapper around C{self.db.state.setState}"
- d = self.getObjectId()
- def set(objectid):
- return self.db.state.setState(objectid, name, value)
- d.addCallback(set)
- return d
-
-class Control:
- implements(interfaces.IControl)
-
- def __init__(self, master):
- self.master = master
-
- def addChange(self, change):
- self.master.addChange(change)
-
- def addBuildset(self, **kwargs):
- return self.master.addBuildset(**kwargs)
-
- def getBuilder(self, name):
- b = self.master.botmaster.builders[name]
- return BuilderControl(b, self)
-
-components.registerAdapter(Control, BuildMaster, interfaces.IControl)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/__init__.py
deleted file mode 100644
index 285e4476..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/__init__.py
+++ /dev/null
@@ -1,83 +0,0 @@
-# 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 twisted
-from twisted.python import versions
-from buildbot.util import sautils
-
-# NOTE: all of these patches test for applicability *before* importing the
-# patch module. This will help cut down on unnecessary imports where the
-# patches are not needed, and also avoid problems with patches importing
-# private things in external libraries that no longer exist.
-
-def patch_bug4881():
- # this patch doesn't apply (or even import!) on Windows
- import sys
- if sys.platform == 'win32':
- return
-
- # this bug was only present in Twisted-10.2.0
- if twisted.version == versions.Version('twisted', 10, 2, 0):
- from buildbot.monkeypatches import bug4881
- bug4881.patch()
-
-def patch_bug4520():
- # this bug was patched in twisted-11.1.0, and only affects py26 and up
- import sys
- py_26 = (sys.version_info[0] > 2 or
- (sys.version_info[0] == 2 and sys.version_info[1] >= 6))
- if twisted.version < versions.Version('twisted', 11, 1, 0) and py_26:
- from buildbot.monkeypatches import bug4520
- bug4520.patch()
-
-def patch_bug5079():
- # this bug is patched in Twisted-12.0.0; it was probably
- # present in Twisted-8.x.0, but the patch doesn't work
- if (twisted.version < versions.Version('twisted', 12, 0, 0) and
- twisted.version >= versions.Version('twisted', 9, 0, 0)):
- from buildbot.monkeypatches import bug5079
- bug5079.patch()
-
-def patch_sqlalchemy2364():
- # fix for SQLAlchemy bug 2364
- if sautils.sa_version() < (0,7,5):
- from buildbot.monkeypatches import sqlalchemy2364
- sqlalchemy2364.patch()
-
-def patch_sqlalchemy2189():
- # fix for SQLAlchemy bug 2189
- if sautils.sa_version() <= (0,7,1):
- from buildbot.monkeypatches import sqlalchemy2189
- sqlalchemy2189.patch()
-
-def patch_gatherResults():
- if twisted.version < versions.Version('twisted', 11, 1, 0):
- from buildbot.monkeypatches import gatherResults
- gatherResults.patch()
-
-
-def patch_all(for_tests=False):
- patch_bug4881()
- patch_bug4520()
- patch_bug5079()
- patch_sqlalchemy2364()
- patch_sqlalchemy2189()
- patch_gatherResults()
-
- if for_tests:
- from buildbot.monkeypatches import servicechecks
- servicechecks.patch_servicechecks()
- from buildbot.monkeypatches import testcase_patch
- testcase_patch.patch_testcase_patch()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug4520.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug4520.py
deleted file mode 100644
index ffb891eb..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug4520.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# coding=utf-8
-# 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
-
-from twisted.spread import pb
-from twisted.python import log
-
-def patch():
- log.msg("Applying patch for http://twistedmatrix.com/trac/ticket/4520")
- pb.RemoteError = RemoteError
- pb.CopiedFailure.throwExceptionIntoGenerator = \
- CopiedFailure_throwExceptionIntoGenerator
- old_getStateToCopy = pb.CopyableFailure.getStateToCopy
- def getStateToCopy(self):
- state = old_getStateToCopy(self)
- state['value'] = str(self.value) # Exception instance
- return state
-
-
-#############################################################################
-# Everything below this line was taken from Twisted, except as annotated. See
-# http://twistedmatrix.com/trac/changeset/32211
-#
-# Merge copiedfailure-stringexc-4520
-#
-# Author: sirgolan, Koblaid, glyph
-# Reviewer: exarkun, glyph
-# Fixes: #4520
-#
-# Allow inlineCallbacks and exceptions raised from a twisted.spread remote
-# call to work together. A new RemoteError exception will be raised into
-# the generator when a yielded Deferred fails with a remote PB failure.
-
-class RemoteError(Exception):
- def __init__(self, remoteType, value, remoteTraceback):
- Exception.__init__(self, value)
- self.remoteType = remoteType
- self.remoteTraceback = remoteTraceback
-
-def CopiedFailure_throwExceptionIntoGenerator(self, g):
- return g.throw(RemoteError(self.type, self.value, self.traceback))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug4881.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug4881.py
deleted file mode 100644
index aaa4bba3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug4881.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# coding=utf-8
-# 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 os
-from twisted.internet import process
-from twisted.python import log
-
-def patch():
- log.msg("Applying patch for http://twistedmatrix.com/trac/ticket/4881")
- process._listOpenFDs = _listOpenFDs
-
-#############################################################################
-# Everything below this line was taken verbatim from Twisted, except as
-# annotated.
-
-########
-# r31474:trunk/LICENSE
-
-# Copyright (c) 2001-2010
-# Allen Short
-# Andy Gayton
-# Andrew Bennetts
-# Antoine Pitrou
-# Apple Computer, Inc.
-# Benjamin Bruheim
-# Bob Ippolito
-# Canonical Limited
-# Christopher Armstrong
-# David Reid
-# Donovan Preston
-# Eric Mangold
-# Eyal Lotem
-# Itamar Shtull-Trauring
-# James Knight
-# Jason A. Mobarak
-# Jean-Paul Calderone
-# Jessica McKellar
-# Jonathan Jacobs
-# Jonathan Lange
-# Jonathan D. Simms
-# Jürgen Hermann
-# Kevin Horn
-# Kevin Turner
-# Mary Gardiner
-# Matthew Lefkowitz
-# Massachusetts Institute of Technology
-# Moshe Zadka
-# Paul Swartz
-# Pavel Pergamenshchik
-# Ralph Meijer
-# Sean Riley
-# Software Freedom Conservancy
-# Travis B. Hartwell
-# Thijs Triemstra
-# Thomas Herve
-# Timothy Allen
-#
-# Permission is hereby granted, free of charge, to any person obtaining
-# a copy of this software and associated documentation files (the
-# "Software"), to deal in the Software without restriction, including
-# without limitation the rights to use, copy, modify, merge, publish,
-# distribute, sublicense, and/or sell copies of the Software, and to
-# permit persons to whom the Software is furnished to do so, subject to
-# the following conditions:
-#
-# The above copyright notice and this permission notice shall be
-# included in all copies or substantial portions of the Software.
-#
-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
-# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
-# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
-# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-########
-# r31474:trunk/twisted/internet/process.py
-
-# Copyright (c) Twisted Matrix Laboratories.
-# See LICENSE for details.
-
-class _FDDetector(object):
- """
- This class contains the logic necessary to decide which of the available
- system techniques should be used to detect the open file descriptors for
- the current process. The chosen technique gets monkey-patched into the
- _listOpenFDs method of this class so that the detection only needs to occur
- once.
-
- @ivars listdir: The implementation of listdir to use. This gets overwritten
- by the test cases.
- @ivars getpid: The implementation of getpid to use, returns the PID of the
- running process.
- @ivars openfile: The implementation of open() to use, by default the Python
- builtin.
- """
- # So that we can unit test this
- listdir = os.listdir
- getpid = os.getpid
- openfile = open
-
-
- def _listOpenFDs(self):
- """
- Figure out which implementation to use, then run it.
- """
- self._listOpenFDs = self._getImplementation()
- return self._listOpenFDs()
-
-
- def _getImplementation(self):
- """
- Check if /dev/fd works, if so, use that. Otherwise, check if
- /proc/%d/fd exists, if so use that.
-
- Otherwise, ask resource.getrlimit, if that throws an exception, then
- fallback to _fallbackFDImplementation.
- """
- try:
- self.listdir("/dev/fd")
- if self._checkDevFDSanity(): # FreeBSD support :-)
- return self._devFDImplementation
- else:
- return self._fallbackFDImplementation
- except:
- try:
- self.listdir("/proc/%d/fd" % (self.getpid(),))
- return self._procFDImplementation
- except:
- try:
- self._resourceFDImplementation() # Imports resource
- return self._resourceFDImplementation
- except:
- return self._fallbackFDImplementation
-
-
- def _checkDevFDSanity(self):
- """
- Returns true iff opening a file modifies the fds visible
- in /dev/fd, as it should on a sane platform.
- """
- start = self.listdir("/dev/fd")
- self.openfile("/dev/null", "r") # changed in Buildbot to hush pyflakes
- end = self.listdir("/dev/fd")
- return start != end
-
-
- def _devFDImplementation(self):
- """
- Simple implementation for systems where /dev/fd actually works.
- See: http://www.freebsd.org/cgi/man.cgi?fdescfs
- """
- dname = "/dev/fd"
- result = [int(fd) for fd in os.listdir(dname)]
- return result
-
-
- def _procFDImplementation(self):
- """
- Simple implementation for systems where /proc/pid/fd exists (we assume
- it works).
- """
- dname = "/proc/%d/fd" % (os.getpid(),)
- return [int(fd) for fd in os.listdir(dname)]
-
-
- def _resourceFDImplementation(self):
- """
- Fallback implementation where the resource module can inform us about
- how many FDs we can expect.
-
- Note that on OS-X we expect to be using the /dev/fd implementation.
- """
- import resource
- maxfds = resource.getrlimit(resource.RLIMIT_NOFILE)[1] + 1
- # OS-X reports 9223372036854775808. That's a lot of fds
- # to close
- if maxfds > 1024:
- maxfds = 1024
- return xrange(maxfds)
-
-
- def _fallbackFDImplementation(self):
- """
- Fallback-fallback implementation where we just assume that we need to
- close 256 FDs.
- """
- maxfds = 256
- return xrange(maxfds)
-
-
-detector = _FDDetector()
-
-def _listOpenFDs():
- """
- Use the global detector object to figure out which FD implementation to
- use.
- """
- return detector._listOpenFDs()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug5079.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug5079.py
deleted file mode 100644
index 30202323..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/bug5079.py
+++ /dev/null
@@ -1,49 +0,0 @@
-# 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
-
-from twisted.spread import pb
-from twisted.python import log
-from twisted.spread.interfaces import IJellyable
-
-def patch():
- log.msg("Applying patch for http://twistedmatrix.com/trac/ticket/5079")
- if not hasattr(pb, '_JellyableAvatarMixin'):
- log.msg("..patch not applicable; please file a bug at buildbot.net")
- else:
- pb._JellyableAvatarMixin._cbLogin = _fixed_cbLogin
-
-def _fixed_cbLogin(self, (interface, avatar, logout)):
- """
- Ensure that the avatar to be returned to the client is jellyable and
- set up disconnection notification to call the realm's logout object.
- """
- if not IJellyable.providedBy(avatar):
- avatar = pb.AsReferenceable(avatar, "perspective")
-
- puid = avatar.processUniqueID()
-
- # only call logout once, whether the connection is dropped (disconnect)
- # or a logout occurs (cleanup), and be careful to drop the reference to
- # it in either case
- logout = [ logout ]
- def maybeLogout():
- if not logout: return
- fn = logout[0]
- del logout[0]
- fn()
- self.broker._localCleanup[puid] = maybeLogout
- self.broker.notifyOnDisconnect(maybeLogout)
-
- return avatar
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/gatherResults.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/gatherResults.py
deleted file mode 100644
index 492f97ba..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/gatherResults.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# 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
-
-from twisted.internet import defer
-
-def patch():
- """
- Patch gatherResults to support consumeErrors on old versions of twisted
- """
- defer.gatherResults = gatherResults
-
-#############################################################################
-# Everything below this line was taken from Twisted, except as annotated. See
-# https://twistedmatrix.com/trac/browser/trunk/twisted/internet/defer.py?rev=32405#L805
-#
-# Merge gatherresults-consumeerrors-5159
-#
-# Author: dustin
-# Reviewer: exarkun
-# Fixes: #5159
-#
-# Add a `consumeErrors` parameter to `twisted.internet.defer.gatherResults`
-# with the same meaning as the parameter of the same name accepted by
-# `DeferredList`.
-
-
-
-def _parseDListResult(l, fireOnOneErrback=False):
- if __debug__:
- for success, value in l:
- assert success
- return [x[1] for x in l]
-
-def gatherResults(deferredList, consumeErrors=False):
- """
- Returns, via a L{Deferred}, a list with the results of the given
- L{Deferred}s - in effect, a "join" of multiple deferred operations.
-
- The returned L{Deferred} will fire when I{all} of the provided L{Deferred}s
- have fired, or when any one of them has failed.
-
- This differs from L{DeferredList} in that you don't need to parse
- the result for success/failure.
-
- @type deferredList: C{list} of L{Deferred}s
-
- @param consumeErrors: (keyword param) a flag, defaulting to False,
- indicating that failures in any of the given L{Deferreds} should not be
- propagated to errbacks added to the individual L{Deferreds} after this
- L{gatherResults} invocation. Any such errors in the individual
- L{Deferred}s will be converted to a callback result of C{None}. This
- is useful to prevent spurious 'Unhandled error in Deferred' messages
- from being logged. This parameter is available since 11.1.0.
- @type consumeErrors: C{bool}
- """
- d = defer.DeferredList(deferredList, fireOnOneErrback=True,
- consumeErrors=consumeErrors)
- d.addCallback(_parseDListResult)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/servicechecks.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/servicechecks.py
deleted file mode 100644
index 46ac7bc2..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/servicechecks.py
+++ /dev/null
@@ -1,34 +0,0 @@
-# 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
-
-
-def patch_servicechecks():
- """
- Patch startService and stopService so that they check the previous state
- first.
-
- (used for debugging only)
- """
- from twisted.application.service import Service
- old_startService = Service.startService
- old_stopService = Service.stopService
- def startService(self):
- assert not self.running
- return old_startService(self)
- def stopService(self):
- assert self.running
- return old_stopService(self)
- Service.startService = startService
- Service.stopService = stopService
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/sqlalchemy2189.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/sqlalchemy2189.py
deleted file mode 100644
index eda357ed..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/sqlalchemy2189.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# 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 re
-from buildbot.util import sautils
-from sqlalchemy.engine import reflection
-from sqlalchemy.dialects.sqlite.base import SQLiteDialect, _pragma_cursor
-from sqlalchemy.dialects.sqlite.base import sqltypes, util
-
-@reflection.cache
-def get_columns_06x_fixed(self, connection, table_name, schema=None, **kw):
- quote = self.identifier_preparer.quote_identifier
- if schema is not None:
- pragma = "PRAGMA %s." % quote(schema)
- else:
- pragma = "PRAGMA "
- qtable = quote(table_name)
- c = _pragma_cursor(connection.execute("%stable_info(%s)" % (pragma, qtable)))
- #### found_table = False (pyflake)
- columns = []
- while True:
- row = c.fetchone()
- if row is None:
- break
- (name, type_, nullable, default, has_default, primary_key) = (row[1], row[2].upper(), not row[3], row[4], row[4] is not None, row[5])
- name = re.sub(r'^\"|\"$', '', name)
- #### if default:
- #### default = re.sub(r"^\'|\'$", '', default)
- match = re.match(r'(\w+)(\(.*?\))?', type_)
- if match:
- coltype = match.group(1)
- args = match.group(2)
- else:
- coltype = "VARCHAR"
- args = ''
- try:
- coltype = self.ischema_names[coltype]
- except KeyError:
- util.warn("Did not recognize type '%s' of column '%s'" %
- (coltype, name))
- coltype = sqltypes.NullType
- if args is not None:
- args = re.findall(r'(\d+)', args)
- coltype = coltype(*[int(a) for a in args])
-
- columns.append({
- 'name' : name,
- 'type' : coltype,
- 'nullable' : nullable,
- 'default' : default,
- 'primary_key': primary_key
- })
- return columns
-
-
-@reflection.cache
-def get_columns_07x_fixed(self, connection, table_name, schema=None, **kw):
- quote = self.identifier_preparer.quote_identifier
- if schema is not None:
- pragma = "PRAGMA %s." % quote(schema)
- else:
- pragma = "PRAGMA "
- qtable = quote(table_name)
- c = _pragma_cursor(connection.execute("%stable_info(%s)" % (pragma, qtable)))
- #### found_table = False (pyflake)
- columns = []
- while True:
- row = c.fetchone()
- if row is None:
- break
- (name, type_, nullable, default, has_default, primary_key) = (row[1], row[2].upper(), not row[3], row[4], row[4] is not None, row[5])
- name = re.sub(r'^\"|\"$', '', name)
- #### if default:
- #### default = re.sub(r"^\'|\'$", '', default)
- match = re.match(r'(\w+)(\(.*?\))?', type_)
- if match:
- coltype = match.group(1)
- args = match.group(2)
- else:
- coltype = "VARCHAR"
- args = ''
- try:
- coltype = self.ischema_names[coltype]
- if args is not None:
- args = re.findall(r'(\d+)', args)
- coltype = coltype(*[int(a) for a in args])
- except KeyError:
- util.warn("Did not recognize type '%s' of column '%s'" %
- (coltype, name))
- coltype = sqltypes.NullType()
-
- columns.append({
- 'name' : name,
- 'type' : coltype,
- 'nullable' : nullable,
- 'default' : default,
- 'autoincrement':default is None,
- 'primary_key': primary_key
- })
- return columns
-
-def patch():
- # fix for http://www.sqlalchemy.org/trac/ticket/2189, backported to 0.6.0
- if sautils.sa_version()[:2] == (0, 6):
- get_columns_fixed = get_columns_06x_fixed
- else:
- get_columns_fixed = get_columns_07x_fixed
- SQLiteDialect.get_columns = get_columns_fixed
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/sqlalchemy2364.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/sqlalchemy2364.py
deleted file mode 100644
index 5720d31a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/sqlalchemy2364.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# 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
-
-def patch():
- # a fix for http://www.sqlalchemy.org/trac/ticket/2364
- from sqlalchemy.dialects.sqlite.base import SQLiteDialect
- old_get_foreign_keys = SQLiteDialect.get_foreign_keys
- def get_foreign_keys_wrapper(*args, **kwargs):
- fkeys = old_get_foreign_keys(*args, **kwargs)
- # foreign keys don't have names
- for fkey in fkeys:
- fkey['name'] = None
- return fkeys
- SQLiteDialect.get_foreign_keys = get_foreign_keys_wrapper
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/testcase_patch.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/testcase_patch.py
deleted file mode 100644
index f626f4f7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/monkeypatches/testcase_patch.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# 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 sys
-import twisted
-from twisted.trial import unittest
-
-def patch_testcase_patch():
- """
- Patch out TestCase.patch to skip the test on version combinations where it
- does not work.
-
- (used for debugging only)
- """
- # Twisted-9.0.0 and earlier did not have a UnitTest.patch that worked on
- # Python-2.7
- if twisted.version.major <= 9 and sys.version_info[:2] == (2,7):
- def nopatch(self, *args):
- raise unittest.SkipTest('unittest.TestCase.patch is not available')
- unittest.TestCase.patch = nopatch
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/pbmanager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/pbmanager.py
deleted file mode 100644
index d499c112..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/pbmanager.py
+++ /dev/null
@@ -1,187 +0,0 @@
-# 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
-
-from zope.interface import implements
-from twisted.spread import pb
-from twisted.python import failure, log
-from twisted.internet import defer
-from twisted.cred import portal, checkers, credentials, error
-from twisted.application import service, strports
-
-debug = False
-
-class PBManager(service.MultiService):
- """
- A centralized manager for PB ports and authentication on them.
-
- Allows various pieces of code to request a (port, username) combo, along
- with a password and a perspective factory.
- """
- def __init__(self):
- service.MultiService.__init__(self)
- self.setName('pbmanager')
- self.dispatchers = {}
-
- def register(self, portstr, username, password, pfactory):
- """
- Register a perspective factory PFACTORY to be executed when a PB
- connection arrives on PORTSTR with USERNAME/PASSWORD. Returns a
- Registration object which can be used to unregister later.
- """
- # do some basic normalization of portstrs
- if type(portstr) == type(0) or ':' not in portstr:
- portstr = "tcp:%s" % portstr
-
- reg = Registration(self, portstr, username)
-
- if portstr not in self.dispatchers:
- disp = self.dispatchers[portstr] = Dispatcher(portstr)
- disp.setServiceParent(self)
- else:
- disp = self.dispatchers[portstr]
-
- disp.register(username, password, pfactory)
-
- return reg
-
- def _unregister(self, registration):
- disp = self.dispatchers[registration.portstr]
- disp.unregister(registration.username)
- registration.username = None
- if not disp.users:
- disp = self.dispatchers[registration.portstr]
- del self.dispatchers[registration.portstr]
- return disp.disownServiceParent()
- return defer.succeed(None)
-
-class Registration(object):
- def __init__(self, pbmanager, portstr, username):
- self.portstr = portstr
- "portstr this registration is active on"
- self.username = username
- "username of this registration"
-
- self.pbmanager = pbmanager
-
- def __repr__(self):
- return "<pbmanager.Registration for %s on %s>" % \
- (self.username, self.portstr)
-
- def unregister(self):
- """
- Unregister this registration, removing the username from the port, and
- closing the port if there are no more users left. Returns a Deferred.
- """
- return self.pbmanager._unregister(self)
-
- def getPort(self):
- """
- Helper method for testing; returns the TCP port used for this
- registration, even if it was specified as 0 and thus allocated by the
- OS.
- """
- disp = self.pbmanager.dispatchers[self.portstr]
- return disp.port.getHost().port
-
-
-class Dispatcher(service.Service):
- implements(portal.IRealm, checkers.ICredentialsChecker)
-
- credentialInterfaces = [ credentials.IUsernamePassword,
- credentials.IUsernameHashedPassword ]
-
- def __init__(self, portstr):
- self.portstr = portstr
- self.users = {}
-
- # there's lots of stuff to set up for a PB connection!
- self.portal = portal.Portal(self)
- self.portal.registerChecker(self)
- self.serverFactory = pb.PBServerFactory(self.portal)
- self.serverFactory.unsafeTracebacks = True
- self.port = strports.listen(portstr, self.serverFactory)
-
- def __repr__(self):
- return "<pbmanager.Dispatcher for %s on %s>" % \
- (", ".join(self.users.keys()), self.portstr)
-
- def stopService(self):
- # stop listening on the port when shut down
- d = defer.maybeDeferred(self.port.stopListening)
- d.addCallback(lambda _ : service.Service.stopService(self))
- return d
-
- def register(self, username, password, pfactory):
- if debug:
- log.msg("registering username '%s' on pb port %s: %s"
- % (username, self.portstr, pfactory))
- if username in self.users:
- raise KeyError, ("username '%s' is already registered on PB port %s"
- % (username, self.portstr))
- self.users[username] = (password, pfactory)
-
- def unregister(self, username):
- if debug:
- log.msg("unregistering username '%s' on pb port %s"
- % (username, self.portstr))
- del self.users[username]
-
- # IRealm
-
- def requestAvatar(self, username, mind, interface):
- assert interface == pb.IPerspective
- if username not in self.users:
- d = defer.succeed(None) # no perspective
- else:
- _, afactory = self.users.get(username)
- d = defer.maybeDeferred(afactory, mind, username)
-
- # check that we got a perspective
- def check(persp):
- if not persp:
- raise ValueError("no perspective for '%s'" % username)
- return persp
- d.addCallback(check)
-
- # call the perspective's attached(mind)
- def call_attached(persp):
- d = defer.maybeDeferred(persp.attached, mind)
- d.addCallback(lambda _ : persp) # keep returning the perspective
- return d
- d.addCallback(call_attached)
-
- # return the tuple requestAvatar is expected to return
- def done(persp):
- return (pb.IPerspective, persp, lambda: persp.detached(mind))
- d.addCallback(done)
-
- return d
-
- # ICredentialsChecker
-
- def requestAvatarId(self, creds):
- if creds.username in self.users:
- password, _ = self.users[creds.username]
- d = defer.maybeDeferred(creds.checkPassword, password)
- def check(matched):
- if not matched:
- log.msg("invalid login from user '%s'" % creds.username)
- return failure.Failure(error.UnauthorizedLogin())
- return creds.username
- d.addCallback(check)
- return d
- else:
- log.msg("invalid login from unknown user '%s'" % creds.username)
- return defer.fail(error.UnauthorizedLogin())
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/pbutil.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/pbutil.py
deleted file mode 100644
index b1ef76d4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/pbutil.py
+++ /dev/null
@@ -1,155 +0,0 @@
-# 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
-
-
-"""Base classes handy for use with PB clients.
-"""
-
-from twisted.spread import pb
-
-from twisted.spread.pb import PBClientFactory
-from twisted.internet import protocol
-from twisted.python import log
-
-class NewCredPerspective(pb.Avatar):
- def attached(self, mind):
- return self
- def detached(self, mind):
- pass
-
-class ReconnectingPBClientFactory(PBClientFactory,
- protocol.ReconnectingClientFactory):
- """Reconnecting client factory for PB brokers.
-
- Like PBClientFactory, but if the connection fails or is lost, the factory
- will attempt to reconnect.
-
- Instead of using f.getRootObject (which gives a Deferred that can only
- be fired once), override the gotRootObject method.
-
- Instead of using the newcred f.login (which is also one-shot), call
- f.startLogin() with the credentials and client, and override the
- gotPerspective method.
-
- Instead of using the oldcred f.getPerspective (also one-shot), call
- f.startGettingPerspective() with the same arguments, and override
- gotPerspective.
-
- gotRootObject and gotPerspective will be called each time the object is
- received (once per successful connection attempt). You will probably want
- to use obj.notifyOnDisconnect to find out when the connection is lost.
-
- If an authorization error occurs, failedToGetPerspective() will be
- invoked.
-
- To use me, subclass, then hand an instance to a connector (like
- TCPClient).
- """
-
- def __init__(self):
- PBClientFactory.__init__(self)
- self._doingLogin = False
- self._doingGetPerspective = False
-
- def clientConnectionFailed(self, connector, reason):
- PBClientFactory.clientConnectionFailed(self, connector, reason)
- # Twisted-1.3 erroneously abandons the connection on non-UserErrors.
- # To avoid this bug, don't upcall, and implement the correct version
- # of the method here.
- if self.continueTrying:
- self.connector = connector
- self.retry()
-
- def clientConnectionLost(self, connector, reason):
- PBClientFactory.clientConnectionLost(self, connector, reason,
- reconnecting=True)
- RCF = protocol.ReconnectingClientFactory
- RCF.clientConnectionLost(self, connector, reason)
-
- def clientConnectionMade(self, broker):
- self.resetDelay()
- PBClientFactory.clientConnectionMade(self, broker)
- if self._doingLogin:
- self.doLogin(self._root)
- if self._doingGetPerspective:
- self.doGetPerspective(self._root)
- self.gotRootObject(self._root)
-
- # oldcred methods
-
- def getPerspective(self, *args):
- raise RuntimeError, "getPerspective is one-shot: use startGettingPerspective instead"
-
- def startGettingPerspective(self, username, password, serviceName,
- perspectiveName=None, client=None):
- self._doingGetPerspective = True
- if perspectiveName == None:
- perspectiveName = username
- self._oldcredArgs = (username, password, serviceName,
- perspectiveName, client)
-
- def doGetPerspective(self, root):
- # oldcred getPerspective()
- (username, password,
- serviceName, perspectiveName, client) = self._oldcredArgs
- d = self._cbAuthIdentity(root, username, password)
- d.addCallback(self._cbGetPerspective,
- serviceName, perspectiveName, client)
- d.addCallbacks(self.gotPerspective, self.failedToGetPerspective)
-
-
- # newcred methods
-
- def login(self, *args):
- raise RuntimeError, "login is one-shot: use startLogin instead"
-
- def startLogin(self, credentials, client=None):
- self._credentials = credentials
- self._client = client
- self._doingLogin = True
-
- def doLogin(self, root):
- # newcred login()
- d = self._cbSendUsername(root, self._credentials.username,
- self._credentials.password, self._client)
- d.addCallbacks(self.gotPerspective, self.failedToGetPerspective)
-
-
- # methods to override
-
- def gotPerspective(self, perspective):
- """The remote avatar or perspective (obtained each time this factory
- connects) is now available."""
- pass
-
- def gotRootObject(self, root):
- """The remote root object (obtained each time this factory connects)
- is now available. This method will be called each time the connection
- is established and the object reference is retrieved."""
- pass
-
- def failedToGetPerspective(self, why):
- """The login process failed, most likely because of an authorization
- failure (bad password), but it is also possible that we lost the new
- connection before we managed to send our credentials.
- """
- log.msg("ReconnectingPBClientFactory.failedToGetPerspective")
- if why.check(pb.PBConnectionLost):
- log.msg("we lost the brand-new connection")
- # retrying might help here, let clientConnectionLost decide
- return
- # probably authorization
- self.stopTrying() # logging in harder won't help
- log.err(why)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/base.py
deleted file mode 100644
index 6735e932..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/base.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# 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
-
-from buildbot.process.build import Build
-_hush_pyflakes = [ Build ]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/botmaster.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/botmaster.py
deleted file mode 100644
index f2c3b9fe..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/botmaster.py
+++ /dev/null
@@ -1,492 +0,0 @@
-# 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
-
-
-from twisted.python import log, reflect
-from twisted.python.failure import Failure
-from twisted.internet import defer, reactor
-from twisted.spread import pb
-from twisted.application import service
-
-from buildbot.process.builder import Builder
-from buildbot import interfaces, locks, config, util
-from buildbot.process import metrics
-from buildbot.process.buildrequestdistributor import BuildRequestDistributor
-
-class BotMaster(config.ReconfigurableServiceMixin, service.MultiService):
-
- """This is the master-side service which manages remote buildbot slaves.
- It provides them with BuildSlaves, and distributes build requests to
- them."""
-
- debug = 0
-
- def __init__(self, master):
- service.MultiService.__init__(self)
- self.setName("botmaster")
- self.master = master
-
- self.builders = {}
- self.builderNames = []
- # builders maps Builder names to instances of bb.p.builder.Builder,
- # which is the master-side object that defines and controls a build.
-
- # self.slaves contains a ready BuildSlave instance for each
- # potential buildslave, i.e. all the ones listed in the config file.
- # If the slave is connected, self.slaves[slavename].slave will
- # contain a RemoteReference to their Bot instance. If it is not
- # connected, that attribute will hold None.
- self.slaves = {} # maps slavename to BuildSlave
- self.watchers = {}
-
- # self.locks holds the real Lock instances
- self.locks = {}
-
- # self.mergeRequests is the callable override for merging build
- # requests
- self.mergeRequests = None
-
- self.shuttingDown = False
-
- self.lastSlavePortnum = None
-
- # subscription to new build requests
- self.buildrequest_sub = None
-
- # a distributor for incoming build requests; see below
- self.brd = BuildRequestDistributor(self)
- self.brd.setServiceParent(self)
-
- def cleanShutdown(self, _reactor=reactor):
- """Shut down the entire process, once all currently-running builds are
- complete."""
- if self.shuttingDown:
- return
- log.msg("Initiating clean shutdown")
- self.shuttingDown = True
-
- # first, stop the distributor; this will finish any ongoing scheduling
- # operations before firing
- d = self.brd.stopService()
-
- # then wait for all builds to finish
- def wait(_):
- l = []
- for builder in self.builders.values():
- for build in builder.builder_status.getCurrentBuilds():
- l.append(build.waitUntilFinished())
- if len(l) == 0:
- log.msg("No running jobs, starting shutdown immediately")
- else:
- log.msg("Waiting for %i build(s) to finish" % len(l))
- return defer.DeferredList(l)
- d.addCallback(wait)
-
- # Finally, shut the whole process down
- def shutdown(ign):
- # Double check that we're still supposed to be shutting down
- # The shutdown may have been cancelled!
- if self.shuttingDown:
- # Check that there really aren't any running builds
- for builder in self.builders.values():
- n = len(builder.builder_status.getCurrentBuilds())
- if n > 0:
- log.msg("Not shutting down, builder %s has %i builds running" % (builder, n))
- log.msg("Trying shutdown sequence again")
- self.shuttingDown = False
- self.cleanShutdown()
- return
- log.msg("Stopping reactor")
- _reactor.stop()
- else:
- self.brd.startService()
- d.addCallback(shutdown)
- d.addErrback(log.err, 'while processing cleanShutdown')
-
- def cancelCleanShutdown(self):
- """Cancel a clean shutdown that is already in progress, if any"""
- if not self.shuttingDown:
- return
- log.msg("Cancelling clean shutdown")
- self.shuttingDown = False
-
- @metrics.countMethod('BotMaster.slaveLost()')
- def slaveLost(self, bot):
- metrics.MetricCountEvent.log("BotMaster.attached_slaves", -1)
- for name, b in self.builders.items():
- if bot.slavename in b.config.slavenames:
- b.detached(bot)
-
- @metrics.countMethod('BotMaster.getBuildersForSlave()')
- def getBuildersForSlave(self, slavename):
- return [ b for b in self.builders.values()
- if slavename in b.config.slavenames ]
-
- def getBuildernames(self):
- return self.builderNames
-
- def getBuilders(self):
- return self.builders.values()
-
- def startService(self):
- def buildRequestAdded(notif):
- self.maybeStartBuildsForBuilder(notif['buildername'])
- self.buildrequest_sub = \
- self.master.subscribeToBuildRequests(buildRequestAdded)
- service.MultiService.startService(self)
-
- @defer.inlineCallbacks
- def reconfigService(self, new_config):
- timer = metrics.Timer("BotMaster.reconfigService")
- timer.start()
-
- # reconfigure slaves
- yield self.reconfigServiceSlaves(new_config)
-
- # reconfigure builders
- yield self.reconfigServiceBuilders(new_config)
-
- # call up
- yield config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
- # try to start a build for every builder; this is necessary at master
- # startup, and a good idea in any other case
- self.maybeStartBuildsForAllBuilders()
-
- timer.stop()
-
-
- @defer.inlineCallbacks
- def reconfigServiceSlaves(self, new_config):
-
- timer = metrics.Timer("BotMaster.reconfigServiceSlaves")
- timer.start()
-
- # arrange slaves by name
- old_by_name = dict([ (s.slavename, s)
- for s in list(self)
- if interfaces.IBuildSlave.providedBy(s) ])
- old_set = set(old_by_name.iterkeys())
- new_by_name = dict([ (s.slavename, s)
- for s in new_config.slaves ])
- new_set = set(new_by_name.iterkeys())
-
- # calculate new slaves, by name, and removed slaves
- removed_names, added_names = util.diffSets(old_set, new_set)
-
- # find any slaves for which the fully qualified class name has
- # changed, and treat those as an add and remove
- for n in old_set & new_set:
- old = old_by_name[n]
- new = new_by_name[n]
- # detect changed class name
- if reflect.qual(old.__class__) != reflect.qual(new.__class__):
- removed_names.add(n)
- added_names.add(n)
-
- if removed_names or added_names:
- log.msg("adding %d new slaves, removing %d" %
- (len(added_names), len(removed_names)))
-
- for n in removed_names:
- slave = old_by_name[n]
-
- del self.slaves[n]
- slave.master = None
- slave.botmaster = None
-
- yield defer.maybeDeferred(lambda :
- slave.disownServiceParent())
-
- for n in added_names:
- slave = new_by_name[n]
- slave.setServiceParent(self)
- self.slaves[n] = slave
-
- metrics.MetricCountEvent.log("num_slaves",
- len(self.slaves), absolute=True)
-
- timer.stop()
-
-
- @defer.inlineCallbacks
- def reconfigServiceBuilders(self, new_config):
-
- timer = metrics.Timer("BotMaster.reconfigServiceBuilders")
- timer.start()
-
- # arrange builders by name
- old_by_name = dict([ (b.name, b)
- for b in list(self)
- if isinstance(b, Builder) ])
- old_set = set(old_by_name.iterkeys())
- new_by_name = dict([ (bc.name, bc)
- for bc in new_config.builders ])
- new_set = set(new_by_name.iterkeys())
-
- # calculate new builders, by name, and removed builders
- removed_names, added_names = util.diffSets(old_set, new_set)
-
- if removed_names or added_names:
- log.msg("adding %d new builders, removing %d" %
- (len(added_names), len(removed_names)))
-
- for n in removed_names:
- builder = old_by_name[n]
-
- del self.builders[n]
- builder.master = None
- builder.botmaster = None
-
- yield defer.maybeDeferred(lambda :
- builder.disownServiceParent())
-
- for n in added_names:
- builder = Builder(n)
- self.builders[n] = builder
-
- builder.botmaster = self
- builder.master = self.master
- builder.setServiceParent(self)
-
- # Use order according to configuration files builders list
- self.builderNames = list([ (bc.name) for bc in new_config.builders ])
-
- metrics.MetricCountEvent.log("num_builders",
- len(self.builders), absolute=True)
-
- timer.stop()
-
-
- def stopService(self):
- if self.buildrequest_sub:
- self.buildrequest_sub.unsubscribe()
- self.buildrequest_sub = None
- for b in self.builders.values():
- b.builder_status.addPointEvent(["master", "shutdown"])
- b.builder_status.saveYourself()
- return service.MultiService.stopService(self)
-
- def getLockByID(self, lockid):
- """Convert a Lock identifier into an actual Lock instance.
- @param lockid: a locks.MasterLock or locks.SlaveLock instance
- @return: a locks.RealMasterLock or locks.RealSlaveLock instance
- """
- assert isinstance(lockid, (locks.MasterLock, locks.SlaveLock))
- if not lockid in self.locks:
- self.locks[lockid] = lockid.lockClass(lockid)
- # if the master.cfg file has changed maxCount= on the lock, the next
- # time a build is started, they'll get a new RealLock instance. Note
- # that this requires that MasterLock and SlaveLock (marker) instances
- # be hashable and that they should compare properly.
- return self.locks[lockid]
-
- def getLockFromLockAccess(self, access):
- # Convert a lock-access object into an actual Lock instance.
- if not isinstance(access, locks.LockAccess):
- # Buildbot 0.7.7 compability: user did not specify access
- access = access.defaultAccess()
- lock = self.getLockByID(access.lockid)
- return lock
-
- def maybeStartBuildsForBuilder(self, buildername):
- """
- Call this when something suggests that a particular builder may now
- be available to start a build.
-
- @param buildername: the name of the builder
- """
- self.brd.maybeStartBuildsOn([buildername])
-
- def maybeStartBuildsForSlave(self, slave_name):
- """
- Call this when something suggests that a particular slave may now be
- available to start a build.
-
- @param slave_name: the name of the slave
- """
- builders = self.getBuildersForSlave(slave_name)
- self.brd.maybeStartBuildsOn([ b.name for b in builders ])
-
- def maybeStartBuildsForAllBuilders(self):
- """
- Call this when something suggests that this would be a good time to
- start some builds, but nothing more specific.
- """
- self.brd.maybeStartBuildsOn(self.builderNames)
-
-
-class DuplicateSlaveArbitrator(object):
- """Utility class to arbitrate the situation when a new slave connects with
- the name of an existing, connected slave
-
- @ivar buildslave: L{buildbot.process.slavebuilder.AbstractBuildSlave}
- instance
- @ivar old_remote: L{RemoteReference} to the old slave
- @ivar new_remote: L{RemoteReference} to the new slave
- """
- _reactor = reactor # for testing
-
- # There are several likely duplicate slave scenarios in practice:
- #
- # 1. two slaves are configured with the same username/password
- #
- # 2. the same slave process believes it is disconnected (due to a network
- # hiccup), and is trying to reconnect
- #
- # For the first case, we want to prevent the two slaves from repeatedly
- # superseding one another (which results in lots of failed builds), so we
- # will prefer the old slave. However, for the second case we need to
- # detect situations where the old slave is "gone". Sometimes "gone" means
- # that the TCP/IP connection to it is in a long timeout period (10-20m,
- # depending on the OS configuration), so this can take a while.
-
- PING_TIMEOUT = 10
- """Timeout for pinging the old slave. Set this to something quite long, as
- a very busy slave (e.g., one sending a big log chunk) may take a while to
- return a ping.
- """
-
- def __init__(self, buildslave):
- self.buildslave = buildslave
- self.old_remote = self.buildslave.slave
-
- def getPerspective(self, mind, slavename):
- self.new_remote = mind
- self.ping_old_slave_done = False
- self.old_slave_connected = True
- self.ping_new_slave_done = False
-
- old_tport = self.old_remote.broker.transport
- new_tport = self.new_remote.broker.transport
- log.msg("duplicate slave %s; delaying new slave (%s) and pinging old "
- "(%s)" % (self.buildslave.slavename, new_tport.getPeer(),
- old_tport.getPeer()))
-
- # delay the new slave until we decide what to do with it
- d = self.new_slave_d = defer.Deferred()
-
- # Ping the old slave. If this kills it, then we can allow the new
- # slave to connect. If this does not kill it, then we disconnect
- # the new slave.
- self.ping_old_slave(new_tport.getPeer())
-
- # Print a message on the new slave, if possible.
- self.ping_new_slave()
-
- return d
-
- def ping_new_slave(self):
- d = defer.maybeDeferred(lambda :
- self.new_remote.callRemote("print", "master already has a "
- "connection named '%s' - checking its liveness"
- % self.buildslave.slavename))
- def done(_):
- # failure or success, doesn't matter - the ping is done.
- self.ping_new_slave_done = True
- self.maybe_done()
- d.addBoth(done)
-
- def ping_old_slave(self, new_peer):
- # set a timer on this ping, in case the network is bad. TODO: a
- # timeout on the ping itself is not quite what we want. If there is
- # other data flowing over the PB connection, then we should keep
- # waiting. Bug #1703
- def timeout():
- self.ping_old_slave_timeout = None
- self.ping_old_slave_timed_out = True
- self.old_slave_connected = False
- self.ping_old_slave_done = True
- self.maybe_done()
- self.ping_old_slave_timeout = self._reactor.callLater(
- self.PING_TIMEOUT, timeout)
- self.ping_old_slave_timed_out = False
-
- # call this in maybeDeferred because callRemote tends to raise
- # exceptions instead of returning Failures
- d = defer.maybeDeferred(lambda :
- self.old_remote.callRemote("print",
- "master got a duplicate connection from %s; keeping this one"
- % new_peer))
-
- def clear_timeout(r):
- if self.ping_old_slave_timeout:
- self.ping_old_slave_timeout.cancel()
- self.ping_old_slave_timeout = None
- return r
- d.addBoth(clear_timeout)
-
- def old_gone(f):
- if self.ping_old_slave_timed_out:
- return # ignore after timeout
- f.trap(pb.PBConnectionLost, pb.DeadReferenceError)
- log.msg(("connection lost while pinging old slave '%s' - " +
- "keeping new slave") % self.buildslave.slavename)
- self.old_slave_connected = False
- d.addErrback(old_gone)
-
- def other_err(f):
- log.err(f, "unexpected error pinging old slave; disconnecting it")
- self.old_slave_connected = False
- d.addErrback(other_err)
-
- def done(_):
- if self.ping_old_slave_timed_out:
- return # ignore after timeout
- self.ping_old_slave_done = True
- self.maybe_done()
- d.addCallback(done)
-
- def maybe_done(self):
- if not self.ping_new_slave_done or not self.ping_old_slave_done:
- return
-
- # both pings are done, so sort out the results
- if self.old_slave_connected:
- self.disconnect_new_slave()
- else:
- self.start_new_slave()
-
- def start_new_slave(self):
- # just in case
- if not self.new_slave_d: # pragma: ignore
- return
-
- d = self.new_slave_d
- self.new_slave_d = None
-
- if self.buildslave.isConnected():
- # we need to wait until the old slave has fully detached, which can
- # take a little while as buffers drain, etc.
- def detached():
- d.callback(self.buildslave)
- self.buildslave.subscribeToDetach(detached)
- self.old_remote.broker.transport.loseConnection()
- else: # pragma: ignore
- # by some unusual timing, it's quite possible that the old slave
- # has disconnected while the arbitration was going on. In that
- # case, we're already done!
- d.callback(self.buildslave)
-
- def disconnect_new_slave(self):
- # just in case
- if not self.new_slave_d: # pragma: ignore
- return
-
- d = self.new_slave_d
- self.new_slave_d = None
- log.msg("rejecting duplicate slave with exception")
- d.errback(Failure(RuntimeError("rejecting duplicate slave")))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/build.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/build.py
deleted file mode 100644
index e30d685c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/build.py
+++ /dev/null
@@ -1,567 +0,0 @@
-# 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 types
-
-from zope.interface import implements
-from twisted.python import log, components
-from twisted.python.failure import Failure
-from twisted.internet import defer, error
-
-from buildbot import interfaces
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE, EXCEPTION, \
- RETRY, SKIPPED, worst_status
-from buildbot.status.builder import Results
-from buildbot.status.progress import BuildProgress
-from buildbot.process import metrics, properties
-from buildbot.util.eventual import eventually
-
-
-class Build(properties.PropertiesMixin):
- """I represent a single build by a single slave. Specialized Builders can
- use subclasses of Build to hold status information unique to those build
- processes.
-
- I control B{how} the build proceeds. The actual build is broken up into a
- series of steps, saved in the .buildSteps[] array as a list of
- L{buildbot.process.step.BuildStep} objects. Each step is a single remote
- command, possibly a shell command.
-
- During the build, I put status information into my C{BuildStatus}
- gatherer.
-
- After the build, I go away.
-
- I can be used by a factory by setting buildClass on
- L{buildbot.process.factory.BuildFactory}
-
- @ivar requests: the list of L{BuildRequest}s that triggered me
- @ivar build_status: the L{buildbot.status.build.BuildStatus} that
- collects our status
- """
-
- implements(interfaces.IBuildControl)
-
- workdir = "build"
- build_status = None
- reason = "changes"
- finished = False
- results = None
- stopped = False
- set_runtime_properties = True
-
- def __init__(self, requests):
- self.requests = requests
- self.locks = []
- # build a source stamp
- self.sources = requests[0].mergeSourceStampsWith(requests[1:])
- self.reason = requests[0].mergeReasons(requests[1:])
-
- self.progress = None
- self.currentStep = None
- self.slaveEnvironment = {}
-
- self.terminate = False
-
- self._acquiringLock = None
-
- def setBuilder(self, builder):
- """
- Set the given builder as our builder.
-
- @type builder: L{buildbot.process.builder.Builder}
- """
- self.builder = builder
-
- def setLocks(self, lockList):
- # convert all locks into their real forms
- self.locks = [(self.builder.botmaster.getLockFromLockAccess(access), access)
- for access in lockList ]
-
- def setSlaveEnvironment(self, env):
- self.slaveEnvironment = env
-
- def getSourceStamp(self, codebase=''):
- for source in self.sources:
- if source.codebase == codebase:
- return source
- return None
-
- def getAllSourceStamps(self):
- return list(self.sources)
-
- def allChanges(self):
- for s in self.sources:
- for c in s.changes:
- yield c
-
- def allFiles(self):
- # return a list of all source files that were changed
- files = []
- for c in self.allChanges():
- for f in c.files:
- files.append(f)
- return files
-
- def __repr__(self):
- return "<Build %s>" % (self.builder.name,)
-
- def blamelist(self):
- blamelist = []
- for c in self.allChanges():
- if c.who not in blamelist:
- blamelist.append(c.who)
- for source in self.sources:
- if source.patch_info: #Add patch author to blamelist
- blamelist.append(source.patch_info[0])
- blamelist.sort()
- return blamelist
-
- def changesText(self):
- changetext = ""
- for c in self.allChanges():
- changetext += "-" * 60 + "\n\n" + c.asText() + "\n"
- # consider sorting these by number
- return changetext
-
- def setStepFactories(self, step_factories):
- """Set a list of 'step factories', which are tuples of (class,
- kwargs), where 'class' is generally a subclass of step.BuildStep .
- These are used to create the Steps themselves when the Build starts
- (as opposed to when it is first created). By creating the steps
- later, their __init__ method will have access to things like
- build.allFiles() ."""
- self.stepFactories = list(step_factories)
-
- useProgress = True
-
- def getSlaveCommandVersion(self, command, oldversion=None):
- return self.slavebuilder.getSlaveCommandVersion(command, oldversion)
- def getSlaveName(self):
- return self.slavebuilder.slave.slavename
-
- def setupProperties(self):
- props = interfaces.IProperties(self)
-
- # give the properties a reference back to this build
- props.build = self
-
- # start with global properties from the configuration
- master = self.builder.botmaster.master
- props.updateFromProperties(master.config.properties)
-
- # from the SourceStamps, which have properties via Change
- for change in self.allChanges():
- props.updateFromProperties(change.properties)
-
- # and finally, get any properties from requests (this is the path
- # through which schedulers will send us properties)
- for rq in self.requests:
- props.updateFromProperties(rq.properties)
-
- # now set some properties of our own, corresponding to the
- # build itself
- props.setProperty("buildnumber", self.build_status.number, "Build")
-
- if self.sources and len(self.sources) == 1:
- # old interface for backwards compatibility
- source = self.sources[0]
- props.setProperty("branch", source.branch, "Build")
- props.setProperty("revision", source.revision, "Build")
- props.setProperty("repository", source.repository, "Build")
- props.setProperty("codebase", source.codebase, "Build")
- props.setProperty("project", source.project, "Build")
-
- self.builder.setupProperties(props)
-
- def setupSlaveBuilder(self, slavebuilder):
- self.slavebuilder = slavebuilder
-
- self.path_module = slavebuilder.slave.path_module
-
- # navigate our way back to the L{buildbot.buildslave.BuildSlave}
- # object that came from the config, and get its properties
- buildslave_properties = slavebuilder.slave.properties
- self.getProperties().updateFromProperties(buildslave_properties)
- if slavebuilder.slave.slave_basedir:
- builddir = self.path_module.join(
- slavebuilder.slave.slave_basedir,
- self.builder.config.slavebuilddir)
- self.setProperty("builddir", builddir, "slave")
- self.setProperty("workdir", builddir, "slave (deprecated)")
-
- self.slavename = slavebuilder.slave.slavename
- self.build_status.setSlavename(self.slavename)
-
- def startBuild(self, build_status, expectations, slavebuilder):
- """This method sets up the build, then starts it by invoking the
- first Step. It returns a Deferred which will fire when the build
- finishes. This Deferred is guaranteed to never errback."""
-
- # we are taking responsibility for watching the connection to the
- # remote. This responsibility was held by the Builder until our
- # startBuild was called, and will not return to them until we fire
- # the Deferred returned by this method.
-
- log.msg("%s.startBuild" % self)
- self.build_status = build_status
- # now that we have a build_status, we can set properties
- self.setupProperties()
- self.setupSlaveBuilder(slavebuilder)
- slavebuilder.slave.updateSlaveStatus(buildStarted=build_status)
-
- # then narrow SlaveLocks down to the right slave
- self.locks = [(l.getLock(self.slavebuilder.slave), a)
- for l, a in self.locks ]
- self.remote = slavebuilder.remote
- self.remote.notifyOnDisconnect(self.lostRemote)
-
- metrics.MetricCountEvent.log('active_builds', 1)
-
- d = self.deferred = defer.Deferred()
- def _uncount_build(res):
- metrics.MetricCountEvent.log('active_builds', -1)
- return res
- d.addBoth(_uncount_build)
-
- def _release_slave(res, slave, bs):
- self.slavebuilder.buildFinished()
- slave.updateSlaveStatus(buildFinished=bs)
- return res
- d.addCallback(_release_slave, self.slavebuilder.slave, build_status)
-
- try:
- self.setupBuild(expectations) # create .steps
- except:
- # the build hasn't started yet, so log the exception as a point
- # event instead of flunking the build.
- # TODO: associate this failure with the build instead.
- # this involves doing
- # self.build_status.buildStarted() from within the exception
- # handler
- log.msg("Build.setupBuild failed")
- log.err(Failure())
- self.builder.builder_status.addPointEvent(["setupBuild",
- "exception"])
- self.finished = True
- self.results = EXCEPTION
- self.deferred = None
- d.callback(self)
- return d
-
- self.build_status.buildStarted(self)
- self.acquireLocks().addCallback(self._startBuild_2)
- return d
-
- @staticmethod
- def canStartWithSlavebuilder(lockList, slavebuilder):
- for lock, access in lockList:
- slave_lock = lock.getLock(slavebuilder.slave)
- if not slave_lock.isAvailable(None, access):
- return False
- return True
-
- def acquireLocks(self, res=None):
- self._acquiringLock = None
- if not self.locks:
- return defer.succeed(None)
- if self.stopped:
- return defer.succeed(None)
- log.msg("acquireLocks(build %s, locks %s)" % (self, self.locks))
- for lock, access in self.locks:
- if not lock.isAvailable(self, access):
- log.msg("Build %s waiting for lock %s" % (self, lock))
- d = lock.waitUntilMaybeAvailable(self, access)
- d.addCallback(self.acquireLocks)
- self._acquiringLock = (lock, access, d)
- return d
- # all locks are available, claim them all
- for lock, access in self.locks:
- lock.claim(self, access)
- return defer.succeed(None)
-
- def _startBuild_2(self, res):
- self.startNextStep()
-
- def setupBuild(self, expectations):
- # create the actual BuildSteps. If there are any name collisions, we
- # add a count to the loser until it is unique.
- self.steps = []
- self.stepStatuses = {}
- stepnames = {}
- sps = []
-
- for factory in self.stepFactories:
- step = factory.buildStep()
- step.setBuild(self)
- step.setBuildSlave(self.slavebuilder.slave)
- if callable (self.workdir):
- step.setDefaultWorkdir (self.workdir (self.sources))
- else:
- step.setDefaultWorkdir (self.workdir)
- name = step.name
- if stepnames.has_key(name):
- count = stepnames[name]
- count += 1
- stepnames[name] = count
- name = step.name + "_%d" % count
- else:
- stepnames[name] = 0
- step.name = name
- self.steps.append(step)
-
- # tell the BuildStatus about the step. This will create a
- # BuildStepStatus and bind it to the Step.
- step_status = self.build_status.addStepWithName(name)
- step.setStepStatus(step_status)
-
- sp = None
- if self.useProgress:
- # XXX: maybe bail if step.progressMetrics is empty? or skip
- # progress for that one step (i.e. "it is fast"), or have a
- # separate "variable" flag that makes us bail on progress
- # tracking
- sp = step.setupProgress()
- if sp:
- sps.append(sp)
-
- # Create a buildbot.status.progress.BuildProgress object. This is
- # called once at startup to figure out how to build the long-term
- # Expectations object, and again at the start of each build to get a
- # fresh BuildProgress object to track progress for that individual
- # build. TODO: revisit at-startup call
-
- if self.useProgress:
- self.progress = BuildProgress(sps)
- if self.progress and expectations:
- self.progress.setExpectationsFrom(expectations)
-
- # we are now ready to set up our BuildStatus.
- # pass all sourcestamps to the buildstatus
- self.build_status.setSourceStamps(self.sources)
- self.build_status.setReason(self.reason)
- self.build_status.setBlamelist(self.blamelist())
- self.build_status.setProgress(self.progress)
-
- # gather owners from build requests
- owners = [r.properties['owner'] for r in self.requests
- if r.properties.has_key('owner')]
- if owners: self.setProperty('owners', owners, self.reason)
-
- self.results = [] # list of FAILURE, SUCCESS, WARNINGS, SKIPPED
- self.result = SUCCESS # overall result, may downgrade after each step
- self.text = [] # list of text string lists (text2)
-
- def getNextStep(self):
- """This method is called to obtain the next BuildStep for this build.
- When it returns None (or raises a StopIteration exception), the build
- is complete."""
- if not self.steps:
- return None
- if not self.remote:
- return None
- if self.terminate or self.stopped:
- # Run any remaining alwaysRun steps, and skip over the others
- while True:
- s = self.steps.pop(0)
- if s.alwaysRun:
- return s
- if not self.steps:
- return None
- else:
- return self.steps.pop(0)
-
- def startNextStep(self):
- try:
- s = self.getNextStep()
- except StopIteration:
- s = None
- if not s:
- return self.allStepsDone()
- self.currentStep = s
- d = defer.maybeDeferred(s.startStep, self.remote)
- d.addCallback(self._stepDone, s)
- d.addErrback(self.buildException)
-
- def _stepDone(self, results, step):
- self.currentStep = None
- if self.finished:
- return # build was interrupted, don't keep building
- terminate = self.stepDone(results, step) # interpret/merge results
- if terminate:
- self.terminate = True
- return self.startNextStep()
-
- def stepDone(self, result, step):
- """This method is called when the BuildStep completes. It is passed a
- status object from the BuildStep and is responsible for merging the
- Step's results into those of the overall Build."""
-
- terminate = False
- text = None
- if type(result) == types.TupleType:
- result, text = result
- assert type(result) == type(SUCCESS)
- log.msg(" step '%s' complete: %s" % (step.name, Results[result]))
- self.results.append(result)
- if text:
- self.text.extend(text)
- if not self.remote:
- terminate = True
-
- possible_overall_result = result
- if result == FAILURE:
- if not step.flunkOnFailure:
- possible_overall_result = SUCCESS
- if step.warnOnFailure:
- possible_overall_result = WARNINGS
- if step.flunkOnFailure:
- possible_overall_result = FAILURE
- if step.haltOnFailure:
- terminate = True
- elif result == WARNINGS:
- if not step.warnOnWarnings:
- possible_overall_result = SUCCESS
- else:
- possible_overall_result = WARNINGS
- if step.flunkOnWarnings:
- possible_overall_result = FAILURE
- elif result in (EXCEPTION, RETRY):
- terminate = True
-
- # if we skipped this step, then don't adjust the build status
- if result != SKIPPED:
- self.result = worst_status(self.result, possible_overall_result)
-
- return terminate
-
- def lostRemote(self, remote=None):
- # the slave went away. There are several possible reasons for this,
- # and they aren't necessarily fatal. For now, kill the build, but
- # TODO: see if we can resume the build when it reconnects.
- log.msg("%s.lostRemote" % self)
- self.remote = None
- if self.currentStep:
- # this should cause the step to finish.
- log.msg(" stopping currentStep", self.currentStep)
- self.currentStep.interrupt(Failure(error.ConnectionLost()))
- else:
- self.result = RETRY
- self.text = ["lost", "remote"]
- self.stopped = True
- if self._acquiringLock:
- lock, access, d = self._acquiringLock
- lock.stopWaitingUntilAvailable(self, access, d)
- d.callback(None)
-
- def stopBuild(self, reason="<no reason given>"):
- # the idea here is to let the user cancel a build because, e.g.,
- # they realized they committed a bug and they don't want to waste
- # the time building something that they know will fail. Another
- # reason might be to abandon a stuck build. We want to mark the
- # build as failed quickly rather than waiting for the slave's
- # timeout to kill it on its own.
-
- log.msg(" %s: stopping build: %s" % (self, reason))
- if self.finished:
- return
- # TODO: include 'reason' in this point event
- self.builder.builder_status.addPointEvent(['interrupt'])
- self.stopped = True
- if self.currentStep:
- self.currentStep.interrupt(reason)
-
- self.result = EXCEPTION
-
- if self._acquiringLock:
- lock, access, d = self._acquiringLock
- lock.stopWaitingUntilAvailable(self, access, d)
- d.callback(None)
-
- def allStepsDone(self):
- if self.result == FAILURE:
- text = ["failed"]
- elif self.result == WARNINGS:
- text = ["warnings"]
- elif self.result == EXCEPTION:
- text = ["exception"]
- elif self.result == RETRY:
- text = ["retry"]
- else:
- text = ["build", "successful"]
- text.extend(self.text)
- return self.buildFinished(text, self.result)
-
- def buildException(self, why):
- log.msg("%s.buildException" % self)
- log.err(why)
- # try to finish the build, but since we've already faced an exception,
- # this may not work well.
- try:
- self.buildFinished(["build", "exception"], EXCEPTION)
- except:
- log.err(Failure(), 'while finishing a build with an exception')
-
- def buildFinished(self, text, results):
- """This method must be called when the last Step has completed. It
- marks the Build as complete and returns the Builder to the 'idle'
- state.
-
- It takes two arguments which describe the overall build status:
- text, results. 'results' is one of SUCCESS, WARNINGS, or FAILURE.
-
- If 'results' is SUCCESS or WARNINGS, we will permit any dependant
- builds to start. If it is 'FAILURE', those builds will be
- abandoned."""
-
- self.finished = True
- if self.remote:
- self.remote.dontNotifyOnDisconnect(self.lostRemote)
- self.remote = None
- self.results = results
-
- log.msg(" %s: build finished" % self)
- self.build_status.setText(text)
- self.build_status.setResults(results)
- self.build_status.buildFinished()
- if self.progress and results == SUCCESS:
- # XXX: also test a 'timing consistent' flag?
- log.msg(" setting expectations for next time")
- self.builder.setExpectations(self.progress)
- eventually(self.releaseLocks)
- self.deferred.callback(self)
- self.deferred = None
-
- def releaseLocks(self):
- if self.locks:
- log.msg("releaseLocks(%s): %s" % (self, self.locks))
- for lock, access in self.locks:
- if lock.isOwner(self, access):
- lock.release(self, access)
- else:
- # This should only happen if we've been interrupted
- assert self.stopped
-
- # IBuildControl
-
- def getStatus(self):
- return self.build_status
-
- # stopBuild is defined earlier
-
-components.registerAdapter(
- lambda build : interfaces.IProperties(build.build_status),
- Build, interfaces.IProperties)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/builder.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/builder.py
deleted file mode 100644
index fe521581..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/builder.py
+++ /dev/null
@@ -1,629 +0,0 @@
-# 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 weakref
-from zope.interface import implements
-from twisted.python import log, failure
-from twisted.spread import pb
-from twisted.application import service, internet
-from twisted.internet import defer
-
-from buildbot import interfaces, config
-from buildbot.status.progress import Expectations
-from buildbot.status.builder import RETRY
-from buildbot.status.buildrequest import BuildRequestStatus
-from buildbot.process.properties import Properties
-from buildbot.process import buildrequest, slavebuilder
-from buildbot.process.build import Build
-from buildbot.process.slavebuilder import BUILDING
-
-def enforceChosenSlave(bldr, slavebuilder, breq):
- if 'slavename' in breq.properties:
- slavename = breq.properties['slavename']
- if isinstance(slavename, basestring):
- return slavename==slavebuilder.slave.slavename
-
- return True
-
-class Builder(config.ReconfigurableServiceMixin,
- pb.Referenceable,
- service.MultiService):
-
- # reconfigure builders before slaves
- reconfig_priority = 196
-
- def __init__(self, name, _addServices=True):
- service.MultiService.__init__(self)
- self.name = name
-
- # this is created the first time we get a good build
- self.expectations = None
-
- # build/wannabuild slots: Build objects move along this sequence
- self.building = []
- # old_building holds active builds that were stolen from a predecessor
- self.old_building = weakref.WeakKeyDictionary()
-
- # buildslaves which have connected but which are not yet available.
- # These are always in the ATTACHING state.
- self.attaching_slaves = []
-
- # buildslaves at our disposal. Each SlaveBuilder instance has a
- # .state that is IDLE, PINGING, or BUILDING. "PINGING" is used when a
- # Build is about to start, to make sure that they're still alive.
- self.slaves = []
-
- self.config = None
- self.builder_status = None
-
- if _addServices:
- self.reclaim_svc = internet.TimerService(10*60,
- self.reclaimAllBuilds)
- self.reclaim_svc.setServiceParent(self)
-
- # update big status every 30 minutes, working around #1980
- self.updateStatusService = internet.TimerService(30*60,
- self.updateBigStatus)
- self.updateStatusService.setServiceParent(self)
-
- def reconfigService(self, new_config):
- # find this builder in the config
- for builder_config in new_config.builders:
- if builder_config.name == self.name:
- break
- else:
- assert 0, "no config found for builder '%s'" % self.name
-
- # set up a builder status object on the first reconfig
- if not self.builder_status:
- self.builder_status = self.master.status.builderAdded(
- builder_config.name,
- builder_config.builddir,
- builder_config.category,
- builder_config.description)
-
- self.config = builder_config
-
- self.builder_status.setDescription(builder_config.description)
- self.builder_status.setCategory(builder_config.category)
- self.builder_status.setSlavenames(self.config.slavenames)
- self.builder_status.setCacheSize(new_config.caches['Builds'])
-
- return defer.succeed(None)
-
- def stopService(self):
- d = defer.maybeDeferred(lambda :
- service.MultiService.stopService(self))
- return d
-
- def __repr__(self):
- return "<Builder '%r' at %d>" % (self.name, id(self))
-
- @defer.inlineCallbacks
- def getOldestRequestTime(self):
-
- """Returns the submitted_at of the oldest unclaimed build request for
- this builder, or None if there are no build requests.
-
- @returns: datetime instance or None, via Deferred
- """
- unclaimed = yield self.master.db.buildrequests.getBuildRequests(
- buildername=self.name, claimed=False)
-
- if unclaimed:
- unclaimed = [ brd['submitted_at'] for brd in unclaimed ]
- unclaimed.sort()
- defer.returnValue(unclaimed[0])
- else:
- defer.returnValue(None)
-
- def reclaimAllBuilds(self):
- brids = set()
- for b in self.building:
- brids.update([br.id for br in b.requests])
- for b in self.old_building:
- brids.update([br.id for br in b.requests])
-
- if not brids:
- return defer.succeed(None)
-
- d = self.master.db.buildrequests.reclaimBuildRequests(brids)
- d.addErrback(log.err, 'while re-claiming running BuildRequests')
- return d
-
- def getBuild(self, number):
- for b in self.building:
- if b.build_status and b.build_status.number == number:
- return b
- for b in self.old_building.keys():
- if b.build_status and b.build_status.number == number:
- return b
- return None
-
- def addLatentSlave(self, slave):
- assert interfaces.ILatentBuildSlave.providedBy(slave)
- for s in self.slaves:
- if s == slave:
- break
- else:
- sb = slavebuilder.LatentSlaveBuilder(slave, self)
- self.builder_status.addPointEvent(
- ['added', 'latent', slave.slavename])
- self.slaves.append(sb)
- self.botmaster.maybeStartBuildsForBuilder(self.name)
-
- def attached(self, slave, remote, commands):
- """This is invoked by the BuildSlave when the self.slavename bot
- registers their builder.
-
- @type slave: L{buildbot.buildslave.BuildSlave}
- @param slave: the BuildSlave that represents the buildslave as a whole
- @type remote: L{twisted.spread.pb.RemoteReference}
- @param remote: a reference to the L{buildbot.slave.bot.SlaveBuilder}
- @type commands: dict: string -> string, or None
- @param commands: provides the slave's version of each RemoteCommand
-
- @rtype: L{twisted.internet.defer.Deferred}
- @return: a Deferred that fires (with 'self') when the slave-side
- builder is fully attached and ready to accept commands.
- """
- for s in self.attaching_slaves + self.slaves:
- if s.slave == slave:
- # already attached to them. This is fairly common, since
- # attached() gets called each time we receive the builder
- # list from the slave, and we ask for it each time we add or
- # remove a builder. So if the slave is hosting builders
- # A,B,C, and the config file changes A, we'll remove A and
- # re-add it, triggering two builder-list requests, getting
- # two redundant calls to attached() for B, and another two
- # for C.
- #
- # Therefore, when we see that we're already attached, we can
- # just ignore it.
- return defer.succeed(self)
-
- sb = slavebuilder.SlaveBuilder()
- sb.setBuilder(self)
- self.attaching_slaves.append(sb)
- d = sb.attached(slave, remote, commands)
- d.addCallback(self._attached)
- d.addErrback(self._not_attached, slave)
- return d
-
- def _attached(self, sb):
- self.builder_status.addPointEvent(['connect', sb.slave.slavename])
- self.attaching_slaves.remove(sb)
- self.slaves.append(sb)
-
- self.updateBigStatus()
-
- return self
-
- def _not_attached(self, why, slave):
- # already log.err'ed by SlaveBuilder._attachFailure
- # TODO: remove from self.slaves (except that detached() should get
- # run first, right?)
- log.err(why, 'slave failed to attach')
- self.builder_status.addPointEvent(['failed', 'connect',
- slave.slavename])
- # TODO: add an HTMLLogFile of the exception
-
- def detached(self, slave):
- """This is called when the connection to the bot is lost."""
- for sb in self.attaching_slaves + self.slaves:
- if sb.slave == slave:
- break
- else:
- log.msg("WEIRD: Builder.detached(%s) (%s)"
- " not in attaching_slaves(%s)"
- " or slaves(%s)" % (slave, slave.slavename,
- self.attaching_slaves,
- self.slaves))
- return
- if sb.state == BUILDING:
- # the Build's .lostRemote method (invoked by a notifyOnDisconnect
- # handler) will cause the Build to be stopped, probably right
- # after the notifyOnDisconnect that invoked us finishes running.
- pass
-
- if sb in self.attaching_slaves:
- self.attaching_slaves.remove(sb)
- if sb in self.slaves:
- self.slaves.remove(sb)
-
- self.builder_status.addPointEvent(['disconnect', slave.slavename])
- sb.detached() # inform the SlaveBuilder that their slave went away
- self.updateBigStatus()
-
- def updateBigStatus(self):
- try:
- # Catch exceptions here, since this is called in a LoopingCall.
- if not self.builder_status:
- return
- if not self.slaves:
- self.builder_status.setBigState("offline")
- elif self.building or self.old_building:
- self.builder_status.setBigState("building")
- else:
- self.builder_status.setBigState("idle")
- except Exception:
- log.err(None, "while trying to update status of builder '%s'" % (self.name,))
-
- def getAvailableSlaves(self):
- return [ sb for sb in self.slaves if sb.isAvailable() ]
-
- def canStartWithSlavebuilder(self, slavebuilder):
- locks = [(self.botmaster.getLockFromLockAccess(access), access)
- for access in self.config.locks ]
- return Build.canStartWithSlavebuilder(locks, slavebuilder)
-
- def canStartBuild(self, slavebuilder, breq):
- if callable(self.config.canStartBuild):
- return defer.maybeDeferred(self.config.canStartBuild, self, slavebuilder, breq)
- return defer.succeed(True)
-
- @defer.inlineCallbacks
- def _startBuildFor(self, slavebuilder, buildrequests):
- """Start a build on the given slave.
- @param build: the L{base.Build} to start
- @param sb: the L{SlaveBuilder} which will host this build
-
- @return: (via Deferred) boolean indicating that the build was
- succesfully started.
- """
-
- # as of the Python versions supported now, try/finally can't be used
- # with a generator expression. So instead, we push cleanup functions
- # into a list so that, at any point, we can abort this operation.
- cleanups = []
- def run_cleanups():
- try:
- while cleanups:
- fn = cleanups.pop()
- fn()
- except:
- log.err(failure.Failure(), "while running %r" % (run_cleanups,))
-
- # the last cleanup we want to perform is to update the big
- # status based on any other cleanup
- cleanups.append(lambda : self.updateBigStatus())
-
- build = self.config.factory.newBuild(buildrequests)
- build.setBuilder(self)
- log.msg("starting build %s using slave %s" % (build, slavebuilder))
-
- # set up locks
- build.setLocks(self.config.locks)
- cleanups.append(lambda : slavebuilder.slave.releaseLocks())
-
- if len(self.config.env) > 0:
- build.setSlaveEnvironment(self.config.env)
-
- # append the build to self.building
- self.building.append(build)
- cleanups.append(lambda : self.building.remove(build))
-
- # update the big status accordingly
- self.updateBigStatus()
-
- try:
- ready = yield slavebuilder.prepare(self.builder_status, build)
- except:
- log.err(failure.Failure(), 'while preparing slavebuilder:')
- ready = False
-
- # If prepare returns True then it is ready and we start a build
- # If it returns false then we don't start a new build.
- if not ready:
- log.msg("slave %s can't build %s after all; re-queueing the "
- "request" % (build, slavebuilder))
- run_cleanups()
- defer.returnValue(False)
- return
-
- # ping the slave to make sure they're still there. If they've
- # fallen off the map (due to a NAT timeout or something), this
- # will fail in a couple of minutes, depending upon the TCP
- # timeout.
- #
- # TODO: This can unnecessarily suspend the starting of a build, in
- # situations where the slave is live but is pushing lots of data to
- # us in a build.
- log.msg("starting build %s.. pinging the slave %s"
- % (build, slavebuilder))
- try:
- ping_success = yield slavebuilder.ping()
- except:
- log.err(failure.Failure(), 'while pinging slave before build:')
- ping_success = False
-
- if not ping_success:
- log.msg("slave ping failed; re-queueing the request")
- run_cleanups()
- defer.returnValue(False)
- return
-
- # The buildslave is ready to go. slavebuilder.buildStarted() sets its
- # state to BUILDING (so we won't try to use it for any other builds).
- # This gets set back to IDLE by the Build itself when it finishes.
- slavebuilder.buildStarted()
- cleanups.append(lambda : slavebuilder.buildFinished())
-
- # tell the remote that it's starting a build, too
- try:
- yield slavebuilder.remote.callRemote("startBuild")
- except:
- log.err(failure.Failure(), 'while calling remote startBuild:')
- run_cleanups()
- defer.returnValue(False)
- return
-
- # create the BuildStatus object that goes with the Build
- bs = self.builder_status.newBuild()
-
- # record the build in the db - one row per buildrequest
- try:
- bids = []
- for req in build.requests:
- bid = yield self.master.db.builds.addBuild(req.id, bs.number)
- bids.append(bid)
- except:
- log.err(failure.Failure(), 'while adding rows to build table:')
- run_cleanups()
- defer.returnValue(False)
- return
-
- # IMPORTANT: no yielding is allowed from here to the startBuild call!
-
- # it's possible that we lost the slave remote between the ping above
- # and now. If so, bail out. The build.startBuild call below transfers
- # responsibility for monitoring this connection to the Build instance,
- # so this check ensures we hand off a working connection.
- if not slavebuilder.remote:
- log.msg("slave disappeared before build could start")
- run_cleanups()
- defer.returnValue(False)
- return
-
- # let status know
- self.master.status.build_started(req.id, self.name, bs)
-
- # start the build. This will first set up the steps, then tell the
- # BuildStatus that it has started, which will announce it to the world
- # (through our BuilderStatus object, which is its parent). Finally it
- # will start the actual build process. This is done with a fresh
- # Deferred since _startBuildFor should not wait until the build is
- # finished. This uses `maybeDeferred` to ensure that any exceptions
- # raised by startBuild are treated as deferred errbacks (see
- # http://trac.buildbot.net/ticket/2428).
- d = defer.maybeDeferred(build.startBuild,
- bs, self.expectations, slavebuilder)
- d.addCallback(self.buildFinished, slavebuilder, bids)
- # this shouldn't happen. if it does, the slave will be wedged
- d.addErrback(log.err, 'from a running build; this is a '
- 'serious error - please file a bug at http://buildbot.net')
-
- # make sure the builder's status is represented correctly
- self.updateBigStatus()
-
- defer.returnValue(True)
-
- def setupProperties(self, props):
- props.setProperty("buildername", self.name, "Builder")
- if len(self.config.properties) > 0:
- for propertyname in self.config.properties:
- props.setProperty(propertyname,
- self.config.properties[propertyname],
- "Builder")
-
- def buildFinished(self, build, sb, bids):
- """This is called when the Build has finished (either success or
- failure). Any exceptions during the build are reported with
- results=FAILURE, not with an errback."""
-
- # by the time we get here, the Build has already released the slave,
- # which will trigger a check for any now-possible build requests
- # (maybeStartBuilds)
-
- # mark the builds as finished, although since nothing ever reads this
- # table, it's not too important that it complete successfully
- d = self.master.db.builds.finishBuilds(bids)
- d.addErrback(log.err, 'while marking builds as finished (ignored)')
-
- results = build.build_status.getResults()
- self.building.remove(build)
- if results == RETRY:
- self._resubmit_buildreqs(build).addErrback(log.err)
- else:
- brids = [br.id for br in build.requests]
- db = self.master.db
- d = db.buildrequests.completeBuildRequests(brids, results)
- d.addCallback(
- lambda _ : self._maybeBuildsetsComplete(build.requests))
- # nothing in particular to do with this deferred, so just log it if
- # it fails..
- d.addErrback(log.err, 'while marking build requests as completed')
-
- if sb.slave:
- sb.slave.releaseLocks()
-
- self.updateBigStatus()
-
- @defer.inlineCallbacks
- def _maybeBuildsetsComplete(self, requests):
- # inform the master that we may have completed a number of buildsets
- for br in requests:
- yield self.master.maybeBuildsetComplete(br.bsid)
-
- def _resubmit_buildreqs(self, build):
- brids = [br.id for br in build.requests]
- return self.master.db.buildrequests.unclaimBuildRequests(brids)
-
- def setExpectations(self, progress):
- """Mark the build as successful and update expectations for the next
- build. Only call this when the build did not fail in any way that
- would invalidate the time expectations generated by it. (if the
- compile failed and thus terminated early, we can't use the last
- build to predict how long the next one will take).
- """
- if self.expectations:
- self.expectations.update(progress)
- else:
- # the first time we get a good build, create our Expectations
- # based upon its results
- self.expectations = Expectations(progress)
- log.msg("new expectations: %s seconds" %
- self.expectations.expectedBuildTime())
-
- # Build Creation
-
- @defer.inlineCallbacks
- def maybeStartBuild(self, slavebuilder, breqs):
- # This method is called by the botmaster whenever this builder should
- # start a set of buildrequests on a slave. Do not call this method
- # directly - use master.botmaster.maybeStartBuildsForBuilder, or one of
- # the other similar methods if more appropriate
-
- # first, if we're not running, then don't start builds; stopService
- # uses this to ensure that any ongoing maybeStartBuild invocations
- # are complete before it stops.
- if not self.running:
- defer.returnValue(False)
- return
-
- # If the build fails from here on out (e.g., because a slave has failed),
- # it will be handled outside of this function. TODO: test that!
-
- build_started = yield self._startBuildFor(slavebuilder, breqs)
- defer.returnValue(build_started)
-
- # a few utility functions to make the maybeStartBuild a bit shorter and
- # easier to read
-
- def getMergeRequestsFn(self):
- """Helper function to determine which mergeRequests function to use
- from L{_mergeRequests}, or None for no merging"""
- # first, seek through builder, global, and the default
- mergeRequests_fn = self.config.mergeRequests
- if mergeRequests_fn is None:
- mergeRequests_fn = self.master.config.mergeRequests
- if mergeRequests_fn is None:
- mergeRequests_fn = True
-
- # then translate False and True properly
- if mergeRequests_fn is False:
- mergeRequests_fn = None
- elif mergeRequests_fn is True:
- mergeRequests_fn = Builder._defaultMergeRequestFn
-
- return mergeRequests_fn
-
- def _defaultMergeRequestFn(self, req1, req2):
- return req1.canBeMergedWith(req2)
-
-
-class BuilderControl:
- implements(interfaces.IBuilderControl)
-
- def __init__(self, builder, control):
- self.original = builder
- self.control = control
-
- def submitBuildRequest(self, ss, reason, props=None):
- d = ss.getSourceStampSetId(self.control.master)
- def add_buildset(sourcestampsetid):
- return self.control.master.addBuildset(
- builderNames=[self.original.name],
- sourcestampsetid=sourcestampsetid, reason=reason, properties=props)
- d.addCallback(add_buildset)
- def get_brs((bsid,brids)):
- brs = BuildRequestStatus(self.original.name,
- brids[self.original.name],
- self.control.master.status)
- return brs
- d.addCallback(get_brs)
- return d
-
- @defer.inlineCallbacks
- def rebuildBuild(self, bs, reason="<rebuild, no reason given>", extraProperties=None):
- if not bs.isFinished():
- return
-
- # Make a copy of the properties so as not to modify the original build.
- properties = Properties()
- # Don't include runtime-set properties in a rebuild request
- properties.updateFromPropertiesNoRuntime(bs.getProperties())
- if extraProperties is None:
- properties.updateFromProperties(extraProperties)
-
- properties_dict = dict((k,(v,s)) for (k,v,s) in properties.asList())
- ssList = bs.getSourceStamps(absolute=True)
-
- if ssList:
- sourcestampsetid = yield ssList[0].getSourceStampSetId(self.control.master)
- dl = []
- for ss in ssList[1:]:
- # add defered to the list
- dl.append(ss.addSourceStampToDatabase(self.control.master, sourcestampsetid))
- yield defer.gatherResults(dl)
-
- bsid, brids = yield self.control.master.addBuildset(
- builderNames=[self.original.name],
- sourcestampsetid=sourcestampsetid,
- reason=reason,
- properties=properties_dict)
- defer.returnValue((bsid, brids))
- else:
- log.msg('Cannot start rebuild, rebuild has no sourcestamps for a new build')
- defer.returnValue(None)
-
- @defer.inlineCallbacks
- def getPendingBuildRequestControls(self):
- master = self.original.master
- brdicts = yield master.db.buildrequests.getBuildRequests(
- buildername=self.original.name,
- claimed=False)
-
- # convert those into BuildRequest objects
- buildrequests = [ ]
- for brdict in brdicts:
- br = yield buildrequest.BuildRequest.fromBrdict(
- self.control.master, brdict)
- buildrequests.append(br)
-
- # and return the corresponding control objects
- defer.returnValue([ buildrequest.BuildRequestControl(self.original, r)
- for r in buildrequests ])
-
- def getBuild(self, number):
- return self.original.getBuild(number)
-
- def ping(self):
- if not self.original.slaves:
- self.original.builder_status.addPointEvent(["ping", "no slave"])
- return defer.succeed(False) # interfaces.NoSlaveError
- dl = []
- for s in self.original.slaves:
- dl.append(s.ping(self.original.builder_status))
- d = defer.DeferredList(dl)
- d.addCallback(self._gatherPingResults)
- return d
-
- def _gatherPingResults(self, res):
- for ignored,success in res:
- if not success:
- return False
- return True
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildrequest.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildrequest.py
deleted file mode 100644
index c9b9daa7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildrequest.py
+++ /dev/null
@@ -1,253 +0,0 @@
-# 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 calendar
-from zope.interface import implements
-from twisted.python import log
-from twisted.internet import defer
-from buildbot import interfaces, sourcestamp
-from buildbot.process import properties
-from buildbot.status.results import FAILURE
-from buildbot.db import buildrequests
-
-class BuildRequest(object):
- """
-
- A rolled-up encapsulation of all of the data relevant to a build request.
-
- This class is used by the C{nextBuild} and C{mergeRequests} configuration
- parameters, as well as in starting a build. Construction of a BuildRequest
- object is a heavyweight process involving a lot of database queries, so
- it should be avoided where possible. See bug #1894.
-
- Build requests have a SourceStamp which specifies what sources to build.
- This may specify a specific revision of the source tree (so source.branch,
- source.revision, and source.patch are used). The .patch attribute is either
- None or a tuple of (patchlevel, diff), consisting of a number to use in
- 'patch -pN', and a unified-format context diff.
-
- Alternatively, the SourceStamp may specify a set of Changes to be built,
- contained in source.changes. In this case, the requeset may be mergeable
- with other BuildRequests on the same branch.
-
- @type source: L{buildbot.sourcestamp.SourceStamp}
- @ivar source: the source stamp that this BuildRequest use
-
- @type reason: string
- @ivar reason: the reason this Build is being requested. Schedulers provide
- this, but for forced builds the user requesting the build will provide a
- string. It comes from the buildsets table.
-
- @type properties: L{properties.Properties}
- @ivar properties: properties that should be applied to this build, taken
- from the buildset containing this build request
-
- @ivar submittedAt: a timestamp (seconds since epoch) when this request was
- submitted to the Builder. This is used by the CVS step to compute a
- checkout timestamp, as well as by the master to prioritize build requests
- from oldest to newest.
-
- @ivar buildername: name of the requested builder
-
- @ivar priority: request priority
-
- @ivar id: build request ID
-
- @ivar bsid: ID of the parent buildset
- """
-
- source = None
- sources = None
- submittedAt = None
-
- @classmethod
- def fromBrdict(cls, master, brdict):
- """
- Construct a new L{BuildRequest} from a dictionary as returned by
- L{BuildRequestsConnectorComponent.getBuildRequest}.
-
- This method uses a cache, which may result in return of stale objects;
- for the most up-to-date information, use the database connector
- methods.
-
- @param master: current build master
- @param brdict: build request dictionary
-
- @returns: L{BuildRequest}, via Deferred
- """
- cache = master.caches.get_cache("BuildRequests", cls._make_br)
- return cache.get(brdict['brid'], brdict=brdict, master=master)
-
- @classmethod
- @defer.inlineCallbacks
- def _make_br(cls, brid, brdict, master):
- buildrequest = cls()
- buildrequest.id = brid
- buildrequest.bsid = brdict['buildsetid']
- buildrequest.buildername = brdict['buildername']
- buildrequest.priority = brdict['priority']
- dt = brdict['submitted_at']
- buildrequest.submittedAt = dt and calendar.timegm(dt.utctimetuple())
- buildrequest.master = master
-
- # fetch the buildset to get the reason
- buildset = yield master.db.buildsets.getBuildset(brdict['buildsetid'])
- assert buildset # schema should guarantee this
- buildrequest.reason = buildset['reason']
-
- # fetch the buildset properties, and convert to Properties
- buildset_properties = yield master.db.buildsets.getBuildsetProperties(brdict['buildsetid'])
-
- buildrequest.properties = properties.Properties.fromDict(buildset_properties)
-
- # fetch the sourcestamp dictionary
- sslist = yield master.db.sourcestamps.getSourceStamps(buildset['sourcestampsetid'])
- assert len(sslist) > 0, "Empty sourcestampset: db schema enforces set to exist but cannot enforce a non empty set"
-
- # and turn it into a SourceStamps
- buildrequest.sources = {}
- def store_source(source):
- buildrequest.sources[source.codebase] = source
-
- dlist = []
- for ssdict in sslist:
- d = sourcestamp.SourceStamp.fromSsdict(master, ssdict)
- d.addCallback(store_source)
- dlist.append(d)
-
- yield defer.gatherResults(dlist)
-
- if buildrequest.sources:
- buildrequest.source = buildrequest.sources.values()[0]
-
- defer.returnValue(buildrequest)
-
- def requestsHaveSameCodebases(self, other):
- self_codebases = set(self.sources.iterkeys())
- other_codebases = set(other.sources.iterkeys())
- return self_codebases == other_codebases
-
- def requestsHaveChangesForSameCodebases(self, other):
- # Merge can only be done if both requests have sourcestampsets containing
- # comparable sourcestamps, that means sourcestamps with the same codebase.
- # This means that both requests must have exact the same set of codebases
- # If not then merge cannot be performed.
- # The second requirement is that both request have the changes in the
- # same codebases.
- #
- # Normaly a scheduler always delivers the same set of codebases:
- # sourcestamps with and without changes
- # For the case a scheduler is not configured with a set of codebases
- # it delivers only a set with sourcestamps that have changes.
- self_codebases = set(self.sources.iterkeys())
- other_codebases = set(other.sources.iterkeys())
- if self_codebases != other_codebases:
- return False
-
- for c in self_codebases:
- # Check either both or neither have changes
- if ((len(self.sources[c].changes) > 0)
- != (len(other.sources[c].changes) > 0)):
- return False
- # all codebases tested, no differences found
- return True
-
- def canBeMergedWith(self, other):
- """
- Returns if both requests can be merged
- """
-
- if not self.requestsHaveChangesForSameCodebases(other):
- return False
-
- #get codebases from myself, they are equal to other
- self_codebases = set(self.sources.iterkeys())
-
- for c in self_codebases:
- # check to prevent exception
- if c not in other.sources:
- return False
- if not self.sources[c].canBeMergedWith(other.sources[c]):
- return False
- return True
-
- def mergeSourceStampsWith(self, others):
- """ Returns one merged sourcestamp for every codebase """
- #get all codebases from all requests
- all_codebases = set(self.sources.iterkeys())
- for other in others:
- all_codebases |= set(other.sources.iterkeys())
-
- all_merged_sources = {}
- # walk along the codebases
- for codebase in all_codebases:
- all_sources = []
- if codebase in self.sources:
- all_sources.append(self.sources[codebase])
- for other in others:
- if codebase in other.sources:
- all_sources.append(other.sources[codebase])
- assert len(all_sources)>0, "each codebase should have atleast one sourcestamp"
- all_merged_sources[codebase] = all_sources[0].mergeWith(all_sources[1:])
-
- return [source for source in all_merged_sources.itervalues()]
-
- def mergeReasons(self, others):
- """Return a reason for the merged build request."""
- reasons = []
- for req in [self] + others:
- if req.reason and req.reason not in reasons:
- reasons.append(req.reason)
- return ", ".join(reasons)
-
- def getSubmitTime(self):
- return self.submittedAt
-
- @defer.inlineCallbacks
- def cancelBuildRequest(self):
- # first, try to claim the request; if this fails, then it's too late to
- # cancel the build anyway
- try:
- yield self.master.db.buildrequests.claimBuildRequests([self.id])
- except buildrequests.AlreadyClaimedError:
- log.msg("build request already claimed; cannot cancel")
- return
-
- # then complete it with 'FAILURE'; this is the closest we can get to
- # cancelling a request without running into trouble with dangling
- # references.
- yield self.master.db.buildrequests.completeBuildRequests([self.id],
- FAILURE)
-
- # and let the master know that the enclosing buildset may be complete
- yield self.master.maybeBuildsetComplete(self.bsid)
-
-class BuildRequestControl:
- implements(interfaces.IBuildRequestControl)
-
- def __init__(self, builder, request):
- self.original_builder = builder
- self.original_request = request
- self.brid = request.id
-
- def subscribe(self, observer):
- raise NotImplementedError
-
- def unsubscribe(self, observer):
- raise NotImplementedError
-
- def cancel(self):
- d = self.original_request.cancelBuildRequest()
- d.addErrback(log.err, 'while cancelling build request')
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildrequestdistributor.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildrequestdistributor.py
deleted file mode 100644
index afae3b8e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildrequestdistributor.py
+++ /dev/null
@@ -1,544 +0,0 @@
-# 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
-
-
-from twisted.python import log
-from twisted.python.failure import Failure
-from twisted.internet import defer
-from twisted.application import service
-
-from buildbot.process import metrics
-from buildbot.process.buildrequest import BuildRequest
-from buildbot.db.buildrequests import AlreadyClaimedError
-
-import random
-
-class BuildChooserBase(object):
- #
- # WARNING: This API is experimental and in active development.
- #
- # This internal object selects a new build+slave pair. It acts as a
- # generator, initializing its state on creation and offering up new
- # pairs until exhaustion. The object can be destroyed at any time
- # (eg, before the list exhausts), and can be "restarted" by abandoning
- # an old instance and creating a new one.
- #
- # The entry point is:
- # * bc.chooseNextBuild() - get the next (slave, [breqs]) or (None, None)
- #
- # The default implementation of this class implements a default
- # chooseNextBuild() that delegates out to two other functions:
- # * bc.popNextBuild() - get the next (slave, breq) pair
- # * bc.mergeRequests(breq) - perform a merge for this breq and return
- # the list of breqs consumed by the merge (including breq itself)
-
- def __init__(self, bldr, master):
- self.bldr = bldr
- self.master = master
- self.breqCache = {}
- self.unclaimedBrdicts = None
-
- @defer.inlineCallbacks
- def chooseNextBuild(self):
- # Return the next build, as a (slave, [breqs]) pair
-
- slave, breq = yield self.popNextBuild()
- if not slave or not breq:
- defer.returnValue((None, None))
- return
-
- breqs = yield self.mergeRequests(breq)
- for b in breqs:
- self._removeBuildRequest(b)
-
- defer.returnValue((slave, breqs))
-
-
- # Must be implemented by subclass
- def popNextBuild(self):
- # Pick the next (slave, breq) pair; note this is pre-merge, so
- # it's just one breq
- raise NotImplementedError("Subclasses must implement this!")
-
- # Must be implemented by subclass
- def mergeRequests(self, breq):
- # Merge the chosen breq with any other breqs that are compatible
- # Returns a list of the breqs chosen (and should include the
- # original breq as well!)
- raise NotImplementedError("Subclasses must implement this!")
-
-
- # - Helper functions that are generally useful to all subclasses -
-
- @defer.inlineCallbacks
- def _fetchUnclaimedBrdicts(self):
- # Sets up a cache of all the unclaimed brdicts. The cache is
- # saved at self.unclaimedBrdicts cache. If the cache already
- # exists, this function does nothing. If a refetch is desired, set
- # the self.unclaimedBrdicts to None before calling."""
-
- if self.unclaimedBrdicts is None:
- brdicts = yield self.master.db.buildrequests.getBuildRequests(
- buildername=self.bldr.name, claimed=False)
- # sort by submitted_at, so the first is the oldest
- brdicts.sort(key=lambda brd : brd['submitted_at'])
- self.unclaimedBrdicts = brdicts
- defer.returnValue(self.unclaimedBrdicts)
-
- @defer.inlineCallbacks
- def _getBuildRequestForBrdict(self, brdict):
- # Turn a brdict into a BuildRequest into a brdict. This is useful
- # for API like 'nextBuild', which operate on BuildRequest objects.
-
- breq = self.breqCache.get(brdict['brid'])
- if not breq:
- breq = yield BuildRequest.fromBrdict(self.master, brdict)
- if breq:
- self.breqCache[brdict['brid']] = breq
- defer.returnValue(breq)
-
- def _getBrdictForBuildRequest(self, breq):
- # Turn a BuildRequest back into a brdict. This operates from the
- # cache, which must be set up once via _fetchUnclaimedBrdicts
-
- if breq is None:
- return None
-
- brid = breq.id
- for brdict in self.unclaimedBrdicts:
- if brid == brdict['brid']:
- return brdict
- return None
-
- def _removeBuildRequest(self, breq):
- # Remove a BuildrRequest object (and its brdict)
- # from the caches
-
- if breq is None:
- return
-
- brdict = self._getBrdictForBuildRequest(breq)
- if brdict is not None:
- self.unclaimedBrdicts.remove(brdict)
-
- if breq.id in self.breqCache:
- del self.breqCache[breq.id]
-
- def _getUnclaimedBuildRequests(self):
- # Retrieve the list of BuildRequest objects for all unclaimed builds
- return defer.gatherResults([
- self._getBuildRequestForBrdict(brdict)
- for brdict in self.unclaimedBrdicts ])
-
-class BasicBuildChooser(BuildChooserBase):
- # BasicBuildChooser generates build pairs via the configuration points:
- # * config.nextSlave (or random.choice if not set)
- # * config.nextBuild (or "pop top" if not set)
- #
- # For N slaves, this will call nextSlave at most N times. If nextSlave
- # returns a slave that cannot satisfy the build chosen by nextBuild,
- # it will search for a slave that can satisfy the build. If one is found,
- # the slaves that cannot be used are "recycled" back into a list
- # to be tried, in order, for the next chosen build.
- #
- # There are two tests performed on the slave:
- # * can the slave start a generic build for the Builder?
- # * if so, can the slave start the chosen build on the Builder?
- # Slaves that cannot meet the first criterion are saved into the
- # self.rejectedSlaves list and will be used as a last resort. An example
- # of this test is whether the slave can grab the Builder's locks.
- #
- # If all slaves fail the first test, then the algorithm will assign the
- # slaves in the order originally generated. By setting self.rejectedSlaves
- # to None, the behavior will instead refuse to ever assign to a slave that
- # fails the generic test.
-
- def __init__(self, bldr, master):
- BuildChooserBase.__init__(self, bldr, master)
-
- self.nextSlave = self.bldr.config.nextSlave
- if not self.nextSlave:
- self.nextSlave = lambda _,slaves: random.choice(slaves) if slaves else None
-
- self.slavepool = self.bldr.getAvailableSlaves()
-
- # Pick slaves one at a time from the pool, and if the Builder says
- # they're usable (eg, locks can be satisfied), then prefer those slaves;
- # otherwise they go in the 'last resort' bucket, and we'll use them if
- # we need to. (Setting rejectedSlaves to None disables that feature)
- self.preferredSlaves = []
- self.rejectedSlaves = []
-
- self.nextBuild = self.bldr.config.nextBuild
-
- self.mergeRequestsFn = self.bldr.getMergeRequestsFn()
-
- @defer.inlineCallbacks
- def popNextBuild(self):
- nextBuild = (None, None)
-
- while 1:
- # 1. pick a slave
- slave = yield self._popNextSlave()
- if not slave:
- break
-
- # 2. pick a build
- breq = yield self._getNextUnclaimedBuildRequest()
- if not breq:
- break
-
- # either satisfy this build or we leave it for another day
- self._removeBuildRequest(breq)
-
- # 3. make sure slave+ is usable for the breq
- recycledSlaves = []
- while slave:
- canStart = yield self.canStartBuild(slave, breq)
- if canStart:
- break
- # try a different slave
- recycledSlaves.append(slave)
- slave = yield self._popNextSlave()
-
- # recycle the slaves that we didnt use to the head of the queue
- # this helps ensure we run 'nextSlave' only once per slave choice
- if recycledSlaves:
- self._unpopSlaves(recycledSlaves)
-
- # 4. done? otherwise we will try another build
- if slave:
- nextBuild = (slave, breq)
- break
-
- defer.returnValue(nextBuild)
-
- @defer.inlineCallbacks
- def mergeRequests(self, breq):
- mergedRequests = [ breq ]
-
- # short circuit if there is no merging to do
- if not self.mergeRequestsFn or not self.unclaimedBrdicts:
- defer.returnValue(mergedRequests)
- return
-
- # we'll need BuildRequest objects, so get those first
- unclaimedBreqs = yield self._getUnclaimedBuildRequests()
-
- # gather the mergeable requests
- for req in unclaimedBreqs:
- canMerge = yield self.mergeRequestsFn(self.bldr, breq, req)
- if canMerge:
- mergedRequests.append(req)
-
- defer.returnValue(mergedRequests)
-
-
- @defer.inlineCallbacks
- def _getNextUnclaimedBuildRequest(self):
- # ensure the cache is there
- yield self._fetchUnclaimedBrdicts()
- if not self.unclaimedBrdicts:
- defer.returnValue(None)
- return
-
- if self.nextBuild:
- # nextBuild expects BuildRequest objects
- breqs = yield self._getUnclaimedBuildRequests()
- try:
- nextBreq = yield self.nextBuild(self.bldr, breqs)
- if nextBreq not in breqs:
- nextBreq = None
- except Exception:
- nextBreq = None
- else:
- # otherwise just return the first build
- brdict = self.unclaimedBrdicts[0]
- nextBreq = yield self._getBuildRequestForBrdict(brdict)
-
- defer.returnValue(nextBreq)
-
- @defer.inlineCallbacks
- def _popNextSlave(self):
- # use 'preferred' slaves first, if we have some ready
- if self.preferredSlaves:
- slave = self.preferredSlaves.pop(0)
- defer.returnValue(slave)
- return
-
- while self.slavepool:
- try:
- slave = yield self.nextSlave(self.bldr, self.slavepool)
- except Exception:
- slave = None
-
- if not slave or slave not in self.slavepool:
- # bad slave or no slave returned
- break
-
- self.slavepool.remove(slave)
-
- canStart = yield self.bldr.canStartWithSlavebuilder(slave)
- if canStart:
- defer.returnValue(slave)
- return
-
- # save as a last resort, just in case we need them later
- if self.rejectedSlaves is not None:
- self.rejectedSlaves.append(slave)
-
- # if we chewed through them all, use as last resort:
- if self.rejectedSlaves:
- slave = self.rejectedSlaves.pop(0)
- defer.returnValue(slave)
- return
-
- defer.returnValue(None)
-
- def _unpopSlaves(self, slaves):
- # push the slaves back to the front
- self.preferredSlaves[:0] = slaves
-
- def canStartBuild(self, slave, breq):
- return self.bldr.canStartBuild(slave, breq)
-
-
-class BuildRequestDistributor(service.Service):
- """
- Special-purpose class to handle distributing build requests to builders by
- calling their C{maybeStartBuild} method.
-
- This takes account of the C{prioritizeBuilders} configuration, and is
- highly re-entrant; that is, if a new build request arrives while builders
- are still working on the previous build request, then this class will
- correctly re-prioritize invocations of builders' C{maybeStartBuild}
- methods.
- """
-
- BuildChooser = BasicBuildChooser
-
- def __init__(self, botmaster):
- self.botmaster = botmaster
- self.master = botmaster.master
-
- # lock to ensure builders are only sorted once at any time
- self.pending_builders_lock = defer.DeferredLock()
-
- # sorted list of names of builders that need their maybeStartBuild
- # method invoked.
- self._pending_builders = []
- self.activity_lock = defer.DeferredLock()
- self.active = False
-
- self._pendingMSBOCalls = []
-
- @defer.inlineCallbacks
- def stopService(self):
- # Lots of stuff happens asynchronously here, so we need to let it all
- # quiesce. First, let the parent stopService succeed between
- # activities; then the loop will stop calling itself, since
- # self.running is false.
- yield self.activity_lock.run(service.Service.stopService, self)
-
- # now let any outstanding calls to maybeStartBuildsOn to finish, so
- # they don't get interrupted in mid-stride. This tends to be
- # particularly painful because it can occur when a generator is gc'd.
- if self._pendingMSBOCalls:
- yield defer.DeferredList(self._pendingMSBOCalls)
-
- def maybeStartBuildsOn(self, new_builders):
- """
- Try to start any builds that can be started right now. This function
- returns immediately, and promises to trigger those builders
- eventually.
-
- @param new_builders: names of new builders that should be given the
- opportunity to check for new requests.
- """
- if not self.running:
- return
-
- d = self._maybeStartBuildsOn(new_builders)
- self._pendingMSBOCalls.append(d)
- @d.addBoth
- def remove(x):
- self._pendingMSBOCalls.remove(d)
- return x
- d.addErrback(log.err, "while strting builds on %s" % (new_builders,))
-
- def _maybeStartBuildsOn(self, new_builders):
- new_builders = set(new_builders)
- existing_pending = set(self._pending_builders)
-
- # if we won't add any builders, there's nothing to do
- if new_builders < existing_pending:
- return defer.succeed(None)
-
- # reset the list of pending builders
- @defer.inlineCallbacks
- def resetPendingBuildersList(new_builders):
- try:
- # re-fetch existing_pending, in case it has changed
- # while acquiring the lock
- existing_pending = set(self._pending_builders)
-
- # then sort the new, expanded set of builders
- self._pending_builders = \
- yield self._sortBuilders(
- list(existing_pending | new_builders))
-
- # start the activity loop, if we aren't already
- # working on that.
- if not self.active:
- self._activityLoop()
- except Exception:
- log.err(Failure(),
- "while attempting to start builds on %s" % self.name)
-
- return self.pending_builders_lock.run(
- resetPendingBuildersList, new_builders)
-
- @defer.inlineCallbacks
- def _defaultSorter(self, master, builders):
- timer = metrics.Timer("BuildRequestDistributor._defaultSorter()")
- timer.start()
- # perform an asynchronous schwarzian transform, transforming None
- # into sys.maxint so that it sorts to the end
- def xform(bldr):
- d = defer.maybeDeferred(lambda :
- bldr.getOldestRequestTime())
- d.addCallback(lambda time :
- (((time is None) and None or time),bldr))
- return d
- xformed = yield defer.gatherResults(
- [ xform(bldr) for bldr in builders ])
-
- # sort the transformed list synchronously, comparing None to the end of
- # the list
- def nonecmp(a,b):
- if a[0] is None: return 1
- if b[0] is None: return -1
- return cmp(a,b)
- xformed.sort(cmp=nonecmp)
-
- # and reverse the transform
- rv = [ xf[1] for xf in xformed ]
- timer.stop()
- defer.returnValue(rv)
-
- @defer.inlineCallbacks
- def _sortBuilders(self, buildernames):
- timer = metrics.Timer("BuildRequestDistributor._sortBuilders()")
- timer.start()
- # note that this takes and returns a list of builder names
-
- # convert builder names to builders
- builders_dict = self.botmaster.builders
- builders = [ builders_dict.get(n)
- for n in buildernames
- if n in builders_dict ]
-
- # find a sorting function
- sorter = self.master.config.prioritizeBuilders
- if not sorter:
- sorter = self._defaultSorter
-
- # run it
- try:
- builders = yield defer.maybeDeferred(lambda :
- sorter(self.master, builders))
- except Exception:
- log.err(Failure(), "prioritizing builders; order unspecified")
-
- # and return the names
- rv = [ b.name for b in builders ]
- timer.stop()
- defer.returnValue(rv)
-
- @defer.inlineCallbacks
- def _activityLoop(self):
- self.active = True
-
- timer = metrics.Timer('BuildRequestDistributor._activityLoop()')
- timer.start()
-
- while 1:
- yield self.activity_lock.acquire()
-
- # lock pending_builders, pop an element from it, and release
- yield self.pending_builders_lock.acquire()
-
- # bail out if we shouldn't keep looping
- if not self.running or not self._pending_builders:
- self.pending_builders_lock.release()
- self.activity_lock.release()
- break
-
- bldr_name = self._pending_builders.pop(0)
- self.pending_builders_lock.release()
-
- # get the actual builder object
- bldr = self.botmaster.builders.get(bldr_name)
- try:
- if bldr:
- yield self._maybeStartBuildsOnBuilder(bldr)
- except Exception:
- log.err(Failure(),
- "from maybeStartBuild for builder '%s'" % (bldr_name,))
-
- self.activity_lock.release()
-
- timer.stop()
-
- self.active = False
- self._quiet()
-
- @defer.inlineCallbacks
- def _maybeStartBuildsOnBuilder(self, bldr):
- # create a chooser to give us our next builds
- # this object is temporary and will go away when we're done
-
- bc = self.createBuildChooser(bldr, self.master)
-
- while 1:
- slave, breqs = yield bc.chooseNextBuild()
- if not slave or not breqs:
- break
-
- # claim brid's
- brids = [ br.id for br in breqs ]
- try:
- yield self.master.db.buildrequests.claimBuildRequests(brids)
- except AlreadyClaimedError:
- # some brids were already claimed, so start over
- bc = self.createBuildChooser(bldr, self.master)
- continue
-
- buildStarted = yield bldr.maybeStartBuild(slave, breqs)
-
- if not buildStarted:
- yield self.master.db.buildrequests.unclaimBuildRequests(brids)
-
- # and try starting builds again. If we still have a working slave,
- # then this may re-claim the same buildrequests
- self.botmaster.maybeStartBuildsForBuilder(self.name)
-
- def createBuildChooser(self, bldr, master):
- # just instantiate the build chooser requested
- return self.BuildChooser(bldr, master)
-
- def _quiet(self):
- # shim for tests
- pass # pragma: no cover
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildstep.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildstep.py
deleted file mode 100644
index c8272aa4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/buildstep.py
+++ /dev/null
@@ -1,985 +0,0 @@
-# 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 re
-
-from zope.interface import implements
-from twisted.internet import defer, error
-from twisted.protocols import basic
-from twisted.spread import pb
-from twisted.python import log, components
-from twisted.python.failure import Failure
-from twisted.web.util import formatFailure
-from twisted.python.reflect import accumulateClassList
-
-from buildbot import interfaces, util, config
-from buildbot.status import progress
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE, SKIPPED, \
- EXCEPTION, RETRY, worst_status
-from buildbot.process import metrics, properties
-from buildbot.util.eventual import eventually
-
-class BuildStepFailed(Exception):
- pass
-
-class RemoteCommand(pb.Referenceable):
-
- # class-level unique identifier generator for command ids
- _commandCounter = 0
-
- active = False
- rc = None
- debug = False
-
- def __init__(self, remote_command, args, ignore_updates=False,
- collectStdout=False, collectStderr=False, decodeRC={0:SUCCESS}):
- self.logs = {}
- self.delayedLogs = {}
- self._closeWhenFinished = {}
- self.collectStdout = collectStdout
- self.collectStderr = collectStderr
- self.stdout = ''
- self.stderr = ''
-
- self._startTime = None
- self._remoteElapsed = None
- self.remote_command = remote_command
- self.args = args
- self.ignore_updates = ignore_updates
- self.decodeRC = decodeRC
-
- def __repr__(self):
- return "<RemoteCommand '%s' at %d>" % (self.remote_command, id(self))
-
- def run(self, step, remote):
- self.active = True
- self.step = step
- self.remote = remote
-
- # generate a new command id
- cmd_id = RemoteCommand._commandCounter
- RemoteCommand._commandCounter += 1
- self.commandID = "%d" % cmd_id
-
- log.msg("%s: RemoteCommand.run [%s]" % (self, self.commandID))
- self.deferred = defer.Deferred()
-
- d = defer.maybeDeferred(self._start)
-
- # _finished is called with an error for unknown commands, errors
- # that occur while the command is starting (including OSErrors in
- # exec()), StaleBroker (when the connection was lost before we
- # started), and pb.PBConnectionLost (when the slave isn't responding
- # over this connection, perhaps it had a power failure, or NAT
- # weirdness). If this happens, self.deferred is fired right away.
- d.addErrback(self._finished)
-
- # Connections which are lost while the command is running are caught
- # when our parent Step calls our .lostRemote() method.
- return self.deferred
-
- def useLog(self, log, closeWhenFinished=False, logfileName=None):
- assert interfaces.ILogFile.providedBy(log)
- if not logfileName:
- logfileName = log.getName()
- assert logfileName not in self.logs
- assert logfileName not in self.delayedLogs
- self.logs[logfileName] = log
- self._closeWhenFinished[logfileName] = closeWhenFinished
-
- def useLogDelayed(self, logfileName, activateCallBack, closeWhenFinished=False):
- assert logfileName not in self.logs
- assert logfileName not in self.delayedLogs
- self.delayedLogs[logfileName] = (activateCallBack, closeWhenFinished)
-
- def _start(self):
- self.updates = {}
- self._startTime = util.now()
-
- # This method only initiates the remote command.
- # We will receive remote_update messages as the command runs.
- # We will get a single remote_complete when it finishes.
- # We should fire self.deferred when the command is done.
- d = self.remote.callRemote("startCommand", self, self.commandID,
- self.remote_command, self.args)
- return d
-
- def _finished(self, failure=None):
- self.active = False
- # call .remoteComplete. If it raises an exception, or returns the
- # Failure that we gave it, our self.deferred will be errbacked. If
- # it does not (either it ate the Failure or there the step finished
- # normally and it didn't raise a new exception), self.deferred will
- # be callbacked.
- d = defer.maybeDeferred(self.remoteComplete, failure)
- # arrange for the callback to get this RemoteCommand instance
- # instead of just None
- d.addCallback(lambda r: self)
- # this fires the original deferred we returned from .run(),
- # with self as the result, or a failure
- d.addBoth(self.deferred.callback)
-
- def interrupt(self, why):
- log.msg("RemoteCommand.interrupt", self, why)
- if not self.active:
- log.msg(" but this RemoteCommand is already inactive")
- return defer.succeed(None)
- if not self.remote:
- log.msg(" but our .remote went away")
- return defer.succeed(None)
- if isinstance(why, Failure) and why.check(error.ConnectionLost):
- log.msg("RemoteCommand.disconnect: lost slave")
- self.remote = None
- self._finished(why)
- return defer.succeed(None)
-
- # tell the remote command to halt. Returns a Deferred that will fire
- # when the interrupt command has been delivered.
-
- d = defer.maybeDeferred(self.remote.callRemote, "interruptCommand",
- self.commandID, str(why))
- # the slave may not have remote_interruptCommand
- d.addErrback(self._interruptFailed)
- return d
-
- def _interruptFailed(self, why):
- log.msg("RemoteCommand._interruptFailed", self)
- # TODO: forcibly stop the Command now, since we can't stop it
- # cleanly
- return None
-
- def remote_update(self, updates):
- """
- I am called by the slave's L{buildbot.slave.bot.SlaveBuilder} so
- I can receive updates from the running remote command.
-
- @type updates: list of [object, int]
- @param updates: list of updates from the remote command
- """
- self.buildslave.messageReceivedFromSlave()
- max_updatenum = 0
- for (update, num) in updates:
- #log.msg("update[%d]:" % num)
- try:
- if self.active and not self.ignore_updates:
- self.remoteUpdate(update)
- except:
- # log failure, terminate build, let slave retire the update
- self._finished(Failure())
- # TODO: what if multiple updates arrive? should
- # skip the rest but ack them all
- if num > max_updatenum:
- max_updatenum = num
- return max_updatenum
-
- def remote_complete(self, failure=None):
- """
- Called by the slave's L{buildbot.slave.bot.SlaveBuilder} to
- notify me the remote command has finished.
-
- @type failure: L{twisted.python.failure.Failure} or None
-
- @rtype: None
- """
- self.buildslave.messageReceivedFromSlave()
- # call the real remoteComplete a moment later, but first return an
- # acknowledgement so the slave can retire the completion message.
- if self.active:
- eventually(self._finished, failure)
- return None
-
- def addStdout(self, data):
- if 'stdio' in self.logs:
- self.logs['stdio'].addStdout(data)
- if self.collectStdout:
- self.stdout += data
-
- def addStderr(self, data):
- if 'stdio' in self.logs:
- self.logs['stdio'].addStderr(data)
- if self.collectStderr:
- self.stderr += data
-
- def addHeader(self, data):
- if 'stdio' in self.logs:
- self.logs['stdio'].addHeader(data)
-
- def addToLog(self, logname, data):
- # Activate delayed logs on first data.
- if logname in self.delayedLogs:
- (activateCallBack, closeWhenFinished) = self.delayedLogs[logname]
- del self.delayedLogs[logname]
- loog = activateCallBack(self)
- self.logs[logname] = loog
- self._closeWhenFinished[logname] = closeWhenFinished
-
- if logname in self.logs:
- self.logs[logname].addStdout(data)
- else:
- log.msg("%s.addToLog: no such log %s" % (self, logname))
-
- @metrics.countMethod('RemoteCommand.remoteUpdate()')
- def remoteUpdate(self, update):
- if self.debug:
- for k,v in update.items():
- log.msg("Update[%s]: %s" % (k,v))
- if update.has_key('stdout'):
- # 'stdout': data
- self.addStdout(update['stdout'])
- if update.has_key('stderr'):
- # 'stderr': data
- self.addStderr(update['stderr'])
- if update.has_key('header'):
- # 'header': data
- self.addHeader(update['header'])
- if update.has_key('log'):
- # 'log': (logname, data)
- logname, data = update['log']
- self.addToLog(logname, data)
- if update.has_key('rc'):
- rc = self.rc = update['rc']
- log.msg("%s rc=%s" % (self, rc))
- self.addHeader("program finished with exit code %d\n" % rc)
- if update.has_key('elapsed'):
- self._remoteElapsed = update['elapsed']
-
- # TODO: these should be handled at the RemoteCommand level
- for k in update:
- if k not in ('stdout', 'stderr', 'header', 'rc'):
- if k not in self.updates:
- self.updates[k] = []
- self.updates[k].append(update[k])
-
- def remoteComplete(self, maybeFailure):
- if self._startTime and self._remoteElapsed:
- delta = (util.now() - self._startTime) - self._remoteElapsed
- metrics.MetricTimeEvent.log("RemoteCommand.overhead", delta)
-
- for name,loog in self.logs.items():
- if self._closeWhenFinished[name]:
- if maybeFailure:
- loog.addHeader("\nremoteFailed: %s" % maybeFailure)
- else:
- log.msg("closing log %s" % loog)
- loog.finish()
- return maybeFailure
-
- def results(self):
- if self.rc in self.decodeRC:
- return self.decodeRC[self.rc]
- return FAILURE
-
- def didFail(self):
- return self.results() == FAILURE
-LoggedRemoteCommand = RemoteCommand
-
-
-class LogObserver:
- implements(interfaces.ILogObserver)
-
- def setStep(self, step):
- self.step = step
-
- def setLog(self, loog):
- assert interfaces.IStatusLog.providedBy(loog)
- loog.subscribe(self, True)
-
- def logChunk(self, build, step, log, channel, text):
- if channel == interfaces.LOG_CHANNEL_STDOUT:
- self.outReceived(text)
- elif channel == interfaces.LOG_CHANNEL_STDERR:
- self.errReceived(text)
-
- # TODO: add a logEnded method? er, stepFinished?
-
- def outReceived(self, data):
- """This will be called with chunks of stdout data. Override this in
- your observer."""
- pass
-
- def errReceived(self, data):
- """This will be called with chunks of stderr data. Override this in
- your observer."""
- pass
-
-
-class LogLineObserver(LogObserver):
- def __init__(self):
- self.stdoutParser = basic.LineOnlyReceiver()
- self.stdoutParser.delimiter = "\n"
- self.stdoutParser.lineReceived = self.outLineReceived
- self.stdoutParser.transport = self # for the .disconnecting attribute
- self.disconnecting = False
-
- self.stderrParser = basic.LineOnlyReceiver()
- self.stderrParser.delimiter = "\n"
- self.stderrParser.lineReceived = self.errLineReceived
- self.stderrParser.transport = self
-
- def setMaxLineLength(self, max_length):
- """
- Set the maximum line length: lines longer than max_length are
- dropped. Default is 16384 bytes. Use sys.maxint for effective
- infinity.
- """
- self.stdoutParser.MAX_LENGTH = max_length
- self.stderrParser.MAX_LENGTH = max_length
-
- def outReceived(self, data):
- self.stdoutParser.dataReceived(data)
-
- def errReceived(self, data):
- self.stderrParser.dataReceived(data)
-
- def outLineReceived(self, line):
- """This will be called with complete stdout lines (not including the
- delimiter). Override this in your observer."""
- pass
-
- def errLineReceived(self, line):
- """This will be called with complete lines of stderr (not including
- the delimiter). Override this in your observer."""
- pass
-
-
-class RemoteShellCommand(RemoteCommand):
- def __init__(self, workdir, command, env=None,
- want_stdout=1, want_stderr=1,
- timeout=20*60, maxTime=None, logfiles={},
- usePTY="slave-config", logEnviron=True,
- collectStdout=False,collectStderr=False,
- interruptSignal=None,
- initialStdin=None, decodeRC={0:SUCCESS}):
-
- self.command = command # stash .command, set it later
- if env is not None:
- # avoid mutating the original master.cfg dictionary. Each
- # ShellCommand gets its own copy, any start() methods won't be
- # able to modify the original.
- env = env.copy()
- args = {'workdir': workdir,
- 'env': env,
- 'want_stdout': want_stdout,
- 'want_stderr': want_stderr,
- 'logfiles': logfiles,
- 'timeout': timeout,
- 'maxTime': maxTime,
- 'usePTY': usePTY,
- 'logEnviron': logEnviron,
- 'initial_stdin': initialStdin
- }
- if interruptSignal is not None:
- args['interruptSignal'] = interruptSignal
- RemoteCommand.__init__(self, "shell", args, collectStdout=collectStdout,
- collectStderr=collectStderr,
- decodeRC=decodeRC)
-
- def _start(self):
- self.args['command'] = self.command
- if self.remote_command == "shell":
- # non-ShellCommand slavecommands are responsible for doing this
- # fixup themselves
- if self.step.slaveVersion("shell", "old") == "old":
- self.args['dir'] = self.args['workdir']
- what = "command '%s' in dir '%s'" % (self.args['command'],
- self.args['workdir'])
- log.msg(what)
- return RemoteCommand._start(self)
-
- def __repr__(self):
- return "<RemoteShellCommand '%s'>" % repr(self.command)
-
-class _BuildStepFactory(util.ComparableMixin):
- """
- This is a wrapper to record the arguments passed to as BuildStep subclass.
- We use an instance of this class, rather than a closure mostly to make it
- easier to test that the right factories are getting created.
- """
- compare_attrs = ['factory', 'args', 'kwargs' ]
- implements(interfaces.IBuildStepFactory)
-
- def __init__(self, factory, *args, **kwargs):
- self.factory = factory
- self.args = args
- self.kwargs = kwargs
-
- def buildStep(self):
- try:
- return self.factory(*self.args, **self.kwargs)
- except:
- log.msg("error while creating step, factory=%s, args=%s, kwargs=%s"
- % (self.factory, self.args, self.kwargs))
- raise
-
-class BuildStep(object, properties.PropertiesMixin):
-
- haltOnFailure = False
- flunkOnWarnings = False
- flunkOnFailure = False
- warnOnWarnings = False
- warnOnFailure = False
- alwaysRun = False
- doStepIf = True
- hideStepIf = False
-
- # properties set on a build step are, by nature, always runtime properties
- set_runtime_properties = True
-
- # 'parms' holds a list of all the parameters we care about, to allow
- # users to instantiate a subclass of BuildStep with a mixture of
- # arguments, some of which are for us, some of which are for the subclass
- # (or a delegate of the subclass, like how ShellCommand delivers many
- # arguments to the RemoteShellCommand that it creates). Such delegating
- # subclasses will use this list to figure out which arguments are meant
- # for us and which should be given to someone else.
- parms = ['name', 'locks',
- 'haltOnFailure',
- 'flunkOnWarnings',
- 'flunkOnFailure',
- 'warnOnWarnings',
- 'warnOnFailure',
- 'alwaysRun',
- 'progressMetrics',
- 'useProgress',
- 'doStepIf',
- 'hideStepIf',
- ]
-
- name = "generic"
- locks = []
- progressMetrics = () # 'time' is implicit
- useProgress = True # set to False if step is really unpredictable
- build = None
- step_status = None
- progress = None
-
- def __init__(self, **kwargs):
- for p in self.__class__.parms:
- if kwargs.has_key(p):
- setattr(self, p, kwargs[p])
- del kwargs[p]
- if kwargs:
- config.error("%s.__init__ got unexpected keyword argument(s) %s" \
- % (self.__class__, kwargs.keys()))
- self._pendingLogObservers = []
-
- if not isinstance(self.name, str):
- config.error("BuildStep name must be a string: %r" % (self.name,))
-
- self._acquiringLock = None
- self.stopped = False
-
- def __new__(klass, *args, **kwargs):
- self = object.__new__(klass)
- self._factory = _BuildStepFactory(klass, *args, **kwargs)
- return self
-
- def describe(self, done=False):
- return [self.name]
-
- def setBuild(self, build):
- self.build = build
-
- def setBuildSlave(self, buildslave):
- self.buildslave = buildslave
-
- def setDefaultWorkdir(self, workdir):
- pass
-
- def addFactoryArguments(self, **kwargs):
- # this is here for backwards compatability
- pass
-
- def _getStepFactory(self):
- return self._factory
-
- def setStepStatus(self, step_status):
- self.step_status = step_status
-
- def setupProgress(self):
- if self.useProgress:
- sp = progress.StepProgress(self.name, self.progressMetrics)
- self.progress = sp
- self.step_status.setProgress(sp)
- return sp
- return None
-
- def setProgress(self, metric, value):
- if self.progress:
- self.progress.setProgress(metric, value)
-
- def startStep(self, remote):
- self.remote = remote
- self.deferred = defer.Deferred()
- # convert all locks into their real form
- self.locks = [(self.build.builder.botmaster.getLockByID(access.lockid), access)
- for access in self.locks ]
- # then narrow SlaveLocks down to the slave that this build is being
- # run on
- self.locks = [(l.getLock(self.build.slavebuilder.slave), la)
- for l, la in self.locks ]
-
- for l, la in self.locks:
- if l in self.build.locks:
- log.msg("Hey, lock %s is claimed by both a Step (%s) and the"
- " parent Build (%s)" % (l, self, self.build))
- raise RuntimeError("lock claimed by both Step and Build")
-
- # Set the step's text here so that the stepStarted notification sees
- # the correct description
- self.step_status.setText(self.describe(False))
- self.step_status.stepStarted()
-
- d = self.acquireLocks()
- d.addCallback(self._startStep_2)
- d.addErrback(self.failed)
- return self.deferred
-
- def acquireLocks(self, res=None):
- self._acquiringLock = None
- if not self.locks:
- return defer.succeed(None)
- if self.stopped:
- return defer.succeed(None)
- log.msg("acquireLocks(step %s, locks %s)" % (self, self.locks))
- for lock, access in self.locks:
- if not lock.isAvailable(self, access):
- self.step_status.setWaitingForLocks(True)
- log.msg("step %s waiting for lock %s" % (self, lock))
- d = lock.waitUntilMaybeAvailable(self, access)
- d.addCallback(self.acquireLocks)
- self._acquiringLock = (lock, access, d)
- return d
- # all locks are available, claim them all
- for lock, access in self.locks:
- lock.claim(self, access)
- self.step_status.setWaitingForLocks(False)
- return defer.succeed(None)
-
- def _startStep_2(self, res):
- if self.stopped:
- self.finished(EXCEPTION)
- return
-
- if self.progress:
- self.progress.start()
-
- if isinstance(self.doStepIf, bool):
- doStep = defer.succeed(self.doStepIf)
- else:
- doStep = defer.maybeDeferred(self.doStepIf, self)
-
- renderables = []
- accumulateClassList(self.__class__, 'renderables', renderables)
-
- def setRenderable(res, attr):
- setattr(self, attr, res)
-
- dl = [ doStep ]
- for renderable in renderables:
- d = self.build.render(getattr(self, renderable))
- d.addCallback(setRenderable, renderable)
- dl.append(d)
- dl = defer.gatherResults(dl)
-
- dl.addCallback(self._startStep_3)
- return dl
-
- @defer.inlineCallbacks
- def _startStep_3(self, doStep):
- doStep = doStep[0]
- try:
- if doStep:
- result = yield defer.maybeDeferred(self.start)
- if result == SKIPPED:
- doStep = False
- except:
- log.msg("BuildStep.startStep exception in .start")
- self.failed(Failure())
-
- if not doStep:
- self.step_status.setText(self.describe(True) + ['skipped'])
- self.step_status.setSkipped(True)
- # this return value from self.start is a shortcut to finishing
- # the step immediately; we skip calling finished() as
- # subclasses may have overridden that an expect it to be called
- # after start() (bug #837)
- eventually(self._finishFinished, SKIPPED)
-
- def start(self):
- raise NotImplementedError("your subclass must implement this method")
-
- def interrupt(self, reason):
- self.stopped = True
- if self._acquiringLock:
- lock, access, d = self._acquiringLock
- lock.stopWaitingUntilAvailable(self, access, d)
- d.callback(None)
-
- def releaseLocks(self):
- log.msg("releaseLocks(%s): %s" % (self, self.locks))
- for lock, access in self.locks:
- if lock.isOwner(self, access):
- lock.release(self, access)
- else:
- # This should only happen if we've been interrupted
- assert self.stopped
-
- def finished(self, results):
- if self.stopped and results != RETRY:
- # We handle this specially because we don't care about
- # the return code of an interrupted command; we know
- # that this should just be exception due to interrupt
- # At the same time we must respect RETRY status because it's used
- # to retry interrupted build due to some other issues for example
- # due to slave lost
- results = EXCEPTION
- self.step_status.setText(self.describe(True) +
- ["interrupted"])
- self.step_status.setText2(["interrupted"])
- self._finishFinished(results)
-
- def _finishFinished(self, results):
- # internal function to indicate that this step is done; this is separated
- # from finished() so that subclasses can override finished()
- if self.progress:
- self.progress.finish()
-
- try:
- hidden = self._maybeEvaluate(self.hideStepIf, results, self)
- except Exception:
- why = Failure()
- self.addHTMLLog("err.html", formatFailure(why))
- self.addCompleteLog("err.text", why.getTraceback())
- results = EXCEPTION
- hidden = False
-
- self.step_status.stepFinished(results)
- self.step_status.setHidden(hidden)
-
- self.releaseLocks()
- self.deferred.callback(results)
-
- def failed(self, why):
- # This can either be a BuildStepFailed exception/failure, meaning we
- # should call self.finished, or it can be a real exception, which should
- # be recorded as such.
- if why.check(BuildStepFailed):
- self.finished(FAILURE)
- return
-
- log.err(why, "BuildStep.failed; traceback follows")
- try:
- if self.progress:
- self.progress.finish()
- try:
- self.addCompleteLog("err.text", why.getTraceback())
- self.addHTMLLog("err.html", formatFailure(why))
- except Exception:
- log.err(Failure(), "error while formatting exceptions")
-
- # could use why.getDetailedTraceback() for more information
- self.step_status.setText([self.name, "exception"])
- self.step_status.setText2([self.name])
- self.step_status.stepFinished(EXCEPTION)
-
- hidden = self._maybeEvaluate(self.hideStepIf, EXCEPTION, self)
- self.step_status.setHidden(hidden)
- except Exception:
- log.err(Failure(), "exception during failure processing")
- # the progress stuff may still be whacked (the StepStatus may
- # think that it is still running), but the build overall will now
- # finish
-
- try:
- self.releaseLocks()
- except Exception:
- log.err(Failure(), "exception while releasing locks")
-
- log.msg("BuildStep.failed now firing callback")
- self.deferred.callback(EXCEPTION)
-
- # utility methods that BuildSteps may find useful
-
- def slaveVersion(self, command, oldversion=None):
- return self.build.getSlaveCommandVersion(command, oldversion)
-
- def slaveVersionIsOlderThan(self, command, minversion):
- sv = self.build.getSlaveCommandVersion(command, None)
- if sv is None:
- return True
- if map(int, sv.split(".")) < map(int, minversion.split(".")):
- return True
- return False
-
- def getSlaveName(self):
- return self.build.getSlaveName()
-
- def addLog(self, name):
- loog = self.step_status.addLog(name)
- self._connectPendingLogObservers()
- return loog
-
- def getLog(self, name):
- for l in self.step_status.getLogs():
- if l.getName() == name:
- return l
- raise KeyError("no log named '%s'" % (name,))
-
- def addCompleteLog(self, name, text):
- log.msg("addCompleteLog(%s)" % name)
- loog = self.step_status.addLog(name)
- size = loog.chunkSize
- for start in range(0, len(text), size):
- loog.addStdout(text[start:start+size])
- loog.finish()
- self._connectPendingLogObservers()
-
- def addHTMLLog(self, name, html):
- log.msg("addHTMLLog(%s)" % name)
- self.step_status.addHTMLLog(name, html)
- self._connectPendingLogObservers()
-
- def addLogObserver(self, logname, observer):
- assert interfaces.ILogObserver.providedBy(observer)
- observer.setStep(self)
- self._pendingLogObservers.append((logname, observer))
- self._connectPendingLogObservers()
-
- def _connectPendingLogObservers(self):
- if not self._pendingLogObservers:
- return
- if not self.step_status:
- return
- current_logs = {}
- for loog in self.step_status.getLogs():
- current_logs[loog.getName()] = loog
- for logname, observer in self._pendingLogObservers[:]:
- if logname in current_logs:
- observer.setLog(current_logs[logname])
- self._pendingLogObservers.remove((logname, observer))
-
- def addURL(self, name, url):
- self.step_status.addURL(name, url)
-
- def runCommand(self, c):
- c.buildslave = self.buildslave
- d = c.run(self, self.remote)
- return d
-
- @staticmethod
- def _maybeEvaluate(value, *args, **kwargs):
- if callable(value):
- value = value(*args, **kwargs)
- return value
-
-components.registerAdapter(
- BuildStep._getStepFactory,
- BuildStep, interfaces.IBuildStepFactory)
-components.registerAdapter(
- lambda step : interfaces.IProperties(step.build),
- BuildStep, interfaces.IProperties)
-
-
-class OutputProgressObserver(LogObserver):
- length = 0
-
- def __init__(self, name):
- self.name = name
-
- def logChunk(self, build, step, log, channel, text):
- self.length += len(text)
- self.step.setProgress(self.name, self.length)
-
-class LoggingBuildStep(BuildStep):
-
- progressMetrics = ('output',)
- logfiles = {}
-
- parms = BuildStep.parms + ['logfiles', 'lazylogfiles', 'log_eval_func']
- cmd = None
-
- renderables = [ 'logfiles', 'lazylogfiles' ]
-
- def __init__(self, logfiles={}, lazylogfiles=False, log_eval_func=None,
- *args, **kwargs):
- BuildStep.__init__(self, *args, **kwargs)
-
- if logfiles and not isinstance(logfiles, dict):
- config.error(
- "the ShellCommand 'logfiles' parameter must be a dictionary")
-
- # merge a class-level 'logfiles' attribute with one passed in as an
- # argument
- self.logfiles = self.logfiles.copy()
- self.logfiles.update(logfiles)
- self.lazylogfiles = lazylogfiles
- if log_eval_func and not callable(log_eval_func):
- config.error(
- "the 'log_eval_func' paramater must be a callable")
- self.log_eval_func = log_eval_func
- self.addLogObserver('stdio', OutputProgressObserver("output"))
-
- def addLogFile(self, logname, filename):
- self.logfiles[logname] = filename
-
- def buildCommandKwargs(self):
- kwargs = dict()
- kwargs['logfiles'] = self.logfiles
- return kwargs
-
- def startCommand(self, cmd, errorMessages=[]):
- """
- @param cmd: a suitable RemoteCommand which will be launched, with
- all output being put into our self.stdio_log LogFile
- """
- log.msg("ShellCommand.startCommand(cmd=%s)" % (cmd,))
- log.msg(" cmd.args = %r" % (cmd.args))
- self.cmd = cmd # so we can interrupt it
- self.step_status.setText(self.describe(False))
-
- # stdio is the first log
- self.stdio_log = stdio_log = self.addLog("stdio")
- cmd.useLog(stdio_log, True)
- for em in errorMessages:
- stdio_log.addHeader(em)
- # TODO: consider setting up self.stdio_log earlier, and have the
- # code that passes in errorMessages instead call
- # self.stdio_log.addHeader() directly.
-
- # there might be other logs
- self.setupLogfiles(cmd, self.logfiles)
-
- d = self.runCommand(cmd) # might raise ConnectionLost
- d.addCallback(lambda res: self.commandComplete(cmd))
- d.addCallback(lambda res: self.createSummary(cmd.logs['stdio']))
- d.addCallback(lambda res: self.evaluateCommand(cmd)) # returns results
- def _gotResults(results):
- self.setStatus(cmd, results)
- return results
- d.addCallback(_gotResults) # returns results
- d.addCallbacks(self.finished, self.checkDisconnect)
- d.addErrback(self.failed)
-
- def setupLogfiles(self, cmd, logfiles):
- for logname,remotefilename in logfiles.items():
- if self.lazylogfiles:
- # Ask RemoteCommand to watch a logfile, but only add
- # it when/if we see any data.
- #
- # The dummy default argument local_logname is a work-around for
- # Python name binding; default values are bound by value, but
- # captured variables in the body are bound by name.
- callback = lambda cmd_arg, local_logname=logname: self.addLog(local_logname)
- cmd.useLogDelayed(logname, callback, True)
- else:
- # tell the BuildStepStatus to add a LogFile
- newlog = self.addLog(logname)
- # and tell the RemoteCommand to feed it
- cmd.useLog(newlog, True)
-
- def interrupt(self, reason):
- # TODO: consider adding an INTERRUPTED or STOPPED status to use
- # instead of FAILURE, might make the text a bit more clear.
- # 'reason' can be a Failure, or text
- BuildStep.interrupt(self, reason)
- if self.step_status.isWaitingForLocks():
- self.addCompleteLog('interrupt while waiting for locks', str(reason))
- else:
- self.addCompleteLog('interrupt', str(reason))
-
- if self.cmd:
- d = self.cmd.interrupt(reason)
- d.addErrback(log.err, 'while interrupting command')
-
- def checkDisconnect(self, f):
- f.trap(error.ConnectionLost)
- self.step_status.setText(self.describe(True) +
- ["exception", "slave", "lost"])
- self.step_status.setText2(["exception", "slave", "lost"])
- return self.finished(RETRY)
-
- def commandComplete(self, cmd):
- pass
-
- def createSummary(self, stdio):
- pass
-
- def evaluateCommand(self, cmd):
- if self.log_eval_func:
- return self.log_eval_func(cmd, self.step_status)
- return cmd.results()
-
- def getText(self, cmd, results):
- if results == SUCCESS:
- return self.describe(True)
- elif results == WARNINGS:
- return self.describe(True) + ["warnings"]
- elif results == EXCEPTION:
- return self.describe(True) + ["exception"]
- else:
- return self.describe(True) + ["failed"]
-
- def getText2(self, cmd, results):
- return [self.name]
-
- def maybeGetText2(self, cmd, results):
- if results == SUCCESS:
- # successful steps do not add anything to the build's text
- pass
- elif results == WARNINGS:
- if (self.flunkOnWarnings or self.warnOnWarnings):
- # we're affecting the overall build, so tell them why
- return self.getText2(cmd, results)
- else:
- if (self.haltOnFailure or self.flunkOnFailure
- or self.warnOnFailure):
- # we're affecting the overall build, so tell them why
- return self.getText2(cmd, results)
- return []
-
- def setStatus(self, cmd, results):
- # this is good enough for most steps, but it can be overridden to
- # get more control over the displayed text
- self.step_status.setText(self.getText(cmd, results))
- self.step_status.setText2(self.maybeGetText2(cmd, results))
-
-
-# Parses the logs for a list of regexs. Meant to be invoked like:
-# regexes = ((re.compile(...), FAILURE), (re.compile(...), WARNINGS))
-# self.addStep(ShellCommand,
-# command=...,
-# ...,
-# log_eval_func=lambda c,s: regex_log_evaluator(c, s, regexs)
-# )
-def regex_log_evaluator(cmd, step_status, regexes):
- worst = cmd.results()
- for err, possible_status in regexes:
- # worst_status returns the worse of the two status' passed to it.
- # we won't be changing "worst" unless possible_status is worse than it,
- # so we don't even need to check the log if that's the case
- if worst_status(worst, possible_status) == possible_status:
- if isinstance(err, (basestring)):
- err = re.compile(".*%s.*" % err, re.DOTALL)
- for l in cmd.logs.values():
- if err.search(l.getText()):
- worst = possible_status
- return worst
-
-# (WithProperties used to be available in this module)
-from buildbot.process.properties import WithProperties
-_hush_pyflakes = [WithProperties]
-del _hush_pyflakes
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/cache.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/cache.py
deleted file mode 100644
index fbc0051d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/cache.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# 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
-
-from buildbot.util import lru
-from buildbot import config
-from twisted.application import service
-
-class CacheManager(config.ReconfigurableServiceMixin, service.Service):
- """
- A manager for a collection of caches, each for different types of objects
- and with potentially-overlapping key spaces.
-
- There is generally only one instance of this class, available at
- C{master.caches}.
- """
-
- # a cache of length one still has many benefits: it collects objects that
- # remain referenced elsewhere; it collapses simultaneous misses into one
- # miss function; and it will optimize repeated fetches of the same object.
- DEFAULT_CACHE_SIZE = 1
-
- def __init__(self):
- self.setName('caches')
- self.config = {}
- self._caches = {}
-
- def get_cache(self, cache_name, miss_fn):
- """
- Get an L{AsyncLRUCache} object with the given name. If such an object
- does not exist, it will be created. Since the cache is permanent, this
- method can be called only once, e.g., in C{startService}, and it value
- stored indefinitely.
-
- @param cache_name: name of the cache (usually the name of the type of
- object it stores)
- @param miss_fn: miss function for the cache; see L{AsyncLRUCache}
- constructor.
- @returns: L{AsyncLRUCache} instance
- """
- try:
- return self._caches[cache_name]
- except KeyError:
- max_size = self.config.get(cache_name, self.DEFAULT_CACHE_SIZE)
- assert max_size >= 1
- c = self._caches[cache_name] = lru.AsyncLRUCache(miss_fn, max_size)
- return c
-
- def reconfigService(self, new_config):
- self.config = new_config.caches
- for name, cache in self._caches.iteritems():
- cache.set_max_size(new_config.caches.get(name,
- self.DEFAULT_CACHE_SIZE))
-
- return config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
- def get_metrics(self):
- return dict([
- (n, dict(hits=c.hits, refhits=c.refhits,
- misses=c.misses, max_size=c.max_size))
- for n, c in self._caches.iteritems()])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/debug.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/debug.py
deleted file mode 100644
index 485928e7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/debug.py
+++ /dev/null
@@ -1,136 +0,0 @@
-# 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
-
-from twisted.python import log
-from twisted.internet import defer
-from twisted.application import service
-from buildbot.pbutil import NewCredPerspective
-from buildbot.sourcestamp import SourceStamp
-from buildbot import interfaces, config
-from buildbot.process.properties import Properties
-
-class DebugServices(config.ReconfigurableServiceMixin, service.MultiService):
-
- def __init__(self, master):
- service.MultiService.__init__(self)
- self.setName('debug_services')
- self.master = master
-
- self.debug_port = None
- self.debug_password = None
- self.debug_registration = None
- self.manhole = None
-
-
- @defer.inlineCallbacks
- def reconfigService(self, new_config):
-
- # debug client
- config_changed = (self.debug_port != new_config.slavePortnum or
- self.debug_password != new_config.debugPassword)
-
- if not new_config.debugPassword or config_changed:
- if self.debug_registration:
- yield self.debug_registration.unregister()
- self.debug_registration = None
-
- if new_config.debugPassword and config_changed:
- factory = lambda mind, user : DebugPerspective(self.master)
- self.debug_registration = self.master.pbmanager.register(
- new_config.slavePortnum, "debug", new_config.debugPassword,
- factory)
-
- self.debug_password = new_config.debugPassword
- if self.debug_password:
- self.debug_port = new_config.slavePortnum
- else:
- self.debug_port = None
-
- # manhole
- if new_config.manhole != self.manhole:
- if self.manhole:
- yield defer.maybeDeferred(lambda :
- self.manhole.disownServiceParent())
- self.manhole.master = None
- self.manhole = None
-
- if new_config.manhole:
- self.manhole = new_config.manhole
- self.manhole.master = self.master
- self.manhole.setServiceParent(self)
-
- # chain up
- yield config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
-
- @defer.inlineCallbacks
- def stopService(self):
- if self.debug_registration:
- yield self.debug_registration.unregister()
- self.debug_registration = None
-
- # manhole will get stopped as a sub-service
-
- yield defer.maybeDeferred(lambda :
- service.MultiService.stopService(self))
-
- # clean up
- if self.manhole:
- self.manhole.master = None
- self.manhole = None
-
-
-class DebugPerspective(NewCredPerspective):
-
- def __init__(self, master):
- self.master = master
-
- def attached(self, mind):
- return self
-
- def detached(self, mind):
- pass
-
- def perspective_requestBuild(self, buildername, reason, branch,
- revision, properties={}):
- c = interfaces.IControl(self.master)
- bc = c.getBuilder(buildername)
- ss = SourceStamp(branch, revision)
- bpr = Properties()
- bpr.update(properties, "remote requestBuild")
- return bc.submitBuildRequest(ss, reason, bpr)
-
- def perspective_pingBuilder(self, buildername):
- c = interfaces.IControl(self.master)
- bc = c.getBuilder(buildername)
- bc.ping()
-
- def perspective_reload(self):
- log.msg("debug client - triggering master reconfig")
- self.master.reconfig()
-
- def perspective_pokeIRC(self):
- log.msg("saying something on IRC")
- from buildbot.status import words
- for s in self.master:
- if isinstance(s, words.IRC):
- bot = s.f
- for channel in bot.channels:
- print " channel", channel
- bot.p.msg(channel, "Ow, quit it")
-
- def perspective_print(self, msg):
- log.msg("debug %s" % msg)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/factory.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/factory.py
deleted file mode 100644
index 5578a033..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/factory.py
+++ /dev/null
@@ -1,202 +0,0 @@
-# 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 warnings
-from twisted.python import deprecate, versions
-
-from buildbot import interfaces, util
-from buildbot.process.build import Build
-from buildbot.process.buildstep import BuildStep
-from buildbot.steps.source import CVS, SVN
-from buildbot.steps.shell import Configure, Compile, Test, PerlModuleTest
-
-# deprecated, use BuildFactory.addStep
-@deprecate.deprecated(versions.Version("buildbot", 0, 8, 6))
-def s(steptype, **kwargs):
- # convenience function for master.cfg files, to create step
- # specification tuples
- return interfaces.IBuildStepFactory(steptype(**kwargs))
-
-
-class BuildFactory(util.ComparableMixin):
- """
- @cvar buildClass: class to use when creating builds
- @type buildClass: L{buildbot.process.build.Build}
- """
- buildClass = Build
- useProgress = 1
- workdir = "build"
- compare_attrs = ['buildClass', 'steps', 'useProgress', 'workdir']
-
- def __init__(self, steps=None):
- self.steps = []
- if steps:
- self.addSteps(steps)
-
- def newBuild(self, requests):
- """Create a new Build instance.
-
- @param requests: a list of buildrequest dictionaries describing what is
- to be built
- """
- b = self.buildClass(requests)
- b.useProgress = self.useProgress
- b.workdir = self.workdir
- b.setStepFactories(self.steps)
- return b
-
- def addStep(self, step, **kwargs):
- if kwargs or (type(step) == type(BuildStep) and issubclass(step, BuildStep)):
- warnings.warn(
- "Passing a BuildStep subclass to factory.addStep is "
- "deprecated. Please pass a BuildStep instance instead.",
- DeprecationWarning, stacklevel=2)
- step = step(**kwargs)
- self.steps.append(interfaces.IBuildStepFactory(step))
-
- def addSteps(self, steps):
- for s in steps:
- self.addStep(s)
-
-# BuildFactory subclasses for common build tools
-
-class GNUAutoconf(BuildFactory):
- def __init__(self, source, configure="./configure",
- configureEnv={},
- configureFlags=[],
- compile=["make", "all"],
- test=["make", "check"]):
- BuildFactory.__init__(self, [source])
- if configure is not None:
- # we either need to wind up with a string (which will be
- # space-split), or with a list of strings (which will not). The
- # list of strings is the preferred form.
- if type(configure) is str:
- if configureFlags:
- assert not " " in configure # please use list instead
- command = [configure] + configureFlags
- else:
- command = configure
- else:
- assert isinstance(configure, (list, tuple))
- command = configure + configureFlags
- self.addStep(Configure(command=command, env=configureEnv))
- if compile is not None:
- self.addStep(Compile(command=compile))
- if test is not None:
- self.addStep(Test(command=test))
-
-class CPAN(BuildFactory):
- def __init__(self, source, perl="perl"):
- BuildFactory.__init__(self, [source])
- self.addStep(Configure(command=[perl, "Makefile.PL"]))
- self.addStep(Compile(command=["make"]))
- self.addStep(PerlModuleTest(command=["make", "test"]))
-
-class Distutils(BuildFactory):
- def __init__(self, source, python="python", test=None):
- BuildFactory.__init__(self, [source])
- self.addStep(Compile(command=[python, "./setup.py", "build"]))
- if test is not None:
- self.addStep(Test(command=test))
-
-class Trial(BuildFactory):
- """Build a python module that uses distutils and trial. Set 'tests' to
- the module in which the tests can be found, or set useTestCaseNames=True
- to always have trial figure out which tests to run (based upon which
- files have been changed).
-
- See docs/factories.xhtml for usage samples. Not all of the Trial
- BuildStep options are available here, only the most commonly used ones.
- To get complete access, you will need to create a custom
- BuildFactory."""
-
- trial = "trial"
- randomly = False
- recurse = False
-
- def __init__(self, source,
- buildpython=["python"], trialpython=[], trial=None,
- testpath=".", randomly=None, recurse=None,
- tests=None, useTestCaseNames=False, env=None):
- BuildFactory.__init__(self, [source])
- assert tests or useTestCaseNames, "must use one or the other"
- if trial is not None:
- self.trial = trial
- if randomly is not None:
- self.randomly = randomly
- if recurse is not None:
- self.recurse = recurse
-
- from buildbot.steps.python_twisted import Trial
- buildcommand = buildpython + ["./setup.py", "build"]
- self.addStep(Compile(command=buildcommand, env=env))
- self.addStep(Trial(
- python=trialpython, trial=self.trial,
- testpath=testpath,
- tests=tests, testChanges=useTestCaseNames,
- randomly=self.randomly,
- recurse=self.recurse,
- env=env,
- ))
-
-
-# compatibility classes, will go away. Note that these only offer
-# compatibility at the constructor level: if you have subclassed these
-# factories, your subclasses are unlikely to still work correctly.
-
-ConfigurableBuildFactory = BuildFactory
-
-class BasicBuildFactory(GNUAutoconf):
- # really a "GNU Autoconf-created tarball -in-CVS tree" builder
-
- def __init__(self, cvsroot, cvsmodule,
- configure=None, configureEnv={},
- compile="make all",
- test="make check", cvsCopy=False):
- mode = "clobber"
- if cvsCopy:
- mode = "copy"
- source = CVS(cvsroot=cvsroot, cvsmodule=cvsmodule, mode=mode)
- GNUAutoconf.__init__(self, source,
- configure=configure, configureEnv=configureEnv,
- compile=compile,
- test=test)
-
-class QuickBuildFactory(BasicBuildFactory):
- useProgress = False
-
- def __init__(self, cvsroot, cvsmodule,
- configure=None, configureEnv={},
- compile="make all",
- test="make check", cvsCopy=False):
- mode = "update"
- source = CVS(cvsroot=cvsroot, cvsmodule=cvsmodule, mode=mode)
- GNUAutoconf.__init__(self, source,
- configure=configure, configureEnv=configureEnv,
- compile=compile,
- test=test)
-
-class BasicSVN(GNUAutoconf):
-
- def __init__(self, svnurl,
- configure=None, configureEnv={},
- compile="make all",
- test="make check"):
- source = SVN(svnurl=svnurl, mode="update")
- GNUAutoconf.__init__(self, source,
- configure=configure, configureEnv=configureEnv,
- compile=compile,
- test=test)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/metrics.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/metrics.py
deleted file mode 100644
index d0f28bb3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/metrics.py
+++ /dev/null
@@ -1,494 +0,0 @@
-# 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
-
-from __future__ import with_statement
-"""
-Buildbot metrics module
-
-Keeps track of counts and timings of various internal buildbot
-activities.
-
-Basic architecture:
-
- MetricEvent.log(...)
- ||
- \/
- MetricLogObserver
- ||
- \/
- MetricHandler
- ||
- \/
- MetricWatcher
-"""
-from collections import deque
-
-from twisted.python import log
-from twisted.internet.task import LoopingCall
-from twisted.internet import reactor
-from twisted.application import service
-from buildbot import util, config
-from collections import defaultdict
-
-import gc, os, sys
-# Make use of the resource module if we can
-try:
- import resource
- assert resource
-except ImportError:
- resource = None
-
-class MetricEvent(object):
- @classmethod
- def log(cls, *args, **kwargs):
- log.msg(metric=cls(*args, **kwargs))
-
-class MetricCountEvent(MetricEvent):
- def __init__(self, counter, count=1, absolute=False):
- self.counter = counter
- self.count = count
- self.absolute = absolute
-
-class MetricTimeEvent(MetricEvent):
- def __init__(self, timer, elapsed):
- self.timer = timer
- self.elapsed = elapsed
-
-ALARM_OK, ALARM_WARN, ALARM_CRIT = range(3)
-ALARM_TEXT = ["OK", "WARN", "CRIT"]
-
-class MetricAlarmEvent(MetricEvent):
- def __init__(self, alarm, msg=None, level=ALARM_OK):
- self.alarm = alarm
- self.level = level
- self.msg = msg
-
-def countMethod(counter):
- def decorator(func):
- def wrapper(*args, **kwargs):
- MetricCountEvent.log(counter=counter)
- return func(*args, **kwargs)
- return wrapper
- return decorator
-
-class Timer(object):
- # For testing
- _reactor = None
-
- def __init__(self, name):
- self.name = name
- self.started = None
-
- def startTimer(self, func):
- def wrapper(*args, **kwargs):
- self.start()
- return func(*args, **kwargs)
- return wrapper
-
- def stopTimer(self, func):
- def wrapper(*args, **kwargs):
- try:
- return func(*args, **kwargs)
- finally:
- self.stop()
- return wrapper
-
- def start(self):
- self.started = util.now(self._reactor)
-
- def stop(self):
- if self.started is not None:
- elapsed = util.now(self._reactor) - self.started
- MetricTimeEvent.log(timer=self.name, elapsed=elapsed)
- self.started = None
-
-def timeMethod(name, _reactor=None):
- def decorator(func):
- t = Timer(name)
- t._reactor=_reactor
- def wrapper(*args, **kwargs):
- t.start()
- try:
- return func(*args, **kwargs)
- finally:
- t.stop()
- return wrapper
- return decorator
-
-class FiniteList(deque):
- def __init__(self, maxlen=10):
- self._maxlen = maxlen
- deque.__init__(self)
-
- def append(self, o):
- deque.append(self, o)
- if len(self) > self._maxlen:
- self.popleft()
-
-class AveragingFiniteList(FiniteList):
- def __init__(self, maxlen=10):
- FiniteList.__init__(self, maxlen)
- self.average = 0
-
- def append(self, o):
- FiniteList.append(self, o)
- self._calc()
-
- def _calc(self):
- if len(self) == 0:
- self.average = 0
- else:
- self.average = float(sum(self)) / len(self)
-
- return self.average
-
-class MetricHandler(object):
- def __init__(self, metrics):
- self.metrics = metrics
- self.watchers = []
-
- self.reset()
-
- def addWatcher(self, watcher):
- self.watchers.append(watcher)
-
- def removeWatcher(self, watcher):
- self.watchers.remove(watcher)
-
- # For subclasses to define
- def reset(self):
- raise NotImplementedError
-
- def handle(self, eventDict, metric):
- raise NotImplementedError
-
- def get(self, metric):
- raise NotImplementedError
-
- def keys(self):
- raise NotImplementedError
-
- def report(self):
- raise NotImplementedError
-
- def asDict(self):
- raise NotImplementedError
-
-class MetricCountHandler(MetricHandler):
- _counters = None
- def reset(self):
- self._counters = defaultdict(int)
-
- def handle(self, eventDict, metric):
- if metric.absolute:
- self._counters[metric.counter] = metric.count
- else:
- self._counters[metric.counter] += metric.count
-
- def keys(self):
- return self._counters.keys()
-
- def get(self, counter):
- return self._counters[counter]
-
- def report(self):
- retval = []
- for counter in sorted(self.keys()):
- retval.append("Counter %s: %i" % (counter, self.get(counter)))
- return "\n".join(retval)
-
- def asDict(self):
- retval = {}
- for counter in sorted(self.keys()):
- retval[counter] = self.get(counter)
- return dict(counters=retval)
-
-class MetricTimeHandler(MetricHandler):
- _timers = None
- def reset(self):
- self._timers = defaultdict(AveragingFiniteList)
-
- def handle(self, eventDict, metric):
- self._timers[metric.timer].append(metric.elapsed)
-
- def keys(self):
- return self._timers.keys()
-
- def get(self, timer):
- return self._timers[timer].average
-
- def report(self):
- retval = []
- for timer in sorted(self.keys()):
- retval.append("Timer %s: %.3g" % (timer, self.get(timer)))
- return "\n".join(retval)
-
- def asDict(self):
- retval = {}
- for timer in sorted(self.keys()):
- retval[timer] = self.get(timer)
- return dict(timers=retval)
-
-class MetricAlarmHandler(MetricHandler):
- _alarms = None
- def reset(self):
- self._alarms = defaultdict(lambda x: ALARM_OK)
-
- def handle(self, eventDict, metric):
- self._alarms[metric.alarm] = (metric.level, metric.msg)
-
- def report(self):
- retval = []
- for alarm, (level, msg) in sorted(self._alarms.items()):
- if msg:
- retval.append("%s %s: %s" % (ALARM_TEXT[level], alarm, msg))
- else:
- retval.append("%s %s" % (ALARM_TEXT[level], alarm))
- return "\n".join(retval)
-
- def asDict(self):
- retval = {}
- for alarm, (level, msg) in sorted(self._alarms.items()):
- retval[alarm] = (ALARM_TEXT[level], msg)
- return dict(alarms=retval)
-
-class PollerWatcher(object):
- def __init__(self, metrics):
- self.metrics = metrics
-
- def run(self):
- # Check if 'BuildMaster.pollDatabaseChanges()' and
- # 'BuildMaster.pollDatabaseBuildRequests()' are running fast enough
- h = self.metrics.getHandler(MetricTimeEvent)
- if not h:
- log.msg("Couldn't get MetricTimeEvent handler")
- MetricAlarmEvent.log('PollerWatcher',
- msg="Coudln't get MetricTimeEvent handler",
- level=ALARM_WARN)
- return
-
- for method in ('BuildMaster.pollDatabaseChanges()',
- 'BuildMaster.pollDatabaseBuildRequests()'):
- t = h.get(method)
- master = self.metrics.parent
- db_poll_interval = master.config.db['db_poll_interval']
-
- if db_poll_interval:
- if t < 0.8 * db_poll_interval:
- level = ALARM_OK
- elif t < db_poll_interval:
- level = ALARM_WARN
- else:
- level = ALARM_CRIT
- MetricAlarmEvent.log(method, level=level)
-
-class AttachedSlavesWatcher(object):
- def __init__(self, metrics):
- self.metrics = metrics
-
- def run(self):
- # Check if 'BotMaster.attached_slaves' equals
- # 'AbstractBuildSlave.attached_slaves'
- h = self.metrics.getHandler(MetricCountEvent)
- if not h:
- log.msg("Couldn't get MetricCountEvent handler")
- MetricAlarmEvent.log('AttachedSlavesWatcher',
- msg="Coudln't get MetricCountEvent handler",
- level=ALARM_WARN)
- return
- botmaster_count = h.get('BotMaster.attached_slaves')
- buildslave_count = h.get('AbstractBuildSlave.attached_slaves')
-
- # We let these be off by one since they're counted at slightly
- # different times
- if abs(botmaster_count - buildslave_count) > 1:
- level = ALARM_WARN
- else:
- level = ALARM_OK
-
- MetricAlarmEvent.log('attached_slaves',
- msg='%s %s' % (botmaster_count, buildslave_count),
- level=level)
-
-def _get_rss():
- if sys.platform == 'linux2':
- try:
- with open("/proc/%i/statm" % os.getpid()) as f:
- return int(f.read().split()[1])
- except:
- return 0
- return 0
-
-def periodicCheck(_reactor=reactor):
- try:
- # Measure how much garbage we have
- garbage_count = len(gc.garbage)
- MetricCountEvent.log('gc.garbage', garbage_count, absolute=True)
- if garbage_count == 0:
- level = ALARM_OK
- else:
- level = ALARM_WARN
- MetricAlarmEvent.log('gc.garbage', level=level)
-
- if resource:
- r = resource.getrusage(resource.RUSAGE_SELF)
- attrs = ['ru_utime', 'ru_stime', 'ru_maxrss', 'ru_ixrss', 'ru_idrss',
- 'ru_isrss', 'ru_minflt', 'ru_majflt', 'ru_nswap',
- 'ru_inblock', 'ru_oublock', 'ru_msgsnd', 'ru_msgrcv',
- 'ru_nsignals', 'ru_nvcsw', 'ru_nivcsw']
- for i,a in enumerate(attrs):
- # Linux versions prior to 2.6.32 didn't report this value, but we
- # can calculate it from /proc/<pid>/statm
- v = r[i]
- if a == 'ru_maxrss' and v == 0:
- v = _get_rss() * resource.getpagesize() / 1024
- MetricCountEvent.log('resource.%s' % a, v, absolute=True)
- MetricCountEvent.log('resource.pagesize', resource.getpagesize(), absolute=True)
- # Measure the reactor delay
- then = util.now(_reactor)
- dt = 0.1
- def cb():
- now = util.now(_reactor)
- delay = (now - then) - dt
- MetricTimeEvent.log("reactorDelay", delay)
- _reactor.callLater(dt, cb)
- except Exception:
- log.err(None, "while collecting VM metrics")
-
-class MetricLogObserver(config.ReconfigurableServiceMixin,
- service.MultiService):
- _reactor = reactor
- def __init__(self):
- service.MultiService.__init__(self)
- self.setName('metrics')
-
- self.enabled = False
- self.periodic_task = None
- self.periodic_interval = None
- self.log_task = None
- self.log_interval = None
-
- # Mapping of metric type to handlers for that type
- self.handlers = {}
-
- # Register our default handlers
- self.registerHandler(MetricCountEvent, MetricCountHandler(self))
- self.registerHandler(MetricTimeEvent, MetricTimeHandler(self))
- self.registerHandler(MetricAlarmEvent, MetricAlarmHandler(self))
-
- # Make sure our changes poller is behaving
- self.getHandler(MetricTimeEvent).addWatcher(PollerWatcher(self))
- self.getHandler(MetricCountEvent).addWatcher(
- AttachedSlavesWatcher(self))
-
- def reconfigService(self, new_config):
- # first, enable or disable
- if new_config.metrics is None:
- self.disable()
- else:
- self.enable()
-
- metrics_config = new_config.metrics
-
- # Start up periodic logging
- log_interval = metrics_config.get('log_interval', 60)
- if log_interval != self.log_interval:
- if self.log_task:
- self.log_task.stop()
- self.log_task = None
- if log_interval:
- self.log_task = LoopingCall(self.report)
- self.log_task.clock = self._reactor
- self.log_task.start(log_interval)
-
- # same for the periodic task
- periodic_interval = metrics_config.get('periodic_interval', 10)
- if periodic_interval != self.periodic_interval:
- if self.periodic_task:
- self.periodic_task.stop()
- self.periodic_task = None
- if periodic_interval:
- self.periodic_task = LoopingCall(periodicCheck,
- self._reactor)
- self.periodic_task.clock = self._reactor
- self.periodic_task.start(periodic_interval)
-
- # upcall
- return config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
- def stopService(self):
- self.disable()
- service.MultiService.stopService(self)
-
- def enable(self):
- if self.enabled:
- return
- log.addObserver(self.emit)
- self.enabled = True
-
- def disable(self):
- if not self.enabled:
- return
-
- if self.periodic_task:
- self.periodic_task.stop()
- self.periodic_task = None
-
- if self.log_task:
- self.log_task.stop()
- self.log_task = None
-
- log.removeObserver(self.emit)
- self.enabled = False
-
- def registerHandler(self, interface, handler):
- old = self.getHandler(interface)
- self.handlers[interface] = handler
- return old
-
- def getHandler(self, interface):
- return self.handlers.get(interface)
-
- def emit(self, eventDict):
- # Ignore non-statistic events
- metric = eventDict.get('metric')
- if not metric or not isinstance(metric, MetricEvent):
- return
-
- if metric.__class__ not in self.handlers:
- return
-
- h = self.handlers[metric.__class__]
- h.handle(eventDict, metric)
- for w in h.watchers:
- w.run()
-
- def asDict(self):
- retval = {}
- for interface, handler in self.handlers.iteritems():
- retval.update(handler.asDict())
- return retval
-
- def report(self):
- try:
- for interface, handler in self.handlers.iteritems():
- report = handler.report()
- if not report:
- continue
- for line in report.split("\n"):
- log.msg(line)
- except:
- log.err(None, "generating metric report")
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/mtrlogobserver.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/mtrlogobserver.py
deleted file mode 100644
index a49b90e2..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/mtrlogobserver.py
+++ /dev/null
@@ -1,474 +0,0 @@
-# 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 sys
-import re
-from twisted.python import log
-from twisted.internet import defer
-from twisted.enterprise import adbapi
-from buildbot.process.buildstep import LogLineObserver
-from buildbot.steps.shell import Test
-
-class EqConnectionPool(adbapi.ConnectionPool):
- """This class works the same way as
-twisted.enterprise.adbapi.ConnectionPool. But it adds the ability to
-compare connection pools for equality (by comparing the arguments
-passed to the constructor).
-
-This is useful when passing the ConnectionPool to a BuildStep, as
-otherwise Buildbot will consider the buildstep (and hence the
-containing buildfactory) to have changed every time the configuration
-is reloaded.
-
-It also sets some defaults differently from adbapi.ConnectionPool that
-are more suitable for use in MTR.
-"""
- def __init__(self, *args, **kwargs):
- self._eqKey = (args, kwargs)
- return adbapi.ConnectionPool.__init__(self,
- cp_reconnect=True, cp_min=1, cp_max=3,
- *args, **kwargs)
-
- def __eq__(self, other):
- if isinstance(other, EqConnectionPool):
- return self._eqKey == other._eqKey
- else:
- return False
-
- def __ne__(self, other):
- return not self.__eq__(other)
-
-
-class MtrTestFailData:
- def __init__(self, testname, variant, result, info, text, callback):
- self.testname = testname
- self.variant = variant
- self.result = result
- self.info = info
- self.text = text
- self.callback = callback
-
- def add(self, line):
- self.text+= line
-
- def fireCallback(self):
- return self.callback(self.testname, self.variant, self.result, self.info, self.text)
-
-
-class MtrLogObserver(LogLineObserver):
- """
- Class implementing a log observer (can be passed to
- BuildStep.addLogObserver().
-
- It parses the output of mysql-test-run.pl as used in MySQL,
- MariaDB, Drizzle, etc.
-
- It counts number of tests run and uses it to provide more accurate
- completion estimates.
-
- It parses out test failures from the output and summarises the results on
- the Waterfall page. It also passes the information to methods that can be
- overridden in a subclass to do further processing on the information."""
-
- _line_re = re.compile(r"^([-._0-9a-zA-z]+)( '[-_ a-zA-Z]+')?\s+(w[0-9]+\s+)?\[ (fail|pass) \]\s*(.*)$")
- _line_re2 = re.compile(r"^[-._0-9a-zA-z]+( '[-_ a-zA-Z]+')?\s+(w[0-9]+\s+)?\[ [-a-z]+ \]")
- _line_re3 = re.compile(r"^\*\*\*Warnings generated in error logs during shutdown after running tests: (.*)")
- _line_re4 = re.compile(r"^The servers were restarted [0-9]+ times$")
- _line_re5 = re.compile(r"^Only\s+[0-9]+\s+of\s+[0-9]+\s+completed.$")
-
- def __init__(self, textLimit=5, testNameLimit=16, testType=None):
- self.textLimit = textLimit
- self.testNameLimit = testNameLimit
- self.testType = testType
- self.numTests = 0
- self.testFail = None
- self.failList = []
- self.warnList = []
- LogLineObserver.__init__(self)
-
- def setLog(self, loog):
- LogLineObserver.setLog(self, loog)
- d= loog.waitUntilFinished()
- d.addCallback(lambda l: self.closeTestFail())
-
- def outLineReceived(self, line):
- stripLine = line.strip("\r\n")
- m = self._line_re.search(stripLine)
- if m:
- testname, variant, worker, result, info = m.groups()
- self.closeTestFail()
- self.numTests += 1
- self.step.setProgress('tests', self.numTests)
-
- if result == "fail":
- if variant == None:
- variant = ""
- else:
- variant = variant[2:-1]
- self.openTestFail(testname, variant, result, info, stripLine + "\n")
-
- else:
- m = self._line_re3.search(stripLine)
- if m:
- stuff = m.group(1)
- self.closeTestFail()
- testList = stuff.split(" ")
- self.doCollectWarningTests(testList)
-
- elif (self._line_re2.search(stripLine) or
- self._line_re4.search(stripLine) or
- self._line_re5.search(stripLine) or
- stripLine == "Test suite timeout! Terminating..." or
- stripLine.startswith("mysql-test-run: *** ERROR: Not all tests completed") or
- (stripLine.startswith("------------------------------------------------------------")
- and self.testFail != None)):
- self.closeTestFail()
-
- else:
- self.addTestFailOutput(stripLine + "\n")
-
- def openTestFail(self, testname, variant, result, info, line):
- self.testFail = MtrTestFailData(testname, variant, result, info, line, self.doCollectTestFail)
-
- def addTestFailOutput(self, line):
- if self.testFail != None:
- self.testFail.add(line)
-
- def closeTestFail(self):
- if self.testFail != None:
- self.testFail.fireCallback()
- self.testFail = None
-
- def addToText(self, src, dst):
- lastOne = None
- count = 0
- for t in src:
- if t != lastOne:
- dst.append(t)
- count += 1
- if count >= self.textLimit:
- break
-
- def makeText(self, done):
- if done:
- text = ["test"]
- else:
- text = ["testing"]
- if self.testType:
- text.append(self.testType)
- fails = self.failList[:]
- fails.sort()
- self.addToText(fails, text)
- warns = self.warnList[:]
- warns.sort()
- self.addToText(warns, text)
- return text
-
- # Update waterfall status.
- def updateText(self):
- self.step.step_status.setText(self.makeText(False))
-
- strip_re = re.compile(r"^[a-z]+\.")
-
- def displayTestName(self, testname):
-
- displayTestName = self.strip_re.sub("", testname)
-
- if len(displayTestName) > self.testNameLimit:
- displayTestName = displayTestName[:(self.testNameLimit-2)] + "..."
- return displayTestName
-
- def doCollectTestFail(self, testname, variant, result, info, text):
- self.failList.append("F:" + self.displayTestName(testname))
- self.updateText()
- self.collectTestFail(testname, variant, result, info, text)
-
- def doCollectWarningTests(self, testList):
- for t in testList:
- self.warnList.append("W:" + self.displayTestName(t))
- self.updateText()
- self.collectWarningTests(testList)
-
- # These two methods are overridden to actually do something with the data.
- def collectTestFail(self, testname, variant, result, info, text):
- pass
- def collectWarningTests(self, testList):
- pass
-
-class MTR(Test):
- """
- Build step that runs mysql-test-run.pl, as used in MySQL, Drizzle,
- MariaDB, etc.
-
- It uses class MtrLogObserver to parse test results out from the
- output of mysql-test-run.pl, providing better completion time
- estimates and summarising test failures on the waterfall page.
-
- It also provides access to mysqld server error logs from the test
- run to help debugging any problems.
-
- Optionally, it can insert into a database data about the test run,
- including details of any test failures.
-
- Parameters:
-
- textLimit
- Maximum number of test failures to show on the waterfall page
- (to not flood the page in case of a large number of test
- failures. Defaults to 5.
-
- testNameLimit
- Maximum length of test names to show unabbreviated in the
- waterfall page, to avoid excessive column width. Defaults to 16.
-
- parallel
- Value of --parallel option used for mysql-test-run.pl (number
- of processes used to run the test suite in parallel). Defaults
- to 4. This is used to determine the number of server error log
- files to download from the slave. Specifying a too high value
- does not hurt (as nonexisting error logs will be ignored),
- however if using --parallel value greater than the default it
- needs to be specified, or some server error logs will be
- missing.
-
- dbpool
- An instance of twisted.enterprise.adbapi.ConnectionPool, or None.
- Defaults to None. If specified, results are inserted into the database
- using the ConnectionPool.
-
- The class process.mtrlogobserver.EqConnectionPool subclass of
- ConnectionPool can be useful to pass as value for dbpool, to
- avoid having config reloads think the Buildstep is changed
- just because it gets a new ConnectionPool instance (even
- though connection parameters are unchanged).
-
- autoCreateTables
- Boolean, defaults to False. If True (and dbpool is specified), the
- necessary database tables will be created automatically if they do
- not exist already. Alternatively, the tables can be created manually
- from the SQL statements found in the mtrlogobserver.py source file.
-
- test_type
- test_info
- Two descriptive strings that will be inserted in the database tables if
- dbpool is specified. The test_type string, if specified, will also
- appear on the waterfall page."""
-
- renderables = [ 'mtr_subdir' ]
-
- def __init__(self, dbpool=None, test_type=None, test_info="",
- description=None, descriptionDone=None,
- autoCreateTables=False, textLimit=5, testNameLimit=16,
- parallel=4, logfiles = {}, lazylogfiles = True,
- warningPattern="MTR's internal check of the test case '.*' failed",
- mtr_subdir="mysql-test", **kwargs):
-
- if description is None:
- description = ["testing"]
- if test_type:
- description.append(test_type)
- if descriptionDone is None:
- descriptionDone = ["test"]
- if test_type:
- descriptionDone.append(test_type)
- Test.__init__(self, logfiles=logfiles, lazylogfiles=lazylogfiles,
- description=description, descriptionDone=descriptionDone,
- warningPattern=warningPattern, **kwargs)
- self.dbpool = dbpool
- self.test_type = test_type
- self.test_info = test_info
- self.autoCreateTables = autoCreateTables
- self.textLimit = textLimit
- self.testNameLimit = testNameLimit
- self.parallel = parallel
- self.mtr_subdir = mtr_subdir
- self.progressMetrics += ('tests',)
-
- def start(self):
- # Add mysql server logfiles.
- for mtr in range(0, self.parallel+1):
- for mysqld in range(1, 4+1):
- if mtr == 0:
- logname = "mysqld.%d.err" % mysqld
- filename = "var/log/mysqld.%d.err" % mysqld
- else:
- logname = "mysqld.%d.err.%d" % (mysqld, mtr)
- filename = "var/%d/log/mysqld.%d.err" % (mtr, mysqld)
- self.addLogFile(logname, self.mtr_subdir + "/" + filename)
-
- self.myMtr = self.MyMtrLogObserver(textLimit=self.textLimit,
- testNameLimit=self.testNameLimit,
- testType=self.test_type)
- self.addLogObserver("stdio", self.myMtr)
- # Insert a row for this test run into the database and set up
- # build properties, then start the command proper.
- d = self.registerInDB()
- d.addCallback(self.afterRegisterInDB)
- d.addErrback(self.failed)
-
- def getText(self, command, results):
- return self.myMtr.makeText(True)
-
- def runInteractionWithRetry(self, actionFn, *args, **kw):
- """
- Run a database transaction with dbpool.runInteraction, but retry the
- transaction in case of a temporary error (like connection lost).
-
- This is needed to be robust against things like database connection
- idle timeouts.
-
- The passed callable that implements the transaction must be retryable,
- ie. it must not have any destructive side effects in the case where
- an exception is thrown and/or rollback occurs that would prevent it
- from functioning correctly when called again."""
-
- def runWithRetry(txn, *args, **kw):
- retryCount = 0
- while(True):
- try:
- return actionFn(txn, *args, **kw)
- except txn.OperationalError:
- retryCount += 1
- if retryCount >= 5:
- raise
- excType, excValue, excTraceback = sys.exc_info()
- log.msg("Database transaction failed (caught exception %s(%s)), retrying ..." % (excType, excValue))
- txn.close()
- txn.reconnect()
- txn.reopen()
-
- return self.dbpool.runInteraction(runWithRetry, *args, **kw)
-
- def runQueryWithRetry(self, *args, **kw):
- """
- Run a database query, like with dbpool.runQuery, but retry the query in
- case of a temporary error (like connection lost).
-
- This is needed to be robust against things like database connection
- idle timeouts."""
-
- def runQuery(txn, *args, **kw):
- txn.execute(*args, **kw)
- return txn.fetchall()
-
- return self.runInteractionWithRetry(runQuery, *args, **kw)
-
- def registerInDB(self):
- if self.dbpool:
- return self.runInteractionWithRetry(self.doRegisterInDB)
- else:
- return defer.succeed(0)
-
- # The real database work is done in a thread in a synchronous way.
- def doRegisterInDB(self, txn):
- # Auto create tables.
- # This is off by default, as it gives warnings in log file
- # about tables already existing (and I did not find the issue
- # important enough to find a better fix).
- if self.autoCreateTables:
- txn.execute("""
-CREATE TABLE IF NOT EXISTS test_run(
- id INT PRIMARY KEY AUTO_INCREMENT,
- branch VARCHAR(100),
- revision VARCHAR(32) NOT NULL,
- platform VARCHAR(100) NOT NULL,
- dt TIMESTAMP NOT NULL,
- bbnum INT NOT NULL,
- typ VARCHAR(32) NOT NULL,
- info VARCHAR(255),
- KEY (branch, revision),
- KEY (dt),
- KEY (platform, bbnum)
-) ENGINE=innodb
-""")
- txn.execute("""
-CREATE TABLE IF NOT EXISTS test_failure(
- test_run_id INT NOT NULL,
- test_name VARCHAR(100) NOT NULL,
- test_variant VARCHAR(16) NOT NULL,
- info_text VARCHAR(255),
- failure_text TEXT,
- PRIMARY KEY (test_run_id, test_name, test_variant)
-) ENGINE=innodb
-""")
- txn.execute("""
-CREATE TABLE IF NOT EXISTS test_warnings(
- test_run_id INT NOT NULL,
- list_id INT NOT NULL,
- list_idx INT NOT NULL,
- test_name VARCHAR(100) NOT NULL,
- PRIMARY KEY (test_run_id, list_id, list_idx)
-) ENGINE=innodb
-""")
-
- revision = self.getProperty("got_revision")
- if revision is None:
- revision = self.getProperty("revision")
- typ = "mtr"
- if self.test_type:
- typ = self.test_type
- txn.execute("""
-INSERT INTO test_run(branch, revision, platform, dt, bbnum, typ, info)
-VALUES (%s, %s, %s, CURRENT_TIMESTAMP(), %s, %s, %s)
-""", (self.getProperty("branch"), revision,
- self.getProperty("buildername"), self.getProperty("buildnumber"),
- typ, self.test_info))
-
- return txn.lastrowid
-
- def afterRegisterInDB(self, insert_id):
- self.setProperty("mtr_id", insert_id)
- self.setProperty("mtr_warn_id", 0)
-
- Test.start(self)
-
- def reportError(self, err):
- log.msg("Error in async insert into database: %s" % err)
-
- class MyMtrLogObserver(MtrLogObserver):
- def collectTestFail(self, testname, variant, result, info, text):
- # Insert asynchronously into database.
- dbpool = self.step.dbpool
- run_id = self.step.getProperty("mtr_id")
- if dbpool == None:
- return defer.succeed(None)
- if variant == None:
- variant = ""
- d = self.step.runQueryWithRetry("""
-INSERT INTO test_failure(test_run_id, test_name, test_variant, info_text, failure_text)
-VALUES (%s, %s, %s, %s, %s)
-""", (run_id, testname, variant, info, text))
-
- d.addErrback(self.step.reportError)
- return d
-
- def collectWarningTests(self, testList):
- # Insert asynchronously into database.
- dbpool = self.step.dbpool
- if dbpool == None:
- return defer.succeed(None)
- run_id = self.step.getProperty("mtr_id")
- warn_id = self.step.getProperty("mtr_warn_id")
- self.step.setProperty("mtr_warn_id", warn_id + 1)
- q = ("INSERT INTO test_warnings(test_run_id, list_id, list_idx, test_name) " +
- "VALUES " + ", ".join(map(lambda x: "(%s, %s, %s, %s)", testList)))
- v = []
- idx = 0
- for t in testList:
- v.extend([run_id, warn_id, idx, t])
- idx = idx + 1
- d = self.step.runQueryWithRetry(q, tuple(v))
- d.addErrback(self.step.reportError)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/properties.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/properties.py
deleted file mode 100644
index 4edf394e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/properties.py
+++ /dev/null
@@ -1,689 +0,0 @@
-# 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 collections
-import re
-import warnings
-import weakref
-from buildbot import config, util
-from buildbot.util import json
-from buildbot.interfaces import IRenderable, IProperties
-from twisted.internet import defer
-from twisted.python.components import registerAdapter
-from zope.interface import implements
-
-class Properties(util.ComparableMixin):
- """
- I represent a set of properties that can be interpolated into various
- strings in buildsteps.
-
- @ivar properties: dictionary mapping property values to tuples
- (value, source), where source is a string identifing the source
- of the property.
-
- Objects of this class can be read like a dictionary -- in this case,
- only the property value is returned.
-
- As a special case, a property value of None is returned as an empty
- string when used as a mapping.
- """
-
- compare_attrs = ('properties',)
- implements(IProperties)
-
- def __init__(self, **kwargs):
- """
- @param kwargs: initial property values (for testing)
- """
- self.properties = {}
- # Track keys which are 'runtime', and should not be
- # persisted if a build is rebuilt
- self.runtime = set()
- self.build = None # will be set by the Build when starting
- if kwargs: self.update(kwargs, "TEST")
-
- @classmethod
- def fromDict(cls, propDict):
- properties = cls()
- for name, (value, source) in propDict.iteritems():
- properties.setProperty(name, value, source)
- return properties
-
- def __getstate__(self):
- d = self.__dict__.copy()
- d['build'] = None
- return d
-
- def __setstate__(self, d):
- self.__dict__ = d
- if not hasattr(self, 'runtime'):
- self.runtime = set()
-
- def __contains__(self, name):
- return name in self.properties
-
- def __getitem__(self, name):
- """Just get the value for this property."""
- rv = self.properties[name][0]
- return rv
-
- def __nonzero__(self):
- return not not self.properties
-
- def getPropertySource(self, name):
- return self.properties[name][1]
-
- def asList(self):
- """Return the properties as a sorted list of (name, value, source)"""
- l = [ (k, v[0], v[1]) for k,v in self.properties.iteritems() ]
- l.sort()
- return l
-
- def asDict(self):
- """Return the properties as a simple key:value dictionary"""
- return dict(self.properties)
-
- def __repr__(self):
- return ('Properties(**' +
- repr(dict((k,v[0]) for k,v in self.properties.iteritems())) +
- ')')
-
- def update(self, dict, source, runtime=False):
- """Update this object from a dictionary, with an explicit source specified."""
- for k, v in dict.items():
- self.setProperty(k, v, source, runtime=runtime)
-
- def updateFromProperties(self, other):
- """Update this object based on another object; the other object's """
- self.properties.update(other.properties)
- self.runtime.update(other.runtime)
-
- def updateFromPropertiesNoRuntime(self, other):
- """Update this object based on another object, but don't
- include properties that were marked as runtime."""
- for k,v in other.properties.iteritems():
- if k not in other.runtime:
- self.properties[k] = v
-
- # IProperties methods
-
- def getProperty(self, name, default=None):
- return self.properties.get(name, (default,))[0]
-
- def hasProperty(self, name):
- return self.properties.has_key(name)
-
- has_key = hasProperty
-
- def setProperty(self, name, value, source, runtime=False):
- try:
- json.dumps(value)
- except TypeError:
- warnings.warn(
- "Non jsonable properties are not explicitly supported and" +
- "will be explicitly disallowed in a future version.",
- DeprecationWarning, stacklevel=2)
-
- self.properties[name] = (value, source)
- if runtime:
- self.runtime.add(name)
-
- def getProperties(self):
- return self
-
- def getBuild(self):
- return self.build
-
- def render(self, value):
- renderable = IRenderable(value)
- return defer.maybeDeferred(renderable.getRenderingFor, self)
-
-
-class PropertiesMixin:
- """
- A mixin to add L{IProperties} methods to a class which does not implement
- the interface, but which can be coerced to the interface via an adapter.
-
- This is useful because L{IProperties} methods are often called on L{Build}
- and L{BuildStatus} objects without first coercing them.
-
- @ivar set_runtime_properties: the default value for the C{runtime}
- parameter of L{setProperty}.
- """
-
- set_runtime_properties = False
-
- def getProperty(self, propname, default=None):
- props = IProperties(self)
- return props.getProperty(propname, default)
-
- def hasProperty(self, propname):
- props = IProperties(self)
- return props.hasProperty(propname)
-
- has_key = hasProperty
-
- def setProperty(self, propname, value, source='Unknown', runtime=None):
- # source is not optional in IProperties, but is optional here to avoid
- # breaking user-supplied code that fails to specify a source
- props = IProperties(self)
- if runtime is None:
- runtime = self.set_runtime_properties
- props.setProperty(propname, value, source, runtime=runtime)
-
- def getProperties(self):
- return IProperties(self)
-
- def render(self, value):
- props = IProperties(self)
- return props.render(value)
-
-
-
-class _PropertyMap(object):
- """
- Privately-used mapping object to implement WithProperties' substitutions,
- including the rendering of None as ''.
- """
- colon_minus_re = re.compile(r"(.*):-(.*)")
- colon_tilde_re = re.compile(r"(.*):~(.*)")
- colon_plus_re = re.compile(r"(.*):\+(.*)")
- def __init__(self, properties):
- # use weakref here to avoid a reference loop
- self.properties = weakref.ref(properties)
- self.temp_vals = {}
-
- def __getitem__(self, key):
- properties = self.properties()
- assert properties is not None
-
- def colon_minus(mo):
- # %(prop:-repl)s
- # if prop exists, use it; otherwise, use repl
- prop, repl = mo.group(1,2)
- if prop in self.temp_vals:
- return self.temp_vals[prop]
- elif properties.has_key(prop):
- return properties[prop]
- else:
- return repl
-
- def colon_tilde(mo):
- # %(prop:~repl)s
- # if prop exists and is true (nonempty), use it; otherwise, use repl
- prop, repl = mo.group(1,2)
- if prop in self.temp_vals and self.temp_vals[prop]:
- return self.temp_vals[prop]
- elif properties.has_key(prop) and properties[prop]:
- return properties[prop]
- else:
- return repl
-
- def colon_plus(mo):
- # %(prop:+repl)s
- # if prop exists, use repl; otherwise, an empty string
- prop, repl = mo.group(1,2)
- if properties.has_key(prop) or prop in self.temp_vals:
- return repl
- else:
- return ''
-
- for regexp, fn in [
- ( self.colon_minus_re, colon_minus ),
- ( self.colon_tilde_re, colon_tilde ),
- ( self.colon_plus_re, colon_plus ),
- ]:
- mo = regexp.match(key)
- if mo:
- rv = fn(mo)
- break
- else:
- # If explicitly passed as a kwarg, use that,
- # otherwise, use the property value.
- if key in self.temp_vals:
- rv = self.temp_vals[key]
- else:
- rv = properties[key]
-
- # translate 'None' to an empty string
- if rv is None: rv = ''
- return rv
-
- def add_temporary_value(self, key, val):
- 'Add a temporary value (to support keyword arguments to WithProperties)'
- self.temp_vals[key] = val
-
-class WithProperties(util.ComparableMixin):
- """
- This is a marker class, used fairly widely to indicate that we
- want to interpolate build properties.
- """
-
- implements(IRenderable)
- compare_attrs = ('fmtstring', 'args', 'lambda_subs')
-
- def __init__(self, fmtstring, *args, **lambda_subs):
- self.fmtstring = fmtstring
- self.args = args
- if not self.args:
- self.lambda_subs = lambda_subs
- for key, val in self.lambda_subs.iteritems():
- if not callable(val):
- raise ValueError('Value for lambda substitution "%s" must be callable.' % key)
- elif lambda_subs:
- raise ValueError('WithProperties takes either positional or keyword substitutions, not both.')
-
- def getRenderingFor(self, build):
- pmap = _PropertyMap(build.getProperties())
- if self.args:
- strings = []
- for name in self.args:
- strings.append(pmap[name])
- s = self.fmtstring % tuple(strings)
- else:
- for k,v in self.lambda_subs.iteritems():
- pmap.add_temporary_value(k, v(build))
- s = self.fmtstring % pmap
- return s
-
-
-
-_notHasKey = object() ## Marker object for _Lookup(..., hasKey=...) default
-class _Lookup(util.ComparableMixin, object):
- implements(IRenderable)
-
- compare_attrs = ('value', 'index', 'default', 'defaultWhenFalse', 'hasKey', 'elideNoneAs')
-
- def __init__(self, value, index, default=None,
- defaultWhenFalse=True, hasKey=_notHasKey,
- elideNoneAs=None):
- self.value = value
- self.index = index
- self.default = default
- self.defaultWhenFalse = defaultWhenFalse
- self.hasKey = hasKey
- self.elideNoneAs = elideNoneAs
-
- def __repr__(self):
- return '_Lookup(%r, %r%s%s%s%s)' % (
- self.value,
- self.index,
- ', default=%r' % (self.default,)
- if self.default is not None else '',
- ', defaultWhenFalse=False'
- if not self.defaultWhenFalse else '',
- ', hasKey=%r' % (self.hasKey,)
- if self.hasKey is not _notHasKey else '',
- ', elideNoneAs=%r'% (self.elideNoneAs,)
- if self.elideNoneAs is not None else '')
-
-
- @defer.inlineCallbacks
- def getRenderingFor(self, build):
- value = build.render(self.value)
- index = build.render(self.index)
- value, index = yield defer.gatherResults([value, index])
- if not value.has_key(index):
- rv = yield build.render(self.default)
- else:
- if self.defaultWhenFalse:
- rv = yield build.render(value[index])
- if not rv:
- rv = yield build.render(self.default)
- elif self.hasKey is not _notHasKey:
- rv = yield build.render(self.hasKey)
- elif self.hasKey is not _notHasKey:
- rv = yield build.render(self.hasKey)
- else:
- rv = yield build.render(value[index])
- if rv is None:
- rv = yield build.render(self.elideNoneAs)
- defer.returnValue(rv)
-
-
-def _getInterpolationList(fmtstring):
- # TODO: Verify that no positial substitutions are requested
- dd = collections.defaultdict(str)
- fmtstring % dd
- return dd.keys()
-
-
-class _PropertyDict(object):
- implements(IRenderable)
- def getRenderingFor(self, build):
- return build.getProperties()
-_thePropertyDict = _PropertyDict()
-
-class _SourceStampDict(util.ComparableMixin, object):
- implements(IRenderable)
-
- compare_attrs = ('codebase',)
-
- def __init__(self, codebase):
- self.codebase = codebase
- def getRenderingFor(self, build):
- ss = build.getBuild().getSourceStamp(self.codebase)
- if ss:
- return ss.asDict()
- else:
- return {}
-
-class _Lazy(util.ComparableMixin, object):
- implements(IRenderable)
-
- compare_attrs = ('value',)
- def __init__(self, value):
- self.value = value
- def getRenderingFor(self, build):
- return self.value
-
- def __repr__(self):
- return '_Lazy(%r)' % self.value
-
-
-class Interpolate(util.ComparableMixin, object):
- """
- This is a marker class, used fairly widely to indicate that we
- want to interpolate build properties.
- """
-
- implements(IRenderable)
- compare_attrs = ('fmtstring', 'args', 'kwargs')
-
- identifier_re = re.compile('^[\w-]*$')
-
- def __init__(self, fmtstring, *args, **kwargs):
- self.fmtstring = fmtstring
- self.args = args
- self.kwargs = kwargs
- if self.args and self.kwargs:
- config.error("Interpolate takes either positional or keyword "
- "substitutions, not both.")
- if not self.args:
- self.interpolations = {}
- self._parse(fmtstring)
-
- # TODO: add case below for when there's no args or kwargs..
- def __repr__(self):
- if self.args:
- return 'Interpolate(%r, *%r)' % (self.fmtstring, self.args)
- elif self.kwargs:
- return 'Interpolate(%r, **%r)' % (self.fmtstring, self.kwargs)
- else:
- return 'Interpolate(%r)' % (self.fmtstring,)
-
- @staticmethod
- def _parse_prop(arg):
- try:
- prop, repl = arg.split(":", 1)
- except ValueError:
- prop, repl = arg, None
- if not Interpolate.identifier_re.match(prop):
- config.error("Property name must be alphanumeric for prop Interpolation '%s'" % arg)
- prop = repl = None
- return _thePropertyDict, prop, repl
-
- @staticmethod
- def _parse_src(arg):
- ## TODO: Handle changes
- try:
- codebase, attr, repl = arg.split(":", 2)
- except ValueError:
- try:
- codebase, attr = arg.split(":",1)
- repl = None
- except ValueError:
- config.error("Must specify both codebase and attribute for src Interpolation '%s'" % arg)
- return {}, None, None
-
- if not Interpolate.identifier_re.match(codebase):
- config.error("Codebase must be alphanumeric for src Interpolation '%s'" % arg)
- codebase = attr = repl = None
- if not Interpolate.identifier_re.match(attr):
- config.error("Attribute must be alphanumeric for src Interpolation '%s'" % arg)
- codebase = attr = repl = None
- return _SourceStampDict(codebase), attr, repl
-
- def _parse_kw(self, arg):
- try:
- kw, repl = arg.split(":", 1)
- except ValueError:
- kw, repl = arg, None
- if not Interpolate.identifier_re.match(kw):
- config.error("Keyword must be alphanumeric for kw Interpolation '%s'" % arg)
- kw = repl = None
- return _Lazy(self.kwargs), kw, repl
-
- def _parseSubstitution(self, fmt):
- try:
- key, arg = fmt.split(":", 1)
- except ValueError:
- config.error("invalid Interpolate substitution without selector '%s'" % fmt)
- return
-
- fn = getattr(self, "_parse_" + key, None)
- if not fn:
- config.error("invalid Interpolate selector '%s'" % key)
- return None
- else:
- return fn(arg)
-
- @staticmethod
- def _splitBalancedParen(delim, arg):
- parenCount = 0
- for i in range(0, len(arg)):
- if arg[i] == "(":
- parenCount += 1
- if arg[i] == ")":
- parenCount -= 1
- if parenCount < 0:
- raise ValueError
- if parenCount == 0 and arg[i] == delim:
- return arg[0:i], arg[i+1:]
- return arg
-
- def _parseColon_minus(self, d, kw, repl):
- return _Lookup(d, kw,
- default=Interpolate(repl, **self.kwargs),
- defaultWhenFalse=False,
- elideNoneAs='')
-
- def _parseColon_tilde(self, d, kw, repl):
- return _Lookup(d, kw,
- default=Interpolate(repl, **self.kwargs),
- defaultWhenFalse=True,
- elideNoneAs='')
-
- def _parseColon_plus(self, d, kw, repl):
- return _Lookup(d, kw,
- hasKey=Interpolate(repl, **self.kwargs),
- default='',
- defaultWhenFalse=False,
- elideNoneAs='')
-
- def _parseColon_ternary(self, d, kw, repl, defaultWhenFalse=False):
- delim = repl[0]
- if delim == '(':
- config.error("invalid Interpolate ternary delimiter '('")
- return None
- try:
- truePart, falsePart = self._splitBalancedParen(delim, repl[1:])
- except ValueError:
- config.error("invalid Interpolate ternary expression '%s' with delimiter '%s'" % (repl[1:], repl[0]))
- return None
- return _Lookup(d, kw,
- hasKey=Interpolate(truePart, **self.kwargs),
- default=Interpolate(falsePart, **self.kwargs),
- defaultWhenFalse=defaultWhenFalse,
- elideNoneAs='')
-
- def _parseColon_ternary_hash(self, d, kw, repl):
- return self._parseColon_ternary(d, kw, repl, defaultWhenFalse=True)
-
- def _parse(self, fmtstring):
- keys = _getInterpolationList(fmtstring)
- for key in keys:
- if not self.interpolations.has_key(key):
- d, kw, repl = self._parseSubstitution(key)
- if repl is None:
- repl = '-'
- for pattern, fn in [
- ( "-", self._parseColon_minus ),
- ( "~", self._parseColon_tilde ),
- ( "+", self._parseColon_plus ),
- ( "?", self._parseColon_ternary ),
- ( "#?", self._parseColon_ternary_hash )
- ]:
- junk, matches, tail = repl.partition(pattern)
- if not junk and matches:
- self.interpolations[key] = fn(d, kw, tail)
- break
- if not self.interpolations.has_key(key):
- config.error("invalid Interpolate default type '%s'" % repl[0])
-
- def getRenderingFor(self, props):
- props = props.getProperties()
- if self.args:
- d = props.render(self.args)
- d.addCallback(lambda args:
- self.fmtstring % tuple(args))
- return d
- else:
- d = props.render(self.interpolations)
- d.addCallback(lambda res:
- self.fmtstring % res)
- return d
-
-class Property(util.ComparableMixin):
- """
- An instance of this class renders a property of a build.
- """
-
- implements(IRenderable)
-
- compare_attrs = ('key','default', 'defaultWhenFalse')
-
- def __init__(self, key, default=None, defaultWhenFalse=True):
- """
- @param key: Property to render.
- @param default: Value to use if property isn't set.
- @param defaultWhenFalse: When true (default), use default value
- if property evaluates to False. Otherwise, use default value
- only when property isn't set.
- """
- self.key = key
- self.default = default
- self.defaultWhenFalse = defaultWhenFalse
-
- def getRenderingFor(self, props):
- if self.defaultWhenFalse:
- d = props.render(props.getProperty(self.key))
- @d.addCallback
- def checkDefault(rv):
- if rv:
- return rv
- else:
- return props.render(self.default)
- return d
- else:
- if props.hasProperty(self.key):
- return props.render(props.getProperty(self.key))
- else:
- return props.render(self.default)
-
-class _Renderer(util.ComparableMixin, object):
- implements(IRenderable)
-
- compare_attrs = ('getRenderingFor',)
-
- def __init__(self, fn):
- self.getRenderingFor = fn
-
- def __repr__(self):
- return 'renderer(%r)' % (self.getRenderingFor,)
-
-def renderer(fn):
- return _Renderer(fn)
-
-class _DefaultRenderer(object):
- """
- Default IRenderable adaptor. Calls .getRenderingFor if availble, otherwise
- returns argument unchanged.
- """
-
- implements(IRenderable)
-
- def __init__(self, value):
- try:
- self.renderer = value.getRenderingFor
- except AttributeError:
- self.renderer = lambda _: value
-
- def getRenderingFor(self, build):
- return self.renderer(build)
-
-registerAdapter(_DefaultRenderer, object, IRenderable)
-
-
-class _ListRenderer(object):
- """
- List IRenderable adaptor. Maps Build.render over the list.
- """
-
- implements(IRenderable)
-
- def __init__(self, value):
- self.value = value
-
- def getRenderingFor(self, build):
- return defer.gatherResults([ build.render(e) for e in self.value ])
-
-registerAdapter(_ListRenderer, list, IRenderable)
-
-
-class _TupleRenderer(object):
- """
- Tuple IRenderable adaptor. Maps Build.render over the tuple.
- """
-
- implements(IRenderable)
-
- def __init__(self, value):
- self.value = value
-
- def getRenderingFor(self, build):
- d = defer.gatherResults([ build.render(e) for e in self.value ])
- d.addCallback(tuple)
- return d
-
-registerAdapter(_TupleRenderer, tuple, IRenderable)
-
-
-class _DictRenderer(object):
- """
- Dict IRenderable adaptor. Maps Build.render over the keya and values in the dict.
- """
-
- implements(IRenderable)
-
- def __init__(self, value):
- self.value = _ListRenderer([ _TupleRenderer((k,v)) for k,v in value.iteritems() ])
-
- def getRenderingFor(self, build):
- d = self.value.getRenderingFor(build)
- d.addCallback(dict)
- return d
-
-registerAdapter(_DictRenderer, dict, IRenderable)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/slavebuilder.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/slavebuilder.py
deleted file mode 100644
index 174ee741..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/slavebuilder.py
+++ /dev/null
@@ -1,297 +0,0 @@
-# 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
-
-from twisted.spread import pb
-from twisted.internet import defer
-from twisted.python import log
-
-(ATTACHING, # slave attached, still checking hostinfo/etc
- IDLE, # idle, available for use
- PINGING, # build about to start, making sure it is still alive
- BUILDING, # build is running
- LATENT, # latent slave is not substantiated; similar to idle
- SUBSTANTIATING,
- ) = range(6)
-
-class AbstractSlaveBuilder(pb.Referenceable):
- """I am the master-side representative for one of the
- L{buildbot.slave.bot.SlaveBuilder} objects that lives in a remote
- buildbot. When a remote builder connects, I query it for command versions
- and then make it available to any Builds that are ready to run. """
-
- def __init__(self):
- self.ping_watchers = []
- self.state = None # set in subclass
- self.remote = None
- self.slave = None
- self.builder_name = None
- self.locks = None
-
- def __repr__(self):
- r = ["<", self.__class__.__name__]
- if self.builder_name:
- r.extend([" builder=", repr(self.builder_name)])
- if self.slave:
- r.extend([" slave=", repr(self.slave.slavename)])
- r.append(">")
- return ''.join(r)
-
- def setBuilder(self, b):
- self.builder = b
- self.builder_name = b.name
-
- def getSlaveCommandVersion(self, command, oldversion=None):
- if self.remoteCommands is None:
- # the slave is 0.5.0 or earlier
- return oldversion
- return self.remoteCommands.get(command)
-
- def isAvailable(self):
- # if this SlaveBuilder is busy, then it's definitely not available
- if self.isBusy():
- return False
-
- # otherwise, check in with the BuildSlave
- if self.slave:
- return self.slave.canStartBuild()
-
- # no slave? not very available.
- return False
-
- def isBusy(self):
- return self.state not in (IDLE, LATENT)
-
- def buildStarted(self):
- self.state = BUILDING
-
- def buildFinished(self):
- self.state = IDLE
- if self.slave:
- self.slave.buildFinished(self)
-
- def attached(self, slave, remote, commands):
- """
- @type slave: L{buildbot.buildslave.BuildSlave}
- @param slave: the BuildSlave that represents the buildslave as a
- whole
- @type remote: L{twisted.spread.pb.RemoteReference}
- @param remote: a reference to the L{buildbot.slave.bot.SlaveBuilder}
- @type commands: dict: string -> string, or None
- @param commands: provides the slave's version of each RemoteCommand
- """
- self.state = ATTACHING
- self.remote = remote
- self.remoteCommands = commands # maps command name to version
- if self.slave is None:
- self.slave = slave
- self.slave.addSlaveBuilder(self)
- else:
- assert self.slave == slave
- log.msg("Buildslave %s attached to %s" % (slave.slavename,
- self.builder_name))
- d = defer.succeed(None)
-
- d.addCallback(lambda _:
- self.remote.callRemote("setMaster", self))
-
- d.addCallback(lambda _:
- self.remote.callRemote("print", "attached"))
-
- def setIdle(res):
- self.state = IDLE
- return self
- d.addCallback(setIdle)
-
- return d
-
- def prepare(self, builder_status, build):
- if not self.slave.acquireLocks():
- return defer.succeed(False)
- return defer.succeed(True)
-
- def ping(self, status=None):
- """Ping the slave to make sure it is still there. Returns a Deferred
- that fires with True if it is.
-
- @param status: if you point this at a BuilderStatus, a 'pinging'
- event will be pushed.
- """
- oldstate = self.state
- self.state = PINGING
- newping = not self.ping_watchers
- d = defer.Deferred()
- self.ping_watchers.append(d)
- if newping:
- if status:
- event = status.addEvent(["pinging"])
- d2 = defer.Deferred()
- d2.addCallback(self._pong_status, event)
- self.ping_watchers.insert(0, d2)
- # I think it will make the tests run smoother if the status
- # is updated before the ping completes
- Ping().ping(self.remote).addCallback(self._pong)
-
- def reset_state(res):
- if self.state == PINGING:
- self.state = oldstate
- return res
- d.addCallback(reset_state)
- return d
-
- def _pong(self, res):
- watchers, self.ping_watchers = self.ping_watchers, []
- for d in watchers:
- d.callback(res)
-
- def _pong_status(self, res, event):
- if res:
- event.text = ["ping", "success"]
- else:
- event.text = ["ping", "failed"]
- event.finish()
-
- def detached(self):
- log.msg("Buildslave %s detached from %s" % (self.slave.slavename,
- self.builder_name))
- if self.slave:
- self.slave.removeSlaveBuilder(self)
- self.slave = None
- self.remote = None
- self.remoteCommands = None
-
-
-class Ping:
- running = False
-
- def ping(self, remote):
- assert not self.running
- if not remote:
- # clearly the ping must fail
- return defer.succeed(False)
- self.running = True
- log.msg("sending ping")
- self.d = defer.Deferred()
- # TODO: add a distinct 'ping' command on the slave.. using 'print'
- # for this purpose is kind of silly.
- remote.callRemote("print", "ping").addCallbacks(self._pong,
- self._ping_failed,
- errbackArgs=(remote,))
- return self.d
-
- def _pong(self, res):
- log.msg("ping finished: success")
- self.d.callback(True)
-
- def _ping_failed(self, res, remote):
- log.msg("ping finished: failure")
- # the slave has some sort of internal error, disconnect them. If we
- # don't, we'll requeue a build and ping them again right away,
- # creating a nasty loop.
- remote.broker.transport.loseConnection()
- # TODO: except, if they actually did manage to get this far, they'll
- # probably reconnect right away, and we'll do this game again. Maybe
- # it would be better to leave them in the PINGING state.
- self.d.callback(False)
-
-
-class SlaveBuilder(AbstractSlaveBuilder):
-
- def __init__(self):
- AbstractSlaveBuilder.__init__(self)
- self.state = ATTACHING
-
- def detached(self):
- AbstractSlaveBuilder.detached(self)
- if self.slave:
- self.slave.removeSlaveBuilder(self)
- self.slave = None
- self.state = ATTACHING
-
-class LatentSlaveBuilder(AbstractSlaveBuilder):
- def __init__(self, slave, builder):
- AbstractSlaveBuilder.__init__(self)
- self.slave = slave
- self.state = LATENT
- self.setBuilder(builder)
- self.slave.addSlaveBuilder(self)
- log.msg("Latent buildslave %s attached to %s" % (slave.slavename,
- self.builder_name))
-
- def prepare(self, builder_status, build):
- # If we can't lock, then don't bother trying to substantiate
- if not self.slave or not self.slave.acquireLocks():
- return defer.succeed(False)
-
- log.msg("substantiating slave %s" % (self,))
- d = self.substantiate(build)
- def substantiation_failed(f):
- builder_status.addPointEvent(['removing', 'latent',
- self.slave.slavename])
- self.slave.disconnect()
- # TODO: should failover to a new Build
- return f
- def substantiation_cancelled(res):
- # if res is False, latent slave cancelled subtantiation
- if not res:
- self.state = LATENT
- return res
- d.addCallback(substantiation_cancelled)
- d.addErrback(substantiation_failed)
- return d
-
- def substantiate(self, build):
- self.state = SUBSTANTIATING
- d = self.slave.substantiate(self, build)
- if not self.slave.substantiated:
- event = self.builder.builder_status.addEvent(
- ["substantiating"])
- def substantiated(res):
- msg = ["substantiate", "success"]
- if isinstance(res, basestring):
- msg.append(res)
- elif isinstance(res, (tuple, list)):
- msg.extend(res)
- event.text = msg
- event.finish()
- return res
- def substantiation_failed(res):
- event.text = ["substantiate", "failed"]
- # TODO add log of traceback to event
- event.finish()
- return res
- d.addCallbacks(substantiated, substantiation_failed)
- return d
-
- def detached(self):
- AbstractSlaveBuilder.detached(self)
- self.state = LATENT
-
- def buildStarted(self):
- AbstractSlaveBuilder.buildStarted(self)
- self.slave.buildStarted(self)
-
- def _attachFailure(self, why, where):
- self.state = LATENT
- return AbstractSlaveBuilder._attachFailure(self, why, where)
-
- def ping(self, status=None):
- if not self.slave.substantiated:
- if status:
- status.addEvent(["ping", "latent"]).finish()
- return defer.succeed(True)
- return AbstractSlaveBuilder.ping(self, status)
-
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/subunitlogobserver.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/subunitlogobserver.py
deleted file mode 100644
index de5df820..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/subunitlogobserver.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# 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
-
-
-from unittest import TestResult
-from StringIO import StringIO
-
-from buildbot.process import buildstep
-from buildbot.status.testresult import TestResult as aTestResult
-from buildbot.status.results import SUCCESS, FAILURE, SKIPPED
-
-class SubunitLogObserver(buildstep.LogLineObserver, TestResult):
- """Observe a log that may contain subunit output.
-
- This class extends TestResult to receive the callbacks from the subunit
- parser in the most direct fashion.
- """
-
- def __init__(self):
- buildstep.LogLineObserver.__init__(self)
- TestResult.__init__(self)
- try:
- from subunit import TestProtocolServer, PROGRESS_CUR, PROGRESS_SET
- from subunit import PROGRESS_PUSH, PROGRESS_POP
- except ImportError:
- raise ImportError("subunit is not importable, but is required for "
- "SubunitLogObserver support.")
- self.PROGRESS_CUR = PROGRESS_CUR
- self.PROGRESS_SET = PROGRESS_SET
- self.PROGRESS_PUSH = PROGRESS_PUSH
- self.PROGRESS_POP = PROGRESS_POP
- self.warningio = StringIO()
- self.protocol = TestProtocolServer(self, self.warningio)
- self.skips = []
- self.seen_tags = set() #don't yet know what tags does in subunit
-
- def outLineReceived(self, line):
- """Process a received stdout line."""
- # Impedance mismatch: subunit wants lines, observers get lines-no\n
- self.protocol.lineReceived(line + '\n')
-
- def errLineReceived(self, line):
- """same for stderr line."""
- self.protocol.lineReceived(line + '\n')
-
- def stopTest(self, test):
- TestResult.stopTest(self, test)
- self.step.setProgress('tests', self.testsRun)
-
- def addSuccess(self, test):
- TestResult.addSuccess(self, test)
- self.addAResult(test, SUCCESS, 'SUCCESS')
-
- def addSkip(self, test, detail):
- if hasattr(TestResult,'addSkip'):
- TestResult.addSkip(self, test, detail)
- else:
- self.skips.append((test, detail))
- self.addAResult(test, SKIPPED, 'SKIPPED', detail)
-
- def addError(self, test, err):
- TestResult.addError(self, test, err)
- self.issue(test, err)
-
- def addFailure(self, test, err):
- TestResult.addFailure(self, test, err)
- self.issue(test, err)
-
- def addAResult(self, test, result, text, log=""):
- tr = aTestResult(tuple(test.id().split('.')), result, text, log)
- self.step.build.build_status.addTestResult(tr)
-
- def issue(self, test, err):
- """An issue - failing, erroring etc test."""
- self.addAResult(test, FAILURE, 'FAILURE', err)
- self.step.setProgress('tests failed', len(self.failures) +
- len(self.errors))
-
- expectedTests = 0
- contextLevel = 0
- def progress(self, offset, whence):
- if not self.contextLevel:
- if whence == self.PROGRESS_CUR:
- self.expectedTests += offset
- elif whence == self.PROGRESS_SET:
- self.expectedTests = offset
- self.step.progress.setExpectations({'tests': self.expectedTests})
- #TODO: properly support PUSH/POP
- if whence == self.PROGRESS_PUSH:
- self.contextLevel += 1
- elif whence == self.PROGRESS_POP:
- self.contextLevel -= 1
-
- def tags(self, new_tags, gone_tags):
- """Accumulate the seen tags."""
- self.seen_tags.update(new_tags)
-
-# this used to be referenced here, so we keep a link for old time's sake
-import buildbot.steps.subunit
-SubunitShellCommand = buildbot.steps.subunit.SubunitShellCommand
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/manager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/manager.py
deleted file mode 100644
index 855af0c7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/manager.py
+++ /dev/null
@@ -1,45 +0,0 @@
-# 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
-
-from twisted.internet import defer
-from twisted.application import service
-from buildbot import config
-
-class UserManagerManager(config.ReconfigurableServiceMixin,
- service.MultiService):
- # this class manages a fleet of user managers; hence the name..
-
- def __init__(self, master):
- service.MultiService.__init__(self)
- self.setName('user_manager_manager')
- self.master = master
-
- @defer.inlineCallbacks
- def reconfigService(self, new_config):
- # this is easy - kick out all of the old managers, and add the
- # new ones.
-
- for mgr in list(self):
- yield defer.maybeDeferred(lambda :
- mgr.disownServiceParent())
- mgr.master = None
-
- for mgr in new_config.user_managers:
- mgr.master = self.master
- mgr.setServiceParent(self)
-
- # reconfig any newly-added change sources, as well as existing
- yield config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/manual.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/manual.py
deleted file mode 100644
index be94a691..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/manual.py
+++ /dev/null
@@ -1,234 +0,0 @@
-# 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
-
-# this class is known to contain cruft and will be looked at later, so
-# no current implementation utilizes it aside from scripts.runner.
-
-from twisted.python import log
-from twisted.internet import defer
-from twisted.application import service
-from buildbot import pbutil
-
-class UsersBase(service.MultiService):
- """
- Base class for services that manage users manually. This takes care
- of the service.MultiService work needed by all the services that
- subclass it.
- """
-
- def __init__(self):
- service.MultiService.__init__(self)
- self.master = None
-
- def startService(self):
- service.MultiService.startService(self)
-
- def stopService(self):
- return service.MultiService.stopService(self)
-
-class CommandlineUserManagerPerspective(pbutil.NewCredPerspective):
- """
- Perspective registered in buildbot.pbmanager and contains the real
- workings of `buildbot user` by working with the database when
- perspective_commandline is called.
- """
-
- def __init__(self, master):
- self.master = master
-
- def formatResults(self, op, results):
- """
- This formats the results of the database operations for printing
- back to the caller
-
- @param op: operation to perform (add, remove, update, get)
- @type op: string
-
- @param results: results from db queries in perspective_commandline
- @type results: list
-
- @returns: string containing formatted results
- """
- formatted_results = ""
-
- if op == 'add':
- # list, alternating ident, uid
- formatted_results += "user(s) added:\n"
- for user in results:
- if isinstance(user, basestring):
- formatted_results += "identifier: %s\n" % user
- else:
- formatted_results += "uid: %d\n\n" % user
- elif op == 'remove':
- # list of dictionaries
- formatted_results += "user(s) removed:\n"
- for user in results:
- if user:
- formatted_results += "identifier: %s\n" % (user)
- elif op == 'update':
- # list, alternating ident, None
- formatted_results += "user(s) updated:\n"
- for user in results:
- if user:
- formatted_results += "identifier: %s\n" % (user)
- elif op == 'get':
- # list of dictionaries
- formatted_results += "user(s) found:\n"
- for user in results:
- if user:
- for key in user:
- if key != 'bb_password':
- formatted_results += "%s: %s\n" % (key, user[key])
- formatted_results += "\n"
- else:
- formatted_results += "no match found\n"
- return formatted_results
-
- @defer.inlineCallbacks
- def perspective_commandline(self, op, bb_username, bb_password, ids, info):
- """
- This performs the requested operations from the `buildbot user`
- call by calling the proper buildbot.db.users methods based on
- the operation. It yields a deferred instance with the results
- from the database methods.
-
- @param op: operation to perform (add, remove, update, get)
- @type op: string
-
- @param bb_username: username portion of auth credentials
- @type bb_username: string
-
- @param bb_password: hashed password portion of auth credentials
- @type bb_password: hashed string
-
- @param ids: user identifiers used to find existing users
- @type ids: list of strings or None
-
- @param info: type/value pairs for each user that will be added
- or updated in the database
- @type info: list of dictionaries or None
-
- @returns: results from db.users methods via deferred
- """
- log.msg("perspective_commandline called")
- results = []
-
- if ids:
- for user in ids:
- # get identifier, guaranteed to be in user from checks
- # done in C{scripts.runner}
- uid = yield self.master.db.users.identifierToUid(
- identifier=user)
-
- result = None
- if op == 'remove':
- if uid:
- yield self.master.db.users.removeUser(uid)
- result = user
- else:
- log.msg("Unable to find uid for identifier %s" % user)
- elif op == 'get':
- if uid:
- result = yield self.master.db.users.getUser(uid)
- else:
- log.msg("Unable to find uid for identifier %s" % user)
-
- results.append(result)
- else:
- for user in info:
- # get identifier, guaranteed to be in user from checks
- # done in C{scripts.runner}
- ident = user.pop('identifier')
- uid = yield self.master.db.users.identifierToUid(
- identifier=ident)
-
- # if only an identifier was in user, we're updating only
- # the bb_username and bb_password.
- if not user:
- if uid:
- result = yield self.master.db.users.updateUser(
- uid=uid,
- identifier=ident,
- bb_username=bb_username,
- bb_password=bb_password)
- results.append(ident)
- else:
- log.msg("Unable to find uid for identifier %s"
- % user)
- else:
- # when adding, we update the user after the first attr
- once_through = False
- for attr in user:
- if op == 'update' or once_through:
- if uid:
- result = yield self.master.db.users.updateUser(
- uid=uid,
- identifier=ident,
- bb_username=bb_username,
- bb_password=bb_password,
- attr_type=attr,
- attr_data=user[attr])
- else:
- log.msg("Unable to find uid for identifier %s"
- % user)
- elif op == 'add':
- result = yield self.master.db.users.findUserByAttr(
- identifier=ident,
- attr_type=attr,
- attr_data=user[attr])
- once_through = True
- results.append(ident)
-
- # result is None from updateUser calls
- if result:
- results.append(result)
- uid = result
- results = self.formatResults(op, results)
- defer.returnValue(results)
-
-class CommandlineUserManager(UsersBase):
- """
- Service that runs to set up and register CommandlineUserManagerPerspective
- so `buildbot user` calls get to perspective_commandline.
- """
-
- def __init__(self, username=None, passwd=None, port=None):
- UsersBase.__init__(self)
- assert username and passwd, ("A username and password pair must be given "
- "to connect and use `buildbot user`")
- self.username = username
- self.passwd = passwd
-
- assert port, "A port must be specified for a PB connection"
- self.port = port
- self.registration = None
-
- def startService(self):
- UsersBase.startService(self)
- # set up factory and register with buildbot.pbmanager
- def factory(mind, username):
- return CommandlineUserManagerPerspective(self.master)
- self.registration = self.master.pbmanager.register(self.port,
- self.username,
- self.passwd,
- factory)
-
- def stopService(self):
- d = defer.maybeDeferred(UsersBase.stopService, self)
- def unreg(_):
- if self.registration:
- return self.registration.unregister()
- d.addCallback(unreg)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/users.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/users.py
deleted file mode 100644
index cae07428..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/process/users/users.py
+++ /dev/null
@@ -1,184 +0,0 @@
-# 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 os
-from twisted.python import log
-from twisted.internet import defer
-
-from buildbot.util import flatten
-
-try:
- from hashlib import sha1 as sha
- assert sha
-except ImportError:
- # For Python 2.4
- import sha
-
-srcs = ['git', 'svn', 'hg', 'cvs', 'darcs', 'bzr']
-salt_len = 8
-
-def createUserObject(master, author, src=None):
- """
- Take a Change author and source and translate them into a User Object,
- storing the user in master.db, or returning None if the src is not
- specified.
-
- @param master: link to Buildmaster for database operations
- @type master: master.Buildmaster instance
-
- @param authors: Change author if string or Authz instance
- @type authors: string or status.web.authz instance
-
- @param src: source from which the User Object will be created
- @type src: string
- """
-
- if not src:
- log.msg("No vcs information found, unable to create User Object")
- return defer.succeed(None)
-
- if src in srcs:
- usdict = dict(identifier=author, attr_type=src, attr_data=author)
- else:
- log.msg("Unrecognized source argument: %s" % src)
- return defer.succeed(None)
-
- return master.db.users.findUserByAttr(
- identifier=usdict['identifier'],
- attr_type=usdict['attr_type'],
- attr_data=usdict['attr_data'])
-
-
-def _extractContact(usdict, contact_types, uid):
- if usdict:
- for type in contact_types:
- contact = usdict.get(type)
- if contact:
- break
- else:
- contact = None
- if contact is None:
- log.msg(format="Unable to find any of %(contact_types)r for uid: %(uid)r",
- contact_types=contact_types, uid=uid)
- return contact
-
-def getUserContact(master, contact_types, uid):
- """
- This is a simple getter function that returns a user attribute
- that matches the contact_types argument, or returns None if no
- uid/match is found.
-
- @param master: BuildMaster used to query the database
- @type master: BuildMaster instance
-
- @param contact_types: list of contact attributes to look for in
- in a given user, such as 'email' or 'nick'
- @type contact_types: list of strings
-
- @param uid: user that is searched for the contact_types match
- @type uid: integer
-
- @returns: string of contact information or None via deferred
- """
- d = master.db.users.getUser(uid)
- d.addCallback(_extractContact, contact_types, uid)
- return d
-
-def _filter(contacts):
- def notNone(c):
- return c is not None
- return filter(notNone, contacts)
-
-def getUsersContacts(master, contact_types, uids):
- d = defer.gatherResults([getUserContact(master, contact_types, uid) for uid in uids])
- d.addCallback(_filter)
- return d
-
-def getChangeContacts(master, change, contact_types):
- d = master.db.changes.getChangeUids(change.number)
- d.addCallback(lambda uids: getUsersContacts(master, contact_types, uids))
- return d
-
-def getSourceStampContacts(master, ss, contact_types):
- dl = [getChangeContacts(master, change, contact_types) for change in ss.changes]
- if False and ss.patch_info:
- d = master.db.users.getUserByUsername(ss.patch_into[0])
- d.addCallback(_extractContact, contact_types, ss.patch_info[0])
- d.addCallback(lambda contact: filter(None, [contact]))
- dl.append(d)
- d = defer.gatherResults(dl)
- d.addCallback(flatten)
- return d
-
-def getBuildContacts(master, build, contact_types):
- dl = []
- ss_list = build.getSourceStamps()
- for ss in ss_list:
- dl.append(getSourceStampContacts(master, ss, contact_types))
- d = defer.gatherResults(dl)
- d.addCallback(flatten)
- @d.addCallback
- def addOwners(recipients):
- dl = []
- for owner in build.getInterestedUsers():
- d = master.db.users.getUserByUsername(owner)
- d.addCallback(_extractContact, contact_types, owner)
- dl.append(d)
- d = defer.gatherResults(dl)
- d.addCallback(_filter)
- d.addCallback(lambda owners: recipients + owners)
- return d
- return d
-
-def encrypt(passwd):
- """
- Encrypts the incoming password after adding some salt to store
- it in the database.
-
- @param passwd: password portion of user credentials
- @type passwd: string
-
- @returns: encrypted/salted string
- """
- try:
- m = sha()
- except TypeError:
- m = sha.new()
-
- salt = os.urandom(salt_len).encode('hex_codec')
- m.update(passwd + salt)
- crypted = salt + m.hexdigest()
- return crypted
-
-def check_passwd(guess, passwd):
- """
- Tests to see if the guess, after salting and hashing, matches the
- passwd from the database.
-
- @param guess: incoming password trying to be used for authentication
- @param passwd: already encrypted password from the database
-
- @returns: boolean
- """
- try:
- m = sha()
- except TypeError:
- m = sha.new()
-
- salt = passwd[:salt_len * 2] # salt_len * 2 due to encode('hex_codec')
- m.update(guess + salt)
- crypted_guess = salt + m.hexdigest()
-
- return (crypted_guess == passwd)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/revlinks.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/revlinks.py
deleted file mode 100644
index 033af9ae..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/revlinks.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# 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 re
-
-class RevlinkMatch(object):
- def __init__(self, repo_urls, revlink):
- if isinstance(repo_urls, str) or isinstance(repo_urls, unicode):
- repo_urls = [ repo_urls ]
- self.repo_urls = map(re.compile, repo_urls)
- self.revlink = revlink
- def __call__(self, rev, repo):
- for url in self.repo_urls:
- m = url.match(repo)
- if m:
- return m.expand(self.revlink) % rev
-
-GithubRevlink = RevlinkMatch(
- repo_urls = [ r'https://github.com/([^/]*)/([^/]*?)(?:\.git)?$',
- r'git://github.com/([^/]*)/([^/]*?)(?:\.git)?$',
- r'git@github.com:([^/]*)/([^/]*?)(?:\.git)?$',
- r'ssh://git@github.com/([^/]*)/([^/]*?)(?:\.git)?$'
- ],
- revlink = r'https://github.com/\1/\2/commit/%s')
-
-class GitwebMatch(RevlinkMatch):
- def __init__(self, repo_urls, revlink):
- RevlinkMatch.__init__(self, repo_urls = repo_urls, revlink = revlink + r'?p=\g<repo>;a=commit;h=%s')
-
-SourceforgeGitRevlink = GitwebMatch(
- repo_urls = [ r'^git://([^.]*).git.sourceforge.net/gitroot/(?P<repo>.*)$',
- r'[^@]*@([^.]*).git.sourceforge.net:gitroot/(?P<repo>.*)$',
- r'ssh://(?:[^@]*@)?([^.]*).git.sourceforge.net/gitroot/(?P<repo>.*)$',
- ],
- revlink = r'http://\1.git.sourceforge.net/git/gitweb.cgi')
-
-class RevlinkMultiplexer(object):
- def __init__(self, *revlinks):
- self.revlinks = revlinks
- def __call__(self, rev, repo):
- for revlink in self.revlinks:
- url = revlink(rev, repo)
- if url:
- return url
-
-default_revlink_matcher = RevlinkMultiplexer(GithubRevlink, SourceforgeGitRevlink)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scheduler.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scheduler.py
deleted file mode 100644
index 5997faaf..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scheduler.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# 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
-
-from buildbot.schedulers.basic import Scheduler, AnyBranchScheduler
-from buildbot.schedulers.dependent import Dependent
-from buildbot.schedulers.timed import Periodic, Nightly
-from buildbot.schedulers.triggerable import Triggerable
-from buildbot.schedulers.trysched import Try_Jobdir, Try_Userpass
-
-_hush_pyflakes = [Scheduler, AnyBranchScheduler, Dependent,
- Periodic, Nightly, Triggerable, Try_Jobdir, Try_Userpass]
-del _hush_pyflakes
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/base.py
deleted file mode 100644
index 4b18f935..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/base.py
+++ /dev/null
@@ -1,453 +0,0 @@
-# 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
-
-from zope.interface import implements
-from twisted.python import failure, log
-from twisted.application import service
-from twisted.internet import defer
-from buildbot.process.properties import Properties
-from buildbot.util import ComparableMixin
-from buildbot import config, interfaces
-from buildbot.util.state import StateMixin
-
-class BaseScheduler(service.MultiService, ComparableMixin, StateMixin):
- """
- Base class for all schedulers; this provides the equipment to manage
- reconfigurations and to handle basic scheduler state. It also provides
- utility methods to begin various sorts of builds.
-
- Subclasses should add any configuration-derived attributes to
- C{base.Scheduler.compare_attrs}.
- """
-
- implements(interfaces.IScheduler)
-
- DefaultCodebases = {'':{}}
-
- compare_attrs = ('name', 'builderNames', 'properties', 'codebases')
-
- def __init__(self, name, builderNames, properties,
- codebases = DefaultCodebases):
- """
- Initialize a Scheduler.
-
- @param name: name of this scheduler (used as a key for state)
- @type name: unicode
-
- @param builderNames: list of builders this scheduler may start
- @type builderNames: list of unicode
-
- @param properties: properties to add to builds triggered by this
- scheduler
- @type properties: dictionary
-
- @param codebases: codebases that are necessary to process the changes
- @type codebases: dict with following struct:
- key: '<codebase>'
- value: {'repository':'<repo>', 'branch':'<br>', 'revision:'<rev>'}
-
- @param consumeChanges: true if this scheduler wishes to be informed
- about the addition of new changes. Defaults to False. This should
- be passed explicitly from subclasses to indicate their interest in
- consuming changes.
- @type consumeChanges: boolean
- """
- service.MultiService.__init__(self)
- self.name = name
- "name of this scheduler; used to identify replacements on reconfig"
-
- ok = True
- if not isinstance(builderNames, (list, tuple)):
- ok = False
- else:
- for b in builderNames:
- if not isinstance(b, basestring):
- ok = False
- if not ok:
- config.error(
- "The builderNames argument to a scheduler must be a list "
- "of Builder names.")
-
- self.builderNames = builderNames
- "list of builder names to start in each buildset"
-
- self.properties = Properties()
- "properties that are contributed to each buildset"
- self.properties.update(properties, "Scheduler")
- self.properties.setProperty("scheduler", name, "Scheduler")
-
- self.objectid = None
-
- self.master = None
-
- # Set the codebases that are necessary to process the changes
- # These codebases will always result in a sourcestamp with or without changes
- if codebases is not None:
- if not isinstance(codebases, dict):
- config.error("Codebases must be a dict of dicts")
- for codebase, codebase_attrs in codebases.iteritems():
- if not isinstance(codebase_attrs, dict):
- config.error("Codebases must be a dict of dicts")
- if (codebases != BaseScheduler.DefaultCodebases and
- 'repository' not in codebase_attrs):
- config.error("The key 'repository' is mandatory in codebases")
- else:
- config.error("Codebases cannot be None")
-
- self.codebases = codebases
-
- # internal variables
- self._change_subscription = None
- self._change_consumption_lock = defer.DeferredLock()
-
- ## service handling
-
- def startService(self):
- service.MultiService.startService(self)
-
- def findNewSchedulerInstance(self, new_config):
- return new_config.schedulers[self.name] # should exist!
-
- def stopService(self):
- d = defer.maybeDeferred(self._stopConsumingChanges)
- d.addCallback(lambda _ : service.MultiService.stopService(self))
- return d
-
-
- ## status queries
-
- # TODO: these aren't compatible with distributed schedulers
-
- def listBuilderNames(self):
- "Returns the list of builder names"
- return self.builderNames
-
- def getPendingBuildTimes(self):
- "Returns a list of the next times that builds are scheduled, if known."
- return []
-
- ## change handling
-
- def startConsumingChanges(self, fileIsImportant=None, change_filter=None,
- onlyImportant=False):
- """
- Subclasses should call this method from startService to register to
- receive changes. The BaseScheduler class will take care of filtering
- the changes (using change_filter) and (if fileIsImportant is not None)
- classifying them. See L{gotChange}. Returns a Deferred.
-
- @param fileIsImportant: a callable provided by the user to distinguish
- important and unimportant changes
- @type fileIsImportant: callable
-
- @param change_filter: a filter to determine which changes are even
- considered by this scheduler, or C{None} to consider all changes
- @type change_filter: L{buildbot.changes.filter.ChangeFilter} instance
-
- @param onlyImportant: If True, only important changes, as specified by
- fileIsImportant, will be added to the buildset.
- @type onlyImportant: boolean
-
- """
- assert fileIsImportant is None or callable(fileIsImportant)
-
- # register for changes with master
- assert not self._change_subscription
- def changeCallback(change):
- # ignore changes delivered while we're not running
- if not self._change_subscription:
- return
-
- if change_filter and not change_filter.filter_change(change):
- return
- if change.codebase not in self.codebases:
- log.msg(format='change contains codebase %(codebase)s that is'
- 'not processed by scheduler %(scheduler)s',
- codebase=change.codebase, name=self.name)
- return
- if fileIsImportant:
- try:
- important = fileIsImportant(change)
- if not important and onlyImportant:
- return
- except:
- log.err(failure.Failure(),
- 'in fileIsImportant check for %s' % change)
- return
- else:
- important = True
-
- # use change_consumption_lock to ensure the service does not stop
- # while this change is being processed
- d = self._change_consumption_lock.run(self.gotChange, change, important)
- d.addErrback(log.err, 'while processing change')
- self._change_subscription = self.master.subscribeToChanges(changeCallback)
-
- return defer.succeed(None)
-
- def _stopConsumingChanges(self):
- # (note: called automatically in stopService)
-
- # acquire the lock change consumption lock to ensure that any change
- # consumption is complete before we are done stopping consumption
- def stop():
- if self._change_subscription:
- self._change_subscription.unsubscribe()
- self._change_subscription = None
- return self._change_consumption_lock.run(stop)
-
- def gotChange(self, change, important):
- """
- Called when a change is received; returns a Deferred. If the
- C{fileIsImportant} parameter to C{startConsumingChanges} was C{None},
- then all changes are considered important.
- The C{codebase} of the change has always an entry in the C{codebases}
- dictionary of the scheduler.
-
- @param change: the new change object
- @type change: L{buildbot.changes.changes.Change} instance
- @param important: true if this is an important change, according to
- C{fileIsImportant}.
- @type important: boolean
- @returns: Deferred
- """
- raise NotImplementedError
-
- ## starting bulids
-
- @defer.inlineCallbacks
- def addBuildsetForLatest(self, reason='', external_idstring=None,
- branch=None, repository='', project='',
- builderNames=None, properties=None):
- """
- Add a buildset for the 'latest' source in the given branch,
- repository, and project. This will create a relative sourcestamp for
- the buildset.
-
- This method will add any properties provided to the scheduler
- constructor to the buildset, and will call the master's addBuildset
- method with the appropriate parameters.
-
- @param reason: reason for this buildset
- @type reason: unicode string
- @param external_idstring: external identifier for this buildset, or None
- @param branch: branch to build (note that None often has a special meaning)
- @param repository: repository name for sourcestamp
- @param project: project name for sourcestamp
- @param builderNames: builders to name in the buildset (defaults to
- C{self.builderNames})
- @param properties: a properties object containing initial properties for
- the buildset
- @type properties: L{buildbot.process.properties.Properties}
- @returns: (buildset ID, buildrequest IDs) via Deferred
- """
- # Define setid for this set of changed repositories
- setid = yield self.master.db.sourcestampsets.addSourceStampSet()
-
- # add a sourcestamp for each codebase
- for codebase, cb_info in self.codebases.iteritems():
- ss_repository = cb_info.get('repository', repository)
- ss_branch = cb_info.get('branch', branch)
- ss_revision = cb_info.get('revision', None)
- yield self.master.db.sourcestamps.addSourceStamp(
- codebase=codebase,
- repository=ss_repository,
- branch=ss_branch,
- revision=ss_revision,
- project=project,
- changeids=set(),
- sourcestampsetid=setid)
-
- bsid,brids = yield self.addBuildsetForSourceStamp(
- setid=setid, reason=reason,
- external_idstring=external_idstring,
- builderNames=builderNames,
- properties=properties)
-
- defer.returnValue((bsid,brids))
-
-
- @defer.inlineCallbacks
- def addBuildsetForSourceStampDetails(self, reason='', external_idstring=None,
- branch=None, repository='', project='', revision=None,
- builderNames=None, properties=None):
- """
- Given details about the source code to build, create a source stamp and
- then add a buildset for it.
-
- @param reason: reason for this buildset
- @type reason: unicode string
- @param external_idstring: external identifier for this buildset, or None
- @param branch: branch to build (note that None often has a special meaning)
- @param repository: repository name for sourcestamp
- @param project: project name for sourcestamp
- @param revision: revision to build - default is latest
- @param builderNames: builders to name in the buildset (defaults to
- C{self.builderNames})
- @param properties: a properties object containing initial properties for
- the buildset
- @type properties: L{buildbot.process.properties.Properties}
- @returns: (buildset ID, buildrequest IDs) via Deferred
- """
- # Define setid for this set of changed repositories
- setid = yield self.master.db.sourcestampsets.addSourceStampSet()
-
- yield self.master.db.sourcestamps.addSourceStamp(
- branch=branch, revision=revision, repository=repository,
- project=project, sourcestampsetid=setid)
-
- rv = yield self.addBuildsetForSourceStamp(
- setid=setid, reason=reason,
- external_idstring=external_idstring,
- builderNames=builderNames,
- properties=properties)
- defer.returnValue(rv)
-
-
- @defer.inlineCallbacks
- def addBuildsetForSourceStampSetDetails(self, reason, sourcestamps,
- properties, builderNames=None):
- if sourcestamps is None:
- sourcestamps = {}
-
- # Define new setid for this set of sourcestamps
- new_setid = yield self.master.db.sourcestampsets.addSourceStampSet()
-
- # Merge codebases with the passed list of sourcestamps
- # This results in a new sourcestamp for each codebase
- for codebase in self.codebases:
- ss = self.codebases[codebase].copy()
- # apply info from passed sourcestamps onto the configured default
- # sourcestamp attributes for this codebase.
- ss.update(sourcestamps.get(codebase,{}))
-
- # add sourcestamp to the new setid
- yield self.master.db.sourcestamps.addSourceStamp(
- codebase=codebase,
- repository=ss.get('repository', ''),
- branch=ss.get('branch', None),
- revision=ss.get('revision', None),
- project=ss.get('project', ''),
- changeids=[c['number'] for c in ss.get('changes', [])],
- patch_body=ss.get('patch_body', None),
- patch_level=ss.get('patch_level', None),
- patch_author=ss.get('patch_author', None),
- patch_comment=ss.get('patch_comment', None),
- sourcestampsetid=new_setid)
-
- rv = yield self.addBuildsetForSourceStamp(
- setid=new_setid, reason=reason,
- properties=properties,
- builderNames=builderNames)
-
- defer.returnValue(rv)
-
-
- @defer.inlineCallbacks
- def addBuildsetForChanges(self, reason='', external_idstring=None,
- changeids=[], builderNames=None, properties=None):
- changesByCodebase = {}
-
- def get_last_change_for_codebase(codebase):
- return max(changesByCodebase[codebase],key = lambda change: change["changeid"])
-
- # Define setid for this set of changed repositories
- setid = yield self.master.db.sourcestampsets.addSourceStampSet()
-
- # Changes are retrieved from database and grouped by their codebase
- for changeid in changeids:
- chdict = yield self.master.db.changes.getChange(changeid)
- # group change by codebase
- changesByCodebase.setdefault(chdict["codebase"], []).append(chdict)
-
- for codebase in self.codebases:
- args = {'codebase': codebase, 'sourcestampsetid': setid }
- if codebase not in changesByCodebase:
- # codebase has no changes
- # create a sourcestamp that has no changes
- args['repository'] = self.codebases[codebase]['repository']
- args['branch'] = self.codebases[codebase].get('branch', None)
- args['revision'] = self.codebases[codebase].get('revision', None)
- args['changeids'] = set()
- args['project'] = ''
- else:
- #codebase has changes
- args['changeids'] = [c["changeid"] for c in changesByCodebase[codebase]]
- lastChange = get_last_change_for_codebase(codebase)
- for key in ['repository', 'branch', 'revision', 'project']:
- args[key] = lastChange[key]
-
- yield self.master.db.sourcestamps.addSourceStamp(**args)
-
- # add one buildset, this buildset is connected to the sourcestamps by the setid
- bsid,brids = yield self.addBuildsetForSourceStamp( setid=setid,
- reason=reason, external_idstring=external_idstring,
- builderNames=builderNames, properties=properties)
-
- defer.returnValue((bsid,brids))
-
- @defer.inlineCallbacks
- def addBuildsetForSourceStamp(self, ssid=None, setid=None, reason='', external_idstring=None,
- properties=None, builderNames=None):
- """
- Add a buildset for the given, already-existing sourcestamp.
-
- This method will add any properties provided to the scheduler
- constructor to the buildset, and will call the master's
- L{BuildMaster.addBuildset} method with the appropriate parameters, and
- return the same result.
-
- @param reason: reason for this buildset
- @type reason: unicode string
- @param external_idstring: external identifier for this buildset, or None
- @param properties: a properties object containing initial properties for
- the buildset
- @type properties: L{buildbot.process.properties.Properties}
- @param builderNames: builders to name in the buildset (defaults to
- C{self.builderNames})
- @param setid: idenitification of a set of sourcestamps
- @returns: (buildset ID, buildrequest IDs) via Deferred
- """
- assert (ssid is None and setid is not None) \
- or (ssid is not None and setid is None), "pass a single sourcestamp OR set not both"
-
- # combine properties
- if properties:
- properties.updateFromProperties(self.properties)
- else:
- properties = self.properties
-
- # apply the default builderNames
- if not builderNames:
- builderNames = self.builderNames
-
- # translate properties object into a dict as required by the
- # addBuildset method
- properties_dict = properties.asDict()
-
- if setid == None:
- if ssid is not None:
- ssdict = yield self.master.db.sourcestamps.getSourceStamp(ssid)
- setid = ssdict['sourcestampsetid']
- else:
- # no sourcestamp and no sets
- yield None
-
- rv = yield self.master.addBuildset(sourcestampsetid=setid,
- reason=reason, properties=properties_dict,
- builderNames=builderNames,
- external_idstring=external_idstring)
- defer.returnValue(rv)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/basic.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/basic.py
deleted file mode 100644
index a2b9f19c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/basic.py
+++ /dev/null
@@ -1,256 +0,0 @@
-# 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
-
-from twisted.internet import defer, reactor
-from twisted.python import log
-from buildbot import util, config
-from buildbot.util import NotABranch
-from collections import defaultdict
-from buildbot.changes import filter, changes
-from buildbot.schedulers import base, dependent
-
-class BaseBasicScheduler(base.BaseScheduler):
- """
- @param onlyImportant: If True, only important changes will be added to the
- buildset.
- @type onlyImportant: boolean
-
- """
-
- compare_attrs = (base.BaseScheduler.compare_attrs +
- ('treeStableTimer', 'change_filter', 'fileIsImportant',
- 'onlyImportant') )
-
- _reactor = reactor # for tests
-
- fileIsImportant = None
-
- class NotSet: pass
- def __init__(self, name, shouldntBeSet=NotSet, treeStableTimer=None,
- builderNames=None, branch=NotABranch, branches=NotABranch,
- fileIsImportant=None, properties={}, categories=None,
- change_filter=None, onlyImportant=False, **kwargs):
- if shouldntBeSet is not self.NotSet:
- config.error(
- "pass arguments to schedulers using keyword arguments")
- if fileIsImportant and not callable(fileIsImportant):
- config.error(
- "fileIsImportant must be a callable")
-
- # initialize parent classes
- base.BaseScheduler.__init__(self, name, builderNames, properties, **kwargs)
-
- self.treeStableTimer = treeStableTimer
- if fileIsImportant is not None:
- self.fileIsImportant = fileIsImportant
- self.onlyImportant = onlyImportant
- self.change_filter = self.getChangeFilter(branch=branch,
- branches=branches, change_filter=change_filter,
- categories=categories)
-
- # the IDelayedCall used to wake up when this scheduler's
- # treeStableTimer expires.
- self._stable_timers = defaultdict(lambda : None)
- self._stable_timers_lock = defer.DeferredLock()
-
- def getChangeFilter(self, branch, branches, change_filter, categories):
- raise NotImplementedError
-
- def startService(self, _returnDeferred=False):
- base.BaseScheduler.startService(self)
-
- d = self.startConsumingChanges(fileIsImportant=self.fileIsImportant,
- change_filter=self.change_filter,
- onlyImportant=self.onlyImportant)
-
- # if treeStableTimer is False, then we don't care about classified
- # changes, so get rid of any hanging around from previous
- # configurations
- if not self.treeStableTimer:
- d.addCallback(lambda _ :
- self.master.db.schedulers.flushChangeClassifications(
- self.objectid))
-
- # otherwise, if there are classified changes out there, start their
- # treeStableTimers again
- else:
- d.addCallback(lambda _ :
- self.scanExistingClassifiedChanges())
-
- # handle Deferred errors, since startService does not return a Deferred
- d.addErrback(log.err, "while starting SingleBranchScheduler '%s'"
- % self.name)
-
- if _returnDeferred:
- return d # only used in tests
-
- def stopService(self):
- # the base stopService will unsubscribe from new changes
- d = base.BaseScheduler.stopService(self)
- @util.deferredLocked(self._stable_timers_lock)
- def cancel_timers(_):
- for timer in self._stable_timers.values():
- if timer:
- timer.cancel()
- self._stable_timers.clear()
- d.addCallback(cancel_timers)
- return d
-
- @util.deferredLocked('_stable_timers_lock')
- def gotChange(self, change, important):
- if not self.treeStableTimer:
- # if there's no treeStableTimer, we can completely ignore
- # unimportant changes
- if not important:
- return defer.succeed(None)
- # otherwise, we'll build it right away
- return self.addBuildsetForChanges(reason='scheduler',
- changeids=[ change.number ])
-
- timer_name = self.getTimerNameForChange(change)
-
- # if we have a treeStableTimer, then record the change's importance
- # and:
- # - for an important change, start the timer
- # - for an unimportant change, reset the timer if it is running
- d = self.master.db.schedulers.classifyChanges(
- self.objectid, { change.number : important })
- def fix_timer(_):
- if not important and not self._stable_timers[timer_name]:
- return
- if self._stable_timers[timer_name]:
- self._stable_timers[timer_name].cancel()
- def fire_timer():
- d = self.stableTimerFired(timer_name)
- d.addErrback(log.err, "while firing stable timer")
- self._stable_timers[timer_name] = self._reactor.callLater(
- self.treeStableTimer, fire_timer)
- d.addCallback(fix_timer)
- return d
-
- @defer.inlineCallbacks
- def scanExistingClassifiedChanges(self):
- # call gotChange for each classified change. This is called at startup
- # and is intended to re-start the treeStableTimer for any changes that
- # had not yet been built when the scheduler was stopped.
-
- # NOTE: this may double-call gotChange for changes that arrive just as
- # the scheduler starts up. In practice, this doesn't hurt anything.
- classifications = \
- yield self.master.db.schedulers.getChangeClassifications(
- self.objectid)
-
- # call gotChange for each change, after first fetching it from the db
- for changeid, important in classifications.iteritems():
- chdict = yield self.master.db.changes.getChange(changeid)
-
- if not chdict:
- continue
-
- change = yield changes.Change.fromChdict(self.master, chdict)
- yield self.gotChange(change, important)
-
- def getTimerNameForChange(self, change):
- raise NotImplementedError # see subclasses
-
- def getChangeClassificationsForTimer(self, objectid, timer_name):
- """similar to db.schedulers.getChangeClassifications, but given timer
- name"""
- raise NotImplementedError # see subclasses
-
- @util.deferredLocked('_stable_timers_lock')
- @defer.inlineCallbacks
- def stableTimerFired(self, timer_name):
- # if the service has already been stoppd then just bail out
- if not self._stable_timers[timer_name]:
- return
-
- # delete this now-fired timer
- del self._stable_timers[timer_name]
-
- classifications = \
- yield self.getChangeClassificationsForTimer(self.objectid,
- timer_name)
-
- # just in case: databases do weird things sometimes!
- if not classifications: # pragma: no cover
- return
-
- changeids = sorted(classifications.keys())
- yield self.addBuildsetForChanges(reason='scheduler',
- changeids=changeids)
-
- max_changeid = changeids[-1] # (changeids are sorted)
- yield self.master.db.schedulers.flushChangeClassifications(
- self.objectid, less_than=max_changeid+1)
-
- def getPendingBuildTimes(self):
- # This isn't locked, since the caller expects and immediate value,
- # and in any case, this is only an estimate.
- return [timer.getTime() for timer in self._stable_timers.values() if timer and timer.active()]
-
-class SingleBranchScheduler(BaseBasicScheduler):
- def getChangeFilter(self, branch, branches, change_filter, categories):
- if branch is NotABranch and not change_filter:
- config.error(
- "the 'branch' argument to SingleBranchScheduler is " +
- "mandatory unless change_filter is provided")
- elif branches is not NotABranch:
- config.error(
- "the 'branches' argument is not allowed for " +
- "SingleBranchScheduler")
-
-
- return filter.ChangeFilter.fromSchedulerConstructorArgs(
- change_filter=change_filter, branch=branch,
- categories=categories)
-
- def getTimerNameForChange(self, change):
- return "only" # this class only uses one timer
-
- def getChangeClassificationsForTimer(self, objectid, timer_name):
- return self.master.db.schedulers.getChangeClassifications(
- self.objectid)
-
-
-class Scheduler(SingleBranchScheduler):
- "alias for SingleBranchScheduler"
- def __init__(self, *args, **kwargs):
- log.msg("WARNING: the name 'Scheduler' is deprecated; use " +
- "buildbot.schedulers.basic.SingleBranchScheduler instead " +
- "(note that this may require you to change your import " +
- "statement)")
- SingleBranchScheduler.__init__(self, *args, **kwargs)
-
-
-class AnyBranchScheduler(BaseBasicScheduler):
- def getChangeFilter(self, branch, branches, change_filter, categories):
- assert branch is NotABranch
- return filter.ChangeFilter.fromSchedulerConstructorArgs(
- change_filter=change_filter, branch=branches,
- categories=categories)
-
- def getTimerNameForChange(self, change):
- # Py2.6+: could be a namedtuple
- return (change.codebase, change.project, change.repository, change.branch)
-
- def getChangeClassificationsForTimer(self, objectid, timer_name):
- codebase, project, repository, branch = timer_name # set in getTimerNameForChange
- return self.master.db.schedulers.getChangeClassifications(
- self.objectid, branch=branch, repository=repository,
- codebase=codebase, project=project)
-
-# now at buildbot.schedulers.dependent, but keep the old name alive
-Dependent = dependent.Dependent
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/dependent.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/dependent.py
deleted file mode 100644
index f28df579..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/dependent.py
+++ /dev/null
@@ -1,148 +0,0 @@
-# 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
-
-from twisted.internet import defer
-from twisted.python import log
-from buildbot import util, interfaces, config
-from buildbot.status.results import SUCCESS, WARNINGS
-from buildbot.schedulers import base
-
-class Dependent(base.BaseScheduler):
-
- compare_attrs = base.BaseScheduler.compare_attrs + ('upstream_name',)
-
- def __init__(self, name, upstream, builderNames, properties={}, **kwargs):
- base.BaseScheduler.__init__(self, name, builderNames, properties,
- **kwargs)
- if not interfaces.IScheduler.providedBy(upstream):
- config.error(
- "upstream must be another Scheduler instance")
- self.upstream_name = upstream.name
- self._buildset_addition_subscr = None
- self._buildset_completion_subscr = None
- self._cached_upstream_bsids = None
-
- # the subscription lock makes sure that we're done inserting a
- # subcription into the DB before registering that the buildset is
- # complete.
- self._subscription_lock = defer.DeferredLock()
-
- def startService(self):
- self._buildset_addition_subscr = \
- self.master.subscribeToBuildsets(self._buildsetAdded)
- self._buildset_completion_subscr = \
- self.master.subscribeToBuildsetCompletions(self._buildsetCompleted)
-
- # check for any buildsets completed before we started
- d = self._checkCompletedBuildsets(None, None)
- d.addErrback(log.err, 'while checking for completed buildsets in start')
-
- def stopService(self):
- if self._buildset_addition_subscr:
- self._buildset_addition_subscr.unsubscribe()
- if self._buildset_completion_subscr:
- self._buildset_completion_subscr.unsubscribe()
- self._cached_upstream_bsids = None
- return defer.succeed(None)
-
- @util.deferredLocked('_subscription_lock')
- def _buildsetAdded(self, bsid=None, properties=None, **kwargs):
- # check if this was submitetted by our upstream by checking the
- # scheduler property
- submitter = properties.get('scheduler', (None, None))[0]
- if submitter != self.upstream_name:
- return
-
- # record our interest in this buildset
- d = self._addUpstreamBuildset(bsid)
- d.addErrback(log.err, 'while subscribing to buildset %d' % bsid)
-
- def _buildsetCompleted(self, bsid, result):
- d = self._checkCompletedBuildsets(bsid, result)
- d.addErrback(log.err, 'while checking for completed buildsets')
-
- @util.deferredLocked('_subscription_lock')
- @defer.inlineCallbacks
- def _checkCompletedBuildsets(self, bsid, result):
- subs = yield self._getUpstreamBuildsets()
-
- sub_bsids = []
- for (sub_bsid, sub_sssetid, sub_complete, sub_results) in subs:
- # skip incomplete builds, handling the case where the 'complete'
- # column has not been updated yet
- if not sub_complete and sub_bsid != bsid:
- continue
-
- # build a dependent build if the status is appropriate
- if sub_results in (SUCCESS, WARNINGS):
- yield self.addBuildsetForSourceStamp(setid=sub_sssetid,
- reason='downstream')
-
- sub_bsids.append(sub_bsid)
-
- # and regardless of status, remove the subscriptions
- yield self._removeUpstreamBuildsets(sub_bsids)
-
- @defer.inlineCallbacks
- def _updateCachedUpstreamBuilds(self):
- if self._cached_upstream_bsids is None:
- bsids = yield self.master.db.state.getState(self.objectid,
- 'upstream_bsids', [])
- self._cached_upstream_bsids = bsids
-
- @defer.inlineCallbacks
- def _getUpstreamBuildsets(self):
- # get a list of (bsid, sssid, complete, results) for all
- # upstream buildsets
- yield self._updateCachedUpstreamBuilds()
-
- changed = False
- rv = []
- for bsid in self._cached_upstream_bsids[:]:
- bsdict = yield self.master.db.buildsets.getBuildset(bsid)
- if not bsdict:
- self._cached_upstream_bsids.remove(bsid)
- changed = True
- continue
-
- rv.append((bsid, bsdict['sourcestampsetid'], bsdict['complete'],
- bsdict['results']))
-
- if changed:
- yield self.master.db.state.setState(self.objectid,
- 'upstream_bsids', self._cached_upstream_bsids)
-
- defer.returnValue(rv)
-
- @defer.inlineCallbacks
- def _addUpstreamBuildset(self, bsid):
- yield self._updateCachedUpstreamBuilds()
-
- if bsid not in self._cached_upstream_bsids:
- self._cached_upstream_bsids.append(bsid)
-
- yield self.master.db.state.setState(self.objectid,
- 'upstream_bsids', self._cached_upstream_bsids)
-
- @defer.inlineCallbacks
- def _removeUpstreamBuildsets(self, bsids):
- yield self._updateCachedUpstreamBuilds()
-
- old = set(self._cached_upstream_bsids)
- self._cached_upstream_bsids = list(old - set(bsids))
-
- yield self.master.db.state.setState(self.objectid,
- 'upstream_bsids', self._cached_upstream_bsids)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/filter.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/filter.py
deleted file mode 100644
index c06e2315..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/filter.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# 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
-
-# old (pre-0.8.4) location for ChangeFilter
-from buildbot.changes.filter import ChangeFilter
-_hush_pyflakes = ChangeFilter # keep pyflakes happy
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/forcesched.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/forcesched.py
deleted file mode 100644
index 90ff950f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/forcesched.py
+++ /dev/null
@@ -1,666 +0,0 @@
-# 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 traceback
-import re
-from twisted.internet import defer
-import email.utils as email_utils
-
-from buildbot.process.properties import Properties
-from buildbot.schedulers import base
-from buildbot import config
-
-class ValidationError(ValueError):
- pass
-
-DefaultField = object() # sentinel object to signal default behavior
-
-class BaseParameter(object):
- """
- BaseParameter provides a base implementation for property customization
- """
- name = ""
- parentName = None
- label = ""
- type = []
- default = ""
- required = False
- multiple = False
- regex = None
- debug=True
- hide = False
-
- @property
- def fullName(self):
- """A full name, intended to uniquely identify a parameter"""
- # join with '_' if both are set
- if self.parentName and self.name:
- return self.parentName+'_'+self.name
- # otherwise just use the one that is set
- # (this allows empty name for "anonymous nests")
- return self.name or self.parentName
-
- def setParent(self, parent):
- self.parentName = parent.fullName if parent else None
-
- def __init__(self, name, label=None, regex=None, **kw):
- """
- @param name: the name of the field, used during posting values
- back to the scheduler. This is not necessarily a UI value,
- and there may be restrictions on the characters allowed for
- this value. For example, HTML would require this field to
- avoid spaces and other punctuation ('-', '.', and '_' allowed)
- @type name: unicode
-
- @param label: (optional) the name of the field, used for UI display.
- @type label: unicode or None (to use 'name')
-
- @param regex: (optional) regex to validate the value with. Not used by
- all subclasses
- @type regex: unicode or regex
- """
-
- self.name = name
- self.label = name if label is None else label
- if regex:
- self.regex = re.compile(regex)
- # all other properties are generically passed via **kw
- self.__dict__.update(kw)
-
- def getFromKwargs(self, kwargs):
- """Simple customization point for child classes that do not need the other
- parameters supplied to updateFromKwargs. Return the value for the property
- named 'self.name'.
-
- The default implementation converts from a list of items, validates using
- the optional regex field and calls 'parse_from_args' for the final conversion.
- """
- args = kwargs.get(self.fullName, [])
- if len(args) == 0:
- if self.required:
- raise ValidationError("'%s' needs to be specified" % (self.label))
- if self.multiple:
- args = self.default
- else:
- args = [self.default]
-
- if self.regex:
- for arg in args:
- if not self.regex.match(arg):
- raise ValidationError("%s:'%s' does not match pattern '%s'"
- % (self.label, arg, self.regex.pattern))
-
- try:
- arg = self.parse_from_args(args)
- except Exception, e:
- # an exception will just display an alert in the web UI
- # also log the exception
- if self.debug:
- traceback.print_exc()
- raise e
- if arg is None:
- raise ValidationError("need %s: no default provided by config"
- % (self.fullName,))
- return arg
-
- def updateFromKwargs(self, properties, kwargs, **unused):
- """Primary entry point to turn 'kwargs' into 'properties'"""
- properties[self.name] = self.getFromKwargs(kwargs)
-
- def parse_from_args(self, l):
- """Secondary customization point, called from getFromKwargs to turn
- a validated value into a single property value"""
- if self.multiple:
- return map(self.parse_from_arg, l)
- else:
- return self.parse_from_arg(l[0])
-
- def parse_from_arg(self, s):
- return s
-
-
-class FixedParameter(BaseParameter):
- """A fixed parameter that cannot be modified by the user."""
- type = ["fixed"]
- hide = True
- default = ""
-
- def parse_from_args(self, l):
- return self.default
-
-
-class StringParameter(BaseParameter):
- """A simple string parameter"""
- type = ["text"]
- size = 10
-
- def parse_from_arg(self, s):
- return s
-
-
-class TextParameter(StringParameter):
- """A generic string parameter that may span multiple lines"""
- type = ["textarea"]
- cols = 80
- rows = 20
-
- def value_to_text(self, value):
- return str(value)
-
-
-class IntParameter(StringParameter):
- """An integer parameter"""
- type = ["int"]
-
- parse_from_arg = int # will throw an exception if parse fail
-
-
-class BooleanParameter(BaseParameter):
- """A boolean parameter"""
- type = ["bool"]
-
- def getFromKwargs(self, kwargs):
- return kwargs.get(self.fullName, None) == [True]
-
-
-class UserNameParameter(StringParameter):
- """A username parameter to supply the 'owner' of a build"""
- type = ["text"]
- default = ""
- size = 30
- need_email = True
-
- def __init__(self, name="username", label="Your name:", **kw):
- BaseParameter.__init__(self, name, label, **kw)
-
- def parse_from_arg(self, s):
- if not s and not self.required:
- return s
- if self.need_email:
- e = email_utils.parseaddr(s)
- if e[0]=='' or e[1] == '':
- raise ValidationError("%s: please fill in email address in the "
- "form 'User <email@email.com>'" % (self.name,))
- return s
-
-
-class ChoiceStringParameter(BaseParameter):
- """A list of strings, allowing the selection of one of the predefined values.
- The 'strict' parameter controls whether values outside the predefined list
- of choices are allowed"""
- type = ["list"]
- choices = []
- strict = True
-
- def parse_from_arg(self, s):
- if self.strict and not s in self.choices:
- raise ValidationError("'%s' does not belongs to list of available choices '%s'"%(s, self.choices))
- return s
-
- def getChoices(self, master, scheduler, buildername):
- return self.choices
-
-class InheritBuildParameter(ChoiceStringParameter):
- """A parameter that takes its values from another build"""
- type = ChoiceStringParameter.type + ["inherit"]
- name = "inherit"
- compatible_builds = None
-
- def getChoices(self, master, scheduler, buildername):
- return self.compatible_builds(master.status, buildername)
-
- def getFromKwargs(self, kwargs):
- raise ValidationError("InheritBuildParameter can only be used by properties")
-
- def updateFromKwargs(self, master, properties, changes, kwargs, **unused):
- arg = kwargs.get(self.fullName, [""])[0]
- splitted_arg = arg.split(" ")[0].split("/")
- if len(splitted_arg) != 2:
- raise ValidationError("bad build: %s"%(arg))
- builder, num = splitted_arg
- builder_status = master.status.getBuilder(builder)
- if not builder_status:
- raise ValidationError("unknown builder: %s in %s"%(builder, arg))
- b = builder_status.getBuild(int(num))
- if not b:
- raise ValidationError("unknown build: %d in %s"%(num, arg))
- props = {self.name:(arg.split(" ")[0])}
- for name, value, source in b.getProperties().asList():
- if source == "Force Build Form":
- if name == "owner":
- name = "orig_owner"
- props[name] = value
- properties.update(props)
- changes.extend(b.changes)
-
-
-class BuildslaveChoiceParameter(ChoiceStringParameter):
- """A parameter that lets the buildslave name be explicitly chosen.
-
- This parameter works in conjunction with 'buildbot.process.builder.enforceChosenSlave',
- which should be added as the 'canStartBuild' parameter to the Builder.
-
- The "anySentinel" parameter represents the sentinel value to specify that
- there is no buildslave preference.
- """
- anySentinel = '-any-'
- label = 'Build slave'
- required = False
- strict = False
-
- def __init__(self, name='slavename', **kwargs):
- ChoiceStringParameter.__init__(self, name, **kwargs)
-
- def updateFromKwargs(self, kwargs, **unused):
- slavename = self.getFromKwargs(kwargs)
- if slavename==self.anySentinel:
- # no preference, so dont set a parameter at all
- return
- ChoiceStringParameter.updateFromKwargs(self, kwargs=kwargs, **unused)
-
- def getChoices(self, master, scheduler, buildername):
- if buildername is None:
- # this is the "Force All Builds" page
- slavenames = master.status.getSlaveNames()
- else:
- builderStatus = master.status.getBuilder(buildername)
- slavenames = [slave.getName() for slave in builderStatus.getSlaves()]
- slavenames.sort()
- slavenames.insert(0, self.anySentinel)
- return slavenames
-
-
-class NestedParameter(BaseParameter):
- """A 'parent' parameter for a set of related parameters. This provices a
- logical grouping for the child parameters.
-
- Typically, the 'fullName' of the child parameters mix in the parent's
- 'fullName'. This allows for a field to appear multiple times in a form
- (for example, two codebases each have a 'branch' field).
-
- If the 'name' of the parent is the empty string, then the parent's name
- does not mix in with the child 'fullName'. This is useful when a field
- will not appear multiple time in a scheduler but the logical grouping is
- helpful.
-
- The result of a NestedParameter is typically a dictionary, with the key/value
- being the name/value of the children.
- """
- type = ['nested']
- fields = None
-
- def __init__(self, name, fields, **kwargs):
- BaseParameter.__init__(self, fields=fields, name=name, **kwargs)
-
- # fix up the child nodes with the parent (use None for now):
- self.setParent(None)
-
- def setParent(self, parent):
- BaseParameter.setParent(self, parent)
- for field in self.fields:
- field.setParent(self)
-
- def collectChildProperties(self, kwargs, properties, **kw):
- """Collapse the child values into a dictionary. This is intended to be
- called by child classes to fix up the fullName->name conversions."""
-
- childProperties = {}
- for field in self.fields:
- field.updateFromKwargs(kwargs=kwargs,
- properties=childProperties,
- **kw)
-
- kwargs[self.fullName] = childProperties
-
- def updateFromKwargs(self, kwargs, properties, **kw):
- """By default, the child values will be collapsed into a dictionary. If
- the parent is anonymous, this dictionary is the top-level properties."""
- self.collectChildProperties(kwargs=kwargs, properties=properties, **kw)
-
- # default behavior is to set a property
- # -- use setdefault+update in order to collapse 'anonymous' nested
- # parameters correctly
- if self.name:
- d = properties.setdefault(self.name, {})
- else:
- # if there's no name, collapse this nest all the way
- d = properties
- d.update(kwargs[self.fullName])
-
-class AnyPropertyParameter(NestedParameter):
- """A generic property parameter, where both the name and value of the property
- must be given."""
- type = NestedParameter.type + ["any"]
-
- def __init__(self, name, **kw):
- fields = [
- StringParameter(name='name', label="Name:"),
- StringParameter(name='value', label="Value:"),
- ]
- NestedParameter.__init__(self, name, label='', fields=fields, **kw)
-
- def getFromKwargs(self, kwargs):
- raise ValidationError("AnyPropertyParameter can only be used by properties")
-
- def updateFromKwargs(self, master, properties, kwargs, **kw):
- self.collectChildProperties(master=master,
- properties=properties,
- kwargs=kwargs,
- **kw)
-
- pname = kwargs[self.fullName].get("name", "")
- pvalue = kwargs[self.fullName].get("value", "")
- if not pname:
- return
-
- validation = master.config.validation
- pname_validate = validation['property_name']
- pval_validate = validation['property_value']
-
- if not pname_validate.match(pname) \
- or not pval_validate.match(pvalue):
- raise ValidationError("bad property name='%s', value='%s'" % (pname, pvalue))
- properties[pname] = pvalue
-
-
-class CodebaseParameter(NestedParameter):
- """A parameter whose result is a codebase specification instead of a property"""
- type = NestedParameter.type + ["codebase"]
- codebase = ''
-
- def __init__(self,
- codebase,
- name=None,
- label=None,
-
- branch=DefaultField,
- revision=DefaultField,
- repository=DefaultField,
- project=DefaultField,
-
- **kwargs):
- """
- A set of properties that will be used to generate a codebase dictionary.
-
- The branch/revision/repository/project should each be a parameter that
- will map to the corresponding value in the sourcestamp. Use None to disable
- the field.
-
- @param codebase: name of the codebase; used as key for the sourcestamp set
- @type codebase: unicode
-
- @param name: optional override for the name-currying for the subfields
- @type codebase: unicode
-
- @param label: optional override for the label for this set of parameters
- @type codebase: unicode
- """
-
- name = name or codebase
- if label is None and codebase:
- label = "Codebase: " + codebase
-
- if branch is DefaultField:
- branch = StringParameter(name='branch', label="Branch:")
- if revision is DefaultField:
- revision = StringParameter(name='revision', label="Revision:")
- if repository is DefaultField:
- repository = StringParameter(name='repository', label="Repository:")
- if project is DefaultField:
- project = StringParameter(name='project', label="Project:")
-
- fields = filter(None, [branch, revision, repository, project])
-
- NestedParameter.__init__(self, name=name, label=label,
- codebase=codebase,
- fields=fields, **kwargs)
-
- def createSourcestamp(self, properties, kwargs):
- # default, just return the things we put together
- return kwargs.get(self.fullName, {})
-
- def updateFromKwargs(self, sourcestamps, kwargs, properties, **kw):
- self.collectChildProperties(sourcestamps=sourcestamps,
- properties=properties,
- kwargs=kwargs,
- **kw)
-
- # convert the "property" to a sourcestamp
- ss = self.createSourcestamp(properties, kwargs)
- if ss is not None:
- sourcestamps[self.codebase] = ss
-
-
-class ForceScheduler(base.BaseScheduler):
- """
- ForceScheduler implements the backend for a UI to allow customization of
- builds. For example, a web form be populated to trigger a build.
- """
- compare_attrs = ( 'name', 'builderNames',
- 'reason', 'username',
- 'forcedProperties' )
-
- def __init__(self, name, builderNames,
- username=UserNameParameter(),
- reason=StringParameter(name="reason", default="force build", length=20),
-
- codebases=None,
-
- properties=[
- NestedParameter(name='', fields=[
- AnyPropertyParameter("property1"),
- AnyPropertyParameter("property2"),
- AnyPropertyParameter("property3"),
- AnyPropertyParameter("property4"),
- ])
- ],
-
- # deprecated; use 'codebase' instead
- branch=None,
- revision=None,
- repository=None,
- project=None
- ):
- """
- Initialize a ForceScheduler.
-
- The UI will provide a set of fields to the user; these fields are
- driven by a corresponding child class of BaseParameter.
-
- Use NestedParameter to provide logical groupings for parameters.
-
- The branch/revision/repository/project fields are deprecated and
- provided only for backwards compatibility. Using a Codebase(name='')
- will give the equivalent behavior.
-
- @param name: name of this scheduler (used as a key for state)
- @type name: unicode
-
- @param builderNames: list of builders this scheduler may start
- @type builderNames: list of unicode
-
- @param username: the "owner" for a build (may not be shown depending
- on the Auth configuration for the master)
- @type username: BaseParameter
-
- @param reason: the "reason" for a build
- @type reason: BaseParameter
-
- @param codebases: the codebases for a build
- @type codebases: list of string's or CodebaseParameter's;
- None will generate a default, but [] will
- remove all codebases
-
- @param properties: extra properties to configure the build
- @type properties: list of BaseParameter's
- """
-
- if not self.checkIfType(name, str):
- config.error("ForceScheduler name must be a unicode string: %r" %
- name)
-
- if not name:
- config.error("ForceScheduler name must not be empty: %r " %
- name)
-
- if not self.checkIfListOfType(builderNames, str):
- config.error("ForceScheduler builderNames must be a list of strings: %r" %
- builderNames)
-
- if self.checkIfType(reason, BaseParameter):
- self.reason = reason
- else:
- config.error("ForceScheduler reason must be a StringParameter: %r" %
- reason)
-
- if not self.checkIfListOfType(properties, BaseParameter):
- config.error("ForceScheduler properties must be a list of BaseParameters: %r" %
- properties)
-
- if self.checkIfType(username, BaseParameter):
- self.username = username
- else:
- config.error("ForceScheduler username must be a StringParameter: %r" %
- username)
-
- self.forcedProperties = []
-
- if any((branch, revision, repository, project)):
- if codebases:
- config.error("ForceScheduler: Must either specify 'codebases' or the 'branch/revision/repository/project' parameters: %r " % (codebases,))
-
- codebases = [
- CodebaseParameter(codebase='',
- branch=branch or DefaultField,
- revision=revision or DefaultField,
- repository=repository or DefaultField,
- project=project or DefaultField,
- )
- ]
-
- # Use the default single codebase form if none are provided
- if codebases is None:
- codebases =[CodebaseParameter(codebase='')]
- elif not codebases:
- config.error("ForceScheduler: 'codebases' cannot be empty; use CodebaseParameter(codebase='', hide=True) if needed: %r " % (codebases,))
-
- codebase_dict = {}
- for codebase in codebases:
- if isinstance(codebase, basestring):
- codebase = CodebaseParameter(codebase=codebase)
- elif not isinstance(codebase, CodebaseParameter):
- config.error("ForceScheduler: 'codebases' must be a list of strings or CodebaseParameter objects: %r" % (codebases,))
-
- self.forcedProperties.append(codebase)
- codebase_dict[codebase.codebase] = dict(branch='',repository='',revision='')
-
- base.BaseScheduler.__init__(self,
- name=name,
- builderNames=builderNames,
- properties={},
- codebases=codebase_dict)
-
- if properties:
- self.forcedProperties.extend(properties)
-
- # this is used to simplify the template
- self.all_fields = [ NestedParameter(name='', fields=[username, reason]) ]
- self.all_fields.extend(self.forcedProperties)
-
- def checkIfType(self, obj, chkType):
- return isinstance(obj, chkType)
-
- def checkIfListOfType(self, obj, chkType):
- isListOfType = True
-
- if self.checkIfType(obj, list):
- for item in obj:
- if not self.checkIfType(item, chkType):
- isListOfType = False
- break
- else:
- isListOfType = False
-
- return isListOfType
-
- def startService(self):
- pass
-
- def stopService(self):
- pass
-
- @defer.inlineCallbacks
- def gatherPropertiesAndChanges(self, **kwargs):
- properties = {}
- changeids = []
- sourcestamps = {}
-
- for param in self.forcedProperties:
- yield defer.maybeDeferred(param.updateFromKwargs,
- master=self.master,
- properties=properties,
- changes=changeids,
- sourcestamps=sourcestamps,
- kwargs=kwargs)
-
- changeids = map(lambda a: type(a)==int and a or a.number, changeids)
-
- real_properties = Properties()
- for pname, pvalue in properties.items():
- real_properties.setProperty(pname, pvalue, "Force Build Form")
-
- defer.returnValue((real_properties, changeids, sourcestamps))
-
- @defer.inlineCallbacks
- def force(self, owner, builderNames=None, **kwargs):
- """
- We check the parameters, and launch the build, if everything is correct
- """
- if builderNames is None:
- builderNames = self.builderNames
- else:
- builderNames = set(builderNames).intersection(self.builderNames)
-
- if not builderNames:
- defer.returnValue(None)
- return
-
- # Currently the validation code expects all kwargs to be lists
- # I don't want to refactor that now so much sure we comply...
- kwargs = dict((k, [v]) if not isinstance(v, list) else (k,v) for k,v in kwargs.items())
-
- # probably need to clean that out later as the IProperty is already a
- # validation mechanism
-
- reason = self.reason.getFromKwargs(kwargs)
- if owner is None:
- owner = self.username.getFromKwargs(kwargs)
-
- properties, changeids, sourcestamps = yield self.gatherPropertiesAndChanges(**kwargs)
-
- properties.setProperty("reason", reason, "Force Build Form")
- properties.setProperty("owner", owner, "Force Build Form")
-
- r = ("A build was forced by '%s': %s" % (owner, reason))
-
- # everything is validated, we can create our source stamp, and buildrequest
- res = yield self.addBuildsetForSourceStampSetDetails(
- reason = r,
- sourcestamps = sourcestamps,
- properties = properties,
- builderNames = builderNames,
- )
-
- defer.returnValue(res)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/manager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/manager.py
deleted file mode 100644
index d4c8b795..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/manager.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# 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
-
-from twisted.internet import defer
-from twisted.application import service
-from twisted.python import log, reflect
-from buildbot.process import metrics
-from buildbot import config, util
-
-class SchedulerManager(config.ReconfigurableServiceMixin,
- service.MultiService):
- def __init__(self, master):
- service.MultiService.__init__(self)
- self.setName('scheduler_manager')
- self.master = master
-
- @defer.inlineCallbacks
- def reconfigService(self, new_config):
- timer = metrics.Timer("SchedulerManager.reconfigService")
- timer.start()
-
- old_by_name = dict((sch.name, sch) for sch in self)
- old_set = set(old_by_name.iterkeys())
- new_by_name = new_config.schedulers
- new_set = set(new_by_name.iterkeys())
-
- removed_names, added_names = util.diffSets(old_set, new_set)
-
- # find any schedulers that don't know how to reconfig, and, if they
- # have changed, add them to both removed and added, so that we
- # run the new version. While we're at it, find any schedulers whose
- # fully qualified class name has changed, and consider those a removal
- # and re-add as well.
- for n in old_set & new_set:
- old = old_by_name[n]
- new = new_by_name[n]
- # detect changed class name
- if reflect.qual(old.__class__) != reflect.qual(new.__class__):
- removed_names.add(n)
- added_names.add(n)
-
- # compare using ComparableMixin if they don't support reconfig
- elif not hasattr(old, 'reconfigService'):
- if old != new:
- removed_names.add(n)
- added_names.add(n)
-
- # removals first
-
- for sch_name in removed_names:
- log.msg("removing scheduler '%s'" % (sch_name,))
- sch = old_by_name[sch_name]
- yield defer.maybeDeferred(lambda :
- sch.disownServiceParent())
- sch.master = None
-
- # .. then additions
-
- for sch_name in added_names:
- log.msg("adding scheduler '%s'" % (sch_name,))
- sch = new_by_name[sch_name]
-
- # get the scheduler's objectid
- class_name = '%s.%s' % (sch.__class__.__module__,
- sch.__class__.__name__)
- objectid = yield self.master.db.state.getObjectId(
- sch.name, class_name)
-
- # set up the scheduler
- sch.objectid = objectid
- sch.master = self.master
-
- # *then* attacah and start it
- sch.setServiceParent(self)
-
- metrics.MetricCountEvent.log("num_schedulers", len(list(self)),
- absolute=True)
-
- # reconfig any newly-added schedulers, as well as existing
- yield config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
- timer.stop()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/timed.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/timed.py
deleted file mode 100644
index e735ca93..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/timed.py
+++ /dev/null
@@ -1,410 +0,0 @@
-# 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
-
-from zope.interface import implements
-
-from buildbot import util
-from buildbot.interfaces import ITriggerableScheduler
-from buildbot.process import buildstep, properties
-from buildbot.schedulers import base
-from twisted.internet import defer, reactor
-from twisted.python import log
-from buildbot import config
-from buildbot.changes import filter
-# Import croniter if available.
-# This is only required for Nightly schedulers,
-# so fail gracefully if it isn't present.
-try:
- from buildbot.util import croniter
-except ImportError:
- # Pyflakes doesn't like a redefinition here
- # Instead, we check if croniter is defined when we need it
- pass
-
-class Timed(base.BaseScheduler):
- """
- Parent class for timed schedulers. This takes care of the (surprisingly
- subtle) mechanics of ensuring that each timed actuation runs to completion
- before the service stops.
- """
-
- compare_attrs = base.BaseScheduler.compare_attrs
-
- def __init__(self, name, builderNames, properties={}, **kwargs):
- base.BaseScheduler.__init__(self, name, builderNames, properties,
- **kwargs)
-
- # tracking for when to start the next build
- self.lastActuated = None
-
- # A lock to make sure that each actuation occurs without interruption.
- # This lock governs actuateAt, actuateAtTimer, and actuateOk
- self.actuationLock = defer.DeferredLock()
- self.actuateOk = False
- self.actuateAt = None
- self.actuateAtTimer = None
-
- self._reactor = reactor # patched by tests
-
- def startService(self):
- base.BaseScheduler.startService(self)
-
- # no need to lock this; nothing else can run before the service is started
- self.actuateOk = True
-
- # get the scheduler's last_build time (note: only done at startup)
- d = self.getState('last_build', None)
- def set_last(lastActuated):
- self.lastActuated = lastActuated
- d.addCallback(set_last)
-
- # schedule the next build
- d.addCallback(lambda _ : self.scheduleNextBuild())
-
- # give subclasses a chance to start up
- d.addCallback(lambda _ : self.startTimedSchedulerService())
-
- # startService does not return a Deferred, so handle errors with a traceback
- d.addErrback(log.err, "while initializing %s '%s'" %
- (self.__class__.__name__, self.name))
-
- def startTimedSchedulerService(self):
- """Hook for subclasses to participate in the L{startService} process;
- can return a Deferred"""
-
- def stopService(self):
- # shut down any pending actuation, and ensure that we wait for any
- # current actuation to complete by acquiring the lock. This ensures
- # that no build will be scheduled after stopService is complete.
- def stop_actuating():
- self.actuateOk = False
- self.actuateAt = None
- if self.actuateAtTimer:
- self.actuateAtTimer.cancel()
- self.actuateAtTimer = None
- d = self.actuationLock.run(stop_actuating)
-
- # and chain to the parent class
- d.addCallback(lambda _ : base.BaseScheduler.stopService(self))
- return d
-
- ## Scheduler methods
-
- def getPendingBuildTimes(self):
- # take the latest-calculated value of actuateAt as a reasonable
- # estimate
- return [ self.actuateAt ]
-
- ## Timed methods
-
- def startBuild(self):
- """The time has come to start a new build. Returns a Deferred.
- Override in subclasses."""
- raise NotImplementedError
-
- def getNextBuildTime(self, lastActuation):
- """
- Called by to calculate the next time to actuate a BuildSet. Override
- in subclasses. To trigger a fresh call to this method, use
- L{rescheduleNextBuild}.
-
- @param lastActuation: the time of the last actuation, or None for never
-
- @returns: a Deferred firing with the next time a build should occur (in
- the future), or None for never.
- """
- raise NotImplementedError
-
- def scheduleNextBuild(self):
- """
- Schedule the next build, re-invoking L{getNextBuildTime}. This can be
- called at any time, and it will avoid contention with builds being
- started concurrently.
-
- @returns: Deferred
- """
- return self.actuationLock.run(self._scheduleNextBuild_locked)
-
- ## utilities
-
- def now(self):
- "Similar to util.now, but patchable by tests"
- return util.now(self._reactor)
-
- def _scheduleNextBuild_locked(self):
- # clear out the existing timer
- if self.actuateAtTimer:
- self.actuateAtTimer.cancel()
- self.actuateAtTimer = None
-
- # calculate the new time
- d = self.getNextBuildTime(self.lastActuated)
-
- # set up the new timer
- def set_timer(actuateAt):
- now = self.now()
- self.actuateAt = max(actuateAt, now)
- if actuateAt is not None:
- untilNext = self.actuateAt - now
- if untilNext == 0:
- log.msg(("%s: missed scheduled build time, so building "
- "immediately") % self.name)
- self.actuateAtTimer = self._reactor.callLater(untilNext,
- self._actuate)
- d.addCallback(set_timer)
-
- return d
-
- def _actuate(self):
- # called from the timer when it's time to start a build
- self.actuateAtTimer = None
- self.lastActuated = self.actuateAt
-
- @defer.inlineCallbacks
- def set_state_and_start():
- # bail out if we shouldn't be actuating anymore
- if not self.actuateOk:
- return
-
- # mark the last build time
- self.actuateAt = None
- yield self.setState('last_build', self.lastActuated)
-
- # start the build
- yield self.startBuild()
-
- # schedule the next build (noting the lock is already held)
- yield self._scheduleNextBuild_locked()
- d = self.actuationLock.run(set_state_and_start)
-
- # this function can't return a deferred, so handle any failures via
- # log.err
- d.addErrback(log.err, 'while actuating')
-
-
-class Periodic(Timed):
- compare_attrs = Timed.compare_attrs + ('periodicBuildTimer', 'branch',)
-
- def __init__(self, name, builderNames, periodicBuildTimer,
- branch=None, properties={}, onlyImportant=False):
- Timed.__init__(self, name=name, builderNames=builderNames,
- properties=properties)
- if periodicBuildTimer <= 0:
- config.error(
- "periodicBuildTimer must be positive")
- self.periodicBuildTimer = periodicBuildTimer
- self.branch = branch
- self.reason = "The Periodic scheduler named '%s' triggered this build" % self.name
-
- def getNextBuildTime(self, lastActuated):
- if lastActuated is None:
- return defer.succeed(self.now()) # meaning "ASAP"
- else:
- return defer.succeed(lastActuated + self.periodicBuildTimer)
-
- def startBuild(self):
- return self.addBuildsetForLatest(reason=self.reason, branch=self.branch)
-
-class NightlyBase(Timed):
- compare_attrs = (Timed.compare_attrs
- + ('minute', 'hour', 'dayOfMonth', 'month', 'dayOfWeek'))
-
- def __init__(self, name, builderNames, minute=0, hour='*',
- dayOfMonth='*', month='*', dayOfWeek='*',
- properties={}, codebases=base.BaseScheduler.DefaultCodebases):
- Timed.__init__(self, name=name, builderNames=builderNames,
- properties=properties, codebases=codebases)
-
- self.minute = minute
- self.hour = hour
- self.dayOfMonth = dayOfMonth
- self.month = month
- self.dayOfWeek = dayOfWeek
-
- try:
- croniter
- except NameError:
- config.error("python-dateutil required for scheduler %s '%s'." %
- (self.__class__.__name__, self.name))
-
- def _timeToCron(self, time, isDayOfWeek = False):
- if isinstance(time, int):
- if isDayOfWeek:
- time = (time + 1) % 7 # Convert from Mon = 0 format to Sun = 0 format for use in croniter
- return time
-
- if isinstance(time, basestring):
- return time
-
- if isDayOfWeek:
- time = [ (t + 1) % 7 for t in time ] # Conversion for croniter (see above)
-
- return ','.join([ str(s) for s in time ]) # Convert the list to a string
-
- def getNextBuildTime(self, lastActuated):
- dateTime = lastActuated or self.now()
- sched = '%s %s %s %s %s' % (self._timeToCron(self.minute),
- self._timeToCron(self.hour),
- self._timeToCron(self.dayOfMonth),
- self._timeToCron(self.month),
- self._timeToCron(self.dayOfWeek, True))
- cron = croniter.croniter(sched, dateTime)
- nextdate = cron.get_next(float)
- return defer.succeed(nextdate)
-
-class Nightly(NightlyBase):
- compare_attrs = (NightlyBase.compare_attrs
- + ('branch', 'onlyIfChanged', 'fileIsImportant',
- 'change_filter', 'onlyImportant',))
-
- class NoBranch: pass
- def __init__(self, name, builderNames, minute=0, hour='*',
- dayOfMonth='*', month='*', dayOfWeek='*',
- branch=NoBranch, fileIsImportant=None, onlyIfChanged=False,
- properties={}, change_filter=None, onlyImportant=False,
- codebases = base.BaseScheduler.DefaultCodebases):
- NightlyBase.__init__(self, name=name, builderNames=builderNames,
- minute=minute, hour=hour, dayOfWeek=dayOfWeek, dayOfMonth=dayOfMonth,
- properties=properties, codebases=codebases)
-
- # If True, only important changes will be added to the buildset.
- self.onlyImportant = onlyImportant
-
- if fileIsImportant and not callable(fileIsImportant):
- config.error(
- "fileIsImportant must be a callable")
-
- if branch is Nightly.NoBranch:
- config.error(
- "Nightly parameter 'branch' is required")
-
- self.branch = branch
- self.onlyIfChanged = onlyIfChanged
- self.fileIsImportant = fileIsImportant
- self.change_filter = filter.ChangeFilter.fromSchedulerConstructorArgs(
- change_filter=change_filter)
- self.reason = "The Nightly scheduler named '%s' triggered this build" % self.name
-
- def startTimedSchedulerService(self):
- if self.onlyIfChanged:
- return self.startConsumingChanges(fileIsImportant=self.fileIsImportant,
- change_filter=self.change_filter,
- onlyImportant=self.onlyImportant)
- else:
- return self.master.db.schedulers.flushChangeClassifications(self.objectid)
-
- def gotChange(self, change, important):
- # both important and unimportant changes on our branch are recorded, as
- # we will include all such changes in any buildsets we start. Note
- # that we must check the branch here because it is not included in the
- # change filter.
- if change.branch != self.branch:
- return defer.succeed(None) # don't care about this change
- return self.master.db.schedulers.classifyChanges(
- self.objectid, { change.number : important })
-
- @defer.inlineCallbacks
- def startBuild(self):
- scheds = self.master.db.schedulers
- # if onlyIfChanged is True, then we will skip this build if no
- # important changes have occurred since the last invocation
- if self.onlyIfChanged:
- classifications = \
- yield scheds.getChangeClassifications(self.objectid)
-
- # see if we have any important changes
- for imp in classifications.itervalues():
- if imp:
- break
- else:
- log.msg(("Nightly Scheduler <%s>: skipping build " +
- "- No important changes on configured branch") % self.name)
- return
-
- changeids = sorted(classifications.keys())
- yield self.addBuildsetForChanges(reason=self.reason,
- changeids=changeids)
-
- max_changeid = changeids[-1] # (changeids are sorted)
- yield scheds.flushChangeClassifications(self.objectid,
- less_than=max_changeid+1)
- else:
- # start a build of the latest revision, whatever that is
- yield self.addBuildsetForLatest(reason=self.reason,
- branch=self.branch)
-
-class NightlyTriggerable(NightlyBase):
- implements(ITriggerableScheduler)
- def __init__(self, name, builderNames, minute=0, hour='*',
- dayOfMonth='*', month='*', dayOfWeek='*',
- properties={}, codebases=base.BaseScheduler.DefaultCodebases):
- NightlyBase.__init__(self, name=name, builderNames=builderNames, minute=minute, hour=hour,
- dayOfWeek=dayOfWeek, dayOfMonth=dayOfMonth, properties=properties, codebases=codebases)
-
- self._lastTrigger = None
- self.reason = "The NightlyTriggerable scheduler named '%s' triggered this build" % self.name
-
- def startService(self):
- NightlyBase.startService(self)
-
- # get the scheduler's lastTrigger time (note: only done at startup)
- d = self.getState('lastTrigger', None)
- def setLast(lastTrigger):
- try:
- if lastTrigger:
- assert isinstance(lastTrigger[0], dict)
- self._lastTrigger = (lastTrigger[0], properties.Properties.fromDict(lastTrigger[1]))
- except:
- # If the lastTrigger isn't of the right format, ignore it
- log.msg("NightlyTriggerable Scheduler <%s>: bad lastTrigger: %r" % (self.name, lastTrigger))
- d.addCallback(setLast)
-
- def trigger(self, sourcestamps, set_props=None):
- """Trigger this scheduler with the given sourcestamp ID. Returns a
- deferred that will fire when the buildset is finished."""
- self._lastTrigger = (sourcestamps, set_props)
-
- # record the trigger in the db
- if set_props:
- propsDict = set_props.asDict()
- else:
- propsDict = {}
- d = self.setState('lastTrigger',
- (sourcestamps, propsDict))
-
- ## Trigger expects a callback with the success of the triggered
- ## build, if waitForFinish is True.
- ## Just return SUCCESS, to indicate that the trigger was succesful,
- ## don't want for the nightly to run.
- return d.addCallback(lambda _: buildstep.SUCCESS)
-
- @defer.inlineCallbacks
- def startBuild(self):
- if self._lastTrigger is None:
- defer.returnValue(None)
-
- (sourcestamps, set_props) = self._lastTrigger
- self._lastTrigger = None
- yield self.setState('lastTrigger', None)
-
- # properties for this buildset are composed of our own properties,
- # potentially overridden by anything from the triggering build
- props = properties.Properties()
- props.updateFromProperties(self.properties)
- if set_props:
- props.updateFromProperties(set_props)
-
- yield self.addBuildsetForSourceStampSetDetails(reason=self.reason, sourcestamps=sourcestamps,
- properties=props)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/triggerable.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/triggerable.py
deleted file mode 100644
index a50e120e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/triggerable.py
+++ /dev/null
@@ -1,94 +0,0 @@
-# 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
-
-from zope.interface import implements
-
-from twisted.python import failure
-from twisted.internet import defer
-from buildbot.interfaces import ITriggerableScheduler
-from buildbot.schedulers import base
-from buildbot.process.properties import Properties
-
-class Triggerable(base.BaseScheduler):
- implements(ITriggerableScheduler)
-
- compare_attrs = base.BaseScheduler.compare_attrs
-
- def __init__(self, name, builderNames, properties={}, **kwargs):
- base.BaseScheduler.__init__(self, name, builderNames, properties,
- **kwargs)
- self._waiters = {}
- self._bsc_subscription = None
- self.reason = "Triggerable(%s)" % name
-
- def trigger(self, sourcestamps = None, set_props=None):
- """Trigger this scheduler with the optional given list of sourcestamps
- Returns a deferred that will fire when the buildset is finished."""
- # properties for this buildset are composed of our own properties,
- # potentially overridden by anything from the triggering build
- props = Properties()
- props.updateFromProperties(self.properties)
- if set_props:
- props.updateFromProperties(set_props)
-
- # note that this does not use the buildset subscriptions mechanism, as
- # the duration of interest to the caller is bounded by the lifetime of
- # this process.
- d = self.addBuildsetForSourceStampSetDetails(self.reason,
- sourcestamps, props)
- def setup_waiter((bsid,brids)):
- d = defer.Deferred()
- self._waiters[bsid] = (d, brids)
- self._updateWaiters()
- return d
- d.addCallback(setup_waiter)
- return d
-
- def stopService(self):
- # cancel any outstanding subscription
- if self._bsc_subscription:
- self._bsc_subscription.unsubscribe()
- self._bsc_subscription = None
-
- # and errback any outstanding deferreds
- if self._waiters:
- msg = 'Triggerable scheduler stopped before build was complete'
- for d, brids in self._waiters.values():
- d.errback(failure.Failure(RuntimeError(msg)))
- self._waiters = {}
-
- return base.BaseScheduler.stopService(self)
-
-
- def _updateWaiters(self):
- if self._waiters and not self._bsc_subscription:
- self._bsc_subscription = \
- self.master.subscribeToBuildsetCompletions(
- self._buildsetComplete)
- elif not self._waiters and self._bsc_subscription:
- self._bsc_subscription.unsubscribe()
- self._bsc_subscription = None
-
- def _buildsetComplete(self, bsid, result):
- if bsid not in self._waiters:
- return
-
- # pop this bsid from the waiters list, and potentially unsubscribe
- # from completion notifications
- d, brids = self._waiters.pop(bsid)
- self._updateWaiters()
-
- # fire the callback to indicate that the triggered build is complete
- d.callback((result, brids))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/trysched.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/trysched.py
deleted file mode 100644
index 79179ba8..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/schedulers/trysched.py
+++ /dev/null
@@ -1,304 +0,0 @@
-# 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 os
-
-from twisted.internet import defer
-from twisted.python import log
-from twisted.protocols import basic
-
-from buildbot import pbutil
-from buildbot.util.maildir import MaildirService
-from buildbot.util import json
-from buildbot.util import netstrings
-from buildbot.process.properties import Properties
-from buildbot.schedulers import base
-from buildbot.status.buildset import BuildSetStatus
-
-
-class TryBase(base.BaseScheduler):
-
- def filterBuilderList(self, builderNames):
- """
- Make sure that C{builderNames} is a subset of the configured
- C{self.builderNames}, returning an empty list if not. If
- C{builderNames} is empty, use C{self.builderNames}.
-
- @returns: list of builder names to build on
- """
-
- # self.builderNames is the configured list of builders
- # available for try. If the user supplies a list of builders,
- # it must be restricted to the configured list. If not, build
- # on all of the configured builders.
- if builderNames:
- for b in builderNames:
- if not b in self.builderNames:
- log.msg("%s got with builder %s" % (self, b))
- log.msg(" but that wasn't in our list: %s"
- % (self.builderNames,))
- return []
- else:
- builderNames = self.builderNames
- return builderNames
-
-
-class BadJobfile(Exception):
- pass
-
-
-class JobdirService(MaildirService):
- # NOTE: tightly coupled with Try_Jobdir, below
-
- def messageReceived(self, filename):
- f = self.moveToCurDir(filename)
- return self.parent.handleJobFile(filename, f)
-
-
-class Try_Jobdir(TryBase):
-
- compare_attrs = TryBase.compare_attrs + ('jobdir',)
-
- def __init__(self, name, builderNames, jobdir,
- properties={}):
- TryBase.__init__(self, name=name, builderNames=builderNames,
- properties=properties)
- self.jobdir = jobdir
- self.watcher = JobdirService()
- self.watcher.setServiceParent(self)
-
- def startService(self):
- # set the watcher's basedir now that we have a master
- jobdir = os.path.join(self.master.basedir, self.jobdir)
- self.watcher.setBasedir(jobdir)
- for subdir in "cur new tmp".split():
- if not os.path.exists(os.path.join(jobdir, subdir)):
- os.mkdir(os.path.join(jobdir, subdir))
- TryBase.startService(self)
-
- def parseJob(self, f):
- # jobfiles are serialized build requests. Each is a list of
- # serialized netstrings, in the following order:
- # format version number:
- # "1" the original
- # "2" introduces project and repository
- # "3" introduces who
- # "4" introduces comment
- # "5" introduces properties and JSON serialization of values after
- # version
- # jobid: arbitrary string, used to find the buildSet later
- # branch: branch name, "" for default-branch
- # baserev: revision, "" for HEAD
- # patch_level: usually "1"
- # patch_body: patch to be applied for build
- # repository
- # project
- # who: user requesting build
- # comment: comment from user about diff and/or build
- # builderNames: list of builder names
- # properties: dict of build properties
- p = netstrings.NetstringParser()
- f.seek(0,2)
- if f.tell() > basic.NetstringReceiver.MAX_LENGTH:
- raise BadJobfile("The patch size is greater that NetStringReceiver.MAX_LENGTH. Please Set this higher in the master.cfg")
- f.seek(0,0)
- try:
- p.feed(f.read())
- except basic.NetstringParseError:
- raise BadJobfile("unable to parse netstrings")
- if not p.strings:
- raise BadJobfile("could not find any complete netstrings")
- ver = p.strings.pop(0)
-
- v1_keys = ['jobid', 'branch', 'baserev', 'patch_level', 'patch_body']
- v2_keys = v1_keys + ['repository', 'project']
- v3_keys = v2_keys + ['who']
- v4_keys = v3_keys + ['comment']
- keys = [v1_keys, v2_keys, v3_keys, v4_keys]
- # v5 introduces properties and uses JSON serialization
-
- parsed_job = {}
-
- def extract_netstrings(p, keys):
- for i, key in enumerate(keys):
- parsed_job[key] = p.strings[i]
-
- def postprocess_parsed_job():
- # apply defaults and handle type casting
- parsed_job['branch'] = parsed_job['branch'] or None
- parsed_job['baserev'] = parsed_job['baserev'] or None
- parsed_job['patch_level'] = int(parsed_job['patch_level'])
- for key in 'repository project who comment'.split():
- parsed_job[key] = parsed_job.get(key, '')
- parsed_job['properties'] = parsed_job.get('properties', {})
-
- if ver <= "4":
- i = int(ver) - 1
- extract_netstrings(p, keys[i])
- parsed_job['builderNames'] = p.strings[len(keys[i]):]
- postprocess_parsed_job()
- elif ver == "5":
- try:
- parsed_job = json.loads(p.strings[0])
- except ValueError:
- raise BadJobfile("unable to parse JSON")
- postprocess_parsed_job()
- else:
- raise BadJobfile("unknown version '%s'" % ver)
- return parsed_job
-
- def handleJobFile(self, filename, f):
- try:
- parsed_job = self.parseJob(f)
- builderNames = parsed_job['builderNames']
- except BadJobfile:
- log.msg("%s reports a bad jobfile in %s" % (self, filename))
- log.err()
- return defer.succeed(None)
-
- # Validate/fixup the builder names.
- builderNames = self.filterBuilderList(builderNames)
- if not builderNames:
- log.msg(
- "incoming Try job did not specify any allowed builder names")
- return defer.succeed(None)
-
- who = ""
- if parsed_job['who']:
- who = parsed_job['who']
-
- comment = ""
- if parsed_job['comment']:
- comment = parsed_job['comment']
-
- d = self.master.db.sourcestampsets.addSourceStampSet()
-
- def addsourcestamp(setid):
- self.master.db.sourcestamps.addSourceStamp(
- sourcestampsetid=setid,
- branch=parsed_job['branch'],
- revision=parsed_job['baserev'],
- patch_body=parsed_job['patch_body'],
- patch_level=parsed_job['patch_level'],
- patch_author=who,
- patch_comment=comment,
- patch_subdir='', # TODO: can't set this remotely - #1769
- project=parsed_job['project'],
- repository=parsed_job['repository'])
- return setid
-
- d.addCallback(addsourcestamp)
-
- def create_buildset(setid):
- reason = "'try' job"
- if parsed_job['who']:
- reason += " by user %s" % parsed_job['who']
- properties = parsed_job['properties']
- requested_props = Properties()
- requested_props.update(properties, "try build")
- return self.addBuildsetForSourceStamp(
- ssid=None, setid=setid,
- reason=reason, external_idstring=parsed_job['jobid'],
- builderNames=builderNames, properties=requested_props)
- d.addCallback(create_buildset)
- return d
-
-
-class Try_Userpass_Perspective(pbutil.NewCredPerspective):
- def __init__(self, scheduler, username):
- self.scheduler = scheduler
- self.username = username
-
- @defer.inlineCallbacks
- def perspective_try(self, branch, revision, patch, repository, project,
- builderNames, who="", comment="", properties={}):
- db = self.scheduler.master.db
- log.msg("user %s requesting build on builders %s" % (self.username,
- builderNames))
-
- # build the intersection of the request and our configured list
- builderNames = self.scheduler.filterBuilderList(builderNames)
- if not builderNames:
- return
-
- reason = "'try' job"
-
- if who:
- reason += " by user %s" % who
-
- if comment:
- reason += " (%s)" % comment
-
- sourcestampsetid = yield db.sourcestampsets.addSourceStampSet()
-
- yield db.sourcestamps.addSourceStamp(
- branch=branch, revision=revision, repository=repository,
- project=project, patch_level=patch[0], patch_body=patch[1],
- patch_subdir='', patch_author=who or '',
- patch_comment=comment or '',
- sourcestampsetid=sourcestampsetid)
- # note: no way to specify patch subdir - #1769
-
- requested_props = Properties()
- requested_props.update(properties, "try build")
- (bsid, brids) = yield self.scheduler.addBuildsetForSourceStamp(
- setid=sourcestampsetid, reason=reason,
- properties=requested_props, builderNames=builderNames)
-
- # return a remotely-usable BuildSetStatus object
- bsdict = yield db.buildsets.getBuildset(bsid)
-
- bss = BuildSetStatus(bsdict, self.scheduler.master.status)
- from buildbot.status.client import makeRemote
- defer.returnValue(makeRemote(bss))
-
- def perspective_getAvailableBuilderNames(self):
- # Return a list of builder names that are configured
- # for the try service
- # This is mostly intended for integrating try services
- # into other applications
- return self.scheduler.listBuilderNames()
-
-
-class Try_Userpass(TryBase):
- compare_attrs = ('name', 'builderNames', 'port', 'userpass', 'properties')
-
- def __init__(self, name, builderNames, port, userpass,
- properties={}):
- TryBase.__init__(self, name=name, builderNames=builderNames,
- properties=properties)
- self.port = port
- self.userpass = userpass
-
- def startService(self):
- TryBase.startService(self)
-
- # register each user/passwd with the pbmanager
- def factory(mind, username):
- return Try_Userpass_Perspective(self, username)
- self.registrations = []
- for user, passwd in self.userpass:
- self.registrations.append(
- self.master.pbmanager.register(
- self.port, user, passwd, factory))
-
- def stopService(self):
- d = defer.maybeDeferred(TryBase.stopService, self)
-
- def unreg(_):
- return defer.gatherResults(
- [reg.unregister() for reg in self.registrations])
- d.addCallback(unreg)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/base.py
deleted file mode 100644
index b1349a65..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/base.py
+++ /dev/null
@@ -1,172 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os
-import copy
-import stat
-from twisted.python import usage, runtime
-
-def isBuildmasterDir(dir):
- def print_error(error_message):
- print "%s\ninvalid buildmaster directory '%s'" % (error_message, dir)
-
- buildbot_tac = os.path.join(dir, "buildbot.tac")
- try:
- contents = open(buildbot_tac).read()
- except IOError, exception:
- print_error("error reading '%s': %s" % \
- (buildbot_tac, exception.strerror))
- return False
-
- if "Application('buildmaster')" not in contents:
- print_error("unexpected content in '%s'" % buildbot_tac)
- return False
-
- return True
-
-def getConfigFileFromTac(basedir):
- # execute the .tac file to see if its configfile location exists
- tacFile = os.path.join(basedir, 'buildbot.tac')
- if os.path.exists(tacFile):
- # don't mess with the global namespace, but set __file__ for relocatable buildmasters
- tacGlobals = {'__file__' : tacFile}
- execfile(tacFile, tacGlobals)
- return tacGlobals.get("configfile", "master.cfg")
- else:
- return "master.cfg"
-
-class SubcommandOptions(usage.Options):
- # subclasses should set this to a list-of-lists in order to source the
- # .buildbot/options file. Note that this *only* works with optParameters,
- # not optFlags. Example:
- # buildbotOptions = [ [ 'optfile-name', 'parameter-name' ], .. ]
- buildbotOptions = None
-
- # set this to options that must have non-None values
- requiredOptions = []
-
- def __init__(self, *args):
- # for options in self.buildbotOptions, optParameters, and the options
- # file, change the default in optParameters to the value in the options
- # file, call through to the constructor, and then change it back.
- # Options uses reflect.accumulateClassList, so this *must* be a class
- # attribute; however, we do not want to permanently change the class.
- # So we patch it temporarily and restore it after.
- cls = self.__class__
- if hasattr(cls, 'optParameters'):
- old_optParameters = cls.optParameters
- cls.optParameters = op = copy.deepcopy(cls.optParameters)
- if self.buildbotOptions:
- optfile = self.optionsFile = self.loadOptionsFile()
- for optfile_name, option_name in self.buildbotOptions:
- for i in range(len(op)):
- if (op[i][0] == option_name
- and optfile_name in optfile):
- op[i] = list(op[i])
- op[i][2] = optfile[optfile_name]
- usage.Options.__init__(self, *args)
- if hasattr(cls, 'optParameters'):
- cls.optParameters = old_optParameters
-
- def loadOptionsFile(self, _here=None):
- """Find the .buildbot/options file. Crawl from the current directory
- up towards the root, and also look in ~/.buildbot . The first directory
- that's owned by the user and has the file we're looking for wins.
- Windows skips the owned-by-user test.
-
- @rtype: dict
- @return: a dictionary of names defined in the options file. If no
- options file was found, return an empty dict.
- """
-
- here = _here or os.path.abspath(os.getcwd())
-
- if runtime.platformType == 'win32':
- # never trust env-vars, use the proper API
- from win32com.shell import shellcon, shell
- appdata = shell.SHGetFolderPath(0, shellcon.CSIDL_APPDATA, 0, 0)
- home = os.path.join(appdata, "buildbot")
- else:
- home = os.path.expanduser("~/.buildbot")
-
- searchpath = []
- toomany = 20
- while True:
- searchpath.append(os.path.join(here, ".buildbot"))
- next = os.path.dirname(here)
- if next == here:
- break # we've hit the root
- here = next
- toomany -= 1 # just in case
- if toomany == 0:
- print ("I seem to have wandered up into the infinite glories "
- "of the heavens. Oops.")
- break
-
- searchpath.append(home)
-
- localDict = {}
-
- for d in searchpath:
- if os.path.isdir(d):
- if runtime.platformType != 'win32':
- if os.stat(d)[stat.ST_UID] != os.getuid():
- print "skipping %s because you don't own it" % d
- continue # security, skip other people's directories
- optfile = os.path.join(d, "options")
- if os.path.exists(optfile):
- try:
- with open(optfile, "r") as f:
- options = f.read()
- exec options in localDict
- except:
- print "error while reading %s" % optfile
- raise
- break
-
- for k in localDict.keys():
- if k.startswith("__"):
- del localDict[k]
- return localDict
-
- def postOptions(self):
- missing = [ k for k in self.requiredOptions if self[k] is None ]
- if missing:
- if len(missing) > 1:
- msg = 'Required arguments missing: ' + ', '.join(missing)
- else:
- msg = 'Required argument missing: ' + missing[0]
- raise usage.UsageError(msg)
-
-class BasedirMixin(object):
-
- """SubcommandOptions Mixin to handle subcommands that take a basedir
- argument"""
-
- def parseArgs(self, *args):
- if len(args) > 0:
- self['basedir'] = args[0]
- else:
- # Use the current directory if no basedir was specified.
- self['basedir'] = os.getcwd()
- if len(args) > 1:
- raise usage.UsageError("I wasn't expecting so many arguments")
-
- def postOptions(self):
- # get an unambiguous, epxnaed basedir, including expanding '~', which
- # may be useful in a .buildbot/config file
- self['basedir'] = os.path.abspath(os.path.expanduser(self['basedir']))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/buildbot_tac.tmpl b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/buildbot_tac.tmpl
deleted file mode 100644
index 146c9698..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/buildbot_tac.tmpl
+++ /dev/null
@@ -1,42 +0,0 @@
-import os
-
-from twisted.application import service
-from buildbot.master import BuildMaster
-
-{% if relocatable -%}
-basedir = '.'
-{% else -%}
-basedir = {{ basedir|repr }}
-{%- endif %}
-{% if not no_logrotate -%}
-rotateLength = {{ log_size|repr }}
-maxRotatedFiles = {{ log_count|repr }}
-{%- endif %}
-configfile = {{ config|repr }}
-
-# Default umask for server
-umask = None
-
-# if this is a relocatable tac file, get the directory containing the TAC
-if basedir == '.':
- import os.path
- basedir = os.path.abspath(os.path.dirname(__file__))
-
-# note: this line is matched against to check that this is a buildmaster
-# directory; do not edit it.
-application = service.Application('buildmaster')
-{% if not no_logrotate -%}
-from twisted.python.logfile import LogFile
-from twisted.python.log import ILogObserver, FileLogObserver
-logfile = LogFile.fromFullPath(os.path.join(basedir, "twistd.log"), rotateLength=rotateLength,
- maxRotatedFiles=maxRotatedFiles)
-application.setComponent(ILogObserver, FileLogObserver(logfile).emit)
-{%- endif %}
-
-m = BuildMaster(basedir, configfile, umask)
-m.setServiceParent(application)
-{% if not no_logrotate -%}
-m.log_rotation.rotateLength = rotateLength
-m.log_rotation.maxRotatedFiles = maxRotatedFiles
-{%- endif %}
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/checkconfig.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/checkconfig.py
deleted file mode 100644
index 8e05b0bb..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/checkconfig.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# 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 sys
-import os
-from buildbot import config
-from buildbot.scripts.base import getConfigFileFromTac
-
-def _loadConfig(basedir, configFile, quiet):
- try:
- config.MasterConfig.loadConfig(
- basedir, configFile)
- except config.ConfigErrors, e:
- if not quiet:
- print >> sys.stderr, "Configuration Errors:"
- for e in e.errors:
- print >> sys.stderr, " " + e
- return 1
-
- if not quiet:
- print "Config file is good!"
- return 0
-
-
-def checkconfig(config):
- quiet = config.get('quiet')
- configFile = config.get('configFile')
-
- if os.path.isdir(configFile):
- basedir = configFile
- try:
- configFile = getConfigFileFromTac(basedir)
- except (SyntaxError, ImportError), e:
- if not quiet:
- print "Unable to load 'buildbot.tac' from '%s':" % basedir
- print e
- return 1
- else:
- basedir = os.getcwd()
-
- return _loadConfig(basedir=basedir, configFile=configFile, quiet=quiet)
-
-
-__all__ = ['checkconfig']
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/create_master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/create_master.py
deleted file mode 100644
index ba5a5f60..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/create_master.py
+++ /dev/null
@@ -1,150 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os
-import jinja2
-from twisted.python import util
-from twisted.internet import defer
-from buildbot.util import in_reactor
-from buildbot.db import connector
-from buildbot.master import BuildMaster
-from buildbot import config as config_module
-from buildbot import monkeypatches
-
-def makeBasedir(config):
- if os.path.exists(config['basedir']):
- if not config['quiet']:
- print "updating existing installation"
- return
- if not config['quiet']:
- print "mkdir", config['basedir']
- os.mkdir(config['basedir'])
-
-def makeTAC(config):
- # render buildbot_tac.tmpl using the config
- loader = jinja2.FileSystemLoader(os.path.dirname(__file__))
- env = jinja2.Environment(loader=loader, undefined=jinja2.StrictUndefined)
- env.filters['repr'] = repr
- tpl = env.get_template('buildbot_tac.tmpl')
- cxt = dict((k.replace('-', '_'), v) for k,v in config.iteritems())
- contents = tpl.render(cxt)
-
- tacfile = os.path.join(config['basedir'], "buildbot.tac")
- if os.path.exists(tacfile):
- with open(tacfile, "rt") as f:
- oldcontents = f.read()
- if oldcontents == contents:
- if not config['quiet']:
- print "buildbot.tac already exists and is correct"
- return
- if not config['quiet']:
- print "not touching existing buildbot.tac"
- print "creating buildbot.tac.new instead"
- tacfile += ".new"
- with open(tacfile, "wt") as f:
- f.write(contents)
-
-def makeSampleConfig(config):
- source = util.sibpath(__file__, "sample.cfg")
- target = os.path.join(config['basedir'], "master.cfg.sample")
- if not config['quiet']:
- print "creating %s" % target
- with open(source, "rt") as f:
- config_sample = f.read()
- if config['db']:
- config_sample = config_sample.replace('sqlite:///state.sqlite',
- config['db'])
- with open(target, "wt") as f:
- f.write(config_sample)
- os.chmod(target, 0600)
-
-def makePublicHtml(config):
- files = {
- 'bg_gradient.jpg' : "../status/web/files/bg_gradient.jpg",
- 'default.css' : "../status/web/files/default.css",
- 'robots.txt' : "../status/web/files/robots.txt",
- 'favicon.ico' : "../status/web/files/favicon.ico",
- }
- webdir = os.path.join(config['basedir'], "public_html")
- if os.path.exists(webdir):
- if not config['quiet']:
- print "public_html/ already exists: not replacing"
- return
- else:
- os.mkdir(webdir)
- if not config['quiet']:
- print "populating public_html/"
- for target, source in files.iteritems():
- source = util.sibpath(__file__, source)
- target = os.path.join(webdir, target)
- with open(target, "wt") as f:
- with open(source, "rt") as i:
- f.write(i.read())
-
-def makeTemplatesDir(config):
- files = {
- 'README.txt' : "../status/web/files/templates_readme.txt",
- }
- template_dir = os.path.join(config['basedir'], "templates")
- if os.path.exists(template_dir):
- if not config['quiet']:
- print "templates/ already exists: not replacing"
- return
- else:
- os.mkdir(template_dir)
- if not config['quiet']:
- print "populating templates/"
- for target, source in files.iteritems():
- source = util.sibpath(__file__, source)
- target = os.path.join(template_dir, target)
- with open(target, "wt") as f:
- with open(source, "rt") as i:
- f.write(i.read())
-
-@defer.inlineCallbacks
-def createDB(config, _noMonkey=False):
- # apply the db monkeypatches (and others - no harm)
- if not _noMonkey: # pragma: no cover
- monkeypatches.patch_all()
-
- # create a master with the default configuration, but with db_url
- # overridden
- master_cfg = config_module.MasterConfig()
- master_cfg.db['db_url'] = config['db']
- master = BuildMaster(config['basedir'])
- master.config = master_cfg
- db = connector.DBConnector(master, config['basedir'])
- yield db.setup(check_version=False, verbose=not config['quiet'])
- if not config['quiet']:
- print "creating database (%s)" % (master_cfg.db['db_url'],)
- yield db.model.upgrade()
-
-
-@in_reactor
-@defer.inlineCallbacks
-def createMaster(config):
- makeBasedir(config)
- makeTAC(config)
- makeSampleConfig(config)
- makePublicHtml(config)
- makeTemplatesDir(config)
- yield createDB(config)
-
- if not config['quiet']:
- print "buildmaster configured in %s" % (config['basedir'],)
-
- defer.returnValue(0)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/debugclient.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/debugclient.py
deleted file mode 100644
index 4846c0bf..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/debugclient.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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
-
-def debugclient(config):
- from buildbot.clients import debug
-
- d = debug.DebugWidget(config['master'], config['passwd'])
- d.run()
- return 0
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/logwatcher.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/logwatcher.py
deleted file mode 100644
index dede9704..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/logwatcher.py
+++ /dev/null
@@ -1,110 +0,0 @@
-# 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 os
-from twisted.python.failure import Failure
-from twisted.internet import defer, reactor, protocol, error
-from twisted.protocols.basic import LineOnlyReceiver
-
-class FakeTransport:
- disconnecting = False
-
-class BuildmasterTimeoutError(Exception):
- pass
-class ReconfigError(Exception):
- pass
-
-class TailProcess(protocol.ProcessProtocol):
- def outReceived(self, data):
- self.lw.dataReceived(data)
- def errReceived(self, data):
- print "ERR: '%s'" % (data,)
-
-
-class LogWatcher(LineOnlyReceiver):
- POLL_INTERVAL = 0.1
- TIMEOUT_DELAY = 10.0
- delimiter = os.linesep
-
- def __init__(self, logfile):
- self.logfile = logfile
- self.in_reconfig = False
- self.transport = FakeTransport()
- self.pp = TailProcess()
- self.pp.lw = self
- self.timer = None
-
- def start(self):
- # If the log file doesn't exist, create it now.
- if not os.path.exists(self.logfile):
- open(self.logfile, 'a').close()
-
- # return a Deferred that fires when the reconfig process has
- # finished. It errbacks with TimeoutError if the finish line has not
- # been seen within 10 seconds, and with ReconfigError if the error
- # line was seen. If the logfile could not be opened, it errbacks with
- # an IOError.
- self.p = reactor.spawnProcess(self.pp, "/usr/bin/tail",
- ("tail", "-f", "-n", "0", self.logfile),
- env=os.environ,
- )
- self.running = True
- d = defer.maybeDeferred(self._start)
- return d
-
- def _start(self):
- self.d = defer.Deferred()
- self.timer = reactor.callLater(self.TIMEOUT_DELAY, self.timeout)
- return self.d
-
- def timeout(self):
- self.timer = None
- e = BuildmasterTimeoutError()
- self.finished(Failure(e))
-
- def finished(self, results):
- try:
- self.p.signalProcess("KILL")
- except error.ProcessExitedAlready:
- pass
- if self.timer:
- self.timer.cancel()
- self.timer = None
- self.running = False
- self.in_reconfig = False
- self.d.callback(results)
-
- def lineReceived(self, line):
- if not self.running:
- return
- if "Log opened." in line:
- self.in_reconfig = True
- if "beginning configuration update" in line:
- self.in_reconfig = True
-
- if self.in_reconfig:
- print line
-
- if "message from master: attached" in line:
- return self.finished("buildslave")
- if "reconfig aborted" in line or 'reconfig partially applied' in line:
- return self.finished(Failure(ReconfigError()))
- if "Server Shut Down" in line:
- return self.finished(Failure(ReconfigError()))
- if "configuration update complete" in line:
- return self.finished("buildmaster")
- if "BuildMaster is running" in line:
- return self.finished("buildmaster")
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/reconfig.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/reconfig.py
deleted file mode 100644
index a7f5602e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/reconfig.py
+++ /dev/null
@@ -1,92 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-
-import os
-import signal
-import platform
-from twisted.internet import reactor
-
-from buildbot.scripts.logwatcher import LogWatcher, BuildmasterTimeoutError, \
- ReconfigError
-from buildbot.util import in_reactor
-
-class Reconfigurator:
-
- rc = 0
-
- def run(self, basedir, quiet):
- # Returns "Microsoft" for Vista and "Windows" for other versions
- if platform.system() in ("Windows", "Microsoft"):
- print "Reconfig (through SIGHUP) is not supported on Windows."
- print "The 'buildbot debugclient' tool can trigger a reconfig"
- print "remotely, but requires Gtk+ libraries to run."
- return
-
- with open(os.path.join(basedir, "twistd.pid"), "rt") as f:
- self.pid = int(f.read().strip())
- if quiet:
- os.kill(self.pid, signal.SIGHUP)
- return
-
- # keep reading twistd.log. Display all messages between "loading
- # configuration from ..." and "configuration update complete" or
- # "I will keep using the previous config file instead.", or until
- # 10 seconds have elapsed.
-
- self.sent_signal = False
- reactor.callLater(0.2, self.sighup)
-
- lw = LogWatcher(os.path.join(basedir, "twistd.log"))
- d = lw.start()
- d.addCallbacks(self.success, self.failure)
- d.addBoth(lambda _ : self.rc)
- return d
-
- def sighup(self):
- if self.sent_signal:
- return
- print "sending SIGHUP to process %d" % self.pid
- self.sent_signal = True
- os.kill(self.pid, signal.SIGHUP)
-
- def success(self, res):
- print """
-Reconfiguration appears to have completed successfully.
-"""
-
- def failure(self, why):
- self.rc = 1
- if why.check(BuildmasterTimeoutError):
- print "Never saw reconfiguration finish."
- elif why.check(ReconfigError):
- print """
-Reconfiguration failed. Please inspect the master.cfg file for errors,
-correct them, then try 'buildbot reconfig' again.
-"""
- elif why.check(IOError):
- # we were probably unable to open the file in the first place
- self.sighup()
- else:
- print "Error while following twistd.log: %s" % why
-
-@in_reactor
-def reconfig(config):
- basedir = config['basedir']
- quiet = config['quiet']
- r = Reconfigurator()
- return r.run(basedir, quiet)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/restart.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/restart.py
deleted file mode 100644
index f9e0e28a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/restart.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-from buildbot.scripts import base, stop, start
-
-def restart(config):
- basedir = config['basedir']
- quiet = config['quiet']
-
- if not base.isBuildmasterDir(basedir):
- return 1
-
- if stop.stop(config, wait=True) != 0:
- return 1
- if not quiet:
- print "now restarting buildbot process.."
- return start.start(config)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/runner.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/runner.py
deleted file mode 100644
index 89254c2a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/runner.py
+++ /dev/null
@@ -1,731 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-# N.B.: don't import anything that might pull in a reactor yet. Some of our
-# subcommands want to load modules that need the gtk reactor.
-#
-# Also don't forget to mirror your changes on command-line options in manual
-# pages and texinfo documentation.
-
-from twisted.python import usage, reflect
-import re
-import sys
-
-from buildbot.scripts import base
-
-# Note that the terms 'options' and 'config' are used interchangeably here - in
-# fact, they are interchanged several times. Caveat legator.
-
-def validateMasterOption(master):
- """
- Validate master (-m, --master) command line option.
-
- Checks that option is a string of the 'hostname:port' form, otherwise
- raises an UsageError exception.
-
- @type master: string
- @param master: master option
-
- @raise usage.UsageError: on invalid master option
- """
- try:
- hostname, port = master.split(":")
- port = int(port)
- except:
- raise usage.UsageError("master must have the form 'hostname:port'")
-
-
-class UpgradeMasterOptions(base.BasedirMixin, base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.upgrade_master.upgradeMaster"
- optFlags = [
- ["quiet", "q", "Do not emit the commands being run"],
- ["replace", "r", "Replace any modified files without confirmation."],
- ]
- optParameters = [
- ]
-
- def getSynopsis(self):
- return "Usage: buildbot upgrade-master [options] [<basedir>]"
-
- longdesc = """
- This command takes an existing buildmaster working directory and
- adds/modifies the files there to work with the current version of
- buildbot. When this command is finished, the buildmaster directory should
- look much like a brand-new one created by the 'create-master' command.
-
- Use this after you've upgraded your buildbot installation and before you
- restart the buildmaster to use the new version.
-
- If you have modified the files in your working directory, this command
- will leave them untouched, but will put the new recommended contents in a
- .new file (for example, if index.html has been modified, this command
- will create index.html.new). You can then look at the new version and
- decide how to merge its contents into your modified file.
-
- When upgrading from a pre-0.8.0 release (which did not use a database),
- this command will create the given database and migrate data from the old
- pickle files into it, then move the pickle files out of the way (e.g. to
- changes.pck.old).
-
- When upgrading the database, this command uses the database specified in
- the master configuration file. If you wish to use a database other than
- the default (sqlite), be sure to set that parameter before upgrading.
- """
-
-
-class CreateMasterOptions(base.BasedirMixin, base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.create_master.createMaster"
- optFlags = [
- ["quiet", "q", "Do not emit the commands being run"],
- ["force", "f",
- "Re-use an existing directory (will not overwrite master.cfg file)"],
- ["relocatable", "r",
- "Create a relocatable buildbot.tac"],
- ["no-logrotate", "n",
- "Do not permit buildmaster rotate logs by itself"]
- ]
- optParameters = [
- ["config", "c", "master.cfg", "name of the buildmaster config file"],
- ["log-size", "s", "10000000",
- "size at which to rotate twisted log files"],
- ["log-count", "l", "10",
- "limit the number of kept old twisted log files"],
- ["db", None, "sqlite:///state.sqlite",
- "which DB to use for scheduler/status state. See below for syntax."],
- ]
- def getSynopsis(self):
- return "Usage: buildbot create-master [options] [<basedir>]"
-
- longdesc = """
- This command creates a buildmaster working directory and buildbot.tac file.
- The master will live in <dir> and create various files there. If
- --relocatable is given, then the resulting buildbot.tac file will be
- written such that its containing directory is assumed to be the basedir.
- This is generally a good idea.
-
- At runtime, the master will read a configuration file (named
- 'master.cfg' by default) in its basedir. This file should contain python
- code which eventually defines a dictionary named 'BuildmasterConfig'.
- The elements of this dictionary are used to configure the Buildmaster.
- See doc/config.xhtml for details about what can be controlled through
- this interface.
-
- The --db string is evaluated to build the DB object, which specifies
- which database the buildmaster should use to hold scheduler state and
- status information. The default (which creates an SQLite database in
- BASEDIR/state.sqlite) is equivalent to:
-
- --db='sqlite:///state.sqlite'
-
- To use a remote MySQL database instead, use something like:
-
- --db='mysql://bbuser:bbpasswd@dbhost/bbdb'
- The --db string is stored verbatim in the buildbot.tac file, and
- evaluated as 'buildbot start' time to pass a DBConnector instance into
- the newly-created BuildMaster object.
- """
-
- def postOptions(self):
- base.BasedirMixin.postOptions(self)
- if not re.match('^\d+$', self['log-size']):
- raise usage.UsageError("log-size parameter needs to be an int")
- if not re.match('^\d+$', self['log-count']) and \
- self['log-count'] != 'None':
- raise usage.UsageError("log-count parameter needs to be an int "+
- " or None")
-
-
-class StopOptions(base.BasedirMixin, base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.stop.stop"
- optFlags = [
- ["quiet", "q", "Do not emit the commands being run"],
- ["clean", "c", "Clean shutdown master"],
- ]
- def getSynopsis(self):
- return "Usage: buildbot stop [<basedir>]"
-
-
-class RestartOptions(base.BasedirMixin, base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.restart.restart"
- optFlags = [
- ['quiet', 'q', "Don't display startup log messages"],
- ['nodaemon', None, "Don't daemonize (stay in foreground)"],
- ["clean", "c", "Clean shutdown master"],
- ]
- def getSynopsis(self):
- return "Usage: buildbot restart [<basedir>]"
-
-
-class StartOptions(base.BasedirMixin, base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.start.start"
- optFlags = [
- ['quiet', 'q', "Don't display startup log messages"],
- ['nodaemon', None, "Don't daemonize (stay in foreground)"],
- ]
- def getSynopsis(self):
- return "Usage: buildbot start [<basedir>]"
-
-
-class ReconfigOptions(base.BasedirMixin, base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.reconfig.reconfig"
- optFlags = [
- ['quiet', 'q', "Don't display log messages about reconfiguration"],
- ]
- def getSynopsis(self):
- return "Usage: buildbot reconfig [<basedir>]"
-
-
-class DebugClientOptions(base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.debugclient.debugclient"
- optParameters = [
- ["master", "m", None,
- "Location of the buildmaster's slaveport (host:port)"],
- ["passwd", "p", None, "Debug password to use"],
- ]
- buildbotOptions = [
- [ 'master', 'master' ],
- [ 'debugMaster', 'master' ],
- ]
- requiredOptions = [ 'master', 'passwd' ]
-
- def getSynopsis(self):
- return "Usage: buildbot debugclient [options]"
-
- def parseArgs(self, *args):
- if len(args) > 0:
- self['master'] = args[0]
- if len(args) > 1:
- self['passwd'] = args[1]
- if len(args) > 2:
- raise usage.UsageError("I wasn't expecting so many arguments")
-
- def postOptions(self):
- base.SubcommandOptions.postOptions(self)
- validateMasterOption(self.get('master'))
-
-
-class BaseStatusClientOptions(base.SubcommandOptions):
- optFlags = [
- ['help', 'h', "Display this message"],
- ]
- optParameters = [
- ["master", "m", None,
- "Location of the buildmaster's status port (host:port)"],
- ["username", "u", "statusClient", "Username performing the trial build"],
- ["passwd", 'p', "clientpw", "password for PB authentication"],
- ]
- buildbotOptions = [
- [ 'master', 'master' ],
- [ 'masterstatus', 'master' ],
- ]
- requiredOptions = [ 'master' ]
-
- def parseArgs(self, *args):
- if len(args) > 0:
- self['master'] = args[0]
- if len(args) > 1:
- raise usage.UsageError("I wasn't expecting so many arguments")
-
- def postOptions(self):
- base.SubcommandOptions.postOptions(self)
- validateMasterOption(self.get('master'))
-
-
-
-class StatusLogOptions(BaseStatusClientOptions):
- subcommandFunction = "buildbot.scripts.statuslog.statuslog"
- def getSynopsis(self):
- return "Usage: buildbot statuslog [options]"
-
-
-class StatusGuiOptions(BaseStatusClientOptions):
- subcommandFunction = "buildbot.scripts.statusgui.statusgui"
- def getSynopsis(self):
- return "Usage: buildbot statusgui [options]"
-
-
-class SendChangeOptions(base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.sendchange.sendchange"
- def __init__(self):
- base.SubcommandOptions.__init__(self)
- self['properties'] = {}
-
- optParameters = [
- ("master", "m", None,
- "Location of the buildmaster's PBListener (host:port)"),
- # deprecated in 0.8.3; remove in 0.8.5 (bug #1711)
- ("auth", "a", 'change:changepw',
- "Authentication token - username:password, or prompt for password"),
- ("who", "W", None, "Author of the commit"),
- ("repository", "R", '', "Repository specifier"),
- ("vc", "s", None, "The VC system in use, one of: cvs, svn, darcs, hg, "
- "bzr, git, mtn, p4"),
- ("project", "P", '', "Project specifier"),
- ("branch", "b", None, "Branch specifier"),
- ("category", "C", None, "Category of repository"),
- ("codebase", None, None,
- "Codebase this change is in (requires 0.8.7 master or later)"),
- ("revision", "r", None, "Revision specifier"),
- ("revision_file", None, None, "Filename containing revision spec"),
- ("property", "p", None,
- "A property for the change, in the format: name:value"),
- ("comments", "c", None, "log message"),
- ("logfile", "F", None,
- "Read the log messages from this file (- for stdin)"),
- ("when", "w", None, "timestamp to use as the change time"),
- ("revlink", "l", '', "Revision link (revlink)"),
- ("encoding", "e", 'utf8',
- "Encoding of other parameters (default utf8)"),
- ]
-
- buildbotOptions = [
- [ 'master', 'master' ],
- [ 'who', 'who' ],
- [ 'branch', 'branch' ],
- [ 'category', 'category' ],
- [ 'vc', 'vc' ],
- ]
-
- requiredOptions = [ 'who', 'master' ]
-
- def getSynopsis(self):
- return "Usage: buildbot sendchange [options] filenames.."
-
- def parseArgs(self, *args):
- self['files'] = args
-
- def opt_property(self, property):
- name,value = property.split(':', 1)
- self['properties'][name] = value
-
- def postOptions(self):
- base.SubcommandOptions.postOptions(self)
-
- if self.get("revision_file"):
- with open(self["revision_file"],"r") as f:
- self['revision'] = f.read()
-
- if self.get('when'):
- try:
- self['when'] = float(self['when'])
- except:
- raise usage.UsageError('invalid "when" value %s'
- % (self['when'],))
- else:
- self['when'] = None
-
- if not self.get('comments') and self.get('logfile'):
- if self['logfile'] == "-":
- self['comments'] = sys.stdin.read()
- else:
- with open(self['logfile'], "rt") as f:
- self['comments'] = f.read()
- if self.get('comments') is None:
- self['comments'] = ""
-
- # fix up the auth with a password if none was given
- auth = self.get('auth')
- if ':' not in auth:
- import getpass
- pw = getpass.getpass("Enter password for '%s': " % auth)
- auth = "%s:%s" % (auth, pw)
- self['auth'] = tuple(auth.split(':', 1))
-
- vcs = ['cvs', 'svn', 'darcs', 'hg', 'bzr', 'git', 'mtn', 'p4']
- if self.get('vc') and self.get('vc') not in vcs:
- raise usage.UsageError("vc must be one of %s" % (', '.join(vcs)))
-
- validateMasterOption(self.get('master'))
-
-class TryOptions(base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.trycmd.trycmd"
- optParameters = [
- ["connect", "c", None,
- "How to reach the buildmaster, either 'ssh' or 'pb'"],
- # for ssh, use --host, --username, and --jobdir
- ["host", None, None,
- "Hostname (used by ssh) for the buildmaster"],
- ["jobdir", None, None,
- "Directory (on the buildmaster host) where try jobs are deposited"],
- ["username", "u", None,
- "Username performing the try build"],
- # for PB, use --master, --username, and --passwd
- ["master", "m", None,
- "Location of the buildmaster's PBListener (host:port)"],
- ["passwd", None, None,
- "Password for PB authentication"],
- ["who", "w", None,
- "Who is responsible for the try build"],
- ["comment", "C", None,
- "A comment which can be used in notifications for this build"],
-
- # for ssh to accommodate running in a virtualenv on the buildmaster
- ["buildbotbin", None, "buildbot",
- "buildbot binary to use on the buildmaster host"],
-
- ["diff", None, None,
- "Filename of a patch to use instead of scanning a local tree. "
- "Use '-' for stdin."],
- ["patchlevel", "p", 0,
- "Number of slashes to remove from patch pathnames, "
- "like the -p option to 'patch'"],
-
- ["baserev", None, None,
- "Base revision to use instead of scanning a local tree."],
-
- ["vc", None, None,
- "The VC system in use, one of: bzr, cvs, darcs, git, hg, "
- "mtn, p4, svn"],
- ["branch", None, None,
- "The branch in use, for VC systems that can't figure it out "
- "themselves"],
- ["repository", None, None,
- "Repository to use, instead of path to working directory."],
-
- ["builder", "b", None,
- "Run the trial build on this Builder. Can be used multiple times."],
- ["properties", None, None,
- "A set of properties made available in the build environment, "
- "format is --properties=prop1=value1,prop2=value2,.. "
- "option can be specified multiple times."],
- ["property", None, None,
- "A property made available in the build environment, "
- "format:prop=value. Can be used multiple times."],
-
- ["topfile", None, None,
- "Name of a file at the top of the tree, used to find the top. "
- "Only needed for SVN and CVS."],
- ["topdir", None, None,
- "Path to the top of the working copy. Only needed for SVN and CVS."],
- ]
-
- optFlags = [
- ["wait", None,
- "wait until the builds have finished"],
- ["dryrun", 'n',
- "Gather info, but don't actually submit."],
- ["get-builder-names", None,
- "Get the names of available builders. Doesn't submit anything. "
- "Only supported for 'pb' connections."],
- ["quiet", "q",
- "Don't print status of current builds while waiting."],
- ]
-
- # Mapping of .buildbot/options names to command-line options
- buildbotOptions = [
- [ 'try_connect', 'connect' ],
- #[ 'try_builders', 'builders' ], <-- handled in postOptions
- [ 'try_vc', 'vc' ],
- [ 'try_branch', 'branch' ],
- [ 'try_repository', 'repository' ],
- [ 'try_topdir', 'topdir' ],
- [ 'try_topfile', 'topfile' ],
- [ 'try_host', 'host' ],
- [ 'try_username', 'username' ],
- [ 'try_jobdir', 'jobdir' ],
- [ 'try_buildbotbin', 'buildbotbin' ],
- [ 'try_passwd', 'passwd' ],
- [ 'try_master', 'master' ],
- [ 'try_who', 'who' ],
- [ 'try_comment', 'comment' ],
- #[ 'try_wait', 'wait' ], <-- handled in postOptions
- #[ 'try_quiet', 'quiet' ], <-- handled in postOptions
-
- # Deprecated command mappings from the quirky old days:
- [ 'try_masterstatus', 'master' ],
- [ 'try_dir', 'jobdir' ],
- [ 'try_password', 'passwd' ],
- ]
-
- def __init__(self):
- base.SubcommandOptions.__init__(self)
- self['builders'] = []
- self['properties'] = {}
-
- def opt_builder(self, option):
- self['builders'].append(option)
-
- def opt_properties(self, option):
- # We need to split the value of this option into a dictionary of properties
- propertylist = option.split(",")
- for i in range(0,len(propertylist)):
- splitproperty = propertylist[i].split("=", 1)
- self['properties'][splitproperty[0]] = splitproperty[1]
-
- def opt_property(self, option):
- name, _, value = option.partition("=")
- self['properties'][name] = value
-
- def opt_patchlevel(self, option):
- self['patchlevel'] = int(option)
-
- def getSynopsis(self):
- return "Usage: buildbot try [options]"
-
- def postOptions(self):
- base.SubcommandOptions.postOptions(self)
- opts = self.optionsFile
- if not self['builders']:
- self['builders'] = opts.get('try_builders', [])
- if opts.get('try_wait', False):
- self['wait'] = True
- if opts.get('try_quiet', False):
- self['quiet'] = True
- # get the global 'masterstatus' option if it's set and no master
- # was specified otherwise
- if not self['master']:
- self['master'] = opts.get('masterstatus', None)
-
- if self['connect'] == 'pb':
- if not self['master']:
- raise usage.UsageError("master location must be specified" \
- "for 'pb' connections")
- validateMasterOption(self['master'])
-
-
-class TryServerOptions(base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.tryserver.tryserver"
- optParameters = [
- ["jobdir", None, None, "the jobdir (maildir) for submitting jobs"],
- ]
- requiredOptions = [ 'jobdir' ]
-
- def getSynopsis(self):
- return "Usage: buildbot tryserver [options]"
-
- def postOptions(self):
- if not self['jobdir']:
- raise usage.UsageError('jobdir is required')
-
-
-class CheckConfigOptions(base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.checkconfig.checkconfig"
- optFlags = [
- ['quiet', 'q', "Don't display error messages or tracebacks"],
- ]
-
- def getSynopsis(self):
- return "Usage: buildbot checkconfig [configFile]\n" + \
- " If not specified, 'master.cfg' will be used as 'configFile'"
-
- def parseArgs(self, *args):
- if len(args) >= 1:
- self['configFile'] = args[0]
- else:
- self['configFile'] = 'master.cfg'
-
-
-class UserOptions(base.SubcommandOptions):
- subcommandFunction = "buildbot.scripts.user.user"
- optParameters = [
- ["master", "m", None,
- "Location of the buildmaster's PBListener (host:port)"],
- ["username", "u", None,
- "Username for PB authentication"],
- ["passwd", "p", None,
- "Password for PB authentication"],
- ["op", None, None,
- "User management operation: add, remove, update, get"],
- ["bb_username", None, None,
- "Username to set for a given user. Only availabe on 'update', "
- "and bb_password must be given as well."],
- ["bb_password", None, None,
- "Password to set for a given user. Only availabe on 'update', "
- "and bb_username must be given as well."],
- ["ids", None, None,
- "User's identifiers, used to find users in 'remove' and 'get' "
- "Can be specified multiple times (--ids=id1,id2,id3)"],
- ["info", None, None,
- "User information in the form: --info=type=value,type=value,.. "
- "Used in 'add' and 'update', can be specified multiple times. "
- "Note that 'update' requires --info=id:type=value..."]
- ]
- buildbotOptions = [
- [ 'master', 'master' ],
- [ 'user_master', 'master' ],
- [ 'user_username', 'username' ],
- [ 'user_passwd', 'passwd' ],
- ]
- requiredOptions = [ 'master' ]
-
- longdesc = """
- Currently implemented types for --info= are:\n
- git, svn, hg, cvs, darcs, bzr, email
- """
-
- def __init__(self):
- base.SubcommandOptions.__init__(self)
- self['ids'] = []
- self['info'] = []
-
- def opt_ids(self, option):
- id_list = option.split(",")
- self['ids'].extend(id_list)
-
- def opt_info(self, option):
- # splits info into type/value dictionary, appends to info
- info_list = option.split(",")
- info_elem = {}
-
- if len(info_list) == 1 and '=' not in info_list[0]:
- info_elem["identifier"] = info_list[0]
- self['info'].append(info_elem)
- else:
- for i in range(0, len(info_list)):
- split_info = info_list[i].split("=", 1)
-
- # pull identifier from update --info
- if ":" in split_info[0]:
- split_id = split_info[0].split(":")
- info_elem["identifier"] = split_id[0]
- split_info[0] = split_id[1]
-
- info_elem[split_info[0]] = split_info[1]
- self['info'].append(info_elem)
-
- def getSynopsis(self):
- return "Usage: buildbot user [options]"
-
- def _checkValidTypes(self, info):
- from buildbot.process.users import users
- valid = set(['identifier', 'email'] + users.srcs)
-
- for user in info:
- for attr_type in user:
- if attr_type not in valid:
- raise usage.UsageError(
- "Type not a valid attr_type, must be in: %s"
- % ', '.join(valid))
-
- def postOptions(self):
- base.SubcommandOptions.postOptions(self)
-
- validateMasterOption(self.get('master'))
-
- op = self.get('op')
- if not op:
- raise usage.UsageError("you must specify an operation: add, "
- "remove, update, get")
- if op not in ['add', 'remove', 'update', 'get']:
- raise usage.UsageError("bad op %r, use 'add', 'remove', 'update', "
- "or 'get'" % op)
-
- if not self.get('username') or not self.get('passwd'):
- raise usage.UsageError("A username and password must be given")
-
- bb_username = self.get('bb_username')
- bb_password = self.get('bb_password')
- if bb_username or bb_password:
- if op != 'update':
- raise usage.UsageError("bb_username and bb_password only work "
- "with update")
- if not bb_username or not bb_password:
- raise usage.UsageError("Must specify both bb_username and "
- "bb_password or neither.")
-
- info = self.get('info')
- ids = self.get('ids')
-
- # check for erroneous args
- if not info and not ids:
- raise usage.UsageError("must specify either --ids or --info")
-
- if op == 'add' or op == 'update':
- if ids:
- raise usage.UsageError("cannot use --ids with 'add' or "
- "'update'")
- self._checkValidTypes(info)
- if op == 'update':
- for user in info:
- if 'identifier' not in user:
- raise usage.UsageError("no ids found in update info; "
- "use: --info=id:type=value,type=value,..")
- if op == 'add':
- for user in info:
- if 'identifier' in user:
- raise usage.UsageError("identifier found in add info, "
- "use: --info=type=value,type=value,..")
- if op == 'remove' or op == 'get':
- if info:
- raise usage.UsageError("cannot use --info with 'remove' "
- "or 'get'")
-
-
-class Options(usage.Options):
- synopsis = "Usage: buildbot <command> [command options]"
-
- subCommands = [
- ['create-master', None, CreateMasterOptions,
- "Create and populate a directory for a new buildmaster"],
- ['upgrade-master', None, UpgradeMasterOptions,
- "Upgrade an existing buildmaster directory for the current version"],
- ['start', None, StartOptions,
- "Start a buildmaster"],
- ['stop', None, StopOptions,
- "Stop a buildmaster"],
- ['restart', None, RestartOptions,
- "Restart a buildmaster"],
- ['reconfig', None, ReconfigOptions,
- "SIGHUP a buildmaster to make it re-read the config file"],
- ['sighup', None, ReconfigOptions,
- "SIGHUP a buildmaster to make it re-read the config file"],
- ['sendchange', None, SendChangeOptions,
- "Send a change to the buildmaster"],
- ['debugclient', None, DebugClientOptions,
- "Launch a small debug panel GUI"],
- ['statuslog', None, StatusLogOptions,
- "Emit current builder status to stdout"],
- ['statusgui', None, StatusGuiOptions,
- "Display a small window showing current builder status"],
- ['try', None, TryOptions,
- "Run a build with your local changes"],
- ['tryserver', None, TryServerOptions,
- "buildmaster-side 'try' support function, not for users"],
- ['checkconfig', None, CheckConfigOptions,
- "test the validity of a master.cfg config file"],
- ['user', None, UserOptions,
- "Manage users in buildbot's database"]
- ]
-
- def opt_version(self):
- import buildbot
- print "Buildbot version: %s" % buildbot.version
- usage.Options.opt_version(self)
-
- def opt_verbose(self):
- from twisted.python import log
- log.startLogging(sys.stderr)
-
- def postOptions(self):
- if not hasattr(self, 'subOptions'):
- raise usage.UsageError("must specify a command")
-
-
-def run():
- config = Options()
- try:
- config.parseOptions(sys.argv[1:])
- except usage.error, e:
- print "%s: %s" % (sys.argv[0], e)
- print
- c = getattr(config, 'subOptions', config)
- print str(c)
- sys.exit(1)
-
- subconfig = config.subOptions
- subcommandFunction = reflect.namedObject(subconfig.subcommandFunction)
- sys.exit(subcommandFunction(subconfig))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/sample.cfg b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/sample.cfg
deleted file mode 100644
index c461f644..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/sample.cfg
+++ /dev/null
@@ -1,126 +0,0 @@
-# -*- python -*-
-# ex: set syntax=python:
-
-# This is a sample buildmaster config file. It must be installed as
-# 'master.cfg' in your buildmaster's base directory.
-
-# This is the dictionary that the buildmaster pays attention to. We also use
-# a shorter alias to save typing.
-c = BuildmasterConfig = {}
-
-####### BUILDSLAVES
-
-# The 'slaves' list defines the set of recognized buildslaves. Each element is
-# a BuildSlave object, specifying a unique slave name and password. The same
-# slave name and password must be configured on the slave.
-from buildbot.buildslave import BuildSlave
-c['slaves'] = [BuildSlave("example-slave", "pass")]
-
-# 'slavePortnum' defines the TCP port to listen on for connections from slaves.
-# This must match the value configured into the buildslaves (with their
-# --master option)
-c['slavePortnum'] = 9989
-
-####### CHANGESOURCES
-
-# the 'change_source' setting tells the buildmaster how it should find out
-# about source code changes. Here we point to the buildbot clone of pyflakes.
-
-from buildbot.changes.gitpoller import GitPoller
-c['change_source'] = []
-c['change_source'].append(GitPoller(
- 'git://github.com/buildbot/pyflakes.git',
- workdir='gitpoller-workdir', branch='master',
- pollinterval=300))
-
-####### SCHEDULERS
-
-# Configure the Schedulers, which decide how to react to incoming changes. In this
-# case, just kick off a 'runtests' build
-
-from buildbot.schedulers.basic import SingleBranchScheduler
-from buildbot.schedulers.forcesched import ForceScheduler
-from buildbot.changes import filter
-c['schedulers'] = []
-c['schedulers'].append(SingleBranchScheduler(
- name="all",
- change_filter=filter.ChangeFilter(branch='master'),
- treeStableTimer=None,
- builderNames=["runtests"]))
-c['schedulers'].append(ForceScheduler(
- name="force",
- builderNames=["runtests"]))
-
-####### BUILDERS
-
-# The 'builders' list defines the Builders, which tell Buildbot how to perform a build:
-# what steps, and which slaves can execute them. Note that any particular build will
-# only take place on one slave.
-
-from buildbot.process.factory import BuildFactory
-from buildbot.steps.source.git import Git
-from buildbot.steps.shell import ShellCommand
-
-factory = BuildFactory()
-# check out the source
-factory.addStep(Git(repourl='git://github.com/buildbot/pyflakes.git', mode='incremental'))
-# run the tests (note that this will require that 'trial' is installed)
-factory.addStep(ShellCommand(command=["trial", "pyflakes"]))
-
-from buildbot.config import BuilderConfig
-
-c['builders'] = []
-c['builders'].append(
- BuilderConfig(name="runtests",
- slavenames=["example-slave"],
- factory=factory))
-
-####### STATUS TARGETS
-
-# 'status' is a list of Status Targets. The results of each build will be
-# pushed to these targets. buildbot/status/*.py has a variety to choose from,
-# including web pages, email senders, and IRC bots.
-
-c['status'] = []
-
-from buildbot.status import html
-from buildbot.status.web import authz, auth
-
-authz_cfg=authz.Authz(
- # change any of these to True to enable; see the manual for more
- # options
- auth=auth.BasicAuth([("pyflakes","pyflakes")]),
- gracefulShutdown = False,
- forceBuild = 'auth', # use this to test your slave once it is set up
- forceAllBuilds = False,
- pingBuilder = False,
- stopBuild = False,
- stopAllBuilds = False,
- cancelPendingBuild = False,
-)
-c['status'].append(html.WebStatus(http_port=8010, authz=authz_cfg))
-
-####### PROJECT IDENTITY
-
-# the 'title' string will appear at the top of this buildbot
-# installation's html.WebStatus home page (linked to the
-# 'titleURL') and is embedded in the title of the waterfall HTML page.
-
-c['title'] = "Pyflakes"
-c['titleURL'] = "https://launchpad.net/pyflakes"
-
-# the 'buildbotURL' string should point to the location where the buildbot's
-# internal web server (usually the html.WebStatus page) is visible. This
-# typically uses the port number set in the Waterfall 'status' entry, but
-# with an externally-visible host name which the buildbot cannot figure out
-# without some help.
-
-c['buildbotURL'] = "http://localhost:8010/"
-
-####### DB URL
-
-c['db'] = {
- # This specifies what database buildbot uses to store its state. You can leave
- # this at its default for all but the largest installations.
- 'db_url' : "sqlite:///state.sqlite",
-}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/sendchange.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/sendchange.py
deleted file mode 100644
index 480d28dd..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/sendchange.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# 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 sys
-import traceback
-from twisted.internet import defer
-from buildbot.clients import sendchange as sendchange_client
-from buildbot.util import in_reactor
-
-@in_reactor
-@defer.inlineCallbacks
-def sendchange(config):
- encoding = config.get('encoding', 'utf8')
- who = config.get('who')
- auth = config.get('auth')
- master = config.get('master')
- branch = config.get('branch')
- category = config.get('category')
- revision = config.get('revision')
- properties = config.get('properties', {})
- repository = config.get('repository', '')
- vc = config.get('vc', None)
- project = config.get('project', '')
- revlink = config.get('revlink', '')
- when = config.get('when')
- comments = config.get('comments')
- files = config.get('files', ())
- codebase = config.get('codebase', None)
-
- s = sendchange_client.Sender(master, auth, encoding=encoding)
- try:
- yield s.send(branch, revision, comments, files, who=who,
- category=category, when=when, properties=properties,
- repository=repository, vc=vc, project=project, revlink=revlink,
- codebase=codebase)
- except:
- print "change not sent:"
- traceback.print_exc(file=sys.stdout)
- defer.returnValue(1)
- else:
- print "change sent successfully"
- defer.returnValue(0)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/start.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/start.py
deleted file mode 100644
index e49787b5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/start.py
+++ /dev/null
@@ -1,115 +0,0 @@
-# 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 os, sys
-from buildbot.scripts import base
-from twisted.internet import reactor, protocol
-from twisted.python.runtime import platformType
-from buildbot.scripts.logwatcher import LogWatcher
-from buildbot.scripts.logwatcher import BuildmasterTimeoutError
-from buildbot.scripts.logwatcher import ReconfigError
-
-class Follower:
- def follow(self, basedir):
- self.rc = 0
- print "Following twistd.log until startup finished.."
- lw = LogWatcher(os.path.join(basedir, "twistd.log"))
- d = lw.start()
- d.addCallbacks(self._success, self._failure)
- reactor.run()
- return self.rc
-
- def _success(self, _):
- print "The buildmaster appears to have (re)started correctly."
- self.rc = 0
- reactor.stop()
-
- def _failure(self, why):
- if why.check(BuildmasterTimeoutError):
- print """
-The buildmaster took more than 10 seconds to start, so we were unable to
-confirm that it started correctly. Please 'tail twistd.log' and look for a
-line that says 'configuration update complete' to verify correct startup.
-"""
- elif why.check(ReconfigError):
- print """
-The buildmaster appears to have encountered an error in the master.cfg config
-file during startup. Please inspect and fix master.cfg, then restart the
-buildmaster.
-"""
- else:
- print """
-Unable to confirm that the buildmaster started correctly. You may need to
-stop it, fix the config file, and restart.
-"""
- print why
- self.rc = 1
- reactor.stop()
-
-def launchNoDaemon(config):
- os.chdir(config['basedir'])
- sys.path.insert(0, os.path.abspath(config['basedir']))
-
- argv = ["twistd",
- "--no_save",
- '--nodaemon',
- "--logfile=twistd.log", # windows doesn't use the same default
- "--python=buildbot.tac"]
- sys.argv = argv
-
- # this is copied from bin/twistd. twisted-2.0.0 through 2.4.0 use
- # _twistw.run . Twisted-2.5.0 and later use twistd.run, even for
- # windows.
- from twisted.scripts import twistd
- twistd.run()
-
-def launch(config):
- os.chdir(config['basedir'])
- sys.path.insert(0, os.path.abspath(config['basedir']))
-
- # see if we can launch the application without actually having to
- # spawn twistd, since spawning processes correctly is a real hassle
- # on windows.
- argv = [sys.executable,
- "-c",
- # this is copied from bin/twistd. twisted-2.0.0 through 2.4.0 use
- # _twistw.run . Twisted-2.5.0 and later use twistd.run, even for
- # windows.
- "from twisted.scripts import twistd; twistd.run()",
- "--no_save",
- "--logfile=twistd.log", # windows doesn't use the same default
- "--python=buildbot.tac"]
-
- # ProcessProtocol just ignores all output
- reactor.spawnProcess(protocol.ProcessProtocol(), sys.executable, argv, env=os.environ)
-
-def start(config):
- if not base.isBuildmasterDir(config['basedir']):
- return 1
-
- if config['nodaemon']:
- launchNoDaemon(config)
- return 0
-
- launch(config)
-
- # We don't have tail on windows
- if platformType == "win32" or config['quiet']:
- return 0
-
- # this is the parent
- rc = Follower().follow(config['basedir'])
- return rc
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/statusgui.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/statusgui.py
deleted file mode 100644
index bf8ac31f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/statusgui.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# 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
-
-# note that this cannot be run in tests for code coverage, as it requires a
-# different reactor than the default
-
-def statusgui(config):
- from buildbot.clients import gtkPanes
-
- master = config.get('master')
- passwd = config.get('passwd')
- username = config.get('username')
- c = gtkPanes.GtkClient(master, username=username, passwd=passwd)
- c.run()
- return 0
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/statuslog.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/statuslog.py
deleted file mode 100644
index 2c65cc41..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/statuslog.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# 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
-
-# note that this cannot be run in tests for code coverage, as it requires a
-# different reactor than the default
-
-from buildbot.clients import text
-
-def statuslog(config):
- master = config.get('master')
- passwd = config.get('passwd')
- username = config.get('username')
- c = text.TextClient(master, username=username, passwd=passwd)
- c.run()
- return 0
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/stop.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/stop.py
deleted file mode 100644
index 69020a3b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/stop.py
+++ /dev/null
@@ -1,79 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import time
-import os
-import errno
-import signal
-from buildbot.scripts import base
-
-def stop(config, signame="TERM", wait=False):
- basedir = config['basedir']
- quiet = config['quiet']
-
- if config['clean']:
- signame = 'USR1'
-
- if not base.isBuildmasterDir(config['basedir']):
- return 1
-
- pidfile = os.path.join(basedir, 'twistd.pid')
- try:
- with open(pidfile, "rt") as f:
- pid = int(f.read().strip())
- except:
- if not config['quiet']:
- print "buildmaster not running"
- return 0
-
- signum = getattr(signal, "SIG"+signame)
- try:
- os.kill(pid, signum)
- except OSError, e:
- if e.errno != errno.ESRCH:
- raise
- else:
- if not config['quiet']:
- print "buildmaster not running"
- try:
- os.unlink(pidfile)
- except:
- pass
- return 0
-
- if not wait:
- if not quiet:
- print "sent SIG%s to process" % signame
- return 0
-
- time.sleep(0.1)
-
- # poll once per second until twistd.pid goes away, up to 10 seconds,
- # unless we're doing a clean stop, in which case wait forever
- count = 0
- while count < 10 or config['clean']:
- try:
- os.kill(pid, 0)
- except OSError:
- if not quiet:
- print "buildbot process %d is dead" % pid
- return 0
- time.sleep(1)
- count += 1
- if not quiet:
- print "never saw process go away"
- return 1
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/trycmd.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/trycmd.py
deleted file mode 100644
index e4f70cd1..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/trycmd.py
+++ /dev/null
@@ -1,20 +0,0 @@
-# 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
-
-def trycmd(config):
- from buildbot.clients import tryclient
- t = tryclient.Try(config)
- t.run()
- return 0
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/tryserver.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/tryserver.py
deleted file mode 100644
index 713cdacb..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/tryserver.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os
-import sys
-import time
-from hashlib import md5
-
-def tryserver(config):
- jobdir = os.path.expanduser(config["jobdir"])
- job = sys.stdin.read()
- # now do a 'safecat'-style write to jobdir/tmp, then move atomically to
- # jobdir/new . Rather than come up with a unique name randomly, I'm just
- # going to MD5 the contents and prepend a timestamp.
- timestring = "%d" % time.time()
- m = md5()
- m.update(job)
- jobhash = m.hexdigest()
- fn = "%s-%s" % (timestring, jobhash)
- tmpfile = os.path.join(jobdir, "tmp", fn)
- newfile = os.path.join(jobdir, "new", fn)
- with open(tmpfile, "w") as f:
- f.write(job)
- os.rename(tmpfile, newfile)
-
- return 0
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/upgrade_master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/upgrade_master.py
deleted file mode 100644
index c471965d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/upgrade_master.py
+++ /dev/null
@@ -1,180 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os
-import sys
-import traceback
-from twisted.internet import defer
-from twisted.python import util, runtime
-from buildbot import config as config_module
-from buildbot import monkeypatches
-from buildbot.db import connector
-from buildbot.master import BuildMaster
-from buildbot.util import in_reactor
-from buildbot.scripts import base
-
-def checkBasedir(config):
- if not config['quiet']:
- print "checking basedir"
-
- if not base.isBuildmasterDir(config['basedir']):
- return False
-
- if runtime.platformType != 'win32': # no pids on win32
- if not config['quiet']:
- print "checking for running master"
- pidfile = os.path.join(config['basedir'], 'twistd.pid')
- if os.path.exists(pidfile):
- print "'%s' exists - is this master still running?" % (pidfile,)
- return False
-
- return True
-
-def loadConfig(config, configFileName='master.cfg'):
- if not config['quiet']:
- print "checking %s" % configFileName
-
- try:
- master_cfg = config_module.MasterConfig.loadConfig(
- config['basedir'], configFileName)
- except config_module.ConfigErrors, e:
- print "Errors loading configuration:"
- for msg in e.errors:
- print " " + msg
- return
- except:
- print "Errors loading configuration:"
- traceback.print_exc(file=sys.stdout)
- return
-
- return master_cfg
-
-def installFile(config, target, source, overwrite=False):
- with open(source, "rt") as f:
- new_contents = f.read()
- if os.path.exists(target):
- with open(target, "rt") as f:
- old_contents = f.read()
- if old_contents != new_contents:
- if overwrite:
- if not config['quiet']:
- print "%s has old/modified contents" % target
- print " overwriting it with new contents"
- with open(target, "wt") as f:
- f.write(new_contents)
- else:
- if not config['quiet']:
- print "%s has old/modified contents" % target
- print " writing new contents to %s.new" % target
- with open(target + ".new", "wt") as f:
- f.write(new_contents)
- # otherwise, it's up to date
- else:
- if not config['quiet']:
- print "creating %s" % target
- with open(target, "wt") as f:
- f.write(new_contents)
-
-def upgradeFiles(config):
- if not config['quiet']:
- print "upgrading basedir"
-
- webdir = os.path.join(config['basedir'], "public_html")
- if not os.path.exists(webdir):
- if not config['quiet']:
- print "creating public_html"
- os.mkdir(webdir)
-
- templdir = os.path.join(config['basedir'], "templates")
- if not os.path.exists(templdir):
- if not config['quiet']:
- print "creating templates"
- os.mkdir(templdir)
-
- for file in ('bg_gradient.jpg', 'default.css',
- 'robots.txt', 'favicon.ico'):
- source = util.sibpath(__file__, "../status/web/files/%s" % (file,))
- target = os.path.join(webdir, file)
- try:
- installFile(config, target, source)
- except IOError:
- print "Can't write '%s'." % (target,)
-
- installFile(config, os.path.join(config['basedir'], "master.cfg.sample"),
- util.sibpath(__file__, "sample.cfg"), overwrite=True)
-
- # if index.html exists, use it to override the root page tempalte
- index_html = os.path.join(webdir, "index.html")
- root_html = os.path.join(templdir, "root.html")
- if os.path.exists(index_html):
- if os.path.exists(root_html):
- print "Notice: %s now overrides %s" % (root_html, index_html)
- print " as the latter is not used by buildbot anymore."
- print " Decide which one you want to keep."
- else:
- try:
- print "Notice: Moving %s to %s." % (index_html, root_html)
- print " You can (and probably want to) remove it if " \
- "you haven't modified this file."
- os.renames(index_html, root_html)
- except Exception, e:
- print "Error moving %s to %s: %s" % (index_html, root_html,
- str(e))
-
-@defer.inlineCallbacks
-def upgradeDatabase(config, master_cfg):
- if not config['quiet']:
- print "upgrading database (%s)" % (master_cfg.db['db_url'])
-
- master = BuildMaster(config['basedir'])
- master.config = master_cfg
- db = connector.DBConnector(master, basedir=config['basedir'])
-
- yield db.setup(check_version=False, verbose=not config['quiet'])
- yield db.model.upgrade()
-
-@in_reactor
-@defer.inlineCallbacks
-def upgradeMaster(config, _noMonkey=False):
- if not _noMonkey: # pragma: no cover
- monkeypatches.patch_all()
-
- if not checkBasedir(config):
- defer.returnValue(1)
- return
-
- os.chdir(config['basedir'])
-
- try:
- configFile = base.getConfigFileFromTac(config['basedir'])
- except (SyntaxError, ImportError), e:
- print "Unable to load 'buildbot.tac' from '%s':" % config['basedir']
- print e
- defer.returnValue(1)
- return
- master_cfg = loadConfig(config, configFile)
- if not master_cfg:
- defer.returnValue(1)
- return
-
- upgradeFiles(config)
- yield upgradeDatabase(config, master_cfg)
-
- if not config['quiet']:
- print "upgrade complete"
-
- defer.returnValue(0)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/user.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/user.py
deleted file mode 100644
index 4f231e76..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/scripts/user.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# 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
-
-from twisted.internet import defer
-from buildbot.clients import usersclient
-from buildbot.process.users import users
-from buildbot.util import in_reactor
-
-@in_reactor
-@defer.inlineCallbacks
-def user(config):
-
- master = config.get('master')
- op = config.get('op')
- username = config.get('username')
- passwd = config.get('passwd')
- master, port = master.split(":")
- port = int(port)
- bb_username = config.get('bb_username')
- bb_password = config.get('bb_password')
- if bb_username or bb_password:
- bb_password = users.encrypt(bb_password)
- info = config.get('info')
- ids = config.get('ids')
-
- # find identifier if op == add
- if info and op == 'add':
- for user in info:
- user['identifier'] = sorted(user.values())[0]
-
- uc = usersclient.UsersClient(master, username, passwd, port)
- output = yield uc.send(op, bb_username, bb_password, ids, info)
- if output:
- print output
-
- defer.returnValue(0)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/sourcestamp.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/sourcestamp.py
deleted file mode 100644
index bb4042ce..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/sourcestamp.py
+++ /dev/null
@@ -1,359 +0,0 @@
-# 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
-
-
-from zope.interface import implements
-from twisted.persisted import styles
-from twisted.internet import defer
-from buildbot.changes.changes import Change
-from buildbot import util, interfaces
-# TODO: kill this class, or at least make it less significant
-class SourceStamp(util.ComparableMixin, styles.Versioned):
- """This is a tuple of (branch, revision, patchspec, changes, project, repository).
-
- C{branch} is always valid, although it may be None to let the Source
- step use its default branch. There are three possibilities for the
- remaining elements:
- - (revision=REV, patchspec=None, changes=None): build REV. If REV is
- None, build the HEAD revision from the given branch. Note that REV
- must always be a string: SVN, Perforce, and other systems which use
- integers should provide a string here, but the Source checkout step
- will integerize it when making comparisons.
- - (revision=REV, patchspec=(LEVEL, DIFF), changes=None): checkout REV,
- then apply a patch to the source, with C{patch -pLEVEL <DIFF}.
- If REV is None, checkout HEAD and patch it.
- - (revision=None, patchspec=None, changes=[CHANGES]): let the Source
- step check out the latest revision indicated by the given Changes.
- CHANGES is a tuple of L{buildbot.changes.changes.Change} instances,
- and all must be on the same branch.
-
- @ivar ssid: sourcestamp ID, or None if this sourcestamp has not yet been
- added to the database
-
- @ivar branch: branch name or None
-
- @ivar revision: revision string or None
-
- @ivar patch: tuple (patch level, patch body) or None
-
- @ivar patch_info: tuple (patch author, patch comment) or None
-
- @ivar changes: tuple of changes that went into this source stamp, sorted by
- number
-
- @ivar project: project name
-
- @ivar repository: repository URL
- """
-
- persistenceVersion = 3
- persistenceForgets = ( 'wasUpgraded', )
-
- # all seven of these are publicly visible attributes
- branch = None
- revision = None
- patch = None
- patch_info = None
- changes = ()
- project = ''
- repository = ''
- codebase = ''
- sourcestampsetid = None
- ssid = None
-
- compare_attrs = ('branch', 'revision', 'patch', 'patch_info', 'changes', 'project', 'repository', 'codebase')
-
- implements(interfaces.ISourceStamp)
-
- @classmethod
- def fromSsdict(cls, master, ssdict):
- """
- Class method to create a L{SourceStamp} from a dictionary as returned
- by L{SourceStampConnectorComponent.getSourceStamp}.
-
- @param master: build master instance
- @param ssdict: source stamp dictionary
-
- @returns: L{SourceStamp} via Deferred
- """
- # try to fetch from the cache, falling back to _make_ss if not
- # found
- cache = master.caches.get_cache("SourceStamps", cls._make_ss)
- return cache.get(ssdict['ssid'], ssdict=ssdict, master=master)
-
- @classmethod
- def _make_ss(cls, ssid, ssdict, master):
- sourcestamp = cls(_fromSsdict=True)
- sourcestamp.ssid = ssid
- sourcestamp.branch = ssdict['branch']
- sourcestamp.revision = ssdict['revision']
- sourcestamp.project = ssdict['project']
- sourcestamp.repository = ssdict['repository']
- sourcestamp.codebase = ssdict['codebase']
- sourcestamp.sourcestampsetid = ssdict['sourcestampsetid']
-
- sourcestamp.patch = None
- if ssdict['patch_body']:
- sourcestamp.patch = (ssdict['patch_level'], ssdict['patch_body'],
- ssdict.get('patch_subdir'))
- sourcestamp.patch_info = (ssdict['patch_author'],
- ssdict['patch_comment'])
-
- if ssdict['changeids']:
- # sort the changeids in order, oldest to newest
- sorted_changeids = sorted(ssdict['changeids'])
- def gci(id):
- d = master.db.changes.getChange(id)
- d.addCallback(lambda chdict :
- Change.fromChdict(master, chdict))
- return d
- d = defer.gatherResults([ gci(id)
- for id in sorted_changeids ])
- else:
- d = defer.succeed([])
- def got_changes(changes):
- sourcestamp.changes = tuple(changes)
- return sourcestamp
- d.addCallback(got_changes)
- return d
-
- def __init__(self, branch=None, revision=None, patch=None, sourcestampsetid=None,
- patch_info=None, changes=None, project='', repository='',
- codebase = '', _fromSsdict=False, _ignoreChanges=False):
- self._addSourceStampToDatabase_lock = defer.DeferredLock();
-
- # skip all this madness if we're being built from the database
- if _fromSsdict:
- return
-
- if patch is not None:
- assert 2 <= len(patch) <= 3
- assert int(patch[0]) != -1
- self.sourcestampsetid = sourcestampsetid
- self.branch = branch
- self.patch = patch
- self.patch_info = patch_info
- self.project = project or ''
- self.repository = repository or ''
- self.codebase = codebase or ''
- if changes:
- self.changes = changes = list(changes)
- changes.sort()
- if not _ignoreChanges:
- # set branch and revision to most recent change
- self.branch = changes[-1].branch
- revision = changes[-1].revision
- if not self.project and hasattr(changes[-1], 'project'):
- self.project = changes[-1].project
- if not self.repository and hasattr(changes[-1], 'repository'):
- self.repository = changes[-1].repository
-
- if revision is not None:
- if isinstance(revision, int):
- revision = str(revision)
-
- self.revision = revision
-
- def canBeMergedWith(self, other):
- # this algorithm implements the "compatible" mergeRequests defined in
- # detail in cfg-buidlers.texinfo; change that documentation if the
- # algorithm changes!
- if other.codebase != self.codebase:
- return False
- if other.repository != self.repository:
- return False
- if other.branch != self.branch:
- return False # the builds are completely unrelated
- if other.project != self.project:
- return False
- if self.patch or other.patch:
- # you can't merge patched builds with anything else
- return self is other
-
- if self.changes and other.changes:
- return True
- elif self.changes and not other.changes:
- return False # we're using changes, they aren't
- elif not self.changes and other.changes:
- return False # they're using changes, we aren't
-
- if self.revision == other.revision:
- # both builds are using the same specific revision, so they can
- # be merged. It might be the case that revision==None, so they're
- # both building HEAD.
- return True
-
- return False
-
- def mergeWith(self, others):
- """Generate a SourceStamp for the merger of me and all the other
- SourceStamps. This is called by a Build when it starts, to figure
- out what its sourceStamp should be."""
-
- # either we're all building the same thing (changes==None), or we're
- # all building changes (which can be merged)
- changes = []
- changes.extend(self.changes)
- for ss in others:
- changes.extend(ss.changes)
- newsource = SourceStamp(sourcestampsetid=self.sourcestampsetid,
- branch=self.branch,
- revision=self.revision,
- patch=self.patch,
- patch_info=self.patch_info,
- project=self.project,
- repository=self.repository,
- codebase=self.codebase,
- changes=changes)
- return newsource
-
- def clone(self):
- # Create an exact but identityless copy
- return SourceStamp(branch=self.branch, revision=self.revision,
- patch=self.patch, repository=self.repository,
- codebase=self.codebase, patch_info=self.patch_info,
- project=self.project, changes=self.changes,
- _ignoreChanges=True)
-
- def getAbsoluteSourceStamp(self, got_revision):
- cloned = self.clone()
- cloned.revision = got_revision
- return cloned
-
- def getText(self):
- # note: this won't work for VC systems with huge 'revision' strings
- text = []
- if self.project:
- text.append("for %s" % self.project)
- if self.repository:
- text.append("in %s" % self.repository)
- if self.codebase:
- text.append("(%s)" % self.codebase)
- if self.revision is None:
- return text + [ "latest" ]
- text.append(str(self.revision))
- if self.branch:
- text.append("in '%s'" % self.branch)
- if self.patch:
- text.append("[patch]")
- return text
-
- def asDict(self):
- result = {}
- # Constant
- result['revision'] = self.revision
-
- # TODO(maruel): Make the patch content a suburl.
- result['hasPatch'] = self.patch is not None
- if self.patch:
- result['patch_level'] = self.patch[0]
- result['patch_body'] = self.patch[1]
- if len(self.patch) > 2:
- result['patch_subdir'] = self.patch[2]
- if self.patch_info:
- result['patch_author'] = self.patch_info[0]
- result['patch_comment'] = self.patch_info[1]
-
- result['branch'] = self.branch
- result['changes'] = [c.asDict() for c in getattr(self, 'changes', [])]
- result['project'] = self.project
- result['repository'] = self.repository
- result['codebase'] = self.codebase
- return result
-
- def __setstate__(self, d):
- styles.Versioned.__setstate__(self, d)
- self._addSourceStampToDatabase_lock = defer.DeferredLock();
-
- def upgradeToVersion1(self):
- # version 0 was untyped; in version 1 and later, types matter.
- if self.branch is not None and not isinstance(self.branch, str):
- self.branch = str(self.branch)
- if self.revision is not None and not isinstance(self.revision, str):
- self.revision = str(self.revision)
- if self.patch is not None:
- self.patch = ( int(self.patch[0]), str(self.patch[1]) )
- self.wasUpgraded = True
-
- def upgradeToVersion2(self):
- # version 1 did not have project or repository; just set them to a default ''
- self.project = ''
- self.repository = ''
- self.wasUpgraded = True
-
- def upgradeToVersion3(self):
- #The database has been upgraded where all existing sourcestamps got an
- #setid equal to its ssid
- self.sourcestampsetid = self.ssid
- #version 2 did not have codebase; set to ''
- self.codebase = ''
- self.wasUpgraded = True
-
- def getSourceStampSetId(self, master):
- "temporary; do not use widely!"
- if self.sourcestampsetid:
- return defer.succeed(self.sourcestampsetid)
- else:
- return self.addSourceStampToDatabase(master)
-
-
- @util.deferredLocked('_addSourceStampToDatabase_lock')
- def addSourceStampToDatabase(self, master, sourcestampsetid = None):
- # add it to the DB
- patch_body = None
- patch_level = None
- patch_subdir = None
- if self.patch:
- patch_level = self.patch[0]
- patch_body = self.patch[1]
- if len(self.patch) > 2:
- patch_subdir = self.patch[2]
-
- patch_author = None
- patch_comment = None
- if self.patch_info:
- patch_author, patch_comment = self.patch_info
-
- def get_setid():
- if sourcestampsetid is not None:
- return defer.succeed( sourcestampsetid )
- else:
- return master.db.sourcestampsets.addSourceStampSet()
-
- def set_setid(setid):
- self.sourcestampsetid = setid
- return setid
-
- def add_sourcestamp(setid):
- return master.db.sourcestamps.addSourceStamp(
- sourcestampsetid=setid,
- branch=self.branch, revision=self.revision,
- repository=self.repository, codebase=self.codebase,
- project=self.project,
- patch_body=patch_body, patch_level=patch_level,
- patch_author=patch_author, patch_comment=patch_comment,
- patch_subdir=patch_subdir,
- changeids=[c.number for c in self.changes])
-
- def set_ssid(ssid):
- self.ssid = ssid
- return ssid
-
- d = get_setid()
- d.addCallback(set_setid)
- d.addCallback(add_sourcestamp)
- d.addCallback(set_ssid)
- d.addCallback(lambda _ : self.sourcestampsetid)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/__init__.py
deleted file mode 100644
index 080f18f1..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/__init__.py
+++ /dev/null
@@ -1,19 +0,0 @@
-import build, builder, buildstep, buildset, testresult, logfile
-import slave, master, buildrequest
-
-# styles.Versioned requires this, as it keys the version numbers on the fully
-# qualified class name; see master/buildbot/test/regressions/test_unpickling.py
-buildstep.BuildStepStatus.__module__ = 'buildbot.status.builder'
-build.BuildStatus.__module__ = 'buildbot.status.builder'
-
-# add all of these classes to builder; this is a form of late binding to allow
-# circular module references among the status modules
-builder.BuildStepStatus = buildstep.BuildStepStatus
-builder.BuildSetStatus = buildset.BuildSetStatus
-builder.TestResult = testresult.TestResult
-builder.LogFile = logfile.LogFile
-builder.HTMLLogFile = logfile.HTMLLogFile
-builder.SlaveStatus = slave.SlaveStatus
-builder.Status = master.Status
-builder.BuildStatus = build.BuildStatus
-builder.BuildRequestStatus = buildrequest.BuildRequestStatus
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/base.py
deleted file mode 100644
index 5efaf20f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/base.py
+++ /dev/null
@@ -1,104 +0,0 @@
-# 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
-
-
-from zope.interface import implements
-from twisted.application import service
-
-from buildbot.interfaces import IStatusReceiver
-from buildbot import util, pbutil
-
-class StatusReceiverBase:
- implements(IStatusReceiver)
-
- def requestSubmitted(self, request):
- pass
-
- def requestCancelled(self, builder, request):
- pass
-
- def buildsetSubmitted(self, buildset):
- pass
-
- def builderAdded(self, builderName, builder):
- pass
-
- def builderChangedState(self, builderName, state):
- pass
-
- def buildStarted(self, builderName, build):
- pass
-
- def buildETAUpdate(self, build, ETA):
- pass
-
- def changeAdded(self, change):
- pass
-
- def stepStarted(self, build, step):
- pass
-
- def stepTextChanged(self, build, step, text):
- pass
-
- def stepText2Changed(self, build, step, text2):
- pass
-
- def stepETAUpdate(self, build, step, ETA, expectations):
- pass
-
- def logStarted(self, build, step, log):
- pass
-
- def logChunk(self, build, step, log, channel, text):
- pass
-
- def logFinished(self, build, step, log):
- pass
-
- def stepFinished(self, build, step, results):
- pass
-
- def buildFinished(self, builderName, build, results):
- pass
-
- def builderRemoved(self, builderName):
- pass
-
- def slaveConnected(self, slaveName):
- pass
-
- def slaveDisconnected(self, slaveName):
- pass
-
- def checkConfig(self, otherStatusReceivers):
- pass
-
-class StatusReceiverMultiService(StatusReceiverBase, service.MultiService,
- util.ComparableMixin):
-
- def __init__(self):
- service.MultiService.__init__(self)
-
-class StatusReceiverService(StatusReceiverBase, service.Service,
- util.ComparableMixin):
- pass
-
-StatusReceiver = StatusReceiverService
-
-
-class StatusReceiverPerspective(StatusReceiver, pbutil.NewCredPerspective):
- implements(IStatusReceiver)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/build.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/build.py
deleted file mode 100644
index d1efa96d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/build.py
+++ /dev/null
@@ -1,479 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os, shutil, re
-from cPickle import dump
-from zope.interface import implements
-from twisted.python import log, runtime, components
-from twisted.persisted import styles
-from twisted.internet import reactor, defer
-from buildbot import interfaces, util, sourcestamp
-from buildbot.process import properties
-from buildbot.status.buildstep import BuildStepStatus
-
-class BuildStatus(styles.Versioned, properties.PropertiesMixin):
- implements(interfaces.IBuildStatus, interfaces.IStatusEvent)
-
- persistenceVersion = 4
- persistenceForgets = ( 'wasUpgraded', )
-
- sources = None
- reason = None
- changes = []
- blamelist = []
- progress = None
- started = None
- finished = None
- currentStep = None
- text = []
- results = None
- slavename = "???"
-
- set_runtime_properties = True
-
- # these lists/dicts are defined here so that unserialized instances have
- # (empty) values. They are set in __init__ to new objects to make sure
- # each instance gets its own copy.
- watchers = []
- updates = {}
- finishedWatchers = []
- testResults = {}
-
- def __init__(self, parent, master, number):
- """
- @type parent: L{BuilderStatus}
- @type number: int
- """
- assert interfaces.IBuilderStatus(parent)
- self.builder = parent
- self.master = master
- self.number = number
- self.watchers = []
- self.updates = {}
- self.finishedWatchers = []
- self.steps = []
- self.testResults = {}
- self.properties = properties.Properties()
-
- def __repr__(self):
- return "<%s #%s>" % (self.__class__.__name__, self.number)
-
- # IBuildStatus
-
- def getBuilder(self):
- """
- @rtype: L{BuilderStatus}
- """
- return self.builder
-
- def getNumber(self):
- return self.number
-
- def getPreviousBuild(self):
- if self.number == 0:
- return None
- return self.builder.getBuild(self.number-1)
-
- def getAllGotRevisions(self):
- all_got_revisions = self.properties.getProperty('got_revision', {})
- # For backwards compatibility all_got_revisions is a string if codebases
- # are not used. Convert to the default internal type (dict)
- if not isinstance(all_got_revisions, dict):
- all_got_revisions = {'': all_got_revisions}
- return all_got_revisions
-
- def getSourceStamps(self, absolute=False):
- sourcestamps = []
- if not absolute:
- sourcestamps.extend(self.sources)
- else:
- all_got_revisions = self.getAllGotRevisions() or {}
- # always make a new instance
- for ss in self.sources:
- if ss.codebase in all_got_revisions:
- got_revision = all_got_revisions[ss.codebase]
- sourcestamps.append(ss.getAbsoluteSourceStamp(got_revision))
- else:
- # No absolute revision information available
- # Probably build has been stopped before ending all sourcesteps
- # Return a clone with original revision
- sourcestamps.append(ss.clone())
- return sourcestamps
-
- def getReason(self):
- return self.reason
-
- def getChanges(self):
- return self.changes
-
- def getRevisions(self):
- revs = []
- for c in self.changes:
- rev = str(c.revision)
- if rev > 7: # for long hashes
- rev = rev[:7]
- revs.append(rev)
- return ", ".join(revs)
-
- def getResponsibleUsers(self):
- return self.blamelist
-
- def getInterestedUsers(self):
- # TODO: the Builder should add others: sheriffs, domain-owners
- return self.properties.getProperty('owners', [])
-
- def getSteps(self):
- """Return a list of IBuildStepStatus objects. For invariant builds
- (those which always use the same set of Steps), this should be the
- complete list, however some of the steps may not have started yet
- (step.getTimes()[0] will be None). For variant builds, this may not
- be complete (asking again later may give you more of them)."""
- return self.steps
-
- def getTimes(self):
- return (self.started, self.finished)
-
- _sentinel = [] # used as a sentinel to indicate unspecified initial_value
- def getSummaryStatistic(self, name, summary_fn, initial_value=_sentinel):
- """Summarize the named statistic over all steps in which it
- exists, using combination_fn and initial_value to combine multiple
- results into a single result. This translates to a call to Python's
- X{reduce}::
- return reduce(summary_fn, step_stats_list, initial_value)
- """
- step_stats_list = [
- st.getStatistic(name)
- for st in self.steps
- if st.hasStatistic(name) ]
- if initial_value is self._sentinel:
- return reduce(summary_fn, step_stats_list)
- else:
- return reduce(summary_fn, step_stats_list, initial_value)
-
- def isFinished(self):
- return (self.finished is not None)
-
- def waitUntilFinished(self):
- if self.finished:
- d = defer.succeed(self)
- else:
- d = defer.Deferred()
- self.finishedWatchers.append(d)
- return d
-
- # while the build is running, the following methods make sense.
- # Afterwards they return None
-
- def getETA(self):
- if self.finished is not None:
- return None
- if not self.progress:
- return None
- eta = self.progress.eta()
- if eta is None:
- return None
- return eta - util.now()
-
- def getCurrentStep(self):
- return self.currentStep
-
- # Once you know the build has finished, the following methods are legal.
- # Before ths build has finished, they all return None.
-
- def getText(self):
- text = []
- text.extend(self.text)
- for s in self.steps:
- text.extend(s.text2)
- return text
-
- def getResults(self):
- return self.results
-
- def getSlavename(self):
- return self.slavename
-
- def getTestResults(self):
- return self.testResults
-
- def getLogs(self):
- logs = []
- for s in self.steps:
- for loog in s.getLogs():
- logs.append(loog)
- return logs
-
- # subscription interface
-
- def subscribe(self, receiver, updateInterval=None):
- # will receive stepStarted and stepFinished messages
- # and maybe buildETAUpdate
- self.watchers.append(receiver)
- if updateInterval is not None:
- self.sendETAUpdate(receiver, updateInterval)
-
- def sendETAUpdate(self, receiver, updateInterval):
- self.updates[receiver] = None
- ETA = self.getETA()
- if ETA is not None:
- receiver.buildETAUpdate(self, self.getETA())
- # they might have unsubscribed during buildETAUpdate
- if receiver in self.watchers:
- self.updates[receiver] = reactor.callLater(updateInterval,
- self.sendETAUpdate,
- receiver,
- updateInterval)
-
- def unsubscribe(self, receiver):
- if receiver in self.watchers:
- self.watchers.remove(receiver)
- if receiver in self.updates:
- if self.updates[receiver] is not None:
- self.updates[receiver].cancel()
- del self.updates[receiver]
-
- # methods for the base.Build to invoke
-
- def addStepWithName(self, name):
- """The Build is setting up, and has added a new BuildStep to its
- list. Create a BuildStepStatus object to which it can send status
- updates."""
-
- s = BuildStepStatus(self, self.master, len(self.steps))
- s.setName(name)
- self.steps.append(s)
- return s
-
- def addTestResult(self, result):
- self.testResults[result.getName()] = result
-
- def setSourceStamps(self, sourceStamps):
- self.sources = sourceStamps
- self.changes = []
- for source in self.sources:
- self.changes.extend(source.changes)
-
- def setReason(self, reason):
- self.reason = reason
- def setBlamelist(self, blamelist):
- self.blamelist = blamelist
- def setProgress(self, progress):
- self.progress = progress
-
- def buildStarted(self, build):
- """The Build has been set up and is about to be started. It can now
- be safely queried, so it is time to announce the new build."""
-
- self.started = util.now()
- # now that we're ready to report status, let the BuilderStatus tell
- # the world about us
- self.builder.buildStarted(self)
-
- def setSlavename(self, slavename):
- self.slavename = slavename
-
- def setText(self, text):
- assert isinstance(text, (list, tuple))
- self.text = text
- def setResults(self, results):
- self.results = results
-
- def buildFinished(self):
- self.currentStep = None
- self.finished = util.now()
-
- for r in self.updates.keys():
- if self.updates[r] is not None:
- self.updates[r].cancel()
- del self.updates[r]
-
- watchers = self.finishedWatchers
- self.finishedWatchers = []
- for w in watchers:
- w.callback(self)
-
- # methods called by our BuildStepStatus children
-
- def stepStarted(self, step):
- self.currentStep = step
- for w in self.watchers:
- receiver = w.stepStarted(self, step)
- if receiver:
- if type(receiver) == type(()):
- step.subscribe(receiver[0], receiver[1])
- else:
- step.subscribe(receiver)
- d = step.waitUntilFinished()
- d.addCallback(lambda step: step.unsubscribe(receiver))
-
- step.waitUntilFinished().addCallback(self._stepFinished)
-
- def _stepFinished(self, step):
- results = step.getResults()
- for w in self.watchers:
- w.stepFinished(self, step, results)
-
- # methods called by our BuilderStatus parent
-
- def pruneSteps(self):
- # this build is very old: remove the build steps too
- self.steps = []
-
- # persistence stuff
-
- def generateLogfileName(self, stepname, logname):
- """Return a filename (relative to the Builder's base directory) where
- the logfile's contents can be stored uniquely.
-
- The base filename is made by combining our build number, the Step's
- name, and the log's name, then removing unsuitable characters. The
- filename is then made unique by appending _0, _1, etc, until it does
- not collide with any other logfile.
-
- These files are kept in the Builder's basedir (rather than a
- per-Build subdirectory) because that makes cleanup easier: cron and
- find will help get rid of the old logs, but the empty directories are
- more of a hassle to remove."""
-
- starting_filename = "%d-log-%s-%s" % (self.number, stepname, logname)
- starting_filename = re.sub(r'[^\w\.\-]', '_', starting_filename)
- # now make it unique
- unique_counter = 0
- filename = starting_filename
- while filename in [l.filename
- for step in self.steps
- for l in step.getLogs()
- if l.filename]:
- filename = "%s_%d" % (starting_filename, unique_counter)
- unique_counter += 1
- return filename
-
- def __getstate__(self):
- d = styles.Versioned.__getstate__(self)
- # for now, a serialized Build is always "finished". We will never
- # save unfinished builds.
- if not self.finished:
- d['finished'] = util.now()
- # TODO: push an "interrupted" step so it is clear that the build
- # was interrupted. The builder will have a 'shutdown' event, but
- # someone looking at just this build will be confused as to why
- # the last log is truncated.
- for k in [ 'builder', 'watchers', 'updates', 'finishedWatchers',
- 'master' ]:
- if k in d: del d[k]
- return d
-
- def __setstate__(self, d):
- styles.Versioned.__setstate__(self, d)
- self.watchers = []
- self.updates = {}
- self.finishedWatchers = []
-
- def setProcessObjects(self, builder, master):
- self.builder = builder
- self.master = master
- for step in self.steps:
- step.setProcessObjects(self, master)
- def upgradeToVersion1(self):
- if hasattr(self, "sourceStamp"):
- # the old .sourceStamp attribute wasn't actually very useful
- maxChangeNumber, patch = self.sourceStamp
- changes = getattr(self, 'changes', [])
- source = sourcestamp.SourceStamp(branch=None,
- revision=None,
- patch=patch,
- changes=changes)
- self.source = source
- self.changes = source.changes
- del self.sourceStamp
- self.wasUpgraded = True
-
- def upgradeToVersion2(self):
- self.properties = {}
- self.wasUpgraded = True
-
- def upgradeToVersion3(self):
- # in version 3, self.properties became a Properties object
- propdict = self.properties
- self.properties = properties.Properties()
- self.properties.update(propdict, "Upgrade from previous version")
- self.wasUpgraded = True
-
- def upgradeToVersion4(self):
- # buildstatus contains list of sourcestamps, convert single to list
- if hasattr(self, "source"):
- self.sources = [self.source]
- del self.source
- self.wasUpgraded = True
-
- def checkLogfiles(self):
- # check that all logfiles exist, and remove references to any that
- # have been deleted (e.g., by purge())
- for s in self.steps:
- s.checkLogfiles()
-
- def saveYourself(self):
- filename = os.path.join(self.builder.basedir, "%d" % self.number)
- if os.path.isdir(filename):
- # leftover from 0.5.0, which stored builds in directories
- shutil.rmtree(filename, ignore_errors=True)
- tmpfilename = filename + ".tmp"
- try:
- with open(tmpfilename, "wb") as f:
- dump(self, f, -1)
- if runtime.platformType == 'win32':
- # windows cannot rename a file on top of an existing one, so
- # fall back to delete-first. There are ways this can fail and
- # lose the builder's history, so we avoid using it in the
- # general (non-windows) case
- if os.path.exists(filename):
- os.unlink(filename)
- os.rename(tmpfilename, filename)
- except:
- log.msg("unable to save build %s-#%d" % (self.builder.name,
- self.number))
- log.err()
-
- def asDict(self):
- result = {}
- # Constant
- result['builderName'] = self.builder.name
- result['number'] = self.getNumber()
- result['sourceStamps'] = [ss.asDict() for ss in self.getSourceStamps()]
- result['reason'] = self.getReason()
- result['blame'] = self.getResponsibleUsers()
-
- # Transient
- result['properties'] = self.getProperties().asList()
- result['times'] = self.getTimes()
- result['text'] = self.getText()
- result['results'] = self.getResults()
- result['slave'] = self.getSlavename()
- # TODO(maruel): Add.
- #result['test_results'] = self.getTestResults()
- result['logs'] = [[l.getName(),
- self.builder.status.getURLForThing(l)] for l in self.getLogs()]
- result['eta'] = self.getETA()
- result['steps'] = [bss.asDict() for bss in self.steps]
- if self.getCurrentStep():
- result['currentStep'] = self.getCurrentStep().asDict()
- else:
- result['currentStep'] = None
- return result
-
-components.registerAdapter(lambda build_status : build_status.properties,
- BuildStatus, interfaces.IProperties)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/builder.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/builder.py
deleted file mode 100644
index 8430d13e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/builder.py
+++ /dev/null
@@ -1,583 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-
-import os, re, itertools
-from cPickle import load, dump
-
-from zope.interface import implements
-from twisted.python import log, runtime
-from twisted.persisted import styles
-from buildbot import interfaces, util
-from buildbot.util.lru import LRUCache
-from buildbot.status.event import Event
-from buildbot.status.build import BuildStatus
-from buildbot.status.buildrequest import BuildRequestStatus
-
-# user modules expect these symbols to be present here
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE, SKIPPED
-from buildbot.status.results import EXCEPTION, RETRY, Results, worst_status
-_hush_pyflakes = [ SUCCESS, WARNINGS, FAILURE, SKIPPED,
- EXCEPTION, RETRY, Results, worst_status ]
-
-class BuilderStatus(styles.Versioned):
- """I handle status information for a single process.build.Builder object.
- That object sends status changes to me (frequently as Events), and I
- provide them on demand to the various status recipients, like the HTML
- waterfall display and the live status clients. It also sends build
- summaries to me, which I log and provide to status clients who aren't
- interested in seeing details of the individual build steps.
-
- I am responsible for maintaining the list of historic Events and Builds,
- pruning old ones, and loading them from / saving them to disk.
-
- I live in the buildbot.process.build.Builder object, in the
- .builder_status attribute.
-
- @type category: string
- @ivar category: user-defined category this builder belongs to; can be
- used to filter on in status clients
- """
-
- implements(interfaces.IBuilderStatus, interfaces.IEventSource)
-
- persistenceVersion = 1
- persistenceForgets = ( 'wasUpgraded', )
-
- category = None
- currentBigState = "offline" # or idle/waiting/interlocked/building
- basedir = None # filled in by our parent
-
- def __init__(self, buildername, category, master, description):
- self.name = buildername
- self.category = category
- self.description = description
- self.master = master
-
- self.slavenames = []
- self.events = []
- # these three hold Events, and are used to retrieve the current
- # state of the boxes.
- self.lastBuildStatus = None
- #self.currentBig = None
- #self.currentSmall = None
- self.currentBuilds = []
- self.nextBuild = None
- self.watchers = []
- self.buildCache = LRUCache(self.cacheMiss)
-
- # persistence
-
- def __getstate__(self):
- # when saving, don't record transient stuff like what builds are
- # currently running, because they won't be there when we start back
- # up. Nor do we save self.watchers, nor anything that gets set by our
- # parent like .basedir and .status
- d = styles.Versioned.__getstate__(self)
- d['watchers'] = []
- del d['buildCache']
- for b in self.currentBuilds:
- b.saveYourself()
- # TODO: push a 'hey, build was interrupted' event
- del d['currentBuilds']
- d.pop('pendingBuilds', None)
- del d['currentBigState']
- del d['basedir']
- del d['status']
- del d['nextBuildNumber']
- del d['master']
- return d
-
- def __setstate__(self, d):
- # when loading, re-initialize the transient stuff. Remember that
- # upgradeToVersion1 and such will be called after this finishes.
- styles.Versioned.__setstate__(self, d)
- self.buildCache = LRUCache(self.cacheMiss)
- self.currentBuilds = []
- self.watchers = []
- self.slavenames = []
- # self.basedir must be filled in by our parent
- # self.status must be filled in by our parent
- # self.master must be filled in by our parent
-
- def upgradeToVersion1(self):
- if hasattr(self, 'slavename'):
- self.slavenames = [self.slavename]
- del self.slavename
- if hasattr(self, 'nextBuildNumber'):
- del self.nextBuildNumber # determineNextBuildNumber chooses this
- self.wasUpgraded = True
-
- def determineNextBuildNumber(self):
- """Scan our directory of saved BuildStatus instances to determine
- what our self.nextBuildNumber should be. Set it one larger than the
- highest-numbered build we discover. This is called by the top-level
- Status object shortly after we are created or loaded from disk.
- """
- existing_builds = [int(f)
- for f in os.listdir(self.basedir)
- if re.match("^\d+$", f)]
- if existing_builds:
- self.nextBuildNumber = max(existing_builds) + 1
- else:
- self.nextBuildNumber = 0
-
- def saveYourself(self):
- for b in self.currentBuilds:
- if not b.isFinished:
- # interrupted build, need to save it anyway.
- # BuildStatus.saveYourself will mark it as interrupted.
- b.saveYourself()
- filename = os.path.join(self.basedir, "builder")
- tmpfilename = filename + ".tmp"
- try:
- with open(tmpfilename, "wb") as f:
- dump(self, f, -1)
- if runtime.platformType == 'win32':
- # windows cannot rename a file on top of an existing one
- if os.path.exists(filename):
- os.unlink(filename)
- os.rename(tmpfilename, filename)
- except:
- log.msg("unable to save builder %s" % self.name)
- log.err()
-
- # build cache management
-
- def setCacheSize(self, size):
- self.buildCache.set_max_size(size)
-
- def makeBuildFilename(self, number):
- return os.path.join(self.basedir, "%d" % number)
-
- def getBuildByNumber(self, number):
- return self.buildCache.get(number)
-
- def loadBuildFromFile(self, number):
- filename = self.makeBuildFilename(number)
- try:
- log.msg("Loading builder %s's build %d from on-disk pickle"
- % (self.name, number))
- with open(filename, "rb") as f:
- build = load(f)
- build.setProcessObjects(self, self.master)
-
- # (bug #1068) if we need to upgrade, we probably need to rewrite
- # this pickle, too. We determine this by looking at the list of
- # Versioned objects that have been unpickled, and (after doUpgrade)
- # checking to see if any of them set wasUpgraded. The Versioneds'
- # upgradeToVersionNN methods all set this.
- versioneds = styles.versionedsToUpgrade
- styles.doUpgrade()
- if True in [ hasattr(o, 'wasUpgraded') for o in versioneds.values() ]:
- log.msg("re-writing upgraded build pickle")
- build.saveYourself()
-
- # check that logfiles exist
- build.checkLogfiles()
- return build
- except IOError:
- raise IndexError("no such build %d" % number)
- except EOFError:
- raise IndexError("corrupted build pickle %d" % number)
-
- def cacheMiss(self, number, **kwargs):
- # If kwargs['val'] exists, this is a new value being added to
- # the cache. Just return it.
- if 'val' in kwargs:
- return kwargs['val']
-
- # first look in currentBuilds
- for b in self.currentBuilds:
- if b.number == number:
- return b
-
- # then fall back to loading it from disk
- return self.loadBuildFromFile(number)
-
- def prune(self, events_only=False):
- # begin by pruning our own events
- eventHorizon = self.master.config.eventHorizon
- self.events = self.events[-eventHorizon:]
-
- if events_only:
- return
-
- # get the horizons straight
- buildHorizon = self.master.config.buildHorizon
- if buildHorizon is not None:
- earliest_build = self.nextBuildNumber - buildHorizon
- else:
- earliest_build = 0
-
- logHorizon = self.master.config.logHorizon
- if logHorizon is not None:
- earliest_log = self.nextBuildNumber - logHorizon
- else:
- earliest_log = 0
-
- if earliest_log < earliest_build:
- earliest_log = earliest_build
-
- if earliest_build == 0:
- return
-
- # skim the directory and delete anything that shouldn't be there anymore
- build_re = re.compile(r"^([0-9]+)$")
- build_log_re = re.compile(r"^([0-9]+)-.*$")
- # if the directory doesn't exist, bail out here
- if not os.path.exists(self.basedir):
- return
-
- for filename in os.listdir(self.basedir):
- num = None
- mo = build_re.match(filename)
- is_logfile = False
- if mo:
- num = int(mo.group(1))
- else:
- mo = build_log_re.match(filename)
- if mo:
- num = int(mo.group(1))
- is_logfile = True
-
- if num is None: continue
- if num in self.buildCache.cache: continue
-
- if (is_logfile and num < earliest_log) or num < earliest_build:
- pathname = os.path.join(self.basedir, filename)
- log.msg("pruning '%s'" % pathname)
- try: os.unlink(pathname)
- except OSError: pass
-
- # IBuilderStatus methods
- def getName(self):
- # if builderstatus page does show not up without any reason then
- # str(self.name) may be a workaround
- return self.name
-
- def setDescription(self, description):
- # used during reconfig
- self.description = description
-
- def getDescription(self):
- return self.description
-
- def getState(self):
- return (self.currentBigState, self.currentBuilds)
-
- def getSlaves(self):
- return [self.status.getSlave(name) for name in self.slavenames]
-
- def getPendingBuildRequestStatuses(self):
- db = self.status.master.db
- d = db.buildrequests.getBuildRequests(claimed=False,
- buildername=self.name)
- def make_statuses(brdicts):
- return [BuildRequestStatus(self.name, brdict['brid'],
- self.status)
- for brdict in brdicts]
- d.addCallback(make_statuses)
- return d
-
- def getCurrentBuilds(self):
- return self.currentBuilds
-
- def getLastFinishedBuild(self):
- b = self.getBuild(-1)
- if not (b and b.isFinished()):
- b = self.getBuild(-2)
- return b
-
- def setCategory(self, category):
- # used during reconfig
- self.category = category
-
- def getCategory(self):
- return self.category
-
- def getBuild(self, number):
- if number < 0:
- number = self.nextBuildNumber + number
- if number < 0 or number >= self.nextBuildNumber:
- return None
-
- try:
- return self.getBuildByNumber(number)
- except IndexError:
- return None
-
- def getEvent(self, number):
- try:
- return self.events[number]
- except IndexError:
- return None
-
- def _getBuildBranches(self, build):
- return set([ ss.branch
- for ss in build.getSourceStamps() ])
-
- def generateFinishedBuilds(self, branches=[],
- num_builds=None,
- max_buildnum=None,
- finished_before=None,
- results=None,
- max_search=200):
- got = 0
- branches = set(branches)
- for Nb in itertools.count(1):
- if Nb > self.nextBuildNumber:
- break
- if Nb > max_search:
- break
- build = self.getBuild(-Nb)
- if build is None:
- continue
- if max_buildnum is not None:
- if build.getNumber() > max_buildnum:
- continue
- if not build.isFinished():
- continue
- if finished_before is not None:
- start, end = build.getTimes()
- if end >= finished_before:
- continue
- # if we were asked to filter on branches, and none of the
- # sourcestamps match, skip this build
- if branches and not branches & self._getBuildBranches(build):
- continue
- if results is not None:
- if build.getResults() not in results:
- continue
- got += 1
- yield build
- if num_builds is not None:
- if got >= num_builds:
- return
-
- def eventGenerator(self, branches=[], categories=[], committers=[], minTime=0):
- """This function creates a generator which will provide all of this
- Builder's status events, starting with the most recent and
- progressing backwards in time. """
-
- # remember the oldest-to-earliest flow here. "next" means earlier.
-
- # TODO: interleave build steps and self.events by timestamp.
- # TODO: um, I think we're already doing that.
-
- # TODO: there's probably something clever we could do here to
- # interleave two event streams (one from self.getBuild and the other
- # from self.getEvent), which would be simpler than this control flow
-
- eventIndex = -1
- e = self.getEvent(eventIndex)
- branches = set(branches)
- for Nb in range(1, self.nextBuildNumber+1):
- b = self.getBuild(-Nb)
- if not b:
- # HACK: If this is the first build we are looking at, it is
- # possible it's in progress but locked before it has written a
- # pickle; in this case keep looking.
- if Nb == 1:
- continue
- break
- if b.getTimes()[0] < minTime:
- break
- # if we were asked to filter on branches, and none of the
- # sourcestamps match, skip this build
- if branches and not branches & self._getBuildBranches(b):
- continue
- if categories and not b.getBuilder().getCategory() in categories:
- continue
- if committers and not [True for c in b.getChanges() if c.who in committers]:
- continue
- steps = b.getSteps()
- for Ns in range(1, len(steps)+1):
- if steps[-Ns].started:
- step_start = steps[-Ns].getTimes()[0]
- while e is not None and e.getTimes()[0] > step_start:
- yield e
- eventIndex -= 1
- e = self.getEvent(eventIndex)
- yield steps[-Ns]
- yield b
- while e is not None:
- yield e
- eventIndex -= 1
- e = self.getEvent(eventIndex)
- if e and e.getTimes()[0] < minTime:
- break
-
- def subscribe(self, receiver):
- # will get builderChangedState, buildStarted, buildFinished,
- # requestSubmitted, requestCancelled. Note that a request which is
- # resubmitted (due to a slave disconnect) will cause requestSubmitted
- # to be invoked multiple times.
- self.watchers.append(receiver)
- self.publishState(receiver)
- # our parent Status provides requestSubmitted and requestCancelled
- self.status._builder_subscribe(self.name, receiver)
-
- def unsubscribe(self, receiver):
- self.watchers.remove(receiver)
- self.status._builder_unsubscribe(self.name, receiver)
-
- ## Builder interface (methods called by the Builder which feeds us)
-
- def setSlavenames(self, names):
- self.slavenames = names
-
- def addEvent(self, text=[]):
- # this adds a duration event. When it is done, the user should call
- # e.finish(). They can also mangle it by modifying .text
- e = Event()
- e.started = util.now()
- e.text = text
- self.events.append(e)
- self.prune(events_only=True)
- return e # they are free to mangle it further
-
- def addPointEvent(self, text=[]):
- # this adds a point event, one which occurs as a single atomic
- # instant of time.
- e = Event()
- e.started = util.now()
- e.finished = 0
- e.text = text
- self.events.append(e)
- self.prune(events_only=True)
- return e # for consistency, but they really shouldn't touch it
-
- def setBigState(self, state):
- needToUpdate = state != self.currentBigState
- self.currentBigState = state
- if needToUpdate:
- self.publishState()
-
- def publishState(self, target=None):
- state = self.currentBigState
-
- if target is not None:
- # unicast
- target.builderChangedState(self.name, state)
- return
- for w in self.watchers:
- try:
- w.builderChangedState(self.name, state)
- except:
- log.msg("Exception caught publishing state to %r" % w)
- log.err()
-
- def newBuild(self):
- """The Builder has decided to start a build, but the Build object is
- not yet ready to report status (it has not finished creating the
- Steps). Create a BuildStatus object that it can use."""
- number = self.nextBuildNumber
- self.nextBuildNumber += 1
- # TODO: self.saveYourself(), to make sure we don't forget about the
- # build number we've just allocated. This is not quite as important
- # as it was before we switch to determineNextBuildNumber, but I think
- # it may still be useful to have the new build save itself.
- s = BuildStatus(self, self.master, number)
- s.waitUntilFinished().addCallback(self._buildFinished)
- return s
-
- # buildStarted is called by our child BuildStatus instances
- def buildStarted(self, s):
- """Now the BuildStatus object is ready to go (it knows all of its
- Steps, its ETA, etc), so it is safe to notify our watchers."""
-
- assert s.builder is self # paranoia
- assert s not in self.currentBuilds
- self.currentBuilds.append(s)
- self.buildCache.get(s.number, val=s)
-
- # now that the BuildStatus is prepared to answer queries, we can
- # announce the new build to all our watchers
-
- for w in self.watchers: # TODO: maybe do this later? callLater(0)?
- try:
- receiver = w.buildStarted(self.getName(), s)
- if receiver:
- if type(receiver) == type(()):
- s.subscribe(receiver[0], receiver[1])
- else:
- s.subscribe(receiver)
- d = s.waitUntilFinished()
- d.addCallback(lambda s: s.unsubscribe(receiver))
- except:
- log.msg("Exception caught notifying %r of buildStarted event" % w)
- log.err()
-
- def _buildFinished(self, s):
- assert s in self.currentBuilds
- s.saveYourself()
- self.currentBuilds.remove(s)
-
- name = self.getName()
- results = s.getResults()
- for w in self.watchers:
- try:
- w.buildFinished(name, s, results)
- except:
- log.msg("Exception caught notifying %r of buildFinished event" % w)
- log.err()
-
- self.prune() # conserve disk
-
-
- def asDict(self):
- result = {}
- # Constant
- # TODO(maruel): Fix me. We don't want to leak the full path.
- result['basedir'] = os.path.basename(self.basedir)
- result['category'] = self.category
- result['slaves'] = self.slavenames
- result['schedulers'] = [ s.name
- for s in self.status.master.allSchedulers()
- if self.name in s.builderNames ]
- #result['url'] = self.parent.getURLForThing(self)
- # TODO(maruel): Add cache settings? Do we care?
-
- # Transient
- # Collect build numbers.
- # Important: Only grab the *cached* builds numbers to reduce I/O.
- current_builds = [b.getNumber() for b in self.currentBuilds]
- cached_builds = list(set(self.buildCache.keys() + current_builds))
- cached_builds.sort()
- result['cachedBuilds'] = cached_builds
- result['currentBuilds'] = current_builds
- result['state'] = self.getState()[0]
- # lies, but we don't have synchronous access to this info; use
- # asDict_async instead
- result['pendingBuilds'] = 0
- return result
-
- def asDict_async(self):
- """Just like L{asDict}, but with a nonzero pendingBuilds."""
- result = self.asDict()
- d = self.getPendingBuildRequestStatuses()
- def combine(statuses):
- result['pendingBuilds'] = len(statuses)
- return result
- d.addCallback(combine)
- return d
-
- def getMetrics(self):
- return self.botmaster.parent.metrics
-
-# vim: set ts=4 sts=4 sw=4 et:
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildrequest.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildrequest.py
deleted file mode 100644
index 1f52902e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildrequest.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# 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
-
-from zope.interface import implements
-from twisted.python import log
-from twisted.internet import defer
-from buildbot import interfaces
-from buildbot.util.eventual import eventually
-
-class BuildRequestStatus:
- implements(interfaces.IBuildRequestStatus)
-
- def __init__(self, buildername, brid, status):
- self.buildername = buildername
- self.brid = brid
- self.status = status
- self.master = status.master
-
- self._buildrequest = None
- self._buildrequest_lock = defer.DeferredLock()
-
- @defer.inlineCallbacks
- def _getBuildRequest(self):
- """
- Get the underlying BuildRequest object for this status. This is a slow
- operation!
-
- @returns: BuildRequest instance or None, via Deferred
- """
- # late binding to avoid an import cycle
- from buildbot.process import buildrequest
-
- # this is only set once, so no need to lock if we already have it
- if self._buildrequest:
- defer.returnValue(self._buildrequest)
- return
-
- yield self._buildrequest_lock.acquire()
-
- try:
- if not self._buildrequest:
- brd = yield self.master.db.buildrequests.getBuildRequest(
- self.brid)
-
- br = yield buildrequest.BuildRequest.fromBrdict(self.master,
- brd)
- self._buildrequest = br
- except: # try/finally isn't allowed in generators in older Pythons
- self._buildrequest_lock.release()
- raise
-
- self._buildrequest_lock.release()
-
- defer.returnValue(self._buildrequest)
-
- def buildStarted(self, build):
- self.status._buildrequest_buildStarted(build.status)
- self.builds.append(build.status)
-
- # methods called by our clients
- @defer.inlineCallbacks
- def getBsid(self):
- br = yield self._getBuildRequest()
- defer.returnValue(br.bsid)
-
- @defer.inlineCallbacks
- def getBuildProperties(self):
- br = yield self._getBuildRequest()
- defer.returnValue(br.properties)
-
- @defer.inlineCallbacks
- def getSourceStamp(self):
- br = yield self._getBuildRequest()
- defer.returnValue(br.source)
-
- def getBuilderName(self):
- return self.buildername
-
- @defer.inlineCallbacks
- def getBuilds(self):
- builder = self.status.getBuilder(self.getBuilderName())
- builds = []
-
- bdicts = yield self.master.db.builds.getBuildsForRequest(self.brid)
-
- buildnums = sorted([ bdict['number'] for bdict in bdicts ])
-
- for buildnum in buildnums:
- bs = builder.getBuild(buildnum)
- if bs:
- builds.append(bs)
- defer.returnValue(builds)
-
- def subscribe(self, observer):
- d = self.getBuilds()
- def notify_old(oldbuilds):
- for bs in oldbuilds:
- eventually(observer, bs)
- d.addCallback(notify_old)
- d.addCallback(lambda _ :
- self.status._buildrequest_subscribe(self.brid, observer))
- d.addErrback(log.err, 'while notifying subscribers')
-
- def unsubscribe(self, observer):
- self.status._buildrequest_unsubscribe(self.brid, observer)
-
- @defer.inlineCallbacks
- def getSubmitTime(self):
- br = yield self._getBuildRequest()
- defer.returnValue(br.submittedAt)
-
- def asDict(self):
- result = {}
- # Constant
- result['source'] = None # not available sync, sorry
- result['builderName'] = self.buildername
- result['submittedAt'] = None # not availably sync, sorry
-
- # Transient
- result['builds'] = [] # not available async, sorry
- return result
-
- @defer.inlineCallbacks
- def asDict_async(self):
- result = {}
-
- ss = yield self.getSourceStamp()
- result['source'] = ss.asDict()
- props = yield self.getBuildProperties()
- result['properties'] = props.asList()
- result['builderName'] = self.getBuilderName()
- result['submittedAt'] = yield self.getSubmitTime()
-
- builds = yield self.getBuilds()
- result['builds'] = [ build.asDict() for build in builds ]
-
- defer.returnValue(result)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildset.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildset.py
deleted file mode 100644
index 524473a7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildset.py
+++ /dev/null
@@ -1,68 +0,0 @@
-# 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
-
-from zope.interface import implements
-from buildbot import interfaces
-from buildbot.status.buildrequest import BuildRequestStatus
-
-class BuildSetStatus:
- implements(interfaces.IBuildSetStatus)
-
- def __init__(self, bsdict, status):
- self.id = bsdict['bsid']
- self.bsdict = bsdict
- self.status = status
- self.master = status.master
-
- # methods for our clients
-
- def getReason(self):
- return self.bsdict['reason']
-
- def getResults(self):
- return self.bsdict['results']
-
- def getID(self):
- return self.bsdict['external_idstring']
-
- def isFinished(self):
- return self.bsdict['complete']
-
- def getBuilderNamesAndBuildRequests(self):
- # returns a Deferred; undocumented method that may be removed
- # without warning
- d = self.master.db.buildrequests.getBuildRequests(bsid=self.id)
- def get_objects(brdicts):
- return dict([
- (brd['buildername'], BuildRequestStatus(brd['buildername'],
- brd['brid'], self.status))
- for brd in brdicts ])
- d.addCallback(get_objects)
- return d
-
- def getBuilderNames(self):
- d = self.master.db.buildrequests.getBuildRequests(bsid=self.id)
- def get_names(brdicts):
- return sorted([ brd['buildername'] for brd in brdicts ])
- d.addCallback(get_names)
- return d
-
- def waitUntilFinished(self):
- return self.status._buildset_waitUntilFinished(self.id)
-
- def asDict(self):
- d = dict(self.bsdict)
- d["submitted_at"] = str(self.bsdict["submitted_at"])
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildstep.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildstep.py
deleted file mode 100644
index 8e453873..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/buildstep.py
+++ /dev/null
@@ -1,386 +0,0 @@
-# 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 os
-from zope.interface import implements
-from twisted.persisted import styles
-from twisted.python import log
-from twisted.internet import reactor, defer
-from buildbot import interfaces, util
-from buildbot.status.logfile import LogFile, HTMLLogFile
-
-class BuildStepStatus(styles.Versioned):
- """
- I represent a collection of output status for a
- L{buildbot.process.step.BuildStep}.
-
- Statistics contain any information gleaned from a step that is
- not in the form of a logfile. As an example, steps that run
- tests might gather statistics about the number of passed, failed,
- or skipped tests.
-
- @type progress: L{buildbot.status.progress.StepProgress}
- @cvar progress: tracks ETA for the step
- @type text: list of strings
- @cvar text: list of short texts that describe the command and its status
- @type text2: list of strings
- @cvar text2: list of short texts added to the overall build description
- @type logs: dict of string -> L{buildbot.status.logfile.LogFile}
- @ivar logs: logs of steps
- @type statistics: dict
- @ivar statistics: results from running this step
- """
- # note that these are created when the Build is set up, before each
- # corresponding BuildStep has started.
- implements(interfaces.IBuildStepStatus, interfaces.IStatusEvent)
-
- persistenceVersion = 4
- persistenceForgets = ( 'wasUpgraded', )
-
- started = None
- finished = None
- progress = None
- text = []
- results = None
- text2 = []
- watchers = []
- updates = {}
- finishedWatchers = []
- statistics = {}
- step_number = None
- hidden = False
-
- def __init__(self, parent, master, step_number):
- assert interfaces.IBuildStatus(parent)
- self.build = parent
- self.step_number = step_number
- self.hidden = False
- self.logs = []
- self.urls = {}
- self.watchers = []
- self.updates = {}
- self.finishedWatchers = []
- self.statistics = {}
- self.skipped = False
-
- self.master = master
-
- self.waitingForLocks = False
-
- def getName(self):
- """Returns a short string with the name of this step. This string
- may have spaces in it."""
- return self.name
-
- def getBuild(self):
- return self.build
-
- def getTimes(self):
- return (self.started, self.finished)
-
- def getExpectations(self):
- """Returns a list of tuples (name, current, target)."""
- if not self.progress:
- return []
- ret = []
- metrics = self.progress.progress.keys()
- metrics.sort()
- for m in metrics:
- t = (m, self.progress.progress[m], self.progress.expectations[m])
- ret.append(t)
- return ret
-
- def getLogs(self):
- return self.logs
-
- def getURLs(self):
- return self.urls.copy()
-
- def isStarted(self):
- return (self.started is not None)
-
- def isSkipped(self):
- return self.skipped
-
- def isFinished(self):
- return (self.finished is not None)
-
- def isHidden(self):
- return self.hidden
-
- def waitUntilFinished(self):
- if self.finished:
- d = defer.succeed(self)
- else:
- d = defer.Deferred()
- self.finishedWatchers.append(d)
- return d
-
- # while the step is running, the following methods make sense.
- # Afterwards they return None
-
- def getETA(self):
- if self.started is None:
- return None # not started yet
- if self.finished is not None:
- return None # already finished
- if not self.progress:
- return None # no way to predict
- return self.progress.remaining()
-
- # Once you know the step has finished, the following methods are legal.
- # Before this step has finished, they all return None.
-
- def getText(self):
- """Returns a list of strings which describe the step. These are
- intended to be displayed in a narrow column. If more space is
- available, the caller should join them together with spaces before
- presenting them to the user."""
- return self.text
-
- def getResults(self):
- """Return a tuple describing the results of the step.
- 'result' is one of the constants in L{buildbot.status.builder}:
- SUCCESS, WARNINGS, FAILURE, or SKIPPED.
- 'strings' is an optional list of strings that the step wants to
- append to the overall build's results. These strings are usually
- more terse than the ones returned by getText(): in particular,
- successful Steps do not usually contribute any text to the
- overall build.
-
- @rtype: tuple of int, list of strings
- @returns: (result, strings)
- """
- return (self.results, self.text2)
-
- def hasStatistic(self, name):
- """Return true if this step has a value for the given statistic.
- """
- return self.statistics.has_key(name)
-
- def getStatistic(self, name, default=None):
- """Return the given statistic, if present
- """
- return self.statistics.get(name, default)
-
- def getStatistics(self):
- return self.statistics.copy()
-
- # subscription interface
-
- def subscribe(self, receiver, updateInterval=10):
- # will get logStarted, logFinished, stepETAUpdate
- assert receiver not in self.watchers
- self.watchers.append(receiver)
- self.sendETAUpdate(receiver, updateInterval)
-
- def sendETAUpdate(self, receiver, updateInterval):
- self.updates[receiver] = None
- # they might unsubscribe during stepETAUpdate
- receiver.stepETAUpdate(self.build, self,
- self.getETA(), self.getExpectations())
- if receiver in self.watchers:
- self.updates[receiver] = reactor.callLater(updateInterval,
- self.sendETAUpdate,
- receiver,
- updateInterval)
-
- def unsubscribe(self, receiver):
- if receiver in self.watchers:
- self.watchers.remove(receiver)
- if receiver in self.updates:
- if self.updates[receiver] is not None:
- self.updates[receiver].cancel()
- del self.updates[receiver]
-
-
- # methods to be invoked by the BuildStep
-
- def setName(self, stepname):
- self.name = stepname
-
- def setColor(self, color):
- log.msg("BuildStepStatus.setColor is no longer supported -- ignoring color %s" % (color,))
-
- def setProgress(self, stepprogress):
- self.progress = stepprogress
-
- def setHidden(self, hidden):
- self.hidden = hidden
-
- def stepStarted(self):
- self.started = util.now()
- if self.build:
- self.build.stepStarted(self)
-
- def addLog(self, name):
- assert self.started # addLog before stepStarted won't notify watchers
- logfilename = self.build.generateLogfileName(self.name, name)
- log = LogFile(self, name, logfilename)
- self.logs.append(log)
- for w in self.watchers:
- receiver = w.logStarted(self.build, self, log)
- if receiver:
- log.subscribe(receiver, True)
- d = log.waitUntilFinished()
- d.addCallback(lambda log: log.unsubscribe(receiver))
- d = log.waitUntilFinished()
- d.addCallback(self.logFinished)
- return log
-
- def addHTMLLog(self, name, html):
- assert self.started # addLog before stepStarted won't notify watchers
- logfilename = self.build.generateLogfileName(self.name, name)
- log = HTMLLogFile(self, name, logfilename, html)
- self.logs.append(log)
- for w in self.watchers:
- w.logStarted(self.build, self, log)
- w.logFinished(self.build, self, log)
-
- def logFinished(self, log):
- for w in self.watchers:
- w.logFinished(self.build, self, log)
-
- def addURL(self, name, url):
- self.urls[name] = url
-
- def setText(self, text):
- self.text = text
- for w in self.watchers:
- w.stepTextChanged(self.build, self, text)
- def setText2(self, text):
- self.text2 = text
- for w in self.watchers:
- w.stepText2Changed(self.build, self, text)
-
- def setStatistic(self, name, value):
- """Set the given statistic. Usually called by subclasses.
- """
- self.statistics[name] = value
-
- def setSkipped(self, skipped):
- self.skipped = skipped
-
- def stepFinished(self, results):
- self.finished = util.now()
- self.results = results
- cld = [] # deferreds for log compression
- logCompressionLimit = self.master.config.logCompressionLimit
- for loog in self.logs:
- if not loog.isFinished():
- loog.finish()
- # if log compression is on, and it's a real LogFile,
- # HTMLLogFiles aren't files
- if logCompressionLimit is not False and \
- isinstance(loog, LogFile):
- if os.path.getsize(loog.getFilename()) > logCompressionLimit:
- loog_deferred = loog.compressLog()
- if loog_deferred:
- cld.append(loog_deferred)
-
- for r in self.updates.keys():
- if self.updates[r] is not None:
- self.updates[r].cancel()
- del self.updates[r]
-
- watchers = self.finishedWatchers
- self.finishedWatchers = []
- for w in watchers:
- w.callback(self)
- if cld:
- return defer.DeferredList(cld)
-
- def checkLogfiles(self):
- # filter out logs that have been deleted
- self.logs = [ l for l in self.logs if l.hasContents() ]
-
- def isWaitingForLocks(self):
- return self.waitingForLocks
-
- def setWaitingForLocks(self, waiting):
- self.waitingForLocks = waiting
-
- # persistence
-
- def __getstate__(self):
- d = styles.Versioned.__getstate__(self)
- del d['build'] # filled in when loading
- if d.has_key('progress'):
- del d['progress']
- del d['watchers']
- del d['finishedWatchers']
- del d['updates']
- del d['master']
- return d
-
- def __setstate__(self, d):
- styles.Versioned.__setstate__(self, d)
- # self.build must be filled in by our parent
-
- # point the logs to this object
- self.watchers = []
- self.finishedWatchers = []
- self.updates = {}
-
- def setProcessObjects(self, build, master):
- self.build = build
- self.master = master
- for loog in self.logs:
- loog.step = self
- loog.master = master
-
- def upgradeToVersion1(self):
- if not hasattr(self, "urls"):
- self.urls = {}
- self.wasUpgraded = True
-
- def upgradeToVersion2(self):
- if not hasattr(self, "statistics"):
- self.statistics = {}
- self.wasUpgraded = True
-
- def upgradeToVersion3(self):
- if not hasattr(self, "step_number"):
- self.step_number = 0
- self.wasUpgraded = True
-
- def upgradeToVersion4(self):
- if not hasattr(self, "hidden"):
- self.hidden = False
- self.wasUpgraded = True
-
- def asDict(self):
- result = {}
- # Constant
- result['name'] = self.getName()
-
- # Transient
- result['text'] = self.getText()
- result['results'] = self.getResults()
- result['isStarted'] = self.isStarted()
- result['isFinished'] = self.isFinished()
- result['statistics'] = self.statistics
- result['times'] = self.getTimes()
- result['expectations'] = self.getExpectations()
- result['eta'] = self.getETA()
- result['urls'] = self.getURLs()
- result['step_number'] = self.step_number
- result['hidden'] = self.hidden
- result['logs'] = [[l.getName(),
- self.build.builder.status.getURLForThing(l)]
- for l in self.getLogs()]
- return result
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/client.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/client.py
deleted file mode 100644
index 39adcec5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/client.py
+++ /dev/null
@@ -1,586 +0,0 @@
-# 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
-
-
-from twisted.spread import pb
-from twisted.python import components, log as twlog
-from twisted.application import strports
-from twisted.cred import portal, checkers
-
-from buildbot import interfaces
-from zope.interface import Interface, implements
-from buildbot.status import logfile, base
-from buildbot.changes import changes
-from buildbot.util.eventual import eventually
-
-class IRemote(Interface):
- pass
-
-def makeRemote(obj):
- # we want IRemote(None) to be None, but you can't really do that with
- # adapters, so we fake it
- if obj is None:
- return None
- return IRemote(obj)
-
-
-class RemoteBuildSet(pb.Referenceable):
- def __init__(self, buildset):
- self.b = buildset
-
- def remote_getSourceStamp(self):
- return self.b.getSourceStamp()
-
- def remote_getReason(self):
- return self.b.getReason()
-
- def remote_getID(self):
- return self.b.getID()
-
- def remote_getBuilderNames(self):
- return self.b.getBuilderNames() # note: passes along the Deferred
-
- def remote_getBuildRequests(self):
- """Returns a list of (builderName, BuildRequest) tuples."""
- d = self.b.getBuilderNamesAndBuildRequests()
- def add_remote(buildrequests):
- for k,v in buildrequests.iteritems():
- buildrequests[k] = IRemote(v)
- return buildrequests.items()
- d.addCallback(add_remote)
- return d
-
- def remote_isFinished(self):
- return self.b.isFinished()
-
- def remote_waitUntilFinished(self):
- d = self.b.waitUntilFinished()
- d.addCallback(makeRemote)
- return d
-
- def remote_getResults(self):
- return self.b.getResults()
-
-components.registerAdapter(RemoteBuildSet,
- interfaces.IBuildSetStatus, IRemote)
-
-
-class RemoteBuilder(pb.Referenceable):
- def __init__(self, builder):
- self.b = builder
-
- def remote_getName(self):
- return self.b.getName()
-
- def remote_getCategory(self):
- return self.b.getCategory()
-
- def remote_getState(self):
- state, builds = self.b.getState()
- return (state,
- None, # TODO: remove leftover ETA
- [makeRemote(b) for b in builds])
-
- def remote_getSlaves(self):
- return [IRemote(s) for s in self.b.getSlaves()]
-
- def remote_getLastFinishedBuild(self):
- return makeRemote(self.b.getLastFinishedBuild())
-
- def remote_getCurrentBuilds(self):
- return [IRemote(b) for b in self.b.getCurrentBuilds()]
-
- def remote_getBuild(self, number):
- return makeRemote(self.b.getBuild(number))
-
- def remote_getEvent(self, number):
- return IRemote(self.b.getEvent(number))
-
-components.registerAdapter(RemoteBuilder,
- interfaces.IBuilderStatus, IRemote)
-
-
-class RemoteBuildRequest(pb.Referenceable):
- def __init__(self, buildreq):
- self.b = buildreq
- # mapping of observers (RemoteReference instances) to local callable
- # objects that have been passed to BuildRequestStatus.subscribe
- self.observers = []
-
- def remote_getSourceStamp(self):
- # note that this now returns a Deferred
- return self.b.getSourceStamp()
-
- def remote_getBuilderName(self):
- return self.b.getBuilderName()
-
- def remote_subscribe(self, observer):
- """The observer's remote_newbuild method will be called (with two
- arguments: the RemoteBuild object, and our builderName) for each new
- Build that is created to handle this BuildRequest."""
- def send(bs):
- d = observer.callRemote("newbuild",
- IRemote(bs), self.b.getBuilderName())
- d.addErrback(twlog.err,
- "while calling client-side remote_newbuild")
- self.observers.append((observer, send))
- self.b.subscribe(send)
-
- def remote_unsubscribe(self, observer):
- for i, (obs, send) in enumerate(self.observers):
- if obs == observer:
- del self.observers[i]
- self.b.unsubscribe(send)
- break
-
-components.registerAdapter(RemoteBuildRequest,
- interfaces.IBuildRequestStatus, IRemote)
-
-class RemoteBuild(pb.Referenceable):
- def __init__(self, build):
- self.b = build
- self.observers = []
-
- def remote_getBuilderName(self):
- return self.b.getBuilder().getName()
-
- def remote_getNumber(self):
- return self.b.getNumber()
-
- def remote_getReason(self):
- return self.b.getReason()
-
- def remote_getChanges(self):
- return [IRemote(c) for c in self.b.getChanges()]
-
- def remote_getRevisions(self):
- return self.b.getRevisions()
-
- def remote_getResponsibleUsers(self):
- return self.b.getResponsibleUsers()
-
- def remote_getSteps(self):
- return [IRemote(s) for s in self.b.getSteps()]
-
- def remote_getTimes(self):
- return self.b.getTimes()
-
- def remote_isFinished(self):
- return self.b.isFinished()
-
- def remote_waitUntilFinished(self):
- # the Deferred returned by callRemote() will fire when this build is
- # finished
- d = self.b.waitUntilFinished()
- d.addCallback(lambda res: self)
- return d
-
- def remote_getETA(self):
- return self.b.getETA()
-
- def remote_getCurrentStep(self):
- return makeRemote(self.b.getCurrentStep())
-
- def remote_getText(self):
- return self.b.getText()
-
- def remote_getResults(self):
- return self.b.getResults()
-
- def remote_getLogs(self):
- logs = {}
- for name,log in self.b.getLogs().items():
- logs[name] = IRemote(log)
- return logs
-
- def remote_subscribe(self, observer, updateInterval=None):
- """The observer will have remote_stepStarted(buildername, build,
- stepname, step), remote_stepFinished(buildername, build, stepname,
- step, results), and maybe remote_buildETAUpdate(buildername, build,
- eta)) messages sent to it."""
- self.observers.append(observer)
- s = BuildSubscriber(observer)
- self.b.subscribe(s, updateInterval)
-
- def remote_unsubscribe(self, observer):
- # TODO: is the observer automatically unsubscribed when the build
- # finishes? Or are they responsible for unsubscribing themselves
- # anyway? How do we avoid a race condition here?
- for o in self.observers:
- if o == observer:
- self.observers.remove(o)
-
-
-components.registerAdapter(RemoteBuild,
- interfaces.IBuildStatus, IRemote)
-
-class BuildSubscriber:
- def __init__(self, observer):
- self.observer = observer
-
- def buildETAUpdate(self, build, eta):
- self.observer.callRemote("buildETAUpdate",
- build.getBuilder().getName(),
- IRemote(build),
- eta)
-
- def stepStarted(self, build, step):
- self.observer.callRemote("stepStarted",
- build.getBuilder().getName(),
- IRemote(build),
- step.getName(), IRemote(step))
- return None
-
- def stepFinished(self, build, step, results):
- self.observer.callRemote("stepFinished",
- build.getBuilder().getName(),
- IRemote(build),
- step.getName(), IRemote(step),
- results)
-
-
-class RemoteBuildStep(pb.Referenceable):
- def __init__(self, step):
- self.s = step
-
- def remote_getName(self):
- return self.s.getName()
-
- def remote_getBuild(self):
- return IRemote(self.s.getBuild())
-
- def remote_getTimes(self):
- return self.s.getTimes()
-
- def remote_getExpectations(self):
- return self.s.getExpectations()
-
- def remote_getLogs(self):
- logs = {}
- for log in self.s.getLogs():
- logs[log.getName()] = IRemote(log)
- return logs
-
- def remote_isFinished(self):
- return self.s.isFinished()
-
- def remote_waitUntilFinished(self):
- return self.s.waitUntilFinished() # returns a Deferred
-
- def remote_getETA(self):
- return self.s.getETA()
-
- def remote_getText(self):
- return self.s.getText()
-
- def remote_getResults(self):
- return self.s.getResults()
-
-components.registerAdapter(RemoteBuildStep,
- interfaces.IBuildStepStatus, IRemote)
-
-class RemoteSlave:
- def __init__(self, slave):
- self.s = slave
-
- def remote_getName(self):
- return self.s.getName()
- def remote_getAdmin(self):
- return self.s.getAdmin()
- def remote_getHost(self):
- return self.s.getHost()
- def remote_isConnected(self):
- return self.s.isConnected()
-
-components.registerAdapter(RemoteSlave,
- interfaces.ISlaveStatus, IRemote)
-
-class RemoteEvent:
- def __init__(self, event):
- self.e = event
-
- def remote_getTimes(self):
- return self.s.getTimes()
- def remote_getText(self):
- return self.s.getText()
-
-components.registerAdapter(RemoteEvent,
- interfaces.IStatusEvent, IRemote)
-
-class RemoteLog(pb.Referenceable):
- def __init__(self, log):
- self.l = log
-
- def remote_getName(self):
- return self.l.getName()
-
- def remote_isFinished(self):
- return self.l.isFinished()
- def remote_waitUntilFinished(self):
- d = self.l.waitUntilFinished()
- d.addCallback(lambda res: self)
- return d
-
- def remote_getText(self):
- return self.l.getText()
- def remote_getTextWithHeaders(self):
- return self.l.getTextWithHeaders()
- def remote_getChunks(self):
- return self.l.getChunks()
- # TODO: subscription interface
-
-components.registerAdapter(RemoteLog, logfile.LogFile, IRemote)
-# TODO: something similar for builder.HTMLLogfile ?
-
-class RemoteChange:
- def __init__(self, change):
- self.c = change
-
- def getWho(self):
- return self.c.who
- def getFiles(self):
- return self.c.files
- def getComments(self):
- return self.c.comments
-
-components.registerAdapter(RemoteChange, changes.Change, IRemote)
-
-
-class StatusClientPerspective(base.StatusReceiverPerspective):
-
- subscribed = None
- client = None
-
- def __init__(self, status):
- self.status = status # the IStatus
- self.subscribed_to_builders = [] # Builders to which we're subscribed
- self.subscribed_to = [] # everything else we're subscribed to
-
- def __getstate__(self):
- d = self.__dict__.copy()
- d['client'] = None
- return d
-
- def attached(self, mind):
- #twlog.msg("StatusClientPerspective.attached")
- return self
-
- def detached(self, mind):
- twlog.msg("PB client detached")
- self.client = None
- for name in self.subscribed_to_builders:
- twlog.msg(" unsubscribing from Builder(%s)" % name)
- self.status.getBuilder(name).unsubscribe(self)
- for s in self.subscribed_to:
- twlog.msg(" unsubscribe from %s" % s)
- s.unsubscribe(self)
- self.subscribed = None
-
- def perspective_subscribe(self, mode, interval, target):
- """The remote client wishes to subscribe to some set of events.
- 'target' will be sent remote messages when these events happen.
- 'mode' indicates which events are desired: it is a string with one
- of the following values:
-
- 'builders': builderAdded, builderRemoved
- 'builds': those plus builderChangedState, buildStarted, buildFinished
- 'steps': all those plus buildETAUpdate, stepStarted, stepFinished
- 'logs': all those plus stepETAUpdate, logStarted, logFinished
- 'full': all those plus logChunk (with the log contents)
-
-
- Messages are defined by buildbot.interfaces.IStatusReceiver .
- 'interval' is used to specify how frequently ETAUpdate messages
- should be sent.
-
- Raising or lowering the subscription level will take effect starting
- with the next build or step."""
-
- assert mode in ("builders", "builds", "steps", "logs", "full")
- assert target
- twlog.msg("PB subscribe(%s)" % mode)
-
- self.client = target
- self.subscribed = mode
- self.interval = interval
- self.subscribed_to.append(self.status)
- # wait a moment before subscribing, so the new-builder messages
- # won't appear before this remote method finishes
- eventually(self.status.subscribe, self)
- return None
-
- def perspective_unsubscribe(self):
- twlog.msg("PB unsubscribe")
- self.status.unsubscribe(self)
- self.subscribed_to.remove(self.status)
- self.client = None
-
- def perspective_getBuildSets(self):
- """This returns tuples of (buildset, bsid), because that is much more
- convenient for tryclient."""
- d = self.status.getBuildSets()
- def make_remotes(buildsets):
- return [(IRemote(s), s.id) for s in buildsets]
- d.addCallback(make_remotes)
- return d
-
- def perspective_getBuilderNames(self):
- return self.status.getBuilderNames()
-
- def perspective_getBuilder(self, name):
- b = self.status.getBuilder(name)
- return IRemote(b)
-
- def perspective_getSlave(self, name):
- s = self.status.getSlave(name)
- return IRemote(s)
-
- def perspective_ping(self):
- """Ping method to allow pb clients to validate their connections."""
- return "pong"
-
- # IStatusReceiver methods, invoked if we've subscribed
-
- # mode >= builder
- def builderAdded(self, name, builder):
- self.client.callRemote("builderAdded", name, IRemote(builder))
- if self.subscribed in ("builds", "steps", "logs", "full"):
- self.subscribed_to_builders.append(name)
- return self
- return None
-
- def builderChangedState(self, name, state):
- self.client.callRemote("builderChangedState", name, state, None)
- # TODO: remove leftover ETA argument
-
- def builderRemoved(self, name):
- if name in self.subscribed_to_builders:
- self.subscribed_to_builders.remove(name)
- self.client.callRemote("builderRemoved", name)
-
- def buildsetSubmitted(self, buildset):
- # TODO: deliver to client, somehow
- pass
-
- # mode >= builds
- def buildStarted(self, name, build):
- self.client.callRemote("buildStarted", name, IRemote(build))
- if self.subscribed in ("steps", "logs", "full"):
- self.subscribed_to.append(build)
- return (self, self.interval)
- return None
-
- def buildFinished(self, name, build, results):
- if build in self.subscribed_to:
- # we might have joined during the build
- self.subscribed_to.remove(build)
- self.client.callRemote("buildFinished",
- name, IRemote(build), results)
-
- # mode >= steps
- def buildETAUpdate(self, build, eta):
- self.client.callRemote("buildETAUpdate",
- build.getBuilder().getName(), IRemote(build),
- eta)
-
- def stepStarted(self, build, step):
- # we add some information here so the client doesn't have to do an
- # extra round-trip
- self.client.callRemote("stepStarted",
- build.getBuilder().getName(), IRemote(build),
- step.getName(), IRemote(step))
- if self.subscribed in ("logs", "full"):
- self.subscribed_to.append(step)
- return (self, self.interval)
- return None
-
- def stepFinished(self, build, step, results):
- self.client.callRemote("stepFinished",
- build.getBuilder().getName(), IRemote(build),
- step.getName(), IRemote(step),
- results)
- if step in self.subscribed_to:
- # eventually (through some new subscription method) we could
- # join in the middle of the step
- self.subscribed_to.remove(step)
-
- # mode >= logs
- def stepETAUpdate(self, build, step, ETA, expectations):
- self.client.callRemote("stepETAUpdate",
- build.getBuilder().getName(), IRemote(build),
- step.getName(), IRemote(step),
- ETA, expectations)
-
- def logStarted(self, build, step, log):
- # TODO: make the HTMLLog adapter
- rlog = IRemote(log, None)
- if not rlog:
- print "hey, couldn't adapt %s to IRemote" % log
- self.client.callRemote("logStarted",
- build.getBuilder().getName(), IRemote(build),
- step.getName(), IRemote(step),
- log.getName(), IRemote(log, None))
- if self.subscribed in ("full",):
- self.subscribed_to.append(log)
- return self
- return None
-
- def logFinished(self, build, step, log):
- self.client.callRemote("logFinished",
- build.getBuilder().getName(), IRemote(build),
- step.getName(), IRemote(step),
- log.getName(), IRemote(log, None))
- if log in self.subscribed_to:
- self.subscribed_to.remove(log)
-
- # mode >= full
- def logChunk(self, build, step, log, channel, text):
- self.client.callRemote("logChunk",
- build.getBuilder().getName(), IRemote(build),
- step.getName(), IRemote(step),
- log.getName(), IRemote(log),
- channel, text)
-
-
-class PBListener(base.StatusReceiverMultiService):
- """I am a listener for PB-based status clients."""
-
- compare_attrs = ["port", "cred"]
- implements(portal.IRealm)
-
- def __init__(self, port, user="statusClient", passwd="clientpw"):
- base.StatusReceiverMultiService.__init__(self)
- if type(port) is int:
- port = "tcp:%d" % port
- self.port = port
- self.cred = (user, passwd)
- p = portal.Portal(self)
- c = checkers.InMemoryUsernamePasswordDatabaseDontUse()
- c.addUser(user, passwd)
- p.registerChecker(c)
- f = pb.PBServerFactory(p)
- s = strports.service(port, f)
- s.setServiceParent(self)
-
- def setServiceParent(self, parent):
- base.StatusReceiverMultiService.setServiceParent(self, parent)
- self.status = parent
-
- def requestAvatar(self, avatarID, mind, interface):
- assert interface == pb.IPerspective
- p = StatusClientPerspective(self.status)
- p.attached(mind) # perhaps .callLater(0) ?
- return (pb.IPerspective, p,
- lambda p=p,mind=mind: p.detached(mind))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/event.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/event.py
deleted file mode 100644
index 8e072931..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/event.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# 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
-
-from zope.interface import implements
-from buildbot import interfaces, util
-
-class Event:
- implements(interfaces.IStatusEvent)
-
- started = None
- finished = None
- text = []
-
- # IStatusEvent methods
- def getTimes(self):
- return (self.started, self.finished)
- def getText(self):
- return self.text
- def getLogs(self):
- return []
-
- def finish(self):
- self.finished = util.now()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/html.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/html.py
deleted file mode 100644
index a0fc5755..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/html.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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
-
-
-# compatibility wrapper. This is currently the preferred place for master.cfg
-# to import from.
-
-from buildbot.status.web.baseweb import WebStatus
-_hush_pyflakes = [WebStatus]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/logfile.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/logfile.py
deleted file mode 100644
index bd1d686d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/logfile.py
+++ /dev/null
@@ -1,699 +0,0 @@
-# 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 os
-from cStringIO import StringIO
-from bz2 import BZ2File
-from gzip import GzipFile
-
-from zope.interface import implements
-from twisted.python import log, runtime
-from twisted.internet import defer, threads, reactor
-from buildbot.util import netstrings
-from buildbot.util.eventual import eventually
-from buildbot import interfaces
-
-STDOUT = interfaces.LOG_CHANNEL_STDOUT
-STDERR = interfaces.LOG_CHANNEL_STDERR
-HEADER = interfaces.LOG_CHANNEL_HEADER
-ChunkTypes = ["stdout", "stderr", "header"]
-
-class LogFileScanner(netstrings.NetstringParser):
- def __init__(self, chunk_cb, channels=[]):
- self.chunk_cb = chunk_cb
- self.channels = channels
- netstrings.NetstringParser.__init__(self)
-
- def stringReceived(self, line):
- channel = int(line[0])
- if not self.channels or (channel in self.channels):
- self.chunk_cb((channel, line[1:]))
-
-class LogFileProducer:
- """What's the plan?
-
- the LogFile has just one FD, used for both reading and writing.
- Each time you add an entry, fd.seek to the end and then write.
-
- Each reader (i.e. Producer) keeps track of their own offset. The reader
- starts by seeking to the start of the logfile, and reading forwards.
- Between each hunk of file they yield chunks, so they must remember their
- offset before yielding and re-seek back to that offset before reading
- more data. When their read() returns EOF, they're finished with the first
- phase of the reading (everything that's already been written to disk).
-
- After EOF, the remaining data is entirely in the current entries list.
- These entries are all of the same channel, so we can do one "".join and
- obtain a single chunk to be sent to the listener. But since that involves
- a yield, and more data might arrive after we give up control, we have to
- subscribe them before yielding. We can't subscribe them any earlier,
- otherwise they'd get data out of order.
-
- We're using a generator in the first place so that the listener can
- throttle us, which means they're pulling. But the subscription means
- we're pushing. Really we're a Producer. In the first phase we can be
- either a PullProducer or a PushProducer. In the second phase we're only a
- PushProducer.
-
- So the client gives a LogFileConsumer to File.subscribeConsumer . This
- Consumer must have registerProducer(), unregisterProducer(), and
- writeChunk(), and is just like a regular twisted.interfaces.IConsumer,
- except that writeChunk() takes chunks (tuples of (channel,text)) instead
- of the normal write() which takes just text. The LogFileConsumer is
- allowed to call stopProducing, pauseProducing, and resumeProducing on the
- producer instance it is given. """
-
- paused = False
- subscribed = False
- BUFFERSIZE = 2048
-
- def __init__(self, logfile, consumer):
- self.logfile = logfile
- self.consumer = consumer
- self.chunkGenerator = self.getChunks()
- consumer.registerProducer(self, True)
-
- def getChunks(self):
- f = self.logfile.getFile()
- offset = 0
- chunks = []
- p = LogFileScanner(chunks.append)
- f.seek(offset)
- data = f.read(self.BUFFERSIZE)
- offset = f.tell()
- while data:
- p.dataReceived(data)
- while chunks:
- yield chunks.pop(0)
- f.seek(offset)
- data = f.read(self.BUFFERSIZE)
- offset = f.tell()
- del f
-
- # now subscribe them to receive new entries
- self.subscribed = True
- self.logfile.watchers.append(self)
- d = self.logfile.waitUntilFinished()
-
- # then give them the not-yet-merged data
- if self.logfile.runEntries:
- channel = self.logfile.runEntries[0][0]
- text = "".join([c[1] for c in self.logfile.runEntries])
- yield (channel, text)
-
- # now we've caught up to the present. Anything further will come from
- # the logfile subscription. We add the callback *after* yielding the
- # data from runEntries, because the logfile might have finished
- # during the yield.
- d.addCallback(self.logfileFinished)
-
- def stopProducing(self):
- # TODO: should we still call consumer.finish? probably not.
- self.paused = True
- self.consumer = None
- self.done()
-
- def done(self):
- if self.chunkGenerator:
- self.chunkGenerator = None # stop making chunks
- if self.subscribed:
- self.logfile.watchers.remove(self)
- self.subscribed = False
-
- def pauseProducing(self):
- self.paused = True
-
- def resumeProducing(self):
- # Twisted-1.3.0 has a bug which causes hangs when resumeProducing
- # calls transport.write (there is a recursive loop, fixed in 2.0 in
- # t.i.abstract.FileDescriptor.doWrite by setting the producerPaused
- # flag *before* calling resumeProducing). To work around this, we
- # just put off the real resumeProducing for a moment. This probably
- # has a performance hit, but I'm going to assume that the log files
- # are not retrieved frequently enough for it to be an issue.
-
- eventually(self._resumeProducing)
-
- def _resumeProducing(self):
- self.paused = False
- if not self.chunkGenerator:
- return
- try:
- while not self.paused:
- chunk = self.chunkGenerator.next()
- self.consumer.writeChunk(chunk)
- # we exit this when the consumer says to stop, or we run out
- # of chunks
- except StopIteration:
- # if the generator finished, it will have done releaseFile
- self.chunkGenerator = None
- # now everything goes through the subscription, and they don't get to
- # pause anymore
-
- def logChunk(self, build, step, logfile, channel, chunk):
- if self.consumer:
- self.consumer.writeChunk((channel, chunk))
-
- def logfileFinished(self, logfile):
- self.done()
- if self.consumer:
- self.consumer.unregisterProducer()
- self.consumer.finish()
- self.consumer = None
-
-class LogFile:
- """
- A LogFile keeps all of its contents on disk, in a non-pickle format to
- which new entries can easily be appended. The file on disk has a name like
- 12-log-compile-output, under the Builder's directory. The actual filename
- is generated (before the LogFile is created) by
- L{BuildStatus.generateLogfileName}.
-
- @ivar length: length of the data in the logfile (sum of chunk sizes; not
- the length of the on-disk encoding)
- """
-
- implements(interfaces.IStatusLog, interfaces.ILogFile)
-
- finished = False
- length = 0
- nonHeaderLength = 0
- tailLength = 0
- chunkSize = 10*1000
- runLength = 0
- # No max size by default
- # Don't keep a tail buffer by default
- logMaxTailSize = None
- maxLengthExceeded = False
- runEntries = [] # provided so old pickled builds will getChunks() ok
- entries = None
- BUFFERSIZE = 2048
- filename = None # relative to the Builder's basedir
- openfile = None
-
- def __init__(self, parent, name, logfilename):
- """
- @type parent: L{BuildStepStatus}
- @param parent: the Step that this log is a part of
- @type name: string
- @param name: the name of this log, typically 'output'
- @type logfilename: string
- @param logfilename: the Builder-relative pathname for the saved entries
- """
- self.step = parent
- self.master = parent.build.builder.master
- self.name = name
- self.filename = logfilename
- fn = self.getFilename()
- if os.path.exists(fn):
- # the buildmaster was probably stopped abruptly, before the
- # BuilderStatus could be saved, so BuilderStatus.nextBuildNumber
- # is out of date, and we're overlapping with earlier builds now.
- # Warn about it, but then overwrite the old pickle file
- log.msg("Warning: Overwriting old serialized Build at %s" % fn)
- dirname = os.path.dirname(fn)
- if not os.path.exists(dirname):
- os.makedirs(dirname)
- self.openfile = open(fn, "w+")
- self.runEntries = []
- self.watchers = []
- self.finishedWatchers = []
- self.tailBuffer = []
-
- def getFilename(self):
- """
- Get the base (uncompressed) filename for this log file.
-
- @returns: filename
- """
- return os.path.join(self.step.build.builder.basedir, self.filename)
-
- def hasContents(self):
- """
- Return true if this logfile's contents are available. For a newly
- created logfile, this is always true, but for a L{LogFile} instance
- that has been persisted, the logfiles themselves may have been deleted,
- in which case this method will return False.
-
- @returns: boolean
- """
- return os.path.exists(self.getFilename() + '.bz2') or \
- os.path.exists(self.getFilename() + '.gz') or \
- os.path.exists(self.getFilename())
-
- def getName(self):
- """
- Get this logfile's name
-
- @returns: string
- """
- return self.name
-
- def getStep(self):
- """
- Get the L{BuildStepStatus} instance containing this logfile
-
- @returns: L{BuildStepStatus} instance
- """
- return self.step
-
- def isFinished(self):
- """
- Return true if this logfile is finished (that is, if it will not
- receive any additional data
-
- @returns: boolean
- """
-
- return self.finished
-
- def waitUntilFinished(self):
- """
- Return a Deferred that will fire when this logfile is finished, or will
- fire immediately if the logfile is already finished.
- """
- if self.finished:
- d = defer.succeed(self)
- else:
- d = defer.Deferred()
- self.finishedWatchers.append(d)
- return d
-
- def getFile(self):
- """
- Get an open file object for this log. The file may also be in use for
- writing, so it should not be closed by the caller, and the caller
- should not rely on its file position remaining constant between
- asynchronous code segments.
-
- @returns: file object
- """
- if self.openfile:
- # this is the filehandle we're using to write to the log, so
- # don't close it!
- return self.openfile
- # otherwise they get their own read-only handle
- # try a compressed log first
- try:
- return BZ2File(self.getFilename() + ".bz2", "r")
- except IOError:
- pass
- try:
- return GzipFile(self.getFilename() + ".gz", "r")
- except IOError:
- pass
- return open(self.getFilename(), "r")
-
- def getText(self):
- # this produces one ginormous string
- return "".join(self.getChunks([STDOUT, STDERR], onlyText=True))
-
- def getTextWithHeaders(self):
- return "".join(self.getChunks(onlyText=True))
-
- def getChunks(self, channels=[], onlyText=False):
- # generate chunks for everything that was logged at the time we were
- # first called, so remember how long the file was when we started.
- # Don't read beyond that point. The current contents of
- # self.runEntries will follow.
-
- # this returns an iterator, which means arbitrary things could happen
- # while we're yielding. This will faithfully deliver the log as it
- # existed when it was started, and not return anything after that
- # point. To use this in subscribe(catchup=True) without missing any
- # data, you must insure that nothing will be added to the log during
- # yield() calls.
-
- f = self.getFile()
- if not self.finished:
- offset = 0
- f.seek(0, 2)
- remaining = f.tell()
- else:
- offset = 0
- remaining = None
-
- leftover = None
- if self.runEntries and (not channels or
- (self.runEntries[0][0] in channels)):
- leftover = (self.runEntries[0][0],
- "".join([c[1] for c in self.runEntries]))
-
- # freeze the state of the LogFile by passing a lot of parameters into
- # a generator
- return self._generateChunks(f, offset, remaining, leftover,
- channels, onlyText)
-
- def _generateChunks(self, f, offset, remaining, leftover,
- channels, onlyText):
- chunks = []
- p = LogFileScanner(chunks.append, channels)
- f.seek(offset)
- if remaining is not None:
- data = f.read(min(remaining, self.BUFFERSIZE))
- remaining -= len(data)
- else:
- data = f.read(self.BUFFERSIZE)
-
- offset = f.tell()
- while data:
- p.dataReceived(data)
- while chunks:
- channel, text = chunks.pop(0)
- if onlyText:
- yield text
- else:
- yield (channel, text)
- f.seek(offset)
- if remaining is not None:
- data = f.read(min(remaining, self.BUFFERSIZE))
- remaining -= len(data)
- else:
- data = f.read(self.BUFFERSIZE)
- offset = f.tell()
- del f
-
- if leftover:
- if onlyText:
- yield leftover[1]
- else:
- yield leftover
-
- def readlines(self):
- """Return an iterator that produces newline-terminated lines,
- excluding header chunks."""
- alltext = "".join(self.getChunks([STDOUT], onlyText=True))
- io = StringIO(alltext)
- return io.readlines()
-
- def subscribe(self, receiver, catchup):
- if self.finished:
- return
- self.watchers.append(receiver)
- if catchup:
- for channel, text in self.getChunks():
- # TODO: add logChunks(), to send over everything at once?
- receiver.logChunk(self.step.build, self.step, self,
- channel, text)
-
- def unsubscribe(self, receiver):
- if receiver in self.watchers:
- self.watchers.remove(receiver)
-
- def subscribeConsumer(self, consumer):
- p = LogFileProducer(self, consumer)
- p.resumeProducing()
-
- # interface used by the build steps to add things to the log
-
- def _merge(self):
- # merge all .runEntries (which are all of the same type) into a
- # single chunk for .entries
- if not self.runEntries:
- return
- channel = self.runEntries[0][0]
- text = "".join([c[1] for c in self.runEntries])
- assert channel < 10, "channel number must be a single decimal digit"
- f = self.openfile
- f.seek(0, 2)
- offset = 0
- while offset < len(text):
- size = min(len(text)-offset, self.chunkSize)
- f.write("%d:%d" % (1 + size, channel))
- f.write(text[offset:offset+size])
- f.write(",")
- offset += size
- self.runEntries = []
- self.runLength = 0
-
- def addEntry(self, channel, text, _no_watchers=False):
- """
- Add an entry to the logfile. The C{channel} is one of L{STDOUT},
- L{STDERR}, or L{HEADER}. The C{text} is the text to add to the
- logfile, which can be a unicode string or a bytestring which is
- presumed to be encoded with utf-8.
-
- This method cannot be called after the logfile is finished.
-
- @param channel: channel to add a chunk for
- @param text: chunk of text
- @param _no_watchers: private
- """
-
- assert not self.finished, "logfile is already finished"
-
- if isinstance(text, unicode):
- text = text.encode('utf-8')
-
- # notify watchers first, before the chunk gets munged, so that they get
- # a complete picture of the actual log output
- # TODO: is this right, or should the watchers get a picture of the chunks?
- if not _no_watchers:
- for w in self.watchers:
- w.logChunk(self.step.build, self.step, self, channel, text)
-
- if channel != HEADER:
- # Truncate the log if it's more than logMaxSize bytes
- logMaxSize = self.master.config.logMaxSize
- logMaxTailSize = self.master.config.logMaxTailSize
- if logMaxSize:
- self.nonHeaderLength += len(text)
- if self.nonHeaderLength > logMaxSize:
- # Add a message about what's going on and truncate this
- # chunk if necessary
- if not self.maxLengthExceeded:
- if self.runEntries and channel != self.runEntries[0][0]:
- self._merge()
- i = -(self.nonHeaderLength - logMaxSize)
- trunc, text = text[:i], text[i:]
- self.runEntries.append((channel, trunc))
- self._merge()
- msg = ("\nOutput exceeded %i bytes, remaining output "
- "has been truncated\n" % logMaxSize)
- self.runEntries.append((HEADER, msg))
- self.maxLengthExceeded = True
-
- # and track the tail of the text
- if logMaxTailSize and text:
- # Update the tail buffer
- self.tailBuffer.append((channel, text))
- self.tailLength += len(text)
- while self.tailLength > logMaxTailSize:
- # Drop some stuff off the beginning of the buffer
- c,t = self.tailBuffer.pop(0)
- n = len(t)
- self.tailLength -= n
- assert self.tailLength >= 0
- return
-
- # we only add to .runEntries here. _merge() is responsible for adding
- # merged chunks to .entries
- if self.runEntries and channel != self.runEntries[0][0]:
- self._merge()
- self.runEntries.append((channel, text))
- self.runLength += len(text)
- if self.runLength >= self.chunkSize:
- self._merge()
-
- self.length += len(text)
-
- def addStdout(self, text):
- """
- Shortcut to add stdout text to the logfile
-
- @param text: text to add to the logfile
- """
- self.addEntry(STDOUT, text)
-
- def addStderr(self, text):
- """
- Shortcut to add stderr text to the logfile
-
- @param text: text to add to the logfile
- """
- self.addEntry(STDERR, text)
-
- def addHeader(self, text):
- """
- Shortcut to add header text to the logfile
-
- @param text: text to add to the logfile
- """
- self.addEntry(HEADER, text)
-
- def finish(self):
- """
- Finish the logfile, flushing any buffers and preventing any further
- writes to the log.
- """
- self._merge()
- if self.tailBuffer:
- msg = "\nFinal %i bytes follow below:\n" % self.tailLength
- tmp = self.runEntries
- self.runEntries = [(HEADER, msg)]
- self._merge()
- self.runEntries = self.tailBuffer
- self._merge()
- self.runEntries = tmp
- self._merge()
- self.tailBuffer = []
-
- if self.openfile:
- # we don't do an explicit close, because there might be readers
- # shareing the filehandle. As soon as they stop reading, the
- # filehandle will be released and automatically closed.
- self.openfile.flush()
- self.openfile = None
- self.finished = True
- watchers = self.finishedWatchers
- self.finishedWatchers = []
- for w in watchers:
- w.callback(self)
- self.watchers = []
-
-
- def compressLog(self):
- logCompressionMethod = self.master.config.logCompressionMethod
- # bail out if there's no compression support
- if logCompressionMethod == "bz2":
- compressed = self.getFilename() + ".bz2.tmp"
- elif logCompressionMethod == "gz":
- compressed = self.getFilename() + ".gz.tmp"
- else:
- return defer.succeed(None)
-
- def _compressLog():
- infile = self.getFile()
- if logCompressionMethod == "bz2":
- cf = BZ2File(compressed, 'w')
- elif logCompressionMethod == "gz":
- cf = GzipFile(compressed, 'w')
- bufsize = 1024*1024
- while True:
- buf = infile.read(bufsize)
- cf.write(buf)
- if len(buf) < bufsize:
- break
- cf.close()
- d = threads.deferToThread(_compressLog)
-
- def _renameCompressedLog(rv):
- if logCompressionMethod == "bz2":
- filename = self.getFilename() + '.bz2'
- else:
- filename = self.getFilename() + '.gz'
- if runtime.platformType == 'win32':
- # windows cannot rename a file on top of an existing one, so
- # fall back to delete-first. There are ways this can fail and
- # lose the builder's history, so we avoid using it in the
- # general (non-windows) case
- if os.path.exists(filename):
- os.unlink(filename)
- os.rename(compressed, filename)
- _tryremove(self.getFilename(), 1, 5)
- d.addCallback(_renameCompressedLog)
-
- def _cleanupFailedCompress(failure):
- log.msg("failed to compress %s" % self.getFilename())
- if os.path.exists(compressed):
- _tryremove(compressed, 1, 5)
- failure.trap() # reraise the failure
- d.addErrback(_cleanupFailedCompress)
- return d
-
-
- # persistence stuff
- def __getstate__(self):
- d = self.__dict__.copy()
- del d['step'] # filled in upon unpickling
- del d['watchers']
- del d['finishedWatchers']
- del d['master']
- d['entries'] = [] # let 0.6.4 tolerate the saved log. TODO: really?
- if d.has_key('finished'):
- del d['finished']
- if d.has_key('openfile'):
- del d['openfile']
- return d
-
- def __setstate__(self, d):
- self.__dict__ = d
- self.watchers = [] # probably not necessary
- self.finishedWatchers = [] # same
- # self.step must be filled in by our parent
- self.finished = True
-
-class HTMLLogFile:
- implements(interfaces.IStatusLog)
-
- filename = None
-
- def __init__(self, parent, name, logfilename, html):
- self.step = parent
- self.name = name
- self.filename = logfilename
- self.html = html
-
- def getName(self):
- return self.name # set in BuildStepStatus.addLog
- def getStep(self):
- return self.step
-
- def isFinished(self):
- return True
- def waitUntilFinished(self):
- return defer.succeed(self)
-
- def hasContents(self):
- return True
- def getText(self):
- return self.html # looks kinda like text
- def getTextWithHeaders(self):
- return self.html
- def getChunks(self):
- return [(STDERR, self.html)]
-
- def subscribe(self, receiver, catchup):
- pass
- def unsubscribe(self, receiver):
- pass
-
- def finish(self):
- pass
-
- def __getstate__(self):
- d = self.__dict__.copy()
- del d['step']
- if d.has_key('master'):
- del d['master']
- return d
-
-
-def _tryremove(filename, timeout, retries):
- """Try to remove a file, and if failed, try again in timeout.
- Increases the timeout by a factor of 4, and only keeps trying for
- another retries-amount of times.
-
- """
- try:
- os.unlink(filename)
- except OSError:
- if retries > 0:
- reactor.callLater(timeout, _tryremove, filename, timeout * 4,
- retries - 1)
- else:
- log.msg("giving up on removing %s after over %d seconds" %
- (filename, timeout))
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/mail.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/mail.py
deleted file mode 100644
index ef48d8e2..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/mail.py
+++ /dev/null
@@ -1,798 +0,0 @@
-# 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 re
-import types
-from email.Message import Message
-from email.Utils import formatdate
-from email.MIMEText import MIMEText
-from email.MIMENonMultipart import MIMENonMultipart
-from email.MIMEMultipart import MIMEMultipart
-from StringIO import StringIO
-import urllib
-
-from zope.interface import implements
-from twisted.internet import defer, reactor
-from twisted.python import log as twlog
-
-try:
- from twisted.mail.smtp import ESMTPSenderFactory
- ESMTPSenderFactory = ESMTPSenderFactory # for pyflakes
-except ImportError:
- ESMTPSenderFactory = None
-
-have_ssl = True
-try:
- from twisted.internet import ssl
- from OpenSSL.SSL import SSLv3_METHOD
-except ImportError:
- have_ssl = False
-
-# this incantation teaches email to output utf-8 using 7- or 8-bit encoding,
-# although it has no effect before python-2.7.
-from email import Charset
-Charset.add_charset('utf-8', Charset.SHORTEST, None, 'utf-8')
-
-from buildbot import interfaces, util, config
-from buildbot.process.users import users
-from buildbot.status import base
-from buildbot.status.results import FAILURE, SUCCESS, WARNINGS, EXCEPTION, Results
-
-VALID_EMAIL = re.compile("[a-zA-Z0-9\.\_\%\-\+]+@[a-zA-Z0-9\.\_\%\-]+.[a-zA-Z]{2,6}")
-
-ENCODING = 'utf8'
-LOG_ENCODING = 'utf-8'
-
-class Domain(util.ComparableMixin):
- implements(interfaces.IEmailLookup)
- compare_attrs = ["domain"]
-
- def __init__(self, domain):
- assert "@" not in domain
- self.domain = domain
-
- def getAddress(self, name):
- """If name is already an email address, pass it through."""
- if '@' in name:
- return name
- return name + "@" + self.domain
-
-
-def defaultMessage(mode, name, build, results, master_status):
- """Generate a buildbot mail message and return a tuple of message text
- and type."""
- ss_list = build.getSourceStamps()
-
- prev = build.getPreviousBuild()
-
- text = ""
- if results == FAILURE:
- if "change" in mode and prev and prev.getResults() != results or \
- "problem" in mode and prev and prev.getResults() != FAILURE:
- text += "The Buildbot has detected a new failure"
- else:
- text += "The Buildbot has detected a failed build"
- elif results == WARNINGS:
- text += "The Buildbot has detected a problem in the build"
- elif results == SUCCESS:
- if "change" in mode and prev and prev.getResults() != results:
- text += "The Buildbot has detected a restored build"
- else:
- text += "The Buildbot has detected a passing build"
- elif results == EXCEPTION:
- text += "The Buildbot has detected a build exception"
-
- projects = []
- if ss_list:
- for ss in ss_list:
- if ss.project and ss.project not in projects:
- projects.append(ss.project)
- if not projects:
- projects = [master_status.getTitle()]
- text += " on builder %s while building %s.\n" % (name, ', '.join(projects))
-
- if master_status.getURLForThing(build):
- text += "Full details are available at:\n %s\n" % master_status.getURLForThing(build)
- text += "\n"
-
- if master_status.getBuildbotURL():
- text += "Buildbot URL: %s\n\n" % urllib.quote(master_status.getBuildbotURL(), '/:')
-
- text += "Buildslave for this Build: %s\n\n" % build.getSlavename()
- text += "Build Reason: %s\n" % build.getReason()
-
- for ss in ss_list:
- source = ""
- if ss and ss.branch:
- source += "[branch %s] " % ss.branch
- if ss and ss.revision:
- source += str(ss.revision)
- else:
- source += "HEAD"
- if ss and ss.patch:
- source += " (plus patch)"
-
- discriminator = ""
- if ss.codebase:
- discriminator = " '%s'" % ss.codebase
- text += "Build Source Stamp%s: %s\n" % (discriminator, source)
-
- text += "Blamelist: %s\n" % ",".join(build.getResponsibleUsers())
-
- text += "\n"
-
- t = build.getText()
- if t:
- t = ": " + " ".join(t)
- else:
- t = ""
-
- if results == SUCCESS:
- text += "Build succeeded!\n"
- elif results == WARNINGS:
- text += "Build Had Warnings%s\n" % t
- else:
- text += "BUILD FAILED%s\n" % t
-
- text += "\n"
- text += "sincerely,\n"
- text += " -The Buildbot\n"
- text += "\n"
- return { 'body' : text, 'type' : 'plain' }
-
-def defaultGetPreviousBuild(current_build):
- return current_build.getPreviousBuild()
-
-class MailNotifier(base.StatusReceiverMultiService):
- """This is a status notifier which sends email to a list of recipients
- upon the completion of each build. It can be configured to only send out
- mail for certain builds, and only send messages when the build fails, or
- when it transitions from success to failure. It can also be configured to
- include various build logs in each message.
-
- By default, the message will be sent to the Interested Users list, which
- includes all developers who made changes in the build. You can add
- additional recipients with the extraRecipients argument.
-
- To get a simple one-message-per-build (say, for a mailing list), use
- sendToInterestedUsers=False, extraRecipients=['listaddr@example.org']
-
- Each MailNotifier sends mail to a single set of recipients. To send
- different kinds of mail to different recipients, use multiple
- MailNotifiers.
- """
-
- implements(interfaces.IEmailSender)
-
- compare_attrs = ["extraRecipients", "lookup", "fromaddr", "mode",
- "categories", "builders", "addLogs", "relayhost",
- "subject", "sendToInterestedUsers", "customMesg",
- "messageFormatter", "extraHeaders"]
-
- possible_modes = ("change", "failing", "passing", "problem", "warnings", "exception")
-
- def __init__(self, fromaddr, mode=("failing", "passing", "warnings"),
- categories=None, builders=None, addLogs=False,
- relayhost="localhost", buildSetSummary=False,
- subject="buildbot %(result)s in %(title)s on %(builder)s",
- lookup=None, extraRecipients=[],
- sendToInterestedUsers=True, customMesg=None,
- messageFormatter=defaultMessage, extraHeaders=None,
- addPatch=True, useTls=False,
- smtpUser=None, smtpPassword=None, smtpPort=25,
- previousBuildGetter=defaultGetPreviousBuild):
- """
- @type fromaddr: string
- @param fromaddr: the email address to be used in the 'From' header.
- @type sendToInterestedUsers: boolean
- @param sendToInterestedUsers: if True (the default), send mail to all
- of the Interested Users. If False, only
- send mail to the extraRecipients list.
-
- @type extraRecipients: tuple of strings
- @param extraRecipients: a list of email addresses to which messages
- should be sent (in addition to the
- InterestedUsers list, which includes any
- developers who made Changes that went into this
- build). It is a good idea to create a small
- mailing list and deliver to that, then let
- subscribers come and go as they please. The
- addresses in this list are used literally (they
- are not processed by lookup).
-
- @type subject: string
- @param subject: a string to be used as the subject line of the message.
- %(builder)s will be replaced with the name of the
- builder which provoked the message.
-
- @type mode: list of strings
- @param mode: a list of MailNotifer.possible_modes:
- - "change": send mail about builds which change status
- - "failing": send mail about builds which fail
- - "passing": send mail about builds which succeed
- - "problem": send mail about a build which failed
- when the previous build passed
- - "warnings": send mail if a build contain warnings
- - "exception": send mail if a build fails due to an exception
- - "all": always send mail
- Defaults to ("failing", "passing", "warnings").
-
- @type builders: list of strings
- @param builders: a list of builder names for which mail should be
- sent. Defaults to None (send mail for all builds).
- Use either builders or categories, but not both.
-
- @type categories: list of strings
- @param categories: a list of category names to serve status
- information for. Defaults to None (all
- categories). Use either builders or categories,
- but not both.
-
- @type addLogs: boolean
- @param addLogs: if True, include all build logs as attachments to the
- messages. These can be quite large. This can also be
- set to a list of log names, to send a subset of the
- logs. Defaults to False.
-
- @type addPatch: boolean
- @param addPatch: if True, include the patch when the source stamp
- includes one.
-
- @type relayhost: string
- @param relayhost: the host to which the outbound SMTP connection
- should be made. Defaults to 'localhost'
-
- @type buildSetSummary: boolean
- @param buildSetSummary: if True, this notifier will only send a summary
- email when a buildset containing any of its
- watched builds completes
-
- @type lookup: implementor of {IEmailLookup}
- @param lookup: object which provides IEmailLookup, which is
- responsible for mapping User names for Interested
- Users (which come from the VC system) into valid
- email addresses. If not provided, the notifier will
- only be able to send mail to the addresses in the
- extraRecipients list. Most of the time you can use a
- simple Domain instance. As a shortcut, you can pass
- as string: this will be treated as if you had provided
- Domain(str). For example, lookup='twistedmatrix.com'
- will allow mail to be sent to all developers whose SVN
- usernames match their twistedmatrix.com account names.
-
- @type customMesg: func
- @param customMesg: (this function is deprecated)
-
- @type messageFormatter: func
- @param messageFormatter: function taking (mode, name, build, result,
- master_status) and returning a dictionary
- containing two required keys "body" and "type",
- with a third optional key, "subject". The
- "body" key gives a string that contains the
- complete text of the message. The "type" key
- is the message type ('plain' or 'html'). The
- 'html' type should be used when generating an
- HTML message. The optional "subject" key
- gives the subject for the email.
-
- @type extraHeaders: dict
- @param extraHeaders: A dict of extra headers to add to the mail. It's
- best to avoid putting 'To', 'From', 'Date',
- 'Subject', or 'CC' in here. Both the names and
- values may be WithProperties instances.
-
- @type useTls: boolean
- @param useTls: Send emails using TLS and authenticate with the
- smtp host. Defaults to False.
-
- @type smtpUser: string
- @param smtpUser: The user that will attempt to authenticate with the
- relayhost when useTls is True.
-
- @type smtpPassword: string
- @param smtpPassword: The password that smtpUser will use when
- authenticating with relayhost.
-
- @type smtpPort: int
- @param smtpPort: The port that will be used when connecting to the
- relayhost. Defaults to 25.
-
- @type previousBuildGetter: func
- @param previousBuildGetter: function taking a BuildStatus instance
- returning a BuildStatus of the build
- previous to the one passed in. This allows
- to implement a relative ordering between
- builds other than the default one, which is
- chronological.
- """
- base.StatusReceiverMultiService.__init__(self)
-
- if not isinstance(extraRecipients, (list, tuple)):
- config.error("extraRecipients must be a list or tuple")
- else:
- for r in extraRecipients:
- if not isinstance(r, str) or not VALID_EMAIL.search(r):
- config.error(
- "extra recipient %r is not a valid email" % (r,))
- self.extraRecipients = extraRecipients
- self.sendToInterestedUsers = sendToInterestedUsers
- self.fromaddr = fromaddr
- if isinstance(mode, basestring):
- if mode == "all":
- mode = ("failing", "passing", "warnings", "exception")
- elif mode == "warnings":
- mode = ("failing", "warnings")
- else:
- mode = (mode,)
- for m in mode:
- if m not in self.possible_modes:
- config.error(
- "mode %s is not a valid mode" % (m,))
- self.mode = mode
- self.categories = categories
- self.builders = builders
- self.addLogs = addLogs
- self.relayhost = relayhost
- if '\n' in subject:
- config.error(
- 'Newlines are not allowed in email subjects')
- self.subject = subject
- if lookup is not None:
- if type(lookup) is str:
- lookup = Domain(lookup)
- assert interfaces.IEmailLookup.providedBy(lookup)
- self.lookup = lookup
- self.customMesg = customMesg
- self.messageFormatter = messageFormatter
- if extraHeaders:
- if not isinstance(extraHeaders, dict):
- config.error("extraHeaders must be a dictionary")
- self.extraHeaders = extraHeaders
- self.addPatch = addPatch
- self.useTls = useTls
- self.smtpUser = smtpUser
- self.smtpPassword = smtpPassword
- self.smtpPort = smtpPort
- self.buildSetSummary = buildSetSummary
- self.buildSetSubscription = None
- self.getPreviousBuild = previousBuildGetter
- self.watched = []
- self.master_status = None
-
- # you should either limit on builders or categories, not both
- if self.builders != None and self.categories != None:
- config.error(
- "Please specify only builders or categories to include - " +
- "not both.")
-
- if customMesg:
- config.error(
- "customMesg is deprecated; use messageFormatter instead")
-
- def setServiceParent(self, parent):
- """
- @type parent: L{buildbot.master.BuildMaster}
- """
- base.StatusReceiverMultiService.setServiceParent(self, parent)
- self.master_status = self.parent
- self.master_status.subscribe(self)
- self.master = self.master_status.master
-
- def startService(self):
- if self.buildSetSummary:
- self.buildSetSubscription = \
- self.master.subscribeToBuildsetCompletions(self.buildsetFinished)
-
- base.StatusReceiverMultiService.startService(self)
-
- def stopService(self):
- if self.buildSetSubscription is not None:
- self.buildSetSubscription.unsubscribe()
- self.buildSetSubscription = None
-
- return base.StatusReceiverMultiService.stopService(self)
-
- def disownServiceParent(self):
- self.master_status.unsubscribe(self)
- self.master_status = None
- for w in self.watched:
- w.unsubscribe(self)
- return base.StatusReceiverMultiService.disownServiceParent(self)
-
- def builderAdded(self, name, builder):
- # only subscribe to builders we are interested in
- if self.categories != None and builder.category not in self.categories:
- return None
-
- self.watched.append(builder)
- return self # subscribe to this builder
-
- def builderRemoved(self, name):
- pass
-
- def builderChangedState(self, name, state):
- pass
-
- def buildStarted(self, name, build):
- pass
-
- def isMailNeeded(self, build, results):
- # here is where we actually do something.
- builder = build.getBuilder()
- if self.builders is not None and builder.name not in self.builders:
- return False # ignore this build
- if self.categories is not None and \
- builder.category not in self.categories:
- return False # ignore this build
-
- prev = self.getPreviousBuild(build)
- if "change" in self.mode:
- if prev and prev.getResults() != results:
- return True
- if "failing" in self.mode and results == FAILURE:
- return True
- if "passing" in self.mode and results == SUCCESS:
- return True
- if "problem" in self.mode and results == FAILURE:
- if prev and prev.getResults() != FAILURE:
- return True
- if "warnings" in self.mode and results == WARNINGS:
- return True
- if "exception" in self.mode and results == EXCEPTION:
- return True
-
- return False
-
- def buildFinished(self, name, build, results):
- if ( not self.buildSetSummary and
- self.isMailNeeded(build, results) ):
- # for testing purposes, buildMessage returns a Deferred that fires
- # when the mail has been sent. To help unit tests, we return that
- # Deferred here even though the normal IStatusReceiver.buildFinished
- # signature doesn't do anything with it. If that changes (if
- # .buildFinished's return value becomes significant), we need to
- # rearrange this.
- return self.buildMessage(name, [build], results)
- return None
-
- def _gotBuilds(self, res, buildset):
- builds = []
- for (builddictlist, builder) in res:
- for builddict in builddictlist:
- build = builder.getBuild(builddict['number'])
- if build is not None and self.isMailNeeded(build, build.results):
- builds.append(build)
-
- if builds:
- self.buildMessage("Buildset Complete: " + buildset['reason'], builds,
- buildset['results'])
-
- def _gotBuildRequests(self, breqs, buildset):
- dl = []
- for breq in breqs:
- buildername = breq['buildername']
- builder = self.master_status.getBuilder(buildername)
- d = self.master.db.builds.getBuildsForRequest(breq['brid'])
- d.addCallback(lambda builddictlist, builder=builder:
- (builddictlist, builder))
- dl.append(d)
- d = defer.gatherResults(dl)
- d.addCallback(self._gotBuilds, buildset)
-
- def _gotBuildSet(self, buildset, bsid):
- d = self.master.db.buildrequests.getBuildRequests(bsid=bsid)
- d.addCallback(self._gotBuildRequests, buildset)
-
- def buildsetFinished(self, bsid, result):
- d = self.master.db.buildsets.getBuildset(bsid=bsid)
- d.addCallback(self._gotBuildSet, bsid)
-
- return d
-
- def getCustomMesgData(self, mode, name, build, results, master_status):
- #
- # logs is a list of tuples that contain the log
- # name, log url, and the log contents as a list of strings.
- #
- logs = list()
- for logf in build.getLogs():
- logStep = logf.getStep()
- stepName = logStep.getName()
- logStatus, dummy = logStep.getResults()
- logName = logf.getName()
- logs.append(('%s.%s' % (stepName, logName),
- '%s/steps/%s/logs/%s' % (
- master_status.getURLForThing(build),
- stepName, logName),
- logf.getText().splitlines(),
- logStatus))
-
- attrs = {'builderName': name,
- 'title': master_status.getTitle(),
- 'mode': mode,
- 'result': Results[results],
- 'buildURL': master_status.getURLForThing(build),
- 'buildbotURL': master_status.getBuildbotURL(),
- 'buildText': build.getText(),
- 'buildProperties': build.getProperties(),
- 'slavename': build.getSlavename(),
- 'reason': build.getReason().replace('\n', ''),
- 'responsibleUsers': build.getResponsibleUsers(),
- 'branch': "",
- 'revision': "",
- 'patch': "",
- 'patch_info': "",
- 'changes': [],
- 'logs': logs}
-
- ss = None
- ss_list = build.getSourceStamps()
-
- if ss_list:
- if len(ss_list) == 1:
- ss = ss_list[0]
- if ss:
- attrs['branch'] = ss.branch
- attrs['revision'] = ss.revision
- attrs['patch'] = ss.patch
- attrs['patch_info'] = ss.patch_info
- attrs['changes'] = ss.changes[:]
- else:
- for key in ['branch', 'revision', 'patch', 'patch_info', 'changes']:
- attrs[key] = {}
- for ss in ss_list:
- attrs['branch'][ss.codebase] = ss.branch
- attrs['revision'][ss.codebase] = ss.revision
- attrs['patch'][ss.codebase] = ss.patch
- attrs['patch_info'][ss.codebase] = ss.patch_info
- attrs['changes'][ss.codebase] = ss.changes[:]
-
- return attrs
-
- def patch_to_attachment(self, patch, index):
- # patches don't come with an encoding. If the patch is valid utf-8,
- # we'll attach it as MIMEText; otherwise, it gets attached as a binary
- # file. This will suit the vast majority of cases, since utf8 is by
- # far the most common encoding.
- if type(patch[1]) != types.UnicodeType:
- try:
- unicode = patch[1].decode('utf8')
- except UnicodeDecodeError:
- unicode = None
- else:
- unicode = patch[1]
-
- if unicode:
- a = MIMEText(unicode.encode(ENCODING), _charset=ENCODING)
- else:
- # MIMEApplication is not present in Python-2.4 :(
- a = MIMENonMultipart('application', 'octet-stream')
- a.set_payload(patch[1])
- a.add_header('Content-Disposition', "attachment",
- filename="source patch " + str(index) )
- return a
-
- def createEmail(self, msgdict, builderName, title, results, builds=None,
- patches=None, logs=None):
- text = msgdict['body'].encode(ENCODING)
- type = msgdict['type']
- if 'subject' in msgdict:
- subject = msgdict['subject'].encode(ENCODING)
- else:
- subject = self.subject % { 'result': Results[results],
- 'projectName': title,
- 'title': title,
- 'builder': builderName,
- }
-
- assert '\n' not in subject, \
- "Subject cannot contain newlines"
-
- assert type in ('plain', 'html'), \
- "'%s' message type must be 'plain' or 'html'." % type
-
- if patches or logs:
- m = MIMEMultipart()
- m.attach(MIMEText(text, type, ENCODING))
- else:
- m = Message()
- m.set_payload(text, ENCODING)
- m.set_type("text/%s" % type)
-
- m['Date'] = formatdate(localtime=True)
- m['Subject'] = subject
- m['From'] = self.fromaddr
- # m['To'] is added later
-
- if patches:
- for (i, patch) in enumerate(patches):
- a = self.patch_to_attachment(patch, i)
- m.attach(a)
- if logs:
- for log in logs:
- name = "%s.%s" % (log.getStep().getName(),
- log.getName())
- if ( self._shouldAttachLog(log.getName()) or
- self._shouldAttachLog(name) ):
- text = log.getText()
- if not isinstance(text, unicode):
- # guess at the encoding, and use replacement symbols
- # for anything that's not in that encoding
- text = text.decode(LOG_ENCODING, 'replace')
- a = MIMEText(text.encode(ENCODING),
- _charset=ENCODING)
- a.add_header('Content-Disposition', "attachment",
- filename=name)
- m.attach(a)
-
- #@todo: is there a better way to do this?
- # Add any extra headers that were requested, doing WithProperties
- # interpolation if only one build was given
- if self.extraHeaders:
- if len(builds) == 1:
- d = builds[0].render(self.extraHeaders)
- else:
- d = defer.succeed(self.extraHeaders)
- @d.addCallback
- def addExtraHeaders(extraHeaders):
- for k,v in extraHeaders.items():
- if k in m:
- twlog.msg("Warning: Got header " + k +
- " in self.extraHeaders "
- "but it already exists in the Message - "
- "not adding it.")
- m[k] = v
- d.addCallback(lambda _: m)
- return d
-
- return defer.succeed(m)
-
- def buildMessageDict(self, name, build, results):
- if self.customMesg:
- # the customMesg stuff can be *huge*, so we prefer not to load it
- attrs = self.getCustomMesgData(self.mode, name, build, results,
- self.master_status)
- text, type = self.customMesg(attrs)
- msgdict = { 'body' : text, 'type' : type }
- else:
- msgdict = self.messageFormatter(self.mode, name, build, results,
- self.master_status)
-
- return msgdict
-
-
- def buildMessage(self, name, builds, results):
- patches = []
- logs = []
- msgdict = {"body":""}
-
- for build in builds:
- ss_list = build.getSourceStamps()
- if self.addPatch:
- for ss in ss_list:
- if ss.patch:
- patches.append(ss.patch)
- if self.addLogs:
- logs.extend(build.getLogs())
-
- tmp = self.buildMessageDict(name=build.getBuilder().name,
- build=build, results=build.results)
- msgdict['body'] += tmp['body']
- msgdict['body'] += '\n\n'
- msgdict['type'] = tmp['type']
- if "subject" in tmp:
- msgdict['subject'] = tmp['subject']
-
- d = self.createEmail(msgdict, name, self.master_status.getTitle(),
- results, builds, patches, logs)
-
- @d.addCallback
- def getRecipients(m):
- # now, who is this message going to?
- if self.sendToInterestedUsers:
- dl = []
- for build in builds:
- if self.lookup:
- d = self.useLookup(build)
- else:
- d = self.useUsers(build)
- dl.append(d)
- d = defer.gatherResults(dl)
- else:
- d = defer.succeed([])
- d.addCallback(self._gotRecipients, m)
- return d
-
- def useLookup(self, build):
- dl = []
- for u in build.getResponsibleUsers() + build.getInterestedUsers():
- d = defer.maybeDeferred(self.lookup.getAddress, u)
- dl.append(d)
- return defer.gatherResults(dl)
-
- def useUsers(self, build):
- return users.getBuildContacts(self.master, build, ['email'])
-
- def _shouldAttachLog(self, logname):
- if type(self.addLogs) is bool:
- return self.addLogs
- return logname in self.addLogs
-
- def _gotRecipients(self, rlist, m):
- to_recipients = set()
- cc_recipients = set()
-
- for r in reduce(list.__add__, rlist, []):
- if r is None: # getAddress didn't like this address
- continue
-
- # Git can give emails like 'User' <user@foo.com>@foo.com so check
- # for two @ and chop the last
- if r.count('@') > 1:
- r = r[:r.rindex('@')]
-
- if VALID_EMAIL.search(r):
- to_recipients.add(r)
- else:
- twlog.msg("INVALID EMAIL: %r" + r)
-
- # If we're sending to interested users put the extras in the
- # CC list so they can tell if they are also interested in the
- # change:
- if self.sendToInterestedUsers and to_recipients:
- cc_recipients.update(self.extraRecipients)
- else:
- to_recipients.update(self.extraRecipients)
-
- m['To'] = ", ".join(sorted(to_recipients))
- if cc_recipients:
- m['CC'] = ", ".join(sorted(cc_recipients))
-
- return self.sendMessage(m, list(to_recipients | cc_recipients))
-
- def sendmail(self, s, recipients):
- result = defer.Deferred()
-
- if have_ssl and self.useTls:
- client_factory = ssl.ClientContextFactory()
- client_factory.method = SSLv3_METHOD
- else:
- client_factory = None
-
- if self.smtpUser and self.smtpPassword:
- useAuth = True
- else:
- useAuth = False
-
- if not ESMTPSenderFactory:
- raise RuntimeError("twisted-mail is not installed - cannot "
- "send mail")
- sender_factory = ESMTPSenderFactory(
- self.smtpUser, self.smtpPassword,
- self.fromaddr, recipients, StringIO(s),
- result, contextFactory=client_factory,
- requireTransportSecurity=self.useTls,
- requireAuthentication=useAuth)
-
- reactor.connectTCP(self.relayhost, self.smtpPort, sender_factory)
-
- return result
-
- def sendMessage(self, m, recipients):
- s = m.as_string()
- twlog.msg("sending mail (%d bytes) to" % len(s), recipients)
- return self.sendmail(s, recipients)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/master.py
deleted file mode 100644
index 8d5b7e7d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/master.py
+++ /dev/null
@@ -1,475 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os, urllib
-from cPickle import load
-from twisted.python import log
-from twisted.persisted import styles
-from twisted.internet import defer
-from twisted.application import service
-from zope.interface import implements
-from buildbot import config, interfaces, util
-from buildbot.util import bbcollections
-from buildbot.util.eventual import eventually
-from buildbot.changes import changes
-from buildbot.status import buildset, builder, buildrequest
-
-class Status(config.ReconfigurableServiceMixin, service.MultiService):
- implements(interfaces.IStatus)
-
- def __init__(self, master):
- service.MultiService.__init__(self)
- self.master = master
- self.botmaster = master.botmaster
- self.basedir = master.basedir
- self.watchers = []
- # No default limit to the log size
- self.logMaxSize = None
-
- self._builder_observers = bbcollections.KeyedSets()
- self._buildreq_observers = bbcollections.KeyedSets()
- self._buildset_finished_waiters = bbcollections.KeyedSets()
- self._buildset_completion_sub = None
- self._buildset_sub = None
- self._build_request_sub = None
- self._change_sub = None
-
- # service management
-
- def startService(self):
- # subscribe to the things we need to know about
- self._buildset_completion_sub = \
- self.master.subscribeToBuildsetCompletions(
- self._buildsetCompletionCallback)
- self._buildset_sub = \
- self.master.subscribeToBuildsets(
- self._buildsetCallback)
- self._build_request_sub = \
- self.master.subscribeToBuildRequests(
- self._buildRequestCallback)
- self._change_sub = \
- self.master.subscribeToChanges(
- self.changeAdded)
-
- return service.MultiService.startService(self)
-
- @defer.inlineCallbacks
- def reconfigService(self, new_config):
- # remove the old listeners, then add the new
- for sr in list(self):
- yield defer.maybeDeferred(lambda :
- sr.disownServiceParent())
-
- # WebStatus instances tend to "hang around" longer than we'd like -
- # if there's an ongoing HTTP request, or even a connection held
- # open by keepalive, then users may still be talking to an old
- # WebStatus. So WebStatus objects get to keep their `master`
- # attribute, but all other status objects lose theirs. And we want
- # to test this without importing WebStatus, so we use name
- if not sr.__class__.__name__.endswith('WebStatus'):
- sr.master = None
-
- for sr in new_config.status:
- sr.master = self.master
- sr.setServiceParent(self)
-
- # reconfig any newly-added change sources, as well as existing
- yield config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
- def stopService(self):
- if self._buildset_completion_sub:
- self._buildset_completion_sub.unsubscribe()
- self._buildset_completion_sub = None
- if self._buildset_sub:
- self._buildset_sub.unsubscribe()
- self._buildset_sub = None
- if self._build_request_sub:
- self._build_request_sub.unsubscribe()
- self._build_request_sub = None
- if self._change_sub:
- self._change_sub.unsubscribe()
- self._change_sub = None
-
- return service.MultiService.stopService(self)
-
- # clean shutdown
-
- @property
- def shuttingDown(self):
- return self.botmaster.shuttingDown
-
- def cleanShutdown(self):
- return self.botmaster.cleanShutdown()
-
- def cancelCleanShutdown(self):
- return self.botmaster.cancelCleanShutdown()
-
- # methods called by our clients
-
- def getTitle(self):
- return self.master.config.title
- def getTitleURL(self):
- return self.master.config.titleURL
- def getBuildbotURL(self):
- return self.master.config.buildbotURL
-
- def getStatus(self):
- # some listeners expect their .parent to be a BuildMaster object, and
- # use this method to get the Status object. This is documented, so for
- # now keep it working.
- return self
-
- def getMetrics(self):
- return self.master.metrics
-
- def getURLForBuild(self, builder_name, build_number):
- prefix = self.getBuildbotURL()
- import urlparse
- url_path = "builders/%s/builds/%d" % (
- urllib.quote(builder_name, safe=''),
- build_number)
- return(urlparse.urljoin(prefix,url_path))
-
- def getURLForThing(self, thing):
- prefix = self.getBuildbotURL()
- if not prefix:
- return None
- if interfaces.IStatus.providedBy(thing):
- return prefix
- if interfaces.ISchedulerStatus.providedBy(thing):
- pass
- if interfaces.IBuilderStatus.providedBy(thing):
- bldr = thing
- return prefix + "builders/%s" % (
- urllib.quote(bldr.getName(), safe=''),
- )
- if interfaces.IBuildStatus.providedBy(thing):
- build = thing
- bldr = build.getBuilder()
- return self.getURLForBuild(bldr.getName(), build.getNumber())
-
- if interfaces.IBuildStepStatus.providedBy(thing):
- step = thing
- build = step.getBuild()
- bldr = build.getBuilder()
- return prefix + "builders/%s/builds/%d/steps/%s" % (
- urllib.quote(bldr.getName(), safe=''),
- build.getNumber(),
- urllib.quote(step.getName(), safe=''))
- # IBuildSetStatus
- # IBuildRequestStatus
- # ISlaveStatus
- if interfaces.ISlaveStatus.providedBy(thing):
- slave = thing
- return prefix + "buildslaves/%s" % (
- urllib.quote(slave.getName(), safe=''),
- )
-
- # IStatusEvent
- if interfaces.IStatusEvent.providedBy(thing):
- # TODO: this is goofy, create IChange or something
- if isinstance(thing, changes.Change):
- change = thing
- return "%schanges/%d" % (prefix, change.number)
-
- if interfaces.IStatusLog.providedBy(thing):
- loog = thing
- step = loog.getStep()
- build = step.getBuild()
- bldr = build.getBuilder()
-
- logs = step.getLogs()
- for i in range(len(logs)):
- if loog is logs[i]:
- break
- else:
- return None
- return prefix + "builders/%s/builds/%d/steps/%s/logs/%s" % (
- urllib.quote(bldr.getName(), safe=''),
- build.getNumber(),
- urllib.quote(step.getName(), safe=''),
- urllib.quote(loog.getName(), safe=''))
-
- def getChangeSources(self):
- return list(self.master.change_svc)
-
- def getChange(self, number):
- """Get a Change object; returns a deferred"""
- d = self.master.db.changes.getChange(number)
- def chdict2change(chdict):
- if not chdict:
- return None
- return changes.Change.fromChdict(self.master, chdict)
- d.addCallback(chdict2change)
- return d
-
- def getSchedulers(self):
- return self.master.allSchedulers()
-
- def getBuilderNames(self, categories=None):
- if categories == None:
- # assume this is already sorted...
- return self.botmaster.builderNames
-
- l = []
- # respect addition order
- for name in self.botmaster.builderNames:
- bldr = self.botmaster.builders[name]
- if bldr.config.category in categories:
- l.append(name)
- return util.naturalSort(l)
-
- def getBuilder(self, name):
- """
- @rtype: L{BuilderStatus}
- """
- return self.botmaster.builders[name].builder_status
-
- def getSlaveNames(self):
- return self.botmaster.slaves.keys()
-
- def getSlave(self, slavename):
- return self.botmaster.slaves[slavename].slave_status
-
- def getBuildSets(self):
- d = self.master.db.buildsets.getBuildsets(complete=False)
- def make_status_objects(bsdicts):
- return [ buildset.BuildSetStatus(bsdict, self)
- for bsdict in bsdicts ]
- d.addCallback(make_status_objects)
- return d
-
- def generateFinishedBuilds(self, builders=[], branches=[],
- num_builds=None, finished_before=None,
- max_search=200):
-
- def want_builder(bn):
- if builders:
- return bn in builders
- return True
- builder_names = [bn
- for bn in self.getBuilderNames()
- if want_builder(bn)]
-
- # 'sources' is a list of generators, one for each Builder we're
- # using. When the generator is exhausted, it is replaced in this list
- # with None.
- sources = []
- for bn in builder_names:
- b = self.getBuilder(bn)
- g = b.generateFinishedBuilds(branches,
- finished_before=finished_before,
- max_search=max_search)
- sources.append(g)
-
- # next_build the next build from each source
- next_build = [None] * len(sources)
-
- def refill():
- for i,g in enumerate(sources):
- if next_build[i]:
- # already filled
- continue
- if not g:
- # already exhausted
- continue
- try:
- next_build[i] = g.next()
- except StopIteration:
- next_build[i] = None
- sources[i] = None
-
- got = 0
- while True:
- refill()
- # find the latest build among all the candidates
- candidates = [(i, b, b.getTimes()[1])
- for i,b in enumerate(next_build)
- if b is not None]
- candidates.sort(lambda x,y: cmp(x[2], y[2]))
- if not candidates:
- return
-
- # and remove it from the list
- i, build, finshed_time = candidates[-1]
- next_build[i] = None
- got += 1
- yield build
- if num_builds is not None:
- if got >= num_builds:
- return
-
- def subscribe(self, target):
- self.watchers.append(target)
- for name in self.botmaster.builderNames:
- self.announceNewBuilder(target, name, self.getBuilder(name))
- def unsubscribe(self, target):
- self.watchers.remove(target)
-
-
- # methods called by upstream objects
-
- def announceNewBuilder(self, target, name, builder_status):
- t = target.builderAdded(name, builder_status)
- if t:
- builder_status.subscribe(t)
-
- def builderAdded(self, name, basedir, category=None, description=None):
- """
- @rtype: L{BuilderStatus}
- """
- filename = os.path.join(self.basedir, basedir, "builder")
- log.msg("trying to load status pickle from %s" % filename)
- builder_status = None
- try:
- with open(filename, "rb") as f:
- builder_status = load(f)
- builder_status.master = self.master
-
- # (bug #1068) if we need to upgrade, we probably need to rewrite
- # this pickle, too. We determine this by looking at the list of
- # Versioned objects that have been unpickled, and (after doUpgrade)
- # checking to see if any of them set wasUpgraded. The Versioneds'
- # upgradeToVersionNN methods all set this.
- versioneds = styles.versionedsToUpgrade
- styles.doUpgrade()
- if True in [ hasattr(o, 'wasUpgraded') for o in versioneds.values() ]:
- log.msg("re-writing upgraded builder pickle")
- builder_status.saveYourself()
-
- except IOError:
- log.msg("no saved status pickle, creating a new one")
- except:
- log.msg("error while loading status pickle, creating a new one")
- log.msg("error follows:")
- log.err()
- if not builder_status:
- builder_status = builder.BuilderStatus(name, category, self.master,
- description)
- builder_status.addPointEvent(["builder", "created"])
- log.msg("added builder %s in category %s" % (name, category))
- # an unpickled object might not have category set from before,
- # so set it here to make sure
- builder_status.category = category
- builder_status.description = description
- builder_status.master = self.master
- builder_status.basedir = os.path.join(self.basedir, basedir)
- builder_status.name = name # it might have been updated
- builder_status.status = self
-
- if not os.path.isdir(builder_status.basedir):
- os.makedirs(builder_status.basedir)
- builder_status.determineNextBuildNumber()
-
- builder_status.setBigState("offline")
-
- for t in self.watchers:
- self.announceNewBuilder(t, name, builder_status)
-
- return builder_status
-
- def builderRemoved(self, name):
- for t in self.watchers:
- if hasattr(t, 'builderRemoved'):
- t.builderRemoved(name)
-
- def slaveConnected(self, name):
- for t in self.watchers:
- if hasattr(t, 'slaveConnected'):
- t.slaveConnected(name)
-
- def slaveDisconnected(self, name):
- for t in self.watchers:
- if hasattr(t, 'slaveDisconnected'):
- t.slaveDisconnected(name)
-
- def changeAdded(self, change):
- for t in self.watchers:
- if hasattr(t, 'changeAdded'):
- t.changeAdded(change)
-
- def asDict(self):
- result = {}
- # Constant
- result['title'] = self.getTitle()
- result['titleURL'] = self.getTitleURL()
- result['buildbotURL'] = self.getBuildbotURL()
- # TODO: self.getSchedulers()
- # self.getChangeSources()
- return result
-
- def build_started(self, brid, buildername, build_status):
- if brid in self._buildreq_observers:
- for o in self._buildreq_observers[brid]:
- eventually(o, build_status)
-
- def _buildrequest_subscribe(self, brid, observer):
- self._buildreq_observers.add(brid, observer)
-
- def _buildrequest_unsubscribe(self, brid, observer):
- self._buildreq_observers.discard(brid, observer)
-
- def _buildset_waitUntilFinished(self, bsid):
- d = defer.Deferred()
- self._buildset_finished_waiters.add(bsid, d)
- self._maybeBuildsetFinished(bsid)
- return d
-
- def _maybeBuildsetFinished(self, bsid):
- # check bsid to see if it's successful or finished, and notify anyone
- # who cares
- if bsid not in self._buildset_finished_waiters:
- return
- d = self.master.db.buildsets.getBuildset(bsid)
- def do_notifies(bsdict):
- bss = buildset.BuildSetStatus(bsdict, self)
- if bss.isFinished():
- for d in self._buildset_finished_waiters.pop(bsid):
- eventually(d.callback, bss)
- d.addCallback(do_notifies)
- d.addErrback(log.err, 'while notifying for buildset finishes')
-
- def _builder_subscribe(self, buildername, watcher):
- # should get requestSubmitted and requestCancelled
- self._builder_observers.add(buildername, watcher)
-
- def _builder_unsubscribe(self, buildername, watcher):
- self._builder_observers.discard(buildername, watcher)
-
- def _buildsetCallback(self, **kwargs):
- bsid = kwargs['bsid']
- d = self.master.db.buildsets.getBuildset(bsid)
- def do_notifies(bsdict):
- bss = buildset.BuildSetStatus(bsdict, self)
- for t in self.watchers:
- if hasattr(t, 'buildsetSubmitted'):
- t.buildsetSubmitted(bss)
- d.addCallback(do_notifies)
- d.addErrback(log.err, 'while notifying buildsetSubmitted')
-
- def _buildsetCompletionCallback(self, bsid, result):
- self._maybeBuildsetFinished(bsid)
-
- def _buildRequestCallback(self, notif):
- buildername = notif['buildername']
- if buildername in self._builder_observers:
- brs = buildrequest.BuildRequestStatus(buildername,
- notif['brid'], self)
- for observer in self._builder_observers[buildername]:
- if hasattr(observer, 'requestSubmitted'):
- eventually(observer.requestSubmitted, brs)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/persistent_queue.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/persistent_queue.py
deleted file mode 100644
index 0106a210..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/persistent_queue.py
+++ /dev/null
@@ -1,382 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-
-from collections import deque
-import os
-import cPickle as pickle
-
-from zope.interface import implements, Interface
-
-
-def ReadFile(path):
- with open(path, 'rb') as f:
- return f.read()
-
-
-def WriteFile(path, buf):
- with open(path, 'wb') as f:
- f.write(buf)
-
-
-class IQueue(Interface):
- """Abstraction of a queue."""
- def pushItem(item):
- """Adds an individual item to the end of the queue.
-
- Returns an item if it was overflowed."""
-
- def insertBackChunk(items):
- """Adds a list of items as the oldest entries.
-
- Normally called in case of failure to process the data, queue the data
- back so it can be retrieved at a later time.
-
- Returns a list of items if it was overflowed."""
-
- def popChunk(nbItems=None):
- """Pop many items at once. Defaults to self.maxItems()."""
-
- def save():
- """Save the queue to storage if implemented."""
-
- def items():
- """Returns items in the queue.
-
- Warning: Can be extremely slow for queue on disk."""
-
- def nbItems():
- """Returns the number of items in the queue."""
-
- def maxItems():
- """Returns the maximum number of items this queue can hold."""
-
-
-class MemoryQueue(object):
- """Simple length bounded queue using deque.
-
- list.pop(0) operation is O(n) so for a 10000 items list, it can start to
- be real slow. On the contrary, deque.popleft() is O(1) most of the time.
- See http://docs.python.org/library/collections.html for more
- information.
- """
- implements(IQueue)
-
- def __init__(self, maxItems=None):
- self._maxItems = maxItems
- if self._maxItems is None:
- self._maxItems = 10000
- self._items = deque()
-
- def pushItem(self, item):
- ret = None
- if len(self._items) == self._maxItems:
- ret = self._items.popleft()
- self._items.append(item)
- return ret
-
- def insertBackChunk(self, chunk):
- ret = None
- excess = len(self._items) + len(chunk) - self._maxItems
- if excess > 0:
- ret = chunk[0:excess]
- chunk = chunk[excess:]
- self._items.extendleft(reversed(chunk))
- return ret
-
- def popChunk(self, nbItems=None):
- if nbItems is None:
- nbItems = self._maxItems
- if nbItems > len(self._items):
- items = list(self._items)
- self._items = deque()
- else:
- items = []
- for i in range(nbItems):
- items.append(self._items.popleft())
- return items
-
- def save(self):
- pass
-
- def items(self):
- return list(self._items)
-
- def nbItems(self):
- return len(self._items)
-
- def maxItems(self):
- return self._maxItems
-
-
-class DiskQueue(object):
- """Keeps a list of abstract items and serializes it to the disk.
-
- Use pickle for serialization."""
- implements(IQueue)
-
- def __init__(self, path, maxItems=None, pickleFn=pickle.dumps,
- unpickleFn=pickle.loads):
- """
- @path: directory to save the items.
- @maxItems: maximum number of items to keep on disk, flush the
- older ones.
- @pickleFn: function used to pack the items to disk.
- @unpickleFn: function used to unpack items from disk.
- """
- self.path = path
- self._maxItems = maxItems
- if self._maxItems is None:
- self._maxItems = 100000
- if not os.path.isdir(self.path):
- os.mkdir(self.path)
- self.pickleFn = pickleFn
- self.unpickleFn = unpickleFn
-
- # Total number of items.
- self._nbItems = 0
- # The actual items id start at one.
- self.firstItemId = 0
- self.lastItemId = 0
- self._loadFromDisk()
-
- def pushItem(self, item):
- ret = None
- if self._nbItems == self._maxItems:
- id = self._findNext(self.firstItemId)
- path = os.path.join(self.path, str(id))
- ret = self.unpickleFn(ReadFile(path))
- os.remove(path)
- self.firstItemId = id + 1
- else:
- self._nbItems += 1
- self.lastItemId += 1
- path = os.path.join(self.path, str(self.lastItemId))
- if os.path.exists(path):
- raise IOError('%s already exists.' % path)
- WriteFile(path, self.pickleFn(item))
- return ret
-
- def insertBackChunk(self, chunk):
- ret = None
- excess = self._nbItems + len(chunk) - self._maxItems
- if excess > 0:
- ret = chunk[0:excess]
- chunk = chunk[excess:]
- for i in reversed(chunk):
- self.firstItemId -= 1
- path = os.path.join(self.path, str(self.firstItemId))
- if os.path.exists(path):
- raise IOError('%s already exists.' % path)
- WriteFile(path, self.pickleFn(i))
- self._nbItems += 1
- return ret
-
- def popChunk(self, nbItems=None):
- if nbItems is None:
- nbItems = self._maxItems
- ret = []
- for i in range(nbItems):
- if self._nbItems == 0:
- break
- id = self._findNext(self.firstItemId)
- path = os.path.join(self.path, str(id))
- ret.append(self.unpickleFn(ReadFile(path)))
- os.remove(path)
- self._nbItems -= 1
- self.firstItemId = id + 1
- return ret
-
- def save(self):
- pass
-
- def items(self):
- """Warning, very slow."""
- ret = []
- for id in range(self.firstItemId, self.lastItemId + 1):
- path = os.path.join(self.path, str(id))
- if os.path.exists(path):
- ret.append(self.unpickleFn(ReadFile(path)))
- return ret
-
- def nbItems(self):
- return self._nbItems
-
- def maxItems(self):
- return self._maxItems
-
- #### Protected functions
-
- def _findNext(self, id):
- while True:
- path = os.path.join(self.path, str(id))
- if os.path.isfile(path):
- return id
- id += 1
- return None
-
- def _loadFromDisk(self):
- """Loads the queue from disk upto self.maxMemoryItems items into
- self.items.
- """
- def SafeInt(item):
- try:
- return int(item)
- except ValueError:
- return None
-
- files = filter(None, [SafeInt(x) for x in os.listdir(self.path)])
- files.sort()
- self._nbItems = len(files)
- if self._nbItems:
- self.firstItemId = files[0]
- self.lastItemId = files[-1]
-
-
-class PersistentQueue(object):
- """Keeps a list of abstract items and serializes it to the disk.
-
- It has 2 layers of queue, normally an in-memory queue and an on-disk queue.
- When the number of items in the primary queue gets too large, the new items
- are automatically saved to the secondary queue. The older items are kept in
- the primary queue.
- """
- implements(IQueue)
-
- def __init__(self, primaryQueue=None, secondaryQueue=None, path=None):
- """
- @primaryQueue: memory queue to use before buffering to disk.
- @secondaryQueue: disk queue to use as permanent buffer.
- @path: path is a shortcut when using default DiskQueue settings.
- """
- self.primaryQueue = primaryQueue
- if self.primaryQueue is None:
- self.primaryQueue = MemoryQueue()
- self.secondaryQueue = secondaryQueue
- if self.secondaryQueue is None:
- self.secondaryQueue = DiskQueue(path)
- # Preload data from the secondary queue only if we know we won't start
- # using the secondary queue right away.
- if self.secondaryQueue.nbItems() < self.primaryQueue.maxItems():
- self.primaryQueue.insertBackChunk(
- self.secondaryQueue.popChunk(self.primaryQueue.maxItems()))
-
- def pushItem(self, item):
- # If there is already items in secondaryQueue, we'd need to pop them
- # all to start inserting them into primaryQueue so don't bother and
- # just push it in secondaryQueue.
- if (self.secondaryQueue.nbItems() or
- self.primaryQueue.nbItems() == self.primaryQueue.maxItems()):
- item = self.secondaryQueue.pushItem(item)
- if item is None:
- return item
- # If item is not None, secondaryQueue overflowed. We need to push it
- # back to primaryQueue so the oldest item is dumped.
- # Or everything fit in the primaryQueue.
- return self.primaryQueue.pushItem(item)
-
- def insertBackChunk(self, chunk):
- ret = None
- # Overall excess
- excess = self.nbItems() + len(chunk) - self.maxItems()
- if excess > 0:
- ret = chunk[0:excess]
- chunk = chunk[excess:]
- # Memory excess
- excess = (self.primaryQueue.nbItems() + len(chunk) -
- self.primaryQueue.maxItems())
- if excess > 0:
- chunk2 = []
- for i in range(excess):
- chunk2.append(self.primaryQueue.items().pop())
- chunk2.reverse()
- x = self.primaryQueue.insertBackChunk(chunk)
- assert x is None, "primaryQueue.insertBackChunk did not return None"
- if excess > 0:
- x = self.secondaryQueue.insertBackChunk(chunk2)
- assert x is None, ("secondaryQueue.insertBackChunk did not return "
- " None")
- return ret
-
- def popChunk(self, nbItems=None):
- if nbItems is None:
- nbItems = self.primaryQueue.maxItems()
- ret = self.primaryQueue.popChunk(nbItems)
- nbItems -= len(ret)
- if nbItems and self.secondaryQueue.nbItems():
- ret.extend(self.secondaryQueue.popChunk(nbItems))
- return ret
-
- def save(self):
- self.secondaryQueue.insertBackChunk(self.primaryQueue.popChunk())
-
- def items(self):
- return self.primaryQueue.items() + self.secondaryQueue.items()
-
- def nbItems(self):
- return self.primaryQueue.nbItems() + self.secondaryQueue.nbItems()
-
- def maxItems(self):
- return self.primaryQueue.maxItems() + self.secondaryQueue.maxItems()
-
-
-class IndexedQueue(object):
- """Adds functionality to a IQueue object to track its usage.
-
- Adds a new member function getIndex() and modify popChunk() and
- insertBackChunk() to keep a virtual pointer to the queue's first entry
- index."""
- implements(IQueue)
-
- def __init__(self, queue):
- # Copy all the member functions from the other object that this class
- # doesn't already define.
- assert IQueue.providedBy(queue)
- def Filter(m):
- return (m[0] != '_' and callable(getattr(queue, m))
- and not hasattr(self, m))
- for member in filter(Filter, dir(queue)):
- setattr(self, member, getattr(queue, member))
- self.queue = queue
- self._index = 0
-
- def getIndex(self):
- return self._index
-
- def popChunk(self, *args, **kwargs):
- items = self.queue.popChunk(*args, **kwargs)
- if items:
- self._index += len(items)
- return items
-
- def insertBackChunk(self, items):
- self._index -= len(items)
- ret = self.queue.insertBackChunk(items)
- if ret:
- self._index += len(ret)
- return ret
-
-
-def ToIndexedQueue(queue):
- """If the IQueue wasn't already a IndexedQueue, makes it an IndexedQueue."""
- if not IQueue.providedBy(queue):
- raise TypeError("queue doesn't implement IQueue", queue)
- if isinstance(queue, IndexedQueue):
- return queue
- return IndexedQueue(queue)
-
-# vim: set ts=4 sts=4 sw=4 et:
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/progress.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/progress.py
deleted file mode 100644
index 62aae317..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/progress.py
+++ /dev/null
@@ -1,324 +0,0 @@
-# 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
-
-
-from twisted.internet import reactor
-from twisted.spread import pb
-from twisted.python import log
-from buildbot import util
-from collections import defaultdict
-
-class StepProgress:
- """I keep track of how much progress a single BuildStep has made.
-
- Progress is measured along various axes. Time consumed is one that is
- available for all steps. Amount of command output is another, and may be
- better quantified by scanning the output for markers to derive number of
- files compiled, directories walked, tests run, etc.
-
- I am created when the build begins, and given to a BuildProgress object
- so it can track the overall progress of the whole build.
-
- """
-
- startTime = None
- stopTime = None
- expectedTime = None
- buildProgress = None
- debug = False
-
- def __init__(self, name, metricNames):
- self.name = name
- self.progress = {}
- self.expectations = {}
- for m in metricNames:
- self.progress[m] = None
- self.expectations[m] = None
-
- def setBuildProgress(self, bp):
- self.buildProgress = bp
-
- def setExpectations(self, metrics):
- """The step can call this to explicitly set a target value for one
- of its metrics. E.g., ShellCommands knows how many commands it will
- execute, so it could set the 'commands' expectation."""
- for metric, value in metrics.items():
- self.expectations[metric] = value
- self.buildProgress.newExpectations()
-
- def setExpectedTime(self, seconds):
- self.expectedTime = seconds
- self.buildProgress.newExpectations()
-
- def start(self):
- if self.debug: print "StepProgress.start[%s]" % self.name
- self.startTime = util.now()
-
- def setProgress(self, metric, value):
- """The step calls this as progress is made along various axes."""
- if self.debug:
- print "setProgress[%s][%s] = %s" % (self.name, metric, value)
- self.progress[metric] = value
- if self.debug:
- r = self.remaining()
- print " step remaining:", r
- self.buildProgress.newProgress()
-
- def finish(self):
- """This stops the 'time' metric and marks the step as finished
- overall. It should be called after the last .setProgress has been
- done for each axis."""
- if self.debug: print "StepProgress.finish[%s]" % self.name
- self.stopTime = util.now()
- self.buildProgress.stepFinished(self.name)
-
- def totalTime(self):
- if self.startTime != None and self.stopTime != None:
- return self.stopTime - self.startTime
-
- def remaining(self):
- if self.startTime == None:
- return self.expectedTime
- if self.stopTime != None:
- return 0 # already finished
- # TODO: replace this with cleverness that graphs each metric vs.
- # time, then finds the inverse function. Will probably need to save
- # a timestamp with each setProgress update, when finished, go back
- # and find the 2% transition points, then save those 50 values in a
- # list. On the next build, do linear interpolation between the two
- # closest samples to come up with a percentage represented by that
- # metric.
-
- # TODO: If no other metrics are available, just go with elapsed
- # time. Given the non-time-uniformity of text output from most
- # steps, this would probably be better than the text-percentage
- # scheme currently implemented.
-
- percentages = []
- for metric, value in self.progress.items():
- expectation = self.expectations[metric]
- if value != None and expectation != None:
- p = 1.0 * value / expectation
- percentages.append(p)
- if percentages:
- avg = reduce(lambda x,y: x+y, percentages) / len(percentages)
- if avg > 1.0:
- # overdue
- avg = 1.0
- if avg < 0.0:
- avg = 0.0
- if percentages and self.expectedTime != None:
- return self.expectedTime - (avg * self.expectedTime)
- if self.expectedTime is not None:
- # fall back to pure time
- return self.expectedTime - (util.now() - self.startTime)
- return None # no idea
-
-
-class WatcherState:
- def __init__(self, interval):
- self.interval = interval
- self.timer = None
- self.needUpdate = 0
-
-class BuildProgress(pb.Referenceable):
- """I keep track of overall build progress. I hold a list of StepProgress
- objects.
- """
-
- def __init__(self, stepProgresses):
- self.steps = {}
- for s in stepProgresses:
- self.steps[s.name] = s
- s.setBuildProgress(self)
- self.finishedSteps = []
- self.watchers = {}
- self.debug = 0
-
- def setExpectationsFrom(self, exp):
- """Set our expectations from the builder's Expectations object."""
- for name, metrics in exp.steps.items():
- s = self.steps.get(name)
- if s:
- s.setExpectedTime(exp.times[name])
- s.setExpectations(exp.steps[name])
-
- def newExpectations(self):
- """Call this when one of the steps has changed its expectations.
- This should trigger us to update our ETA value and notify any
- subscribers."""
- pass # subscribers are not implemented: they just poll
-
- def stepFinished(self, stepname):
- assert(stepname not in self.finishedSteps)
- self.finishedSteps.append(stepname)
- if len(self.finishedSteps) == len(self.steps.keys()):
- self.sendLastUpdates()
-
- def newProgress(self):
- r = self.remaining()
- if self.debug:
- print " remaining:", r
- if r != None:
- self.sendAllUpdates()
-
- def remaining(self):
- # sum eta of all steps
- sum = 0
- for name, step in self.steps.items():
- rem = step.remaining()
- if rem == None:
- return None # not sure
- sum += rem
- return sum
- def eta(self):
- left = self.remaining()
- if left == None:
- return None # not sure
- done = util.now() + left
- return done
-
-
- def remote_subscribe(self, remote, interval=5):
- # [interval, timer, needUpdate]
- # don't send an update more than once per interval
- self.watchers[remote] = WatcherState(interval)
- remote.notifyOnDisconnect(self.removeWatcher)
- self.updateWatcher(remote)
- self.startTimer(remote)
- log.msg("BuildProgress.remote_subscribe(%s)" % remote)
- def remote_unsubscribe(self, remote):
- # TODO: this doesn't work. I think 'remote' will always be different
- # than the object that appeared in _subscribe.
- log.msg("BuildProgress.remote_unsubscribe(%s)" % remote)
- self.removeWatcher(remote)
- #remote.dontNotifyOnDisconnect(self.removeWatcher)
- def removeWatcher(self, remote):
- #log.msg("removeWatcher(%s)" % remote)
- try:
- timer = self.watchers[remote].timer
- if timer:
- timer.cancel()
- del self.watchers[remote]
- except KeyError:
- log.msg("Weird, removeWatcher on non-existent subscriber:",
- remote)
- def sendAllUpdates(self):
- for r in self.watchers.keys():
- self.updateWatcher(r)
- def updateWatcher(self, remote):
- # an update wants to go to this watcher. Send it if we can, otherwise
- # queue it for later
- w = self.watchers[remote]
- if not w.timer:
- # no timer, so send update now and start the timer
- self.sendUpdate(remote)
- self.startTimer(remote)
- else:
- # timer is running, just mark as needing an update
- w.needUpdate = 1
- def startTimer(self, remote):
- w = self.watchers[remote]
- timer = reactor.callLater(w.interval, self.watcherTimeout, remote)
- w.timer = timer
- def sendUpdate(self, remote, last=0):
- self.watchers[remote].needUpdate = 0
- #text = self.asText() # TODO: not text, duh
- try:
- remote.callRemote("progress", self.remaining())
- if last:
- remote.callRemote("finished", self)
- except:
- log.deferr()
- self.removeWatcher(remote)
-
- def watcherTimeout(self, remote):
- w = self.watchers.get(remote, None)
- if not w:
- return # went away
- w.timer = None
- if w.needUpdate:
- self.sendUpdate(remote)
- self.startTimer(remote)
- def sendLastUpdates(self):
- for remote in self.watchers.keys():
- self.sendUpdate(remote, 1)
- self.removeWatcher(remote)
-
-
-class Expectations:
- debug = False
- # decay=1.0 ignores all but the last build
- # 0.9 is short time constant. 0.1 is very long time constant
- # TODO: let decay be specified per-metric
- decay = 0.5
-
- def __init__(self, buildprogress):
- """Create us from a successful build. We will expect each step to
- take as long as it did in that build."""
-
- # .steps maps stepname to dict2
- # dict2 maps metricname to final end-of-step value
- self.steps = defaultdict(dict)
-
- # .times maps stepname to per-step elapsed time
- self.times = {}
-
- for name, step in buildprogress.steps.items():
- self.steps[name] = {}
- for metric, value in step.progress.items():
- self.steps[name][metric] = value
- self.times[name] = None
- if step.startTime is not None and step.stopTime is not None:
- self.times[name] = step.stopTime - step.startTime
-
- def wavg(self, old, current):
- if old is None:
- return current
- if current is None:
- return old
- else:
- return (current * self.decay) + (old * (1 - self.decay))
-
- def update(self, buildprogress):
- for name, stepprogress in buildprogress.steps.items():
- old = self.times.get(name)
- current = stepprogress.totalTime()
- if current == None:
- log.msg("Expectations.update: current[%s] was None!" % name)
- continue
- new = self.wavg(old, current)
- self.times[name] = new
- if self.debug:
- print "new expected time[%s] = %s, old %s, cur %s" % \
- (name, new, old, current)
-
- for metric, current in stepprogress.progress.items():
- old = self.steps[name].get(metric)
- new = self.wavg(old, current)
- if self.debug:
- print "new expectation[%s][%s] = %s, old %s, cur %s" % \
- (name, metric, new, old, current)
- self.steps[name][metric] = new
-
- def expectedBuildTime(self):
- if None in self.times.values():
- return None
- #return sum(self.times.values())
- # python-2.2 doesn't have 'sum'. TODO: drop python-2.2 support
- s = 0
- for v in self.times.values():
- s += v
- return s
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/results.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/results.py
deleted file mode 100644
index 2b012f0e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/results.py
+++ /dev/null
@@ -1,25 +0,0 @@
-# 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
-
-SUCCESS, WARNINGS, FAILURE, SKIPPED, EXCEPTION, RETRY = range(6)
-Results = ["success", "warnings", "failure", "skipped", "exception", "retry"]
-
-def worst_status(a, b):
- # SUCCESS > WARNINGS > FAILURE > EXCEPTION > RETRY
- # Retry needs to be considered the worst so that conusmers don't have to
- # worry about other failures undermining the RETRY.
- for s in (RETRY, EXCEPTION, FAILURE, WARNINGS, SKIPPED, SUCCESS):
- if s in (a, b):
- return s
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/slave.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/slave.py
deleted file mode 100644
index a3c5b4ec..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/slave.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# 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 time
-from zope.interface import implements
-from buildbot import interfaces
-from buildbot.util.eventual import eventually
-
-class SlaveStatus:
- implements(interfaces.ISlaveStatus)
-
- admin = None
- host = None
- access_uri = None
- version = None
- connected = False
- graceful_shutdown = False
- paused = False
-
- def __init__(self, name):
- self.name = name
- self._lastMessageReceived = 0
- self.runningBuilds = []
- self.graceful_callbacks = []
- self.connect_times = []
-
- def getName(self):
- return self.name
- def getAdmin(self):
- return self.admin
- def getHost(self):
- return self.host
- def getAccessURI(self):
- return self.access_uri
- def getVersion(self):
- return self.version
- def isConnected(self):
- return self.connected
- def isPaused(self):
- return self.paused
- def lastMessageReceived(self):
- return self._lastMessageReceived
- def getRunningBuilds(self):
- return self.runningBuilds
- def getConnectCount(self):
- then = time.time() - 3600
- return len([ t for t in self.connect_times if t > then ])
-
- def setAdmin(self, admin):
- self.admin = admin
- def setHost(self, host):
- self.host = host
- def setAccessURI(self, access_uri):
- self.access_uri = access_uri
- def setVersion(self, version):
- self.version = version
- def setConnected(self, isConnected):
- self.connected = isConnected
- def setLastMessageReceived(self, when):
- self._lastMessageReceived = when
- def setPaused(self, isPaused):
- self.paused = isPaused
-
- def recordConnectTime(self):
- # record this connnect, and keep data for the last hour
- now = time.time()
- self.connect_times = [ t for t in self.connect_times if t > now - 3600 ] + [ now ]
-
- def buildStarted(self, build):
- self.runningBuilds.append(build)
- def buildFinished(self, build):
- self.runningBuilds.remove(build)
-
- def getGraceful(self):
- """Return the graceful shutdown flag"""
- return self.graceful_shutdown
- def setGraceful(self, graceful):
- """Set the graceful shutdown flag, and notify all the watchers"""
- self.graceful_shutdown = graceful
- for cb in self.graceful_callbacks:
- eventually(cb, graceful)
- def addGracefulWatcher(self, watcher):
- """Add watcher to the list of watchers to be notified when the
- graceful shutdown flag is changed."""
- if not watcher in self.graceful_callbacks:
- self.graceful_callbacks.append(watcher)
- def removeGracefulWatcher(self, watcher):
- """Remove watcher from the list of watchers to be notified when the
- graceful shutdown flag is changed."""
- if watcher in self.graceful_callbacks:
- self.graceful_callbacks.remove(watcher)
-
- def asDict(self):
- result = {}
- # Constant
- result['name'] = self.getName()
- result['access_uri'] = self.getAccessURI()
-
- # Transient (since it changes when the slave reconnects)
- result['host'] = self.getHost()
- result['admin'] = self.getAdmin()
- result['version'] = self.getVersion()
- result['connected'] = self.isConnected()
- result['runningBuilds'] = [b.asDict() for b in self.getRunningBuilds()]
- return result
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/status_gerrit.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/status_gerrit.py
deleted file mode 100644
index b4925ccf..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/status_gerrit.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# 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
-
-
-"""Push events to gerrit
-
-."""
-
-from buildbot.status.base import StatusReceiverMultiService
-from buildbot.status.builder import Results, SUCCESS, RETRY
-from twisted.internet import reactor
-from twisted.internet.protocol import ProcessProtocol
-
-def defaultReviewCB(builderName, build, result, status, arg):
- if result == RETRY:
- return None, 0, 0
-
- message = "Buildbot finished compiling your patchset\n"
- message += "on configuration: %s\n" % builderName
- message += "The result is: %s\n" % Results[result].upper()
-
- # message, verified, reviewed
- return message, (result == SUCCESS or -1), 0
-
-class GerritStatusPush(StatusReceiverMultiService):
- """Event streamer to a gerrit ssh server."""
-
- def __init__(self, server, username, reviewCB=defaultReviewCB,
- startCB=None, port=29418, reviewArg=None,
- startArg=None, **kwargs):
- """
- @param server: Gerrit SSH server's address to use for push event notifications.
- @param username: Gerrit SSH server's username.
- @param reviewCB: Callback that is called each time a build is finished, and that is used
- to define the message and review approvals depending on the build result.
- @param startCB: Callback that is called each time a build is started.
- Used to define the message sent to Gerrit.
- @param port: Gerrit SSH server's port.
- @param reviewArg: Optional argument passed to the review callback.
- @param startArg: Optional argument passed to the start callback.
- """
- StatusReceiverMultiService.__init__(self)
- # Parameters.
- self.gerrit_server = server
- self.gerrit_username = username
- self.gerrit_port = port
- self.reviewCB = reviewCB
- self.reviewArg = reviewArg
- self.startCB = startCB
- self.startArg = startArg
-
- class LocalPP(ProcessProtocol):
- def __init__(self, status):
- self.status = status
-
- def outReceived(self, data):
- print "gerritout:", data
-
- def errReceived(self, data):
- print "gerriterr:", data
-
- def processEnded(self, status_object):
- if status_object.value.exitCode:
- print "gerrit status: ERROR:", status_object
- else:
- print "gerrit status: OK"
-
- def startService(self):
- print """Starting up."""
- StatusReceiverMultiService.startService(self)
- self.status = self.parent.getStatus()
- self.status.subscribe(self)
-
- def builderAdded(self, name, builder):
- return self # subscribe to this builder
-
- def buildStarted(self, builderName, build):
- if self.startCB is not None:
- message = self.startCB(builderName, build, self.startArg)
- self.sendCodeReviews(build, message)
-
- def buildFinished(self, builderName, build, result):
- """Do the SSH gerrit verify command to the server."""
- message, verified, reviewed = self.reviewCB(builderName, build, result, self.status, self.reviewArg)
- self.sendCodeReviews(build, message, verified, reviewed)
-
- def sendCodeReviews(self, build, message, verified=0, reviewed=0):
- if message is None:
- return
-
- # Gerrit + Repo
- downloads = build.getProperty("repo_downloads")
- downloaded = build.getProperty("repo_downloaded")
- if downloads is not None and downloaded is not None:
- downloaded = downloaded.split(" ")
- if downloads and 2 * len(downloads) == len(downloaded):
- for i in range(0, len(downloads)):
- try:
- project, change1 = downloads[i].split(" ")
- except ValueError:
- return # something is wrong, abort
- change2 = downloaded[2 * i]
- revision = downloaded[2 * i + 1]
- if change1 == change2:
- self.sendCodeReview(project, revision, message, verified, reviewed)
- else:
- return # something is wrong, abort
- return
-
- # Gerrit + Git
- if build.getProperty("gerrit_branch") is not None: # used only to verify Gerrit source
- project = build.getProperty("project")
- revision = build.getProperty("got_revision")
-
- # review doesn't really work with multiple revisions, so let's
- # just assume it's None there
- if isinstance(revision, dict):
- revision = None
-
- if project is not None and revision is not None:
- self.sendCodeReview(project, revision, message, verified, reviewed)
- return
-
- def sendCodeReview(self, project, revision, message=None, verified=0, reviewed=0):
- command = ["ssh", self.gerrit_username + "@" + self.gerrit_server, "-p %d" % self.gerrit_port,
- "gerrit", "review", "--project %s" % str(project)]
- if message:
- command.append("--message '%s'" % message.replace("'","\""))
- if verified:
- command.extend(["--verified %d" % int(verified)])
- if reviewed:
- command.extend(["--code-review %d" % int(reviewed)])
- command.append(str(revision))
- print command
- reactor.spawnProcess(self.LocalPP(self), "ssh", command)
-
-# vim: set ts=4 sts=4 sw=4 et:
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/status_push.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/status_push.py
deleted file mode 100644
index a3ecf5c0..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/status_push.py
+++ /dev/null
@@ -1,442 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-
-"""Push events to an abstract receiver.
-
-Implements the HTTP receiver."""
-
-import datetime
-import os
-import urllib
-import urlparse
-
-try:
- import simplejson as json
- assert json
-except ImportError:
- import json
-
-from buildbot import config
-from buildbot.status.base import StatusReceiverMultiService
-from buildbot.status.persistent_queue import DiskQueue, IndexedQueue, \
- MemoryQueue, PersistentQueue
-from buildbot.status.web.status_json import FilterOut
-from twisted.internet import defer, reactor
-from twisted.python import log
-from twisted.web import client
-
-
-
-class StatusPush(StatusReceiverMultiService):
- """Event streamer to a abstract channel.
-
- It uses IQueue to batch push requests and queue the data when
- the receiver is down.
- When a PersistentQueue object is used, the items are saved to disk on master
- shutdown so they can be pushed back when the master is restarted.
- """
-
- def __init__(self, serverPushCb, queue=None, path=None, filter=True,
- bufferDelay=1, retryDelay=5, blackList=None):
- """
- @serverPushCb: callback to be used. It receives 'self' as parameter. It
- should call self.queueNextServerPush() when it's done to queue the next
- push. It is guaranteed that the queue is not empty when this function is
- called.
- @queue: a item queue that implements IQueue.
- @path: path to save config.
- @filter: when True (default), removes all "", None, False, [] or {}
- entries.
- @bufferDelay: amount of time events are queued before sending, to
- reduce the number of push requests rate. This is the delay between the
- end of a request to initializing a new one.
- @retryDelay: amount of time between retries when no items were pushed on
- last serverPushCb call.
- @blackList: events that shouldn't be sent.
- """
- StatusReceiverMultiService.__init__(self)
-
- # Parameters.
- self.queue = queue
- if self.queue is None:
- self.queue = MemoryQueue()
- self.queue = IndexedQueue(self.queue)
- self.path = path
- self.filter = filter
- self.bufferDelay = bufferDelay
- self.retryDelay = retryDelay
- if not callable(serverPushCb):
- raise NotImplementedError('Please pass serverPushCb parameter.')
- def hookPushCb():
- # Update the index so we know if the next push succeed or not, don't
- # update the value when the queue is empty.
- if not self.queue.nbItems():
- return
- self.lastIndex = self.queue.getIndex()
- return serverPushCb(self)
- self.serverPushCb = hookPushCb
- self.blackList = blackList
-
- # Other defaults.
- # IDelayedCall object that represents the next queued push.
- self.task = None
- self.stopped = False
- self.lastIndex = -1
- self.state = {}
- self.state['started'] = str(datetime.datetime.utcnow())
- self.state['next_id'] = 1
- self.state['last_id_pushed'] = 0
- # Try to load back the state.
- if self.path and os.path.isdir(self.path):
- state_path = os.path.join(self.path, 'state')
- if os.path.isfile(state_path):
- with open(state_path, 'r') as f:
- self.state.update(json.load(f))
-
- if self.queue.nbItems():
- # Last shutdown was not clean, don't wait to send events.
- self.queueNextServerPush()
-
- def startService(self):
- """Starting up."""
- StatusReceiverMultiService.startService(self)
- self.status = self.parent.getStatus()
- self.status.subscribe(self)
- self.initialPush()
-
- def wasLastPushSuccessful(self):
- """Returns if the "virtual pointer" in the queue advanced."""
- return self.lastIndex <= self.queue.getIndex()
-
- def queueNextServerPush(self):
- """Queue the next push or call it immediately.
-
- Called to signal new items are available to be sent or on shutdown.
- A timer should be queued to trigger a network request or the callback
- should be called immediately. If a status push is already queued, ignore
- the current call."""
- # Determine the delay.
- if self.wasLastPushSuccessful():
- if self.stopped:
- # Shutting down.
- delay = 0
- else:
- # Normal case.
- delay = self.bufferDelay
- else:
- if self.stopped:
- # Too bad, we can't do anything now, we're shutting down and the
- # receiver is also down. We'll just save the objects to disk.
- return
- else:
- # The server is inaccessible, retry less often.
- delay = self.retryDelay
-
- # Cleanup a previously queued task if necessary.
- if self.task:
- # Warning: we could be running inside the task.
- if self.task.active():
- # There was already a task queue, don't requeue it, just let it
- # go.
- return
- else:
- if self.task.active():
- # There was a task queued but it is requested to call it
- # *right now* so cancel it.
- self.task.cancel()
- # Otherwise, it was just a stray object.
- self.task = None
-
- # Do the queue/direct call.
- if delay:
- # Call in delay seconds.
- self.task = reactor.callLater(delay, self.serverPushCb)
- elif self.stopped:
- if not self.queue.nbItems():
- return
- # Call right now, we're shutting down.
- @defer.inlineCallbacks
- def BlockForEverythingBeingSent():
- yield self.serverPushCb()
- return BlockForEverythingBeingSent()
- else:
- # delay should never be 0. That can cause Buildbot to spin tightly
- # trying to push events that may not be received well by a status
- # listener.
- log.err('Did not expect delay to be 0, but it is.')
- return
-
- def stopService(self):
- """Shutting down."""
- self.finalPush()
- self.stopped = True
- if (self.task and self.task.active()):
- # We don't have time to wait, force an immediate call.
- self.task.cancel()
- self.task = None
- d = self.queueNextServerPush()
- elif self.wasLastPushSuccessful():
- d = self.queueNextServerPush()
- else:
- d = defer.succeed(None)
-
- # We're dying, make sure we save the results.
- self.queue.save()
- if self.path and os.path.isdir(self.path):
- state_path = os.path.join(self.path, 'state')
- with open(state_path, 'w') as f:
- json.dump(self.state, f, sort_keys=True,
- indent=2)
- # Make sure all Deferreds are called on time and in a sane order.
- defers = filter(None, [d, StatusReceiverMultiService.stopService(self)])
- return defer.DeferredList(defers)
-
- def push(self, event, **objs):
- """Push a new event.
-
- The new event will be either:
- - Queued in memory to reduce network usage
- - Queued to disk when the sink server is down
- - Pushed (along the other queued items) to the server
- """
- if self.blackList and event in self.blackList:
- return
- # First, generate the packet.
- packet = {}
- packet['id'] = self.state['next_id']
- self.state['next_id'] += 1
- packet['timestamp'] = str(datetime.datetime.utcnow())
- packet['project'] = self.status.getTitle()
- packet['started'] = self.state['started']
- packet['event'] = event
- packet['payload'] = {}
- for obj_name, obj in objs.items():
- if hasattr(obj, 'asDict'):
- obj = obj.asDict()
- if self.filter:
- obj = FilterOut(obj)
- packet['payload'][obj_name] = obj
- self.queue.pushItem(packet)
- if self.task is None or not self.task.active():
- # No task queued since it was probably idle, let's queue a task.
- return self.queueNextServerPush()
-
- #### Events
-
- def initialPush(self):
- # Push everything we want to push from the initial configuration.
- self.push('start', status=self.status)
-
- def finalPush(self):
- self.push('shutdown', status=self.status)
-
- def requestSubmitted(self, request):
- self.push('requestSubmitted', request=request)
-
- def requestCancelled(self, builder, request):
- self.push('requestCancelled', builder=builder, request=request)
-
- def buildsetSubmitted(self, buildset):
- self.push('buildsetSubmitted', buildset=buildset)
-
- def builderAdded(self, builderName, builder):
- self.push('builderAdded', builderName=builderName, builder=builder)
- return self
-
- def builderChangedState(self, builderName, state):
- self.push('builderChangedState', builderName=builderName, state=state)
-
- def buildStarted(self, builderName, build):
- self.push('buildStarted', build=build)
- return self
-
- def buildETAUpdate(self, build, ETA):
- self.push('buildETAUpdate', build=build, ETA=ETA)
-
- def stepStarted(self, build, step):
- self.push('stepStarted',
- properties=build.getProperties().asList(),
- step=step)
-
- def stepTextChanged(self, build, step, text):
- self.push('stepTextChanged',
- properties=build.getProperties().asList(),
- step=step,
- text=text)
-
- def stepText2Changed(self, build, step, text2):
- self.push('stepText2Changed',
- properties=build.getProperties().asList(),
- step=step,
- text2=text2)
-
- def stepETAUpdate(self, build, step, ETA, expectations):
- self.push('stepETAUpdate',
- properties=build.getProperties().asList(),
- step=step,
- ETA=ETA,
- expectations=expectations)
-
- def logStarted(self, build, step, log):
- self.push('logStarted',
- properties=build.getProperties().asList(),
- step=step)
-
- def logFinished(self, build, step, log):
- self.push('logFinished',
- properties=build.getProperties().asList(),
- step=step)
-
- def stepFinished(self, build, step, results):
- self.push('stepFinished',
- properties=build.getProperties().asList(),
- step=step)
-
- def buildFinished(self, builderName, build, results):
- self.push('buildFinished', build=build)
-
- def builderRemoved(self, builderName):
- self.push('buildedRemoved', builderName=builderName)
-
- def changeAdded(self, change):
- self.push('changeAdded', change=change)
-
- def slaveConnected(self, slavename):
- self.push('slaveConnected', slave=self.status.getSlave(slavename))
-
- def slaveDisconnected(self, slavename):
- self.push('slaveDisconnected', slavename=slavename)
-
-
-class HttpStatusPush(StatusPush):
- """Event streamer to a HTTP server."""
-
- def __init__(self, serverUrl, debug=None, maxMemoryItems=None,
- maxDiskItems=None, chunkSize=200, maxHttpRequestSize=2**20,
- extra_post_params=None, **kwargs):
- """
- @serverUrl: Base URL to be used to push events notifications.
- @maxMemoryItems: Maximum number of items to keep queued in memory.
- @maxDiskItems: Maximum number of items to buffer to disk, if 0, doesn't
- use disk at all.
- @debug: Save the json with nice formatting.
- @chunkSize: maximum number of items to send in each at each HTTP POST.
- @maxHttpRequestSize: limits the size of encoded data for AE, the default
- is 1MB.
- """
- if not serverUrl:
- raise config.ConfigErrors(['HttpStatusPush requires a serverUrl'])
-
- # Parameters.
- self.serverUrl = serverUrl
- self.extra_post_params = extra_post_params or {}
- self.debug = debug
- self.chunkSize = chunkSize
- self.lastPushWasSuccessful = True
- self.maxHttpRequestSize = maxHttpRequestSize
- if maxDiskItems != 0:
- # The queue directory is determined by the server url.
- path = ('events_' +
- urlparse.urlparse(self.serverUrl)[1].split(':')[0])
- queue = PersistentQueue(
- primaryQueue=MemoryQueue(maxItems=maxMemoryItems),
- secondaryQueue=DiskQueue(path, maxItems=maxDiskItems))
- else:
- path = None
- queue = MemoryQueue(maxItems=maxMemoryItems)
-
- # Use the unbounded method.
- StatusPush.__init__(self, serverPushCb=HttpStatusPush.pushHttp,
- queue=queue, path=path, **kwargs)
-
- def wasLastPushSuccessful(self):
- return self.lastPushWasSuccessful
-
- def popChunk(self):
- """Pops items from the pending list.
-
- They must be queued back on failure."""
- if self.wasLastPushSuccessful():
- chunkSize = self.chunkSize
- else:
- chunkSize = 1
-
- while True:
- items = self.queue.popChunk(chunkSize)
- newitems = []
- for item in items:
- if hasattr(item, 'asDict'):
- newitems.append(item.asDict())
- else:
- newitems.append(item)
- if self.debug:
- packets = json.dumps(newitems, indent=2, sort_keys=True)
- else:
- packets = json.dumps(newitems, separators=(',',':'))
- params = {'packets': packets}
- params.update(self.extra_post_params)
- data = urllib.urlencode(params)
- if (not self.maxHttpRequestSize or
- len(data) < self.maxHttpRequestSize):
- return (data, items)
-
- if chunkSize == 1:
- # This packet is just too large. Drop this packet.
- log.msg("ERROR: packet %s was dropped, too large: %d > %d" %
- (items[0]['id'], len(data), self.maxHttpRequestSize))
- chunkSize = self.chunkSize
- else:
- # Try with half the packets.
- chunkSize /= 2
- self.queue.insertBackChunk(items)
-
- def pushHttp(self):
- """Do the HTTP POST to the server."""
- (encoded_packets, items) = self.popChunk()
-
- def Success(result):
- """Queue up next push."""
- log.msg('Sent %d events to %s' % (len(items), self.serverUrl))
- self.lastPushWasSuccessful = True
- return self.queueNextServerPush()
-
- def Failure(result):
- """Insert back items not sent and queue up next push."""
- # Server is now down.
- log.msg('Failed to push %d events to %s: %s' %
- (len(items), self.serverUrl, str(result)))
- self.queue.insertBackChunk(items)
- if self.stopped:
- # Bad timing, was being called on shutdown and the server died
- # on us. Make sure the queue is saved since we just queued back
- # items.
- self.queue.save()
- self.lastPushWasSuccessful = False
- return self.queueNextServerPush()
-
- # Trigger the HTTP POST request.
- headers = {'Content-Type': 'application/x-www-form-urlencoded'}
- connection = client.getPage(self.serverUrl,
- method='POST',
- postdata=encoded_packets,
- headers=headers,
- agent='buildbot')
- connection.addCallbacks(Success, Failure)
- return connection
-
-# vim: set ts=4 sts=4 sw=4 et:
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/testresult.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/testresult.py
deleted file mode 100644
index 20002405..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/testresult.py
+++ /dev/null
@@ -1,39 +0,0 @@
-# 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
-
-from zope.interface import implements
-from buildbot import interfaces
-
-class TestResult:
- implements(interfaces.ITestResult)
-
- def __init__(self, name, results, text, logs):
- assert isinstance(name, tuple)
- self.name = name
- self.results = results
- self.text = text
- self.logs = logs
-
- def getName(self):
- return self.name
-
- def getResults(self):
- return self.results
-
- def getText(self):
- return self.text
-
- def getLogs(self):
- return self.logs
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/tinderbox.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/tinderbox.py
deleted file mode 100644
index 1694c243..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/tinderbox.py
+++ /dev/null
@@ -1,276 +0,0 @@
-# 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
-
-
-from email.Message import Message
-from email.Utils import formatdate
-
-from zope.interface import implements
-from twisted.internet import defer
-
-from buildbot import interfaces
-from buildbot.status import mail
-from buildbot.status.results import SUCCESS, WARNINGS, EXCEPTION, RETRY
-from buildbot.steps.shell import WithProperties
-
-import gzip, bz2, base64, re, cStringIO
-
-# TODO: docs, maybe a test of some sort just to make sure it actually imports
-# and can format email without raising an exception.
-
-class TinderboxMailNotifier(mail.MailNotifier):
- """This is a Tinderbox status notifier. It can send e-mail to a number of
- different tinderboxes or people. E-mails are sent at the beginning and
- upon completion of each build. It can be configured to send out e-mails
- for only certain builds.
-
- The most basic usage is as follows::
- TinderboxMailNotifier(fromaddr="buildbot@localhost",
- tree="MyTinderboxTree",
- extraRecipients=["tinderboxdaemon@host.org"])
-
- The builder name (as specified in master.cfg) is used as the "build"
- tinderbox option.
-
- """
- implements(interfaces.IEmailSender)
-
- compare_attrs = ["extraRecipients", "fromaddr", "categories", "builders",
- "addLogs", "relayhost", "subject", "binaryURL", "tree",
- "logCompression", "errorparser", "columnName",
- "useChangeTime"]
-
- def __init__(self, fromaddr, tree, extraRecipients,
- categories=None, builders=None, relayhost="localhost",
- subject="buildbot %(result)s in %(builder)s", binaryURL="",
- logCompression="", errorparser="unix", columnName=None,
- useChangeTime=False):
- """
- @type fromaddr: string
- @param fromaddr: the email address to be used in the 'From' header.
-
- @type tree: string
- @param tree: The Tinderbox tree to post to.
- When tree is a WithProperties instance it will be
- interpolated as such. See WithProperties for more detail
-
- @type extraRecipients: tuple of string
- @param extraRecipients: E-mail addresses of recipients. This should at
- least include the tinderbox daemon.
-
- @type categories: list of strings
- @param categories: a list of category names to serve status
- information for. Defaults to None (all
- categories). Use either builders or categories,
- but not both.
-
- @type builders: list of strings
- @param builders: a list of builder names for which mail should be
- sent. Defaults to None (send mail for all builds).
- Use either builders or categories, but not both.
-
- @type relayhost: string
- @param relayhost: the host to which the outbound SMTP connection
- should be made. Defaults to 'localhost'
-
- @type subject: string
- @param subject: a string to be used as the subject line of the message.
- %(builder)s will be replaced with the name of the
- %builder which provoked the message.
- This parameter is not significant for the tinderbox
- daemon.
-
- @type binaryURL: string
- @param binaryURL: If specified, this should be the location where final
- binary for a build is located.
- (ie. http://www.myproject.org/nightly/08-08-2006.tgz)
- It will be posted to the Tinderbox.
-
- @type logCompression: string
- @param logCompression: The type of compression to use on the log.
- Valid options are"bzip2" and "gzip". gzip is
- only known to work on Python 2.4 and above.
-
- @type errorparser: string
- @param errorparser: The error parser that the Tinderbox server
- should use when scanning the log file.
- Default is "unix".
-
- @type columnName: string
- @param columnName: When columnName is None, use the buildername as
- the Tinderbox column name. When columnName is a
- string this exact string will be used for all
- builders that this TinderboxMailNotifier cares
- about (not recommended). When columnName is a
- WithProperties instance it will be interpolated
- as such. See WithProperties for more detail.
- @type useChangeTime: bool
- @param useChangeTime: When True, the time of the first Change for a
- build is used as the builddate. When False,
- the current time is used as the builddate.
- """
-
- mail.MailNotifier.__init__(self, fromaddr, categories=categories,
- builders=builders, relayhost=relayhost,
- subject=subject,
- extraRecipients=extraRecipients,
- sendToInterestedUsers=False)
- assert isinstance(tree, basestring) \
- or isinstance(tree, WithProperties), \
- "tree must be a string or a WithProperties instance"
- self.tree = tree
- self.binaryURL = binaryURL
- self.logCompression = logCompression
- self.errorparser = errorparser
- self.useChangeTime = useChangeTime
- assert columnName is None or type(columnName) is str \
- or isinstance(columnName, WithProperties), \
- "columnName must be None, a string, or a WithProperties instance"
- self.columnName = columnName
-
- def buildStarted(self, name, build):
- builder = build.getBuilder()
- if self.builders is not None and name not in self.builders:
- return # ignore this Build
- if self.categories is not None and \
- builder.category not in self.categories:
- return # ignore this build
- self.buildMessage(name, build, "building")
-
- @defer.inlineCallbacks
- def buildMessage(self, name, build, results):
- text = ""
- res = ""
- # shortform
- t = "tinderbox:"
-
- tree = yield build.render(self.tree)
- text += "%s tree: %s\n" % (t, tree)
-
- # the start time
- # getTimes() returns a fractioned time that tinderbox doesn't understand
- builddate = int(build.getTimes()[0])
- # attempt to pull a Change time from this Build's Changes.
- # if that doesn't work, fall back on the current time
- if self.useChangeTime:
- try:
- builddate = build.getChanges()[-1].when
- except:
- pass
- text += "%s builddate: %s\n" % (t, builddate)
- text += "%s status: " % t
-
- if results == "building":
- res = "building"
- text += res
- elif results == SUCCESS:
- res = "success"
- text += res
- elif results == WARNINGS:
- res = "testfailed"
- text += res
- elif results in (EXCEPTION, RETRY):
- res = "exception"
- text += res
- else:
- res += "busted"
- text += res
-
- text += "\n";
-
- if self.columnName is None:
- # use the builder name
- text += "%s build: %s\n" % (t, name)
- else:
- columnName = yield build.render(self.columnName)
- text += "%s build: %s\n" % (t, columnName)
- text += "%s errorparser: %s\n" % (t, self.errorparser)
-
- # if the build just started...
- if results == "building":
- text += "%s END\n" % t
- # if the build finished...
- else:
- text += "%s binaryurl: %s\n" % (t, self.binaryURL)
- text += "%s logcompression: %s\n" % (t, self.logCompression)
-
- # logs will always be appended
- logEncoding = ""
- tinderboxLogs = ""
- for bs in build.getSteps():
- # Make sure that shortText is a regular string, so that bad
- # data in the logs don't generate UnicodeDecodeErrors
- shortText = "%s\n" % ' '.join(bs.getText()).encode('ascii', 'replace')
-
- # ignore steps that haven't happened
- if not re.match(".*[^\s].*", shortText):
- continue
- # we ignore TinderboxPrint's here so we can do things like:
- # ShellCommand(command=['echo', 'TinderboxPrint:', ...])
- if re.match(".+TinderboxPrint.*", shortText):
- shortText = shortText.replace("TinderboxPrint",
- "Tinderbox Print")
- logs = bs.getLogs()
-
- tinderboxLogs += "======== BuildStep started ========\n"
- tinderboxLogs += shortText
- tinderboxLogs += "=== Output ===\n"
- for log in logs:
- logText = log.getTextWithHeaders()
- # Because we pull in the log headers here we have to ignore
- # some of them. Basically, if we're TinderboxPrint'ing in
- # a ShellCommand, the only valid one(s) are at the start
- # of a line. The others are prendeded by whitespace, quotes,
- # or brackets/parentheses
- for line in logText.splitlines():
- if re.match(".+TinderboxPrint.*", line):
- line = line.replace("TinderboxPrint",
- "Tinderbox Print")
- tinderboxLogs += line + "\n"
-
- tinderboxLogs += "=== Output ended ===\n"
- tinderboxLogs += "======== BuildStep ended ========\n"
-
- if self.logCompression == "bzip2":
- cLog = bz2.compress(tinderboxLogs)
- tinderboxLogs = base64.encodestring(cLog)
- logEncoding = "base64"
- elif self.logCompression == "gzip":
- cLog = cStringIO.StringIO()
- gz = gzip.GzipFile(mode="w", fileobj=cLog)
- gz.write(tinderboxLogs)
- gz.close()
- cLog = cLog.getvalue()
- tinderboxLogs = base64.encodestring(cLog)
- logEncoding = "base64"
-
- text += "%s logencoding: %s\n" % (t, logEncoding)
- text += "%s END\n\n" % t
- text += tinderboxLogs
- text += "\n"
-
- m = Message()
- m.set_payload(text)
-
- m['Date'] = formatdate(localtime=True)
- m['Subject'] = self.subject % { 'result': res,
- 'builder': name,
- }
- m['From'] = self.fromaddr
- # m['To'] is added later
-
- d = defer.DeferredList([])
- d.addCallback(self._gotRecipients, self.extraRecipients, m)
- defer.returnValue((yield d))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/about.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/about.py
deleted file mode 100644
index 0a5e068b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/about.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# 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
-
-
-from buildbot.status.web.base import HtmlResource
-import buildbot
-import twisted
-import sys
-import jinja2
-
-class AboutBuildbot(HtmlResource):
- pageTitle = "About this Buildbot"
-
- def content(self, request, cxt):
- cxt.update(dict(buildbot=buildbot.version,
- twisted=twisted.__version__,
- jinja=jinja2.__version__,
- python=sys.version,
- platform=sys.platform))
-
- template = request.site.buildbot_service.templates.get_template("about.html")
- template.autoescape = True
- return template.render(**cxt)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/auth.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/auth.py
deleted file mode 100644
index e9b168c9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/auth.py
+++ /dev/null
@@ -1,220 +0,0 @@
-# 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 os
-from zope.interface import Interface, Attribute, implements
-from buildbot.status.web.base import HtmlResource, ActionResource
-from buildbot.status.web.base import path_to_authfail
-
-from buildbot.process.users import users
-
-class IAuth(Interface):
- """
- Represent an authentication method.
-
- Note that each IAuth instance contains a link to the BuildMaster that
- will be set once the IAuth instance is initialized.
- """
-
- master = Attribute('master', "Link to BuildMaster, set when initialized")
-
- def authenticate(self, user, passwd):
- """Check whether C{user} / C{passwd} are valid."""
-
- def getUserInfo(self, user):
- """return dict with user info.
- dict( fullName="", email="", groups=[])
- """
-
- def errmsg(self):
- """Get the reason authentication failed."""
-
-class AuthBase:
- master = None # set in status.web.baseweb
- err = ""
-
- def errmsg(self):
- return self.err
-
- def getUserInfo(self, user):
- """default dummy impl"""
- return dict(userName=user, fullName=user, email=user+"@localhost", groups=[ user ])
-
-class BasicAuth(AuthBase):
- implements(IAuth)
- """Implement basic authentication against a list of user/passwd."""
-
- userpass = []
- """List of user/pass tuples."""
-
- def __init__(self, userpass):
- """C{userpass} is a list of (user, passwd)."""
- for item in userpass:
- assert isinstance(item, tuple) or isinstance(item, list)
- u, p = item
- assert isinstance(u, str)
- assert isinstance(p, str)
- self.userpass = userpass
-
- def authenticate(self, user, passwd):
- """Check that C{user}/C{passwd} is a valid user/pass tuple."""
- if not self.userpass:
- self.err = "Bad self.userpass data"
- return False
- for u, p in self.userpass:
- if user == u and passwd == p:
- self.err = ""
- return True
- self.err = "Invalid username or password"
- return False
-
-class HTPasswdAuth(AuthBase):
- implements(IAuth)
- """Implement authentication against an .htpasswd file."""
-
- file = ""
- """Path to the .htpasswd file to use."""
-
- def __init__(self, file):
- """C{file} is a path to an .htpasswd file."""
- assert os.path.exists(file)
- self.file = file
-
- def authenticate(self, user, passwd):
- """Authenticate C{user} and C{passwd} against an .htpasswd file"""
- if not os.path.exists(self.file):
- self.err = "No such file: " + self.file
- return False
- # Fetch each line from the .htpasswd file and split it into a
- # [user, passwd] array.
- lines = [l.rstrip().split(':', 1)
- for l in file(self.file).readlines()]
- # Keep only the line for this login
- lines = [l for l in lines if l[0] == user]
- if not lines:
- self.err = "Invalid user/passwd"
- return False
- hash = lines[0][1]
- res = self.validatePassword(passwd, hash)
- if res:
- self.err = ""
- else:
- self.err = "Invalid user/passwd"
- return res
-
- def validatePassword(self, passwd, hash):
- # This is the DES-hash of the password. The first two characters are
- # the salt used to introduce disorder in the DES algorithm.
- from crypt import crypt #@UnresolvedImport
- return hash == crypt(passwd, hash[0:2])
-
-
-class HTPasswdAprAuth(HTPasswdAuth):
- implements(IAuth)
- """Implement authentication against an .htpasswd file based on libaprutil"""
-
- file = ""
- """Path to the .htpasswd file to use."""
-
- def __init__(self, file):
- HTPasswdAuth.__init__(self, file)
-
- # Try to load libaprutil throug ctypes
- self.apr = None
- try:
- from ctypes import CDLL
- from ctypes.util import find_library
- lib = find_library("aprutil-1")
- if lib:
- self.apr = CDLL(lib)
- except:
- self.apr = None
-
- def validatePassword(self, passwd, hash):
- # Use apr_password_validate from libaprutil if libaprutil is available.
- # Fallback to DES only checking from HTPasswdAuth
- if self.apr:
- return self.apr.apr_password_validate(passwd, hash) == 0
- else:
- return HTPasswdAuth.validatePassword(self, passwd, hash)
-
-class UsersAuth(AuthBase):
- """Implement authentication against users in database"""
- implements(IAuth)
-
- def authenticate(self, user, passwd):
- """
- It checks for a matching uid in the database for the credentials
- and return True if a match is found, False otherwise.
-
- @param user: username portion of user credentials
- @type user: string
-
- @param passwd: password portion of user credentials
- @type passwd: string
-
- @returns: boolean via deferred.
- """
- d = self.master.db.users.getUserByUsername(user)
- def check_creds(user):
- if user:
- if users.check_passwd(passwd, user['bb_password']):
- return True
- self.err = "no user found with those credentials"
- return False
- d.addCallback(check_creds)
- return d
-
-class AuthFailResource(HtmlResource):
- pageTitle = "Authentication Failed"
-
- def content(self, request, cxt):
- templates =request.site.buildbot_service.templates
- template = templates.get_template("authfail.html")
- return template.render(**cxt)
-
-class AuthzFailResource(HtmlResource):
- pageTitle = "Authorization Failed"
-
- def content(self, request, cxt):
- templates =request.site.buildbot_service.templates
- template = templates.get_template("authzfail.html")
- return template.render(**cxt)
-
-class LoginResource(ActionResource):
-
- def performAction(self, request):
- authz = self.getAuthz(request)
- d = authz.login(request)
- def on_login(res):
- if res:
- status = request.site.buildbot_service.master.status
- root = status.getBuildbotURL()
- return request.requestHeaders.getRawHeaders('referer',
- [root])[0]
- else:
- return path_to_authfail(request)
- d.addBoth(on_login)
- return d
-
-class LogoutResource(ActionResource):
-
- def performAction(self, request):
- authz = self.getAuthz(request)
- authz.logout(request)
- status = request.site.buildbot_service.master.status
- root = status.getBuildbotURL()
- return request.requestHeaders.getRawHeaders('referer',[root])[0]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/authz.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/authz.py
deleted file mode 100644
index dace7f23..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/authz.py
+++ /dev/null
@@ -1,188 +0,0 @@
-# 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
-
-from twisted.internet import defer
-from buildbot.status.web.auth import IAuth
-from buildbot.status.web.session import SessionManager
-
-COOKIE_KEY="BuildBotSession"
-class Authz(object):
- """Decide who can do what."""
-
- knownActions = [
- # If you add a new action here, be sure to also update the documentation
- # at docs/manual/cfg-statustargets.rst.
- 'view',
- 'gracefulShutdown',
- 'forceBuild',
- 'forceAllBuilds',
- 'pingBuilder',
- 'stopBuild',
- 'stopAllBuilds',
- 'cancelPendingBuild',
- 'cancelAllPendingBuilds',
- 'stopChange',
- 'cleanShutdown',
- 'showUsersPage',
- 'pauseSlave',
- ]
-
- def __init__(self,
- default_action=False,
- auth=None,
- useHttpHeader=False,
- httpLoginUrl=False,
- view=True,
- **kwargs):
- self.auth = auth
- if auth:
- assert IAuth.providedBy(auth)
-
- self.useHttpHeader = useHttpHeader
- self.httpLoginUrl = httpLoginUrl
-
- self.config = dict((a, default_action) for a in self.knownActions)
- self.config['view'] = view
- for act in self.knownActions:
- if act in kwargs:
- self.config[act] = kwargs[act]
- del kwargs[act]
-
- self.sessions = SessionManager()
- if kwargs:
- raise ValueError("unknown authorization action(s) " + ", ".join(kwargs.keys()))
-
- def session(self, request):
- if COOKIE_KEY in request.received_cookies:
- cookie = request.received_cookies[COOKIE_KEY]
- return self.sessions.get(cookie)
- return None
-
- def authenticated(self, request):
- if self.useHttpHeader:
- return request.getUser() != ''
- return self.session(request) is not None
-
- def getUserInfo(self, user):
- if self.useHttpHeader:
- return dict(userName=user, fullName=user, email=user, groups=[user])
- s = self.sessions.getUser(user)
- if s:
- return s.infos
-
- def getUsername(self, request):
- """Get the userid of the user"""
- if self.useHttpHeader:
- return request.getUser()
- s = self.session(request)
- if s:
- return s.user
- return request.args.get("username", ["<unknown>"])[0]
-
- def getUsernameHTML(self, request):
- """Get the user formatated in html (with possible link to email)"""
- if self.useHttpHeader:
- return request.getUser()
- s = self.session(request)
- if s:
- return s.userInfosHTML()
- return "not authenticated?!"
-
- def getUsernameFull(self, request):
- """Get the full username as fullname <email>"""
- if self.useHttpHeader:
- return request.getUser()
- s = self.session(request)
- if s:
- return "%(fullName)s <%(email)s>" % (s.infos)
- else:
- return request.args.get("username", ["<unknown>"])[0]
-
-
- def getPassword(self, request):
- if self.useHttpHeader:
- return request.getPassword()
- return request.args.get("passwd", ["<no-password>"])[0]
-
- def advertiseAction(self, action, request):
- """Should the web interface even show the form for ACTION?"""
- if action not in self.knownActions:
- raise KeyError("unknown action")
- cfg = self.config.get(action, False)
- if cfg:
- if cfg == 'auth' or callable(cfg):
- return self.authenticated(request)
- return cfg
-
- def actionAllowed(self, action, request, *args):
- """Is this ACTION allowed, given this http REQUEST?"""
- if action not in self.knownActions:
- raise KeyError("unknown action")
- cfg = self.config.get(action, False)
- if cfg:
- if cfg == 'auth' or callable(cfg):
- if not self.auth:
- return defer.succeed(False)
- def check_authenticate(res):
- if callable(cfg) and not cfg(self.getUsername(request), *args):
- return False
- return True
- # retain old behaviour, if people have scripts
- # without cookie support
- passwd = self.getPassword(request)
- if self.authenticated(request):
- return defer.succeed(check_authenticate(None))
- elif passwd != "<no-password>":
- def check_login(cookie):
- ret = False
- if isinstance(cookie, str):
- ret = check_authenticate(None)
- self.sessions.remove(cookie)
- return ret
- d = self.login(request)
- d.addBoth(check_login)
- return d
- else:
- return defer.succeed(False)
- return defer.succeed(cfg)
-
- def login(self, request):
- """Login one user, and return session cookie"""
- if self.authenticated(request):
- return defer.succeed(False)
-
- user = request.args.get("username", ["<unknown>"])[0]
- passwd = request.args.get("passwd", ["<no-password>"])[0]
- if user == "<unknown>" or passwd == "<no-password>":
- return defer.succeed(False)
- if not self.auth:
- return defer.succeed(False)
- d = defer.maybeDeferred(self.auth.authenticate, user, passwd)
-
- def check_authenticate(res):
- if res:
- cookie, s = self.sessions.new(user, self.auth.getUserInfo(user))
- request.addCookie(COOKIE_KEY, cookie, expires=s.getExpiration(), path="/")
- request.received_cookies = {COOKIE_KEY: cookie}
- return cookie
- else:
- return False
- d.addBoth(check_authenticate)
- return d
-
- def logout(self, request):
- if COOKIE_KEY in request.received_cookies:
- cookie = request.received_cookies[COOKIE_KEY]
- self.sessions.remove(cookie)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/base.py
deleted file mode 100644
index 47a3f344..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/base.py
+++ /dev/null
@@ -1,806 +0,0 @@
-# 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 urlparse, urllib, time, re
-import os, cgi, sys, locale
-import jinja2
-from zope.interface import Interface
-from twisted.internet import defer
-from twisted.web import resource, static, server
-from twisted.python import log
-from buildbot.status import builder, buildstep, build
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE, SKIPPED
-from buildbot.status.results import EXCEPTION, RETRY
-from buildbot import version, util
-from buildbot.process.properties import Properties
-
-class ITopBox(Interface):
- """I represent a box in the top row of the waterfall display: the one
- which shows the status of the last build for each builder."""
- def getBox(self, request):
- """Return a Box instance, which can produce a <td> cell.
- """
-
-class ICurrentBox(Interface):
- """I represent the 'current activity' box, just above the builder name."""
- def getBox(self, status):
- """Return a Box instance, which can produce a <td> cell.
- """
-
-class IBox(Interface):
- """I represent a box in the waterfall display."""
- def getBox(self, request):
- """Return a Box instance, which wraps an Event and can produce a <td>
- cell.
- """
-
-class IHTMLLog(Interface):
- pass
-
-css_classes = {SUCCESS: "success",
- WARNINGS: "warnings",
- FAILURE: "failure",
- SKIPPED: "skipped",
- EXCEPTION: "exception",
- RETRY: "retry",
- None: "",
- }
-
-
-def getAndCheckProperties(req):
- """
- Fetch custom build properties from the HTTP request of a "Force build" or
- "Resubmit build" HTML form.
- Check the names for valid strings, and return None if a problem is found.
- Return a new Properties object containing each property found in req.
- """
- master = req.site.buildbot_service.master
- pname_validate = master.config.validation['property_name']
- pval_validate = master.config.validation['property_value']
- properties = Properties()
- i = 1
- while True:
- pname = req.args.get("property%dname" % i, [""])[0]
- pvalue = req.args.get("property%dvalue" % i, [""])[0]
- if not pname:
- break
- if not pname_validate.match(pname) \
- or not pval_validate.match(pvalue):
- log.msg("bad property name='%s', value='%s'" % (pname, pvalue))
- return None
- properties.setProperty(pname, pvalue, "Force Build Form")
- i = i + 1
-
- return properties
-
-def build_get_class(b):
- """
- Return the class to use for a finished build or buildstep,
- based on the result.
- """
- # FIXME: this getResults duplicity might need to be fixed
- result = b.getResults()
- if isinstance(b, build.BuildStatus):
- result = b.getResults()
- elif isinstance(b, buildstep.BuildStepStatus):
- result = b.getResults()[0]
- # after forcing a build, b.getResults() returns ((None, []), []), ugh
- if isinstance(result, tuple):
- result = result[0]
- else:
- raise TypeError, "%r is not a BuildStatus or BuildStepStatus" % b
-
- if result == None:
- # FIXME: this happens when a buildstep is running ?
- return "running"
- return builder.Results[result]
-
-def path_to_root(request):
- # /waterfall : ['waterfall'] -> './'
- # /somewhere/lower : ['somewhere', 'lower'] -> '../'
- # /somewhere/indexy/ : ['somewhere', 'indexy', ''] -> '../../'
- # / : [] -> './'
- if request.prepath:
- segs = len(request.prepath) - 1
- else:
- segs = 0
- root = "../" * segs if segs else './'
- return root
-
-def path_to_authfail(request):
- return path_to_root(request) + "authfail"
-
-def path_to_authzfail(request):
- return path_to_root(request) + "authzfail"
-
-def path_to_builder(request, builderstatus):
- return (path_to_root(request) +
- "builders/" +
- urllib.quote(builderstatus.getName(), safe=''))
-
-def path_to_build(request, buildstatus):
- return (path_to_builder(request, buildstatus.getBuilder()) +
- "/builds/%d" % buildstatus.getNumber())
-
-def path_to_step(request, stepstatus):
- return (path_to_build(request, stepstatus.getBuild()) +
- "/steps/%s" % urllib.quote(stepstatus.getName(), safe=''))
-
-def path_to_slave(request, slave):
- return (path_to_root(request) +
- "buildslaves/" +
- urllib.quote(slave.getName(), safe=''))
-
-def path_to_change(request, change):
- return (path_to_root(request) +
- "changes/%s" % change.number)
-
-class Box:
- # a Box wraps an Event. The Box has HTML <td> parameters that Events
- # lack, and it has a base URL to which each File's name is relative.
- # Events don't know about HTML.
- spacer = False
- def __init__(self, text=[], class_=None, urlbase=None,
- **parms):
- self.text = text
- self.class_ = class_
- self.urlbase = urlbase
- self.show_idle = 0
- if parms.has_key('show_idle'):
- del parms['show_idle']
- self.show_idle = 1
-
- self.parms = parms
- # parms is a dict of HTML parameters for the <td> element that will
- # represent this Event in the waterfall display.
-
- def td(self, **props):
- props.update(self.parms)
- text = self.text
- if not text and self.show_idle:
- text = ["[idle]"]
- props['class'] = self.class_
- props['text'] = text;
- return props
-
-
-class AccessorMixin(object):
- def getStatus(self, request):
- return request.site.buildbot_service.getStatus()
-
- def getPageTitle(self, request):
- return self.pageTitle
-
- def getAuthz(self, request):
- return request.site.buildbot_service.authz
-
- def getBuildmaster(self, request):
- return request.site.buildbot_service.master
-
-
-class ContextMixin(AccessorMixin):
- def getContext(self, request):
- status = self.getStatus(request)
- rootpath = path_to_root(request)
- locale_enc = locale.getdefaultlocale()[1]
- if locale_enc is not None:
- locale_tz = unicode(time.tzname[time.localtime()[-1]], locale_enc)
- else:
- locale_tz = unicode(time.tzname[time.localtime()[-1]])
- return dict(title_url = status.getTitleURL(),
- title = status.getTitle(),
- stylesheet = rootpath + 'default.css',
- path_to_root = rootpath,
- version = version,
- time = time.strftime("%a %d %b %Y %H:%M:%S",
- time.localtime(util.now())),
- tz = locale_tz,
- metatags = [],
- pageTitle = self.getPageTitle(request),
- welcomeurl = rootpath,
- authz = self.getAuthz(request),
- request = request,
- alert_msg = request.args.get("alert_msg", [""])[0],
- )
-
-
-class ActionResource(resource.Resource, AccessorMixin):
- """A resource that performs some action, then redirects to a new URL."""
-
- isLeaf = 1
-
- def getChild(self, name, request):
- return self
-
- def performAction(self, request):
- """
- Perform the action, and return the URL to redirect to
-
- @param request: the web request
- @returns: URL via Deferred
- can also return (URL, alert_msg) to display simple
- feedback to user in case of failure
- """
-
- def render(self, request):
- d = defer.maybeDeferred(lambda : self.performAction(request))
- def redirect(url):
- if isinstance(url, tuple):
- url, alert_msg = url
- if alert_msg:
- url += "?alert_msg="+urllib.quote(alert_msg, safe='')
- request.redirect(url)
- request.write("see <a href='%s'>%s</a>" % (url,url))
- try:
- request.finish()
- except RuntimeError:
- # this occurs when the client has already disconnected; ignore
- # it (see #2027)
- log.msg("http client disconnected before results were sent")
- d.addCallback(redirect)
-
- def fail(f):
- request.processingFailed(f)
- return None # processingFailed will log this for us
- d.addErrback(fail)
- return server.NOT_DONE_YET
-
-class HtmlResource(resource.Resource, ContextMixin):
- # this is a cheap sort of template thingy
- contentType = "text/html; charset=utf-8"
- pageTitle = "Buildbot"
- addSlash = False # adapted from Nevow
-
- def getChild(self, path, request):
- if self.addSlash and path == "" and len(request.postpath) == 0:
- return self
- return resource.Resource.getChild(self, path, request)
-
-
- def content(self, req, context):
- """
- Generate content using the standard layout and the result of the C{body}
- method.
-
- This is suitable for the case where a resource just wants to generate
- the body of a page. It depends on another method, C{body}, being
- defined to accept the request object and return a C{str}. C{render}
- will call this method and to generate the response body.
- """
- body = self.body(req)
- context['content'] = body
- template = req.site.buildbot_service.templates.get_template(
- "empty.html")
- return template.render(**context)
-
-
- def render(self, request):
- # tell the WebStatus about the HTTPChannel that got opened, so they
- # can close it if we get reconfigured and the WebStatus goes away.
- # They keep a weakref to this, since chances are good that it will be
- # closed by the browser or by us before we get reconfigured. See
- # ticket #102 for details.
- if hasattr(request, "channel"):
- # web.distrib.Request has no .channel
- request.site.buildbot_service.registerChannel(request.channel)
-
- # Our pages no longer require that their URL end in a slash. Instead,
- # they all use request.childLink() or some equivalent which takes the
- # last path component into account. This clause is left here for
- # historical and educational purposes.
- if False and self.addSlash and request.prepath[-1] != '':
- # this is intended to behave like request.URLPath().child('')
- # but we need a relative URL, since we might be living behind a
- # reverse proxy
- #
- # note that the Location: header (as used in redirects) are
- # required to have absolute URIs, and my attempt to handle
- # reverse-proxies gracefully violates rfc2616. This frequently
- # works, but single-component paths sometimes break. The best
- # strategy is to avoid these redirects whenever possible by using
- # HREFs with trailing slashes, and only use the redirects for
- # manually entered URLs.
- url = request.prePathURL()
- scheme, netloc, path, query, fragment = urlparse.urlsplit(url)
- new_url = request.prepath[-1] + "/"
- if query:
- new_url += "?" + query
- request.redirect(new_url)
- return ''
-
- ctx = self.getContext(request)
-
- d = defer.maybeDeferred(lambda : self.content(request, ctx))
- def handle(data):
- request.setHeader("X-Clacks-Overhead", 'GNU N%C3%B3ir%C3%ADn Plunkett')
- if isinstance(data, unicode):
- data = data.encode("utf-8")
- request.setHeader("content-type", self.contentType)
- if request.method == "HEAD":
- request.setHeader("content-length", len(data))
- return ''
- return data
- d.addCallback(handle)
- def ok(data):
- request.write(data)
- try:
- request.finish()
- except RuntimeError:
- # this occurs when the client has already disconnected; ignore
- # it (see #2027)
- log.msg("http client disconnected before results were sent")
- def fail(f):
- request.processingFailed(f)
- return None # processingFailed will log this for us
- d.addCallbacks(ok, fail)
- return server.NOT_DONE_YET
-
-class StaticHTML(HtmlResource):
- def __init__(self, body, pageTitle):
- HtmlResource.__init__(self)
- self.bodyHTML = body
- self.pageTitle = pageTitle
- def content(self, request, cxt):
- cxt['content'] = self.bodyHTML
- cxt['pageTitle'] = self.pageTitle
- template = request.site.buildbot_service.templates.get_template("empty.html")
- return template.render(**cxt)
-
-class DirectoryLister(static.DirectoryLister, ContextMixin):
- """This variant of the static.DirectoryLister uses a template
- for rendering."""
-
- pageTitle = 'BuildBot'
-
- def render(self, request):
- cxt = self.getContext(request)
-
- if self.dirs is None:
- directory = os.listdir(self.path)
- directory.sort()
- else:
- directory = self.dirs
-
- dirs, files = self._getFilesAndDirectories(directory)
-
- cxt['path'] = cgi.escape(urllib.unquote(request.uri))
- cxt['directories'] = dirs
- cxt['files'] = files
- template = request.site.buildbot_service.templates.get_template("directory.html")
- data = template.render(**cxt)
- if isinstance(data, unicode):
- data = data.encode("utf-8")
- return data
-
-class StaticFile(static.File):
- """This class adds support for templated directory
- views."""
-
- def directoryListing(self):
- return DirectoryLister(self.path,
- self.listNames(),
- self.contentTypes,
- self.contentEncodings,
- self.defaultType)
-
-
-MINUTE = 60
-HOUR = 60*MINUTE
-DAY = 24*HOUR
-WEEK = 7*DAY
-MONTH = 30*DAY
-
-def plural(word, words, num):
- if int(num) == 1:
- return "%d %s" % (num, word)
- else:
- return "%d %s" % (num, words)
-
-def abbreviate_age(age):
- if age <= 90:
- return "%s ago" % plural("second", "seconds", age)
- if age < 90*MINUTE:
- return "about %s ago" % plural("minute", "minutes", age / MINUTE)
- if age < DAY:
- return "about %s ago" % plural("hour", "hours", age / HOUR)
- if age < 2*WEEK:
- return "about %s ago" % plural("day", "days", age / DAY)
- if age < 2*MONTH:
- return "about %s ago" % plural("week", "weeks", age / WEEK)
- return "a long time ago"
-
-
-class BuildLineMixin:
- LINE_TIME_FORMAT = "%b %d %H:%M"
-
- def get_line_values(self, req, build, include_builder=True):
- '''
- Collect the data needed for each line display
- '''
- builder_name = build.getBuilder().getName()
- results = build.getResults()
- text = build.getText()
- all_got_revision = build.getAllGotRevisions()
- css_class = css_classes.get(results, "")
- ss_list = build.getSourceStamps()
- if ss_list:
- repo = ss_list[0].repository
- if all_got_revision:
- if len(ss_list) == 1:
- rev = all_got_revision.get(ss_list[0].codebase, "??")
- else:
- rev = "multiple rev."
- else:
- rev = "??"
- else:
- repo = 'unknown, no information in build'
- rev = 'unknown'
-
- if type(text) == list:
- text = " ".join(text)
-
- values = {'class': css_class,
- 'builder_name': builder_name,
- 'buildnum': build.getNumber(),
- 'results': css_class,
- 'text': " ".join(build.getText()),
- 'buildurl': path_to_build(req, build),
- 'builderurl': path_to_builder(req, build.getBuilder()),
- 'rev': rev,
- 'rev_repo' : repo,
- 'time': time.strftime(self.LINE_TIME_FORMAT,
- time.localtime(build.getTimes()[0])),
- 'text': text,
- 'include_builder': include_builder
- }
- return values
-
-def map_branches(branches):
- # when the query args say "trunk", present that to things like
- # IBuilderStatus.generateFinishedBuilds as None, since that's the
- # convention in use. But also include 'trunk', because some VC systems
- # refer to it that way. In the long run we should clean this up better,
- # maybe with Branch objects or something.
- if "trunk" in branches:
- return branches + [None]
- return branches
-
-
-# jinja utilities
-
-def createJinjaEnv(revlink=None, changecommentlink=None,
- repositories=None, projects=None, jinja_loaders=None):
- ''' Create a jinja environment changecommentlink is used to
- render HTML in the WebStatus and for mail changes
-
- @type changecommentlink: C{None}, tuple (2 or 3 strings), dict (string -> 2- or 3-tuple) or callable
- @param changecommentlink: see changelinkfilter()
-
- @type revlink: C{None}, format-string, dict (repository -> format string) or callable
- @param revlink: see revlinkfilter()
-
- @type repositories: C{None} or dict (string -> url)
- @param repositories: an (optinal) mapping from repository identifiers
- (as given by Change sources) to URLs. Is used to create a link
- on every place where a repository is listed in the WebStatus.
-
- @type projects: C{None} or dict (string -> url)
- @param projects: similar to repositories, but for projects.
- '''
-
- # See http://buildbot.net/trac/ticket/658
- assert not hasattr(sys, "frozen"), 'Frozen config not supported with jinja (yet)'
-
- all_loaders = [jinja2.FileSystemLoader(os.path.join(os.getcwd(), 'templates'))]
- if jinja_loaders:
- all_loaders.extend(jinja_loaders)
- all_loaders.append(jinja2.PackageLoader('buildbot.status.web', 'templates'))
- loader = jinja2.ChoiceLoader(all_loaders)
-
- env = jinja2.Environment(loader=loader,
- extensions=['jinja2.ext.i18n'],
- trim_blocks=True,
- undefined=AlmostStrictUndefined)
-
- env.install_null_translations() # needed until we have a proper i18n backend
-
- env.tests['mapping'] = lambda obj : isinstance(obj, dict)
-
- env.filters.update(dict(
- urlencode = urllib.quote,
- email = emailfilter,
- user = userfilter,
- shortrev = shortrevfilter(revlink, env),
- revlink = revlinkfilter(revlink, env),
- changecomment = changelinkfilter(changecommentlink),
- repolink = dictlinkfilter(repositories),
- projectlink = dictlinkfilter(projects)
- ))
-
- return env
-
-def emailfilter(value):
- ''' Escape & obfuscate e-mail addresses
-
- replacing @ with <span style="display:none> reportedly works well against web-spiders
- and the next level is to use rot-13 (or something) and decode in javascript '''
-
- user = jinja2.escape(value)
- obfuscator = jinja2.Markup('<span style="display:none">ohnoyoudont</span>@')
- output = user.replace('@', obfuscator)
- return output
-
-
-def userfilter(value):
- ''' Hide e-mail address from user name when viewing changes
-
- We still include the (obfuscated) e-mail so that we can show
- it on mouse-over or similar etc
- '''
- r = re.compile('(.*) +<(.*)>')
- m = r.search(value)
- if m:
- user = jinja2.escape(m.group(1))
- email = emailfilter(m.group(2))
- return jinja2.Markup('<div class="user">%s<div class="email">%s</div></div>' % (user, email))
- else:
- return emailfilter(value) # filter for emails here for safety
-
-def _revlinkcfg(replace, templates):
- '''Helper function that returns suitable macros and functions
- for building revision links depending on replacement mechanism
-'''
-
- assert not replace or callable(replace) or isinstance(replace, dict) or \
- isinstance(replace, str) or isinstance(replace, unicode)
-
- if not replace:
- return lambda rev, repo: None
- else:
- if callable(replace):
- return lambda rev, repo: replace(rev, repo)
- elif isinstance(replace, dict): # TODO: test for [] instead
- def filter(rev, repo):
- url = replace.get(repo)
- if url:
- return url % urllib.quote(rev)
- else:
- return None
-
- return filter
- else:
- return lambda rev, repo: replace % urllib.quote(rev)
-
- assert False, '_replace has a bad type, but we should never get here'
-
-
-def _revlinkmacros(replace, templates):
- '''return macros for use with revision links, depending
- on whether revlinks are configured or not'''
-
- macros = templates.get_template("revmacros.html").module
-
- if not replace:
- id = macros.id
- short = macros.shorten
- else:
- id = macros.id_replace
- short = macros.shorten_replace
-
- return (id, short)
-
-
-def shortrevfilter(replace, templates):
- ''' Returns a function which shortens the revisison string
- to 12-chars (chosen as this is the Mercurial short-id length)
- and add link if replacement string is set.
-
- (The full id is still visible in HTML, for mouse-over events etc.)
-
- @param replace: see revlinkfilter()
- @param templates: a jinja2 environment
- '''
-
- url_f = _revlinkcfg(replace, templates)
-
- def filter(rev, repo):
- if not rev:
- return u''
-
- id_html, short_html = _revlinkmacros(replace, templates)
- rev = unicode(rev)
- url = url_f(rev, repo)
- rev = jinja2.escape(rev)
- shortrev = rev[:12] # TODO: customize this depending on vc type
-
- if shortrev == rev:
- if url:
- return id_html(rev=rev, url=url)
- else:
- return rev
- else:
- if url:
- return short_html(short=shortrev, rev=rev, url=url)
- else:
- return shortrev + '...'
-
- return filter
-
-
-def revlinkfilter(replace, templates):
- ''' Returns a function which adds an url link to a
- revision identifiers.
-
- Takes same params as shortrevfilter()
-
- @param replace: either a python format string with an %s,
- or a dict mapping repositories to format strings,
- or a callable taking (revision, repository) arguments
- and return an URL (or None, if no URL is available),
- or None, in which case revisions do not get decorated
- with links
-
- @param templates: a jinja2 environment
- '''
-
- url_f = _revlinkcfg(replace, templates)
-
- def filter(rev, repo):
- if not rev:
- return u''
-
- rev = unicode(rev)
- url = url_f(rev, repo)
- if url:
- id_html, _ = _revlinkmacros(replace, templates)
- return id_html(rev=rev, url=url)
- else:
- return jinja2.escape(rev)
-
- return filter
-
-
-def changelinkfilter(changelink):
- ''' Returns function that does regex search/replace in
- comments to add links to bug ids and similar.
-
- @param changelink:
- Either C{None}
- or: a tuple (2 or 3 elements)
- 1. a regex to match what we look for
- 2. an url with regex refs (\g<0>, \1, \2, etc) that becomes the 'href' attribute
- 3. (optional) an title string with regex ref regex
- or: a dict mapping projects to above tuples
- (no links will be added if the project isn't found)
- or: a callable taking (changehtml, project) args
- (where the changetext is HTML escaped in the
- form of a jinja2.Markup instance) and
- returning another jinja2.Markup instance with
- the same change text plus any HTML tags added to it.
- '''
-
- assert not changelink or isinstance(changelink, dict) or \
- isinstance(changelink, tuple) or callable(changelink)
-
- def replace_from_tuple(t):
- search, url_replace = t[:2]
- if len(t) == 3:
- title_replace = t[2]
- else:
- title_replace = ''
-
- search_re = re.compile(search)
-
- def replacement_unmatched(text):
- return jinja2.escape(text)
- def replacement_matched(mo):
- # expand things *after* application of the regular expressions
- url = jinja2.escape(mo.expand(url_replace))
- title = jinja2.escape(mo.expand(title_replace))
- body = jinja2.escape(mo.group())
- if title:
- return '<a href="%s" title="%s">%s</a>' % (url, title, body)
- else:
- return '<a href="%s">%s</a>' % (url, body)
-
- def filter(text, project):
- # now, we need to split the string into matched and unmatched portions,
- # quoting the unmatched portions directly and quoting the components of
- # the 'a' element for the matched portions. We can't use re.split here,
- # because the user-supplied patterns may have multiple groups.
- html = []
- last_idx = 0
- for mo in search_re.finditer(text):
- html.append(replacement_unmatched(text[last_idx:mo.start()]))
- html.append(replacement_matched(mo))
- last_idx = mo.end()
- html.append(replacement_unmatched(text[last_idx:]))
- return jinja2.Markup(''.join(html))
-
- return filter
-
- if not changelink:
- return lambda text, project: jinja2.escape(text)
-
- elif isinstance(changelink, dict):
- def dict_filter(text, project):
- # TODO: Optimize and cache return value from replace_from_tuple so
- # we only compile regex once per project, not per view
-
- t = changelink.get(project)
- if t:
- return replace_from_tuple(t)(text, project)
- else:
- return cgi.escape(text)
-
- return dict_filter
-
- elif isinstance(changelink, tuple):
- return replace_from_tuple(changelink)
-
- elif callable(changelink):
- def callable_filter(text, project):
- text = jinja2.escape(text)
- return changelink(text, project)
-
- return callable_filter
-
- assert False, 'changelink has unsupported type, but that is checked before'
-
-
-def dictlinkfilter(links):
- '''A filter that encloses the given value in a link tag
- given that the value exists in the dictionary'''
-
- assert not links or callable(links) or isinstance(links, dict)
-
- if not links:
- return jinja2.escape
-
- def filter(key):
- if callable(links):
- url = links(key)
- else:
- url = links.get(key)
-
- safe_key = jinja2.escape(key)
-
- if url:
- return jinja2.Markup(r'<a href="%s">%s</a>' % (url, safe_key))
- else:
- return safe_key
-
- return filter
-
-class AlmostStrictUndefined(jinja2.StrictUndefined):
- ''' An undefined that allows boolean testing but
- fails properly on every other use.
-
- Much better than the default Undefined, but not
- fully as strict as StrictUndefined '''
- def __nonzero__(self):
- return False
-
-_charsetRe = re.compile('charset=([^;]*)', re.I)
-def getRequestCharset(req):
- """Get the charset for an x-www-form-urlencoded request"""
- # per http://stackoverflow.com/questions/708915/detecting-the-character-encoding-of-an-http-post-request
- hdr = req.getHeader('Content-Type')
- if hdr:
- mo = _charsetRe.search(hdr)
- if mo:
- return mo.group(1).strip()
- return 'utf-8' # reasonable guess, works for ascii
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/baseweb.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/baseweb.py
deleted file mode 100644
index 9fe5e7fc..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/baseweb.py
+++ /dev/null
@@ -1,607 +0,0 @@
-# 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 os, weakref
-
-from zope.interface import implements
-from twisted.python import log
-from twisted.application import strports, service
-from twisted.internet import defer
-from twisted.web import server, distrib, static
-from twisted.spread import pb
-from twisted.web.util import Redirect
-from buildbot import config
-from buildbot.interfaces import IStatusReceiver
-from buildbot.status.web.base import StaticFile, createJinjaEnv
-from buildbot.status.web.feeds import Rss20StatusResource, \
- Atom10StatusResource
-from buildbot.status.web.waterfall import WaterfallStatusResource
-from buildbot.status.web.console import ConsoleStatusResource
-from buildbot.status.web.olpb import OneLinePerBuild
-from buildbot.status.web.grid import GridStatusResource
-from buildbot.status.web.grid import TransposedGridStatusResource
-from buildbot.status.web.changes import ChangesResource
-from buildbot.status.web.builder import BuildersResource
-from buildbot.status.web.buildstatus import BuildStatusStatusResource
-from buildbot.status.web.slaves import BuildSlavesResource
-from buildbot.status.web.status_json import JsonStatusResource
-from buildbot.status.web.about import AboutBuildbot
-from buildbot.status.web.authz import Authz
-from buildbot.status.web.auth import AuthFailResource,AuthzFailResource, LoginResource, LogoutResource
-from buildbot.status.web.root import RootPage
-from buildbot.status.web.users import UsersResource
-from buildbot.status.web.change_hook import ChangeHookResource
-from twisted.cred.portal import IRealm, Portal
-from twisted.cred import strcred
-from twisted.cred.checkers import ICredentialsChecker
-from twisted.cred.credentials import IUsernamePassword
-from twisted.web import resource, guard
-
-# this class contains the WebStatus class. Basic utilities are in base.py,
-# and specific pages are each in their own module.
-
-class WebStatus(service.MultiService):
- implements(IStatusReceiver)
- # TODO: IStatusReceiver is really about things which subscribe to hear
- # about buildbot events. We need a different interface (perhaps a parent
- # of IStatusReceiver) for status targets that don't subscribe, like the
- # WebStatus class. buildbot.master.BuildMaster.loadConfig:737 asserts
- # that everything in c['status'] provides IStatusReceiver, but really it
- # should check that they provide IStatusTarget instead.
-
- """
- The webserver provided by this class has the following resources:
-
- /waterfall : the big time-oriented 'waterfall' display, with links
- to individual changes, builders, builds, steps, and logs.
- A number of query-arguments can be added to influence
- the display.
- /rss : a rss feed summarizing all failed builds. The same
- query-arguments used by 'waterfall' can be added to
- influence the feed output.
- /atom : an atom feed summarizing all failed builds. The same
- query-arguments used by 'waterfall' can be added to
- influence the feed output.
- /grid : another summary display that shows a grid of builds, with
- sourcestamps on the x axis, and builders on the y. Query
- arguments similar to those for the waterfall can be added.
- /tgrid : similar to the grid display, but the commits are down the
- left side, and the build hosts are across the top.
- /builders/BUILDERNAME: a page summarizing the builder. This includes
- references to the Schedulers that feed it,
- any builds currently in the queue, which
- buildslaves are designated or attached, and a
- summary of the build process it uses.
- /builders/BUILDERNAME/builds/NUM: a page describing a single Build
- /builders/BUILDERNAME/builds/NUM/steps/STEPNAME: describes a single step
- /builders/BUILDERNAME/builds/NUM/steps/STEPNAME/logs/LOGNAME: a StatusLog
- /builders/_all/{force,stop}: force a build/stop building on all builders.
- /buildstatus?builder=...&number=...: an embedded iframe for the console
- /changes : summarize all ChangeSources
- /changes/CHANGENUM: a page describing a single Change
- /buildslaves : list all BuildSlaves
- /buildslaves/SLAVENAME : describe a single BuildSlave
- /one_line_per_build : summarize the last few builds, one line each
- /one_line_per_build/BUILDERNAME : same, but only for a single builder
- /about : describe this buildmaster (Buildbot and support library versions)
- /change_hook[/DIALECT] : accepts changes from external sources, optionally
- choosing the dialect that will be permitted
- (i.e. github format, etc..)
-
- and more! see the manual.
-
-
- All URLs for pages which are not defined here are used to look
- for files in PUBLIC_HTML, which defaults to BASEDIR/public_html.
- This means that /robots.txt or /favicon.ico can be placed in
- that directory
-
- This webserver uses the jinja2 template system to generate the web pages
- (see http://jinja.pocoo.org/2/) and by default loads pages from the
- buildbot.status.web.templates package. Any file here can be overridden by placing
- a corresponding file in the master's 'templates' directory.
-
- The main customization points are layout.html which loads style sheet
- (css) and provides header and footer content, and root.html, which
- generates the root page.
-
- All of the resources provided by this service use relative URLs to reach
- each other. The only absolute links are the c['titleURL'] links at the
- top and bottom of the page, and the buildbot home-page link at the
- bottom.
-
- Buildbot uses some generic classes to identify the type of object, and
- some more specific classes for the various kinds of those types. It does
- this by specifying both in the class attributes where applicable,
- separated by a space. It is important that in your CSS you declare the
- more generic class styles above the more specific ones. For example,
- first define a style for .Event, and below that for .SUCCESS
-
- The following CSS class names are used:
- - Activity, Event, BuildStep, LastBuild: general classes
- - waiting, interlocked, building, offline, idle: Activity states
- - start, running, success, failure, warnings, skipped, exception:
- LastBuild and BuildStep states
- - Change: box with change
- - Builder: box for builder name (at top)
- - Project
- - Time
-
- """
-
- # we are not a ComparableMixin, and therefore the webserver will be
- # rebuilt every time we reconfig. This is because WebStatus.putChild()
- # makes it too difficult to tell whether two instances are the same or
- # not (we'd have to do a recursive traversal of all children to discover
- # all the changes).
-
- def __init__(self, http_port=None, distrib_port=None, allowForce=None,
- public_html="public_html", site=None, numbuilds=20,
- num_events=200, num_events_max=None, auth=None,
- order_console_by_time=False, changecommentlink=None,
- revlink=None, projects=None, repositories=None,
- authz=None, logRotateLength=None, maxRotatedFiles=None,
- change_hook_dialects = {}, provide_feeds=None, jinja_loaders=None,
- change_hook_auth=None):
- """Run a web server that provides Buildbot status.
-
- @type http_port: int or L{twisted.application.strports} string
- @param http_port: a strports specification describing which port the
- buildbot should use for its web server, with the
- Waterfall display as the root page. For backwards
- compatibility this can also be an int. Use
- 'tcp:8000' to listen on that port, or
- 'tcp:12345:interface=127.0.0.1' if you only want
- local processes to connect to it (perhaps because
- you are using an HTTP reverse proxy to make the
- buildbot available to the outside world, and do not
- want to make the raw port visible).
-
- @type distrib_port: int or L{twisted.application.strports} string
- @param distrib_port: Use this if you want to publish the Waterfall
- page using web.distrib instead. The most common
- case is to provide a string that is an absolute
- pathname to the unix socket on which the
- publisher should listen
- (C{os.path.expanduser(~/.twistd-web-pb)} will
- match the default settings of a standard
- twisted.web 'personal web server'). Another
- possibility is to pass an integer, which means
- the publisher should listen on a TCP socket,
- allowing the web server to be on a different
- machine entirely. Both forms are provided for
- backwards compatibility; the preferred form is a
- strports specification like
- 'unix:/home/buildbot/.twistd-web-pb'. Providing
- a non-absolute pathname will probably confuse
- the strports parser.
-
- @param allowForce: deprecated; use authz instead
- @param auth: deprecated; use with authz
-
- @param authz: a buildbot.status.web.authz.Authz instance giving the authorization
- parameters for this view
-
- @param public_html: the path to the public_html directory for this display,
- either absolute or relative to the basedir. The default
- is 'public_html', which selects BASEDIR/public_html.
-
- @type site: None or L{twisted.web.server.Site}
- @param site: Use this if you want to define your own object instead of
- using the default.`
-
- @type numbuilds: int
- @param numbuilds: Default number of entries in lists at the /one_line_per_build
- and /builders/FOO URLs. This default can be overriden both programatically ---
- by passing the equally named argument to constructors of OneLinePerBuildOneBuilder
- and OneLinePerBuild --- and via the UI, by tacking ?numbuilds=xy onto the URL.
-
- @type num_events: int
- @param num_events: Default number of events to show in the waterfall.
-
- @type num_events_max: int
- @param num_events_max: The maximum number of events that are allowed to be
- shown in the waterfall. The default value of C{None} will disable this
- check
-
- @type auth: a L{status.web.auth.IAuth} or C{None}
- @param auth: an object that performs authentication to restrict access
- to the C{allowForce} features. Ignored if C{allowForce}
- is not C{True}. If C{auth} is C{None}, people can force or
- stop builds without auth.
-
- @type order_console_by_time: bool
- @param order_console_by_time: Whether to order changes (commits) in the console
- view according to the time they were created (for VCS like Git) or
- according to their integer revision numbers (for VCS like SVN).
-
- @type changecommentlink: callable, dict, tuple (2 or 3 strings) or C{None}
- @param changecommentlink: adds links to ticket/bug ids in change comments,
- see buildbot.status.web.base.changecommentlink for details
-
- @type revlink: callable, dict, string or C{None}
- @param revlink: decorations revision ids with links to a web-view,
- see buildbot.status.web.base.revlink for details
-
- @type projects: callable, dict or c{None}
- @param projects: maps project identifiers to URLs, so that any project listed
- is automatically decorated with a link to it's front page.
- see buildbot.status.web.base.dictlink for details
-
- @type repositories: callable, dict or c{None}
- @param repositories: maps repository identifiers to URLs, so that any project listed
- is automatically decorated with a link to it's web view.
- see buildbot.status.web.base.dictlink for details
-
- @type logRotateLength: None or int
- @param logRotateLength: file size at which the http.log is rotated/reset.
- If not set, the value set in the buildbot.tac will be used,
- falling back to the BuildMaster's default value (1 Mb).
-
- @type maxRotatedFiles: None or int
- @param maxRotatedFiles: number of old http.log files to keep during log rotation.
- If not set, the value set in the buildbot.tac will be used,
- falling back to the BuildMaster's default value (10 files).
-
- @type change_hook_dialects: None or dict
- @param change_hook_dialects: If empty, disables change_hook support, otherwise
- whitelists valid dialects. In the format of
- {"dialect1": "Option1", "dialect2", None}
- Where the values are options that will be passed
- to the dialect
-
- To enable the DEFAULT handler, use a key of DEFAULT
-
-
-
-
- @type provide_feeds: None or list
- @param provide_feeds: If empty, provides atom, json, and rss feeds.
- Otherwise, a dictionary of strings of
- the type of feeds provided. Current
- possibilities are "atom", "json", and "rss"
-
- @type jinja_loaders: None or list
- @param jinja_loaders: If not empty, a list of additional Jinja2 loader
- objects to search for templates.
- """
-
- service.MultiService.__init__(self)
- if type(http_port) is int:
- http_port = "tcp:%d" % http_port
- self.http_port = http_port
- if distrib_port is not None:
- if type(distrib_port) is int:
- distrib_port = "tcp:%d" % distrib_port
- if distrib_port[0] in "/~.": # pathnames
- distrib_port = "unix:%s" % distrib_port
- self.distrib_port = distrib_port
- self.num_events = num_events
- if num_events_max:
- if num_events_max < num_events:
- config.error(
- "num_events_max must be greater than num_events")
- self.num_events_max = num_events_max
- self.public_html = public_html
-
- # make up an authz if allowForce was given
- if authz:
- if allowForce is not None:
- config.error(
- "cannot use both allowForce and authz parameters")
- if auth:
- config.error(
- "cannot use both auth and authz parameters (pass " +
- "auth as an Authz parameter)")
- else:
- # invent an authz
- if allowForce and auth:
- authz = Authz(auth=auth, default_action="auth")
- elif allowForce:
- authz = Authz(default_action=True)
- else:
- if auth:
- log.msg("Warning: Ignoring authentication. Search for 'authorization'"
- " in the manual")
- authz = Authz() # no authorization for anything
-
- self.authz = authz
-
- # check for correctness of HTTP auth parameters
- if change_hook_auth is not None:
- self.change_hook_auth = []
- for checker in change_hook_auth:
- if isinstance(checker, str):
- try:
- checker = strcred.makeChecker(checker)
- except Exception, error:
- config.error("Invalid change_hook checker description: %s" % (error,))
- continue
- elif not ICredentialsChecker.providedBy(checker):
- config.error("change_hook checker doesn't provide ICredentialChecker: %r" % (checker,))
- continue
-
- if IUsernamePassword not in checker.credentialInterfaces:
- config.error("change_hook checker doesn't support IUsernamePassword: %r" % (checker,))
- continue
-
- self.change_hook_auth.append(checker)
- else:
- self.change_hook_auth = None
-
- self.orderConsoleByTime = order_console_by_time
-
- # If we were given a site object, go ahead and use it. (if not, we add one later)
- self.site = site
-
- # keep track of our child services
- self.http_svc = None
- self.distrib_svc = None
-
- # store the log settings until we create the site object
- self.logRotateLength = logRotateLength
- self.maxRotatedFiles = maxRotatedFiles
-
- # create the web site page structure
- self.childrenToBeAdded = {}
- self.setupUsualPages(numbuilds=numbuilds, num_events=num_events,
- num_events_max=num_events_max)
-
- self.revlink = revlink
- self.changecommentlink = changecommentlink
- self.repositories = repositories
- self.projects = projects
-
- # keep track of cached connections so we can break them when we shut
- # down. See ticket #102 for more details.
- self.channels = weakref.WeakKeyDictionary()
-
- # do we want to allow change_hook
- self.change_hook_dialects = {}
- if change_hook_dialects:
- self.change_hook_dialects = change_hook_dialects
- resource_obj = ChangeHookResource(dialects=self.change_hook_dialects)
- if self.change_hook_auth is not None:
- resource_obj = self.setupProtectedResource(
- resource_obj, self.change_hook_auth)
- self.putChild("change_hook", resource_obj)
-
- # Set default feeds
- if provide_feeds is None:
- self.provide_feeds = ["atom", "json", "rss"]
- else:
- self.provide_feeds = provide_feeds
-
- self.jinja_loaders = jinja_loaders
-
- def setupProtectedResource(self, resource_obj, checkers):
- class SimpleRealm(object):
- """
- A realm which gives out L{ChangeHookResource} instances for authenticated
- users.
- """
- implements(IRealm)
-
- def requestAvatar(self, avatarId, mind, *interfaces):
- if resource.IResource in interfaces:
- return (resource.IResource, resource_obj, lambda: None)
- raise NotImplementedError()
-
- portal = Portal(SimpleRealm(), checkers)
- credentialFactory = guard.BasicCredentialFactory('Protected area')
- wrapper = guard.HTTPAuthSessionWrapper(portal, [credentialFactory])
- return wrapper
-
- def setupUsualPages(self, numbuilds, num_events, num_events_max):
- #self.putChild("", IndexOrWaterfallRedirection())
- self.putChild("waterfall", WaterfallStatusResource(num_events=num_events,
- num_events_max=num_events_max))
- self.putChild("grid", GridStatusResource())
- self.putChild("console", ConsoleStatusResource(
- orderByTime=self.orderConsoleByTime))
- self.putChild("tgrid", TransposedGridStatusResource())
- self.putChild("builders", BuildersResource(numbuilds=numbuilds)) # has builds/steps/logs
- self.putChild("one_box_per_builder", Redirect("builders"))
- self.putChild("changes", ChangesResource())
- self.putChild("buildslaves", BuildSlavesResource())
- self.putChild("buildstatus", BuildStatusStatusResource())
- self.putChild("one_line_per_build",
- OneLinePerBuild(numbuilds=numbuilds))
- self.putChild("about", AboutBuildbot())
- self.putChild("authfail", AuthFailResource())
- self.putChild("authzfail", AuthzFailResource())
- self.putChild("users", UsersResource())
- self.putChild("login", LoginResource())
- self.putChild("logout", LogoutResource())
-
- def __repr__(self):
- if self.http_port is None:
- return "<WebStatus on path %s at %s>" % (self.distrib_port,
- hex(id(self)))
- if self.distrib_port is None:
- return "<WebStatus on port %s at %s>" % (self.http_port,
- hex(id(self)))
- return ("<WebStatus on port %s and path %s at %s>" %
- (self.http_port, self.distrib_port, hex(id(self))))
-
- def setServiceParent(self, parent):
- # this class keeps a *separate* link to the buildmaster, rather than
- # just using self.parent, so that when we are "disowned" (and thus
- # parent=None), any remaining HTTP clients of this WebStatus will still
- # be able to get reasonable results.
- self.master = parent.master
-
- # set master in IAuth instance
- if self.authz.auth:
- self.authz.auth.master = self.master
-
- def either(a,b): # a if a else b for py2.4
- if a:
- return a
- else:
- return b
-
- rotateLength = either(self.logRotateLength, self.master.log_rotation.rotateLength)
- maxRotatedFiles = either(self.maxRotatedFiles, self.master.log_rotation.maxRotatedFiles)
-
- # Set up the jinja templating engine.
- if self.revlink:
- revlink = self.revlink
- else:
- revlink = self.master.config.revlink
- self.templates = createJinjaEnv(revlink, self.changecommentlink,
- self.repositories, self.projects, self.jinja_loaders)
-
- if not self.site:
-
- class RotateLogSite(server.Site):
- def _openLogFile(self, path):
- try:
- from twisted.python.logfile import LogFile
- log.msg("Setting up http.log rotating %s files of %s bytes each" %
- (maxRotatedFiles, rotateLength))
- if hasattr(LogFile, "fromFullPath"): # not present in Twisted-2.5.0
- return LogFile.fromFullPath(path, rotateLength=rotateLength, maxRotatedFiles=maxRotatedFiles)
- else:
- log.msg("WebStatus: rotated http logs are not supported on this version of Twisted")
- except ImportError, e:
- log.msg("WebStatus: Unable to set up rotating http.log: %s" % e)
-
- # if all else fails, just call the parent method
- return server.Site._openLogFile(self, path)
-
- # this will be replaced once we've been attached to a parent (and
- # thus have a basedir and can reference BASEDIR)
- root = static.Data("placeholder", "text/plain")
- httplog = os.path.abspath(os.path.join(self.master.basedir, "http.log"))
- self.site = RotateLogSite(root, logPath=httplog)
-
- # the following items are accessed by HtmlResource when it renders
- # each page.
- self.site.buildbot_service = self
-
- if self.http_port is not None:
- self.http_svc = s = strports.service(self.http_port, self.site)
- s.setServiceParent(self)
- if self.distrib_port is not None:
- f = pb.PBServerFactory(distrib.ResourcePublisher(self.site))
- self.distrib_svc = s = strports.service(self.distrib_port, f)
- s.setServiceParent(self)
-
- self.setupSite()
-
- service.MultiService.setServiceParent(self, parent)
-
- def setupSite(self):
- # this is responsible for creating the root resource. It isn't done
- # at __init__ time because we need to reference the parent's basedir.
- htmldir = os.path.abspath(os.path.join(self.master.basedir, self.public_html))
- if os.path.isdir(htmldir):
- log.msg("WebStatus using (%s)" % htmldir)
- else:
- log.msg("WebStatus: warning: %s is missing. Do you need to run"
- " 'buildbot upgrade-master' on this buildmaster?" % htmldir)
- # all static pages will get a 404 until upgrade-master is used to
- # populate this directory. Create the directory, though, since
- # otherwise we get internal server errors instead of 404s.
- os.mkdir(htmldir)
-
- root = StaticFile(htmldir)
- root_page = RootPage()
- root.putChild("", root_page)
- root.putChild("shutdown", root_page)
- root.putChild("cancel_shutdown", root_page)
-
- for name, child_resource in self.childrenToBeAdded.iteritems():
- root.putChild(name, child_resource)
-
- status = self.getStatus()
- if "rss" in self.provide_feeds:
- root.putChild("rss", Rss20StatusResource(status))
- if "atom" in self.provide_feeds:
- root.putChild("atom", Atom10StatusResource(status))
- if "json" in self.provide_feeds:
- root.putChild("json", JsonStatusResource(status))
-
- self.site.resource = root
-
- def putChild(self, name, child_resource):
- """This behaves a lot like root.putChild() . """
- self.childrenToBeAdded[name] = child_resource
-
- def registerChannel(self, channel):
- self.channels[channel] = 1 # weakrefs
-
- @defer.inlineCallbacks
- def stopService(self):
- for channel in self.channels:
- try:
- channel.transport.loseConnection()
- except:
- log.msg("WebStatus.stopService: error while disconnecting"
- " leftover clients")
- log.err()
- yield service.MultiService.stopService(self)
-
- # having shut them down, now remove our child services so they don't
- # start up again if we're re-started
- if self.http_svc:
- yield self.http_svc.disownServiceParent()
- self.http_svc = None
- if self.distrib_svc:
- yield self.distrib_svc.disownServiceParent()
- self.distrib_svc = None
-
- def getStatus(self):
- return self.master.getStatus()
-
- def getChangeSvc(self):
- return self.master.change_svc
-
- def getPortnum(self):
- # this is for the benefit of unit tests
- s = list(self)[0]
- return s._port.getHost().port
-
- # What happened to getControl?!
- #
- # instead of passing control objects all over the place in the web
- # code, at the few places where a control instance is required we
- # find the requisite object manually, starting at the buildmaster.
- # This is in preparation for removal of the IControl hierarchy
- # entirely.
-
- def checkConfig(self, otherStatusReceivers):
- duplicate_webstatus=0
- for osr in otherStatusReceivers:
- if isinstance(osr,WebStatus):
- if osr is self:
- continue
- # compare against myself and complain if the settings conflict
- if self.http_port == osr.http_port:
- if duplicate_webstatus == 0:
- duplicate_webstatus = 2
- else:
- duplicate_webstatus += 1
-
- if duplicate_webstatus:
- config.error(
- "%d Webstatus objects have same port: %s"
- % (duplicate_webstatus, self.http_port),
- )
-
-# resources can get access to the IStatus by calling
-# request.site.buildbot_service.getStatus()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/build.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/build.py
deleted file mode 100644
index 1cf7f92f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/build.py
+++ /dev/null
@@ -1,332 +0,0 @@
-# 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
-
-
-from twisted.web import html
-from twisted.internet import defer, reactor
-from twisted.web.util import Redirect, DeferredResource
-
-import urllib, time
-from twisted.python import log
-from buildbot.status.web.base import HtmlResource, \
- css_classes, path_to_build, path_to_builder, path_to_slave, \
- getAndCheckProperties, ActionResource, path_to_authzfail, \
- getRequestCharset
-from buildbot.schedulers.forcesched import ForceScheduler, TextParameter
-from buildbot.status.web.step import StepsResource
-from buildbot.status.web.tests import TestsResource
-from buildbot import util, interfaces
-
-class ForceBuildActionResource(ActionResource):
-
- def __init__(self, build_status, builder):
- self.build_status = build_status
- self.builder = builder
- self.action = "forceBuild"
-
- @defer.inlineCallbacks
- def performAction(self, req):
- url = None
- authz = self.getAuthz(req)
- res = yield authz.actionAllowed(self.action, req, self.builder)
-
- if not res:
- url = path_to_authzfail(req)
- else:
- # get a control object
- c = interfaces.IControl(self.getBuildmaster(req))
- bc = c.getBuilder(self.builder.getName())
-
- b = self.build_status
- builder_name = self.builder.getName()
- log.msg("web rebuild of build %s:%s" % (builder_name, b.getNumber()))
- name =authz.getUsernameFull(req)
- comments = req.args.get("comments", ["<no reason specified>"])[0]
- comments.decode(getRequestCharset(req))
- reason = ("The web-page 'rebuild' button was pressed by "
- "'%s': %s\n" % (name, comments))
- msg = ""
- extraProperties = getAndCheckProperties(req)
- if not bc or not b.isFinished() or extraProperties is None:
- msg = "could not rebuild: "
- if b.isFinished():
- msg += "build still not finished "
- if bc:
- msg += "could not get builder control"
- else:
- tup = yield bc.rebuildBuild(b, reason, extraProperties)
- # rebuildBuild returns None on error (?!)
- if not tup:
- msg = "rebuilding a build failed "+ str(tup)
- # we're at
- # http://localhost:8080/builders/NAME/builds/5/rebuild?[args]
- # Where should we send them?
- #
- # Ideally it would be to the per-build page that they just started,
- # but we don't know the build number for it yet (besides, it might
- # have to wait for a current build to finish). The next-most
- # preferred place is somewhere that the user can see tangible
- # evidence of their build starting (or to see the reason that it
- # didn't start). This should be the Builder page.
-
- url = path_to_builder(req, self.builder), msg
- defer.returnValue(url)
-
-
-class StopBuildActionResource(ActionResource):
-
- def __init__(self, build_status):
- self.build_status = build_status
- self.action = "stopBuild"
-
- @defer.inlineCallbacks
- def performAction(self, req):
- authz = self.getAuthz(req)
- res = yield authz.actionAllowed(self.action, req, self.build_status)
-
- if not res:
- defer.returnValue(path_to_authzfail(req))
- return
-
- b = self.build_status
- log.msg("web stopBuild of build %s:%s" % \
- (b.getBuilder().getName(), b.getNumber()))
- name = authz.getUsernameFull(req)
- comments = req.args.get("comments", ["<no reason specified>"])[0]
- comments.decode(getRequestCharset(req))
- # html-quote both the username and comments, just to be safe
- reason = ("The web-page 'stop build' button was pressed by "
- "'%s': %s\n" % (html.escape(name), html.escape(comments)))
-
- c = interfaces.IControl(self.getBuildmaster(req))
- bldrc = c.getBuilder(self.build_status.getBuilder().getName())
- if bldrc:
- bldc = bldrc.getBuild(self.build_status.getNumber())
- if bldc:
- bldc.stopBuild(reason)
-
- defer.returnValue(path_to_builder(req, self.build_status.getBuilder()))
-
-# /builders/$builder/builds/$buildnum
-class StatusResourceBuild(HtmlResource):
- addSlash = True
-
- def __init__(self, build_status):
- HtmlResource.__init__(self)
- self.build_status = build_status
-
- def getPageTitle(self, request):
- return ("Buildbot: %s Build #%d" %
- (self.build_status.getBuilder().getName(),
- self.build_status.getNumber()))
-
- def content(self, req, cxt):
- b = self.build_status
- status = self.getStatus(req)
- req.setHeader('Cache-Control', 'no-cache')
-
- cxt['b'] = b
- cxt['path_to_builder'] = path_to_builder(req, b.getBuilder())
-
- if not b.isFinished():
- step = b.getCurrentStep()
- if not step:
- cxt['current_step'] = "[waiting for Lock]"
- else:
- if step.isWaitingForLocks():
- cxt['current_step'] = "%s [waiting for Lock]" % step.getName()
- else:
- cxt['current_step'] = step.getName()
- when = b.getETA()
- if when is not None:
- cxt['when'] = util.formatInterval(when)
- cxt['when_time'] = time.strftime("%H:%M:%S",
- time.localtime(time.time() + when))
-
- else:
- cxt['result_css'] = css_classes[b.getResults()]
- if b.getTestResults():
- cxt['tests_link'] = req.childLink("tests")
-
- ssList = b.getSourceStamps()
- sourcestamps = cxt['sourcestamps'] = ssList
-
- all_got_revisions = b.getAllGotRevisions()
- cxt['got_revisions'] = all_got_revisions
-
- try:
- cxt['slave_url'] = path_to_slave(req, status.getSlave(b.getSlavename()))
- except KeyError:
- pass
-
- cxt['steps'] = []
-
- for s in b.getSteps():
- step = {'name': s.getName() }
-
- if s.isFinished():
- if s.isHidden():
- continue
-
- step['css_class'] = css_classes[s.getResults()[0]]
- (start, end) = s.getTimes()
- step['time_to_run'] = util.formatInterval(end - start)
- elif s.isStarted():
- if s.isWaitingForLocks():
- step['css_class'] = "waiting"
- step['time_to_run'] = "waiting for locks"
- else:
- start = s.getTimes()[0]
- step['css_class'] = "running"
- step['time_to_run'] = "running %s" % (util.formatInterval(util.now() - start))
- else:
- step['css_class'] = "not_started"
- step['time_to_run'] = ""
-
- cxt['steps'].append(step)
-
- step['link'] = req.childLink("steps/%s" %
- urllib.quote(s.getName(), safe=''))
- step['text'] = " ".join(s.getText())
- step['urls'] = map(lambda x:dict(url=x[1],logname=x[0]), s.getURLs().items())
-
- step['logs']= []
- for l in s.getLogs():
- logname = l.getName()
- step['logs'].append({ 'link': req.childLink("steps/%s/logs/%s" %
- (urllib.quote(s.getName(), safe=''),
- urllib.quote(logname, safe=''))),
- 'name': logname })
-
- scheduler = b.getProperty("scheduler", None)
- parameters = {}
- master = self.getBuildmaster(req)
- for sch in master.allSchedulers():
- if isinstance(sch, ForceScheduler) and scheduler == sch.name:
- for p in sch.all_fields:
- parameters[p.name] = p
-
- ps = cxt['properties'] = []
- for name, value, source in b.getProperties().asList():
- if not isinstance(value, dict):
- cxt_value = unicode(value)
- else:
- cxt_value = value
- p = { 'name': name, 'value': cxt_value, 'source': source}
- if len(cxt_value) > 500:
- p['short_value'] = cxt_value[:500]
- if name in parameters:
- param = parameters[name]
- if isinstance(param, TextParameter):
- p['text'] = param.value_to_text(value)
- p['cols'] = param.cols
- p['rows'] = param.rows
- p['label'] = param.label
- ps.append(p)
-
-
- cxt['responsible_users'] = list(b.getResponsibleUsers())
-
- (start, end) = b.getTimes()
- cxt['start'] = time.ctime(start)
- if end:
- cxt['end'] = time.ctime(end)
- cxt['elapsed'] = util.formatInterval(end - start)
- else:
- now = util.now()
- cxt['elapsed'] = util.formatInterval(now - start)
-
- exactly = True
- has_changes = False
- for ss in sourcestamps:
- exactly = exactly and (ss.revision is not None)
- has_changes = has_changes or ss.changes
- cxt['exactly'] = (exactly) or b.getChanges()
- cxt['has_changes'] = has_changes
- cxt['build_url'] = path_to_build(req, b)
- cxt['authz'] = self.getAuthz(req)
-
- template = req.site.buildbot_service.templates.get_template("build.html")
- return template.render(**cxt)
-
- def stop(self, req, auth_ok=False):
- # check if this is allowed
- if not auth_ok:
- return StopBuildActionResource(self.build_status)
-
- b = self.build_status
- log.msg("web stopBuild of build %s:%s" % \
- (b.getBuilder().getName(), b.getNumber()))
-
- name = self.getAuthz(req).getUsernameFull(req)
- comments = req.args.get("comments", ["<no reason specified>"])[0]
- comments.decode(getRequestCharset(req))
- # html-quote both the username and comments, just to be safe
- reason = ("The web-page 'stop build' button was pressed by "
- "'%s': %s\n" % (html.escape(name), html.escape(comments)))
-
- c = interfaces.IControl(self.getBuildmaster(req))
- bldrc = c.getBuilder(self.build_status.getBuilder().getName())
- if bldrc:
- bldc = bldrc.getBuild(self.build_status.getNumber())
- if bldc:
- bldc.stopBuild(reason)
-
- # we're at http://localhost:8080/svn-hello/builds/5/stop?[args] and
- # we want to go to: http://localhost:8080/svn-hello
- r = Redirect(path_to_builder(req, self.build_status.getBuilder()))
- d = defer.Deferred()
- reactor.callLater(1, d.callback, r)
- return DeferredResource(d)
-
- def rebuild(self, req):
- return ForceBuildActionResource(self.build_status,
- self.build_status.getBuilder())
-
- def getChild(self, path, req):
- if path == "stop":
- return self.stop(req)
- if path == "rebuild":
- return self.rebuild(req)
- if path == "steps":
- return StepsResource(self.build_status)
- if path == "tests":
- return TestsResource(self.build_status)
-
- return HtmlResource.getChild(self, path, req)
-
-# /builders/$builder/builds
-class BuildsResource(HtmlResource):
- addSlash = True
-
- def __init__(self, builder_status):
- HtmlResource.__init__(self)
- self.builder_status = builder_status
-
- def content(self, req, cxt):
- return "subpages shows data for each build"
-
- def getChild(self, path, req):
- try:
- num = int(path)
- except ValueError:
- num = None
- if num is not None:
- build_status = self.builder_status.getBuild(num)
- if build_status:
- return StatusResourceBuild(build_status)
-
- return HtmlResource.getChild(self, path, req)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/builder.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/builder.py
deleted file mode 100644
index b4d15233..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/builder.py
+++ /dev/null
@@ -1,632 +0,0 @@
-# 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
-
-
-from twisted.web import html
-import urllib, time
-from twisted.python import log
-from twisted.internet import defer
-from buildbot import interfaces
-from buildbot.status.web.base import HtmlResource, BuildLineMixin, \
- path_to_build, path_to_slave, path_to_builder, path_to_change, \
- path_to_root, ICurrentBox, build_get_class, \
- map_branches, path_to_authzfail, ActionResource, \
- getRequestCharset
-from buildbot.schedulers.forcesched import ForceScheduler
-from buildbot.schedulers.forcesched import ValidationError
-from buildbot.status.web.build import BuildsResource, StatusResourceBuild
-from buildbot import util
-import collections
-
-class ForceAction(ActionResource):
- @defer.inlineCallbacks
- def force(self, req, builderNames):
- master = self.getBuildmaster(req)
- owner = self.getAuthz(req).getUsernameFull(req)
- schedulername = req.args.get("forcescheduler", ["<unknown>"])[0]
- if schedulername == "<unknown>":
- defer.returnValue((path_to_builder(req, self.builder_status),
- "forcescheduler arg not found"))
- return
-
- args = {}
- # decode all of the args
- encoding = getRequestCharset(req)
- for name, argl in req.args.iteritems():
- if name == "checkbox":
- # damn html's ungeneric checkbox implementation...
- for cb in argl:
- args[cb.decode(encoding)] = True
- else:
- args[name] = [ arg.decode(encoding) for arg in argl ]
-
- for sch in master.allSchedulers():
- if schedulername == sch.name:
- try:
- yield sch.force(owner, builderNames, **args)
- msg = ""
- except ValidationError, e:
- msg = html.escape(e.message.encode('ascii','ignore'))
- break
-
- # send the user back to the builder page
- defer.returnValue(msg)
-
-
-class ForceAllBuildsActionResource(ForceAction):
-
- def __init__(self, status, selectedOrAll):
- self.status = status
- self.selectedOrAll = selectedOrAll
- self.action = "forceAllBuilds"
-
- @defer.inlineCallbacks
- def performAction(self, req):
- authz = self.getAuthz(req)
- res = yield authz.actionAllowed('forceAllBuilds', req)
-
- if not res:
- defer.returnValue(path_to_authzfail(req))
- return
-
- if self.selectedOrAll == 'all':
- builderNames = None
- elif self.selectedOrAll == 'selected':
- builderNames = [b for b in req.args.get("selected", []) if b]
-
- msg = yield self.force(req, builderNames)
-
- # back to the welcome page
- defer.returnValue((path_to_root(req) + "builders", msg))
-
-class StopAllBuildsActionResource(ActionResource):
-
- def __init__(self, status, selectedOrAll):
- self.status = status
- self.selectedOrAll = selectedOrAll
- self.action = "stopAllBuilds"
-
- @defer.inlineCallbacks
- def performAction(self, req):
- authz = self.getAuthz(req)
- res = yield authz.actionAllowed('stopAllBuilds', req)
- if not res:
- defer.returnValue(path_to_authzfail(req))
- return
-
- builders = None
- if self.selectedOrAll == 'all':
- builders = self.status.getBuilderNames()
- elif self.selectedOrAll == 'selected':
- builders = [b for b in req.args.get("selected", []) if b]
-
- for bname in builders:
- builder_status = self.status.getBuilder(bname)
- (state, current_builds) = builder_status.getState()
- if state != "building":
- continue
- for b in current_builds:
- build_status = builder_status.getBuild(b.number)
- if not build_status:
- continue
- build = StatusResourceBuild(build_status)
- build.stop(req, auth_ok=True)
-
- # go back to the welcome page
- defer.returnValue(path_to_root(req))
-
-
-class CancelAllPendingBuildsActionResource(ActionResource):
-
- def __init__(self, status, selectedOrAll):
- self.status = status
- self.selectedOrAll = selectedOrAll
- self.action = 'cancelAllPendingBuilds'
-
- @defer.inlineCallbacks
- def performAction(self, req):
- authz = self.getAuthz(req)
- res = yield authz.actionAllowed('cancelAllPendingBuilds', req)
- if not res:
- defer.returnValue(path_to_authzfail(req))
- return
-
- builders = None
- if self.selectedOrAll == 'all':
- builders = self.status.getBuilderNames()
- elif self.selectedOrAll == 'selected':
- builders = [b for b in req.args.get("selected", []) if b]
-
- c = interfaces.IControl(self.getBuildmaster(req))
- for bname in builders:
- authz = self.getAuthz(req)
- builder_control = c.getBuilder(bname)
-
- brcontrols = yield builder_control.getPendingBuildRequestControls()
-
- for build_req in brcontrols:
- log.msg("Cancelling %s" % build_req)
- build_req.cancel()
-
- # go back to the welcome page
- defer.returnValue(path_to_root(req))
-
-
-class PingBuilderActionResource(ActionResource):
-
- def __init__(self, builder_status):
- self.builder_status = builder_status
- self.action = "pingBuilder"
-
- @defer.inlineCallbacks
- def performAction(self, req):
- log.msg("web ping of builder '%s'" % self.builder_status.getName())
- res = yield self.getAuthz(req).actionAllowed('pingBuilder', req,
- self.builder_status)
- if not res:
- log.msg("..but not authorized")
- defer.returnValue(path_to_authzfail(req))
- return
-
- c = interfaces.IControl(self.getBuildmaster(req))
- bc = c.getBuilder(self.builder_status.getName())
- bc.ping()
- # send the user back to the builder page
- defer.returnValue(path_to_builder(req, self.builder_status))
-
-class ForceBuildActionResource(ForceAction):
-
- def __init__(self, builder_status):
- self.builder_status = builder_status
- self.action = "forceBuild"
-
- @defer.inlineCallbacks
- def performAction(self, req):
- # check if this is allowed
- res = yield self.getAuthz(req).actionAllowed(self.action, req,
- self.builder_status)
- if not res:
- log.msg("..but not authorized")
- defer.returnValue(path_to_authzfail(req))
- return
-
- builderName = self.builder_status.getName()
-
- msg = yield self.force(req, [builderName])
-
- # send the user back to the builder page
- defer.returnValue((path_to_builder(req, self.builder_status), msg))
-
-def buildForceContextForField(req, default_props, sch, field, master, buildername):
- pname = "%s.%s"%(sch.name, field.fullName)
-
- default = field.default
-
- if "list" in field.type:
- choices = field.getChoices(master, sch, buildername)
- if choices:
- default = choices[0]
- default_props[pname+".choices"] = choices
-
- default = req.args.get(pname, [default])[0]
- if "bool" in field.type:
- default = "checked" if default else ""
- elif isinstance(default, unicode):
- # filter out unicode chars, and html stuff
- default = html.escape(default.encode('utf-8','ignore'))
-
- default_props[pname] = default
-
- if "nested" in field.type:
- for subfield in field.fields:
- buildForceContextForField(req, default_props, sch, subfield, master, buildername)
-
-def buildForceContext(cxt, req, master, buildername=None):
- force_schedulers = {}
- default_props = collections.defaultdict(str)
- for sch in master.allSchedulers():
- if isinstance(sch, ForceScheduler) and (buildername is None or(buildername in sch.builderNames)):
- force_schedulers[sch.name] = sch
- for field in sch.all_fields:
- buildForceContextForField(req, default_props, sch, field, master, buildername)
-
- cxt['force_schedulers'] = force_schedulers
- cxt['default_props'] = default_props
-
-# /builders/$builder
-class StatusResourceBuilder(HtmlResource, BuildLineMixin):
- addSlash = True
-
- def __init__(self, builder_status, numbuilds=20):
- HtmlResource.__init__(self)
- self.builder_status = builder_status
- self.numbuilds = numbuilds
-
- def getPageTitle(self, request):
- return "Buildbot: %s" % self.builder_status.getName()
-
- def builder(self, build, req):
- b = {}
-
- b['num'] = build.getNumber()
- b['link'] = path_to_build(req, build)
-
- when = build.getETA()
- if when is not None:
- b['when'] = util.formatInterval(when)
- b['when_time'] = time.strftime("%H:%M:%S",
- time.localtime(time.time() + when))
-
- step = build.getCurrentStep()
- # TODO: is this necessarily the case?
- if not step:
- b['current_step'] = "[waiting for Lock]"
- else:
- if step.isWaitingForLocks():
- b['current_step'] = "%s [waiting for Lock]" % step.getName()
- else:
- b['current_step'] = step.getName()
-
- b['stop_url'] = path_to_build(req, build) + '/stop'
-
- return b
-
- @defer.inlineCallbacks
- def content(self, req, cxt):
- b = self.builder_status
-
- cxt['name'] = b.getName()
- cxt['description'] = b.getDescription()
- req.setHeader('Cache-Control', 'no-cache')
- slaves = b.getSlaves()
- connected_slaves = [s for s in slaves if s.isConnected()]
-
- cxt['current'] = [self.builder(x, req) for x in b.getCurrentBuilds()]
-
- cxt['pending'] = []
- statuses = yield b.getPendingBuildRequestStatuses()
- for pb in statuses:
- changes = []
-
- source = yield pb.getSourceStamp()
- submitTime = yield pb.getSubmitTime()
- bsid = yield pb.getBsid()
-
- properties = yield \
- pb.master.db.buildsets.getBuildsetProperties(bsid)
-
- if source.changes:
- for c in source.changes:
- changes.append({ 'url' : path_to_change(req, c),
- 'who' : c.who,
- 'revision' : c.revision,
- 'repo' : c.repository })
-
- cxt['pending'].append({
- 'when': time.strftime("%b %d %H:%M:%S",
- time.localtime(submitTime)),
- 'delay': util.formatInterval(util.now() - submitTime),
- 'id': pb.brid,
- 'changes' : changes,
- 'num_changes' : len(changes),
- 'properties' : properties,
- })
-
- numbuilds = cxt['numbuilds'] = int(req.args.get('numbuilds', [self.numbuilds])[0])
- recent = cxt['recent'] = []
- for build in b.generateFinishedBuilds(num_builds=int(numbuilds)):
- recent.append(self.get_line_values(req, build, False))
-
- sl = cxt['slaves'] = []
- connected_slaves = 0
- for slave in slaves:
- s = {}
- sl.append(s)
- s['link'] = path_to_slave(req, slave)
- s['name'] = slave.getName()
- c = s['connected'] = slave.isConnected()
- s['paused'] = slave.isPaused()
- s['admin'] = unicode(slave.getAdmin() or '', 'utf-8')
- if c:
- connected_slaves += 1
- cxt['connected_slaves'] = connected_slaves
-
- cxt['authz'] = self.getAuthz(req)
- cxt['builder_url'] = path_to_builder(req, b)
- buildForceContext(cxt, req, self.getBuildmaster(req), b.getName())
- template = req.site.buildbot_service.templates.get_template("builder.html")
- defer.returnValue(template.render(**cxt))
-
- def ping(self, req):
- return PingBuilderActionResource(self.builder_status)
-
- def getChild(self, path, req):
- if path == "force":
- return ForceBuildActionResource(self.builder_status)
- if path == "ping":
- return self.ping(req)
- if path == "cancelbuild":
- return CancelChangeResource(self.builder_status)
- if path == "stopchange":
- return StopChangeResource(self.builder_status)
- if path == "builds":
- return BuildsResource(self.builder_status)
-
- return HtmlResource.getChild(self, path, req)
-
-class CancelChangeResource(ActionResource):
-
- def __init__(self, builder_status):
- ActionResource.__init__(self)
- self.builder_status = builder_status
-
- @defer.inlineCallbacks
- def performAction(self, req):
- try:
- request_id = req.args.get("id", [None])[0]
- if request_id == "all":
- cancel_all = True
- else:
- cancel_all = False
- request_id = int(request_id)
- except:
- request_id = None
-
- authz = self.getAuthz(req)
- if request_id:
- c = interfaces.IControl(self.getBuildmaster(req))
- builder_control = c.getBuilder(self.builder_status.getName())
-
- brcontrols = yield builder_control.getPendingBuildRequestControls()
-
- for build_req in brcontrols:
- if cancel_all or (build_req.brid == request_id):
- log.msg("Cancelling %s" % build_req)
- res = yield authz.actionAllowed('cancelPendingBuild', req,
- build_req)
- if res:
- build_req.cancel()
- else:
- defer.returnValue(path_to_authzfail(req))
- return
- if not cancel_all:
- break
-
- defer.returnValue(path_to_builder(req, self.builder_status))
-
-class StopChangeMixin(object):
-
- @defer.inlineCallbacks
- def stopChangeForBuilder(self, req, builder_status, auth_ok=False):
- try:
- request_change = req.args.get("change", [None])[0]
- request_change = int(request_change)
- except:
- request_change = None
-
- authz = self.getAuthz(req)
- if request_change:
- c = interfaces.IControl(self.getBuildmaster(req))
- builder_control = c.getBuilder(builder_status.getName())
-
- brcontrols = yield builder_control.getPendingBuildRequestControls()
- build_controls = dict((x.brid, x) for x in brcontrols)
-
- build_req_statuses = yield \
- builder_status.getPendingBuildRequestStatuses()
-
- for build_req in build_req_statuses:
- ss = yield build_req.getSourceStamp()
-
- if not ss.changes:
- continue
-
- for change in ss.changes:
- if change.number == request_change:
- control = build_controls[build_req.brid]
- log.msg("Cancelling %s" % control)
- res = yield authz.actionAllowed('stopChange', req, control)
- if (auth_ok or res):
- control.cancel()
- else:
- defer.returnValue(False)
- return
-
- defer.returnValue(True)
-
-
-class StopChangeResource(StopChangeMixin, ActionResource):
-
- def __init__(self, builder_status):
- ActionResource.__init__(self)
- self.builder_status = builder_status
-
- @defer.inlineCallbacks
- def performAction(self, req):
- """Cancel all pending builds that include a given numbered change."""
- success = yield self.stopChangeForBuilder(req, self.builder_status)
-
- if not success:
- defer.returnValue(path_to_authzfail(req))
- else:
- defer.returnValue(path_to_builder(req, self.builder_status))
-
-
-class StopChangeAllResource(StopChangeMixin, ActionResource):
-
- def __init__(self, status):
- ActionResource.__init__(self)
- self.status = status
-
- @defer.inlineCallbacks
- def performAction(self, req):
- """Cancel all pending builds that include a given numbered change."""
- authz = self.getAuthz(req)
- res = yield authz.actionAllowed('stopChange', req)
- if not res:
- defer.returnValue(path_to_authzfail(req))
- return
-
- for bname in self.status.getBuilderNames():
- builder_status = self.status.getBuilder(bname)
- res = yield self.stopChangeForBuilder(req, builder_status, auth_ok=True)
- if not res:
- defer.returnValue(path_to_authzfail(req))
- return
-
- defer.returnValue(path_to_root(req))
-
-
-# /builders/_all
-class StatusResourceAllBuilders(HtmlResource, BuildLineMixin):
-
- def __init__(self, status):
- HtmlResource.__init__(self)
- self.status = status
-
- def getChild(self, path, req):
- if path == "forceall":
- return self.forceall(req)
- if path == "stopall":
- return self.stopall(req)
- if path == "stopchangeall":
- return StopChangeAllResource(self.status)
- if path == "cancelpendingall":
- return CancelAllPendingBuildsActionResource(self.status, 'all')
-
- return HtmlResource.getChild(self, path, req)
-
- def forceall(self, req):
- return ForceAllBuildsActionResource(self.status, 'all')
-
- def stopall(self, req):
- return StopAllBuildsActionResource(self.status, 'all')
-
-# /builders/_selected
-
-
-class StatusResourceSelectedBuilders(HtmlResource, BuildLineMixin):
-
- def __init__(self, status):
- HtmlResource.__init__(self)
- self.status = status
-
- def getChild(self, path, req):
- if path == "forceselected":
- return self.forceselected(req)
- if path == "stopselected":
- return self.stopselected(req)
- if path == "cancelpendingselected":
- return CancelAllPendingBuildsActionResource(self.status, 'selected')
-
- return HtmlResource.getChild(self, path, req)
-
- def forceselected(self, req):
- return ForceAllBuildsActionResource(self.status, 'selected')
-
- def stopselected(self, req):
- return StopAllBuildsActionResource(self.status, 'selected')
-
-# /builders
-
-
-class BuildersResource(HtmlResource):
- pageTitle = "Builders"
- addSlash = True
-
- def __init__(self, numbuilds=20):
- HtmlResource.__init__(self)
- self.numbuilds = numbuilds
-
- @defer.inlineCallbacks
- def content(self, req, cxt):
- status = self.getStatus(req)
- encoding = getRequestCharset(req)
-
- builders = req.args.get("builder", status.getBuilderNames())
- branches = [ b.decode(encoding)
- for b in req.args.get("branch", [])
- if b ]
-
- # get counts of pending builds for each builder
- brstatus_ds = []
- brcounts = {}
- def keep_count(statuses, builderName):
- brcounts[builderName] = len(statuses)
- for builderName in builders:
- builder_status = status.getBuilder(builderName)
- d = builder_status.getPendingBuildRequestStatuses()
- d.addCallback(keep_count, builderName)
- brstatus_ds.append(d)
- yield defer.gatherResults(brstatus_ds)
-
- cxt['branches'] = branches
- bs = cxt['builders'] = []
-
- building = 0
- online = 0
- base_builders_url = path_to_root(req) + "builders/"
- for bn in builders:
- bld = { 'link': base_builders_url + urllib.quote(bn, safe=''),
- 'name': bn }
- bs.append(bld)
-
- builder = status.getBuilder(bn)
- builds = list(builder.generateFinishedBuilds(map_branches(branches),
- num_builds=1))
- if builds:
- b = builds[0]
- bld['build_url'] = (bld['link'] + "/builds/%d" % b.getNumber())
- label = None
- all_got_revisions = b.getAllGotRevisions()
- # If len = 1 then try if revision can be used as label.
- if len(all_got_revisions) == 1:
- label = all_got_revisions[all_got_revisions.keys()[0]]
- if not label or len(str(label)) > 20:
- label = "#%d" % b.getNumber()
-
- bld['build_label'] = label
- bld['build_text'] = " ".join(b.getText())
- bld['build_css_class'] = build_get_class(b)
-
- current_box = ICurrentBox(builder).getBox(status, brcounts)
- bld['current_box'] = current_box.td()
-
- builder_status = builder.getState()[0]
- if builder_status == "building":
- building += 1
- online += 1
- elif builder_status != "offline":
- online += 1
-
- cxt['authz'] = self.getAuthz(req)
- cxt['num_building'] = building
- cxt['num_online'] = online
- buildForceContext(cxt, req, self.getBuildmaster(req))
- template = req.site.buildbot_service.templates.get_template("builders.html")
- defer.returnValue(template.render(**cxt))
-
- def getChild(self, path, req):
- s = self.getStatus(req)
- if path in s.getBuilderNames():
- builder_status = s.getBuilder(path)
- return StatusResourceBuilder(builder_status, self.numbuilds)
- if path == "_all":
- return StatusResourceAllBuilders(self.getStatus(req))
- if path == "_selected":
- return StatusResourceSelectedBuilders(self.getStatus(req))
-
- return HtmlResource.getChild(self, path, req)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/buildstatus.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/buildstatus.py
deleted file mode 100644
index 9dd57b6c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/buildstatus.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# 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
-
-from buildbot.status.web.base import HtmlResource, IBox
-
-class BuildStatusStatusResource(HtmlResource):
- def __init__(self, categories=None):
- HtmlResource.__init__(self)
-
- def content(self, request, ctx):
- """Display a build in the same format as the waterfall page.
- The HTTP GET parameters are the builder name and the build
- number."""
-
- status = self.getStatus(request)
- request.setHeader('Cache-Control', 'no-cache')
-
- # Get the parameters.
- name = request.args.get("builder", [None])[0]
- number = request.args.get("number", [None])[0]
- if not name or not number:
- return "builder and number parameter missing"
- number = int(number)
-
- # Check if the builder in parameter exists.
- try:
- builder = status.getBuilder(name)
- except:
- return "unknown builder"
-
- # Check if the build in parameter exists.
- build = builder.getBuild(int(number))
- if not build:
- return "unknown build %s" % number
-
- rows = ctx['rows'] = []
-
- # Display each step, starting by the last one.
- for i in range(len(build.getSteps()) - 1, -1, -1):
- step = build.getSteps()[i]
- if step.isStarted() and step.getText():
- rows.append(IBox(step).getBox(request).td(align="center"))
-
- # Display the bottom box with the build number in it.
- ctx['build'] = IBox(build).getBox(request).td(align="center")
-
- template = request.site.buildbot_service.templates.get_template("buildstatus.html")
- data = template.render(**ctx)
-
- # We want all links to display in a new tab/window instead of in the
- # current one.
- # TODO: Move to template
- data = data.replace('<a ', '<a target="_blank"')
- return data
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/change_hook.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/change_hook.py
deleted file mode 100644
index cc53e34b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/change_hook.py
+++ /dev/null
@@ -1,136 +0,0 @@
-# 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
-
-# code inspired/copied from contrib/github_buildbot
-# and inspired from code from the Chromium project
-# otherwise, Andrew Melo <andrew.melo@gmail.com> wrote the rest
-# but "the rest" is pretty minimal
-
-import re
-from twisted.web import resource, server
-from twisted.python.reflect import namedModule
-from twisted.python import log
-from twisted.internet import defer
-
-class ChangeHookResource(resource.Resource):
- # this is a cheap sort of template thingy
- contentType = "text/html; charset=utf-8"
- children = {}
- def __init__(self, dialects={}):
- """
- The keys of 'dialects' select a modules to load under
- master/buildbot/status/web/hooks/
- The value is passed to the module's getChanges function, providing
- configuration options to the dialect.
- """
- self.dialects = dialects
- self.request_dialect = None
-
- def getChild(self, name, request):
- return self
-
- def render_GET(self, request):
- """
- Reponds to events and starts the build process
- different implementations can decide on what methods they will accept
- """
- return self.render_POST(request)
-
- def render_POST(self, request):
- """
- Reponds to events and starts the build process
- different implementations can decide on what methods they will accept
-
- :arguments:
- request
- the http request object
- """
-
- try:
- changes, src = self.getChanges( request )
- except ValueError, err:
- request.setResponseCode(400, err.args[0])
- return err.args[0]
- except Exception, e:
- log.err(e, "processing changes from web hook")
- msg = "Error processing changes."
- request.setResponseCode(500, msg)
- return msg
-
- log.msg("Payload: " + str(request.args))
-
- if not changes:
- log.msg("No changes found")
- return "no changes found"
- d = self.submitChanges( changes, request, src )
- def ok(_):
- request.setResponseCode(202)
- request.finish()
- def err(why):
- log.err(why, "adding changes from web hook")
- request.setResponseCode(500)
- request.finish()
- d.addCallbacks(ok, err)
- return server.NOT_DONE_YET
-
-
- def getChanges(self, request):
- """
- Take the logic from the change hook, and then delegate it
- to the proper handler
- http://localhost/change_hook/DIALECT will load up
- buildmaster/status/web/hooks/DIALECT.py
-
- and call getChanges()
-
- the return value is a list of changes
-
- if DIALECT is unspecified, a sample implementation is provided
- """
- uriRE = re.search(r'^/change_hook/?([a-zA-Z0-9_]*)', request.uri)
-
- if not uriRE:
- log.msg("URI doesn't match change_hook regex: %s" % request.uri)
- raise ValueError("URI doesn't match change_hook regex: %s" % request.uri)
-
- changes = []
- src = None
-
- # Was there a dialect provided?
- if uriRE.group(1):
- dialect = uriRE.group(1)
- else:
- dialect = 'base'
-
- if dialect in self.dialects.keys():
- log.msg("Attempting to load module buildbot.status.web.hooks." + dialect)
- tempModule = namedModule('buildbot.status.web.hooks.' + dialect)
- changes, src = tempModule.getChanges(request,self.dialects[dialect])
- log.msg("Got the following changes %s" % changes)
- self.request_dialect = dialect
- else:
- m = "The dialect specified, '%s', wasn't whitelisted in change_hook" % dialect
- log.msg(m)
- log.msg("Note: if dialect is 'base' then it's possible your URL is malformed and we didn't regex it properly")
- raise ValueError(m)
-
- return (changes, src)
-
- @defer.inlineCallbacks
- def submitChanges(self, changes, request, src):
- master = request.site.buildbot_service.master
- for chdict in changes:
- change = yield master.addChange(src=src, **chdict)
- log.msg("injected change %s" % change)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/changes.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/changes.py
deleted file mode 100644
index e579669e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/changes.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# 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
-
-
-from zope.interface import implements
-from twisted.python import components
-from twisted.web.resource import NoResource
-
-from buildbot.changes.changes import Change
-from buildbot.status.web.base import HtmlResource, IBox, Box
-
-class ChangeResource(HtmlResource):
- def __init__(self, changeid):
- self.changeid = changeid
- self.pageTitle = "Change #%d" % changeid
-
- def content(self, req, cxt):
- d = self.getStatus(req).getChange(self.changeid)
- def cb(change):
- if not change:
- return "No change number %d" % self.changeid
- templates = req.site.buildbot_service.templates
- cxt['c'] = change.asDict()
- template = templates.get_template("change.html")
- data = template.render(cxt)
- return data
- d.addCallback(cb)
- return d
-
-# /changes/NN
-class ChangesResource(HtmlResource):
-
- def content(self, req, cxt):
- cxt['sources'] = self.getStatus(req).getChangeSources()
- template = req.site.buildbot_service.templates.get_template("change_sources.html")
- return template.render(**cxt)
-
- def getChild(self, path, req):
- try:
- changeid = int(path)
- except ValueError:
- return NoResource("Expected a change number")
-
- return ChangeResource(changeid)
-
-class ChangeBox(components.Adapter):
- implements(IBox)
-
- def getBox(self, req):
- url = req.childLink("../changes/%d" % self.original.number)
- template = req.site.buildbot_service.templates.get_template("change_macros.html")
- text = template.module.box_contents(url=url,
- who=self.original.getShortAuthor(),
- pageTitle=self.original.comments,
- revision=self.original.revision,
- project=self.original.project)
- return Box([text], class_="Change")
-components.registerAdapter(ChangeBox, Change, IBox)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/console.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/console.py
deleted file mode 100644
index 60eb67c0..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/console.py
+++ /dev/null
@@ -1,744 +0,0 @@
-# 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 time
-import operator
-import re
-import urllib
-from twisted.internet import defer
-from buildbot import util
-from buildbot.status import builder
-from buildbot.status.web.base import HtmlResource
-from buildbot.changes import changes
-
-class DoesNotPassFilter(Exception): pass # Used for filtering revs
-
-def getResultsClass(results, prevResults, inProgress):
- """Given the current and past results, return the class that will be used
- by the css to display the right color for a box."""
-
- if inProgress:
- return "running"
-
- if results is None:
- return "notstarted"
-
- if results == builder.SUCCESS:
- return "success"
-
- if results == builder.WARNINGS:
- return "warnings"
-
- if results == builder.FAILURE:
- if not prevResults:
- # This is the bottom box. We don't know if the previous one failed
- # or not. We assume it did not.
- return "failure"
-
- if prevResults != builder.FAILURE:
- # This is a new failure.
- return "failure"
- else:
- # The previous build also failed.
- return "failure-again"
-
- # Any other results? Like EXCEPTION?
- return "exception"
-
-class ANYBRANCH: pass # a flag value, used below
-
-class DevRevision:
- """Helper class that contains all the information we need for a revision."""
-
- def __init__(self, change):
- self.revision = change.revision
- self.comments = change.comments
- self.who = change.who
- self.date = change.getTime()
- self.revlink = getattr(change, 'revlink', None)
- self.when = change.when
- self.repository = change.repository
- self.project = change.project
-
-
-class DevBuild:
- """Helper class that contains all the information we need for a build."""
-
- def __init__(self, revision, build, details):
- self.revision = revision
- self.results = build.getResults()
- self.number = build.getNumber()
- self.isFinished = build.isFinished()
- self.text = build.getText()
- self.eta = build.getETA()
- self.details = details
- self.when = build.getTimes()[0]
- #TODO: support multiple sourcestamps
- self.source = build.getSourceStamps()[0]
-
-
-class ConsoleStatusResource(HtmlResource):
- """Main console class. It displays a user-oriented status page.
- Every change is a line in the page, and it shows the result of the first
- build with this change for each slave."""
-
- def __init__(self, orderByTime=False):
- HtmlResource.__init__(self)
-
- self.status = None
-
- if orderByTime:
- self.comparator = TimeRevisionComparator()
- else:
- self.comparator = IntegerRevisionComparator()
-
- def getPageTitle(self, request):
- status = self.getStatus(request)
- title = status.getTitle()
- if title:
- return "BuildBot: %s" % title
- else:
- return "BuildBot"
-
- def getChangeManager(self, request):
- return request.site.buildbot_service.parent.change_svc
-
- ##
- ## Data gathering functions
- ##
-
- def getHeadBuild(self, builder):
- """Get the most recent build for the given builder.
- """
- build = builder.getBuild(-1)
-
- # HACK: Work around #601, the head build may be None if it is
- # locked.
- if build is None:
- build = builder.getBuild(-2)
-
- return build
-
- def fetchChangesFromHistory(self, status, max_depth, max_builds, debugInfo):
- """Look at the history of the builders and try to fetch as many changes
- as possible. We need this when the main source does not contain enough
- sourcestamps.
-
- max_depth defines how many builds we will parse for a given builder.
- max_builds defines how many builds total we want to parse. This is to
- limit the amount of time we spend in this function.
-
- This function is sub-optimal, but the information returned by this
- function is cached, so this function won't be called more than once.
- """
-
- allChanges = list()
- build_count = 0
- for builderName in status.getBuilderNames()[:]:
- if build_count > max_builds:
- break
-
- builder = status.getBuilder(builderName)
- build = self.getHeadBuild(builder)
- depth = 0
- while build and depth < max_depth and build_count < max_builds:
- depth += 1
- build_count += 1
- sourcestamp = build.getSourceStamps()[0]
- allChanges.extend(sourcestamp.changes[:])
- build = build.getPreviousBuild()
-
- debugInfo["source_fetch_len"] = len(allChanges)
- return allChanges
-
- @defer.inlineCallbacks
- def getAllChanges(self, request, status, debugInfo):
- master = request.site.buildbot_service.master
-
- chdicts = yield master.db.changes.getRecentChanges(25)
-
- # convert those to Change instances
- allChanges = yield defer.gatherResults([
- changes.Change.fromChdict(master, chdict)
- for chdict in chdicts ])
-
- allChanges.sort(key=self.comparator.getSortingKey())
-
- # Remove the dups
- prevChange = None
- newChanges = []
- for change in allChanges:
- rev = change.revision
- if not prevChange or rev != prevChange.revision:
- newChanges.append(change)
- prevChange = change
- allChanges = newChanges
-
- defer.returnValue(allChanges)
-
- def getBuildDetails(self, request, builderName, build):
- """Returns an HTML list of failures for a given build."""
- details = {}
- if not build.getLogs():
- return details
-
- for step in build.getSteps():
- (result, reason) = step.getResults()
- if result == builder.FAILURE:
- name = step.getName()
-
- # Remove html tags from the error text.
- stripHtml = re.compile(r'<.*?>')
- strippedDetails = stripHtml.sub('', ' '.join(step.getText()))
-
- details['buildername'] = builderName
- details['status'] = strippedDetails
- details['reason'] = reason
- logs = details['logs'] = []
-
- if step.getLogs():
- for log in step.getLogs():
- logname = log.getName()
- logurl = request.childLink(
- "../builders/%s/builds/%s/steps/%s/logs/%s" %
- (urllib.quote(builderName),
- build.getNumber(),
- urllib.quote(name),
- urllib.quote(logname)))
- logs.append(dict(url=logurl, name=logname))
- return details
-
- def getBuildsForRevision(self, request, builder, builderName, codebase,
- lastRevision, numBuilds, debugInfo):
- """Return the list of all the builds for a given builder that we will
- need to be able to display the console page. We start by the most recent
- build, and we go down until we find a build that was built prior to the
- last change we are interested in."""
-
- revision = lastRevision
-
- builds = []
- build = self.getHeadBuild(builder)
- number = 0
- while build and number < numBuilds:
- debugInfo["builds_scanned"] += 1
-
- got_rev = None
- sourceStamps = build.getSourceStamps(absolute=True)
-
- # The console page cannot handle builds that have more than 1 revision
- if codebase is not None:
- # Get the last revision in this build for this codebase.
- for ss in sourceStamps:
- if ss.codebase == codebase:
- got_rev = ss.revision
- break
- elif len(sourceStamps) == 1:
- ss = sourceStamps[0]
- # Get the last revision in this build.
- got_rev = ss.revision
-
- # We ignore all builds that don't have last revisions.
- # TODO(nsylvain): If the build is over, maybe it was a problem
- # with the update source step. We need to find a way to tell the
- # user that his change might have broken the source update.
- if got_rev is not None:
- number += 1
- details = self.getBuildDetails(request, builderName, build)
- devBuild = DevBuild(got_rev, build, details)
- builds.append(devBuild)
-
- # Now break if we have enough builds.
- current_revision = self.getChangeForBuild(
- build, revision)
- if self.comparator.isRevisionEarlier(
- devBuild, current_revision):
- break
-
- build = build.getPreviousBuild()
-
- return builds
-
- def getChangeForBuild(self, build, revision):
- if not build or not build.getChanges(): # Forced build
- return DevBuild(revision, build, None)
-
- for change in build.getChanges():
- if change.revision == revision:
- return change
-
- # No matching change, return the last change in build.
- changes = list(build.getChanges())
- changes.sort(key=self.comparator.getSortingKey())
- return changes[-1]
-
- def getAllBuildsForRevision(self, status, request, codebase, lastRevision,
- numBuilds, categories, builders, debugInfo):
- """Returns a dictionary of builds we need to inspect to be able to
- display the console page. The key is the builder name, and the value is
- an array of build we care about. We also returns a dictionary of
- builders we care about. The key is it's category.
-
- codebase is the codebase to get revisions from
- lastRevision is the last revision we want to display in the page.
- categories is a list of categories to display. It is coming from the
- HTTP GET parameters.
- builders is a list of builders to display. It is coming from the HTTP
- GET parameters.
- """
-
- allBuilds = dict()
-
- # List of all builders in the dictionary.
- builderList = dict()
-
- debugInfo["builds_scanned"] = 0
- # Get all the builders.
- builderNames = status.getBuilderNames()[:]
- for builderName in builderNames:
- builder = status.getBuilder(builderName)
-
- # Make sure we are interested in this builder.
- if categories and builder.category not in categories:
- continue
- if builders and builderName not in builders:
- continue
-
- # We want to display this builder.
- category = builder.category or "default"
- # Strip the category to keep only the text before the first |.
- # This is a hack to support the chromium usecase where they have
- # multiple categories for each slave. We use only the first one.
- # TODO(nsylvain): Create another way to specify "display category"
- # in master.cfg.
- category = category.split('|')[0]
- if not builderList.get(category):
- builderList[category] = []
-
- # Append this builder to the dictionary of builders.
- builderList[category].append(builderName)
- # Set the list of builds for this builder.
- allBuilds[builderName] = self.getBuildsForRevision(request,
- builder,
- builderName,
- codebase,
- lastRevision,
- numBuilds,
- debugInfo)
-
- return (builderList, allBuilds)
-
-
- ##
- ## Display functions
- ##
-
- def displayCategories(self, builderList, debugInfo):
- """Display the top category line."""
-
- count = 0
- for category in builderList:
- count += len(builderList[category])
-
- categories = builderList.keys()
- categories.sort()
-
- cs = []
-
- for category in categories:
- c = {}
-
- c["name"] = category
-
- # To be able to align the table correctly, we need to know
- # what percentage of space this category will be taking. This is
- # (#Builders in Category) / (#Builders Total) * 100.
- c["size"] = (len(builderList[category]) * 100) / count
- cs.append(c)
-
- return cs
-
- def displaySlaveLine(self, status, builderList, debugInfo):
- """Display a line the shows the current status for all the builders we
- care about."""
-
- nbSlaves = 0
-
- # Get the number of builders.
- for category in builderList:
- nbSlaves += len(builderList[category])
-
- # Get the categories, and order them alphabetically.
- categories = builderList.keys()
- categories.sort()
-
- slaves = {}
-
- # For each category, we display each builder.
- for category in categories:
- slaves[category] = []
- # For each builder in this category, we set the build info and we
- # display the box.
- for builder in builderList[category]:
- s = {}
- s["color"] = "notstarted"
- s["pageTitle"] = builder
- s["url"] = "./builders/%s" % urllib.quote(builder)
- state, builds = status.getBuilder(builder).getState()
- # Check if it's offline, if so, the box is purple.
- if state == "offline":
- s["color"] = "offline"
- else:
- # If not offline, then display the result of the last
- # finished build.
- build = self.getHeadBuild(status.getBuilder(builder))
- while build and not build.isFinished():
- build = build.getPreviousBuild()
-
- if build:
- s["color"] = getResultsClass(build.getResults(), None,
- False)
-
- slaves[category].append(s)
-
- return slaves
-
- def displayStatusLine(self, builderList, allBuilds, revision, debugInfo):
- """Display the boxes that represent the status of each builder in the
- first build "revision" was in. Returns an HTML list of errors that
- happened during these builds."""
-
- details = []
- nbSlaves = 0
- for category in builderList:
- nbSlaves += len(builderList[category])
-
- # Sort the categories.
- categories = builderList.keys()
- categories.sort()
-
- builds = {}
-
- # Display the boxes by category group.
- for category in categories:
-
- builds[category] = []
-
- # Display the boxes for each builder in this category.
- for builder in builderList[category]:
- introducedIn = None
- firstNotIn = None
-
- # Find the first build that does not include the revision.
- for build in allBuilds[builder]:
- if self.comparator.isRevisionEarlier(build, revision):
- firstNotIn = build
- break
- else:
- introducedIn = build
-
- # Get the results of the first build with the revision, and the
- # first build that does not include the revision.
- results = None
- previousResults = None
- if introducedIn:
- results = introducedIn.results
- if firstNotIn:
- previousResults = firstNotIn.results
-
- isRunning = False
- if introducedIn and not introducedIn.isFinished:
- isRunning = True
-
- url = "./waterfall"
- pageTitle = builder
- tag = ""
- current_details = {}
- if introducedIn:
- current_details = introducedIn.details or ""
- url = "./buildstatus?builder=%s&number=%s" % (urllib.quote(builder),
- introducedIn.number)
- pageTitle += " "
- pageTitle += urllib.quote(' '.join(introducedIn.text), ' \n\\/:')
-
- builderStrip = builder.replace(' ', '')
- builderStrip = builderStrip.replace('(', '')
- builderStrip = builderStrip.replace(')', '')
- builderStrip = builderStrip.replace('.', '')
- tag = "Tag%s%s" % (builderStrip, introducedIn.number)
-
- if isRunning:
- pageTitle += ' ETA: %ds' % (introducedIn.eta or 0)
-
- resultsClass = getResultsClass(results, previousResults, isRunning)
-
- b = {}
- b["url"] = url
- b["pageTitle"] = pageTitle
- b["color"] = resultsClass
- b["tag"] = tag
-
- builds[category].append(b)
-
- # If the box is red, we add the explaination in the details
- # section.
- if current_details and resultsClass == "failure":
- details.append(current_details)
-
- return (builds, details)
-
- def filterRevisions(self, revisions, filter=None, max_revs=None):
- """Filter a set of revisions based on any number of filter criteria.
- If specified, filter should be a dict with keys corresponding to
- revision attributes, and values of 1+ strings"""
- if not filter:
- if max_revs is None:
- for rev in reversed(revisions):
- yield DevRevision(rev)
- else:
- for index,rev in enumerate(reversed(revisions)):
- if index >= max_revs:
- break
- yield DevRevision(rev)
- else:
- for index, rev in enumerate(reversed(revisions)):
- if max_revs and index >= max_revs:
- break
- try:
- for field,acceptable in filter.iteritems():
- if not hasattr(rev, field):
- raise DoesNotPassFilter
- if type(acceptable) in (str, unicode):
- if getattr(rev, field) != acceptable:
- raise DoesNotPassFilter
- elif type(acceptable) in (list, tuple, set):
- if getattr(rev, field) not in acceptable:
- raise DoesNotPassFilter
- yield DevRevision(rev)
- except DoesNotPassFilter:
- pass
-
- def displayPage(self, request, status, builderList, allBuilds, codebase,
- revisions, categories, repository, project, branch,
- debugInfo):
- """Display the console page."""
- # Build the main template directory with all the informations we have.
- subs = dict()
- subs["branch"] = branch or 'trunk'
- subs["repository"] = repository
- subs["project"] = project
- subs["codebase"] = codebase
- if categories:
- subs["categories"] = ' '.join(categories)
- subs["time"] = time.strftime("%a %d %b %Y %H:%M:%S",
- time.localtime(util.now()))
- subs["debugInfo"] = debugInfo
- subs["ANYBRANCH"] = ANYBRANCH
-
- if builderList:
- subs["categories"] = self.displayCategories(builderList, debugInfo)
- subs['slaves'] = self.displaySlaveLine(status, builderList, debugInfo)
- else:
- subs["categories"] = []
-
- subs['revisions'] = []
-
- # For each revision we show one line
- for revision in revisions:
- r = {}
-
- # Fill the dictionary with this new information
- r['id'] = revision.revision
- r['link'] = revision.revlink
- r['who'] = revision.who
- r['date'] = revision.date
- r['comments'] = revision.comments
- r['repository'] = revision.repository
- r['project'] = revision.project
-
- # Display the status for all builders.
- (builds, details) = self.displayStatusLine(builderList,
- allBuilds,
- revision,
- debugInfo)
- r['builds'] = builds
- r['details'] = details
-
- # Calculate the td span for the comment and the details.
- r["span"] = len(builderList) + 2
-
- subs['revisions'].append(r)
-
- #
- # Display the footer of the page.
- #
- debugInfo["load_time"] = time.time() - debugInfo["load_time"]
- return subs
-
-
- def content(self, request, cxt):
- "This method builds the main console view display."
-
- reload_time = None
- # Check if there was an arg. Don't let people reload faster than
- # every 15 seconds. 0 means no reload.
- if "reload" in request.args:
- try:
- reload_time = int(request.args["reload"][0])
- if reload_time != 0:
- reload_time = max(reload_time, 15)
- except ValueError:
- pass
-
- request.setHeader('Cache-Control', 'no-cache')
-
- # Sets the default reload time to 60 seconds.
- if not reload_time:
- reload_time = 60
-
- # Append the tag to refresh the page.
- if reload_time is not None and reload_time != 0:
- cxt['refresh'] = reload_time
-
- # Debug information to display at the end of the page.
- debugInfo = cxt['debuginfo'] = dict()
- debugInfo["load_time"] = time.time()
-
- # get url parameters
- # Categories to show information for.
- categories = request.args.get("category", [])
- # List of all builders to show on the page.
- builders = request.args.get("builder", [])
- # Repo used to filter the changes shown.
- repository = request.args.get("repository", [None])[0]
- # Project used to filter the changes shown.
- project = request.args.get("project", [None])[0]
- # Branch used to filter the changes shown.
- branch = request.args.get("branch", [ANYBRANCH])[0]
- # Codebase used to filter the changes shown.
- codebase = request.args.get("codebase", [None])[0]
- # List of all the committers name to display on the page.
- devName = request.args.get("name", [])
-
- # and the data we want to render
- status = self.getStatus(request)
-
- # Keep only the revisions we care about.
- # By default we process the last 40 revisions.
- # If a dev name is passed, we look for the changes by this person in the
- # last 80 revisions.
- numRevs = int(request.args.get("revs", [40])[0])
- if devName:
- numRevs *= 2
- numBuilds = numRevs
-
- # Get all changes we can find. This is a DB operation, so it must use
- # a deferred.
- d = self.getAllChanges(request, status, debugInfo)
- def got_changes(allChanges):
- debugInfo["source_all"] = len(allChanges)
-
- revFilter = {}
- if branch != ANYBRANCH:
- revFilter['branch'] = branch
- if devName:
- revFilter['who'] = devName
- if repository:
- revFilter['repository'] = repository
- if project:
- revFilter['project'] = project
- if codebase is not None:
- revFilter['codebase'] = codebase
- revisions = list(self.filterRevisions(allChanges, max_revs=numRevs,
- filter=revFilter))
- debugInfo["revision_final"] = len(revisions)
-
- # Fetch all the builds for all builders until we get the next build
- # after lastRevision.
- builderList = None
- allBuilds = None
- if revisions:
- lastRevision = revisions[len(revisions) - 1].revision
- debugInfo["last_revision"] = lastRevision
-
- (builderList, allBuilds) = self.getAllBuildsForRevision(status,
- request,
- codebase,
- lastRevision,
- numBuilds,
- categories,
- builders,
- debugInfo)
-
- debugInfo["added_blocks"] = 0
-
- cxt.update(self.displayPage(request, status, builderList,
- allBuilds, codebase, revisions,
- categories, repository, project,
- branch, debugInfo))
-
- templates = request.site.buildbot_service.templates
- template = templates.get_template("console.html")
- data = template.render(cxt)
- return data
- d.addCallback(got_changes)
- return d
-
-class RevisionComparator(object):
- """Used for comparing between revisions, as some
- VCS use a plain counter for revisions (like SVN)
- while others use different concepts (see Git).
- """
-
- # TODO (avivby): Should this be a zope interface?
-
- def isRevisionEarlier(self, first_change, second_change):
- """Used for comparing 2 changes"""
- raise NotImplementedError
-
- def isValidRevision(self, revision):
- """Checks whether the revision seems like a VCS revision"""
- raise NotImplementedError
-
- def getSortingKey(self):
- raise NotImplementedError
-
-class TimeRevisionComparator(RevisionComparator):
- def isRevisionEarlier(self, first, second):
- return first.when < second.when
-
- def isValidRevision(self, revision):
- return True # No general way of determining
-
- def getSortingKey(self):
- return operator.attrgetter('when')
-
-class IntegerRevisionComparator(RevisionComparator):
- def isRevisionEarlier(self, first, second):
- try:
- return int(first.revision) < int(second.revision)
- except (TypeError, ValueError):
- return False
-
- def isValidRevision(self, revision):
- try:
- int(revision)
- return True
- except:
- return False
-
- def getSortingKey(self):
- return operator.attrgetter('revision')
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/feeds.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/feeds.py
deleted file mode 100644
index f29a11ca..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/feeds.py
+++ /dev/null
@@ -1,275 +0,0 @@
-# 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
-
-# This module enables ATOM and RSS feeds from webstatus.
-#
-# It is based on "feeder.py" which was part of the Buildbot
-# configuration for the Subversion project. The original file was
-# created by Lieven Gobaerts and later adjusted by API
-# (apinheiro@igalia.coma) and also here
-# http://code.google.com/p/pybots/source/browse/trunk/master/Feeder.py
-#
-# All subsequent changes to feeder.py where made by Chandan-Dutta
-# Chowdhury <chandan-dutta.chowdhury @ hp.com> and Gareth Armstrong
-# <gareth.armstrong @ hp.com>.
-#
-# Those modifications are as follows:
-# 1) the feeds are usable from baseweb.WebStatus
-# 2) feeds are fully validated ATOM 1.0 and RSS 2.0 feeds, verified
-# with code from http://feedvalidator.org
-# 3) nicer xml output
-# 4) feeds can be filtered as per the /waterfall display with the
-# builder and category filters
-# 5) cleaned up white space and imports
-#
-# Finally, the code was directly integrated into these two files,
-# buildbot/status/web/feeds.py (you're reading it, ;-)) and
-# buildbot/status/web/baseweb.py.
-
-import os
-import re
-import time
-from twisted.web import resource
-from buildbot.status import results
-
-class XmlResource(resource.Resource):
- contentType = "text/xml; charset=UTF-8"
- docType = ''
-
- def getChild(self, name, request):
- return self
-
- def render(self, request):
- data = self.content(request)
- request.setHeader("content-type", self.contentType)
- if request.method == "HEAD":
- request.setHeader("content-length", len(data))
- return ''
- return data
-
-_abbr_day = [ 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
-_abbr_mon = ['', 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug',
- 'Sep', 'Oct', 'Nov', 'Dec']
-
-def rfc822_time(tstamp):
- res = time.strftime("%%s, %d %%s %Y %H:%M:%S GMT",
- tstamp)
- res = res % (_abbr_day[tstamp.tm_wday], _abbr_mon[tstamp.tm_mon])
- return res
-
-class FeedResource(XmlResource):
- pageTitle = None
- link = 'http://dummylink'
- language = 'en-us'
- description = 'Dummy rss'
- status = None
-
- def __init__(self, status, categories=None, pageTitle=None):
- self.status = status
- self.categories = categories
- self.pageTitle = pageTitle
- self.title = self.status.getTitle()
- self.link = self.status.getBuildbotURL()
- self.description = 'List of builds'
- self.pubdate = time.gmtime(int(time.time()))
- self.user = self.getEnv(['USER', 'USERNAME'], 'buildmaster')
- self.hostname = self.getEnv(['HOSTNAME', 'COMPUTERNAME'],
- 'buildmaster')
- self.children = {}
-
- def getEnv(self, keys, fallback):
- for key in keys:
- if key in os.environ:
- return os.environ[key]
- return fallback
-
- def getBuilds(self, request):
- builds = []
- # THIS is lifted straight from the WaterfallStatusResource Class in
- # status/web/waterfall.py
- #
- # we start with all Builders available to this Waterfall: this is
- # limited by the config-file -time categories= argument, and defaults
- # to all defined Builders.
- allBuilderNames = self.status.getBuilderNames(categories=self.categories)
- builders = [self.status.getBuilder(name) for name in allBuilderNames]
-
- # but if the URL has one or more builder= arguments (or the old show=
- # argument, which is still accepted for backwards compatibility), we
- # use that set of builders instead. We still don't show anything
- # outside the config-file time set limited by categories=.
- showBuilders = request.args.get("show", [])
- showBuilders.extend(request.args.get("builder", []))
- if showBuilders:
- builders = [b for b in builders if b.name in showBuilders]
-
- # now, if the URL has one or category= arguments, use them as a
- # filter: only show those builders which belong to one of the given
- # categories.
- showCategories = request.args.get("category", [])
- if showCategories:
- builders = [b for b in builders if b.category in showCategories]
-
- failures_only = request.args.get("failures_only", ["false"])
- failures_only = failures_only[0] not in ('false', '0', 'no', 'off')
-
- maxFeeds = 25
-
- # Copy all failed builds in a new list.
- # This could clearly be implemented much better if we had
- # access to a global list of builds.
- for b in builders:
- if failures_only:
- res = (results.FAILURE,)
- else:
- res = None
- builds.extend(b.generateFinishedBuilds(results=res, max_search=maxFeeds))
-
- # Sort build list by date, youngest first.
- # To keep compatibility with python < 2.4, use this for sorting instead:
- # We apply Decorate-Sort-Undecorate
- deco = [(build.getTimes(), build) for build in builds]
- deco.sort()
- deco.reverse()
- builds = [build for (b1, build) in deco]
-
- if builds:
- builds = builds[:min(len(builds), maxFeeds)]
- return builds
-
- def content(self, request):
- builds = self.getBuilds(request)
-
- build_cxts = []
-
- for build in builds:
- start, finished = build.getTimes()
- finishedTime = time.gmtime(int(finished))
- link = re.sub(r'index.html', "", self.status.getURLForThing(build))
-
- # title: trunk r22191 (plus patch) failed on
- # 'i686-debian-sarge1 shared gcc-3.3.5'
- ss_list = build.getSourceStamps()
- all_got_revisions = build.getAllGotRevisions()
- src_cxts = []
- for ss in ss_list:
- sc = {}
- sc['codebase'] = ss.codebase
- if (ss.branch is None and ss.revision is None and ss.patch is None
- and not ss.changes):
- sc['repository'] = None
- sc['branch'] = None
- sc['revision'] = "Latest revision"
- else:
- sc['repository'] = ss.repository
- sc['branch'] = ss.branch
- got_revision = all_got_revisions.get(ss.codebase, None)
- if got_revision:
- sc['revision'] = got_revision
- else:
- sc['revision'] = str(ss.revision)
- if ss.patch:
- sc['revision'] += " (plus patch)"
- if ss.changes:
- pass
- src_cxts.append(sc)
- res = build.getResults()
- pageTitle = ('Builder "%s": %s' %
- (build.getBuilder().getName(), results.Results[res]))
-
- # Add information about the failing steps.
- failed_steps = []
- log_lines = []
- for s in build.getSteps():
- res = s.getResults()[0]
- if res not in (results.SUCCESS, results.WARNINGS,
- results.SKIPPED):
- failed_steps.append(s.getName())
-
- # Add the last 30 lines of each log.
- for log in s.getLogs():
- log_lines.append('Last lines of build log "%s":' %
- log.getName())
- log_lines.append([])
- try:
- logdata = log.getText()
- except IOError:
- # Probably the log file has been removed
- logdata ='** log file not available **'
- unilist = list()
- for line in logdata.split('\n')[-30:]:
- unilist.append(unicode(line,'utf-8'))
- log_lines.extend(unilist)
-
- bc = {}
- bc['sources'] = src_cxts
- bc['date'] = rfc822_time(finishedTime)
- bc['summary_link'] = ('%sbuilders/%s' %
- (self.link,
- build.getBuilder().getName()))
- bc['name'] = build.getBuilder().getName()
- bc['number'] = build.getNumber()
- bc['responsible_users'] = build.getResponsibleUsers()
- bc['failed_steps'] = failed_steps
- bc['pageTitle'] = pageTitle
- bc['link'] = link
- bc['log_lines'] = log_lines
-
- if finishedTime is not None:
- bc['rfc822_pubdate'] = rfc822_time(finishedTime)
- bc['rfc3339_pubdate'] = time.strftime("%Y-%m-%dT%H:%M:%SZ",
- finishedTime)
-
- # Every RSS/Atom item must have a globally unique ID
- guid = ('tag:%s@%s,%s:%s' %
- (self.user, self.hostname,
- time.strftime("%Y-%m-%d", finishedTime),
- time.strftime("%Y%m%d%H%M%S", finishedTime)))
- bc['guid'] = guid
-
- build_cxts.append(bc)
-
- pageTitle = self.pageTitle
- if not pageTitle:
- pageTitle = 'Build status of %s' % self.title
-
- cxt = {}
- cxt['pageTitle'] = pageTitle
- cxt['title_url'] = self.link
- cxt['title'] = self.title
- cxt['language'] = self.language
- cxt['description'] = self.description
- if self.pubdate is not None:
- cxt['rfc822_pubdate'] = rfc822_time( self.pubdate)
- cxt['rfc3339_pubdate'] = time.strftime("%Y-%m-%dT%H:%M:%SZ",
- self.pubdate)
-
- cxt['builds'] = build_cxts
- template = request.site.buildbot_service.templates.get_template(self.template_file)
- return template.render(**cxt).encode('utf-8').strip()
-
-class Rss20StatusResource(FeedResource):
- # contentType = 'application/rss+xml' (browser dependent)
- template_file = 'feed_rss20.xml'
-
- def __init__(self, status, categories=None, pageTitle=None):
- FeedResource.__init__(self, status, categories, pageTitle)
-
-class Atom10StatusResource(FeedResource):
- # contentType = 'application/atom+xml' (browser dependent)
- template_file = 'feed_atom10.xml'
-
- def __init__(self, status, categories=None, pageTitle=None):
- FeedResource.__init__(self, status, categories, pageTitle)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/bg_gradient.jpg b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/bg_gradient.jpg
deleted file mode 100644
index 6c2e5ddf..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/bg_gradient.jpg
+++ /dev/null
Binary files differ
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/default.css b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/default.css
deleted file mode 100644
index d769f73a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/default.css
+++ /dev/null
@@ -1,604 +0,0 @@
-body.interface {
- margin-left: 30px;
- margin-right: 30px;
- margin-top: 20px;
- margin-bottom: 50px;
- padding: 0;
- background: url(bg_gradient.jpg) repeat-x;
- font-family: Verdana, sans-serif;
- font-size: 10px;
- background-color: #fff;
- color: #333;
-}
-
-.auth {
-position:absolute;
-top:5px;
-right:40px;
-}
-
-.alert {
- color: #c30000;
- background-color: #f2dcdc;
- padding: 5px 5px 5px 25px;
- margin-bottom: 20px;
- border-top:1px solid #ccc;
- border-bottom:1px solid #ccc;
- border-color: #c30000;
- font-size: 20px;
-}
-a:link,a:visited,a:active {
- color: #444;
-}
-
-table {
- border-spacing: 1px 1px;
-}
-
-table td {
- padding: 3px 4px 3px 4px;
- text-align: center;
-}
-
-.Project {
- min-width: 6em;
-}
-
-.LastBuild,.Activity {
- padding: 0 0 0 4px;
-}
-
-.LastBuild,.Activity,.Builder,.BuildStep {
- min-width: 5em;
-}
-
-/* Chromium Specific styles */
-div.BuildResultInfo {
- color: #444;
-}
-
-div.Announcement {
- margin-bottom: 1em;
-}
-
-div.Announcement>a:hover {
- color: black;
-}
-
-div.Announcement>div.Notice {
- background-color: #afdaff;
- padding: 0.5em;
- font-size: 16px;
- text-align: center;
-}
-
-div.Announcement>div.Open {
- border: 3px solid #8fdf5f;
- padding: 0.5em;
- font-size: 16px;
- text-align: center;
-}
-
-div.Announcement>div.Closed {
- border: 5px solid #e98080;
- padding: 0.5em;
- font-size: 24px;
- font-weight: bold;
- text-align: center;
-}
-
-td.Time {
- color: #000;
- border-bottom: 1px solid #aaa;
- background-color: #eee;
-}
-
-td.Activity,td.Change,td.Builder {
- color: #333333;
- background-color: #CCCCCC;
-}
-
-td.Change {
- border-radius: 5px;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
-}
-
-td.Event {
- color: #777;
- background-color: #ddd;
- border-radius: 5px;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
-}
-
-td.Activity {
- border-top-left-radius: 10px;
- -webkit-border-top-left-radius: 10px;
- -moz-border-radius-topleft: 10px;
- min-height: 20px;
- padding: 2px 0 2px 0;
-}
-
-td.idle,td.waiting,td.offline,td.building {
- border-top-left-radius: 0px;
- -webkit-border-top-left-radius: 0px;
- -moz-border-radius-topleft: 0px;
-}
-
-.LastBuild {
- border-top-left-radius: 5px;
- -webkit-border-top-left-radius: 5px;
- -moz-border-radius-topleft: 5px;
- border-top-right-radius: 5px;
- -webkit-border-top-right-radius: 5px;
- -moz-border-radius-topright: 5px;
-}
-
-/* Console view styles */
-td.DevRev {
- padding: 4px 8px 4px 8px;
- color: #333333;
- border-top-left-radius: 5px;
- -webkit-border-top-left-radius: 5px;
- -moz-border-radius-topleft: 5px;
- background-color: #eee;
- width: 1%;
-}
-
-td.DevRevCollapse {
- border-bottom-left-radius: 5px;
- -webkit-border-bottom-left-radius: 5px;
- -moz-border-radius-bottomleft: 5px;
-}
-
-td.DevName {
- padding: 4px 8px 4px 8px;
- color: #333333;
- background-color: #eee;
- width: 1%;
- text-align: left;
-}
-
-td.DevStatus {
- padding: 4px 4px 4px 4px;
- color: #333333;
- background-color: #eee;
-}
-
-td.DevSlave {
- padding: 4px 4px 4px 4px;
- color: #333333;
- background-color: #eee;
-}
-
-td.first {
- border-top-left-radius: 5px;
- -webkit-border-top-left-radius: 5px;
- -moz-border-radius-topleft: 5px;
-}
-
-td.last {
- border-top-right-radius: 5px;
- -webkit-border-top-right-radius: 5px;
- -moz-border-radius-topright: 5px;
-}
-
-td.DevStatusCategory {
- border-radius: 5px;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
- border-width: 1px;
- border-style: solid;
-}
-
-td.DevStatusCollapse {
- border-bottom-right-radius: 5px;
- -webkit-border-bottom-right-radius: 5px;
- -moz-border-radius-bottomright: 5px;
-}
-
-td.DevDetails {
- font-weight: normal;
- padding: 8px 8px 8px 8px;
- color: #333333;
- background-color: #eee;
- text-align: left;
-}
-
-td.DevDetails li a {
- padding-right: 5px;
-}
-
-td.DevComment {
- font-weight: normal;
- padding: 8px 8px 8px 8px;
- color: #333333;
- background-color: #eee;
- text-align: left;
-}
-
-td.DevBottom {
- border-bottom-right-radius: 5px;
- -webkit-border-bottom-right-radius: 5px;
- -moz-border-radius-bottomright: 5px;
- border-bottom-left-radius: 5px;
- -webkit-border-bottom-left-radius: 5px;
- -moz-border-radius-bottomleft: 5px;
-}
-
-td.Alt {
- background-color: #ddd;
-}
-
-.legend {
- border-radius: 5px !important;
- -webkit-border-radius: 5px !important;
- -moz-border-radius: 5px !important;
- width: 100px;
- max-width: 100px;
- text-align: center;
- padding: 2px 2px 2px 2px;
- height: 14px;
- white-space: nowrap;
-}
-
-.DevStatusBox {
- text-align: center;
- height: 20px;
- padding: 0 2px;
- line-height: 0;
- white-space: nowrap;
-}
-
-.DevStatusBox a {
- opacity: 0.85;
- border-width: 1px;
- border-style: solid;
- border-radius: 4px;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- display: block;
- width: 90%;
- height: 20px;
- line-height: 20px;
- margin-left: auto;
- margin-right: auto;
-}
-
-.DevSlaveBox {
- text-align: center;
- height: 10px;
- padding: 0 2px;
- line-height: 0;
- white-space: nowrap;
-}
-
-.DevSlaveBox a {
- opacity: 0.85;
- border-width: 1px;
- border-style: solid;
- border-radius: 4px;
- -webkit-border-radius: 4px;
- -moz-border-radius: 4px;
- display: block;
- width: 90%;
- height: 10px;
- line-height: 20px;
- margin-left: auto;
- margin-right: auto;
-}
-
-a.noround {
- border-radius: 0px;
- -webkit-border-radius: 0px;
- -moz-border-radius: 0px;
- position: relative;
- margin-top: -8px;
- margin-bottom: -8px;
- height: 36px;
- border-top-width: 0;
- border-bottom-width: 0;
-}
-
-a.begin {
- border-top-width: 1px;
- position: relative;
- margin-top: 0px;
- margin-bottom: -7px;
- height: 27px;
- border-top-left-radius: 4px;
- -webkit-border-top-left-radius: 4px;
- -moz-border-radius-topleft: 4px;
- border-top-right-radius: 4px;
- -webkit-border-top-right-radius: 4px;
- -moz-border-radius-topright: 4px;
-}
-
-a.end {
- border-bottom-width: 1px;
- position: relative;
- margin-top: -7px;
- margin-bottom: 0px;
- height: 27px;
- border-bottom-left-radius: 4px;
- -webkit-border-bottom-left-radius: 4px;
- -moz-border-radius-bottomleft: 4px;
- border-bottom-right-radius: 4px;
- -webkit-border-bottom-right-radius: 4px;
- -moz-border-radius-bottomright: 4px;
-}
-
-.center_align {
- text-align: center;
-}
-
-.right_align {
- text-align: right;
-}
-
-.left_align {
- text-align: left;
-}
-
-div.BuildWaterfall {
- border-radius: 7px;
- -webkit-border-radius: 7px;
- -moz-border-radius: 7px;
- position: absolute;
- left: 0px;
- top: 0px;
- background-color: #FFFFFF;
- padding: 4px 4px 4px 4px;
- float: left;
- display: none;
- border-width: 1px;
- border-style: solid;
-}
-
-/* LastBuild, BuildStep states */
-.success {
- color: #000;
- background-color: #8d4;
- border-color: #4F8530;
-}
-
-.failure {
- color: #000;
- background-color: #e88;
- border-color: #A77272;
-}
-
-.failure-again {
- color: #000;
- background-color: #eA9;
- border-color: #A77272;
-}
-
-.warnings {
- color: #FFFFFF;
- background-color: #fa3;
- border-color: #C29D46;
-}
-
-.skipped {
- color: #000;
- background: #AADDEE;
- border-color: #AADDEE;
-}
-
-.exception,.retry {
- color: #FFFFFF;
- background-color: #c6c;
- border-color: #ACA0B3;
-}
-
-.start {
- color: #000;
- background-color: #ccc;
- border-color: #ccc;
-}
-
-.running,.waiting,td.building {
- color: #000;
- background-color: #fd3;
- border-color: #C5C56D;
-}
-
-.paused {
- color: #FFFFFF;
- background-color: #8080FF;
- border-color: #dddddd;
-}
-
-.offline,td.offline {
- color: #FFFFFF;
- background-color: #777777;
- border-color: #dddddd;
-}
-
-
-.start {
- border-bottom-left-radius: 10px;
- -webkit-border-bottom-left-radius: 10px;
- -moz-border-radius-bottomleft: 10px;
- border-bottom-right-radius: 10px;
- -webkit-border-bottom-right-radius: 10px;
- -moz-border-radius-bottomright: 10px;
-}
-
-.notstarted {
- border-width: 1px;
- border-style: solid;
- border-color: #aaa;
- background-color: #fff;
-}
-
-.closed {
- background-color: #ff0000;
-}
-
-.closed .large {
- font-size: 1.5em;
- font-weight: bolder;
-}
-
-td.Project a:hover,td.start a:hover {
- color: #000;
-}
-
-.mini-box {
- text-align: center;
- height: 20px;
- padding: 0 2px;
- line-height: 0;
- white-space: nowrap;
-}
-
-.mini-box a {
- border-radius: 0;
- -webkit-border-radius: 0;
- -moz-border-radius: 0;
- display: block;
- width: 100%;
- height: 20px;
- line-height: 20px;
- margin-top: -30px;
-}
-
-.mini-closed {
- -box-sizing: border-box;
- -webkit-box-sizing: border-box;
- border: 4px solid red;
-}
-
-/* grid styles */
-table.Grid {
- border-collapse: collapse;
-}
-
-table.Grid tr td {
- padding: 0.2em;
- margin: 0px;
- text-align: center;
-}
-
-table.Grid tr td.title {
- font-size: 90%;
- border-right: 1px gray solid;
- border-bottom: 1px gray solid;
-}
-
-table.Grid tr td.sourcestamp {
- font-size: 90%;
-}
-
-table.Grid tr td.builder {
- text-align: right;
- font-size: 90%;
-}
-
-table.Grid tr td.build {
- border: 1px gray solid;
-}
-
-/* column container */
-div.column {
- margin: 0 2em 2em 0;
- float: left;
-}
-
-/* info tables */
-table.info {
- border-spacing: 1px;
-}
-
-table.info td {
- padding: 0.1em 1em 0.1em 1em;
- text-align: center;
-}
-
-table.info th {
- padding: 0.2em 1.5em 0.2em 1.5em;
- text-align: center;
-}
-
-table.info td.left {
- text-align: left
-}
-
-.alt {
- background-color: #f6f6f6;
-}
-
-li {
- padding: 0.1em 1em 0.1em 1em;
-}
-
-.result {
- padding: 0.3em 1em 0.3em 1em;
-}
-
-/* log view */
-.log * {
- vlink: #800080;
- font-family: "Courier New", courier, monotype, monospace;
-}
-
-span.stdout {
- color: black;
-}
-
-span.stderr {
- color: red;
-}
-
-span.header {
- color: blue;
-}
-
-/* revision & email */
-.revision .full {
- display: none;
-}
-
-.user .email {
- display: none;
-}
-
-pre {
- white-space: pre-wrap;
-}
-
-/* change comments (use regular colors here) */
-pre.comments>a:link,pre.comments>a:visited {
- color: blue;
-}
-
-pre.comments>a:active {
- color: purple;
-}
-
-form.command_forcebuild {
- border-top: 1px solid black;
- padding: .5em;
- margin: .5em;
-}
-
-form.command_forcebuild > .row {
- border-top: 1px dotted gray;
- padding: .5em 0;
-}
-
-form.command_forcebuild .force-textarea > .label {
- display: block;
-}
-
-form.command_forcebuild .force-nested > .label {
- font-weight: bold;
- display: list-item;
-}
-
-form.command_forcebuild .force-any .force-text {
- display: inline;
-}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/favicon.ico b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/favicon.ico
deleted file mode 100644
index b0b0845d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/favicon.ico
+++ /dev/null
Binary files differ
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/robots.txt b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/robots.txt
deleted file mode 100644
index 7b5fc8da..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/robots.txt
+++ /dev/null
@@ -1,11 +0,0 @@
-User-agent: *
-Disallow: /waterfall
-Disallow: /builders
-Disallow: /changes
-Disallow: /buildslaves
-Disallow: /schedulers
-Disallow: /one_line_per_build
-Disallow: /builders
-Disallow: /grid
-Disallow: /tgrid
-Disallow: /json
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/templates_readme.txt b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/templates_readme.txt
deleted file mode 100644
index 78201578..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/files/templates_readme.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-This is the directory to place customized templates for webstatus.
-
-You can find the sources for the templates used in:
-buildbot/status/web/templates
-
-You can copy any of those files to this directory, make changes, and buildbot will automatically
-use your modified templates.
-
-Also of note is that you will not need to restart/reconfig buildbot master to have these changes take effect.
-
-The syntax of the templates is Jinja2:
-http://jinja.pocoo.org/ \ No newline at end of file
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/grid.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/grid.py
deleted file mode 100644
index dc4fbd62..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/grid.py
+++ /dev/null
@@ -1,341 +0,0 @@
-# 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
-
-from twisted.internet import defer
-from buildbot.status.web.base import HtmlResource
-from buildbot.status.web.base import build_get_class, path_to_builder, path_to_build
-from buildbot.sourcestamp import SourceStamp
-
-class ANYBRANCH: pass # a flag value, used below
-
-class GridStatusMixin(object):
- def getPageTitle(self, request):
- status = self.getStatus(request)
- p = status.getTitle()
- if p:
- return "BuildBot: %s" % p
- else:
- return "BuildBot"
-
- # handle reloads through an http header
- # TODO: send this as a real header, rather than a tag
- def get_reload_time(self, request):
- if "reload" in request.args:
- try:
- reload_time = int(request.args["reload"][0])
- return max(reload_time, 15)
- except ValueError:
- pass
- return None
-
- def build_cxt(self, request, build):
- if not build:
- return {}
-
- if build.isFinished():
- # get the text and annotate the first line with a link
- text = build.getText()
- if not text: text = [ "(no information)" ]
- if text == [ "build", "successful" ]: text = [ "OK" ]
- else:
- text = [ 'building' ]
-
- name = build.getBuilder().getName()
-
- cxt = {}
- cxt['name'] = name
- cxt['got_revision'] = build.getProperty("got_revision")
- cxt['DEST'] = build.getProperty("DEST")
- cxt['url'] = path_to_build(request, build)
- cxt['text'] = text
- cxt['class'] = build_get_class(build)
-
- if build.getProperty("repourl_poky"):
- if build.getProperty("repourl_poky") == "git://git.yoctoproject.org/poky":
- cxt['repository'] = "poky"
- cxt['cgiturl'] = "http://git.yoctoproject.org/cgit/cgit.cgi/poky/commit/?h="
- elif "git://git.yoctoproject.org/poky-contrib" in build.getProperty("repourl_poky"):
- cxt['repository'] = "poky-contrib"
- cxt['cgiturl'] = "http://git.yoctoproject.org/cgit/cgit.cgi/poky-contrib/commit/?h="
- else:
- cxt['repository'] = build.getProperty("repourl_poky")
-
- if build.getProperty("branch_poky"):
- if build.getProperty("branch_poky") == "stage/master_under_test":
- cxt['branchshortname']="mut"
- else:
- cxt['branchshortname']=build.getProperty("branch_poky")
- cxt['branch'] = build.getProperty("branch_poky")
- if 'cgiturl' in cxt and 'got_revision' in cxt and cxt['cgiturl'] is not None and cxt['got_revision'] is not None:
- cxt['cgiturl'] = cxt['cgiturl'] + build.getProperty("branch_poky") + "&id=" + cxt['got_revision']
- if build.getProperty("custom_release_name_nightly"):
- cxt['release_name'] = build.getProperty("custom_release_name_nightly")
- else:
- cxt['commit_desc'] = build.getProperty("commit-description")
-
- return cxt
-
- @defer.inlineCallbacks
- def builder_cxt(self, request, builder):
- state, builds = builder.getState()
-
- # look for upcoming builds. We say the state is "waiting" if the
- # builder is otherwise idle and there is a scheduler which tells us a
- # build will be performed some time in the near future. TODO: this
- # functionality used to be in BuilderStatus.. maybe this code should
- # be merged back into it.
- upcoming = []
- builderName = builder.getName()
- for s in self.getStatus(request).getSchedulers():
- if builderName in s.listBuilderNames():
- upcoming.extend(s.getPendingBuildTimes())
- if state == "idle" and upcoming:
- state = "waiting"
-
- n_pending = len((yield builder.getPendingBuildRequestStatuses()))
-
- cxt = { 'url': path_to_builder(request, builder),
- 'name': builder.getName(),
- 'state': state,
- 'n_pending': n_pending }
-
- defer.returnValue(cxt)
-
- def getSourceStampKey(self, sourcestamps):
- """Given two source stamps, we want to assign them to the same row if
- they are the same version of code, even if they differ in minor detail.
-
- This function returns an appropriate comparison key for that.
- """
- # TODO: Maybe order sourcestamps in key by codebases names?
- return tuple([(ss.branch, ss.revision, ss.patch) for ss in sourcestamps])
-
- def clearRecentBuildsCache(self):
- self.__recentBuildsCache__ = {}
-
- def getRecentBuilds(self, builder, numBuilds, branch):
- cache = getattr(self, '__recentBuildsCache__', {})
- key = (builder.getName(), branch, numBuilds)
- try:
- return cache[key]
- except KeyError:
- # cache miss, get the value and store it in the cache
- result = [b for b in self.__getRecentBuilds(builder, numBuilds, branch)]
- cache[key] = result
- return result
-
- def __getRecentBuilds(self, builder, numBuilds, branch):
- """
- get a list of most recent builds on given builder
- """
- build = builder.getBuild(-1)
- num = 0
- while build and num < numBuilds:
- start = build.getTimes()[0]
- #TODO: support multiple sourcestamps
- ss = build.getSourceStamps(absolute=True)[0]
-
- okay_build = True
-
- # skip un-started builds
- if not start:
- okay_build = False
-
- # skip non-matching branches
- if branch != ANYBRANCH and ss.branch != branch:
- okay_build = False
-
- if okay_build:
- num += 1
- yield build
-
- build = build.getPreviousBuild()
- return
-
- def getRecentSourcestamps(self, status, numBuilds, categories, branch):
- """
- get a list of the most recent NUMBUILDS SourceStamp tuples, sorted
- by the earliest start we've seen for them
- """
- # TODO: use baseweb's getLastNBuilds?
- sourcestamps = { } # { ss-tuple : earliest time }
- for bn in status.getBuilderNames():
- builder = status.getBuilder(bn)
- if categories and builder.category not in categories:
- continue
- for build in self.getRecentBuilds(builder, numBuilds, branch):
- ss = build.getSourceStamps(absolute=True)
- key = self.getSourceStampKey(ss)
- start = min(x for x in build.getTimes() if x is not None)
- if key not in sourcestamps or sourcestamps[key][1] > start:
- sourcestamps[key] = (ss, start)
-
- # now sort those and take the NUMBUILDS most recent
- sourcestamps = sorted(sourcestamps.itervalues(), key = lambda stamp: stamp[1])
- sourcestamps = [stamp[0] for stamp in sourcestamps][-numBuilds:]
-
- return sourcestamps
-
-class GridStatusResource(HtmlResource, GridStatusMixin):
- # TODO: docs
- status = None
- changemaster = None
-
- @defer.inlineCallbacks
- def content(self, request, cxt):
- """This method builds the regular grid display.
- That is, build stamps across the top, build hosts down the left side
- """
-
- # get url parameters
- numBuilds = int(request.args.get("width", [5])[0])
- categories = request.args.get("category", [])
- branch = request.args.get("branch", [ANYBRANCH])[0]
- if branch == 'trunk': branch = None
-
- # and the data we want to render
- status = self.getStatus(request)
- stamps = self.getRecentSourcestamps(status, numBuilds, categories, branch)
-
- cxt['refresh'] = self.get_reload_time(request)
-
- cxt.update({'categories': categories,
- 'branch': branch,
- 'ANYBRANCH': ANYBRANCH,
- 'stamps': [map(SourceStamp.asDict, sstamp) for sstamp in stamps],
- })
- sortedBuilderNames = sorted(status.getBuilderNames())
-
- cxt['builders'] = []
- cxt['build_triggers'] = build_triggers = []
- cxt['range'] = range(len(stamps))
-
- # For each sstamp we want to know the name of the builder which
- # triggered the builds and the buildid of that builder. We'll keep
- # that in a list of dicts which align with the stamps objects list.
- for _ in range(len(stamps)):
- build_triggers.append({'builder': '', 'id': ''})
-
- for bn in sortedBuilderNames:
- builds = [None] * len(stamps)
-
- builder = status.getBuilder(bn)
- if categories and builder.category not in categories:
- continue
-
- for build in self.getRecentBuilds(builder, numBuilds, branch):
- ss = build.getSourceStamps(absolute=True)
- key = self.getSourceStampKey(ss)
-
- for i, sstamp in enumerate(stamps):
- if key == self.getSourceStampKey(sstamp) and builds[i] is None:
- builds[i] = build
- if build_triggers[i].get('builder', None) != 'nightly':
- build_triggers[i]['builder'] = bn
- build_triggers[i]['id'] = str(build.getNumber())
-
- b = yield self.builder_cxt(request, builder)
-
- b['builds'] = []
- for build in builds:
- b['builds'].append(self.build_cxt(request, build))
-
- cxt['builders'].append(b)
-
- self.clearRecentBuildsCache()
- template = request.site.buildbot_service.templates.get_template("grid.html")
- defer.returnValue(template.render(**cxt))
-
-
-class TransposedGridStatusResource(HtmlResource, GridStatusMixin):
- # TODO: docs
- status = None
- changemaster = None
- default_rev_order = "desc"
-
- @defer.inlineCallbacks
- def content(self, request, cxt):
- """This method builds the transposed grid display.
- That is, build hosts across the top, build stamps down the left side
- """
-
- # get url parameters
- numBuilds = int(request.args.get("length", [5])[0])
- categories = request.args.get("category", [])
- branch = request.args.get("branch", [ANYBRANCH])[0]
- if branch == 'trunk': branch = None
-
- rev_order = request.args.get("rev_order", [self.default_rev_order])[0]
- if rev_order not in ["asc", "desc"]:
- rev_order = self.default_rev_order
-
- cxt['refresh'] = self.get_reload_time(request)
-
- # and the data we want to render
- status = self.getStatus(request)
- stamps = self.getRecentSourcestamps(status, numBuilds, categories, branch)
-
- cxt.update({'categories': categories,
- 'branch': branch,
- 'ANYBRANCH': ANYBRANCH,
- 'stamps': [map(SourceStamp.asDict, sstamp) for sstamp in stamps],
- })
-
- sortedBuilderNames = sorted(status.getBuilderNames())
-
- cxt['sorted_builder_names'] = sortedBuilderNames
- cxt['builder_builds'] = builder_builds = []
- cxt['builders'] = builders = []
- cxt['build_triggers'] = build_triggers = []
- cxt['range'] = range(len(stamps))
- if rev_order == "desc":
- cxt['range'].reverse()
-
- # For each sstamp we want to know the name of the builder which
- # triggered the builds and the buildid of that builder. We'll keep
- # that in a list of dicts which align with the stamps objects list.
- for _ in range(len(stamps)):
- build_triggers.append({'builder': '', 'id': ''})
-
- for bn in sortedBuilderNames:
- builds = [None] * len(stamps)
-
- builder = status.getBuilder(bn)
- if categories and builder.category not in categories:
- continue
-
- for build in self.getRecentBuilds(builder, numBuilds, branch):
- #TODO: support multiple sourcestamps
- ss = build.getSourceStamps(absolute=True)
- key = self.getSourceStampKey(ss)
-
- for i, sstamp in enumerate(stamps):
- if key == self.getSourceStampKey(sstamp) and builds[i] is None:
- builds[i] = build
- # At this point we know that there's a build for the sstamp by this builder
- # update the corresponding dict in the build_triggers list with the builder
- # name and buildid unless 'nightly' is already set as the builder name.
- if build_triggers[i].get('builder', None) != 'nightly':
- build_triggers[i]['builder'] = bn
- build_triggers[i]['id'] = str(build.getNumber())
-
- b = yield self.builder_cxt(request, builder)
- builders.append(b)
-
- builder_builds.append(map(lambda b: self.build_cxt(request, b), builds))
-
- self.clearRecentBuildsCache()
- template = request.site.buildbot_service.templates.get_template('grid_transposed.html')
- defer.returnValue(template.render(**cxt))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/__init__.py
deleted file mode 100644
index 00bcb6e3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-# test \ No newline at end of file
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/base.py
deleted file mode 100644
index 3980e8f9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/base.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# 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
-
-# code inspired/copied from contrib/github_buildbot
-# and inspired from code from the Chromium project
-# otherwise, Andrew Melo <andrew.melo@gmail.com> wrote the rest
-# but "the rest" is pretty minimal
-
-from buildbot.util import json
-
-def getChanges(request, options=None):
- """
- Consumes a naive build notification (the default for now)
- basically, set POST variables to match commit object parameters:
- revision, revlink, comments, branch, who, files, links
-
- files, links and properties will be de-json'd, the rest are interpreted as strings
- """
-
- def firstOrNothing( value ):
- """
- Small helper function to return the first value (if value is a list)
- or return the whole thing otherwise
- """
- if ( type(value) == type([])):
- return value[0]
- else:
- return value
-
- args = request.args
-
- # first, convert files, links and properties
- files = None
- if args.get('files'):
- files = json.loads( args.get('files')[0] )
- else:
- files = []
-
- properties = None
- if args.get('properties'):
- properties = json.loads( args.get('properties')[0] )
- else:
- properties = {}
-
- revision = firstOrNothing(args.get('revision'))
- when = firstOrNothing(args.get('when'))
- if when is not None:
- when = float(when)
- author = firstOrNothing(args.get('author'))
- if not author:
- author = firstOrNothing(args.get('who'))
- comments = firstOrNothing(args.get('comments'))
- isdir = firstOrNothing(args.get('isdir',0))
- branch = firstOrNothing(args.get('branch'))
- category = firstOrNothing(args.get('category'))
- revlink = firstOrNothing(args.get('revlink'))
- repository = firstOrNothing(args.get('repository'))
- project = firstOrNothing(args.get('project'))
-
- chdict = dict(author=author, files=files, comments=comments,
- isdir=isdir, revision=revision, when=when,
- branch=branch, category=category, revlink=revlink,
- properties=properties, repository=repository,
- project=project)
- return ([ chdict ], None)
-
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/github.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/github.py
deleted file mode 100644
index 2ff05f12..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/github.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# 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
-
-#!/usr/bin/env python
-"""
-github_buildbot.py is based on git_buildbot.py
-
-github_buildbot.py will determine the repository information from the JSON
-HTTP POST it receives from github.com and build the appropriate repository.
-If your github repository is private, you must add a ssh key to the github
-repository for the user who initiated the build on the buildslave.
-
-"""
-
-import re
-import datetime
-from twisted.python import log
-import calendar
-
-try:
- import json
- assert json
-except ImportError:
- import simplejson as json
-
-# python is silly about how it handles timezones
-class fixedOffset(datetime.tzinfo):
- """
- fixed offset timezone
- """
- def __init__(self, minutes, hours, offsetSign = 1):
- self.minutes = int(minutes) * offsetSign
- self.hours = int(hours) * offsetSign
- self.offset = datetime.timedelta(minutes = self.minutes,
- hours = self.hours)
-
- def utcoffset(self, dt):
- return self.offset
-
- def dst(self, dt):
- return datetime.timedelta(0)
-
-def convertTime(myTestTimestamp):
- #"1970-01-01T00:00:00+00:00"
- matcher = re.compile(r'(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)([-+])(\d\d):(\d\d)')
- result = matcher.match(myTestTimestamp)
- (year, month, day, hour, minute, second, offsetsign, houroffset, minoffset) = \
- result.groups()
- if offsetsign == '+':
- offsetsign = 1
- else:
- offsetsign = -1
-
- offsetTimezone = fixedOffset( minoffset, houroffset, offsetsign )
- myDatetime = datetime.datetime( int(year),
- int(month),
- int(day),
- int(hour),
- int(minute),
- int(second),
- 0,
- offsetTimezone)
- return calendar.timegm( myDatetime.utctimetuple() )
-
-def getChanges(request, options = None):
- """
- Reponds only to POST events and starts the build process
-
- :arguments:
- request
- the http request object
- """
- payload = json.loads(request.args['payload'][0])
- user = payload['repository']['owner']['name']
- repo = payload['repository']['name']
- repo_url = payload['repository']['url']
- project = request.args.get('project', None)
- if project:
- project = project[0]
- elif project is None:
- project = ''
- # This field is unused:
- #private = payload['repository']['private']
- changes = process_change(payload, user, repo, repo_url, project)
- log.msg("Received %s changes from github" % len(changes))
- return (changes, 'git')
-
-def process_change(payload, user, repo, repo_url, project):
- """
- Consumes the JSON as a python object and actually starts the build.
-
- :arguments:
- payload
- Python Object that represents the JSON sent by GitHub Service
- Hook.
- """
- changes = []
- newrev = payload['after']
- refname = payload['ref']
-
- # We only care about regular heads, i.e. branches
- match = re.match(r"^refs\/heads\/(.+)$", refname)
- if not match:
- log.msg("Ignoring refname `%s': Not a branch" % refname)
- return []
-
- branch = match.group(1)
- if re.match(r"^0*$", newrev):
- log.msg("Branch `%s' deleted, ignoring" % branch)
- return []
- else:
- for commit in payload['commits']:
- files = []
- if 'added' in commit:
- files.extend(commit['added'])
- if 'modified' in commit:
- files.extend(commit['modified'])
- if 'removed' in commit:
- files.extend(commit['removed'])
- when = convertTime( commit['timestamp'])
- log.msg("New revision: %s" % commit['id'][:8])
- chdict = dict(
- who = commit['author']['name']
- + " <" + commit['author']['email'] + ">",
- files = files,
- comments = commit['message'],
- revision = commit['id'],
- when = when,
- branch = branch,
- revlink = commit['url'],
- repository = repo_url,
- project = project)
- changes.append(chdict)
- return changes
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/googlecode.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/googlecode.py
deleted file mode 100644
index f40cf174..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/googlecode.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# 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 2011, Louis Opter <kalessin@kalessin.fr>
-
-# Quite inspired from the github hook.
-
-import hmac
-from twisted.python import log
-from buildbot.util import json
-
-class GoogleCodeAuthFailed(Exception):
- pass
-
-class Payload(object):
- def __init__(self, headers, body, branch):
- self._auth_code = headers['Google-Code-Project-Hosting-Hook-Hmac']
- self._body = body # we need to save it if we want to authenticate it
- self._branch = branch
-
- payload = json.loads(body)
- self.project = payload['project_name']
- self.repository = payload['repository_path']
- self.revisions = payload['revisions']
- self.revision_count = payload['revision_count']
-
- def authenticate(self, secret_key):
- m = hmac.new(secret_key)
- m.update(self._body)
- digest = m.hexdigest()
- return digest == self._auth_code
-
- def changes(self):
- changes = []
-
- for r in self.revisions:
- files = set()
- files.update(r['added'])
- files.update(r['modified'])
- files.update(r['removed'])
- changes.append(dict(
- author=r['author'],
- files=list(files),
- comments=r['message'],
- revision=r['revision'],
- when=r['timestamp'],
- # Let's hope Google add the branch one day:
- branch=r.get('branch', self._branch),
- revlink=r['url'],
- repository=self.repository,
- project=self.project
- ))
-
- return changes
-
-def getChanges(request, options=None):
- headers = request.received_headers
- body = request.content.getvalue()
-
- # Instantiate a Payload object: this will parse the body, get the
- # authentication code from the headers and remember the branch picked
- # up by the user (Google Code doesn't send on which branch the changes
- # were made)
- payload = Payload(headers, body, options.get('branch', 'default'))
-
- if 'secret_key' in options:
- if not payload.authenticate(options['secret_key']):
- raise GoogleCodeAuthFailed()
- else:
- log.msg("Missing secret_key in the Google Code WebHook options: "
- "cannot authenticate the request!")
-
- log.msg('Received %d changes from Google Code' %
- (payload.revision_count,))
- changes = payload.changes()
-
- return changes, 'Google Code'
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/poller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/poller.py
deleted file mode 100644
index 1ac29a4f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/hooks/poller.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# 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
-
-# This change hook allows GitHub or a hand crafted curl inovcation to "knock on
-# the door" and trigger a change source to poll.
-
-from buildbot.changes.base import PollingChangeSource
-
-
-def getChanges(req, options=None):
- change_svc = req.site.buildbot_service.master.change_svc
- poll_all = not "poller" in req.args
-
- allow_all = True
- allowed = []
- if isinstance(options, dict) and "allowed" in options:
- allow_all = False
- allowed = options["allowed"]
-
- pollers = []
-
- for source in change_svc:
- if not isinstance(source, PollingChangeSource):
- continue
- if not hasattr(source, "name"):
- continue
- if not poll_all and not source.name in req.args['poller']:
- continue
- if not allow_all and not source.name in allowed:
- continue
- pollers.append(source)
-
- if not poll_all:
- missing = set(req.args['poller']) - set(s.name for s in pollers)
- if missing:
- raise ValueError("Could not find pollers: %s" % ",".join(missing))
-
- for p in pollers:
- p.doPoll()
-
- return [], None
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/logs.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/logs.py
deleted file mode 100644
index d7da8111..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/logs.py
+++ /dev/null
@@ -1,177 +0,0 @@
-# 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
-
-
-from zope.interface import implements
-from twisted.python import components
-from twisted.spread import pb
-from twisted.web import server
-from twisted.web.resource import Resource, NoResource
-
-from buildbot import interfaces
-from buildbot.status import logfile
-from buildbot.status.web.base import IHTMLLog, HtmlResource, path_to_root
-
-class ChunkConsumer:
- implements(interfaces.IStatusLogConsumer)
-
- def __init__(self, original, textlog):
- self.original = original
- self.textlog = textlog
- def registerProducer(self, producer, streaming):
- self.producer = producer
- self.original.registerProducer(producer, streaming)
- def unregisterProducer(self):
- self.original.unregisterProducer()
- def writeChunk(self, chunk):
- formatted = self.textlog.content([chunk])
- try:
- if isinstance(formatted, unicode):
- formatted = formatted.encode('utf-8')
- self.original.write(formatted)
- except pb.DeadReferenceError:
- self.producing.stopProducing()
- def finish(self):
- self.textlog.finished()
-
-
-# /builders/$builder/builds/$buildnum/steps/$stepname/logs/$logname
-class TextLog(Resource):
- # a new instance of this Resource is created for each client who views
- # it, so we can afford to track the request in the Resource.
- implements(IHTMLLog)
-
- asText = False
- subscribed = False
-
- def __init__(self, original):
- Resource.__init__(self)
- self.original = original
-
- def getChild(self, path, req):
- if path == "text":
- self.asText = True
- return self
- return Resource.getChild(self, path, req)
-
- def content(self, entries):
- html_entries = []
- text_data = ''
- for type, entry in entries:
- if type >= len(logfile.ChunkTypes) or type < 0:
- # non-std channel, don't display
- continue
-
- is_header = type == logfile.HEADER
-
- if not self.asText:
- # jinja only works with unicode, or pure ascii, so assume utf-8 in logs
- if not isinstance(entry, unicode):
- entry = unicode(entry, 'utf-8', 'replace')
- html_entries.append(dict(type = logfile.ChunkTypes[type],
- text = entry,
- is_header = is_header))
- elif not is_header:
- text_data += entry
-
- if self.asText:
- return text_data
- else:
- return self.template.module.chunks(html_entries)
-
- def render_HEAD(self, req):
- self._setContentType(req)
-
- # vague approximation, ignores markup
- req.setHeader("content-length", self.original.length)
- return ''
-
- def render_GET(self, req):
- self._setContentType(req)
- self.req = req
-
- if self.original.isFinished():
- req.setHeader("Cache-Control", "max-age=604800")
- else:
- req.setHeader("Cache-Control", "no-cache")
-
- if not self.asText:
- self.template = req.site.buildbot_service.templates.get_template("logs.html")
-
- data = self.template.module.page_header(
- pageTitle = "Log File contents",
- texturl = req.childLink("text"),
- path_to_root = path_to_root(req))
- data = data.encode('utf-8')
- req.write(data)
-
- self.original.subscribeConsumer(ChunkConsumer(req, self))
- return server.NOT_DONE_YET
-
- def _setContentType(self, req):
- if self.asText:
- req.setHeader("content-type", "text/plain; charset=utf-8")
- else:
- req.setHeader("content-type", "text/html; charset=utf-8")
-
- def finished(self):
- if not self.req:
- return
- try:
- if not self.asText:
- data = self.template.module.page_footer()
- data = data.encode('utf-8')
- self.req.write(data)
- self.req.finish()
- except pb.DeadReferenceError:
- pass
- # break the cycle, the Request's .notifications list includes the
- # Deferred (from req.notifyFinish) that's pointing at us.
- self.req = None
-
- # release template
- self.template = None
-
-components.registerAdapter(TextLog, interfaces.IStatusLog, IHTMLLog)
-
-
-class HTMLLog(Resource):
- implements(IHTMLLog)
-
- def __init__(self, original):
- Resource.__init__(self)
- self.original = original
-
- def render(self, request):
- request.setHeader("content-type", "text/html")
- return self.original.html
-
-components.registerAdapter(HTMLLog, logfile.HTMLLogFile, IHTMLLog)
-
-
-class LogsResource(HtmlResource):
- addSlash = True
-
- def __init__(self, step_status):
- HtmlResource.__init__(self)
- self.step_status = step_status
-
- def getChild(self, path, req):
- for log in self.step_status.getLogs():
- if path == log.getName():
- if log.hasContents():
- return IHTMLLog(interfaces.IStatusLog(log))
- return NoResource("Empty Log '%s'" % path)
- return HtmlResource.getChild(self, path, req)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/olpb.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/olpb.py
deleted file mode 100644
index 1bfd647c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/olpb.py
+++ /dev/null
@@ -1,118 +0,0 @@
-# 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
-
-
-from buildbot.status.web.base import HtmlResource, BuildLineMixin, map_branches
-
-# /one_line_per_build
-# accepts builder=, branch=, numbuilds=, reload=
-class OneLinePerBuild(HtmlResource, BuildLineMixin):
- """This shows one line per build, combining all builders together. Useful
- query arguments:
-
- numbuilds=: how many lines to display
- builder=: show only builds for this builder. Multiple builder= arguments
- can be used to see builds from any builder in the set.
- reload=: reload the page after this many seconds
- """
-
- pageTitle = "Recent Builds"
-
- def __init__(self, numbuilds=20):
- HtmlResource.__init__(self)
- self.numbuilds = numbuilds
-
- def getChild(self, path, req):
- status = self.getStatus(req)
- builder = status.getBuilder(path)
- return OneLinePerBuildOneBuilder(builder, numbuilds=self.numbuilds)
-
- def get_reload_time(self, request):
- if "reload" in request.args:
- try:
- reload_time = int(request.args["reload"][0])
- return max(reload_time, 15)
- except ValueError:
- pass
- return None
-
- def content(self, req, cxt):
- status = self.getStatus(req)
- numbuilds = int(req.args.get("numbuilds", [self.numbuilds])[0])
- builders = req.args.get("builder", [])
- branches = [b for b in req.args.get("branch", []) if b]
-
- g = status.generateFinishedBuilds(builders, map_branches(branches),
- numbuilds, max_search=numbuilds)
-
- cxt['refresh'] = self.get_reload_time(req)
- cxt['num_builds'] = numbuilds
- cxt['branches'] = branches
- cxt['builders'] = builders
-
- builds = cxt['builds'] = []
- for build in g:
- builds.append(self.get_line_values(req, build))
-
- cxt['authz'] = self.getAuthz(req)
-
- # get information on the builders - mostly just a count
- building = 0
- online = 0
- for bn in builders:
- builder = status.getBuilder(bn)
- builder_status = builder.getState()[0]
- if builder_status == "building":
- building += 1
- online += 1
- elif builder_status != "offline":
- online += 1
-
- cxt['num_online'] = online
- cxt['num_building'] = building
-
- template = req.site.buildbot_service.templates.get_template('onelineperbuild.html')
- return template.render(**cxt)
-
-
-
-# /one_line_per_build/$BUILDERNAME
-# accepts branch=, numbuilds=
-
-class OneLinePerBuildOneBuilder(HtmlResource, BuildLineMixin):
- def __init__(self, builder, numbuilds=20):
- HtmlResource.__init__(self)
- self.builder = builder
- self.builder_name = builder.getName()
- self.numbuilds = numbuilds
- self.pageTitle = "Recent Builds of %s" % self.builder_name
-
- def content(self, req, cxt):
- numbuilds = int(req.args.get("numbuilds", [self.numbuilds])[0])
- branches = [b for b in req.args.get("branch", []) if b]
-
- # walk backwards through all builds of a single builder
- g = self.builder.generateFinishedBuilds(map_branches(branches),
- numbuilds)
-
- cxt['builds'] = map(lambda b: self.get_line_values(req, b), g)
- cxt.update(dict(num_builds=numbuilds,
- builder_name=self.builder_name,
- branches=branches))
-
- template = req.site.buildbot_service.templates.get_template('onelineperbuildonebuilder.html')
- return template.render(**cxt)
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/root.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/root.py
deleted file mode 100644
index 01a926ed..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/root.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# 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
-
-from twisted.web.util import redirectTo
-from twisted.internet import defer
-
-from buildbot.status.web.base import HtmlResource, path_to_authzfail
-from buildbot.util.eventual import eventually
-
-class RootPage(HtmlResource):
- pageTitle = "Buildbot"
-
- @defer.inlineCallbacks
- def content(self, request, cxt):
- status = self.getStatus(request)
-
- res = yield self.getAuthz(request).actionAllowed("cleanShutdown",
- request)
-
- if request.path == '/shutdown':
- if res:
- eventually(status.cleanShutdown)
- defer.returnValue(redirectTo("/", request))
- return
- else:
- defer.returnValue(
- redirectTo(path_to_authzfail(request), request))
- return
- elif request.path == '/cancel_shutdown':
- if res:
- eventually(status.cancelCleanShutdown)
- defer.returnValue(redirectTo("/", request))
- return
- else:
- defer.returnValue(
- redirectTo(path_to_authzfail(request), request))
- return
-
- cxt.update(
- shutting_down = status.shuttingDown,
- shutdown_url = request.childLink("shutdown"),
- cancel_shutdown_url = request.childLink("cancel_shutdown"),
- )
- template = request.site.buildbot_service.templates.get_template("root.html")
- defer.returnValue(template.render(**cxt))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/session.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/session.py
deleted file mode 100644
index 35c0ad24..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/session.py
+++ /dev/null
@@ -1,121 +0,0 @@
-# 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
-#
-# Insipration, and some code, from:
-# :copyright: (c) 2011 by the Werkzeug Team, see Werkzeug's AUTHORS for more
-# details.
-
-try:
- from hashlib import sha1
- sha1 = sha1 # make pyflakes happy
-except ImportError:
- from sha import new as sha1
-from time import time
-from random import random
-from datetime import datetime, timedelta
-import os
-def _urandom():
- if hasattr(os, 'urandom'):
- return os.urandom(30)
- return random()
-
-def generate_cookie():
- return sha1('%s%s' % (time(), _urandom())).hexdigest()
-
-
-class Session(object):
- """I'm a user's session. Contains information about a user's session
- a user can have several session
- a session is associated with a cookie
- """
- user = ""
- infos = {}
- def __init__(self, user, infos):
- self.user = user
- self.infos = infos
- self.renew()
-
- def renew(self):
- # one day expiration. hardcoded for now...
- self.expiration = datetime.now()+ timedelta(1)
- return self.expiration
-
- def expired(self):
- return datetime.now() > self.expiration
-
- def userInfosHTML(self):
- return ('%(fullName)s [<a href="mailto:%(email)s">%(email)s</a>]' %
- (self.infos))
-
- def getExpiration(self):
- delim = '-'
- d = self.expiration.utctimetuple()
- return '%s, %02d%s%s%s%s %02d:%02d:%02d GMT' % (
- ('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun')[d.tm_wday],
- d.tm_mday, delim,
- ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',
- 'Oct', 'Nov', 'Dec')[d.tm_mon - 1],
- delim, str(d.tm_year), d.tm_hour, d.tm_min, d.tm_sec
- )
-
-class SessionManager(object):
- """I'm the session manager. Holding the current sessions
- managing cookies, and their expiration
-
- KISS version for the moment:
-
- The sessions are stored in RAM so that you have to relogin after buildbot
- reboot
-
- Old sessions are searched at every connection, which is not very good for
- scaling
-
- """
-
- # borg pattern (similar to singleton) not too loose sessions with reconfig
- __shared_state = dict(sessions={},users={})
-
- def __init__(self):
- self.__dict__ = self.__shared_state
-
- def new(self, user, infos):
- cookie = generate_cookie()
- user = infos["userName"]
- self.users[user] = self.sessions[cookie] = s = Session(user, infos)
- return cookie, s
-
- def gc(self):
- """remove old cookies"""
- expired = []
- for cookie in self.sessions:
- s = self.sessions[cookie]
- if s.expired():
- expired.append(cookie)
- for cookie in expired:
- del self.sessions[cookie]
-
- def get(self, cookie):
- self.gc()
- if cookie in self.sessions:
- return self.sessions[cookie]
- return None
-
- def remove(self, cookie):
- if cookie in self.sessions:
- del self.sessions[cookie]
-
- def getUser(self, user):
- return self.users.get(user)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/slaves.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/slaves.py
deleted file mode 100644
index 323b5463..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/slaves.py
+++ /dev/null
@@ -1,203 +0,0 @@
-# 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 time, urllib
-from twisted.web import html
-from twisted.web.util import Redirect
-from twisted.web.resource import NoResource
-from twisted.internet import defer
-
-from buildbot.status.web.base import HtmlResource, abbreviate_age, \
- BuildLineMixin, ActionResource, path_to_slave, path_to_authzfail
-from buildbot import util
-
-class ShutdownActionResource(ActionResource):
-
- def __init__(self, slave):
- self.slave = slave
- self.action = "gracefulShutdown"
-
- @defer.inlineCallbacks
- def performAction(self, request):
- res = yield self.getAuthz(request).actionAllowed(self.action,
- request,
- self.slave)
-
- url = None
- if res:
- self.slave.setGraceful(True)
- url = path_to_slave(request, self.slave)
- else:
- url = path_to_authzfail(request)
- defer.returnValue(url)
-
-class PauseActionResource(ActionResource):
-
- def __init__(self, slave, state):
- self.slave = slave
- self.action = "pauseSlave"
- self.state = state
-
- @defer.inlineCallbacks
- def performAction(self, request):
- res = yield self.getAuthz(request).actionAllowed(self.action,
- request,
- self.slave)
-
- url = None
- if res:
- self.slave.setPaused(self.state)
- url = path_to_slave(request, self.slave)
- else:
- url = path_to_authzfail(request)
- defer.returnValue(url)
-
-# /buildslaves/$slavename
-class OneBuildSlaveResource(HtmlResource, BuildLineMixin):
- addSlash = False
- def __init__(self, slavename):
- HtmlResource.__init__(self)
- self.slavename = slavename
-
- def getPageTitle(self, req):
- return "Buildbot: %s" % self.slavename
-
- def getChild(self, path, req):
- s = self.getStatus(req)
- slave = s.getSlave(self.slavename)
- if path == "shutdown":
- return ShutdownActionResource(slave)
- if path == "pause" or path == "unpause":
- return PauseActionResource(slave, path == "pause")
- return Redirect(path_to_slave(req, slave))
-
- def content(self, request, ctx):
- s = self.getStatus(request)
- slave = s.getSlave(self.slavename)
-
- my_builders = []
- for bname in s.getBuilderNames():
- b = s.getBuilder(bname)
- for bs in b.getSlaves():
- if bs.getName() == self.slavename:
- my_builders.append(b)
-
- # Current builds
- current_builds = []
- for b in my_builders:
- for cb in b.getCurrentBuilds():
- if cb.getSlavename() == self.slavename:
- current_builds.append(self.get_line_values(request, cb))
-
- try:
- max_builds = int(request.args.get('numbuilds')[0])
- except:
- max_builds = 10
-
- recent_builds = []
- n = 0
- for rb in s.generateFinishedBuilds(builders=[b.getName() for b in my_builders]):
- if rb.getSlavename() == self.slavename:
- n += 1
- recent_builds.append(self.get_line_values(request, rb))
- if n > max_builds:
- break
-
- # connects over the last hour
- slave = s.getSlave(self.slavename)
- connect_count = slave.getConnectCount()
-
- if slave.isPaused():
- pause_url = request.childLink("unpause")
- else:
- pause_url = request.childLink("pause")
-
- ctx.update(dict(slave=slave,
- slavename = self.slavename,
- current = current_builds,
- recent = recent_builds,
- shutdown_url = request.childLink("shutdown"),
- pause_url = pause_url,
- authz = self.getAuthz(request),
- this_url = "../../../" + path_to_slave(request, slave),
- access_uri = slave.getAccessURI()),
- admin = unicode(slave.getAdmin() or '', 'utf-8'),
- host = unicode(slave.getHost() or '', 'utf-8'),
- slave_version = slave.getVersion(),
- show_builder_column = True,
- connect_count = connect_count)
- template = request.site.buildbot_service.templates.get_template("buildslave.html")
- data = template.render(**ctx)
- return data
-
-# /buildslaves
-class BuildSlavesResource(HtmlResource):
- pageTitle = "BuildSlaves"
- addSlash = True
-
- def content(self, request, ctx):
- s = self.getStatus(request)
-
- #?no_builders=1 disables build column
- show_builder_column = not (request.args.get('no_builders', '0')[0])=='1'
- ctx['show_builder_column'] = show_builder_column
-
- used_by_builder = {}
- for bname in s.getBuilderNames():
- b = s.getBuilder(bname)
- for bs in b.getSlaves():
- slavename = bs.getName()
- if slavename not in used_by_builder:
- used_by_builder[slavename] = []
- used_by_builder[slavename].append(bname)
-
- slaves = ctx['slaves'] = []
- for name in util.naturalSort(s.getSlaveNames()):
- info = {}
- slaves.append(info)
- slave = s.getSlave(name)
- slave_status = s.botmaster.slaves[name].slave_status
- info['running_builds'] = len(slave_status.getRunningBuilds())
- info['link'] = request.childLink(urllib.quote(name,''))
- info['name'] = name
-
- if show_builder_column:
- info['builders'] = []
- for b in used_by_builder.get(name, []):
- info['builders'].append(dict(link=request.childLink("../builders/%s" % b), name=b))
-
- info['version'] = slave.getVersion()
- info['connected'] = slave.isConnected()
- info['connectCount'] = slave.getConnectCount()
- info['paused'] = slave.isPaused()
-
- info['admin'] = unicode(slave.getAdmin() or '', 'utf-8')
- last = slave.lastMessageReceived()
- if last:
- info['last_heard_from_age'] = abbreviate_age(time.time() - last)
- info['last_heard_from_time'] = time.strftime("%Y-%b-%d %H:%M:%S",
- time.localtime(last))
-
- template = request.site.buildbot_service.templates.get_template("buildslaves.html")
- data = template.render(**ctx)
- return data
-
- def getChild(self, path, req):
- try:
- self.getStatus(req).getSlave(path)
- return OneBuildSlaveResource(path)
- except KeyError:
- return NoResource("No such slave '%s'" % html.escape(path))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/status_json.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/status_json.py
deleted file mode 100644
index a725a35d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/status_json.py
+++ /dev/null
@@ -1,741 +0,0 @@
-# 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.
-#
-# Portions Copyright Buildbot Team Members
-# Original Copyright (c) 2010 The Chromium Authors.
-
-"""Simple JSON exporter."""
-
-import datetime
-import os
-import re
-
-from twisted.internet import defer
-from twisted.web import html, resource, server
-
-from buildbot.status.web.base import HtmlResource
-from buildbot.util import json
-
-
-_IS_INT = re.compile('^[-+]?\d+$')
-
-
-FLAGS = """\
- - as_text
- - By default, application/json is used. Setting as_text=1 change the type
- to text/plain and implicitly sets compact=0 and filter=1. Mainly useful to
- look at the result in a web browser.
- - compact
- - By default, the json data is compact and defaults to 1. For easier to read
- indented output, set compact=0.
- - select
- - By default, most children data is listed. You can do a random selection
- of data by using select=<sub-url> multiple times to coagulate data.
- "select=" includes the actual url otherwise it is skipped.
- - numbuilds
- - By default, only in memory cached builds are listed. You can as for more data
- by using numbuilds=<number>.
- - filter
- - Filters out null, false, and empty string, list and dict. This reduce the
- amount of useless data sent.
- - callback
- - Enable uses of JSONP as described in
- http://en.wikipedia.org/wiki/JSONP. Note that
- Access-Control-Allow-Origin:* is set in the HTTP response header so you
- can use this in compatible browsers.
-"""
-
-EXAMPLES = """\
- - /json
- - Root node, that *doesn't* mean all the data. Many things (like logs) must
- be explicitly queried for performance reasons.
- - /json/builders/
- - All builders.
- - /json/builders/<A_BUILDER>
- - A specific builder as compact text.
- - /json/builders/<A_BUILDER>/builds
- - All *cached* builds.
- - /json/builders/<A_BUILDER>/builds/_all
- - All builds. Warning, reads all previous build data.
- - /json/builders/<A_BUILDER>/builds/<A_BUILD>
- - Where <A_BUILD> is either positive, a build number, or negative, a past
- build.
- - /json/builders/<A_BUILDER>/builds/-1/source_stamp/changes
- - Build changes
- - /json/builders/<A_BUILDER>/builds?select=-1&select=-2
- - Two last builds on '<A_BUILDER>' builder.
- - /json/builders/<A_BUILDER>/builds?select=-1/source_stamp/changes&select=-2/source_stamp/changes
- - Changes of the two last builds on '<A_BUILDER>' builder.
- - /json/builders/<A_BUILDER>/slaves
- - Slaves associated to this builder.
- - /json/builders/<A_BUILDER>?select=&select=slaves
- - Builder information plus details information about its slaves. Neat eh?
- - /json/slaves/<A_SLAVE>
- - A specific slave.
- - /json?select=slaves/<A_SLAVE>/&select=project&select=builders/<A_BUILDER>/builds/<A_BUILD>
- - A selection of random unrelated stuff as an random example. :)
-"""
-
-
-def RequestArg(request, arg, default):
- return request.args.get(arg, [default])[0]
-
-
-def RequestArgToBool(request, arg, default):
- value = RequestArg(request, arg, default)
- if value in (False, True):
- return value
- value = value.lower()
- if value in ('1', 'true'):
- return True
- if value in ('0', 'false'):
- return False
- # Ignore value.
- return default
-
-
-def FilterOut(data):
- """Returns a copy with None, False, "", [], () and {} removed.
- Warning: converts tuple to list."""
- if isinstance(data, (list, tuple)):
- # Recurse in every items and filter them out.
- items = map(FilterOut, data)
- if not filter(lambda x: not x in ('', False, None, [], {}, ()), items):
- return None
- return items
- elif isinstance(data, dict):
- return dict(filter(lambda x: not x[1] in ('', False, None, [], {}, ()),
- [(k, FilterOut(v)) for (k, v) in data.iteritems()]))
- else:
- return data
-
-
-class JsonResource(resource.Resource):
- """Base class for json data."""
-
- contentType = "application/json"
- cache_seconds = 60
- help = None
- pageTitle = None
- level = 0
-
- def __init__(self, status):
- """Adds transparent lazy-child initialization."""
- resource.Resource.__init__(self)
- # buildbot.status.builder.Status
- self.status = status
-
- def getChildWithDefault(self, path, request):
- """Adds transparent support for url ending with /"""
- if path == "" and len(request.postpath) == 0:
- return self
- if path == 'help' and self.help:
- pageTitle = ''
- if self.pageTitle:
- pageTitle = self.pageTitle + ' help'
- return HelpResource(self.help,
- pageTitle=pageTitle,
- parent_node=self)
- # Equivalent to resource.Resource.getChildWithDefault()
- if self.children.has_key(path):
- return self.children[path]
- return self.getChild(path, request)
-
- def putChild(self, name, res):
- """Adds the resource's level for help links generation."""
-
- def RecurseFix(res, level):
- res.level = level + 1
- for c in res.children.itervalues():
- RecurseFix(c, res.level)
-
- RecurseFix(res, self.level)
- resource.Resource.putChild(self, name, res)
-
- def render_GET(self, request):
- """Renders a HTTP GET at the http request level."""
- d = defer.maybeDeferred(lambda : self.content(request))
- def handle(data):
- if isinstance(data, unicode):
- data = data.encode("utf-8")
- request.setHeader("Access-Control-Allow-Origin", "*")
- if RequestArgToBool(request, 'as_text', False):
- request.setHeader("content-type", 'text/plain')
- else:
- request.setHeader("content-type", self.contentType)
- request.setHeader("content-disposition",
- "attachment; filename=\"%s.json\"" % request.path)
- # Make sure we get fresh pages.
- if self.cache_seconds:
- now = datetime.datetime.utcnow()
- expires = now + datetime.timedelta(seconds=self.cache_seconds)
- request.setHeader("Expires",
- expires.strftime("%a, %d %b %Y %H:%M:%S GMT"))
- request.setHeader("Pragma", "no-cache")
- return data
- d.addCallback(handle)
- def ok(data):
- request.write(data)
- request.finish()
- def fail(f):
- request.processingFailed(f)
- return None # processingFailed will log this for us
- d.addCallbacks(ok, fail)
- return server.NOT_DONE_YET
-
- @defer.inlineCallbacks
- def content(self, request):
- """Renders the json dictionaries."""
- # Supported flags.
- select = request.args.get('select')
- as_text = RequestArgToBool(request, 'as_text', False)
- filter_out = RequestArgToBool(request, 'filter', as_text)
- compact = RequestArgToBool(request, 'compact', not as_text)
- callback = request.args.get('callback')
-
- # Implement filtering at global level and every child.
- if select is not None:
- del request.args['select']
- # Do not render self.asDict()!
- data = {}
- # Remove superfluous /
- select = [s.strip('/') for s in select]
- select.sort(cmp=lambda x,y: cmp(x.count('/'), y.count('/')),
- reverse=True)
- for item in select:
- # Start back at root.
- node = data
- # Implementation similar to twisted.web.resource.getChildForRequest
- # but with a hacked up request.
- child = self
- prepath = request.prepath[:]
- postpath = request.postpath[:]
- request.postpath = filter(None, item.split('/'))
- while request.postpath and not child.isLeaf:
- pathElement = request.postpath.pop(0)
- node[pathElement] = {}
- node = node[pathElement]
- request.prepath.append(pathElement)
- child = child.getChildWithDefault(pathElement, request)
-
- # some asDict methods return a Deferred, so handle that
- # properly
- if hasattr(child, 'asDict'):
- child_dict = yield defer.maybeDeferred(lambda :
- child.asDict(request))
- else:
- child_dict = {
- 'error' : 'Not available',
- }
- node.update(child_dict)
-
- request.prepath = prepath
- request.postpath = postpath
- else:
- data = yield defer.maybeDeferred(lambda : self.asDict(request))
-
- if filter_out:
- data = FilterOut(data)
- if compact:
- data = json.dumps(data, sort_keys=True, separators=(',',':'))
- else:
- data = json.dumps(data, sort_keys=True, indent=2)
- if callback:
- # Only accept things that look like identifiers for now
- callback = callback[0]
- if re.match(r'^[a-zA-Z$][a-zA-Z$0-9.]*$', callback):
- data = '%s(%s);' % (callback, data)
- defer.returnValue(data)
-
- @defer.inlineCallbacks
- def asDict(self, request):
- """Generates the json dictionary.
-
- By default, renders every childs."""
- if self.children:
- data = {}
- for name in self.children:
- child = self.getChildWithDefault(name, request)
- if isinstance(child, JsonResource):
- data[name] = yield defer.maybeDeferred(lambda :
- child.asDict(request))
- # else silently pass over non-json resources.
- defer.returnValue(data)
- else:
- raise NotImplementedError()
-
-
-def ToHtml(text):
- """Convert a string in a wiki-style format into HTML."""
- indent = 0
- in_item = False
- output = []
- for line in text.splitlines(False):
- match = re.match(r'^( +)\- (.*)$', line)
- if match:
- if indent < len(match.group(1)):
- output.append('<ul>')
- indent = len(match.group(1))
- elif indent > len(match.group(1)):
- while indent > len(match.group(1)):
- output.append('</ul>')
- indent -= 2
- if in_item:
- # Close previous item
- output.append('</li>')
- output.append('<li>')
- in_item = True
- line = match.group(2)
- elif indent:
- if line.startswith((' ' * indent) + ' '):
- # List continuation
- line = line.strip()
- else:
- # List is done
- if in_item:
- output.append('</li>')
- in_item = False
- while indent > 0:
- output.append('</ul>')
- indent -= 2
-
- if line.startswith('/'):
- if not '?' in line:
- line_full = line + '?as_text=1'
- else:
- line_full = line + '&as_text=1'
- output.append('<a href="' + html.escape(line_full) + '">' +
- html.escape(line) + '</a>')
- else:
- output.append(html.escape(line).replace(' ', '&nbsp;&nbsp;'))
- if not in_item:
- output.append('<br>')
-
- if in_item:
- output.append('</li>')
- while indent > 0:
- output.append('</ul>')
- indent -= 2
- return '\n'.join(output)
-
-
-class HelpResource(HtmlResource):
- def __init__(self, text, pageTitle, parent_node):
- HtmlResource.__init__(self)
- self.text = text
- self.pageTitle = pageTitle
- self.parent_level = parent_node.level
- self.parent_children = parent_node.children.keys()
-
- def content(self, request, cxt):
- cxt['level'] = self.parent_level
- cxt['text'] = ToHtml(self.text)
- cxt['children'] = [ n for n in self.parent_children if n != 'help' ]
- cxt['flags'] = ToHtml(FLAGS)
- cxt['examples'] = ToHtml(EXAMPLES).replace(
- 'href="/json',
- 'href="../%sjson' % (self.parent_level * '../'))
-
- template = request.site.buildbot_service.templates.get_template("jsonhelp.html")
- return template.render(**cxt)
-
-class BuilderPendingBuildsJsonResource(JsonResource):
- help = """Describe pending builds for a builder.
-"""
- pageTitle = 'Builder'
-
- def __init__(self, status, builder_status):
- JsonResource.__init__(self, status)
- self.builder_status = builder_status
-
- def asDict(self, request):
- # buildbot.status.builder.BuilderStatus
- d = self.builder_status.getPendingBuildRequestStatuses()
- def to_dict(statuses):
- return defer.gatherResults(
- [ b.asDict_async() for b in statuses ])
- d.addCallback(to_dict)
- return d
-
-
-class BuilderJsonResource(JsonResource):
- help = """Describe a single builder.
-"""
- pageTitle = 'Builder'
-
- def __init__(self, status, builder_status):
- JsonResource.__init__(self, status)
- self.builder_status = builder_status
- self.putChild('builds', BuildsJsonResource(status, builder_status))
- self.putChild('slaves', BuilderSlavesJsonResources(status,
- builder_status))
- self.putChild(
- 'pendingBuilds',
- BuilderPendingBuildsJsonResource(status, builder_status))
-
- def asDict(self, request):
- # buildbot.status.builder.BuilderStatus
- return self.builder_status.asDict_async()
-
-
-class BuildersJsonResource(JsonResource):
- help = """List of all the builders defined on a master.
-"""
- pageTitle = 'Builders'
-
- def __init__(self, status):
- JsonResource.__init__(self, status)
- for builder_name in self.status.getBuilderNames():
- self.putChild(builder_name,
- BuilderJsonResource(status,
- status.getBuilder(builder_name)))
-
-
-class BuilderSlavesJsonResources(JsonResource):
- help = """Describe the slaves attached to a single builder.
-"""
- pageTitle = 'BuilderSlaves'
-
- def __init__(self, status, builder_status):
- JsonResource.__init__(self, status)
- self.builder_status = builder_status
- for slave_name in self.builder_status.slavenames:
- self.putChild(slave_name,
- SlaveJsonResource(status,
- self.status.getSlave(slave_name)))
-
-
-class BuildJsonResource(JsonResource):
- help = """Describe a single build.
-"""
- pageTitle = 'Build'
-
- def __init__(self, status, build_status):
- JsonResource.__init__(self, status)
- self.build_status = build_status
- # TODO: support multiple sourcestamps
- sourcestamp = build_status.getSourceStamps()[0]
- self.putChild('source_stamp',
- SourceStampJsonResource(status, sourcestamp))
- self.putChild('steps', BuildStepsJsonResource(status, build_status))
-
- def asDict(self, request):
- return self.build_status.asDict()
-
-
-class AllBuildsJsonResource(JsonResource):
- help = """All the builds that were run on a builder.
-"""
- pageTitle = 'AllBuilds'
-
- def __init__(self, status, builder_status):
- JsonResource.__init__(self, status)
- self.builder_status = builder_status
-
- def getChild(self, path, request):
- # Dynamic childs.
- if isinstance(path, int) or _IS_INT.match(path):
- build_status = self.builder_status.getBuild(int(path))
- if build_status:
- return BuildJsonResource(self.status, build_status)
- return JsonResource.getChild(self, path, request)
-
- def asDict(self, request):
- results = {}
- # If max > buildCacheSize, it'll trash the cache...
- cache_size = self.builder_status.master.config.caches['Builds']
- max = int(RequestArg(request, 'max', cache_size))
- for i in range(0, max):
- child = self.getChildWithDefault(-i, request)
- if not isinstance(child, BuildJsonResource):
- continue
- results[child.build_status.getNumber()] = child.asDict(request)
- return results
-
-
-class BuildsJsonResource(AllBuildsJsonResource):
- help = """Builds that were run on a builder.
-"""
- pageTitle = 'Builds'
-
- def __init__(self, status, builder_status):
- AllBuildsJsonResource.__init__(self, status, builder_status)
- self.putChild('_all', AllBuildsJsonResource(status, builder_status))
-
- def getChild(self, path, request):
- # Transparently redirects to _all if path is not ''.
- return self.children['_all'].getChildWithDefault(path, request)
-
- def asDict(self, request):
- # This would load all the pickles and is way too heavy, especially that
- # it would trash the cache:
- # self.children['builds'].asDict(request)
- # TODO(maruel) This list should also need to be cached but how?
- builds = dict([
- (int(file), None)
- for file in os.listdir(self.builder_status.basedir)
- if _IS_INT.match(file)
- ])
- return builds
-
-
-class BuildStepJsonResource(JsonResource):
- help = """A single build step.
-"""
- pageTitle = 'BuildStep'
-
- def __init__(self, status, build_step_status):
- # buildbot.status.buildstep.BuildStepStatus
- JsonResource.__init__(self, status)
- self.build_step_status = build_step_status
- # TODO self.putChild('logs', LogsJsonResource())
-
- def asDict(self, request):
- return self.build_step_status.asDict()
-
-
-class BuildStepsJsonResource(JsonResource):
- help = """A list of build steps that occurred during a build.
-"""
- pageTitle = 'BuildSteps'
-
- def __init__(self, status, build_status):
- JsonResource.__init__(self, status)
- self.build_status = build_status
- # The build steps are constantly changing until the build is done so
- # keep a reference to build_status instead
-
- def getChild(self, path, request):
- # Dynamic childs.
- build_step_status = None
- if isinstance(path, int) or _IS_INT.match(path):
- build_step_status = self.build_status.getSteps()[int(path)]
- else:
- steps_dict = dict([(step.getName(), step)
- for step in self.build_status.getSteps()])
- build_step_status = steps_dict.get(path)
- if build_step_status:
- # Create it on-demand.
- child = BuildStepJsonResource(self.status, build_step_status)
- # Cache it.
- index = self.build_status.getSteps().index(build_step_status)
- self.putChild(str(index), child)
- self.putChild(build_step_status.getName(), child)
- return child
- return JsonResource.getChild(self, path, request)
-
- def asDict(self, request):
- # Only use the number and not the names!
- results = {}
- index = 0
- for step in self.build_status.getSteps():
- results[index] = step.asDict()
- index += 1
- return results
-
-
-class ChangeJsonResource(JsonResource):
- help = """Describe a single change that originates from a change source.
-"""
- pageTitle = 'Change'
-
- def __init__(self, status, change):
- # buildbot.changes.changes.Change
- JsonResource.__init__(self, status)
- self.change = change
-
- def asDict(self, request):
- return self.change.asDict()
-
-
-class ChangesJsonResource(JsonResource):
- help = """List of changes.
-"""
- pageTitle = 'Changes'
-
- def __init__(self, status, changes):
- JsonResource.__init__(self, status)
- for c in changes:
- # c.number can be None or clash another change if the change was
- # generated inside buildbot or if using multiple pollers.
- if c.number is not None and str(c.number) not in self.children:
- self.putChild(str(c.number), ChangeJsonResource(status, c))
- else:
- # Temporary hack since it creates information exposure.
- self.putChild(str(id(c)), ChangeJsonResource(status, c))
-
- def asDict(self, request):
- """Don't throw an exception when there is no child."""
- if not self.children:
- return {}
- return JsonResource.asDict(self, request)
-
-
-class ChangeSourcesJsonResource(JsonResource):
- help = """Describe a change source.
-"""
- pageTitle = 'ChangeSources'
-
- def asDict(self, request):
- result = {}
- n = 0
- for c in self.status.getChangeSources():
- # buildbot.changes.changes.ChangeMaster
- change = {}
- change['description'] = c.describe()
- result[n] = change
- n += 1
- return result
-
-
-class ProjectJsonResource(JsonResource):
- help = """Project-wide settings.
-"""
- pageTitle = 'Project'
-
- def asDict(self, request):
- return self.status.asDict()
-
-
-class SlaveJsonResource(JsonResource):
- help = """Describe a slave.
-"""
- pageTitle = 'Slave'
-
- def __init__(self, status, slave_status):
- JsonResource.__init__(self, status)
- self.slave_status = slave_status
- self.name = self.slave_status.getName()
- self.builders = None
-
- def getBuilders(self):
- if self.builders is None:
- # Figure out all the builders to which it's attached
- self.builders = []
- for builderName in self.status.getBuilderNames():
- if self.name in self.status.getBuilder(builderName).slavenames:
- self.builders.append(builderName)
- return self.builders
-
- def asDict(self, request):
- results = self.slave_status.asDict()
- # Enhance it by adding more informations.
- results['builders'] = {}
- for builderName in self.getBuilders():
- builds = []
- builder_status = self.status.getBuilder(builderName)
- cache_size = builder_status.master.config.caches['Builds']
- numbuilds = int(request.args.get('numbuilds', [cache_size - 1])[0])
- for i in range(1, numbuilds):
- build_status = builder_status.getBuild(-i)
- if not build_status or not build_status.isFinished():
- # If not finished, it will appear in runningBuilds.
- break
- if build_status.getSlavename() == self.name:
- builds.append(build_status.getNumber())
- results['builders'][builderName] = builds
- return results
-
-
-class SlavesJsonResource(JsonResource):
- help = """List the registered slaves.
-"""
- pageTitle = 'Slaves'
-
- def __init__(self, status):
- JsonResource.__init__(self, status)
- for slave_name in status.getSlaveNames():
- self.putChild(slave_name,
- SlaveJsonResource(status,
- status.getSlave(slave_name)))
-
-
-class SourceStampJsonResource(JsonResource):
- help = """Describe the sources for a SourceStamp.
-"""
- pageTitle = 'SourceStamp'
-
- def __init__(self, status, source_stamp):
- # buildbot.sourcestamp.SourceStamp
- JsonResource.__init__(self, status)
- self.source_stamp = source_stamp
- self.putChild('changes',
- ChangesJsonResource(status, source_stamp.changes))
- # TODO(maruel): Should redirect to the patch's url instead.
- #if source_stamp.patch:
- # self.putChild('patch', StaticHTML(source_stamp.path))
-
- def asDict(self, request):
- return self.source_stamp.asDict()
-
-class MetricsJsonResource(JsonResource):
- help = """Master metrics.
-"""
- title = "Metrics"
-
- def asDict(self, request):
- metrics = self.status.getMetrics()
- if metrics:
- return metrics.asDict()
- else:
- # Metrics are disabled
- return None
-
-
-
-class JsonStatusResource(JsonResource):
- """Retrieves all json data."""
- help = """JSON status
-
-Root page to give a fair amount of information in the current buildbot master
-status. You may want to use a child instead to reduce the load on the server.
-
-For help on any sub directory, use url /child/help
-"""
- pageTitle = 'Buildbot JSON'
-
- def __init__(self, status):
- JsonResource.__init__(self, status)
- self.level = 1
- self.putChild('builders', BuildersJsonResource(status))
- self.putChild('change_sources', ChangeSourcesJsonResource(status))
- self.putChild('project', ProjectJsonResource(status))
- self.putChild('slaves', SlavesJsonResource(status))
- self.putChild('metrics', MetricsJsonResource(status))
- # This needs to be called before the first HelpResource().body call.
- self.hackExamples()
-
- def content(self, request):
- result = JsonResource.content(self, request)
- # This is done to hook the downloaded filename.
- request.path = 'buildbot'
- return result
-
- def hackExamples(self):
- global EXAMPLES
- # Find the first builder with a previous build or select the last one.
- builder = None
- for b in self.status.getBuilderNames():
- builder = self.status.getBuilder(b)
- if builder.getBuild(-1):
- break
- if not builder:
- return
- EXAMPLES = EXAMPLES.replace('<A_BUILDER>', builder.getName())
- build = builder.getBuild(-1)
- if build:
- EXAMPLES = EXAMPLES.replace('<A_BUILD>', str(build.getNumber()))
- if builder.slavenames:
- EXAMPLES = EXAMPLES.replace('<A_SLAVE>', builder.slavenames[0])
-
-# vim: set ts=4 sts=4 sw=4 et:
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/step.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/step.py
deleted file mode 100644
index 138fa3cc..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/step.py
+++ /dev/null
@@ -1,96 +0,0 @@
-# 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 urllib
-from buildbot.status.web.base import HtmlResource, path_to_builder, \
- path_to_build, css_classes
-from buildbot.status.web.logs import LogsResource
-from buildbot import util
-from time import ctime
-
-# /builders/$builder/builds/$buildnum/steps/$stepname
-class StatusResourceBuildStep(HtmlResource):
- pageTitle = "Build Step"
- addSlash = True
-
- def __init__(self, build_status, step_status):
- HtmlResource.__init__(self)
- self.status = build_status
- self.step_status = step_status
-
- def content(self, req, cxt):
- s = self.step_status
- b = s.getBuild()
-
- logs = cxt['logs'] = []
- for l in s.getLogs():
- # FIXME: If the step name has a / in it, this is broken
- # either way. If we quote it but say '/'s are safe,
- # it chops up the step name. If we quote it and '/'s
- # are not safe, it escapes the / that separates the
- # step name from the log number.
- logs.append({'has_contents': l.hasContents(),
- 'name': l.getName(),
- 'link': req.childLink("logs/%s" % urllib.quote(l.getName())) })
-
- stepStatistics = s.getStatistics()
- statistics = cxt['statistics'] = []
- for stat in stepStatistics:
- statistics.append({'name': stat, 'value': stepStatistics[stat]})
-
- start, end = s.getTimes()
-
- if start:
- cxt['start'] = ctime(start)
- if end:
- cxt['end'] = ctime(end)
- cxt['elapsed'] = util.formatInterval(end - start)
- else:
- cxt['end'] = "Not Finished"
- cxt['elapsed'] = util.formatInterval(util.now() - start)
-
- cxt.update(dict(builder_link = path_to_builder(req, b.getBuilder()),
- build_link = path_to_build(req, b),
- b = b,
- s = s,
- result_css = css_classes[s.getResults()[0]]))
-
- template = req.site.buildbot_service.templates.get_template("buildstep.html");
- return template.render(**cxt)
-
- def getChild(self, path, req):
- if path == "logs":
- return LogsResource(self.step_status)
- return HtmlResource.getChild(self, path, req)
-
-
-
-# /builders/$builder/builds/$buildnum/steps
-class StepsResource(HtmlResource):
- addSlash = True
-
- def __init__(self, build_status):
- HtmlResource.__init__(self)
- self.build_status = build_status
-
- def content(self, req, ctx):
- return "subpages show data for each step"
-
- def getChild(self, path, req):
- for s in self.build_status.getSteps():
- if s.getName() == path:
- return StatusResourceBuildStep(self.build_status, s)
- return HtmlResource.getChild(self, path, req)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/about.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/about.html
deleted file mode 100644
index f7b799a2..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/about.html
+++ /dev/null
@@ -1,32 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>About this Buildbot</h1>
-
-<div class="column">
-
-<h2>Version Information</h2>
-<ul>
-{% set item_class=cycler('alt', '') %}
-
- <li class="{{ item_class.next() }}">Buildbot: {{ buildbot }}</li>
- <li class="{{ item_class.next() }}">Twisted: {{ twisted }}</li>
- <li class="{{ item_class.next() }}">Jinja: {{ jinja }}</li>
- <li class="{{ item_class.next() }}">Python: {{ python }}</li>
- <li class="{{ item_class.next() }}">Buildmaster platform: {{ platform }}</li>
-
-</ul>
-
-<h2>Source code</h2>
-
-<p>Buildbot is a free software project, released under the terms of the
-<a href="http://www.gnu.org/licenses/gpl.html">GNU GPL</a>.</p>
-
-<p>Please visit the <a href="http://buildbot.net/">Buildbot Home Page</a> for
-more information, including documentation, bug reports, and source
-downloads.</p>
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/authfail.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/authfail.html
deleted file mode 100644
index bae600f7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/authfail.html
+++ /dev/null
@@ -1,11 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>Authentication Failed</h1>
-
-<p>The username or password you entered were not correct.
- Please go back and try again.
-</p>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/authzfail.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/authzfail.html
deleted file mode 100644
index e2bfcd99..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/authzfail.html
+++ /dev/null
@@ -1,10 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>Authorization Failed</h1>
-
-<p>You are not allowed to perform this action.
-</p>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/box_macros.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/box_macros.html
deleted file mode 100644
index ec5b80b6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/box_macros.html
+++ /dev/null
@@ -1,37 +0,0 @@
-{% macro box(text=[], comment=None) -%}
-
-{%- if comment -%}<!-- {{ comment }} -->{%- endif -%}
- <td class="{{ kwargs.class or kwargs.class_ or "" }}"
- {%- for prop in ("align", "colspan", "rowspan", "border", "valign", "halign") -%}
- {%- if prop in kwargs %} {{ prop }}="{{ kwargs[prop] }}"{% endif -%}
- {%- endfor -%}>
-
- {%- if text is string -%}
- {{ text }}
- {%- else -%}
- {{- text|join("<br/>") -}}
- {%- endif -%}
- </td>
-{% endmacro %}
-
-{# this is currently just the text part of the boxes #}
-
-{% macro build_box(reason, url, number) -%}
- <a title="Reason: {{ reason|e }}" href="{{ url }}">Build {{ number }}</a>
-{%- endmacro %}
-
-{% macro step_box(text, logs, urls, stepinfo) -%}
- {%- if text is string -%}
- {{ text }}
- {%- else -%}
- {{- text|join("<br/>") -}}
- {%- endif -%}
- <br/>
- {%- for l in logs %}
- <a {% if l.url %}href="{{ l.url }}"{% endif %}>{{ l.name|e }}</a><br/>
- {%- endfor -%}
-
- {%- for u in urls %}
- [<a href="{{ u.link }}" class="BuildStep external">{{ u.name|e }}</a>]<br/>
- {%- endfor -%}
-{%- endmacro %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/build.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/build.html
deleted file mode 100644
index 0f508880..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/build.html
+++ /dev/null
@@ -1,238 +0,0 @@
-{% extends "layout.html" %}
-{% import 'forms.html' as forms %}
-{% from "change_macros.html" import change with context %}
-
-{% block content %}
-
-<h1>
-Builder <a href="{{ path_to_builder }}">{{ b.getBuilder().getName() }}</a>
-Build #{{ b.getNumber() }}
-</h1>
-
-<div class="column">
-
-{% if not b.isFinished() %}
- <h2>Build In Progress:</h2>
-
- {% if when_time %}
- <p>ETA: {{ when_time }} [{{ when }}]</p>
- {% endif %}
-
- {{ current_step }}
-
- {% if authz.advertiseAction('stopBuild', request) %}
- <h2>Stop Build</h2>
- {{ forms.stop_build(build_url+"/stop", authz, on_all=False, short=False, label='This Build') }}
- {% endif %}
-{% else %}
- <h2>Results:</h2>
-
- <p class="{{ result_css }} result">
- {{ b.getText()|join(' ')|capitalize }}
- </p>
-
- {% if b.getTestResults() %}
- <h3><a href="{{ tests_link }}"/></h3>
- {% endif %}
-{% endif %}
-
-<h2>
-{% if sourcestamps|count == 1 %}
-SourceStamp:
-{% else %}
-SourceStamps:
-{% endif %}
-</h2>
-
-{% for ss in sourcestamps %}
-<h3>{{ ss.codebase }}</h3>
- <table class="info" width="100%">
- {% set ss_class = cycler('alt','') %}
-
- {% if ss.project %}
- <tr class="{{ ss_class.next() }}"><td class="left">Project</td><td>{{ ss.project|projectlink }}</td></tr>
- {% endif %}
-
- {% if ss.repository %}
- <tr class="{{ ss_class.next() }}"><td class="left">Repository</td><td>{{ ss.repository|repolink }}</td></tr>
- {% endif %}
-
- {% if ss.branch %}
- <tr class="{{ ss_class.next() }}"><td class="left">Branch</td><td>{{ ss.branch|e }}</td></tr>
- {% endif %}
-
- {% if ss.revision %}
- <tr class="{{ ss_class.next() }}"><td class="left">Revision</td><td>{{ ss.revision|revlink(ss.repository) }}</td></tr>
- {% endif %}
-
- {% if got_revisions[ss.codebase] %}
- <tr class="{{ ss_class.next() }}"><td class="left">Got Revision</td><td>{{ got_revisions[ss.codebase]|revlink(ss.repository) }}</td></tr>
- {% endif %}
-
- {% if ss.patch %}
- <tr class="{{ ss_class.next() }}"><td class="left">Patch</td><td>YES</td></tr>
- {% endif %}
-
- {% if ss.changes %}
- <tr class="{{ ss_class.next() }}"><td class="left">Changes</td><td><a href="#changes-{{ ss.codebase }}">{{ ss.changes|count }} change{{ 's' if ss.changes|count > 1 else '' }}</a></td></tr>
- {% endif %}
-
- {% if not ss.branch and not ss.revision and not ss.patch and not ss.changes %}
- <tr class="{{ ss_class.next() }}"><td class="left" colspan="2">Build of most recent revision</td></tr>
- {% endif %}
- </table>
-{% endfor %}
-
-{#
- # TODO: turn this into a table, or some other sort of definition-list
- # that doesn't take up quite so much vertical space
- #}
-
-<h2>BuildSlave:</h2>
-
-{% if slave_url %}
- <a href="{{ slave_url|e }}">{{ b.getSlavename()|e }}</a>
-{% else %}
- {{ b.getSlavename()|e }}
-{% endif %}
-
-<h2>Reason:</h2>
-<p>
-{{ b.getReason()|e }}
-</p>
-
-<h2>Steps and Logfiles:</h2>
-
-{#
- # TODO:
- # urls = self.original.getURLs()
- # ex_url_class = "BuildStep external"
- # for name, target in urls.items():
- # text.append('[<a href="%s" class="%s">%s</a>]' %
- # (target, ex_url_class, html.escape(name)))
- #}
-
-<ol>
-{% for s in steps %}
- <li>
- <div class="{{ s.css_class }} result">
- <a href="{{ s.link }}">{{ s.name }}</a>
- {{ s.text }}&nbsp;<span style="float:right">{{ '( ' + s.time_to_run + ' )' if s.time_to_run else '' }}</span>
- </div>
-
- <ol>
- {% set item_class = cycler('alt', '') %}
- {% for l in s.logs %}
- <li class="{{ item_class.next() }}"><a href="{{ l.link }}">{{ l.name }}</a></li>
- {% else %}
- <li class="{{ item_class.next() }}">- no logs -</li>
- {% endfor %}
-
- {% for u in s.urls %}
- <li class="{{ item_class.next() }}"><a href="{{ u.url }}">{{ u.logname }}</a></li>
- {% endfor %}
- </ol>
- </li>
-{% endfor %}
-</ol>
-
-</div>
-<div class="column">
-
-<h2>Build Properties:</h2>
-
-<table class="info" width="100%">
-<tr><th>Name</th><th>Value</th><th>Source</th></tr>
-
-{% for p in properties %}
-{% if p.source != "Force Build Form" %}
- <tr class="{{ loop.cycle('alt', '') }}">
- <td class="left">{{ p.name|e }}</td>
- {% if p.short_value %}
- <td>{{ p.short_value|e }} .. [property value too long]</td>
- {% else %}
- {% if p.value is not mapping %}
- <td>{{ p.value|e }}</td>
- {% else %}
- <td>
- <table class="info" width="100%">
- {%- for key, value in p.value.items() recursive %}
- <tr><td>{{ key|e }}</td><td>{{ value|e }}</td></tr>
- {% endfor %}
- </table>
- </td>
- {% endif %}
- {% endif %}
- <td>{{ p.source|e }}</td>
- </tr>
-{% endif %}
-{% endfor %}
-</table>
-<h2>Forced Build Properties:</h2>
-<table class="info" width="100%">
-<tr><th>Name</th><th>Label</th><th>Value</th></tr>
-
-{% for p in properties %}
- {% if p.source == "Force Build Form" %}
- <tr class="{{ loop.cycle('alt', '') }}">
- <td class="left">{{ p.name|e }}</td>
- <td class="left">
- {% if p.label %}
- {{ p.label }}
- {% endif %}
- </td>
- {% if p.text %}
- <td><textarea readonly cols="{{p.cols}}" rows="{{p.rows}}">{{ p.text|e }}</textarea></td>
- {% else %}
- <td>{{ p.value|e }}</td>
- {% endif %}
- </tr>
- {% endif %}
-{% endfor %}
-</table>
-
-<h2>Responsible Users:</h2>
-
-{% if responsible_users %}
- <ol>
- {% for u in responsible_users %}
- <li class="{{ loop.cycle('alt', '') }}">{{ u|user }}</li>
- {% endfor %}
- </ol>
-{% else %}
- <p>no responsible users</p>
-{% endif %}
-
-
-<h2>Timing:</h2>
-<table class="info" width="100%">
- <tr class="alt"><td class="left">Start</td><td>{{ start }}</td></tr>
-{% if end %}
- <tr><td class="left">End</td><td>{{ end }}</td></tr>
-{% endif %}
- <tr {{ 'class="alt"' if end else '' }}><td class="left">Elapsed</td><td>{{ elapsed }}</td></tr>
-</table>
-
-</div>
-
-<br style="clear:both"/>
-
-{% if has_changes %}
- <div class="column">
- <h2>All Changes:</h2>
- {% for ss in sourcestamps %}
- {% if ss.changes %}
- <h3 id="changes-{{ ss.codebase }}"> {{ ss.codebase }}:</h3>
- <ol>
- {% for c in ss.changes %}
- <li><h3>Change #{{ c.number }}</h3>
- {{ change(c.asDict()) }}
- </li>
- {% endfor %}
- </ol>
- {% endif %}
- {% endfor %}
- </div>
-{% endif %}
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/build_line.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/build_line.html
deleted file mode 100644
index fc08b9dc..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/build_line.html
+++ /dev/null
@@ -1,45 +0,0 @@
-{% macro build_line(b, include_builder=False) %}
- <small>({{ b.time }})</small>
- Rev: {{ b.rev|shortrev(b.rev_repo) }}
- <span class="{{ b.class }}">{{ b.results }}</span>
- {% if include_builder %}
- <a href="{{ b.builderurl }}">{{ b.builder_name }}</a>
- {% endif %}
- <a href="{{ b.buildurl }}">#{{ b.buildnum }}</a> -
- {{ b.text|capitalize }}
-{% endmacro %}
-
-{% macro build_tr(b, include_builder=False, loop=None) %}
- <tr class="{{ loop.cycle('alt', '') if loop }}">
- <td>{{ b.time }}</td>
- <td>{{ b.rev|shortrev(b.rev_repo) }}</td>
- <td class="{{ b.class }}">{{ b.results }}</td>
- {%- if include_builder %}
- <td><a href="{{ b.builderurl }}">{{ b.builder_name }}</a></td>
- {% endif %}
- <td><a href="{{ b.buildurl }}">#{{ b.buildnum }}</a></td>
- <td class="left">{{ b.text|capitalize }}</td>
- </tr>
-{% endmacro %}
-
-{% macro build_table(builds, include_builder=False) %}
-{% if builds %}
-<table class="info">
- <tr>
- <th>Time</th>
- <th>Revision</th>
- <th>Result</th>
- {%- if include_builder %}
- <th>Builder</th>
- {% endif %}
- <th>Build #</th>
- <th>Info</th>
- </tr>
- {% for b in builds %}
- {{ build_tr(b, include_builder, loop) }}
- {% endfor %}
-</table>
-{% else %}
- No matching builds found
-{% endif %}
-{% endmacro %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/builder.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/builder.html
deleted file mode 100644
index f557d7c5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/builder.html
+++ /dev/null
@@ -1,184 +0,0 @@
-{% from 'build_line.html' import build_table %}
-{% import 'forms.html' as forms %}
-
-{% extends "layout.html" %}
-
-{% block head %}
-{{ super() }}
-<script type='text/javascript'>
-// <![CDATA[
-//
-
-// Mapping OE Core branch names to bitbake branch names
-var bbvermap = {
- 'jethro': '1.28',
- 'krogoth': '1.30',
- 'morty': '1.32',
- 'pyro': '1.34',
- 'rocko': '1.36',
- 'sumo': '1.38',
- 'master': 'master'
-};
-
-var eclipseBranchFormat = "branch_eclipse-poky-";
-
-function isEclipseBranch(elementName) {
- var pattern = eclipseBranchFormat + "*";
- return new RegExp(pattern).test(elementName);
-}
-
-function updateFormBranchInputs(pokybranch) {
- var elements = document.querySelectorAll('input[name^="branch_"]');
-
- for (var i = 0, len = elements.length; i < len; i++) {
- var newval = pokybranch;
- if (elements[i].name == "branch_bitbake") {
- newval = bbvermap[pokybranch];
- } else if (isEclipseBranch(elements[i].name)) {
- eclipseRelease = elements[i].name.split(eclipseBranchFormat, 2)[1];
- // Match the Eclipse branch format
- if (pokybranch != "master") {
- newval = eclipseRelease + "/" + pokybranch;
- } else {
- newval = eclipseRelease + "-master";
- }
- } else if (elements[i].name == "branch_refkit") {
- // Refkit only tracks OE-Core master
- newval = "master";
- } else if (elements[i].name == "branch_meta-qt3") {
- // won't get a rocko, or newer, branch
- if (['jethro', 'krogoth', 'morty', 'pyro'].indexOf(pokybranch) < 0) {
- newval = "master"
- }
- } else if (elements[i].name == "branch_meta-gplv2") {
- // only has pyro and master branches
- if (pokybranch != "pyro") {
- newval = "master"
- }
- }
- elements[i].value = newval;
- }
-}
-
-// ]]>
-</script>
-{% endblock %}
-
-{% block content %}
-
-<h1>Builder {{ name }}</h1>
-
-<p>(<a href="{{ path_to_root }}waterfall?show={{ name }}">view in waterfall</a>)</p>
-
-{% if description %}
- <div class="BuilderDescription">{{ description }}</div>
-{% endif %}
-
-<div class="column">
-
-{% if current %}
- <h2>Current Builds:</h2>
- <ul>
- {% for b in current %}
- <li><a href="{{ b.link }}">{{ b.num }}</a>
- {% if b.when %}
- ETA: {{ b.when_time }} [{{ b.when }}]
- {% endif %}
-
- {{ b.current_step }}
-
- {% if authz.advertiseAction('stopBuild', request) %}
- {{ forms.stop_build(b.stop_url, authz, on_all=False, short=True, label='Build') }}
- {% endif %}
- </li>
- {% endfor %}
- </ul>
-{% else %}
- <h2>No current builds</h2>
-{% endif %}
-
-{% if pending %}
- <h2>Pending Build Requests:</h2>
- <ul>
- {% for b in pending %}
- <li><small>({{ b.when }}, waiting {{ b.delay }})</small>
-
- {% if authz.advertiseAction('cancelPendingBuild', request) %}
- {{ forms.cancel_pending_build(builder_url+"/cancelbuild", authz, short=True, id=b.id) }}
- {% endif %}
-
- {% if b.num_changes < 4 %}
- {% for c in b.changes %}{{ c.revision|shortrev(c.repo) }}
- (<a href="{{ c.url }}">{{ c.who|email }}</a>){% if not loop.last %},{% endif %}
- {% endfor %}
- {% else %}
- ({{ b.num_changes }} changes)
- {% endif %}
-
- {% if 'owner' in b.properties %}
- <b>Forced build</b>
- by {{b.properties['owner'][0]}}
- <small>{{b.properties['reason'][0]}}</small>
- {% endif %}
- </li>
- {% endfor %}
- </ul>
-
- {% if authz.advertiseAction('cancelPendingBuild', request) %}
- {{ forms.cancel_pending_build(builder_url+"/cancelbuild", authz, short=False, id='all') }}
- {% endif %}
-
-{% else %}
- <h2>No Pending Build Requests</h2>
-{% endif %}
-
-<h2>Recent Builds:</h2>
-
-{{ build_table(recent) }}
-
-<a href="?numbuilds={{numbuilds + 5}}">Show more</a>
-
-</div>
-<div class="column">
-
-<h2>Buildslaves:</h2>
-<table class="info">
-{% if slaves %}
-<tr>
- <th>Name</th>
- <th>Status</th>
- <th>Admin</th>
-</tr>
-{% endif %}
-{% for s in slaves %}
- <tr class="{{ loop.cycle('alt', '') }}">
- <td><b><a href="{{ s.link|e }}">{{ s.name|e }}</a></b></td>
- {% if s.connected %}
- {% if s.paused %}
- <td class="paused">paused</td>
- {% else %}
- <td class="idle">connected</td>
- {% endif %}
- {% else %}
- <td class="offline">offline</td>
- {% endif %}
- <td>{{ s.admin|email if s.admin else ""}}</td>
- </tr>
-{% else %}
- <td>no slaves attached</td>
-{% endfor %}
-</table>
-
-{% if authz.advertiseAction('pingBuilder', request) %}
- <h2>Ping slaves</h2>
- {{ forms.ping_builder(builder_url+"/ping", authz) }}
-{% endif %}
-
-{% if authz.advertiseAction('forceBuild', request) and force_schedulers != {} %}
- <h2>Force build</h2>
- {{ forms.force_build(builder_url+"/force", authz, request, False, force_schedulers=force_schedulers,default_props=default_props) }}
-{% endif %}
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/builders.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/builders.html
deleted file mode 100644
index 67cb0225..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/builders.html
+++ /dev/null
@@ -1,50 +0,0 @@
-{% extends 'layout.html' %}
-{% import 'forms.html' as forms %}
-{% from "box_macros.html" import box %}
-
-{% block content %}
-<h1>Builders: {{ branches|join(', ')|e }}</h1>
-
-<table>
-{% for b in builders %}
- <tr>
- <td class="box"><a href="{{ b.link }}">{{ b.name|e }}</a></td>
- {% if b.build_url %}
- <td class="LastBuild box {{ b.build_css_class }}">
- <a href="{{ b.build_url }}">{{ b.build_label }}</a>
- <br/>{{ b.build_text }}
- </td>
- {% else %}
- <td class="LastBuild box">no build</td>
- {% endif %}
- {{ box(**b.current_box) }}
- </tr>
-{% endfor %}
-</table>
-
-{% if num_building > 0 %}
- {% if authz.advertiseAction('stopAllBuilds', request) or authz.advertiseAction('stopBuild', request) %}
- <h2>Stop Selected Builds</h2>
- {{ forms.stop_build(path_to_root+"builders/_selected/stopselected", authz, on_selected=True, builders=builders, label='Selected Builds') }}
- <h2>Stop All Builds</h2>
- {{ forms.stop_build(path_to_root+"builders/_all/stopall", authz, on_all=True, label='All Builds') }}
- {% endif %}
-{% endif %}
-
-{% if authz.advertiseAction('cancelAllPendingBuilds', request) %}
- <h2>Cancel Selected Pending Builds</h2>
- {{ forms.cancel_build(path_to_root+"builders/_selected/cancelpendingselected", authz, on_selected=True, builders=builders, label='Selected Pending Builds') }}
- <h2>Cancel All Pending Builds</h2>
- {{ forms.cancel_build(path_to_root+"builders/_all/cancelpendingall", authz, on_all=True, label='All Pending Builds') }}
-{% endif %}
-
-{% if num_online > 0 %}
- {% if authz.advertiseAction('forceAllBuilds', request) or authz.advertiseAction('forceBuild', request) %}
- <h2>Force Selected Builds</h2>
- {{ forms.force_build(path_to_root+"builders/_selected/forceselected", authz, request, on_selected=True, builders=builders, force_schedulers=force_schedulers, default_props=default_props) }}
- <h2>Force All Builds</h2>
- {{ forms.force_build(path_to_root+"builders/_all/forceall", authz,request, on_all=True, force_schedulers=force_schedulers, default_props=default_props) }}
- {% endif %}
-{% endif %}
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildslave.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildslave.html
deleted file mode 100644
index d9f55038..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildslave.html
+++ /dev/null
@@ -1,68 +0,0 @@
-{% from 'build_line.html' import build_table, build_line %}
-{% import 'forms.html' as forms %}
-
-{% extends "layout.html" %}
-{% block content %}
-<h1>Buildslave: {{ slavename|e }}</h1>
-
-<div class="column">
-
-{% if current %}
- <h2>Currently building:</h2>
- <ul>
- {% for b in current %}
- <li>{{ build_line(b, True) }}
- <form method="post" action="{{ b.buildurl }}/stop" class="command stopbuild" style="display:inline">
- <input type="submit" value="Stop Build" />
- <input type="hidden" name="url" value="{{ this_url }}" />
- </form>
- </li>
- {% endfor %}
- </ul>
-{% else %}
- <h2>No current builds</h2>
-{% endif %}
-
-<h2>Recent builds</h2>
-{{ build_table(recent, True) }}
-
-</div>
-<div class="column">
-{% if access_uri %}
- <a href="{{ access_uri|e }}">Click to Access Slave</a>
-{% endif %}
-
-{% if admin %}
- <h2>Administrator</h2>
- <p>{{ admin|email }}</p>
-{% endif %}
-
-{% if host %}
- <h2>Slave information</h2>
- Buildbot-Slave {{ slave_version }}
- <pre>{{ host|e }}</pre>
-{% endif %}
-
-<h2>Connection Status</h2>
-<p>
-{{ connect_count }} connection(s) in the last hour
-{% if not slave.isConnected() %}
-(not currently connected)
-{% else %}
-</p>
- {% if authz.advertiseAction('gracefulShutdown', request) %}
- <h2>Graceful Shutdown</h2>
- {% if slave.getGraceful() %}
- <p>Slave will shut down gracefully when it is idle.</p>
- {% else %}
- {{ forms.graceful_shutdown(shutdown_url, authz) }}
- {% endif %}
- {% endif %}
- {% if authz.advertiseAction('pauseSlave', request) %}
- <h2>Pause Slave</h2>
- {{ forms.pause_slave(pause_url, authz, slave.isPaused()) }}
- {% endif %}
-{% endif %}
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildslaves.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildslaves.html
deleted file mode 100644
index 567e3747..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildslaves.html
+++ /dev/null
@@ -1,76 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>Buildslaves</h1>
-
-<div class="column">
-
-<table class="info">
-
-<tr>
- <th>Name</th>
- {%- if show_builder_column %}
- <th>Builders</th>
- {%- endif %}
- <th>BuildBot</th>
- <th>Admin</th>
- <th>Last heard from</th>
- <th>Connects/Hour</th>
- <th>Status</th>
-</tr>
-
-{% for s in slaves %}
- <tr class="{{ loop.cycle('alt','') }}">
- <td><b><a href="{{ s.link }}">{{ s.name }}</a></b></td>
-
- {%- if show_builder_column %}
- <td>
- {%- if s.builders %}
- {%- for b in s.builders %}
- <a href="{{ b.link }}">{{ b.name }}</a>
- {%- endfor %}
- {%- else %}
- <span class="Warning">no builders</span>
- {%- endif -%}
- </td>
- {%- endif %}
-
-
- <td>{{ (s.version or '-')|e }}</td>
-
- {%- if s.admin -%}
- <td>{{ s.admin|email }}</td>
- {%- else -%}
- <td>-</td>
- {%- endif -%}
-
- <td>
- {%- if s.last_heard_from_age -%}
- {{ s.last_heard_from_age }} <small>({{ s.last_heard_from_time }})</small>
- {%- endif -%}
- </td>
- <td>
- {{ s.connectCount }}
- </td>
-
- {% if s.connected %}
- {% if s.running_builds %}
- <td class="building">Running {{ s.running_builds }} build(s)</td>
- {% elif s.paused %}
- <td class="paused">Paused</td>
- {% else %}
- <td class="idle">Idle</td>
- {% endif %}
-
- {% else %}
- <td class="offline">Not connected</td>
- {% endif %}
-
- </tr>
-{% endfor %}
-</table>
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildstatus.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildstatus.html
deleted file mode 100644
index df33878a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildstatus.html
+++ /dev/null
@@ -1,19 +0,0 @@
-{% extends "layout.html" %}
-{% from "box_macros.html" import box %}
-
-{% block header %}
-{% endblock %}
-
-{% block barecontent %}
-<table>
- {% for r in rows %}
- <tr>{{ box(**r) }}</tr>
- {% endfor %}
-
- <tr>{{ box(**build) }}</tr>
-</table>
-{% endblock %}
-
-{% block footer %}
-{% endblock %}
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildstep.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildstep.html
deleted file mode 100644
index c2c75140..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/buildstep.html
+++ /dev/null
@@ -1,73 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>
- Builder <a href="{{ builder_link }}">{{ b.getBuilder().getName() }}</a>
- build <a href="{{ build_link }}">#{{ b.getNumber() }}</a>
- step <a href="">{{ s.getName() }}</a>
-</h1>
-
-<div class="column">
-
-{% if s.isFinished() %}
- <h2>Finished</h2>
- <p class="{{ result_css }} result">
- {%- set text = s.getText() -%}
- {%- if text is string %}{{ text|e }}
- {%- else %}{{ text|join(" ")|e }}{% endif -%}
- </p>
-{% else %}
- <h2>Not Finished</h2>
- <p>ETA {{ s.getETA()|e }} seconds</p>
-{% endif %}
-
-{% set exp = s.getExpectations() %}
-{% if exp %}
- <h2>Expectations</h2>
- <ul>
- {% for e in exp %}
- <li>{{ e[0]|e }}: current={{ e[1] }}, target={{ e[2] }}</li>
- {% endfor %}
- </ul>
-{% endif %}
-
-<h2>Timing</h2>
-{% if start %}
- <table class="info">
- <tr class="alt"><td class="left">Start</td><td>{{ start }}</td></tr>
- <tr><td class="left">End</td><td>{{ end or "Not finished" }}</td></tr>
- <tr class="alt"><td class="left">Elapsed</td><td>{{ elapsed }}</td></tr>
- </table>
-{% else %}
- <b>Not started</b>
-{% endif %}
-
-<h2>Logs</h2>
-<ul>
-{% for l in logs %}
- <li class="{{ loop.cycle('alt', '') }}">
- {% if l.has_contents %}
- <a href="{{ l.link|e }}">{{ l.name|e }}</a>
- {% else %}
- {{ l.name|e }}
- {% endif %}
- </li>
-{% else %}
- <li class="alt">- No logs -</li>
-{% endfor %}
-</ul>
-
-{% if statistics %}
-<h2>Statistics</h2>
-<table class="info">
- <tr><th>Name</th><th>Value</th></tr>
- {% for stat in statistics %}
- <tr class="{{ loop.cycle('alt', '') }}"><td>{{ stat.name|e }}</td><td>{{ stat.value|e }}</td></tr>
- {% endfor %}
-</table>
-{% endif %}
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change.html
deleted file mode 100644
index f12161da..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change.html
+++ /dev/null
@@ -1,20 +0,0 @@
-{% extends "layout.html" %}
-{% from "change_macros.html" import change with context %}
-{% import 'forms.html' as forms %}
-
-{% block content %}
-
-<h1>{{ pageTitle }}</h1>
-
-<div class="column">
-
-{{ change(c) }}
-
-{% if authz.advertiseAction('stopChange', request) %}
- <h3>Cancel Builds For Change:</h3>
- {{ forms.stop_change_builds("/builders/_all/stopchangeall", c.number, authz) }}
-{% endif %}
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change_macros.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change_macros.html
deleted file mode 100644
index 2ca01d9f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change_macros.html
+++ /dev/null
@@ -1,76 +0,0 @@
-{% macro change(c) %}
-
-<table class="info">
- {% set row_class=cycler('alt','') %}
- <tr class="{{ row_class.next() }}">
- <td class="left">Category</td>
- <td><b>{{ c.category }}</b></td>
- </tr>
- <tr class="{{ row_class.next() }}">
- <td class="left">Changed by</td>
- <td><b>{{ c.who|email }}</b></td>
- </tr>
- <tr class="{{ row_class.next() }}">
- <td class="left">Changed at</td>
- <td><b>{{ c.at }}</b></td>
- </tr>
-
- {% if c.repository %}
- <tr class="{{ row_class.next() }}">
- <td class="left">Repository</td>
- <td><b>{{ c.repository|repolink }}</b></td>
- </tr>
- {% endif %} {% if c.project %}
- <tr class="{{ row_class.next() }}">
- <td class="left">Project</td>
- <td><b>{{ c.project|projectlink }}</b></td>
- </tr>
- {% endif %} {% if c.branch %}
- <tr class="{{ row_class.next() }}">
- <td class="left">Branch</td>
- <td><b>{{ c.branch|e }}</b></td>
- </tr>
- {% endif %} {% if c.rev %}
- <tr class="{{ row_class.next() }}">
- <td class="left">Revision</td>
- <td>{%- if c.revlink -%}<a href="{{ c.revlink }}">{{ c.rev|e }}</a>
- {%- else -%}{{ c.rev|revlink(c.repository) }} {%- endif -%}</td>
- </tr>
- {% endif %}
-</table>
-
-{% if c.comments %}
-<h3>Comments</h3>
-<pre class="comments">{{ c.comments|changecomment(c.project) }}</pre>
-{% endif %}
-
-<h3 class="files">Changed files</h3>
-<ul>
- {% for f in c.files -%}
- <li class="{{ loop.cycle('alt', '') }}">{%- if f.url %}<a
- href="{{ f.url }}"><b>{{ f.name|e }}</b></a></li>
- {%- else %}
- <b>{{ f.name|e }}</b>
- {%- endif -%}
- </li>
- {% else %}
- <li>no files</li>
- {% endfor %}
-</ul>
-
-{% if c.properties %}
-<h3>Properties</h3>
-<table class="info">
- {% for p in c.properties %}
- <tr class="{{ loop.cycle('alt') }}">
- <td class="left">{{ p[0]|capitalize|e }}</td>
- <td>{{ p[1]|e }}</td>
- </tr>
- {% endfor %}
-</table>
-{% endif %}
-{%- endmacro %}
-
-{% macro box_contents(who, url, pageTitle, revision, project) -%}
-<a href="{{ url }}" title="{{ pageTitle|e }}">{{ who|user }}</a>
-{%- endmacro %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change_sources.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change_sources.html
deleted file mode 100644
index 24674dd5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/change_sources.html
+++ /dev/null
@@ -1,21 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>Changesources</h1>
-
-<div class="column">
-
-{% if sources %}
- <ol>
- {% for s in sources -%}
- <li class="{{ loop.cycle('alt', '') }}">{{ s.describe() }}</li>
- {% endfor -%}
- </ol>
-{% else %}
- none (push only)
-{% endif %}
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/console.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/console.html
deleted file mode 100644
index a51c946e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/console.html
+++ /dev/null
@@ -1,276 +0,0 @@
-{% extends "layout.html" %}
-
-{% block head %}
-{{ super() }}
-<script type='text/javascript'>
-// <![CDATA[
-//
-
-//
-// Functions used to display the build status bubble on box click.
-//
-
-// show the build status box. This is called when the user clicks on a block.
-function showBuildBox(url, event) {
- // Find the current curson position.
- var cursorPosTop = (window.event ? window.event.clientY : event.pageY)
- var cursorPosLeft = (window.event ? window.event.clientX : event.pageX)
-
- // Offset the position by 5, to make the window appears under the cursor.
- cursorPosTop = cursorPosTop + document.body.scrollTop -5 ;
- cursorPosLeft = cursorPosLeft + document.body.scrollLeft - 5;
-
- // Move the div (hidden) under the cursor.
- var divBox = document.getElementById('divBox');
- divBox.style.top = parseInt(cursorPosTop) + 'px';
- divBox.style.left = parseInt(cursorPosLeft) + 'px';
-
- // Reload the hidden frame with the build page we want to show.
- // The onload even on this frame will update the div and make it visible.
- document.getElementById("frameBox").src = url
-
- // We don't want to reload the page.
- return false;
-}
-
-// OnLoad handler for the iframe containing the build to show.
-function updateDiv(event) {
- // Get the frame innerHTML.
- var iframeContent = document.getElementById("frameBox").contentWindow.document.body.innerHTML;
-
- // If there is any content, update the div, and make it visible.
- if (iframeContent) {
- var divBox = document.getElementById('divBox');
- divBox.innerHTML = iframeContent ;
- divBox.style.display = "block";
- }
-}
-
-// Util functions to know if an element is contained inside another element.
-// We use this to know when we mouse out our build status div.
-function containsDOM (container, containee) {
- var isParent = false;
- do {
- if ((isParent = container == containee))
- break;
- containee = containee.parentNode;
- } while (containee != null);
-
- return isParent;
-}
-
-// OnMouseOut handler. Returns true if the mouse moved out of the element.
-// It is false if the mouse is still in the element, but in a blank part of it,
-// like in an empty table cell.
-function checkMouseLeave(element, event) {
- if (element.contains && event.toElement) {
- return !element.contains(event.toElement);
- }
- else if (event.relatedTarget) {
- return !containsDOM(element, event.relatedTarget);
- }
-}
-
-// ]]>
-</script>
-{% endblock %}
-
-{% block content %}
-
-<h1>Console View</h1>
-
-<div align="center">
- <table width="95%" class="Grid" border="0" cellspacing="0">
- <tr>
- <td width="33%" align="left" class="left_align">
-{% if categories|length > 1 %}
- <br><b>Categories:</b> {% for c in categories %}{{ c.name|e }} {% endfor %}
-{% endif %}
-{% if codebase %}
- <br><b>Codebase:</b> {{ codebase|e }}
-{% endif %}
-{% if repository %}
- <br><b>Repository:</b> {{ repository|e }}
-{% endif %}
-{% if project %}
- <br><b>Project:</b> {{ project|e }}
-{% endif %}
-{% if branch != ANYBRANCH %}
- <br><b>Branch:</b> {{ branch|e }}
-{% endif %}
- </td>
- <td width="33%" align="center" class="center_align">
- <div align="center">
- <table class="info">
- <tr>
- <td>Legend:&nbsp;&nbsp;</td>
- <td class='legend success' title='All tests passed'>Passed</td>
- <td class='legend failure' title='There is a new failure. Take a look!'>Failed</td>
- <td class='legend warnings' title='Build has warnings'>Warnings</td>
- <td class='legend failure-again' title='It was failing before, and it is still failing. Make sure you did not introduce new regressions'>Failed&nbsp;Again</td>
- <td class='legend running' title='The tests are still running'>Running</td>
- <td class='legend exception' title='Something went wrong with the test, there is no result'>Exception</td>
- <td class='legend offline' title='The builder is offline, as there are no slaves connected to it'>Offline</td>
- <td class='legend notstarted' title='No result yet.'>No&nbsp;data</td>
- </tr>
- </table>
- </div>
- </td>
- <td width="33%" align="right" class="right_align">
- <script type="text/javascript">
-// <![CDATA[
- function reload_page() {
- name_value = document.getElementById('namebox').value
- if (document.location.href.lastIndexOf('?') == -1)
- document.location.href = document.location.href+ '?name=' + name_value;
- else
- document.location.href = document.location.href+ '&name=' + name_value;
- }
-// ]]>
- </script>
- <form onsubmit='reload_page()'>
- <input id='namebox' name='name' type='text' style='color:#999;'
- onblur='this.value = this.value || this.defaultValue; this.style.color = "#999";'
- onfocus='this.value=""; this.style.color = "#000";'
- value='Personalized for...'/>
- <input type='submit' value='Go'/>
- </form>
- </td>
- </tr>
- </table>
-</div>
-
-<br/>
-
-{% set alt_class = cycler('', 'Alt') %}
-
-<div align="center">
-<table width="96%">
-
-{% if categories|length > 1 %}
- <tr>
- <td width="1%">
- </td>
- <td width="1%">
- </td>
- {% for c in categories %}
- <td class='DevStatus {{ alt_class.next() }} {{ "first" if loop.first else '' }} {{ "last" if loop.last else '' }}' width='{{ c.size }}%'>
- {{ c.name|e }}
- </td>
- {% endfor %}
- </tr>
- <tr class='DevStatusSpacing'>
- </tr>
-{% endif %}
-
-{% if slaves %}
- <tr>
- <td width="1%">
- </td>
- <td width="1%">
- </td>
- {% for c in categories %}
- <td class='DevSlave {{ alt_class.next() }}'>
- <table width="100%">
- <tr>
- {% for s in slaves[c.name] %}
- <td class='DevSlaveBox'>
- <a href='{{ s.url }}' title='{{ s.pageTitle }}' class='DevSlaveBox {{ s.color }}' target="_blank">
- </a>
- </td>
- {% endfor %}
- </tr>
- </table>
- </td>
- {% endfor %}
- </tr>
-{% endif %}
-
-{% for r in revisions %}
- {% set alt = alt_class.next() %}
- {% set firstrev = "first" if loop.first else '' %}
-
- <tr>
- <td class='DevRev {{ alt }}' width="1%">
- {{ r.id|shortrev(r.repository) }}
- </td>
- <td class='DevName {{ alt }}' width="1%">
- {{ r.who|user }}
- </td>
-
- {% for c in categories %}
- {% set last = "last" if loop.last else "" %}
- <td class='DevStatus {{ alt }} {{ last if not firstrev else '' }}'>
- <table width="100%">
- <tr>
- {% for b in r.builds[c.name] %}
- <td class='DevStatusBox'>
- <a href='#' onclick='showBuildBox("{{ b.url }}", event); return false;'
- title='{{ b.pageTitle|e }}' class='DevStatusBox {{ b.color }} {{ b.tag }}'
- target="_blank"></a>
- </td>
- {% endfor %}
- </tr>
- </table>
- </td>
- {% endfor %}
- </tr>
-
- <tr>
- <td colspan="{{ r.span }}" class='DevComment {{ alt }} {% if not r.details %}DevBottom{% endif %}'>
- {{ r.comments|changecomment(r.project or None)|replace('\n', '<br/>')|replace(' ','&nbsp; ') }}
- </td>
- </tr>
-
- {% if r.details %}
- <tr>
- <td colspan="{{ r.span }}" class='DevDetails {{ alt }} DevBottom'>
- <ul style='margin: 0px; padding: 0 0 0 1.5em;'>
- {% for d in r.details %}
- <li>{{ d.buildername }}: {{ d.status }} - &nbsp;
- {%- for l in d.logs -%}
- <a href="{{ l.url }}">{{ l.name }}</a>
- {%- endfor -%}
- </li>
- {% endfor %}
- </ul>
- </td>
- </tr>
- {% endif %}
-
- <tr class='DevStatusSpacing'>
- <td>
- </td>
- </tr>
-
-{% else %}
- <tr><td>No revisions available</td></tr>
-{% endfor %}
-
-</table>
-</div>
-
-
-<div id="divBox" onmouseout="if (checkMouseLeave(this, event)) this.style.display = 'None'" class="BuildWaterfall">
-</div>
-
-
-<iframe id="frameBox" style="display: none;"></iframe>
-
-<script type="text/javascript">
-// replace 'onload="updateDiv(event);" with this, as iframe doesn't have onload event in xhtml
-window.onload = function() {
- document.getElementById('frameBox').onload = function(event) {
- updateDiv(event);
- };
-};
-</script>
-
-{% endblock %}
-
-
-{% block footer %}
-
-{{ super() }}
-{# <p>Debug info: {{ debuginfo }}</p> #}
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/directory.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/directory.html
deleted file mode 100644
index 662355de..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/directory.html
+++ /dev/null
@@ -1,37 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>Directory listing for {{ path }}</h1>
-
-{% set row_class = cycler('alt', '') %}
-
-<table>
-
-<tr class="{{ row_class.next() }}">
-<th style="min-width:18em">Name</th>
-<th style="min-width:8em">Size</th>
-<th style="min-width:10em">Type</th>
-<th style="min-width:10em">Encoding</th>
-</tr>
-
-{% for d in directories %}
- <tr class="directory {{ row_class.next() }}">
- <td><a href="{{ d.href }}"><b>{{ d.text }}</b></a></td>
- <td><b>{{ d.size }}</b></td>
- <td><b>{{ d.type }}</b></td>
- <td><b>{{ d.encoding }}</b></td>
- </tr>
-{% endfor %}
-
-{% for f in files %}
- <tr class="file {{ row_class.next() }}">
- <td><a href="{{ f.href }}">{{ f.text }}</a></td>
- <td>{{ f.size }}</td>
- <td>{{ f.type }}</td>
- <td>{{ f.encoding }}</td>
- </tr>
-{% endfor %}
-</table>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/empty.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/empty.html
deleted file mode 100644
index 91f4e591..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/empty.html
+++ /dev/null
@@ -1,5 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-{{ content }}
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_atom10.xml b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_atom10.xml
deleted file mode 100644
index c423e7b0..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_atom10.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-{% from 'feed_description.html' import item_desc %}
-
-<?xml version="1.0" encoding="utf-8"?>
-<feed xmlns="http://www.w3.org/2005/Atom">
- <id>{{ title_url }}</id>
- <title>{{ pageTitle|e }}</title>
- {% if project_url -%}
- <link rel="self" href="{{ title_url }}/atom"/>
- <link rel="alternate" href="{{ title_url }}"/>
- {% endif %}
- {%- if description -%}
- <subtitle>{{ description }}</subtitle>
- {% endif %}
- {%- if rfc3339_pubdate -%}
- <updated>{{ rfc3339_pubdate }}</updated>
- {% endif -%}
- <author>
- <name>BuildBot</name>
- </author>
-
- {% for b in builds -%}
- <entry>
- <title>{{ b.pageTitle }}</title>
- <link href="{{ b.link }}"/>
- <content type="xhtml">
- <div xmlns="http://www.w3.org/1999/xhtml">
- {{ item_desc(b, title_url, title)|indent(6) }}
- <pre xml:space="preserve">{{ b.log_lines|join('\n')|e }}</pre>
- </div>
- </content>
- {% if b.rfc3339_pubdate -%}
- <updated>{{ b.rfc3339_pubdate }}</updated>
- <id>{{ b.guid }}</id>
- {% endif -%}
- <author>Buildbot</author>
- </entry>
-
- {% endfor -%}
-
-</feed>
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_description.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_description.html
deleted file mode 100644
index 7f387c67..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_description.html
+++ /dev/null
@@ -1,18 +0,0 @@
-{% from 'feed_sources.html' import srcs_desc %}
-
-{% macro item_desc(b, title_url, title) -%}
- <p>
- Date: {{ b.date }}<br/>
- Project home: <a href="{{ title_url }}">{{ title|e }}</a><br/>
- Builder summary: <a href="{{ b.summary_link }}">{{ b.name }}</a><br/>
- Build details: <a href="{{ b.link }}">Build {{ b.number }}</a><br/>
- Author list: <b>{{ b.responsible_users|join(', ') }}</b><br/>
- Failed step(s): <b>{{ b.failed_steps|join(', ') }}</b><br/>
- </p>
- {% for src in b.sources %}
- {{ srcs_desc(src) }}
- {% endfor %}
- <p>
- <i>Last lines of the build log:</i>
- </p>
-{%- endmacro %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_rss20.xml b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_rss20.xml
deleted file mode 100644
index 9f30112a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_rss20.xml
+++ /dev/null
@@ -1,39 +0,0 @@
-{% from 'feed_description.html' import item_desc %}
-
-<?xml version="1.0" encoding="utf-8"?>
-<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
- <channel>
- <title>{{ pageTitle|e }}</title>
- <link>{{ title_url }}</link>
- <atom:link href="{{ title_url }}rss" rel="self" type="application/rss+xml"/>
- {% if language -%}
- <language>{{ language }}</language>
- {% endif %}
- {%- if description -%}
- <description>{{ description }}</description>
- {% endif %}
- {%- if rfc822_pubdate -%}
- <pubDate>{{ rfc822_pubdate }}</pubDate>
- {% endif %}
-
- {% for b in builds -%}
- <item>
- <title>{{ b.pageTitle }}</title>
- <link>{{ b.link }}</link>
- <description>
- <![CDATA[
- {{ item_desc(b, title_url, title)|indent(8) }}
- <pre>{{ b.log_lines|join('\n')|e }}</pre>
- ]]>
- </description>
- {% if b.rfc822_pubdate -%}
- <pubDate>{{ b.rfc822_pubdate }}</pubDate>
- <guid isPermaLink="false">{{ b.guid }}</guid>
- {%- endif %}
-
- </item>
-
- {% endfor %}
-
- </channel>
-</rss>
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_sources.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_sources.html
deleted file mode 100644
index 4ec3bc8f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/feed_sources.html
+++ /dev/null
@@ -1,16 +0,0 @@
-{% macro srcs_desc(src) -%}
- <div>
- {%- if src.codebase -%}
- <b>Codebase: {{ src.codebase }}</b><br/>
- {% endif %}
- <p>
- Repository: {{ src.repository }}<br/>
- {%- if src.branch -%}
- Branch: {{ src.branch }}<br/>
- {% endif %}
- {%- if src.revision -%}
- Revision: {{ src.revision }}<br/>
- {% endif %}
- </p>
- </div>
-{%- endmacro %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/footer.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/footer.html
deleted file mode 100644
index 30c664c7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/footer.html
+++ /dev/null
@@ -1,23 +0,0 @@
-<hr />
-<div class="footer">
-
-<a href="{{ welcomeurl }}">Welcome Page</a>
-<br />
-
-<a href="http://buildbot.net/">Buildbot</a>-{{ version }}
-
-{% if title %}
- working for
- {% if title_url %}
- <a href="{{ title_url }}">{{ title }}</a>
- {% else %}
- {{ title }}
- {% endif %}
- project
-{% endif %}
-
-<br />
-
-Page built: {{ time }} ({{ tz }})
-</div>
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/forms.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/forms.html
deleted file mode 100644
index 133c465a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/forms.html
+++ /dev/null
@@ -1,288 +0,0 @@
-
-{% macro cancel_pending_build(cancel_url, authz, short=False, id='all') %}
- <form method="post" name="cancel" action="{{ cancel_url }}" class='command cancelbuild'
- {{ 'style="display:inline"' if short else '' }}>
- {% if not short %}
- {% if id == 'all' %}
- <p>To cancel all builds, push the 'Cancel' button</p>
- <p>To cancel individual builds, click the 'Cancel' buttons above.</p>
- {% else %}
- <p>To cancel this build, push the 'Cancel' button</p>
- {% endif %}
- {% endif %}
- <input type="hidden" name="id" value="{{ id }}" />
- <input type="submit" value="Cancel" />
- </form>
-{% endmacro %}
-
-{% macro stop_change_builds(stopchange_url, changenum, authz) %}
- {% if not changenum %}
- <form method="post" action="{{ stopchange_url }}" class='command stopchange'>
- {% if changenum %}
- <p>To cancel all builds for this change, push the 'Cancel' button</p>
- {% else %}
- <p>To cancel builds for this builder for a given change, fill out the
- following field and push the 'Cancel' button</p>
- {% endif %}
-
- {% if changenum %}
- <input type="hidden" name="change" value="{{ changenum }}" />
- {% else %}
- <div class="row">
- <span class="label">Change #:</span>
- <input type="text" name="change"/>
- </div>
- {% endif %}
- <input type="submit" value="Cancel" />
- </form>
- {% endif %}
-{% endmacro %}
-
-{% macro stop_build(stop_url, authz, on_all=False, on_selected=False, builders=[], short=False, label="Build") %}
- {% if not short %}
- <form method="post" name="stop_build" action="{{ stop_url }}" class='command stopbuild'
- {{ 'style="display:inline"' if short else '' }}>
- {% if not short %}
- {% if on_all %}
- <p>To stop all builds, fill out the following field and
- push the <i>Stop {{ label }}</i> button</p>
- {% elif on_selected %}
- <p>To stop selected builds, select the builders, fill out the
- following field and push the <i>Stop {{ label }}</i> button</p>
- <table>
- {% for b in builders %}
- <tr>
- <td align="center"><input type="checkbox" name="selected" value="{{ b.name }}"></td>
- <td class="box"><a href="{{ b.link }}">{{ b.name|e }}</a></td>
- </tr>
- {% endfor %}
- </table>
-
- {% else %}
- <p>To stop this build, fill out the following field and
- push the <i>Stop {{ label }}</i> button</p>
- {% endif %}
- {% endif %}
-
- {% if not short %}
- <div class="row">
- <span class="label">Reason:</span>
- <input type="text" name="comments"/>
- </div>
- {% endif %}
-
- <input type="submit" value="Stop {{ label }}" />
- </form>
- {% endif %}
-{% endmacro %}
-
-{% macro cancel_build(cancel_url, authz, on_all=False, on_selected=False, builders=[], short=False, label="Build") %}
- {% if not short %}
- <form method="post" name="cancel_build" action="{{ cancel_url }}" class='command cancelbuild'
- {{ 'style="display:inline"' if short else '' }}>
- {% if not short %}
- {% if on_all %}
- <p>To cancel all pending builds, fill out the following field and
- push the <i>Cancel {{ label }}</i> button</p>
- {% elif on_selected %}
- <p>To cancel selected pending builds, select the builders, fill out the
- following field and push the <i>Cancel {{ label }}</i> button</p>
- <table>
- {% for b in builders %}
- <tr>
- <td align="center"><input type="checkbox" name="selected" value="{{ b.name }}"></td>
- <td class="box"><a href="{{ b.link }}">{{ b.name|e }}</a></td>
- </tr>
- {% endfor %}
- </table>
-
- {% else %}
- <p>To cancel this pending build, fill out the following field and
- push the <i>Cancel {{ label }}</i> button</p>
- {% endif %}
- {% endif %}
-
- {% if not short %}
- <div class="row">
- <span class="label">Reason:</span>
- <input type="text" name="comments"/>
- </div>
- {% endif %}
-
- <input type="submit" value="Cancel {{ label }}" />
- </form>
- {% endif %}
-{% endmacro %}
-
-{% macro force_build_scheduler_parameter(f, authz, request, sch, default_props) %}
- {% if f and not f.hide and (f.fullName != "username" or not authz.authenticated(request)) %}
- <div class="row{% for subtype in f.type %} force-{{subtype}}{%endfor%}"{% if f.name %} id="force-{{sch.name}}-{{f.fullName}}"{% endif %}>
- {% if 'text' in f.type or 'int' in f.type %}
- <span class="label">{{f.label}}</span>
- <input type='text' size='{{f.size}}' name='{{f.fullName}}' value='{{default_props[sch.name+"."+f.fullName]}}' />
- {% elif 'bool' in f.type%}
- <input type='checkbox' name='checkbox' value='{{f.fullName}}' {{default_props[sch.name+"."+f.fullName]}} />
- <span class="label">{{f.label}}</span>
- {% elif 'textarea' in f.type %}
- <span class="label">{{f.label}}</span>
- <textarea name='{{f.fullName}}' rows={{f.rows}} cols={{f.cols}}>{{default_props[sch.name+"."+f.fullName]}}</textarea>
- {% elif 'list' in f.type %}
- <span class="label">{{f.label}}</span>
- <span class="select">
- <select name='{{f.fullName}}' {{ f.multiple and "multiple" or ""}}>
- {% for c in default_props[sch.name+"."+f.fullName+".choices"] %}
- <option {{(c in default_props[sch.name+"."+f.fullName]) and "selected" or ""}}>{{c}}</option>
- {% endfor %}
- </select>
- </span>
- {% elif 'nested' in f.type %}
- {% if f.label %}<span class="label">{{f.label}}</span>{% endif %}
- {% for subfield in f.fields %}
- {{ force_build_scheduler_parameter(subfield, authz, request, sch, default_props) }}
- {% endfor %}
- {% endif %}
- </div>
- {% endif %}
-{% endmacro %}
-
-{% macro force_build_one_scheduler(force_url, authz, request, on_all, on_selected, builders, sch, default_props) %}
- <form method="post" name="force_build" action="{{ force_url }}" class="command_forcebuild">
-
- <h3>{{ sch.name|e }}</h3>
- {% if on_all %}
- <p>To force a build on <strong>all Builders</strong>, fill out the following fields
- and push the 'Force Build' button</p>
- {% elif on_selected %}
- <p>To force a build on <strong>certain Builders</strong>, select the
- builders, fill out the following fields and push the
- 'Force Build' button</p>
-
- <table>
- {% for b in builders %}
- {% if b.name in sch.builderNames %}
- <tr>
- <td align="center"><input type="checkbox" name="selected" value="{{ b.name }}"></td>
- <td class="box"><a href="{{ b.link }}">{{ b.name|e }}</a></td>
- </tr>
- {% endif %}
- {% endfor %}
- </table>
-
- {% else %}
- <p>To force a build, fill out the following fields and
- push the 'Force Build' button</p>
- {% endif %}
- <input type='hidden' name='forcescheduler' value='{{sch.name}}' />
- <p>
- <hr />
- {% if "nightly" in sch.builderNames %}
- Set up branch values for Poky branch: <select id ="select_release"
- name="build_release" onchange="updateFormBranchInputs(this.value)">
- <option value="master" selected>master</option>
- <option value="rocko">rocko</option>
- <option value="pyro">pyro</option>
- <option value="morty">morty</option>
- <option value="krogoth">krogoth</option>
- </select>
- <hr/>
- {% endif %}
-
- {% for f in sch.all_fields %}
- {{ force_build_scheduler_parameter(f, authz, request, sch, default_props) }}
- {% endfor %}
-
- <input type="submit" value="Force Build" />
- </form>
-{% endmacro %}
-{% macro force_build(force_url, authz, request, on_all=False, on_selected=False, builders=[], force_schedulers={},default_props={}) %}
- {% for name, sch in force_schedulers.items() | sort %}
- {{ force_build_one_scheduler(force_url, authz, request, on_all, on_selected, builders, sch, default_props=default_props) }}
- {% endfor %}
-
-{% endmacro %}
-
-{% macro graceful_shutdown(shutdown_url, authz) %}
- <form method="post" action="{{ shutdown_url }}" class='command graceful_shutdown'>
-
- <p>To cause this slave to shut down gracefully when it is idle,
- push the 'Graceful Shutdown' button</p>
- <input type="submit" value="Graceful Shutdown" />
- </form>
-{% endmacro %}
-
-{% macro pause_slave(pause_url, authz, paused) %}
- <form method="post" action="{{ pause_url }}" class='command pause_slave'>
-
- {% if paused %}
- <p>To cause this slave to start running new builds again,
- push the 'Unpause Slave' button</p>
- {% else %}
- <p>To cause this slave to stop running new builds,
- push the 'Pause Slave' button</p>
- {% endif %}
-
- {% if paused %}
- <input type="submit" value="Unpause Slave" />
- {% else %}
- <input type="submit" value="Pause Slave" />
- {% endif %}
- </form>
-{% endmacro %}
-
-{% macro clean_shutdown(shutdown_url, authz) %}
- <form method="post" action="{{ shutdown_url }}" class='command clean_shutdown'>
- <p>To cause this master to shut down cleanly, push the 'Clean Shutdown' button.</p>
- <p>No other builds will be started on this master, and the master will
- stop once all current builds are finished.</p>
-
- <input type="submit" value="Clean Shutdown" />
- </form>
-{% endmacro %}
-
-{% macro cancel_clean_shutdown(cancel_shutdown_url, authz) %}
- <form method="post" action="{{ cancel_shutdown_url }}" class='command cancel_clean_shutdown'>
- <p>To cancel a previously initiated shutdown, push the 'Cancel Shutdown' button.</p>
-
- <input type="submit" value="Cancel Shutdown" />
- </form>
-{% endmacro %}
-
-{% macro ping_builder(ping_url, authz) %}
- <form method="post" action="{{ ping_url }}" class='command ping_builder'>
- <p>To ping the buildslave(s), push the 'Ping' button</p>
- <input type="submit" value="Ping Builder" />
- </form>
-{% endmacro %}
-
-{% macro rebuild_build(rebuild_url, authz, ss) %}
- <form method="post" action="{{ rebuild_url }}" class="command rebuild">
-
- {% if on_all %}
- <p>To force a build on <strong>all Builders</strong>, fill out the following fields
- and push the 'Force Build' button</p>
- {% else %}
- <p>To force a build, fill out the following fields and
- push the 'Force Build' button</p>
- {% endif %}
- <div class="row">
- <span class="label">Reason for re-running build:</span>
- <input type='text' name='comments' />
- </div>
- <div class="row">
- Rebuild using:
- <select name="useSourcestamp">
- <option value='exact' selected>Exact same revisions</option>
- <option value='updated'>Same sourcestamps (ignoring 'got revision')</option>
- </select>
- </div>
- <input type="submit" value="Rebuild" />
- </form>
-{% endmacro %}
-
-{% macro show_users(users_url, authz) %}
- <form method="post" action="{{ users_url }}" class='command show_users'>
- <p>To show users, press the 'Show Users' button</p>
-
- <input type="submit" value="Show Users" />
- </form>
-{% endmacro %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid.html
deleted file mode 100644
index ed44ea10..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid.html
+++ /dev/null
@@ -1,31 +0,0 @@
-{% extends "layout.html" %}
-{% import 'grid_macros.html' as grid with context %}
-
-{% block content %}
-
-<h1>Grid View</h1>
-
-<table class="Grid" border="0" cellspacing="0">
-
-<tr>
- <td class="title"><a href="{{ title_url }}">{{ title }}</a>
- {{ grid.category_title() }}
- </td>
-
- {% for i in range %}
- {{ grid.stamp_td(stamps[i], build_triggers[i]) }}
- {% endfor %}
-</tr>
-
-{% for builder in builders %}
- <tr>
- {{ grid.builder_td(builder) }}
- {% for build in builder.builds %}
- {{ grid.build_td(build) }}
- {% endfor %}
- </tr>
-{% endfor %}
-
-</table>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid_macros.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid_macros.html
deleted file mode 100644
index 42a1b451..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid_macros.html
+++ /dev/null
@@ -1,65 +0,0 @@
-{% macro category_title() -%}
- {% if categories %}
- <br>
- {% trans categories=categories %}
- <b>Category:</b></br>
- {% pluralize categories %}
- <b>Categories:</b><br/>
- {% endtrans %}
- {% for c in categories %}
- {{ c|e }}<br/>
- {% endfor %}
- {% endif %}
-
- {% if branch != ANYBRANCH %}
- <br><b>Branch:</b> {{ branch|e or "trunk" }}
- {% endif %}
-{%- endmacro %}
-
-
-{% macro stamp_td(sourcestamps, trigger) -%}
- <td valign="bottom" class="sourcestamp">
- {% for ss in sourcestamps %}
- {%- if ss.codebase %}{{ ss.codebase|e }}: {% endif %}
- {%- if ss.revision -%}
- <br/><b>Commit: </b>{{ ss.revision|shortrev(ss.repository) }}
- {%- else %}<br/><b>Commit: </b>latest{% endif %}
- {%- if ss.branch %} in {{ ss.branch|e }}{% endif %}
- {%- if ss.hasPatch %} [patch]{% endif -%}
- (<a href="http://errors.yoctoproject.org/Errors/Latest/Autobuilder/?filter={{ss.revision}}&type=commit">errors</a>,
- <a href="https://wiki.yoctoproject.org/wiki/BuildLog#{{trigger.builder}}_{{trigger.id}}_-_{{ss.branch}}_{{ss.revision}}">log</a>)
- <br/>
- {%- endfor %}
- </td>
-{%- endmacro %}
-
-{% macro builder_td(b) -%}
- <td valign="middle" style="text-align: center" class="builder {{ b.state }}">
- <a href="{{ b.url }}">{{ b.name }}</a>
- {%- if b.state != 'idle' or b.n_pending > 0 -%}
- <br/>({{ b.state }}
- {%- if b.n_pending > 0 -%}
- , plus {{ b.n_pending }}
- {%- endif -%}
- )
- {%- endif -%}
- {%- if b.time %}<br/><b>Time: </b> {{ b.time }} {% endif %}
- </td>
-{%- endmacro %}
-
-{% macro build_td(build) -%}
-{% if build %}
- <td valign="top" class="build {{ build.class }}" style="text-align: left" style="white-space: nowrap" valign="bottom" >
- {%- if build.release_name %}<br/><b>RELEASE NAME:</b> {{ build.release_name }}{% endif %}
- {%- if build.branchshortname %}<br/><b>Branch:</b> {{ build.branchshortname }} {% endif %}
- {%- if build.repository %}<br/><b>Repo: </b>
- {%- if build.cgiturl %} <a href="{{ build.cgiturl }}"> {% endif %}
- {{ build.repository }}
- {%- if build.cgiturl %} </a> {% endif %}
- {% endif %}
- <br/><b>Build:</b> <a href="{{ build.url }}">{{ build.text|join('<br/>') }}</a>
- </td>
-{% else %}
- <td class="build">&nbsp;</td>
-{% endif %}
-{%- endmacro %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid_transposed.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid_transposed.html
deleted file mode 100644
index 9b6cadad..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/grid_transposed.html
+++ /dev/null
@@ -1,30 +0,0 @@
-{% extends "layout.html" %}
-{% import 'grid_macros.html' as grid with context %}
-
-{% block content %}
-
-<h1>Transposed Grid View</h1>
-
-<table class="Grid" border="0" cellspacing="0">
-
-<tr>
- <td class="title"><a href="{{ title_url }}">{{ title }}</a>
- {{ grid.category_title() }}
- </td>
- {% for builder in builders %}
- {{ grid.builder_td(builder) }}
- {% endfor %}
-</tr>
-
-{% for i in range %}
- <tr>
- {{ grid.stamp_td(stamps[i], build_triggers[i]) }}
- {% for b in builder_builds %}
- {{ grid.build_td(b[i]) }}
- {% endfor %}
- </tr>
-{% endfor %}
-
-</table>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/jsonhelp.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/jsonhelp.html
deleted file mode 100644
index 63c155b9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/jsonhelp.html
+++ /dev/null
@@ -1,28 +0,0 @@
-{% extends "layout.html" %}
-{% block content %}
-
-<p>{{ text }}</p>
-<h2>More Help:</h2>
-
-{% if level != 1 %}
-<p><a href="../help">Parent's Help</a></p>
-{% endif %}
-
-{% if children %}
-<p>Child Nodes</p>
-<ul>
-{% for child in children %}
- <li><a href="{{ child|e }}">{{ child|e }}</a>
- (<a href="{{ child|e }}/help">{{ child|e }}/help</a>)
- </li>
-{% endfor %}
-</ul>
-{% endif %}
-
-<h2>Flags:</h2>
-{{ flags }}
-
-<h2>Examples:</h2>
-{{ examples }}
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/layout.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/layout.html
deleted file mode 100644
index 01dfb80c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/layout.html
+++ /dev/null
@@ -1,90 +0,0 @@
-{%- block doctype -%}
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
-"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-{% endblock %}
-<html xmlns="http://www.w3.org/1999/xhtml">
- <head>
- {% block head %}
- <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
- {% if metatags %}
- {{ metatags }}
- {% endif %}
- {% if refresh %}
- <meta http-equiv="refresh" content="{{ refresh|e }}"/>
- {% endif %}
- <title>{{ pageTitle|e }}</title>
- <link rel="stylesheet" href="{{ stylesheet }}" type="text/css" />
- <link rel="alternate" type="application/rss+xml" title="RSS" href="{{ path_to_root }}rss">
- <link rel="shortcut icon" href="{{ path_to_root }}favicon.ico">
- {% endblock %}
- </head>
- <body class="interface">
- {% block header -%}
- <div class="header">
- <a href="{{ path_to_root or '.' }}">Home</a>
- {% if authz.advertiseAction('view', request) %}
- - <a href="{{ path_to_root }}waterfall">Waterfall</a>
- <a href="{{ path_to_root }}grid">Grid</a>
- <a href="{{ path_to_root }}tgrid">T-Grid</a>
- <a href="{{ path_to_root }}console">Console</a>
- <a href="{{ path_to_root }}builders">Builders</a>
- <a href="{{ path_to_root }}one_line_per_build">Recent Builds</a>
- <a href="{{ path_to_root }}buildslaves">Buildslaves</a>
- <a href="{{ path_to_root }}changes">Changesources</a>
- {% if authz.advertiseAction('showUsersPage', request) %}
- <a href="{{ path_to_root }}users">Users</a>
- {% endif %}
- - <a href="{{ path_to_root }}json/help">JSON API</a>
- - <a href="{{ path_to_root }}about">About</a>
- {% endif %}
- <div class="auth">
- {% if authz.authenticated(request) %}
- {{ authz.getUsernameHTML(request) }}
- |<a href="{{ path_to_root }}logout">Logout</a>
- {% elif authz.useHttpHeader and authz.httpLoginUrl %}
- <a href="{{ authz.httpLoginUrl }}">Login</a>
- {% elif authz.auth %}
- <form method="post" name="login" action="{{ path_to_root }}login">
- <input type="text" name="username" size=10 />
- <input type="password" name="passwd" size=10 />
- <input type="submit" value="login" />
- </form>
- {% endif %}
- </div>
- </div>
- {% endblock %}
-
- {%- block barecontent -%}
- <hr/>
-
- {% if alert_msg != "" %}
- <div class="alert">
- {{ alert_msg }}
- </div>
- {% endif %}
-
- <div class="content">
- {%- block content -%}
- {%- endblock -%}
- </div>
- {%- endblock -%}
-
- {%- block footer -%}
- <div class="footer" style="clear:both">
- <hr/>
- <a href="http://buildbot.net/">BuildBot</a> ({{version}})
- {% if title -%}
- working for the&nbsp;
- {%- if title_url -%}
- <a href="{{ title_url }}">{{ title }}</a>
- {%- else -%}
- {{ title }}
- {%- endif -%}
- &nbsp;project.
- {%- endif -%}
- <br/>
- Page built: <b>{{ time }}</b> ({{ tz }})
- </div>
- {% endblock -%}
- </body>
-</html>
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/logs.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/logs.html
deleted file mode 100644
index 116bbd6a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/logs.html
+++ /dev/null
@@ -1,23 +0,0 @@
-{%- macro page_header(pageTitle, path_to_root, texturl) -%}
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <html>
- <head><title>{{ pageTitle }}</title>
- <link rel="stylesheet" href="{{ path_to_root }}default.css" type="text/css" />
- </head>
- <body class='log'>
- <a href="{{ texturl }}">(view as text)</a><br/>
- <pre>
-{%- endmacro -%}
-
-{%- macro chunks(entries) -%}
-{%- for entry in entries -%}
- <span class="{{ entry.type }}">{{ entry.text|e }}</span>
-{%- endfor -%}
-{%- endmacro -%}
-
-{%- macro page_footer() -%}
-</pre>
-</body>
-</html>
-{%- endmacro -%}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/onelineperbuild.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/onelineperbuild.html
deleted file mode 100644
index d2484465..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/onelineperbuild.html
+++ /dev/null
@@ -1,36 +0,0 @@
-{% extends "layout.html" %}
-{% from 'build_line.html' import build_table %}
-{% import 'forms.html' as forms %}
-
-{% block content %}
-<h1>Last {{ num_builds }} finished builds: {{ branches|join(', ')|e }}</h1>
-
-{% if builders %}
- <p>of builders: {{ builders|join(", ")|e }}</p>
-{% endif %}
-
-<div class="column">
-
-{{ build_table(builds, True) }}
-
-</div>
-<div class="column">
-
-{% if num_building > 0 %}
- {% if authz.advertiseAction('stopBuild', request) %}
- <h2>Stop All Builds</h2>
- {{ forms.stop_build("builders/_all/stopall", authz, on_all=True, label='All Builds') }}
- {% endif %}
-{% endif %}
-
-{% if num_online > 0 %}
- {% if authz.advertiseAction('forceAllBuilds', request) %}
- <h2>Force All Builds</h2>
- {{ forms.force_build("builders/_all/forceall", authz, request, True, force_schedulers=force_schedulers, default_props=default_props) }}
- {% endif %}
-{% endif %}
-
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/onelineperbuildonebuilder.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/onelineperbuildonebuilder.html
deleted file mode 100644
index 051501f2..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/onelineperbuildonebuilder.html
+++ /dev/null
@@ -1,18 +0,0 @@
-{% extends "layout.html" %}
-{% from 'build_line.html' import build_line %}
-
-{% block content %}
-
-<h1>Last {{ num_builds }} builds of builder {{ builder_name|e }}:
- {{ branches|join(', ')|e }}
-</h1>
-
-<ul>
-{% for b in builds %}
- <li>{{ build_line(b) }}</li>
-{% else %}
- <li>No matching builds found</li>
-{% endfor %}
-</ul>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/revmacros.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/revmacros.html
deleted file mode 100644
index 87a87a02..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/revmacros.html
+++ /dev/null
@@ -1,35 +0,0 @@
-{# both macro pairs must have the same signature #}
-
-{% macro id_replace(rev, url) -%}
- <span class="revision" title="Revision {{ rev }}"><a href="{{ url }}">
- {%- if rev|length > 40 %}{{ rev[:40] }}...
- {%- else %}{{ rev }}
- {%- endif -%}
- </a></span>
-{%- endmacro %}
-
-{% macro shorten_replace(short, rev, url) %}
- <div class="revision">
- <div class="short" title="Revision {{ rev }}">
- <a href="{{ url }}">{{ short }}...</a>
- </div>
- <div class="full">
- <a href="{{ url }}">{{ rev }}</a>
- </div>
- </div>
-{% endmacro %}
-
-{% macro id(rev, url) -%}
- <span class="revision" title="Revision {{ rev }}">
- {%- if rev|length > 40 %}{{ rev[:40] }}...
- {%- else %}{{ rev }}
- {%- endif -%}
- </span>
-{%- endmacro %}
-
-{% macro shorten(short, rev, url) %}
- <div class="revision">
- <div class="short" title="Revision {{ rev }}">{{ short }}...</div>
- <div class="full">{{ rev }}</div>
- </div>
-{% endmacro %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/root.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/root.html
deleted file mode 100644
index 561973e4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/root.html
+++ /dev/null
@@ -1,61 +0,0 @@
-{% extends 'layout.html' %}
-{% import 'forms.html' as forms %}
-
-{% block content %}
-
-<h1>Welcome to the Buildbot
-{%- if title -%}
- &nbsp;for the&nbsp;
- {%- if title_url -%}
- <a href="{{ title_url }}">{{ title }}</a>
- {%- else -%}
- {{ title }}
- {%- endif -%}
-&nbsp;project
-{%- endif -%}
-!
-</h1>
-
-<div class="column">
-
-<ul>
- {% set item_class=cycler('alt', '') %}
-
- <li class="{{ item_class.next() }}">The <a href="waterfall">Waterfall Display</a> will give you a
- time-oriented summary of recent buildbot activity. <a href="waterfall/help">Waterfall Help.</a></li>
-
- <li class="{{ item_class.next() }}">The <a href="grid">Grid Display</a> will give you a
- developer-oriented summary of recent buildbot activity.</li>
-
- <li class="{{ item_class.next() }}">The <a href="tgrid">Transposed Grid Display</a> presents
- the same information as the grid, but lists the revisions down the side.</li>
-
- <li class="{{ item_class.next() }}">The <a href="console">Console</a> presents
- a user-oriented status page.</li>
-
- <li class="{{ item_class.next() }}">The <a href="builders">Builders</a> and their most recent builds are
- here.</li>
-
- <li class="{{ item_class.next() }}"><a href="one_line_per_build">Recent Builds</a> are summarized here, one
- per line.</li>
-
- <li class="{{ item_class.next() }}"><a href="buildslaves">Buildslave</a> information</li>
- <li class="{{ item_class.next() }}"><a href="changes">Changesource</a> information.</li>
-
- <li class="{{ item_class.next() }}"><a href="about">About</a> this Buildbot</li>
-</ul>
-
-{%- if authz.advertiseAction('cleanShutdown', request) -%}
-{%- if shutting_down -%}
-Master is shutting down<br/>
-{{ forms.cancel_clean_shutdown(cancel_shutdown_url, authz) }}
-{%- else -%}
-{{ forms.clean_shutdown(shutdown_url, authz) }}
-{%- endif -%}
-{%- endif -%}
-
-<p><i>This and other pages can be overridden and customized.</i></p>
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/testresult.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/testresult.html
deleted file mode 100644
index 70dac7ae..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/testresult.html
+++ /dev/null
@@ -1,34 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>
- Builder <a href="{{ builder_link }}">{{ b.getBuilder().getName() }}</a>
- build <a href="{{ build_link }}">#{{ b.getNumber() }}</a>
- test <a href="">{{ '.'.join(tr.getName()) }}</a>
-</h1>
-
-<div class="column">
-
- <h2>Result</h2>
- <p class="{{ result_css }} result">
- {{ result_word }}
- {%- set text = tr.getText() -%}
- {%- if text is string %}{{ text|e }}
- {%- else %}{{ text|join(" ")|e }}{% endif -%}
- </p>
-
-<h2>Logs</h2>
-<ul>
-{% for l in logs %}
- <h3>Log: {{ l.name|e }}</h3>
- <samp><pre>{{ l.log|e }}</pre></samp>
- </br>
-{% else %}
- <li class="alt">- No logs -</li>
-{% endfor %}
-</ul>
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/user.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/user.html
deleted file mode 100644
index eb136175..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/user.html
+++ /dev/null
@@ -1,29 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>User: {{ user_identifier|e }}</h1>
-
-<div class="column">
-
-<table class="info">
-
-<tr>
- <th>Attribute Type</th>
- <th>Attribute Value</th>
-</tr>
-
-{% for attr in user %}
- <tr class="{{ loop.cycle('alt','') }}">
-
- <td>{{ attr|e }}</td>
- <td>{{ user[attr]|e }}</td>
-
- </tr>
-{% endfor %}
-
-</table>
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/users.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/users.html
deleted file mode 100644
index 5cb2dafc..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/users.html
+++ /dev/null
@@ -1,27 +0,0 @@
-{% extends "layout.html" %}
-
-{% block content %}
-
-<h1>Users</h1>
-
-<table class="info">
-
-<tr>
- <th>Uid</th>
- <th>Identifier</th>
-</tr>
-
-{% for user in users %}
- <tr class="{{ loop.cycle('alt','') }}">
-
- <td><b><a href="{{ user.user_link }}">{{ user.uid }}</a></b></td>
- <td>{{ user.identifier|e }}</td>
-
- </tr>
-{% endfor %}
-
-</table>
-
-</div>
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/waterfall.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/waterfall.html
deleted file mode 100644
index e380406e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/waterfall.html
+++ /dev/null
@@ -1,66 +0,0 @@
-{% extends "layout.html" %}
-{% from "box_macros.html" import box %}
-
-{% block content %}
-
-<div>
- <h1 style="display: inline;">Waterfall</h1>
- <a style="float: right;" href="{{ help_url }}">waterfall help</a>
-</div>
-
-<table border="0" cellspacing="0">
-
-<tr class="LastBuild">
- <td align="right" colspan="2" class="Project">
- last build
- </td>
-
-{% for b in builders %}
- <td align="center" class="{{ b.top_class }}">
- <a href="{{ b.url }}">{{ b.name }}</a><br/>
- {{ " ".join(b.top) }}
- </td>
-{% endfor %}
-</tr>
-
-<tr class="Activity">
-<td align="right" colspan="2">current activity</td>
-
-{% for b in builders %}
- <td align="center" class="{{ b.status_class }}">
- {{ "<br/>".join(b.status) }}
- </td>
-{% endfor %}
-</tr>
-
-<tr>
-<td align="center" class="Time">{{ tz }}</td>
-<td align="center" class="Change"><a href="{{ changes_url }}">changes</a></td>
-
-{% for b in builders %}
- <td align="center" class="Builder"><a href="{{ b.url }}">{{ b.name }}</a></td>
-{% endfor %}
-</tr>
-
-{# waterfall contents goes here #}
-{% for i in range(gridlen) -%}
- <tr>
- {% for strip in grid -%}
- {%- if strip[i] -%}{{ box(**strip[i]) }}
- {%- elif no_bubble -%}{{ box() }}
- {%- endif -%}
- {%- endfor -%}
- </tr>
-{% endfor %}
-
-</table>
-
-{% if nextpage %}
- <a href="{{ nextpage }}">next page</a>
-{% endif %}
-
-{% if no_reload_page %}
- <a href="{{ no_reload_page }}">Stop Reloading</a>
-{% endif %}
-
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/waterfallhelp.html b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/waterfallhelp.html
deleted file mode 100644
index c0e5ec6e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/templates/waterfallhelp.html
+++ /dev/null
@@ -1,140 +0,0 @@
-{% extends "layout.html" %}
-{% block content %}
-
-<form action="../waterfall" method="get">
-
-<h1>The Waterfall Display</h1>
-
-<p>The Waterfall display can be controlled by adding query arguments to the
-URL. For example, if your Waterfall is accessed via the URL
-<tt>http://buildbot.example.org:8080</tt>, then you could add a
-<tt>branch=</tt> argument (described below) by going to
-<tt>http://buildbot.example.org:8080?branch=beta4</tt> instead. Remember that
-query arguments are separated from each other with ampersands, but they are
-separated from the main URL with a question mark, so to add a
-<tt>branch=</tt> and two <tt>builder=</tt> arguments, you would use
-<tt>http://buildbot.example.org:8080?branch=beta4&amp;builder=unix&amp;builder=macos</tt>.</p>
-
-<h2>Limiting the Displayed Interval</h2>
-
-<p>The <tt>last_time=</tt> argument is a unix timestamp (seconds since the
-start of 1970) that will be used as an upper bound on the interval of events
-displayed: nothing will be shown that is more recent than the given time.
-When no argument is provided, all events up to and including the most recent
-steps are included.</p>
-
-<p>The <tt>first_time=</tt> argument provides the lower bound. No events will
-be displayed that occurred <b>before</b> this timestamp. Instead of providing
-<tt>first_time=</tt>, you can provide <tt>show_time=</tt>: in this case,
-<tt>first_time</tt> will be set equal to <tt>last_time</tt> minus
-<tt>show_time</tt>. <tt>show_time</tt> overrides <tt>first_time</tt>.</p>
-
-<p>The display normally shows the latest 200 events that occurred in the
-given interval, where each timestamp on the left hand edge counts as a single
-event. You can add a <tt>num_events=</tt> argument to override this this.</p>
-
-<h2>Showing non-Build events</h2>
-
-<p>By passing <tt>show_events=true</tt>, you can add the "buildslave
-attached", "buildslave detached", and "builder reconfigured" events that
-appear in-between the actual builds.</p>
-
-<p>
-<input type="checkbox" name="show_events" value="true"
-{% if show_events_checked %} checked="checked" {% endif %}/>
-Show non-Build events
-</p>
-
-<h2>Showing only Certain Branches</h2>
-
-<p>If you provide one or more <tt>branch=</tt> arguments, the display will be
-limited to builds that used one of the given branches. If no <tt>branch=</tt>
-arguments are given, builds from all branches will be displayed.</p>
-
-Erase the text from these "Show Branch:" boxes to remove that branch filter.
-
-{% if branches %}
-<table>
- {% for b in branches %}
- <tr>
- <td>Show Branch:
- <input type="text" name="branch" value="{{ b|e }}"/>
- </td>
- </tr>
- {% endfor %}
-</table>
-{% endif %}
-
-<h2>Limiting the Builders that are Displayed</h2>
-
-<p>By adding one or more <tt>builder=</tt> arguments, the display will be
-limited to showing builds that ran on the given builders. This serves to
-limit the display to the specific named columns. If no <tt>builder=</tt>
-arguments are provided, all Builders will be displayed.</p>
-
-<p>To view a Waterfall page with only a subset of Builders displayed, select
-the Builders you are interested in here.</p>
-
-<table>
-{% for bn in all_builders %}
- <tr><td><input type="checkbox" name="builder" value="{{ bn }}"
- {% if bn in show_builders %}checked="checked"{% endif %} />
- </td><td>{{bn}}</td></tr>
-{% endfor %}
-</table>
-
-<h2>Limiting the Builds that are Displayed</h2>
-
-<p>By adding one or more <tt>committer=</tt> arguments, the display will be
-limited to showing builds that were started by the given committer. If no
-<tt>committer=</tt> arguments are provided, all builds will be displayed.</p>
-
-<p>To view a Waterfall page with only a subset of Builds displayed, select
-the committers your are interested in here.</p>
-
-Erase the text from these "Show Committer:" boxes to remove that filter.
-
-{% if committers %}
- <table>
- {% for cn in committers %}
- <tr>
- <td>
- Show Committer: <input type="text" name="committer" value="{{ cn }}">
- </td>
- </tr>
- {% endfor %}
- </table>
-{% endif %}
-
-<h2>Showing only the Builders with failures</h2>
-
-<p>By adding the <tt>failures_only=true</tt> argument, the display will be limited
-to showing builders that are currently failing. A builder is considered
-failing if the last finished build was not successful, a step in the current
-build(s) failed, or if the builder is offline.</p>
-
-<p>
- <input type="checkbox" name="failures_only" value="true"
- {% if failures_only %}checked="checked"{% endif %}/>
- Show failures only
-</p>
-
-<h2>Auto-reloading the Page</h2>
-
-<p>Adding a <tt>reload=</tt> argument will cause the page to automatically
-reload itself after that many seconds.</p>
-
-<table>
-{% for value, name in times %}
- <tr><td><input type="radio" name="reload" value="{{ value|e }}"
- {% if value == current_reload_time %}checked="checked"{% endif %}/>
- </td><td>{{ name|e }}</td></tr>
-{% endfor %}
-</table>
-
-
-<h2>Reload Waterfall Page</h2>
-
-<input type="submit" value="View Waterfall" />
-</form>
-{% endblock %}
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/tests.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/tests.py
deleted file mode 100644
index 52622982..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/tests.py
+++ /dev/null
@@ -1,84 +0,0 @@
-# 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 urllib
-from buildbot.status.web.base import HtmlResource, path_to_builder, \
- path_to_build, css_classes
-from buildbot.status.builder import Results
-
-# /builders/$builder/builds/$buildnum/steps/$stepname
-class StatusResourceBuildTest(HtmlResource):
- pageTitle = "Test Result"
- addSlash = True
-
- def __init__(self, build_status, test_result):
- HtmlResource.__init__(self)
- self.status = build_status
- self.test_result = test_result
-
- def content(self, req, cxt):
- tr = self.test_result
- b = self.status
-
- cxt['b'] = self.status
- logs = cxt['logs'] = []
- for lname, log in tr.getLogs().items():
- if isinstance(log, str):
- log = log.decode('utf-8')
- logs.append({'name': lname,
- 'log': log,
- 'link': req.childLink("logs/%s" % urllib.quote(lname)) })
-
- cxt['text'] = tr.text
- cxt['result_word'] = Results[tr.getResults()]
- cxt.update(dict(builder_link = path_to_builder(req, b.getBuilder()),
- build_link = path_to_build(req, b),
- result_css = css_classes[tr.getResults()],
- b = b,
- tr = tr))
-
- template = req.site.buildbot_service.templates.get_template("testresult.html")
- return template.render(**cxt)
-
- def getChild(self, path, req):
- # if path == "logs":
- # return LogsResource(self.step_status) #TODO we need another class
- return HtmlResource.getChild(self, path, req)
-
-
-
-# /builders/$builder/builds/$buildnum/steps
-class TestsResource(HtmlResource):
- addSlash = True
- nameDelim = '.' # Test result have names like a.b.c
-
- def __init__(self, build_status):
- HtmlResource.__init__(self)
- self.build_status = build_status
-
- def content(self, req, ctx):
- # TODO list the tests
- return "subpages show data for each test"
-
- def getChild(self, path, req):
- tpath = None
- if path:
- tpath = tuple(path.split(self.nameDelim))
- if tpath:
- tr = self.build_status.getTestResults().get(tpath)
- if tr:
- return StatusResourceBuildTest(self.build_status, tr)
- return HtmlResource.getChild(self, path, req)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/users.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/users.py
deleted file mode 100644
index 953ae68f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/users.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# 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 urllib
-from twisted.internet import defer
-from twisted.web.util import redirectTo
-from buildbot.status.web.base import HtmlResource, path_to_authzfail, \
- path_to_root, ActionResource
-
-class UsersActionResource(ActionResource):
-
- def __init__(self):
- self.action = "showUsersPage"
-
- @defer.inlineCallbacks
- def performAction(self, req):
- res = yield self.getAuthz(req).actionAllowed('showUsersPage', req)
- if not res:
- defer.returnValue(path_to_authzfail(req))
- return
- # show the table
- defer.returnValue(path_to_root(req) + "users")
-
-# /users/$uid
-class OneUserResource(HtmlResource):
- addSlash = False
- def __init__(self, uid):
- HtmlResource.__init__(self)
- self.uid = int(uid)
-
- def getPageTitle (self, req):
- return "Buildbot User: %s" % self.uid
-
- def content(self, request, ctx):
- status = self.getStatus(request)
-
- d = status.master.db.users.getUser(self.uid)
- def cb(usdict):
- ctx['user_identifier'] = usdict['identifier']
- user = ctx['user'] = {}
- for attr in usdict:
- if attr not in ['uid', 'identifier', 'bb_password']:
- user[attr] = usdict[attr]
-
- template = request.site.buildbot_service.templates.get_template("user.html")
- data = template.render(**ctx)
- return data
- d.addCallback(cb)
- return d
-
-# /users
-class UsersResource(HtmlResource):
- pageTitle = "Users"
- addSlash = True
-
- def __init__(self):
- HtmlResource.__init__(self)
-
- def getChild(self, path, req):
- return OneUserResource(path)
-
- @defer.inlineCallbacks
- def content(self, req, ctx):
- res = yield self.getAuthz(req).actionAllowed('showUsersPage', req)
- if not res:
- defer.returnValue(redirectTo(path_to_authzfail(req), req))
- return
-
- s = self.getStatus(req)
-
- usdicts = yield s.master.db.users.getUsers()
- users = ctx['users'] = usdicts
-
- for user in users:
- user['user_link'] = req.childLink(urllib.quote(str(user['uid']), ''))
- template = req.site.buildbot_service.templates.get_template(
- "users.html")
- defer.returnValue(template.render(**ctx))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/waterfall.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/waterfall.py
deleted file mode 100644
index 681c5768..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/web/waterfall.py
+++ /dev/null
@@ -1,813 +0,0 @@
-# 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
-
-
-from zope.interface import implements
-from twisted.python import log, components
-from twisted.internet import defer
-import urllib
-
-import time, locale
-import operator
-
-from buildbot import interfaces, util
-from buildbot.status import builder, buildstep, build
-from buildbot.changes import changes
-
-from buildbot.status.web.base import Box, HtmlResource, IBox, ICurrentBox, \
- ITopBox, build_get_class, path_to_build, path_to_step, path_to_root, \
- map_branches
-
-
-def earlier(old, new):
- # minimum of two things, but "None" counts as +infinity
- if old:
- if new < old:
- return new
- return old
- return new
-
-def later(old, new):
- # maximum of two things, but "None" counts as -infinity
- if old:
- if new > old:
- return new
- return old
- return new
-
-
-class CurrentBox(components.Adapter):
- # this provides the "current activity" box, just above the builder name
- implements(ICurrentBox)
-
- def formatETA(self, prefix, eta):
- if eta is None:
- return []
- if eta < 60:
- return ["< 1 min"]
- eta_parts = ["~"]
- eta_secs = eta
- if eta_secs > 3600:
- eta_parts.append("%d hrs" % (eta_secs / 3600))
- eta_secs %= 3600
- if eta_secs > 60:
- eta_parts.append("%d mins" % (eta_secs / 60))
- eta_secs %= 60
- abstime = time.strftime("%H:%M", time.localtime(util.now()+eta))
- return [prefix, " ".join(eta_parts), "at %s" % abstime]
-
- def getBox(self, status, brcounts):
- # getState() returns offline, idle, or building
- state, builds = self.original.getState()
-
- # look for upcoming builds. We say the state is "waiting" if the
- # builder is otherwise idle and there is a scheduler which tells us a
- # build will be performed some time in the near future. TODO: this
- # functionality used to be in BuilderStatus.. maybe this code should
- # be merged back into it.
- upcoming = []
- builderName = self.original.getName()
- for s in status.getSchedulers():
- if builderName in s.listBuilderNames():
- upcoming.extend(s.getPendingBuildTimes())
- if state == "idle" and upcoming:
- state = "waiting"
-
- if state == "building":
- text = ["building"]
- if builds:
- for b in builds:
- eta = b.getETA()
- text.extend(self.formatETA("ETA in", eta))
- elif state == "offline":
- text = ["offline"]
- elif state == "idle":
- text = ["idle"]
- elif state == "waiting":
- text = ["waiting"]
- else:
- # just in case I add a state and forget to update this
- text = [state]
-
- # TODO: for now, this pending/upcoming stuff is in the "current
- # activity" box, but really it should go into a "next activity" row
- # instead. The only times it should show up in "current activity" is
- # when the builder is otherwise idle.
-
- # are any builds pending? (waiting for a slave to be free)
- brcount = brcounts[builderName]
- if brcount:
- text.append("%d pending" % brcount)
- for t in sorted(upcoming):
- if t is not None:
- eta = t - util.now()
- text.extend(self.formatETA("next in", eta))
- return Box(text, class_="Activity " + state)
-
-components.registerAdapter(CurrentBox, builder.BuilderStatus, ICurrentBox)
-
-
-class BuildTopBox(components.Adapter):
- # this provides a per-builder box at the very top of the display,
- # showing the results of the most recent build
- implements(IBox)
-
- def getBox(self, req):
- assert interfaces.IBuilderStatus(self.original)
- branches = [b for b in req.args.get("branch", []) if b]
- builder = self.original
- builds = list(builder.generateFinishedBuilds(map_branches(branches),
- num_builds=1))
- if not builds:
- return Box(["none"], class_="LastBuild")
- b = builds[0]
- url = path_to_build(req, b)
- text = b.getText()
- tests_failed = b.getSummaryStatistic('tests-failed', operator.add, 0)
- if tests_failed: text.extend(["Failed tests: %d" % tests_failed])
- # TODO: maybe add logs?
- class_ = build_get_class(b)
- return Box(text, urlbase=url, class_="LastBuild %s" % class_)
-components.registerAdapter(BuildTopBox, builder.BuilderStatus, ITopBox)
-
-class BuildBox(components.Adapter):
- # this provides the yellow "starting line" box for each build
- implements(IBox)
-
- def getBox(self, req):
- b = self.original
- number = b.getNumber()
- url = path_to_build(req, b)
- reason = b.getReason()
- template = req.site.buildbot_service.templates.get_template("box_macros.html")
- text = template.module.build_box(reason=reason,url=url,number=number)
- class_ = "start"
- if b.isFinished() and not b.getSteps():
- # the steps have been pruned, so there won't be any indication
- # of whether it succeeded or failed.
- class_ = build_get_class(b)
- return Box([text], class_="BuildStep " + class_)
-components.registerAdapter(BuildBox, build.BuildStatus, IBox)
-
-class StepBox(components.Adapter):
- implements(IBox)
-
- def getBox(self, req):
- urlbase = path_to_step(req, self.original)
- text = self.original.getText()
- if text is None:
- log.msg("getText() gave None", urlbase)
- text = []
- text = text[:]
- logs = self.original.getLogs()
-
- cxt = dict(text=text, logs=[], urls=[], stepinfo=self)
-
- for num in range(len(logs)):
- name = logs[num].getName()
- if logs[num].hasContents():
- url = urlbase + "/logs/%s" % urllib.quote(name)
- else:
- url = None
- cxt['logs'].append(dict(name=name, url=url))
-
- for name, target in self.original.getURLs().items():
- cxt['urls'].append(dict(link=target,name=name))
-
- template = req.site.buildbot_service.templates.get_template("box_macros.html")
- text = template.module.step_box(**cxt)
-
- class_ = "BuildStep " + build_get_class(self.original)
- return Box(text, class_=class_)
-components.registerAdapter(StepBox, buildstep.BuildStepStatus, IBox)
-
-
-class EventBox(components.Adapter):
- implements(IBox)
-
- def getBox(self, req):
- text = self.original.getText()
- class_ = "Event"
- return Box(text, class_=class_)
-components.registerAdapter(EventBox, builder.Event, IBox)
-
-
-class Spacer:
- implements(interfaces.IStatusEvent)
-
- def __init__(self, start, finish):
- self.started = start
- self.finished = finish
-
- def getTimes(self):
- return (self.started, self.finished)
- def getText(self):
- return []
-
-class SpacerBox(components.Adapter):
- implements(IBox)
-
- def getBox(self, req):
- #b = Box(["spacer"], "white")
- b = Box([])
- b.spacer = True
- return b
-components.registerAdapter(SpacerBox, Spacer, IBox)
-
-def insertGaps(g, showEvents, lastEventTime, idleGap=2):
- debug = False
-
- e = g.next()
- starts, finishes = e.getTimes()
- if debug: log.msg("E0", starts, finishes)
- if finishes == 0:
- finishes = starts
- if debug: log.msg("E1 finishes=%s, gap=%s, lET=%s" % \
- (finishes, idleGap, lastEventTime))
- if finishes is not None and finishes + idleGap < lastEventTime:
- if debug: log.msg(" spacer0")
- yield Spacer(finishes, lastEventTime)
-
- followingEventStarts = starts
- if debug: log.msg(" fES0", starts)
- yield e
-
- while 1:
- e = g.next()
- if not showEvents and isinstance(e, builder.Event):
- continue
- starts, finishes = e.getTimes()
- if debug: log.msg("E2", starts, finishes)
- if finishes == 0:
- finishes = starts
- if finishes is not None and finishes + idleGap < followingEventStarts:
- # there is a gap between the end of this event and the beginning
- # of the next one. Insert an idle event so the waterfall display
- # shows a gap here.
- if debug:
- log.msg(" finishes=%s, gap=%s, fES=%s" % \
- (finishes, idleGap, followingEventStarts))
- yield Spacer(finishes, followingEventStarts)
- yield e
- followingEventStarts = starts
- if debug: log.msg(" fES1", starts)
-
-
-class WaterfallHelp(HtmlResource):
- pageTitle = "Waterfall Help"
-
- def __init__(self, categories=None):
- HtmlResource.__init__(self)
- self.categories = categories
-
- def content(self, request, cxt):
- status = self.getStatus(request)
-
- cxt['show_events_checked'] = request.args.get("show_events", ["false"])[0].lower() == "true"
- cxt['branches'] = [b for b in request.args.get("branch", []) if b]
- cxt['failures_only'] = request.args.get("failures_only", ["false"])[0].lower() == "true"
- cxt['committers'] = [c for c in request.args.get("committer", []) if c]
-
- # this has a set of toggle-buttons to let the user choose the
- # builders
- show_builders = request.args.get("show", [])
- show_builders.extend(request.args.get("builder", []))
- cxt['show_builders'] = show_builders
- cxt['all_builders'] = status.getBuilderNames(categories=self.categories)
-
- # a couple of radio-button selectors for refresh time will appear
- # just after that text
- times = [("none", "None"),
- ("60", "60 seconds"),
- ("300", "5 minutes"),
- ("600", "10 minutes"),
- ]
- current_reload_time = request.args.get("reload", ["none"])
- if current_reload_time:
- current_reload_time = current_reload_time[0]
- if current_reload_time not in [t[0] for t in times]:
- times.insert(0, (current_reload_time, current_reload_time) )
-
- cxt['times'] = times
- cxt['current_reload_time'] = current_reload_time
-
- template = request.site.buildbot_service.templates.get_template("waterfallhelp.html")
- return template.render(**cxt)
-
-
-class ChangeEventSource(object):
- "A wrapper around a list of changes to supply the IEventSource interface"
- def __init__(self, changes):
- self.changes = changes
- # we want them in newest-to-oldest order
- self.changes.reverse()
-
- def eventGenerator(self, branches, categories, committers, minTime):
- for change in self.changes:
- if branches and change.branch not in branches:
- continue
- if categories and change.category not in categories:
- continue
- if committers and change.author not in committers:
- continue
- if minTime and change.when < minTime:
- continue
- yield change
-
-class WaterfallStatusResource(HtmlResource):
- """This builds the main status page, with the waterfall display, and
- all child pages."""
-
- def __init__(self, categories=None, num_events=200, num_events_max=None):
- HtmlResource.__init__(self)
- self.categories = categories
- self.num_events=num_events
- self.num_events_max=num_events_max
- self.putChild("help", WaterfallHelp(categories))
-
- def getPageTitle(self, request):
- status = self.getStatus(request)
- p = status.getTitle()
- if p:
- return "BuildBot: %s" % p
- else:
- return "BuildBot"
-
- def getChangeManager(self, request):
- # TODO: this wants to go away, access it through IStatus
- return request.site.buildbot_service.getChangeSvc()
-
- def get_reload_time(self, request):
- if "reload" in request.args:
- try:
- reload_time = int(request.args["reload"][0])
- return max(reload_time, 15)
- except ValueError:
- pass
- return None
-
- def isSuccess(self, builderStatus):
- # Helper function to return True if the builder is not failing.
- # The function will return false if the current state is "offline",
- # the last build was not successful, or if a step from the current
- # build(s) failed.
-
- # Make sure the builder is online.
- if builderStatus.getState()[0] == 'offline':
- return False
-
- # Look at the last finished build to see if it was success or not.
- lastBuild = builderStatus.getLastFinishedBuild()
- if lastBuild and lastBuild.getResults() != builder.SUCCESS:
- return False
-
- # Check all the current builds to see if one step is already
- # failing.
- currentBuilds = builderStatus.getCurrentBuilds()
- if currentBuilds:
- for build in currentBuilds:
- for step in build.getSteps():
- if step.getResults()[0] == builder.FAILURE:
- return False
-
- # The last finished build was successful, and all the current builds
- # don't have any failed steps.
- return True
-
- def content(self, request, ctx):
- status = self.getStatus(request)
- master = request.site.buildbot_service.master
-
- # before calling content_with_db_data, make a bunch of database
- # queries. This is a sick hack, but beats rewriting the entire
- # waterfall around asynchronous calls
-
- results = {}
-
- # recent changes
- changes_d = master.db.changes.getRecentChanges(40)
- def to_changes(chdicts):
- return defer.gatherResults([
- changes.Change.fromChdict(master, chdict)
- for chdict in chdicts ])
- changes_d.addCallback(to_changes)
- def keep_changes(changes):
- results['changes'] = changes
- changes_d.addCallback(keep_changes)
-
- # build request counts for each builder
- allBuilderNames = status.getBuilderNames(categories=self.categories)
- brstatus_ds = []
- brcounts = {}
- def keep_count(statuses, builderName):
- brcounts[builderName] = len(statuses)
- for builderName in allBuilderNames:
- builder_status = status.getBuilder(builderName)
- d = builder_status.getPendingBuildRequestStatuses()
- d.addCallback(keep_count, builderName)
- brstatus_ds.append(d)
-
- # wait for it all to finish
- d = defer.gatherResults([ changes_d ] + brstatus_ds)
- def call_content(_):
- return self.content_with_db_data(results['changes'],
- brcounts, request, ctx)
- d.addCallback(call_content)
- return d
-
- def content_with_db_data(self, changes, brcounts, request, ctx):
- status = self.getStatus(request)
- ctx['refresh'] = self.get_reload_time(request)
-
- # we start with all Builders available to this Waterfall: this is
- # limited by the config-file -time categories= argument, and defaults
- # to all defined Builders.
- allBuilderNames = status.getBuilderNames(categories=self.categories)
- builders = [status.getBuilder(name) for name in allBuilderNames]
-
- # but if the URL has one or more builder= arguments (or the old show=
- # argument, which is still accepted for backwards compatibility), we
- # use that set of builders instead. We still don't show anything
- # outside the config-file time set limited by categories=.
- showBuilders = request.args.get("show", [])
- showBuilders.extend(request.args.get("builder", []))
- if showBuilders:
- builders = [b for b in builders if b.name in showBuilders]
-
- # now, if the URL has one or category= arguments, use them as a
- # filter: only show those builders which belong to one of the given
- # categories.
- showCategories = request.args.get("category", [])
- if showCategories:
- builders = [b for b in builders if b.category in showCategories]
-
- # If the URL has the failures_only=true argument, we remove all the
- # builders that are not currently red or won't be turning red at the end
- # of their current run.
- failuresOnly = request.args.get("failures_only", ["false"])[0]
- if failuresOnly.lower() == "true":
- builders = [b for b in builders if not self.isSuccess(b)]
-
- (changeNames, builderNames, timestamps, eventGrid, sourceEvents) = \
- self.buildGrid(request, builders, changes)
-
- # start the table: top-header material
- locale_enc = locale.getdefaultlocale()[1]
- if locale_enc is not None:
- locale_tz = unicode(time.tzname[time.localtime()[-1]], locale_enc)
- else:
- locale_tz = unicode(time.tzname[time.localtime()[-1]])
- ctx['tz'] = locale_tz
- ctx['changes_url'] = request.childLink("../changes")
-
- bn = ctx['builders'] = []
-
- for name in builderNames:
- builder = status.getBuilder(name)
- top_box = ITopBox(builder).getBox(request)
- current_box = ICurrentBox(builder).getBox(status, brcounts)
- bn.append({'name': name,
- 'url': request.childLink("../builders/%s" % urllib.quote(name, safe='')),
- 'top': top_box.text,
- 'top_class': top_box.class_,
- 'status': current_box.text,
- 'status_class': current_box.class_,
- })
-
- ctx.update(self.phase2(request, changeNames + builderNames, timestamps, eventGrid,
- sourceEvents))
-
- def with_args(req, remove_args=[], new_args=[], new_path=None):
- # sigh, nevow makes this sort of manipulation easier
- newargs = req.args.copy()
- for argname in remove_args:
- newargs[argname] = []
- if "branch" in newargs:
- newargs["branch"] = [b for b in newargs["branch"] if b]
- for k,v in new_args:
- if k in newargs:
- newargs[k].append(v)
- else:
- newargs[k] = [v]
- newquery = "&amp;".join(["%s=%s" % (urllib.quote(k), urllib.quote(v))
- for k in newargs
- for v in newargs[k]
- ])
- if new_path:
- new_url = new_path
- elif req.prepath:
- new_url = req.prepath[-1]
- else:
- new_url = ''
- if newquery:
- new_url += "?" + newquery
- return new_url
-
- if timestamps:
- bottom = timestamps[-1]
- ctx['nextpage'] = with_args(request, ["last_time"],
- [("last_time", str(int(bottom)))])
-
-
- helpurl = path_to_root(request) + "waterfall/help"
- ctx['help_url'] = with_args(request, new_path=helpurl)
-
- if self.get_reload_time(request) is not None:
- ctx['no_reload_page'] = with_args(request, remove_args=["reload"])
-
- template = request.site.buildbot_service.templates.get_template("waterfall.html")
- data = template.render(**ctx)
- return data
-
- def buildGrid(self, request, builders, changes):
- debug = False
- # TODO: see if we can use a cached copy
-
- showEvents = False
- if request.args.get("show_events", ["false"])[0].lower() == "true":
- showEvents = True
- filterCategories = request.args.get('category', [])
- filterBranches = [b for b in request.args.get("branch", []) if b]
- filterBranches = map_branches(filterBranches)
- filterCommitters = [c for c in request.args.get("committer", []) if c]
- maxTime = int(request.args.get("last_time", [util.now()])[0])
- if "show_time" in request.args:
- minTime = maxTime - int(request.args["show_time"][0])
- elif "first_time" in request.args:
- minTime = int(request.args["first_time"][0])
- elif filterBranches or filterCommitters:
- minTime = util.now() - 24 * 60 * 60
- else:
- minTime = 0
- spanLength = 10 # ten-second chunks
- req_events=int(request.args.get("num_events", [self.num_events])[0])
- if self.num_events_max and req_events > self.num_events_max:
- maxPageLen = self.num_events_max
- else:
- maxPageLen = req_events
-
- # first step is to walk backwards in time, asking each column
- # (commit, all builders) if they have any events there. Build up the
- # array of events, and stop when we have a reasonable number.
-
- commit_source = ChangeEventSource(changes)
-
- lastEventTime = util.now()
- sources = [commit_source] + builders
- changeNames = ["changes"]
- builderNames = map(lambda builder: builder.getName(), builders)
- sourceNames = changeNames + builderNames
- sourceEvents = []
- sourceGenerators = []
-
- def get_event_from(g):
- try:
- while True:
- e = g.next()
- # e might be buildstep.BuildStepStatus,
- # builder.BuildStatus, builder.Event,
- # waterfall.Spacer(builder.Event), or changes.Change .
- # The showEvents=False flag means we should hide
- # builder.Event .
- if not showEvents and isinstance(e, builder.Event):
- continue
-
- if isinstance(e, buildstep.BuildStepStatus):
- # unfinished steps are always shown
- if e.isFinished() and e.isHidden():
- continue
-
- break
- event = interfaces.IStatusEvent(e)
- if debug:
- log.msg("gen %s gave1 %s" % (g, event.getText()))
- except StopIteration:
- event = None
- return event
-
- for s in sources:
- gen = insertGaps(s.eventGenerator(filterBranches,
- filterCategories,
- filterCommitters,
- minTime),
- showEvents,
- lastEventTime)
- sourceGenerators.append(gen)
- # get the first event
- sourceEvents.append(get_event_from(gen))
- eventGrid = []
- timestamps = []
-
- lastEventTime = 0
- for e in sourceEvents:
- if e and e.getTimes()[0] > lastEventTime:
- lastEventTime = e.getTimes()[0]
- if lastEventTime == 0:
- lastEventTime = util.now()
-
- spanStart = lastEventTime - spanLength
- debugGather = 0
-
- while 1:
- if debugGather: log.msg("checking (%s,]" % spanStart)
- # the tableau of potential events is in sourceEvents[]. The
- # window crawls backwards, and we examine one source at a time.
- # If the source's top-most event is in the window, is it pushed
- # onto the events[] array and the tableau is refilled. This
- # continues until the tableau event is not in the window (or is
- # missing).
-
- spanEvents = [] # for all sources, in this span. row of eventGrid
- firstTimestamp = None # timestamp of first event in the span
- lastTimestamp = None # last pre-span event, for next span
-
- for c in range(len(sourceGenerators)):
- events = [] # for this source, in this span. cell of eventGrid
- event = sourceEvents[c]
- while event and spanStart < event.getTimes()[0]:
- # to look at windows that don't end with the present,
- # condition the .append on event.time <= spanFinish
- if not IBox(event, None):
- log.msg("BAD EVENT", event, event.getText())
- assert 0
- if debug:
- log.msg("pushing", event.getText(), event)
- events.append(event)
- starts, finishes = event.getTimes()
- firstTimestamp = earlier(firstTimestamp, starts)
- event = get_event_from(sourceGenerators[c])
- if debug:
- log.msg("finished span")
-
- if event:
- # this is the last pre-span event for this source
- lastTimestamp = later(lastTimestamp,
- event.getTimes()[0])
- if debugGather:
- log.msg(" got %s from %s" % (events, sourceNames[c]))
- sourceEvents[c] = event # refill the tableau
- spanEvents.append(events)
-
- # only show events older than maxTime. This makes it possible to
- # visit a page that shows what it would be like to scroll off the
- # bottom of this one.
- if firstTimestamp is not None and firstTimestamp <= maxTime:
- eventGrid.append(spanEvents)
- timestamps.append(firstTimestamp)
-
- if lastTimestamp:
- spanStart = lastTimestamp - spanLength
- else:
- # no more events
- break
- if minTime is not None and lastTimestamp < minTime:
- break
-
- if len(timestamps) > maxPageLen:
- break
-
-
- # now loop
-
- # loop is finished. now we have eventGrid[] and timestamps[]
- if debugGather: log.msg("finished loop")
- assert(len(timestamps) == len(eventGrid))
- return (changeNames, builderNames, timestamps, eventGrid, sourceEvents)
-
- def phase2(self, request, sourceNames, timestamps, eventGrid,
- sourceEvents):
-
- if not timestamps:
- return dict(grid=[], gridlen=0)
-
- # first pass: figure out the height of the chunks, populate grid
- grid = []
- for i in range(1+len(sourceNames)):
- grid.append([])
- # grid is a list of columns, one for the timestamps, and one per
- # event source. Each column is exactly the same height. Each element
- # of the list is a single <td> box.
- lastDate = time.strftime("%d %b %Y",
- time.localtime(util.now()))
- for r in range(0, len(timestamps)):
- chunkstrip = eventGrid[r]
- # chunkstrip is a horizontal strip of event blocks. Each block
- # is a vertical list of events, all for the same source.
- assert(len(chunkstrip) == len(sourceNames))
- maxRows = reduce(lambda x,y: max(x,y),
- map(lambda x: len(x), chunkstrip))
- for i in range(maxRows):
- if i != maxRows-1:
- grid[0].append(None)
- else:
- # timestamp goes at the bottom of the chunk
- stuff = []
- # add the date at the beginning (if it is not the same as
- # today's date), and each time it changes
- todayday = time.strftime("%a",
- time.localtime(timestamps[r]))
- today = time.strftime("%d %b %Y",
- time.localtime(timestamps[r]))
- if today != lastDate:
- stuff.append(todayday)
- stuff.append(today)
- lastDate = today
- stuff.append(
- time.strftime("%H:%M:%S",
- time.localtime(timestamps[r])))
- grid[0].append(Box(text=stuff, class_="Time",
- valign="bottom", align="center"))
-
- # at this point the timestamp column has been populated with
- # maxRows boxes, most None but the last one has the time string
- for c in range(0, len(chunkstrip)):
- block = chunkstrip[c]
- assert(block != None) # should be [] instead
- for i in range(maxRows - len(block)):
- # fill top of chunk with blank space
- grid[c+1].append(None)
- for i in range(len(block)):
- # so the events are bottom-justified
- b = IBox(block[i]).getBox(request)
- b.parms['valign'] = "top"
- b.parms['align'] = "center"
- grid[c+1].append(b)
- # now all the other columns have maxRows new boxes too
- # populate the last row, if empty
- gridlen = len(grid[0])
- for i in range(len(grid)):
- strip = grid[i]
- assert(len(strip) == gridlen)
- if strip[-1] == None:
- if sourceEvents[i-1]:
- filler = IBox(sourceEvents[i-1]).getBox(request)
- else:
- # this can happen if you delete part of the build history
- filler = Box(text=["?"], align="center")
- strip[-1] = filler
- strip[-1].parms['rowspan'] = 1
- # second pass: bubble the events upwards to un-occupied locations
- # Every square of the grid that has a None in it needs to have
- # something else take its place.
- noBubble = request.args.get("nobubble",['0'])
- noBubble = int(noBubble[0])
- if not noBubble:
- for col in range(len(grid)):
- strip = grid[col]
- if col == 1: # changes are handled differently
- for i in range(2, len(strip)+1):
- # only merge empty boxes. Don't bubble commit boxes.
- if strip[-i] == None:
- next = strip[-i+1]
- assert(next)
- if next:
- #if not next.event:
- if next.spacer:
- # bubble the empty box up
- strip[-i] = next
- strip[-i].parms['rowspan'] += 1
- strip[-i+1] = None
- else:
- # we are above a commit box. Leave it
- # be, and turn the current box into an
- # empty one
- strip[-i] = Box([], rowspan=1,
- comment="commit bubble")
- strip[-i].spacer = True
- else:
- # we are above another empty box, which
- # somehow wasn't already converted.
- # Shouldn't happen
- pass
- else:
- for i in range(2, len(strip)+1):
- # strip[-i] will go from next-to-last back to first
- if strip[-i] == None:
- # bubble previous item up
- assert(strip[-i+1] != None)
- strip[-i] = strip[-i+1]
- strip[-i].parms['rowspan'] += 1
- strip[-i+1] = None
- else:
- strip[-i].parms['rowspan'] = 1
-
- # convert to dicts
- for i in range(gridlen):
- for strip in grid:
- if strip[i]:
- strip[i] = strip[i].td()
-
- return dict(grid=grid, gridlen=gridlen, no_bubble=noBubble, time=lastDate)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/words.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/words.py
deleted file mode 100644
index 32565ac6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/status/words.py
+++ /dev/null
@@ -1,1097 +0,0 @@
-# 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 re, shlex, random
-from string import join, capitalize, lower
-
-from zope.interface import implements
-from twisted.internet import protocol, reactor
-from twisted.words.protocols import irc
-from twisted.python import usage, log
-from twisted.application import internet
-from twisted.internet import defer, task
-
-from buildbot import config, interfaces, util
-from buildbot import version
-from buildbot.interfaces import IStatusReceiver
-from buildbot.sourcestamp import SourceStamp
-from buildbot.status import base
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE, EXCEPTION, RETRY
-from buildbot.process.properties import Properties
-
-# twisted.internet.ssl requires PyOpenSSL, so be resilient if it's missing
-try:
- from twisted.internet import ssl
- have_ssl = True
-except ImportError:
- have_ssl = False
-
-def maybeColorize(text, color, useColors):
- irc_colors = [
- 'WHITE',
- 'BLACK',
- 'NAVY_BLUE',
- 'GREEN',
- 'RED',
- 'BROWN',
- 'PURPLE',
- 'OLIVE',
- 'YELLOW',
- 'LIME_GREEN',
- 'TEAL',
- 'AQUA_LIGHT',
- 'ROYAL_BLUE',
- 'HOT_PINK',
- 'DARK_GRAY',
- 'LIGHT_GRAY'
- ]
-
- if useColors:
- return "%c%d%s%c" % (3, irc_colors.index(color), text, 3)
- else:
- return text
-
-class UsageError(ValueError):
- def __init__(self, string = "Invalid usage", *more):
- ValueError.__init__(self, string, *more)
-
-class ForceOptions(usage.Options):
- optParameters = [
- ["builder", None, None, "which Builder to start"],
- ["branch", None, None, "which branch to build"],
- ["revision", None, None, "which revision to build"],
- ["reason", None, None, "the reason for starting the build"],
- ["props", None, None,
- "A set of properties made available in the build environment, "
- "format is --properties=prop1=value1,prop2=value2,.. "
- "option can be specified multiple times."],
- ]
-
- def parseArgs(self, *args):
- args = list(args)
- if len(args) > 0:
- if self['builder'] is not None:
- raise UsageError("--builder provided in two ways")
- self['builder'] = args.pop(0)
- if len(args) > 0:
- if self['reason'] is not None:
- raise UsageError("--reason provided in two ways")
- self['reason'] = " ".join(args)
-
-
-class IrcBuildRequest:
- hasStarted = False
- timer = None
-
- def __init__(self, parent, useRevisions=False, useColors=True):
- self.parent = parent
- self.useRevisions = useRevisions
- self.useColors = useColors
- self.timer = reactor.callLater(5, self.soon)
-
- def soon(self):
- del self.timer
- if not self.hasStarted:
- self.parent.send("The build has been queued, I'll give a shout"
- " when it starts")
-
- def started(self, s):
- self.hasStarted = True
- if self.timer:
- self.timer.cancel()
- del self.timer
- eta = s.getETA()
- if self.useRevisions:
- response = "build containing revision(s) [%s] forced" % s.getRevisions()
- else:
- response = "build #%d forced" % s.getNumber()
- if eta is not None:
- response = "build forced [ETA %s]" % self.parent.convertTime(eta)
- self.parent.send(response)
- self.parent.send("I'll give a shout when the build finishes")
- d = s.waitUntilFinished()
- d.addCallback(self.parent.watchedBuildFinished)
-
-class IRCContact(base.StatusReceiver):
- implements(IStatusReceiver)
- """I hold the state for a single user's interaction with the buildbot.
-
- There will be one instance of me for each user who interacts personally
- with the buildbot. There will be an additional instance for each
- 'broadcast contact' (chat rooms, IRC channels as a whole).
- """
-
- def __init__(self, bot, dest):
- self.bot = bot
- self.master = bot.master
- self.notify_events = {}
- self.subscribed = 0
- self.muted = False
- self.useRevisions = bot.useRevisions
- self.useColors = bot.useColors
- self.reported_builds = [] # tuples (when, buildername, buildnum)
- self.add_notification_events(bot.notify_events)
-
- # when people send us public messages ("buildbot: command"),
- # self.dest is the name of the channel ("#twisted"). When they send
- # us private messages (/msg buildbot command), self.dest is their
- # username.
- self.dest = dest
-
- # silliness
-
- silly = {
- "What happen ?": [ "Somebody set up us the bomb." ],
- "It's You !!": ["How are you gentlemen !!",
- "All your base are belong to us.",
- "You are on the way to destruction."],
- "What you say !!": ["You have no chance to survive make your time.",
- "HA HA HA HA ...."],
- }
-
- def doSilly(self, message):
- response = self.silly[message]
- when = 0.5
- for r in response:
- reactor.callLater(when, self.send, r)
- when += 2.5
-
- def getBuilder(self, which):
- try:
- b = self.bot.status.getBuilder(which)
- except KeyError:
- raise UsageError, "no such builder '%s'" % which
- return b
-
- def getControl(self, which):
- if not self.bot.control:
- raise UsageError("builder control is not enabled")
- try:
- bc = self.bot.control.getBuilder(which)
- except KeyError:
- raise UsageError("no such builder '%s'" % which)
- return bc
-
- def getAllBuilders(self):
- """
- @rtype: list of L{buildbot.process.builder.Builder}
- """
- names = self.bot.status.getBuilderNames(categories=self.bot.categories)
- names.sort()
- builders = [self.bot.status.getBuilder(n) for n in names]
- return builders
-
- def convertTime(self, seconds):
- if seconds < 60:
- return "%d seconds" % seconds
- minutes = int(seconds / 60)
- seconds = seconds - 60*minutes
- if minutes < 60:
- return "%dm%02ds" % (minutes, seconds)
- hours = int(minutes / 60)
- minutes = minutes - 60*hours
- return "%dh%02dm%02ds" % (hours, minutes, seconds)
-
- def reportBuild(self, builder, buildnum):
- """Returns True if this build should be reported for this contact
- (eliminating duplicates), and also records the report for later"""
- for w, b, n in self.reported_builds:
- if b == builder and n == buildnum:
- return False
- self.reported_builds.append([util.now(), builder, buildnum])
-
- # clean the reported builds
- horizon = util.now() - 60
- while self.reported_builds and self.reported_builds[0][0] < horizon:
- self.reported_builds.pop(0)
-
- # and return True, since this is a new one
- return True
-
- def splitArgs(self, args):
- """Returns list of arguments parsed by shlex.split() or
- raise UsageError if failed"""
- try:
- return shlex.split(args)
- except ValueError, e:
- raise UsageError(e)
-
- def command_HELLO(self, args, who):
- self.send("yes?")
-
- def command_VERSION(self, args, who):
- self.send("buildbot-%s at your service" % version)
-
- def command_LIST(self, args, who):
- args = self.splitArgs(args)
- if len(args) == 0:
- raise UsageError, "try 'list builders'"
- if args[0] == 'builders':
- builders = self.getAllBuilders()
- str = "Configured builders: "
- for b in builders:
- str += b.name
- state = b.getState()[0]
- if state == 'offline':
- str += "[offline]"
- str += " "
- str.rstrip()
- self.send(str)
- return
- command_LIST.usage = "list builders - List configured builders"
-
- def command_STATUS(self, args, who):
- args = self.splitArgs(args)
- if len(args) == 0:
- which = "all"
- elif len(args) == 1:
- which = args[0]
- else:
- raise UsageError, "try 'status <builder>'"
- if which == "all":
- builders = self.getAllBuilders()
- for b in builders:
- self.emit_status(b.name)
- return
- self.emit_status(which)
- command_STATUS.usage = "status [<which>] - List status of a builder (or all builders)"
-
- def validate_notification_event(self, event):
- if not re.compile("^(started|finished|success|failure|exception|warnings|(success|warnings|exception|failure)To(Failure|Success|Warnings|Exception))$").match(event):
- raise UsageError("try 'notify on|off <EVENT>'")
-
- def list_notified_events(self):
- self.send( "The following events are being notified: %r" % self.notify_events.keys() )
-
- def notify_for(self, *events):
- for event in events:
- if self.notify_events.has_key(event):
- return 1
- return 0
-
- def subscribe_to_build_events(self):
- self.bot.status.subscribe(self)
- self.subscribed = 1
-
- def unsubscribe_from_build_events(self):
- self.bot.status.unsubscribe(self)
- self.subscribed = 0
-
- def add_notification_events(self, events):
- for event in events:
- self.validate_notification_event(event)
- self.notify_events[event] = 1
-
- if not self.subscribed:
- self.subscribe_to_build_events()
-
- def remove_notification_events(self, events):
- for event in events:
- self.validate_notification_event(event)
- del self.notify_events[event]
-
- if len(self.notify_events) == 0 and self.subscribed:
- self.unsubscribe_from_build_events()
-
- def remove_all_notification_events(self):
- self.notify_events = {}
-
- if self.subscribed:
- self.unsubscribe_from_build_events()
-
- def command_NOTIFY(self, args, who):
- args = self.splitArgs(args)
-
- if not args:
- raise UsageError("try 'notify on|off|list <EVENT>'")
- action = args.pop(0)
- events = args
-
- if action == "on":
- if not events: events = ('started','finished')
- self.add_notification_events(events)
-
- self.list_notified_events()
-
- elif action == "off":
- if events:
- self.remove_notification_events(events)
- else:
- self.remove_all_notification_events()
-
- self.list_notified_events()
-
- elif action == "list":
- self.list_notified_events()
- return
-
- else:
- raise UsageError("try 'notify on|off <EVENT>'")
-
- command_NOTIFY.usage = "notify on|off|list [<EVENT>] ... - Notify me about build events. event should be one or more of: 'started', 'finished', 'failure', 'success', 'exception' or 'xToY' (where x and Y are one of success, warnings, failure, exception, but Y is capitalized)"
-
- def command_WATCH(self, args, who):
- args = self.splitArgs(args)
- if len(args) != 1:
- raise UsageError("try 'watch <builder>'")
- which = args[0]
- b = self.getBuilder(which)
- builds = b.getCurrentBuilds()
- if not builds:
- self.send("there are no builds currently running")
- return
- for build in builds:
- assert not build.isFinished()
- d = build.waitUntilFinished()
- d.addCallback(self.watchedBuildFinished)
- if self.useRevisions:
- r = "watching build %s containing revision(s) [%s] until it finishes" \
- % (which, build.getRevisions())
- else:
- r = "watching build %s #%d until it finishes" \
- % (which, build.getNumber())
- eta = build.getETA()
- if eta is not None:
- r += " [%s]" % self.convertTime(eta)
- r += ".."
- self.send(r)
- command_WATCH.usage = "watch <which> - announce the completion of an active build"
-
- def builderAdded(self, builderName, builder):
- if (self.bot.categories != None and
- builder.category not in self.bot.categories):
- return
-
- log.msg('[Contact] Builder %s added' % (builder))
- builder.subscribe(self)
-
- def builderRemoved(self, builderName):
- log.msg('[Contact] Builder %s removed' % (builderName))
-
- def buildStarted(self, builderName, build):
- builder = build.getBuilder()
- log.msg('[Contact] Builder %r in category %s started' % (builder, builder.category))
-
- # only notify about builders we are interested in
-
- if (self.bot.categories != None and
- builder.category not in self.bot.categories):
- log.msg('Not notifying for a build in the wrong category')
- return
-
- if not self.notify_for('started'):
- return
-
- if self.useRevisions:
- r = "build containing revision(s) [%s] on %s started" % \
- (build.getRevisions(), builder.getName())
- else:
- r = "build #%d of %s started, including [%s]" % \
- (build.getNumber(),
- builder.getName(),
- ", ".join([str(c.revision) for c in build.getChanges()])
- )
-
- self.send(r)
-
- results_descriptions = {
- SUCCESS: ("Success", 'GREEN'),
- WARNINGS: ("Warnings", 'YELLOW'),
- FAILURE: ("Failure", 'RED'),
- EXCEPTION: ("Exception", 'PURPLE'),
- RETRY: ("Retry", 'AQUA_LIGHT'),
- }
-
- def getResultsDescriptionAndColor(self, results):
- return self.results_descriptions.get(results, ("??",'RED'))
-
- def buildFinished(self, builderName, build, results):
- builder = build.getBuilder()
-
- if (self.bot.categories != None and
- builder.category not in self.bot.categories):
- return
-
- if not self.notify_for_finished(build):
- return
-
- builder_name = builder.getName()
- buildnum = build.getNumber()
- buildrevs = build.getRevisions()
-
- results = self.getResultsDescriptionAndColor(build.getResults())
- if self.reportBuild(builder_name, buildnum):
- if self.useRevisions:
- r = "build containing revision(s) [%s] on %s is complete: %s" % \
- (buildrevs, builder_name, results[0])
- else:
- r = "build #%d of %s is complete: %s" % \
- (buildnum, builder_name, results[0])
-
- r += ' [%s]' % maybeColorize(" ".join(build.getText()), results[1], self.useColors)
- buildurl = self.bot.status.getURLForThing(build)
- if buildurl:
- r += " Build details are at %s" % buildurl
-
- if self.bot.showBlameList and build.getResults() != SUCCESS and len(build.changes) != 0:
- r += ' blamelist: ' + ', '.join(list(set([c.who for c in build.changes])))
-
- self.send(r)
-
- def notify_for_finished(self, build):
- results = build.getResults()
-
- if self.notify_for('finished'):
- return True
-
- if self.notify_for(lower(self.results_descriptions.get(results)[0])):
- return True
-
- prevBuild = build.getPreviousBuild()
- if prevBuild:
- prevResult = prevBuild.getResults()
-
- required_notification_control_string = join((lower(self.results_descriptions.get(prevResult)[0]), \
- 'To', \
- capitalize(self.results_descriptions.get(results)[0])), \
- '')
-
- if (self.notify_for(required_notification_control_string)):
- return True
-
- return False
-
- def watchedBuildFinished(self, b):
-
- # only notify about builders we are interested in
- builder = b.getBuilder()
- if (self.bot.categories != None and
- builder.category not in self.bot.categories):
- return
-
- builder_name = builder.getName()
- buildnum = b.getNumber()
- buildrevs = b.getRevisions()
-
- results = self.getResultsDescriptionAndColor(b.getResults())
- if self.reportBuild(builder_name, buildnum):
- if self.useRevisions:
- r = "Hey! build %s containing revision(s) [%s] is complete: %s" % \
- (builder_name, buildrevs, results[0])
- else:
- r = "Hey! build %s #%d is complete: %s" % \
- (builder_name, buildnum, results[0])
-
- r += ' [%s]' % maybeColorize(" ".join(b.getText()), results[1], self.useColors)
- self.send(r)
- buildurl = self.bot.status.getURLForThing(b)
- if buildurl:
- self.send("Build details are at %s" % buildurl)
-
- def command_FORCE(self, args, who):
- errReply = "try 'force build [--branch=BRANCH] [--revision=REVISION] [--props=PROP1=VAL1,PROP2=VAL2...] <WHICH> <REASON>'"
- args = self.splitArgs(args)
- if not args:
- raise UsageError(errReply)
- what = args.pop(0)
- if what != "build":
- raise UsageError(errReply)
- opts = ForceOptions()
- opts.parseOptions(args)
-
- which = opts['builder']
- branch = opts['branch']
- revision = opts['revision']
- reason = opts['reason']
- props = opts['props']
-
- if which is None:
- raise UsageError("you must provide a Builder, " + errReply)
-
- # keep weird stuff out of the branch, revision, and properties args.
- branch_validate = self.master.config.validation['branch']
- revision_validate = self.master.config.validation['revision']
- pname_validate = self.master.config.validation['property_name']
- pval_validate = self.master.config.validation['property_value']
- if branch and not branch_validate.match(branch):
- log.msg("bad branch '%s'" % branch)
- self.send("sorry, bad branch '%s'" % branch)
- return
- if revision and not revision_validate.match(revision):
- log.msg("bad revision '%s'" % revision)
- self.send("sorry, bad revision '%s'" % revision)
- return
-
- properties = Properties()
- if props:
- # split props into name:value dict
- pdict = {}
- propertylist = props.split(",")
- for i in range(0,len(propertylist)):
- splitproperty = propertylist[i].split("=", 1)
- pdict[splitproperty[0]] = splitproperty[1]
-
- # set properties
- for prop in pdict:
- pname = prop
- pvalue = pdict[prop]
- if not pname_validate.match(pname) \
- or not pval_validate.match(pvalue):
- log.msg("bad property name='%s', value='%s'" % (pname, pvalue))
- self.send("sorry, bad property name='%s', value='%s'" %
- (pname, pvalue))
- return
- properties.setProperty(pname, pvalue, "Force Build IRC")
-
- bc = self.getControl(which)
-
- reason = "forced: by %s: %s" % (self.describeUser(who), reason)
- ss = SourceStamp(branch=branch, revision=revision)
- d = bc.submitBuildRequest(ss, reason, props=properties.asDict())
- def subscribe(buildreq):
- ireq = IrcBuildRequest(self, self.useRevisions)
- buildreq.subscribe(ireq.started)
- d.addCallback(subscribe)
- d.addErrback(log.err, "while forcing a build")
-
-
- command_FORCE.usage = "force build [--branch=branch] [--revision=revision] [--props=prop1=val1,prop2=val2...] <which> <reason> - Force a build"
-
- def command_STOP(self, args, who):
- args = self.splitArgs(args)
- if len(args) < 3 or args[0] != 'build':
- raise UsageError, "try 'stop build WHICH <REASON>'"
- which = args[1]
- reason = args[2]
-
- buildercontrol = self.getControl(which)
-
- r = "stopped: by %s: %s" % (self.describeUser(who), reason)
-
- # find an in-progress build
- builderstatus = self.getBuilder(which)
- builds = builderstatus.getCurrentBuilds()
- if not builds:
- self.send("sorry, no build is currently running")
- return
- for build in builds:
- num = build.getNumber()
- revs = build.getRevisions()
-
- # obtain the BuildControl object
- buildcontrol = buildercontrol.getBuild(num)
-
- # make it stop
- buildcontrol.stopBuild(r)
-
- if self.useRevisions:
- response = "build containing revision(s) [%s] interrupted" % revs
- else:
- response = "build %d interrupted" % num
- self.send(response)
-
- command_STOP.usage = "stop build <which> <reason> - Stop a running build"
-
- def emit_status(self, which):
- b = self.getBuilder(which)
- str = "%s: " % which
- state, builds = b.getState()
- str += state
- if state == "idle":
- last = b.getLastFinishedBuild()
- if last:
- start,finished = last.getTimes()
- str += ", last build %s ago: %s" % \
- (self.convertTime(int(util.now() - finished)), " ".join(last.getText()))
- if state == "building":
- t = []
- for build in builds:
- step = build.getCurrentStep()
- if step:
- s = "(%s)" % " ".join(step.getText())
- else:
- s = "(no current step)"
- ETA = build.getETA()
- if ETA is not None:
- s += " [ETA %s]" % self.convertTime(ETA)
- t.append(s)
- str += ", ".join(t)
- self.send(str)
-
- def command_LAST(self, args, who):
- args = self.splitArgs(args)
-
- if len(args) == 0:
- which = "all"
- elif len(args) == 1:
- which = args[0]
- else:
- raise UsageError, "try 'last <builder>'"
-
- def emit_last(which):
- last = self.getBuilder(which).getLastFinishedBuild()
- if not last:
- str = "(no builds run since last restart)"
- else:
- start,finish = last.getTimes()
- str = "%s ago: " % (self.convertTime(int(util.now() - finish)))
- str += " ".join(last.getText())
- self.send("last build [%s]: %s" % (which, str))
-
- if which == "all":
- builders = self.getAllBuilders()
- for b in builders:
- emit_last(b.name)
- return
- emit_last(which)
- command_LAST.usage = "last <which> - list last build status for builder <which>"
-
- def build_commands(self):
- commands = []
- for k in dir(self):
- if k.startswith('command_'):
- commands.append(k[8:].lower())
- commands.sort()
- return commands
-
- def describeUser(self, user):
- if self.dest[0] == '#':
- return "IRC user <%s> on channel %s" % (user, self.dest)
- return "IRC user <%s> (privmsg)" % user
-
- # commands
-
- def command_MUTE(self, args, who):
- # The order of these is important! ;)
- self.send("Shutting up for now.")
- self.muted = True
- command_MUTE.usage = "mute - suppress all messages until a corresponding 'unmute' is issued"
-
- def command_UNMUTE(self, args, who):
- if self.muted:
- # The order of these is important! ;)
- self.muted = False
- self.send("I'm baaaaaaaaaaack!")
- else:
- self.send("You hadn't told me to be quiet, but it's the thought that counts, right?")
- command_UNMUTE.usage = "unmute - disable a previous 'mute'"
-
- def command_HELP(self, args, who):
- args = self.splitArgs(args)
- if len(args) == 0:
- self.send("Get help on what? (try 'help <foo>', 'help <foo> <bar>, "
- "or 'commands' for a command list)")
- return
- command = args[0]
- meth = self.getCommandMethod(command)
- if not meth:
- raise UsageError, "no such command '%s'" % command
- usage = getattr(meth, 'usage', None)
- if isinstance(usage, dict):
- if len(args) == 1:
- k = None # command
- elif len(args) == 2:
- k = args[1] # command arg
- else:
- k = tuple(args[1:]) # command arg subarg ...
- usage = usage.get(k, None)
- if usage:
- self.send("Usage: %s" % usage)
- else:
- self.send("No usage info for " + ' '.join(["'%s'" % arg for arg in args]))
- command_HELP.usage = "help <command> [<arg> [<subarg> ...]] - Give help for <command> or one of it's arguments"
-
- def command_SOURCE(self, args, who):
- self.send("My source can be found at "
- "https://github.com/buildbot/buildbot")
- command_SOURCE.usage = "source - the source code for Buildbot"
-
- def command_COMMANDS(self, args, who):
- commands = self.build_commands()
- str = "buildbot commands: " + ", ".join(commands)
- self.send(str)
- command_COMMANDS.usage = "commands - List available commands"
-
- def command_DESTROY(self, args, who):
- if self.bot.nickname not in args:
- self.act("readies phasers")
-
- def command_DANCE(self, args, who):
- reactor.callLater(1.0, self.send, "<(^.^<)")
- reactor.callLater(2.0, self.send, "<(^.^)>")
- reactor.callLater(3.0, self.send, "(>^.^)>")
- reactor.callLater(3.5, self.send, "(7^.^)7")
- reactor.callLater(5.0, self.send, "(>^.^<)")
-
- def command_SHUTDOWN(self, args, who):
- if args not in ('check','start','stop','now'):
- raise UsageError("try 'shutdown check|start|stop|now'")
-
- if not self.bot.factory.allowShutdown:
- raise UsageError("shutdown control is not enabled")
-
- botmaster = self.master.botmaster
- shuttingDown = botmaster.shuttingDown
-
- if args == 'check':
- if shuttingDown:
- self.send("Status: buildbot is shutting down")
- else:
- self.send("Status: buildbot is running")
- elif args == 'start':
- if shuttingDown:
- self.send("Already started")
- else:
- self.send("Starting clean shutdown")
- botmaster.cleanShutdown()
- elif args == 'stop':
- if not shuttingDown:
- self.send("Nothing to stop")
- else:
- self.send("Stopping clean shutdown")
- botmaster.cancelCleanShutdown()
- elif args == 'now':
- self.send("Stopping buildbot")
- reactor.stop()
- command_SHUTDOWN.usage = {
- None: "shutdown check|start|stop|now - shutdown the buildbot master",
- "check": "shutdown check - check if the buildbot master is running or shutting down",
- "start": "shutdown start - start a clean shutdown",
- "stop": "shutdown cancel - stop the clean shutdown",
- "now": "shutdown now - shutdown immediately without waiting for the builders to finish"}
-
- # communication with the user
-
- def send(self, message):
- if not self.muted:
- self.bot.msgOrNotice(self.dest, message.encode("ascii", "replace"))
-
- def act(self, action):
- if not self.muted:
- self.bot.describe(self.dest, action.encode("ascii", "replace"))
-
- # main dispatchers for incoming messages
-
- def getCommandMethod(self, command):
- return getattr(self, 'command_' + command.upper(), None)
-
- def handleMessage(self, message, who):
- # a message has arrived from 'who'. For broadcast contacts (i.e. when
- # people do an irc 'buildbot: command'), this will be a string
- # describing the sender of the message in some useful-to-log way, and
- # a single Contact may see messages from a variety of users. For
- # unicast contacts (i.e. when people do an irc '/msg buildbot
- # command'), a single Contact will only ever see messages from a
- # single user.
- message = message.lstrip()
- if self.silly.has_key(message):
- self.doSilly(message)
- return defer.succeed(None)
-
- parts = message.split(' ', 1)
- if len(parts) == 1:
- parts = parts + ['']
- cmd, args = parts
- log.msg("irc command", cmd)
-
- meth = self.getCommandMethod(cmd)
- if not meth and message[-1] == '!':
- self.send("What you say!")
- return defer.succeed(None)
-
- if meth:
- d = defer.maybeDeferred(meth, args.strip(), who)
- @d.addErrback
- def usageError(f):
- f.trap(UsageError)
- self.send(str(f.value))
- @d.addErrback
- def logErr(f):
- log.err(f)
- self.send("Something bad happened (see logs)")
- d.addErrback(log.err)
- return d
- return defer.succeed(None)
-
- def handleAction(self, data, user):
- # this is sent when somebody performs an action that mentions the
- # buildbot (like '/me kicks buildbot'). 'user' is the name/nick/id of
- # the person who performed the action, so if their action provokes a
- # response, they can be named. This is 100% silly.
- if not data.endswith("s "+ self.bot.nickname):
- return
- words = data.split()
- verb = words[-2]
- if verb == "kicks":
- response = "%s back" % verb
- else:
- response = "%s %s too" % (verb, user)
- self.act(response)
-
-
-class IrcStatusBot(irc.IRCClient):
- """I represent the buildbot to an IRC server.
- """
- contactClass = IRCContact
-
- def __init__(self, nickname, password, channels, pm_to_nicks, status,
- categories, notify_events, noticeOnChannel=False,
- useRevisions=False, showBlameList=False, useColors=True):
- self.nickname = nickname
- self.channels = channels
- self.pm_to_nicks = pm_to_nicks
- self.password = password
- self.status = status
- self.master = status.master
- self.categories = categories
- self.notify_events = notify_events
- self.hasQuit = 0
- self.contacts = {}
- self.noticeOnChannel = noticeOnChannel
- self.useColors = useColors
- self.useRevisions = useRevisions
- self.showBlameList = showBlameList
- self._keepAliveCall = task.LoopingCall(lambda: self.ping(self.nickname))
-
- def connectionMade(self):
- irc.IRCClient.connectionMade(self)
- self._keepAliveCall.start(60)
-
- def connectionLost(self, reason):
- if self._keepAliveCall.running:
- self._keepAliveCall.stop()
- irc.IRCClient.connectionLost(self, reason)
-
- def msgOrNotice(self, dest, message):
- if self.noticeOnChannel and dest[0] == '#':
- self.notice(dest, message)
- else:
- self.msg(dest, message)
-
- def getContact(self, name):
- name = name.lower() # nicknames and channel names are case insensitive
- if name in self.contacts:
- return self.contacts[name]
- new_contact = self.contactClass(self, name)
- self.contacts[name] = new_contact
- return new_contact
-
- def log(self, msg):
- log.msg("%s: %s" % (self, msg))
-
-
- # the following irc.IRCClient methods are called when we have input
-
- def privmsg(self, user, channel, message):
- user = user.split('!', 1)[0] # rest is ~user@hostname
- # channel is '#twisted' or 'buildbot' (for private messages)
- if channel == self.nickname:
- # private message
- contact = self.getContact(user)
- contact.handleMessage(message, user)
- return
- # else it's a broadcast message, maybe for us, maybe not. 'channel'
- # is '#twisted' or the like.
- contact = self.getContact(channel)
- if message.startswith("%s:" % self.nickname) or message.startswith("%s," % self.nickname):
- message = message[len("%s:" % self.nickname):]
- contact.handleMessage(message, user)
-
- def action(self, user, channel, data):
- user = user.split('!', 1)[0] # rest is ~user@hostname
- # somebody did an action (/me actions) in the broadcast channel
- contact = self.getContact(channel)
- if self.nickname in data:
- contact.handleAction(data, user)
-
- def signedOn(self):
- if self.password:
- self.msg("Nickserv", "IDENTIFY " + self.password)
- for c in self.channels:
- if isinstance(c, dict):
- channel = c.get('channel', None)
- password = c.get('password', None)
- else:
- channel = c
- password = None
- self.join(channel=channel, key=password)
- for c in self.pm_to_nicks:
- self.getContact(c)
-
- def joined(self, channel):
- self.log("I have joined %s" % (channel,))
- # trigger contact contructor, which in turn subscribes to notify events
- self.getContact(channel)
-
- def left(self, channel):
- self.log("I have left %s" % (channel,))
-
- def kickedFrom(self, channel, kicker, message):
- self.log("I have been kicked from %s by %s: %s" % (channel,
- kicker,
- message))
-
-
-class ThrottledClientFactory(protocol.ClientFactory):
- lostDelay = random.randint(1, 5)
- failedDelay = random.randint(45, 60)
-
- def __init__(self, lostDelay=None, failedDelay=None):
- if lostDelay is not None:
- self.lostDelay = lostDelay
- if failedDelay is not None:
- self.failedDelay = failedDelay
-
- def clientConnectionLost(self, connector, reason):
- reactor.callLater(self.lostDelay, connector.connect)
-
- def clientConnectionFailed(self, connector, reason):
- reactor.callLater(self.failedDelay, connector.connect)
-
-
-class IrcStatusFactory(ThrottledClientFactory):
- protocol = IrcStatusBot
-
- status = None
- control = None
- shuttingDown = False
- p = None
-
- def __init__(self, nickname, password, channels, pm_to_nicks, categories, notify_events,
- noticeOnChannel=False, useRevisions=False, showBlameList=False,
- lostDelay=None, failedDelay=None, useColors=True, allowShutdown=False):
- ThrottledClientFactory.__init__(self, lostDelay=lostDelay,
- failedDelay=failedDelay)
- self.status = None
- self.nickname = nickname
- self.password = password
- self.channels = channels
- self.pm_to_nicks = pm_to_nicks
- self.categories = categories
- self.notify_events = notify_events
- self.noticeOnChannel = noticeOnChannel
- self.useRevisions = useRevisions
- self.showBlameList = showBlameList
- self.useColors = useColors
- self.allowShutdown = allowShutdown
-
- def __getstate__(self):
- d = self.__dict__.copy()
- del d['p']
- return d
-
- def shutdown(self):
- self.shuttingDown = True
- if self.p:
- self.p.quit("buildmaster reconfigured: bot disconnecting")
-
- def buildProtocol(self, address):
- p = self.protocol(self.nickname, self.password,
- self.channels, self.pm_to_nicks, self.status,
- self.categories, self.notify_events,
- noticeOnChannel = self.noticeOnChannel,
- useColors = self.useColors,
- useRevisions = self.useRevisions,
- showBlameList = self.showBlameList)
- p.factory = self
- p.status = self.status
- p.control = self.control
- self.p = p
- return p
-
- # TODO: I think a shutdown that occurs while the connection is being
- # established will make this explode
-
- def clientConnectionLost(self, connector, reason):
- if self.shuttingDown:
- log.msg("not scheduling reconnection attempt")
- return
- ThrottledClientFactory.clientConnectionLost(self, connector, reason)
-
- def clientConnectionFailed(self, connector, reason):
- if self.shuttingDown:
- log.msg("not scheduling reconnection attempt")
- return
- ThrottledClientFactory.clientConnectionFailed(self, connector, reason)
-
-
-class IRC(base.StatusReceiverMultiService):
- implements(IStatusReceiver)
-
- in_test_harness = False
-
- compare_attrs = ["host", "port", "nick", "password",
- "channels", "pm_to_nicks", "allowForce", "useSSL",
- "useRevisions", "categories", "useColors",
- "lostDelay", "failedDelay", "allowShutdown"]
-
- def __init__(self, host, nick, channels, pm_to_nicks=[], port=6667,
- allowForce=False, categories=None, password=None, notify_events={},
- noticeOnChannel = False, showBlameList = True, useRevisions=False,
- useSSL=False, lostDelay=None, failedDelay=None, useColors=True,
- allowShutdown=False):
- base.StatusReceiverMultiService.__init__(self)
-
- if allowForce not in (True, False):
- config.error("allowForce must be boolean, not %r" % (allowForce,))
- if allowShutdown not in (True, False):
- config.error("allowShutdown must be boolean, not %r" % (allowShutdown,))
-
- # need to stash these so we can detect changes later
- self.host = host
- self.port = port
- self.nick = nick
- self.channels = channels
- self.pm_to_nicks = pm_to_nicks
- self.password = password
- self.allowForce = allowForce
- self.useRevisions = useRevisions
- self.categories = categories
- self.notify_events = notify_events
- self.allowShutdown = allowShutdown
-
- self.f = IrcStatusFactory(self.nick, self.password,
- self.channels, self.pm_to_nicks,
- self.categories, self.notify_events,
- noticeOnChannel = noticeOnChannel,
- useRevisions = useRevisions,
- showBlameList = showBlameList,
- lostDelay = lostDelay,
- failedDelay = failedDelay,
- useColors = useColors,
- allowShutdown = allowShutdown)
-
- if useSSL:
- # SSL client needs a ClientContextFactory for some SSL mumbo-jumbo
- if not have_ssl:
- raise RuntimeError("useSSL requires PyOpenSSL")
- cf = ssl.ClientContextFactory()
- c = internet.SSLClient(self.host, self.port, self.f, cf)
- else:
- c = internet.TCPClient(self.host, self.port, self.f)
-
- c.setServiceParent(self)
-
- def setServiceParent(self, parent):
- base.StatusReceiverMultiService.setServiceParent(self, parent)
- self.f.status = parent
- if self.allowForce:
- self.f.control = interfaces.IControl(self.master)
-
- def stopService(self):
- # make sure the factory will stop reconnecting
- self.f.shutdown()
- return base.StatusReceiverMultiService.stopService(self)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/master.py
deleted file mode 100644
index 52e75de3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/master.py
+++ /dev/null
@@ -1,207 +0,0 @@
-# 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 os, types, re
-from twisted.python import runtime
-from twisted.internet import reactor
-from buildbot.process.buildstep import BuildStep
-from buildbot.process.buildstep import SUCCESS, FAILURE
-from twisted.internet import error
-from twisted.internet.protocol import ProcessProtocol
-import pprint
-
-class MasterShellCommand(BuildStep):
- """
- Run a shell command locally - on the buildmaster. The shell command
- COMMAND is specified just as for a RemoteShellCommand. Note that extra
- logfiles are not supported.
- """
- name='MasterShellCommand'
- description='Running'
- descriptionDone='Ran'
- descriptionSuffix = None
- renderables = [ 'command', 'env', 'description', 'descriptionDone', 'descriptionSuffix' ]
- haltOnFailure = True
- flunkOnFailure = True
-
- def __init__(self, command,
- description=None, descriptionDone=None, descriptionSuffix=None,
- env=None, path=None, usePTY=0, interruptSignal="KILL",
- **kwargs):
- BuildStep.__init__(self, **kwargs)
-
- self.command=command
- if description:
- self.description = description
- if isinstance(self.description, str):
- self.description = [self.description]
- if descriptionDone:
- self.descriptionDone = descriptionDone
- if isinstance(self.descriptionDone, str):
- self.descriptionDone = [self.descriptionDone]
- if descriptionSuffix:
- self.descriptionSuffix = descriptionSuffix
- if isinstance(self.descriptionSuffix, str):
- self.descriptionSuffix = [self.descriptionSuffix]
- self.env=env
- self.path=path
- self.usePTY=usePTY
- self.interruptSignal = interruptSignal
-
- class LocalPP(ProcessProtocol):
- def __init__(self, step):
- self.step = step
-
- def outReceived(self, data):
- self.step.stdio_log.addStdout(data)
-
- def errReceived(self, data):
- self.step.stdio_log.addStderr(data)
-
- def processEnded(self, status_object):
- if status_object.value.exitCode is not None:
- self.step.stdio_log.addHeader("exit status %d\n" % status_object.value.exitCode)
- if status_object.value.signal is not None:
- self.step.stdio_log.addHeader("signal %s\n" % status_object.value.signal)
- self.step.processEnded(status_object)
-
- def start(self):
- # render properties
- command = self.command
- # set up argv
- if type(command) in types.StringTypes:
- if runtime.platformType == 'win32':
- argv = os.environ['COMSPEC'].split() # allow %COMSPEC% to have args
- if '/c' not in argv: argv += ['/c']
- argv += [command]
- else:
- # for posix, use /bin/sh. for other non-posix, well, doesn't
- # hurt to try
- argv = ['/bin/sh', '-c', command]
- else:
- if runtime.platformType == 'win32':
- argv = os.environ['COMSPEC'].split() # allow %COMSPEC% to have args
- if '/c' not in argv: argv += ['/c']
- argv += list(command)
- else:
- argv = command
-
- self.stdio_log = stdio_log = self.addLog("stdio")
-
- if type(command) in types.StringTypes:
- stdio_log.addHeader(command.strip() + "\n\n")
- else:
- stdio_log.addHeader(" ".join(command) + "\n\n")
- stdio_log.addHeader("** RUNNING ON BUILDMASTER **\n")
- stdio_log.addHeader(" in dir %s\n" % os.getcwd())
- stdio_log.addHeader(" argv: %s\n" % (argv,))
- self.step_status.setText(self.describe())
-
- if self.env is None:
- env = os.environ
- else:
- assert isinstance(self.env, dict)
- env = self.env
- for key, v in self.env.iteritems():
- if isinstance(v, list):
- # Need to do os.pathsep translation. We could either do that
- # by replacing all incoming ':'s with os.pathsep, or by
- # accepting lists. I like lists better.
- # If it's not a string, treat it as a sequence to be
- # turned in to a string.
- self.env[key] = os.pathsep.join(self.env[key])
-
- # do substitution on variable values matching pattern: ${name}
- p = re.compile('\${([0-9a-zA-Z_]*)}')
- def subst(match):
- return os.environ.get(match.group(1), "")
- newenv = {}
- for key, v in env.iteritems():
- if v is not None:
- if not isinstance(v, basestring):
- raise RuntimeError("'env' values must be strings or "
- "lists; key '%s' is incorrect" % (key,))
- newenv[key] = p.sub(subst, env[key])
- env = newenv
- stdio_log.addHeader(" env: %r\n" % (env,))
-
- # TODO add a timeout?
- self.process = reactor.spawnProcess(self.LocalPP(self), argv[0], argv,
- path=self.path, usePTY=self.usePTY, env=env )
- # (the LocalPP object will call processEnded for us)
-
- def processEnded(self, status_object):
- if status_object.value.signal is not None:
- self.descriptionDone = ["killed (%s)" % status_object.value.signal]
- self.step_status.setText(self.describe(done=True))
- self.finished(FAILURE)
- elif status_object.value.exitCode != 0:
- self.descriptionDone = ["failed (%d)" % status_object.value.exitCode]
- self.step_status.setText(self.describe(done=True))
- self.finished(FAILURE)
- else:
- self.step_status.setText(self.describe(done=True))
- self.finished(SUCCESS)
-
- def describe(self, done=False):
- desc = self.descriptionDone if done else self.description
- if self.descriptionSuffix:
- desc = desc[:]
- desc.extend(self.descriptionSuffix)
- return desc
-
- def interrupt(self, reason):
- try:
- self.process.signalProcess(self.interruptSignal)
- except KeyError: # Process not started yet
- pass
- except error.ProcessExitedAlready:
- pass
- BuildStep.interrupt(self, reason)
-
-
-class SetProperty(BuildStep):
- name='SetProperty'
- description=['Setting']
- descriptionDone=['Set']
- renderables = [ 'value' ]
-
- def __init__(self, property, value, **kwargs):
- BuildStep.__init__(self, **kwargs)
- self.property = property
- self.value = value
-
- def start(self):
- properties = self.build.getProperties()
- properties.setProperty(self.property, self.value, self.name, runtime=True)
- self.step_status.setText(self.describe(done=True))
- self.finished(SUCCESS)
-
-
-class LogRenderable(BuildStep):
- name='LogRenderable'
- description=['Logging']
- descriptionDone=['Logged']
- renderables = ['content']
-
- def __init__(self, content, **kwargs):
- BuildStep.__init__(self, **kwargs)
- self.content = content
-
- def start(self):
- content = pprint.pformat(self.content)
- self.addCompleteLog(name='Output', text=content)
- self.step_status.setText(self.describe(done=True))
- self.finished(SUCCESS)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/maxq.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/maxq.py
deleted file mode 100644
index bb40677a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/maxq.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# 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
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot import config
-
-class MaxQ(ShellCommand):
- flunkOnFailure = True
- name = "maxq"
-
- def __init__(self, testdir=None, **kwargs):
- if not testdir:
- config.error("please pass testdir")
- kwargs['command'] = 'run_maxq.py %s' % (testdir,)
- ShellCommand.__init__(self, **kwargs)
-
- def commandComplete(self, cmd):
- output = cmd.logs['stdio'].getText()
- self.failures = output.count('\nTEST FAILURE:')
-
- def evaluateCommand(self, cmd):
- # treat a nonzero exit status as a failure, if no other failures are
- # detected
- if not self.failures and cmd.didFail():
- self.failures = 1
- if self.failures:
- return FAILURE
- return SUCCESS
-
- def getText(self, cmd, results):
- if self.failures:
- return [ str(self.failures), 'maxq', 'failures' ]
- return ['maxq', 'tests']
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/__init__.py
deleted file mode 100644
index a65e68da..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/__init__.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# 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.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright Steve 'Ashcrow' Milner <smilner+buildbot@redhat.com>
-"""
-Steps specific to package formats.
-"""
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/lintian.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/lintian.py
deleted file mode 100644
index 5c01a15d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/lintian.py
+++ /dev/null
@@ -1,91 +0,0 @@
-# This program 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.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright Marius Rieder <marius.rieder@durchmesser.ch>
-"""
-Steps and objects related to lintian
-"""
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE
-from buildbot import config
-
-class DebLintian(ShellCommand):
- name = "lintian"
- description = ["Lintian running"]
- descriptionDone = ["Lintian"]
-
- fileloc = None
- suppressTags = []
-
- warnCount = 0
- errCount = 0
-
- flunkOnFailure=False
- warnOnFailure=True
-
- def __init__(self, fileloc=None, suppressTags=None, **kwargs):
- """
- Create the DebLintian object.
-
- @type fileloc: str
- @param fileloc: Location of the .deb or .changes to test.
- @type suppressTags: list
- @param suppressTags: List of tags to suppress.
- @type kwargs: dict
- @param kwargs: all other keyword arguments.
- """
- ShellCommand.__init__(self, **kwargs)
- if fileloc:
- self.fileloc = fileloc
- if suppressTags:
- self.suppressTags = suppressTags
-
- if not self.fileloc:
- config.error("You must specify a fileloc")
-
- self.command = ["lintian", "-v", self.fileloc]
-
- if self.suppressTags:
- for tag in self.suppressTags:
- self.command += ['--suppress-tags', tag]
-
- def createSummary(self, log):
- """
- Create nice summary logs.
-
- @param log: log to create summary off of.
- """
- warnings = []
- errors = []
- for line in log.readlines():
- if 'W: ' in line:
- warnings.append(line)
- elif 'E: ' in line:
- errors.append(line)
-
- if warnings:
- self.addCompleteLog('%d Warnings' % len(warnings), "".join(warnings))
- self.warnCount = len(warnings)
- if errors:
- self.addCompleteLog('%d Errors' % len(errors), "".join(errors))
- self.errCount = len(errors)
-
- def evaluateCommand(self, cmd):
- if ( cmd.rc != 0 or self.errCount):
- return FAILURE
- if self.warnCount:
- return WARNINGS
- return SUCCESS
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/pbuilder.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/pbuilder.py
deleted file mode 100644
index 1ed64c37..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/deb/pbuilder.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# This program 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.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright Marius Rieder <marius.rieder@durchmesser.ch>
-"""
-Steps and objects related to pbuilder
-"""
-
-import re
-import stat
-import time
-
-from twisted.python import log
-
-from buildbot.steps.shell import WarningCountingShellCommand
-from buildbot.process import buildstep
-from buildbot.process.buildstep import FAILURE
-from buildbot import config
-
-class DebPbuilder(WarningCountingShellCommand):
- """Build a debian package with pbuilder inside of a chroot."""
- name = "pbuilder"
-
- haltOnFailure = 1
- flunkOnFailure = 1
- description = ["pdebuilding"]
- descriptionDone = ["pdebuild"]
-
- warningPattern = ".*(warning[: ]|\sW: ).*"
-
- architecture = None
- distribution = 'stable'
- basetgz = "/var/cache/pbuilder/%(distribution)s-%(architecture)s-buildbot.tgz"
- mirror = "http://cdn.debian.net/debian/"
- extrapackages = []
- keyring = None
- components = None
-
- maxAge = 60*60*24*7
- pbuilder = '/usr/sbin/pbuilder'
- baseOption = '--basetgz'
-
- def __init__(self,
- architecture=None,
- distribution=None,
- basetgz=None,
- mirror=None,
- extrapackages=None,
- keyring=None,
- components=None,
- **kwargs):
- """
- Creates the DebPbuilder object.
-
- @type architecture: str
- @param architecture: the name of the architecture to build
- @type distribution: str
- @param distribution: the man of the distribution to use
- @type basetgz: str
- @param basetgz: the path or path template of the basetgz
- @type mirror: str
- @param mirror: the mirror for building basetgz
- @type extrapackages: list
- @param extrapackages: adds packages specified to buildroot
- @type keyring: str
- @param keyring: keyring file to use for verification
- @type components: str
- @param components: components to use for chroot creation
- @type kwargs: dict
- @param kwargs: All further keyword arguments.
- """
- WarningCountingShellCommand.__init__(self, **kwargs)
-
- if architecture:
- self.architecture = architecture
- if distribution:
- self.distribution = distribution
- if mirror:
- self.mirror = mirror
- if extrapackages:
- self.extrapackages = extrapackages
- if keyring:
- self.keyring = keyring
- if components:
- self.components = components
-
- if self.architecture:
- kwargs['architecture'] = self.architecture
- else:
- kwargs['architecture'] = 'local'
- kwargs['distribution'] = self.distribution
-
- if basetgz:
- self.basetgz = basetgz % kwargs
- else:
- self.basetgz = self.basetgz % kwargs
-
- if not self.distribution:
- config.error("You must specify a distribution.")
-
- self.command = ['pdebuild', '--buildresult', '.', '--pbuilder', self.pbuilder]
- if self.architecture:
- self.command += ['--architecture', self.architecture]
- self.command += ['--', '--buildresult', '.', self.baseOption, self.basetgz]
- if self.extrapackages:
- self.command += ['--extrapackages', " ".join(self.extrapackages)]
-
- self.suppressions.append((None, re.compile("\.pbuilderrc does not exist"), None, None))
-
- # Check for Basetgz
- def start(self):
- cmd = buildstep.RemoteCommand('stat', {'file': self.basetgz})
- d = self.runCommand(cmd)
- d.addCallback(lambda res: self.checkBasetgz(cmd))
- d.addErrback(self.failed)
- return d
-
- def checkBasetgz(self, cmd):
- if cmd.rc != 0:
- log.msg("basetgz not found, initializing it.")
-
- command = ['sudo', self.pbuilder, '--create', self.baseOption,
- self.basetgz, '--distribution', self.distribution,
- '--mirror', self.mirror]
- if self.architecture:
- command += ['--architecture', self.architecture]
- if self.extrapackages:
- command += ['--extrapackages', " ".join(self.extrapackages)]
- if self.keyring:
- command += ['--debootstrapopts', "--keyring=%s" % self.keyring]
- if self.components:
- command += ['--components', self.components]
-
- cmd = buildstep.RemoteShellCommand(self.getWorkdir(), command)
-
- stdio_log = stdio_log = self.addLog("pbuilder")
- cmd.useLog(stdio_log, True, "stdio")
- d = self.runCommand(cmd)
- self.step_status.setText(["PBuilder create."])
- d.addCallback(lambda res: self.startBuild(cmd))
- return d
- s = cmd.updates["stat"][-1]
- # basetgz will be a file when running in pbuilder
- # and a directory in case of cowbuilder
- if stat.S_ISREG(s[stat.ST_MODE]) or stat.S_ISDIR(s[stat.ST_MODE]):
- log.msg("%s found." % self.basetgz)
- age = time.time() - s[stat.ST_MTIME]
- if age >= self.maxAge:
- log.msg("basetgz outdated, updating")
- command = ['sudo', self.pbuilder, '--update',
- self.baseOption, self.basetgz]
-
- cmd = buildstep.RemoteShellCommand(self.getWorkdir(), command)
- stdio_log = stdio_log = self.addLog("pbuilder")
- cmd.useLog(stdio_log, True, "stdio")
- d = self.runCommand(cmd)
- self.step_status.setText(["PBuilder update."])
- d.addCallback(lambda res: self.startBuild(cmd))
- return d
- return self.startBuild(cmd)
- else:
- log.msg("%s is not a file or a directory." % self.basetgz)
- self.finished(FAILURE)
-
- def startBuild(self, cmd):
- if cmd.rc != 0:
- log.msg("Failure when running %s." % cmd)
- self.finished(FAILURE)
- else:
- return WarningCountingShellCommand.start(self)
-
- def commandComplete(self, cmd):
- out = cmd.logs['stdio'].getText()
- m = re.search(r"dpkg-genchanges >\.\./(.+\.changes)", out)
- if m:
- self.setProperty("deb-changes", m.group(1), "DebPbuilder")
-
-class DebCowbuilder(DebPbuilder):
- """Build a debian package with cowbuilder inside of a chroot."""
- name = "cowbuilder"
-
- description = ["pdebuilding"]
- descriptionDone = ["pdebuild"]
-
- basetgz = "/var/cache/pbuilder/%(distribution)s-%(architecture)s-buildbot.cow/"
-
- pbuilder = '/usr/sbin/cowbuilder'
- baseOption = '--basepath'
-
-class UbuPbuilder(DebPbuilder):
- """Build a Ubuntu package with pbuilder inside of a chroot."""
- distribution = None
- mirror = "http://archive.ubuntu.com/ubuntu/"
-
- components = "main universe"
-
-class UbuCowbuilder(DebCowbuilder):
- """Build a Ubuntu package with cowbuilder inside of a chroot."""
- distribution = None
- mirror = "http://archive.ubuntu.com/ubuntu/"
-
- components = "main universe"
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/__init__.py
deleted file mode 100644
index 429730a0..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/__init__.py
+++ /dev/null
@@ -1,27 +0,0 @@
-# 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.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright Steve 'Ashcrow' Milner <smilner+buildbot@redhat.com>
-"""
-Steps specific to the rpm format.
-"""
-
-from buildbot.steps.package.rpm.rpmbuild import RpmBuild
-from buildbot.steps.package.rpm.rpmspec import RpmSpec
-from buildbot.steps.package.rpm.rpmlint import RpmLint
-from buildbot.steps.package.rpm.mock import MockBuildSRPM, MockRebuild
-
-__all__ = ['RpmBuild', 'RpmSpec', 'RpmLint', 'MockBuildSRPM', 'MockRebuild']
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/mock.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/mock.py
deleted file mode 100644
index 8c7e3491..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/mock.py
+++ /dev/null
@@ -1,174 +0,0 @@
-# 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.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright Marius Rieder <marius.rieder@durchmesser.ch>
-"""
-Steps and objects related to mock building.
-"""
-
-import re
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.process import buildstep
-from buildbot import config
-
-class MockStateObserver(buildstep.LogLineObserver):
- _line_re = re.compile(r'^.*State Changed: (.*)$')
-
- def outLineReceived(self, line):
- m = self._line_re.search(line.strip())
- if m:
- state = m.group(1)
- if not state == 'end':
- self.step.descriptionSuffix = ["[%s]"%m.group(1)]
- else:
- self.step.descriptionSuffix = None
- self.step.step_status.setText(self.step.describe(False))
-
-class Mock(ShellCommand):
- """Add the mock logfiles and clean them if they already exist. Add support
- for the root and resultdir parameter of mock."""
-
- name = "mock"
-
- haltOnFailure = 1
- flunkOnFailure = 1
-
- mock_logfiles = ['build.log', 'root.log', 'state.log']
-
- root = None
- resultdir = None
-
- def __init__(self,
- root=None,
- resultdir=None,
- **kwargs):
- """
- Creates the Mock object.
-
- @type root: str
- @param root: the name of the mock buildroot
- @type resultdir: str
- @param resultdir: the path of the result dir
- @type kwargs: dict
- @param kwargs: All further keyword arguments.
- """
- ShellCommand.__init__(self, **kwargs)
- if root:
- self.root = root
- if resultdir:
- self.resultdir = resultdir
-
- if not self.root:
- config.error("You must specify a mock root")
-
-
- self.command = ['mock', '--root', self.root]
- if self.resultdir:
- self.command += ['--resultdir', self.resultdir]
-
- def start(self):
- """
- Try to remove the old mock logs first.
- """
- if self.resultdir:
- for lname in self.mock_logfiles:
- self.logfiles[lname] = self.build.path_module.join(self.resultdir,
- lname)
- else:
- for lname in self.mock_logfiles:
- self.logfiles[lname] = lname
- self.addLogObserver('state.log', MockStateObserver())
-
- cmd = buildstep.RemoteCommand('rmdir', {'dir':
- map(lambda l: self.build.path_module.join('build', self.logfiles[l]),
- self.mock_logfiles)})
- d = self.runCommand(cmd)
- def removeDone(cmd):
- ShellCommand.start(self)
- d.addCallback(removeDone)
- d.addErrback(self.failed)
-
-class MockBuildSRPM(Mock):
- """Build a srpm within a mock. Requires a spec file and a sources dir."""
-
- name = "mockbuildsrpm"
-
- description = ["mock buildsrpm"]
- descriptionDone = ["mock buildsrpm"]
-
- spec = None
- sources = '.'
-
- def __init__(self,
- spec=None,
- sources=None,
- **kwargs):
- """
- Creates the MockBuildSRPM object.
-
- @type spec: str
- @param spec: the path of the specfiles.
- @type sources: str
- @param sources: the path of the sources dir.
- @type kwargs: dict
- @param kwargs: All further keyword arguments.
- """
- Mock.__init__(self, **kwargs)
- if spec:
- self.spec = spec
- if sources:
- self.sources = sources
-
- if not self.spec:
- config.error("You must specify a spec file")
- if not self.sources:
- config.error("You must specify a sources dir")
-
- self.command += ['--buildsrpm', '--spec', self.spec,
- '--sources', self.sources]
-
- def commandComplete(self, cmd):
- out = cmd.logs['build.log'].getText()
- m = re.search(r"Wrote: .*/([^/]*.src.rpm)", out)
- if m:
- self.setProperty("srpm", m.group(1), 'MockBuildSRPM')
-
-class MockRebuild(Mock):
- """Rebuild a srpm within a mock. Requires a srpm file."""
-
- name = "mock"
-
- description = ["mock rebuilding srpm"]
- descriptionDone = ["mock rebuild srpm"]
-
- srpm = None
-
- def __init__(self, srpm=None, **kwargs):
- """
- Creates the MockRebuildRPM object.
-
- @type srpm: str
- @param srpm: the path of the srpm file.
- @type kwargs: dict
- @param kwargs: All further keyword arguments.
- """
- Mock.__init__(self, **kwargs)
- if srpm:
- self.srpm = srpm
-
- if not self.srpm:
- config.error("You must specify a srpm")
-
- self.command += ['--rebuild', self.srpm]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmbuild.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmbuild.py
deleted file mode 100644
index 9d5c88ea..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmbuild.py
+++ /dev/null
@@ -1,137 +0,0 @@
-# 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.
-#
-# Portions Copyright Buildbot Team Members
-
-from __future__ import with_statement
-# Portions Copyright Dan Radez <dradez+buildbot@redhat.com>
-# Portions Copyright Steve 'Ashcrow' Milner <smilner+buildbot@redhat.com>
-
-import os
-from buildbot.steps.shell import ShellCommand
-from buildbot.process import buildstep
-from buildbot import config
-
-class RpmBuild(ShellCommand):
- """
- RpmBuild build step.
- """
-
- name = "rpmbuilder"
- haltOnFailure = 1
- flunkOnFailure = 1
- description = ["RPMBUILD"]
- descriptionDone = ["RPMBUILD"]
-
- def __init__(self,
- specfile=None,
- topdir='`pwd`',
- builddir='`pwd`',
- rpmdir='`pwd`',
- sourcedir='`pwd`',
- specdir='`pwd`',
- srcrpmdir='`pwd`',
- dist='.el5',
- autoRelease=False,
- vcsRevision=False,
- **kwargs):
- """
- Create the RpmBuild object.
-
- @type specfile: str
- @param specfile: location of the specfile to build
- @type topdir: str
- @param topdir: define the _topdir rpm parameter
- @type builddir: str
- @param builddir: define the _builddir rpm parameter
- @type rpmdir: str
- @param rpmdir: define the _rpmdir rpm parameter
- @type sourcedir: str
- @param sourcedir: define the _sourcedir rpm parameter
- @type specdir: str
- @param specdir: define the _specdir rpm parameter
- @type srcrpmdir: str
- @param srcrpmdir: define the _srcrpmdir rpm parameter
- @type dist: str
- @param dist: define the dist string.
- @type autoRelease: boolean
- @param autoRelease: Use auto incrementing release numbers.
- @type vcsRevision: boolean
- @param vcsRevision: Use vcs version number as revision number.
- """
- ShellCommand.__init__(self, **kwargs)
- self.rpmbuild = (
- 'rpmbuild --define "_topdir %s" --define "_builddir %s"'
- ' --define "_rpmdir %s" --define "_sourcedir %s"'
- ' --define "_specdir %s" --define "_srcrpmdir %s"'
- ' --define "dist %s"' % (topdir, builddir, rpmdir, sourcedir,
- specdir, srcrpmdir, dist))
- self.specfile = specfile
- self.autoRelease = autoRelease
- self.vcsRevision = vcsRevision
-
- if not self.specfile:
- config.error("You must specify a specfile")
-
- def start(self):
- if self.autoRelease:
- relfile = '%s.release' % (
- os.path.basename(self.specfile).split('.')[0])
- try:
- with open(relfile, 'r') as rfile:
- rel = int(rfile.readline().strip())
- except:
- rel = 0
- self.rpmbuild = self.rpmbuild + ' --define "_release %s"' % rel
- with open(relfile, 'w') as rfile:
- rfile.write(str(rel+1))
-
- if self.vcsRevision:
- revision = self.getProperty('got_revision')
- # only do this in the case where there's a single codebase
- if revision and not isinstance(revision, dict):
- self.rpmbuild = (self.rpmbuild + ' --define "_revision %s"' %
- revision)
-
- self.rpmbuild = self.rpmbuild + ' -ba %s' % self.specfile
-
- self.command = self.rpmbuild
-
- # create the actual RemoteShellCommand instance now
- kwargs = self.remote_kwargs
- kwargs['command'] = self.command
- cmd = buildstep.RemoteShellCommand(**kwargs)
- self.setupEnvironment(cmd)
- self.startCommand(cmd)
-
- def createSummary(self, log):
- rpm_prefixes = ['Provides:', 'Requires(', 'Requires:',
- 'Checking for unpackaged', 'Wrote:',
- 'Executing(%', '+ ', 'Processing files:']
- rpm_err_pfx = [' ', 'RPM build errors:', 'error: ']
-
- rpmcmdlog = []
- rpmerrors = []
-
- for line in log.getText().splitlines(True):
- for pfx in rpm_prefixes:
- if line.startswith(pfx):
- rpmcmdlog.append(line)
- break
- for err in rpm_err_pfx:
- if line.startswith(err):
- rpmerrors.append(line)
- break
- self.addCompleteLog('RPM Command Log', "".join(rpmcmdlog))
- if rpmerrors:
- self.addCompleteLog('RPM Errors', "".join(rpmerrors))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmlint.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmlint.py
deleted file mode 100644
index ab14ca1a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmlint.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# 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.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright Steve 'Ashcrow' Milner <smilner+buildbot@redhat.com>
-"""
-Steps and objects related to rpmlint.
-"""
-
-from buildbot.steps.shell import Test
-
-
-class RpmLint(Test):
- """
- Rpmlint build step.
- """
-
- name = "rpmlint"
-
- description = ["Checking for RPM/SPEC issues"]
- descriptionDone = ["Finished checking RPM/SPEC issues"]
-
- fileloc = '.'
- config = None
-
- def __init__(self,
- fileloc=None,
- config=None,
- **kwargs):
- """
- Create the Rpmlint object.
-
- @type fileloc: str
- @param fileloc: Location glob of the specs or rpms.
- @type config: str
- @param config: path to the rpmlint user config.
- @type kwargs: dict
- @param fileloc: all other keyword arguments.
- """
- Test.__init__(self, **kwargs)
- if fileloc:
- self.fileloc = fileloc
- if config:
- self.config = config
-
- self.command = ["rpmlint", "-i"]
- if self.config:
- self.command += ['-f', self.config]
- self.command.append(self.fileloc)
-
- def createSummary(self, log):
- """
- Create nice summary logs.
-
- @param log: log to create summary off of.
- """
- warnings = []
- errors = []
- for line in log.readlines():
- if ' W: ' in line:
- warnings.append(line)
- elif ' E: ' in line:
- errors.append(line)
- if warnings:
- self.addCompleteLog('%d Warnings'%len(warnings), "".join(warnings))
- if errors:
- self.addCompleteLog('%d Errors'%len(errors), "".join(errors))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmspec.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmspec.py
deleted file mode 100644
index a3676c81..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/package/rpm/rpmspec.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# 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.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright Dan Radez <dradez+buildbot@redhat.com>
-# Portions Copyright Steve 'Ashcrow' Milner <smilner+buildbot@redhat.com>
-"""
-library to populate parameters from and rpmspec file into a memory structure
-"""
-
-import re
-from buildbot.steps.shell import ShellCommand
-
-
-class RpmSpec(ShellCommand):
- """
- read parameters out of an rpm spec file
- """
-
- #initialize spec info vars and get them from the spec file
- n_regex = re.compile('^Name:[ ]*([^\s]*)')
- v_regex = re.compile('^Version:[ ]*([0-9\.]*)')
-
- def __init__(self, specfile=None, **kwargs):
- """
- Creates the RpmSpec object.
-
- @type specfile: str
- @param specfile: the name of the specfile to get the package
- name and version from
- @type kwargs: dict
- @param kwargs: All further keyword arguments.
- """
- self.specfile = specfile
- self._pkg_name = None
- self._pkg_version = None
- self._loaded = False
-
- def load(self):
- """
- call this function after the file exists to populate properties
- """
- # If we are given a string, open it up else assume it's something we
- # can call read on.
- if isinstance(self.specfile, str):
- f = open(self.specfile, 'r')
- else:
- f = self.specfile
-
- for line in f:
- if self.v_regex.match(line):
- self._pkg_version = self.v_regex.match(line).group(1)
- if self.n_regex.match(line):
- self._pkg_name = self.n_regex.match(line).group(1)
- f.close()
- self._loaded = True
-
- # Read-only properties
- loaded = property(lambda self: self._loaded)
- pkg_name = property(lambda self: self._pkg_name)
- pkg_version = property(lambda self: self._pkg_version)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/python.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/python.py
deleted file mode 100644
index ce552b0d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/python.py
+++ /dev/null
@@ -1,304 +0,0 @@
-# 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 re
-from buildbot.status.results import SUCCESS, FAILURE, WARNINGS
-from buildbot.steps.shell import ShellCommand
-from buildbot import config
-
-try:
- import cStringIO
- StringIO = cStringIO.StringIO
-except ImportError:
- from StringIO import StringIO
-
-
-class BuildEPYDoc(ShellCommand):
- name = "epydoc"
- command = ["make", "epydocs"]
- description = ["building", "epydocs"]
- descriptionDone = ["epydoc"]
-
- def createSummary(self, log):
- import_errors = 0
- warnings = 0
- errors = 0
-
- for line in StringIO(log.getText()):
- if line.startswith("Error importing "):
- import_errors += 1
- if line.find("Warning: ") != -1:
- warnings += 1
- if line.find("Error: ") != -1:
- errors += 1
-
- self.descriptionDone = self.descriptionDone[:]
- if import_errors:
- self.descriptionDone.append("ierr=%d" % import_errors)
- if warnings:
- self.descriptionDone.append("warn=%d" % warnings)
- if errors:
- self.descriptionDone.append("err=%d" % errors)
-
- self.import_errors = import_errors
- self.warnings = warnings
- self.errors = errors
-
- def evaluateCommand(self, cmd):
- if cmd.didFail():
- return FAILURE
- if self.warnings or self.errors:
- return WARNINGS
- return SUCCESS
-
-
-class PyFlakes(ShellCommand):
- name = "pyflakes"
- command = ["make", "pyflakes"]
- description = ["running", "pyflakes"]
- descriptionDone = ["pyflakes"]
- flunkOnFailure = False
- flunkingIssues = ["undefined"] # any pyflakes lines like this cause FAILURE
-
- MESSAGES = ("unused", "undefined", "redefs", "import*", "misc")
-
- def __init__(self, *args, **kwargs):
- # PyFlakes return 1 for both warnings and errors. We
- # categorize this initially as WARNINGS so that
- # evaluateCommand below can inspect the results more closely.
- kwargs['decodeRC'] = {0: SUCCESS, 1: WARNINGS}
- ShellCommand.__init__(self, *args, **kwargs)
-
- def createSummary(self, log):
- counts = {}
- summaries = {}
- for m in self.MESSAGES:
- counts[m] = 0
- summaries[m] = []
-
- first = True
- for line in StringIO(log.getText()).readlines():
- # the first few lines might contain echoed commands from a 'make
- # pyflakes' step, so don't count these as warnings. Stop ignoring
- # the initial lines as soon as we see one with a colon.
- if first:
- if line.find(":") != -1:
- # there's the colon, this is the first real line
- first = False
- # fall through and parse the line
- else:
- # skip this line, keep skipping non-colon lines
- continue
- if line.find("imported but unused") != -1:
- m = "unused"
- elif line.find("*' used; unable to detect undefined names") != -1:
- m = "import*"
- elif line.find("undefined name") != -1:
- m = "undefined"
- elif line.find("redefinition of unused") != -1:
- m = "redefs"
- else:
- m = "misc"
- summaries[m].append(line)
- counts[m] += 1
-
- self.descriptionDone = self.descriptionDone[:]
- for m in self.MESSAGES:
- if counts[m]:
- self.descriptionDone.append("%s=%d" % (m, counts[m]))
- self.addCompleteLog(m, "".join(summaries[m]))
- self.setProperty("pyflakes-%s" % m, counts[m], "pyflakes")
- self.setProperty("pyflakes-total", sum(counts.values()), "pyflakes")
-
-
- def evaluateCommand(self, cmd):
- if cmd.didFail():
- return FAILURE
- for m in self.flunkingIssues:
- if self.getProperty("pyflakes-%s" % m):
- return FAILURE
- if self.getProperty("pyflakes-total"):
- return WARNINGS
- return SUCCESS
-
-class PyLint(ShellCommand):
- '''A command that knows about pylint output.
- It is a good idea to add --output-format=parseable to your
- command, since it includes the filename in the message.
- '''
- name = "pylint"
- description = ["running", "pylint"]
- descriptionDone = ["pylint"]
-
- # pylint's return codes (see pylint(1) for details)
- # 1 - 16 will be bit-ORed
-
- RC_OK = 0
- RC_FATAL = 1
- RC_ERROR = 2
- RC_WARNING = 4
- RC_REFACTOR = 8
- RC_CONVENTION = 16
- RC_USAGE = 32
-
- # Using the default text output, the message format is :
- # MESSAGE_TYPE: LINE_NUM:[OBJECT:] MESSAGE
- # with --output-format=parseable it is: (the outer brackets are literal)
- # FILE_NAME:LINE_NUM: [MESSAGE_TYPE[, OBJECT]] MESSAGE
- # message type consists of the type char and 4 digits
- # The message types:
-
- MESSAGES = {
- 'C': "convention", # for programming standard violation
- 'R': "refactor", # for bad code smell
- 'W': "warning", # for python specific problems
- 'E': "error", # for much probably bugs in the code
- 'F': "fatal", # error prevented pylint from further processing.
- 'I': "info",
- }
-
- flunkingIssues = ["F", "E"] # msg categories that cause FAILURE
-
- _re_groupname = 'errtype'
- _msgtypes_re_str = '(?P<%s>[%s])' % (_re_groupname, ''.join(MESSAGES.keys()))
- _default_line_re = re.compile(r'^%s(\d{4})?: *\d+(,\d+)?:.+' % _msgtypes_re_str)
- _parseable_line_re = re.compile(r'[^:]+:\d+: \[%s(\d{4})?[,\]] .+' % _msgtypes_re_str)
-
- def createSummary(self, log):
- counts = {}
- summaries = {}
- for m in self.MESSAGES:
- counts[m] = 0
- summaries[m] = []
-
- line_re = None # decide after first match
- for line in StringIO(log.getText()).readlines():
- if not line_re:
- # need to test both and then decide on one
- if self._parseable_line_re.match(line):
- line_re = self._parseable_line_re
- elif self._default_line_re.match(line):
- line_re = self._default_line_re
- else: # no match yet
- continue
- mo = line_re.match(line)
- if mo:
- msgtype = mo.group(self._re_groupname)
- assert msgtype in self.MESSAGES
- summaries[msgtype].append(line)
- counts[msgtype] += 1
-
- self.descriptionDone = self.descriptionDone[:]
- for msg, fullmsg in self.MESSAGES.items():
- if counts[msg]:
- self.descriptionDone.append("%s=%d" % (fullmsg, counts[msg]))
- self.addCompleteLog(fullmsg, "".join(summaries[msg]))
- self.setProperty("pylint-%s" % fullmsg, counts[msg])
- self.setProperty("pylint-total", sum(counts.values()))
-
- def evaluateCommand(self, cmd):
- if cmd.rc & (self.RC_FATAL|self.RC_ERROR|self.RC_USAGE):
- return FAILURE
- for msg in self.flunkingIssues:
- if self.getProperty("pylint-%s" % self.MESSAGES[msg]):
- return FAILURE
- if self.getProperty("pylint-total"):
- return WARNINGS
- return SUCCESS
-
-class Sphinx(ShellCommand):
- ''' A Step to build sphinx documentation '''
-
- name = "sphinx"
- description = ["running", "sphinx"]
- descriptionDone = ["sphinx"]
-
- haltOnFailure = True
-
- def __init__(self, sphinx_sourcedir='.', sphinx_builddir=None,
- sphinx_builder=None, sphinx = 'sphinx-build', tags = [],
- defines = {}, mode='incremental', **kwargs):
-
- if sphinx_builddir is None:
- # Who the heck is not interested in the built doc ?
- config.error("Sphinx argument sphinx_builddir is required")
-
- if mode not in ('incremental', 'full'):
- config.error("Sphinx argument mode has to be 'incremental' or" +
- "'full' is required")
-
- self.warnings = 0
- self.success = False
- ShellCommand.__init__(self, **kwargs)
-
- # build the command
- command = [sphinx]
- if sphinx_builder is not None:
- command.extend(['-b', sphinx_builder])
-
- for tag in tags:
- command.extend(['-t', tag])
-
- for key in sorted(defines):
- if defines[key] is None:
- command.extend(['-D', key])
- elif isinstance(defines[key], bool):
- command.extend(['-D',
- '%s=%d' % (key, defines[key] and 1 or 0)])
- else:
- command.extend(['-D', '%s=%s' % (key, defines[key])])
-
- if mode == 'full':
- command.extend(['-E']) # Don't use a saved environment
-
- command.extend([sphinx_sourcedir, sphinx_builddir])
- self.setCommand(command)
-
- def createSummary(self, log):
-
- msgs = ['WARNING', 'ERROR', 'SEVERE']
-
- warnings = []
- for line in log.getText().split('\n'):
- if (line.startswith('build succeeded')
- or line.startswith('no targets are out of date.')):
- self.success = True
- else:
- for msg in msgs:
- if msg in line:
- warnings.append(line)
- self.warnings += 1
- if self.warnings > 0:
- self.addCompleteLog('warnings', "\n".join(warnings))
-
- self.step_status.setStatistic('warnings', self.warnings)
-
- def evaluateCommand(self, cmd):
- if self.success:
- if self.warnings == 0:
- return SUCCESS
- else:
- return WARNINGS
- else:
- return FAILURE
-
- def describe(self, done=False):
- if not done:
- return ["building"]
-
- description = [self.name]
- description.append('%d warnings' % self.warnings)
- return description
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/python_twisted.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/python_twisted.py
deleted file mode 100644
index fa91f552..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/python_twisted.py
+++ /dev/null
@@ -1,611 +0,0 @@
-# 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
-
-
-from twisted.python import log
-
-from buildbot.status import testresult
-from buildbot.status.results import SUCCESS, FAILURE, WARNINGS, SKIPPED
-from buildbot.process.buildstep import LogLineObserver, OutputProgressObserver
-from buildbot.steps.shell import ShellCommand
-
-try:
- import cStringIO
- StringIO = cStringIO
-except ImportError:
- import StringIO
-import re
-
-# BuildSteps that are specific to the Twisted source tree
-
-class HLint(ShellCommand):
- """I run a 'lint' checker over a set of .xhtml files. Any deviations
- from recommended style is flagged and put in the output log.
-
- This step looks at .changes in the parent Build to extract a list of
- Lore XHTML files to check."""
-
- name = "hlint"
- description = ["running", "hlint"]
- descriptionDone = ["hlint"]
- warnOnWarnings = True
- warnOnFailure = True
- # TODO: track time, but not output
- warnings = 0
-
- def __init__(self, python=None, **kwargs):
- ShellCommand.__init__(self, **kwargs)
- self.python = python
-
- def start(self):
- # create the command
- htmlFiles = {}
- for f in self.build.allFiles():
- if f.endswith(".xhtml") and not f.startswith("sandbox/"):
- htmlFiles[f] = 1
- # remove duplicates
- hlintTargets = htmlFiles.keys()
- hlintTargets.sort()
- if not hlintTargets:
- return SKIPPED
- self.hlintFiles = hlintTargets
- c = []
- if self.python:
- c.append(self.python)
- c += ["bin/lore", "-p", "--output", "lint"] + self.hlintFiles
- self.setCommand(c)
-
- # add an extra log file to show the .html files we're checking
- self.addCompleteLog("files", "\n".join(self.hlintFiles)+"\n")
-
- ShellCommand.start(self)
-
- def commandComplete(self, cmd):
- # TODO: remove the 'files' file (a list of .xhtml files that were
- # submitted to hlint) because it is available in the logfile and
- # mostly exists to give the user an idea of how long the step will
- # take anyway).
- lines = cmd.logs['stdio'].getText().split("\n")
- warningLines = filter(lambda line:':' in line, lines)
- if warningLines:
- self.addCompleteLog("warnings", "".join(warningLines))
- warnings = len(warningLines)
- self.warnings = warnings
-
- def evaluateCommand(self, cmd):
- # warnings are in stdout, rc is always 0, unless the tools break
- if cmd.didFail():
- return FAILURE
- if self.warnings:
- return WARNINGS
- return SUCCESS
-
- def getText2(self, cmd, results):
- if cmd.didFail():
- return ["hlint"]
- return ["%d hlin%s" % (self.warnings,
- self.warnings == 1 and 't' or 'ts')]
-
-def countFailedTests(output):
- # start scanning 10kb from the end, because there might be a few kb of
- # import exception tracebacks between the total/time line and the errors
- # line
- chunk = output[-10000:]
- lines = chunk.split("\n")
- lines.pop() # blank line at end
- # lines[-3] is "Ran NN tests in 0.242s"
- # lines[-2] is blank
- # lines[-1] is 'OK' or 'FAILED (failures=1, errors=12)'
- # or 'FAILED (failures=1)'
- # or "PASSED (skips=N, successes=N)" (for Twisted-2.0)
- # there might be other lines dumped here. Scan all the lines.
- res = {'total': None,
- 'failures': 0,
- 'errors': 0,
- 'skips': 0,
- 'expectedFailures': 0,
- 'unexpectedSuccesses': 0,
- }
- for l in lines:
- out = re.search(r'Ran (\d+) tests', l)
- if out:
- res['total'] = int(out.group(1))
- if (l.startswith("OK") or
- l.startswith("FAILED ") or
- l.startswith("PASSED")):
- # the extra space on FAILED_ is to distinguish the overall
- # status from an individual test which failed. The lack of a
- # space on the OK is because it may be printed without any
- # additional text (if there are no skips,etc)
- out = re.search(r'failures=(\d+)', l)
- if out: res['failures'] = int(out.group(1))
- out = re.search(r'errors=(\d+)', l)
- if out: res['errors'] = int(out.group(1))
- out = re.search(r'skips=(\d+)', l)
- if out: res['skips'] = int(out.group(1))
- out = re.search(r'expectedFailures=(\d+)', l)
- if out: res['expectedFailures'] = int(out.group(1))
- out = re.search(r'unexpectedSuccesses=(\d+)', l)
- if out: res['unexpectedSuccesses'] = int(out.group(1))
- # successes= is a Twisted-2.0 addition, and is not currently used
- out = re.search(r'successes=(\d+)', l)
- if out: res['successes'] = int(out.group(1))
-
- return res
-
-
-class TrialTestCaseCounter(LogLineObserver):
- _line_re = re.compile(r'^(?:Doctest: )?([\w\.]+) \.\.\. \[([^\]]+)\]$')
- numTests = 0
- finished = False
-
- def outLineReceived(self, line):
- # different versions of Twisted emit different per-test lines with
- # the bwverbose reporter.
- # 2.0.0: testSlave (buildbot.test.test_runner.Create) ... [OK]
- # 2.1.0: buildbot.test.test_runner.Create.testSlave ... [OK]
- # 2.4.0: buildbot.test.test_runner.Create.testSlave ... [OK]
- # Let's just handle the most recent version, since it's the easiest.
- # Note that doctests create lines line this:
- # Doctest: viff.field.GF ... [OK]
-
- if self.finished:
- return
- if line.startswith("=" * 40):
- self.finished = True
- return
-
- m = self._line_re.search(line.strip())
- if m:
- testname, result = m.groups()
- self.numTests += 1
- self.step.setProgress('tests', self.numTests)
-
-
-UNSPECIFIED=() # since None is a valid choice
-
-class Trial(ShellCommand):
- """
- There are some class attributes which may be usefully overridden
- by subclasses. 'trialMode' and 'trialArgs' can influence the trial
- command line.
- """
-
- name = "trial"
- progressMetrics = ('output', 'tests', 'test.log')
- # note: the slash only works on unix buildslaves, of course, but we have
- # no way to know what the buildslave uses as a separator.
- # TODO: figure out something clever.
- logfiles = {"test.log": "_trial_temp/test.log"}
- # we use test.log to track Progress at the end of __init__()
-
- renderables = ['tests', 'jobs']
- flunkOnFailure = True
- python = None
- trial = "trial"
- trialMode = ["--reporter=bwverbose"] # requires Twisted-2.1.0 or newer
- # for Twisted-2.0.0 or 1.3.0, use ["-o"] instead
- trialArgs = []
- jobs = None
- testpath = UNSPECIFIED # required (but can be None)
- testChanges = False # TODO: needs better name
- recurse = False
- reactor = None
- randomly = False
- tests = None # required
-
- def __init__(self, reactor=UNSPECIFIED, python=None, trial=None,
- testpath=UNSPECIFIED,
- tests=None, testChanges=None,
- recurse=None, randomly=None,
- trialMode=None, trialArgs=None, jobs=None,
- **kwargs):
- """
- @type testpath: string
- @param testpath: use in PYTHONPATH when running the tests. If
- None, do not set PYTHONPATH. Setting this to '.' will
- cause the source files to be used in-place.
-
- @type python: string (without spaces) or list
- @param python: which python executable to use. Will form the start of
- the argv array that will launch trial. If you use this,
- you should set 'trial' to an explicit path (like
- /usr/bin/trial or ./bin/trial). Defaults to None, which
- leaves it out entirely (running 'trial args' instead of
- 'python ./bin/trial args'). Likely values are 'python',
- ['python2.2'], ['python', '-Wall'], etc.
-
- @type trial: string
- @param trial: which 'trial' executable to run.
- Defaults to 'trial', which will cause $PATH to be
- searched and probably find /usr/bin/trial . If you set
- 'python', this should be set to an explicit path (because
- 'python2.3 trial' will not work).
-
- @type trialMode: list of strings
- @param trialMode: a list of arguments to pass to trial, specifically
- to set the reporting mode. This defaults to ['-to']
- which means 'verbose colorless output' to the trial
- that comes with Twisted-2.0.x and at least -2.1.0 .
- Newer versions of Twisted may come with a trial
- that prefers ['--reporter=bwverbose'].
-
- @type trialArgs: list of strings
- @param trialArgs: a list of arguments to pass to trial, available to
- turn on any extra flags you like. Defaults to [].
-
- @type jobs: integer
- @param jobs: integer to be used as trial -j/--jobs option (for
- running tests on several workers). Only supported
- since Twisted-12.3.0.
-
- @type tests: list of strings
- @param tests: a list of test modules to run, like
- ['twisted.test.test_defer', 'twisted.test.test_process'].
- If this is a string, it will be converted into a one-item
- list.
-
- @type testChanges: boolean
- @param testChanges: if True, ignore the 'tests' parameter and instead
- ask the Build for all the files that make up the
- Changes going into this build. Pass these filenames
- to trial and ask it to look for test-case-name
- tags, running just the tests necessary to cover the
- changes.
-
- @type recurse: boolean
- @param recurse: If True, pass the --recurse option to trial, allowing
- test cases to be found in deeper subdirectories of the
- modules listed in 'tests'. This does not appear to be
- necessary when using testChanges.
-
- @type reactor: string
- @param reactor: which reactor to use, like 'gtk' or 'java'. If not
- provided, the Twisted's usual platform-dependent
- default is used.
-
- @type randomly: boolean
- @param randomly: if True, add the --random=0 argument, which instructs
- trial to run the unit tests in a random order each
- time. This occasionally catches problems that might be
- masked when one module always runs before another
- (like failing to make registerAdapter calls before
- lookups are done).
-
- @type kwargs: dict
- @param kwargs: parameters. The following parameters are inherited from
- L{ShellCommand} and may be useful to set: workdir,
- haltOnFailure, flunkOnWarnings, flunkOnFailure,
- warnOnWarnings, warnOnFailure, want_stdout, want_stderr,
- timeout.
- """
- ShellCommand.__init__(self, **kwargs)
-
- if python:
- self.python = python
- if self.python is not None:
- if type(self.python) is str:
- self.python = [self.python]
- for s in self.python:
- if " " in s:
- # this is not strictly an error, but I suspect more
- # people will accidentally try to use python="python2.3
- # -Wall" than will use embedded spaces in a python flag
- log.msg("python= component '%s' has spaces")
- log.msg("To add -Wall, use python=['python', '-Wall']")
- why = "python= value has spaces, probably an error"
- raise ValueError(why)
-
- if trial:
- self.trial = trial
- if " " in self.trial:
- raise ValueError("trial= value has spaces")
- if trialMode is not None:
- self.trialMode = trialMode
- if trialArgs is not None:
- self.trialArgs = trialArgs
- if jobs is not None:
- self.jobs = jobs
-
- if testpath is not UNSPECIFIED:
- self.testpath = testpath
- if self.testpath is UNSPECIFIED:
- raise ValueError("You must specify testpath= (it can be None)")
- assert isinstance(self.testpath, str) or self.testpath is None
-
- if reactor is not UNSPECIFIED:
- self.reactor = reactor
-
- if tests is not None:
- self.tests = tests
- if type(self.tests) is str:
- self.tests = [self.tests]
- if testChanges is not None:
- self.testChanges = testChanges
- #self.recurse = True # not sure this is necessary
-
- if not self.testChanges and self.tests is None:
- raise ValueError("Must either set testChanges= or provide tests=")
-
- if recurse is not None:
- self.recurse = recurse
- if randomly is not None:
- self.randomly = randomly
-
- # build up most of the command, then stash it until start()
- command = []
- if self.python:
- command.extend(self.python)
- command.append(self.trial)
- command.extend(self.trialMode)
- if self.recurse:
- command.append("--recurse")
- if self.reactor:
- command.append("--reactor=%s" % reactor)
- if self.randomly:
- command.append("--random=0")
- command.extend(self.trialArgs)
- self.command = command
-
- if self.reactor:
- self.description = ["testing", "(%s)" % self.reactor]
- self.descriptionDone = ["tests"]
- # commandComplete adds (reactorname) to self.text
- else:
- self.description = ["testing"]
- self.descriptionDone = ["tests"]
-
- # this counter will feed Progress along the 'test cases' metric
- self.addLogObserver('stdio', TrialTestCaseCounter())
-
- def setupEnvironment(self, cmd):
- ShellCommand.setupEnvironment(self, cmd)
- if self.testpath != None:
- e = cmd.args['env']
- if e is None:
- cmd.args['env'] = {'PYTHONPATH': self.testpath}
- else:
- #this bit produces a list, which can be used
- #by buildslave.runprocess.RunProcess
- ppath = e.get('PYTHONPATH', self.testpath)
- if isinstance(ppath, str):
- ppath = [ppath]
- if self.testpath not in ppath:
- ppath.insert(0, self.testpath)
- e['PYTHONPATH'] = ppath
-
- def start(self):
- # choose progressMetrics and logfiles based on whether trial is being
- # run with multiple workers or not.
- output_observer = OutputProgressObserver('test.log')
-
- if self.jobs is not None:
- self.jobs = int(self.jobs)
- self.command.append("--jobs=%d" % self.jobs)
-
- # using -j/--jobs flag produces more than one test log.
- self.logfiles = {}
- for i in xrange(self.jobs):
- self.logfiles['test.%d.log' % i] = '_trial_temp/%d/test.log' % i
- self.logfiles['err.%d.log' % i] = '_trial_temp/%d/err.log' % i
- self.logfiles['out.%d.log' % i] = '_trial_temp/%d/out.log' % i
- self.addLogObserver('test.%d.log' % i, output_observer)
- else:
- # this one just measures bytes of output in _trial_temp/test.log
- self.addLogObserver('test.log', output_observer)
-
- # now that self.build.allFiles() is nailed down, finish building the
- # command
- if self.testChanges:
- for f in self.build.allFiles():
- if f.endswith(".py"):
- self.command.append("--testmodule=%s" % f)
- else:
- self.command.extend(self.tests)
- log.msg("Trial.start: command is", self.command)
-
- ShellCommand.start(self)
-
-
- def commandComplete(self, cmd):
- # figure out all status, then let the various hook functions return
- # different pieces of it
-
- # 'cmd' is the original trial command, so cmd.logs['stdio'] is the
- # trial output. We don't have access to test.log from here.
- output = cmd.logs['stdio'].getText()
- counts = countFailedTests(output)
-
- total = counts['total']
- failures, errors = counts['failures'], counts['errors']
- parsed = (total != None)
- text = []
- text2 = ""
-
- if not cmd.didFail():
- if parsed:
- results = SUCCESS
- if total:
- text += ["%d %s" % \
- (total,
- total == 1 and "test" or "tests"),
- "passed"]
- else:
- text += ["no tests", "run"]
- else:
- results = FAILURE
- text += ["testlog", "unparseable"]
- text2 = "tests"
- else:
- # something failed
- results = FAILURE
- if parsed:
- text.append("tests")
- if failures:
- text.append("%d %s" % \
- (failures,
- failures == 1 and "failure" or "failures"))
- if errors:
- text.append("%d %s" % \
- (errors,
- errors == 1 and "error" or "errors"))
- count = failures + errors
- text2 = "%d tes%s" % (count, (count == 1 and 't' or 'ts'))
- else:
- text += ["tests", "failed"]
- text2 = "tests"
-
- if counts['skips']:
- text.append("%d %s" % \
- (counts['skips'],
- counts['skips'] == 1 and "skip" or "skips"))
- if counts['expectedFailures']:
- text.append("%d %s" % \
- (counts['expectedFailures'],
- counts['expectedFailures'] == 1 and "todo"
- or "todos"))
- if 0: # TODO
- results = WARNINGS
- if not text2:
- text2 = "todo"
-
- if 0:
- # ignore unexpectedSuccesses for now, but it should really mark
- # the build WARNING
- if counts['unexpectedSuccesses']:
- text.append("%d surprises" % counts['unexpectedSuccesses'])
- results = WARNINGS
- if not text2:
- text2 = "tests"
-
- if self.reactor:
- text.append(self.rtext('(%s)'))
- if text2:
- text2 = "%s %s" % (text2, self.rtext('(%s)'))
-
- self.results = results
- self.text = text
- self.text2 = [text2]
-
-
- def rtext(self, fmt='%s'):
- if self.reactor:
- rtext = fmt % self.reactor
- return rtext.replace("reactor", "")
- return ""
-
- def addTestResult(self, testname, results, text, tlog):
- if self.reactor is not None:
- testname = (self.reactor,) + testname
- tr = testresult.TestResult(testname, results, text, logs={'log': tlog})
- #self.step_status.build.addTestResult(tr)
- self.build.build_status.addTestResult(tr)
-
- def createSummary(self, loog):
- output = loog.getText()
- problems = ""
- sio = StringIO.StringIO(output)
- warnings = {}
- while 1:
- line = sio.readline()
- if line == "":
- break
- if line.find(" exceptions.DeprecationWarning: ") != -1:
- # no source
- warning = line # TODO: consider stripping basedir prefix here
- warnings[warning] = warnings.get(warning, 0) + 1
- elif (line.find(" DeprecationWarning: ") != -1 or
- line.find(" UserWarning: ") != -1):
- # next line is the source
- warning = line + sio.readline()
- warnings[warning] = warnings.get(warning, 0) + 1
- elif line.find("Warning: ") != -1:
- warning = line
- warnings[warning] = warnings.get(warning, 0) + 1
-
- if line.find("=" * 60) == 0 or line.find("-" * 60) == 0:
- problems += line
- problems += sio.read()
- break
-
- if problems:
- self.addCompleteLog("problems", problems)
- # now parse the problems for per-test results
- pio = StringIO.StringIO(problems)
- pio.readline() # eat the first separator line
- testname = None
- done = False
- while not done:
- while 1:
- line = pio.readline()
- if line == "":
- done = True
- break
- if line.find("=" * 60) == 0:
- break
- if line.find("-" * 60) == 0:
- # the last case has --- as a separator before the
- # summary counts are printed
- done = True
- break
- if testname is None:
- # the first line after the === is like:
-# EXPECTED FAILURE: testLackOfTB (twisted.test.test_failure.FailureTestCase)
-# SKIPPED: testRETR (twisted.test.test_ftp.TestFTPServer)
-# FAILURE: testBatchFile (twisted.conch.test.test_sftp.TestOurServerBatchFile)
- r = re.search(r'^([^:]+): (\w+) \(([\w\.]+)\)', line)
- if not r:
- # TODO: cleanup, if there are no problems,
- # we hit here
- continue
- result, name, case = r.groups()
- testname = tuple(case.split(".") + [name])
- results = {'SKIPPED': SKIPPED,
- 'EXPECTED FAILURE': SUCCESS,
- 'UNEXPECTED SUCCESS': WARNINGS,
- 'FAILURE': FAILURE,
- 'ERROR': FAILURE,
- 'SUCCESS': SUCCESS, # not reported
- }.get(result, WARNINGS)
- text = result.lower().split()
- loog = line
- # the next line is all dashes
- loog += pio.readline()
- else:
- # the rest goes into the log
- loog += line
- if testname:
- self.addTestResult(testname, results, text, loog)
- testname = None
-
- if warnings:
- lines = warnings.keys()
- lines.sort()
- self.addCompleteLog("warnings", "".join(lines))
-
- def evaluateCommand(self, cmd):
- return self.results
-
- def getText(self, cmd, results):
- return self.text
- def getText2(self, cmd, results):
- return self.text2
-
-
-class RemovePYCs(ShellCommand):
- name = "remove-.pyc"
- command = ['find', '.', '-name', '*.pyc', '-exec', 'rm', '{}', ';']
- description = ["removing", ".pyc", "files"]
- descriptionDone = ["remove", ".pycs"]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/shell.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/shell.py
deleted file mode 100644
index b4695795..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/shell.py
+++ /dev/null
@@ -1,756 +0,0 @@
-# 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 re
-import inspect
-from twisted.python import log, failure
-from twisted.spread import pb
-from twisted.python.deprecate import deprecatedModuleAttribute
-from twisted.python.versions import Version
-from buildbot.process import buildstep
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE
-from buildbot.status.logfile import STDOUT, STDERR
-from buildbot import config
-
-# for existing configurations that import WithProperties from here. We like
-# to move this class around just to keep our readers guessing.
-from buildbot.process.properties import WithProperties
-_hush_pyflakes = [WithProperties]
-del _hush_pyflakes
-
-class ShellCommand(buildstep.LoggingBuildStep):
- """I run a single shell command on the buildslave. I return FAILURE if
- the exit code of that command is non-zero, SUCCESS otherwise. To change
- this behavior, override my .evaluateCommand method, or customize
- decodeRC argument
-
- By default, a failure of this step will mark the whole build as FAILURE.
- To override this, give me an argument of flunkOnFailure=False .
-
- I create a single Log named 'log' which contains the output of the
- command. To create additional summary Logs, override my .createSummary
- method.
-
- The shell command I run (a list of argv strings) can be provided in
- several ways:
- - a class-level .command attribute
- - a command= parameter to my constructor (overrides .command)
- - set explicitly with my .setCommand() method (overrides both)
-
- @ivar command: a list of renderable objects (typically strings or
- WithProperties instances). This will be used by start()
- to create a RemoteShellCommand instance.
-
- @ivar logfiles: a dict mapping log NAMEs to workdir-relative FILENAMEs
- of their corresponding logfiles. The contents of the file
- named FILENAME will be put into a LogFile named NAME, ina
- something approximating real-time. (note that logfiles=
- is actually handled by our parent class LoggingBuildStep)
-
- @ivar lazylogfiles: Defaults to False. If True, logfiles will be tracked
- `lazily', meaning they will only be added when and if
- they are written to. Empty or nonexistent logfiles
- will be omitted. (Also handled by class
- LoggingBuildStep.)
- """
-
- name = "shell"
- renderables = buildstep.LoggingBuildStep.renderables + [
- 'slaveEnvironment', 'remote_kwargs', 'command',
- 'description', 'descriptionDone', 'descriptionSuffix']
-
- description = None # set this to a list of short strings to override
- descriptionDone = None # alternate description when the step is complete
- descriptionSuffix = None # extra information to append to suffix
-
- command = None # set this to a command, or set in kwargs
- # logfiles={} # you can also set 'logfiles' to a dictionary, and it
- # will be merged with any logfiles= argument passed in
- # to __init__
-
- # override this on a specific ShellCommand if you want to let it fail
- # without dooming the entire build to a status of FAILURE
- flunkOnFailure = True
-
- def __init__(self, workdir=None,
- description=None, descriptionDone=None, descriptionSuffix=None,
- command=None,
- usePTY="slave-config",
- **kwargs):
- # most of our arguments get passed through to the RemoteShellCommand
- # that we create, but first strip out the ones that we pass to
- # BuildStep (like haltOnFailure and friends), and a couple that we
- # consume ourselves.
-
- if description:
- self.description = description
- if isinstance(self.description, str):
- self.description = [self.description]
- if descriptionDone:
- self.descriptionDone = descriptionDone
- if isinstance(self.descriptionDone, str):
- self.descriptionDone = [self.descriptionDone]
-
- if descriptionSuffix:
- self.descriptionSuffix = descriptionSuffix
- if isinstance(self.descriptionSuffix, str):
- self.descriptionSuffix = [self.descriptionSuffix]
-
- if command:
- self.setCommand(command)
-
- # pull out the ones that LoggingBuildStep wants, then upcall
- buildstep_kwargs = {}
- for k in kwargs.keys()[:]:
- if k in self.__class__.parms:
- buildstep_kwargs[k] = kwargs[k]
- del kwargs[k]
- buildstep.LoggingBuildStep.__init__(self, **buildstep_kwargs)
-
- # check validity of arguments being passed to RemoteShellCommand
- invalid_args = []
- valid_rsc_args = inspect.getargspec(buildstep.RemoteShellCommand.__init__)[0]
- for arg in kwargs.keys():
- if arg not in valid_rsc_args:
- invalid_args.append(arg)
- # Raise Configuration error in case invalid arguments are present
- if invalid_args:
- config.error("Invalid argument(s) passed to RemoteShellCommand: "
- + ', '.join(invalid_args))
-
- # everything left over goes to the RemoteShellCommand
- kwargs['workdir'] = workdir # including a copy of 'workdir'
- kwargs['usePTY'] = usePTY
- self.remote_kwargs = kwargs
-
- def setBuild(self, build):
- buildstep.LoggingBuildStep.setBuild(self, build)
- # Set this here, so it gets rendered when we start the step
- self.slaveEnvironment = self.build.slaveEnvironment
-
- def setStepStatus(self, step_status):
- buildstep.LoggingBuildStep.setStepStatus(self, step_status)
-
- def setDefaultWorkdir(self, workdir):
- rkw = self.remote_kwargs
- rkw['workdir'] = rkw['workdir'] or workdir
-
- def getWorkdir(self):
- """
- Get the current notion of the workdir. Note that this may change
- between instantiation of the step and C{start}, as it is based on the
- build's default workdir, and may even be C{None} before that point.
- """
- return self.remote_kwargs['workdir']
-
- def setCommand(self, command):
- self.command = command
-
- def _flattenList(self, mainlist, commands):
- for x in commands:
- if isinstance(x, (list, tuple)):
- if x != []:
- self._flattenList(mainlist, x)
- else:
- mainlist.append(x)
-
- def describe(self, done=False):
- desc = self._describe(done)
- if self.descriptionSuffix:
- desc = desc[:]
- desc.extend(self.descriptionSuffix)
- return desc
-
- def _describe(self, done=False):
- """Return a list of short strings to describe this step, for the
- status display. This uses the first few words of the shell command.
- You can replace this by setting .description in your subclass, or by
- overriding this method to describe the step better.
-
- @type done: boolean
- @param done: whether the command is complete or not, to improve the
- way the command is described. C{done=False} is used
- while the command is still running, so a single
- imperfect-tense verb is appropriate ('compiling',
- 'testing', ...) C{done=True} is used when the command
- has finished, and the default getText() method adds some
- text, so a simple noun is appropriate ('compile',
- 'tests' ...)
- """
-
- try:
- if done and self.descriptionDone is not None:
- return self.descriptionDone
- if self.description is not None:
- return self.description
-
- # we may have no command if this is a step that sets its command
- # name late in the game (e.g., in start())
- if not self.command:
- return ["???"]
-
- words = self.command
- if isinstance(words, (str, unicode)):
- words = words.split()
-
- try:
- len(words)
- except AttributeError:
- # WithProperties and Property don't have __len__
- return ["???"]
-
- # flatten any nested lists
- tmp = []
- self._flattenList(tmp, words)
- words = tmp
-
- # strip instances and other detritus (which can happen if a
- # description is requested before rendering)
- words = [ w for w in words if isinstance(w, (str, unicode)) ]
-
- if len(words) < 1:
- return ["???"]
- if len(words) == 1:
- return ["'%s'" % words[0]]
- if len(words) == 2:
- return ["'%s" % words[0], "%s'" % words[1]]
- return ["'%s" % words[0], "%s" % words[1], "...'"]
-
- except:
- log.err(failure.Failure(), "Error describing step")
- return ["???"]
-
- def setupEnvironment(self, cmd):
- # merge in anything from Build.slaveEnvironment
- # This can be set from a Builder-level environment, or from earlier
- # BuildSteps. The latter method is deprecated and superceded by
- # BuildProperties.
- # Environment variables passed in by a BuildStep override
- # those passed in at the Builder level.
- slaveEnv = self.slaveEnvironment
- if slaveEnv:
- if cmd.args['env'] is None:
- cmd.args['env'] = {}
- fullSlaveEnv = slaveEnv.copy()
- fullSlaveEnv.update(cmd.args['env'])
- cmd.args['env'] = fullSlaveEnv
- # note that each RemoteShellCommand gets its own copy of the
- # dictionary, so we shouldn't be affecting anyone but ourselves.
-
- def buildCommandKwargs(self, warnings):
- kwargs = buildstep.LoggingBuildStep.buildCommandKwargs(self)
- kwargs.update(self.remote_kwargs)
- tmp = []
- if isinstance(self.command, list):
- self._flattenList(tmp, self.command)
- else:
- tmp = self.command
-
- kwargs['command'] = tmp
-
- # check for the usePTY flag
- if kwargs.has_key('usePTY') and kwargs['usePTY'] != 'slave-config':
- if self.slaveVersionIsOlderThan("svn", "2.7"):
- warnings.append("NOTE: slave does not allow master to override usePTY\n")
- del kwargs['usePTY']
-
- # check for the interruptSignal flag
- if kwargs.has_key('interruptSignal') and self.slaveVersionIsOlderThan("shell", "2.15"):
- warnings.append("NOTE: slave does not allow master to specify interruptSignal\n")
- del kwargs['interruptSignal']
-
- return kwargs
-
- def start(self):
- # this block is specific to ShellCommands. subclasses that don't need
- # to set up an argv array, an environment, or extra logfiles= (like
- # the Source subclasses) can just skip straight to startCommand()
-
- warnings = []
-
- # create the actual RemoteShellCommand instance now
- kwargs = self.buildCommandKwargs(warnings)
- cmd = buildstep.RemoteShellCommand(**kwargs)
- self.setupEnvironment(cmd)
-
- self.startCommand(cmd, warnings)
-
-
-
-class TreeSize(ShellCommand):
- name = "treesize"
- command = ["du", "-s", "-k", "."]
- description = "measuring tree size"
- descriptionDone = "tree size measured"
- kib = None
-
- def commandComplete(self, cmd):
- out = cmd.logs['stdio'].getText()
- m = re.search(r'^(\d+)', out)
- if m:
- self.kib = int(m.group(1))
- self.setProperty("tree-size-KiB", self.kib, "treesize")
-
- def evaluateCommand(self, cmd):
- if cmd.didFail():
- return FAILURE
- if self.kib is None:
- return WARNINGS # not sure how 'du' could fail, but whatever
- return SUCCESS
-
- def getText(self, cmd, results):
- if self.kib is not None:
- return ["treesize", "%d KiB" % self.kib]
- return ["treesize", "unknown"]
-
-class SetPropertyFromCommand(ShellCommand):
- name = "setproperty"
- renderables = [ 'property' ]
-
- def __init__(self, property=None, extract_fn=None, strip=True, **kwargs):
- self.property = property
- self.extract_fn = extract_fn
- self.strip = strip
-
- if not ((property is not None) ^ (extract_fn is not None)):
- config.error(
- "Exactly one of property and extract_fn must be set")
-
- ShellCommand.__init__(self, **kwargs)
-
- self.property_changes = {}
-
- def commandComplete(self, cmd):
- if self.property:
- if cmd.didFail():
- return
- result = cmd.logs['stdio'].getText()
- if self.strip: result = result.strip()
- propname = self.property
- self.setProperty(propname, result, "SetProperty Step")
- self.property_changes[propname] = result
- else:
- log = cmd.logs['stdio']
- new_props = self.extract_fn(cmd.rc,
- ''.join(log.getChunks([STDOUT], onlyText=True)),
- ''.join(log.getChunks([STDERR], onlyText=True)))
- for k,v in new_props.items():
- self.setProperty(k, v, "SetProperty Step")
- self.property_changes = new_props
-
- def createSummary(self, log):
- if self.property_changes:
- props_set = [ "%s: %r" % (k,v)
- for k,v in self.property_changes.items() ]
- self.addCompleteLog('property changes', "\n".join(props_set))
-
- def getText(self, cmd, results):
- if len(self.property_changes) > 1:
- return [ "%d properties set" % len(self.property_changes) ]
- elif len(self.property_changes) == 1:
- return [ "property '%s' set" % self.property_changes.keys()[0] ]
- else:
- # let ShellCommand describe
- return ShellCommand.getText(self, cmd, results)
-
-
-SetProperty = SetPropertyFromCommand
-deprecatedModuleAttribute(Version("Buildbot", 0, 8, 8),
- "It has been renamed to SetPropertyFromCommand",
- "buildbot.steps.shell", "SetProperty")
-
-
-class Configure(ShellCommand):
-
- name = "configure"
- haltOnFailure = 1
- flunkOnFailure = 1
- description = ["configuring"]
- descriptionDone = ["configure"]
- command = ["./configure"]
-
-class StringFileWriter(pb.Referenceable):
- """
- FileWriter class that just puts received data into a buffer.
-
- Used to upload a file from slave for inline processing rather than
- writing into a file on master.
- """
- def __init__(self):
- self.buffer = ""
-
- def remote_write(self, data):
- self.buffer += data
-
- def remote_close(self):
- pass
-
-class WarningCountingShellCommand(ShellCommand):
- renderables = [ 'suppressionFile' ]
-
- warnCount = 0
- warningPattern = '.*warning[: ].*'
- # The defaults work for GNU Make.
- directoryEnterPattern = (u"make.*: Entering directory "
- u"[\u2019\"`'](.*)[\u2019'`\"]")
- directoryLeavePattern = "make.*: Leaving directory"
- suppressionFile = None
-
- commentEmptyLineRe = re.compile(r"^\s*(\#.*)?$")
- suppressionLineRe = re.compile(r"^\s*(.+?)\s*:\s*(.+?)\s*(?:[:]\s*([0-9]+)(?:-([0-9]+))?\s*)?$")
-
- def __init__(self,
- warningPattern=None, warningExtractor=None, maxWarnCount=None,
- directoryEnterPattern=None, directoryLeavePattern=None,
- suppressionFile=None, **kwargs):
- # See if we've been given a regular expression to use to match
- # warnings. If not, use a default that assumes any line with "warning"
- # present is a warning. This may lead to false positives in some cases.
- if warningPattern:
- self.warningPattern = warningPattern
- if directoryEnterPattern:
- self.directoryEnterPattern = directoryEnterPattern
- if directoryLeavePattern:
- self.directoryLeavePattern = directoryLeavePattern
- if suppressionFile:
- self.suppressionFile = suppressionFile
- if warningExtractor:
- self.warningExtractor = warningExtractor
- else:
- self.warningExtractor = WarningCountingShellCommand.warnExtractWholeLine
- self.maxWarnCount = maxWarnCount
-
- # And upcall to let the base class do its work
- ShellCommand.__init__(self, **kwargs)
-
- self.suppressions = []
- self.directoryStack = []
-
- def addSuppression(self, suppressionList):
- """
- This method can be used to add patters of warnings that should
- not be counted.
-
- It takes a single argument, a list of patterns.
-
- Each pattern is a 4-tuple (FILE-RE, WARN-RE, START, END).
-
- FILE-RE is a regular expression (string or compiled regexp), or None.
- If None, the pattern matches all files, else only files matching the
- regexp. If directoryEnterPattern is specified in the class constructor,
- matching is against the full path name, eg. src/main.c.
-
- WARN-RE is similarly a regular expression matched against the
- text of the warning, or None to match all warnings.
-
- START and END form an inclusive line number range to match against. If
- START is None, there is no lower bound, similarly if END is none there
- is no upper bound."""
-
- for fileRe, warnRe, start, end in suppressionList:
- if fileRe != None and isinstance(fileRe, basestring):
- fileRe = re.compile(fileRe)
- if warnRe != None and isinstance(warnRe, basestring):
- warnRe = re.compile(warnRe)
- self.suppressions.append((fileRe, warnRe, start, end))
-
- def warnExtractWholeLine(self, line, match):
- """
- Extract warning text as the whole line.
- No file names or line numbers."""
- return (None, None, line)
-
- def warnExtractFromRegexpGroups(self, line, match):
- """
- Extract file name, line number, and warning text as groups (1,2,3)
- of warningPattern match."""
- file = match.group(1)
- lineNo = match.group(2)
- if lineNo != None:
- lineNo = int(lineNo)
- text = match.group(3)
- return (file, lineNo, text)
-
- def maybeAddWarning(self, warnings, line, match):
- if self.suppressions:
- (file, lineNo, text) = self.warningExtractor(self, line, match)
- lineNo = lineNo and int(lineNo)
-
- if file != None and file != "" and self.directoryStack:
- currentDirectory = '/'.join(self.directoryStack)
- if currentDirectory != None and currentDirectory != "":
- file = "%s/%s" % (currentDirectory, file)
-
- # Skip adding the warning if any suppression matches.
- for fileRe, warnRe, start, end in self.suppressions:
- if not (file == None or fileRe == None or fileRe.match(file)):
- continue
- if not (warnRe == None or warnRe.search(text)):
- continue
- if not ((start == None and end == None) or
- (lineNo != None and start <= lineNo and end >= lineNo)):
- continue
- return
-
- warnings.append(line)
- self.warnCount += 1
-
- def start(self):
- if self.suppressionFile == None:
- return ShellCommand.start(self)
-
- self.myFileWriter = StringFileWriter()
-
- args = {
- 'slavesrc': self.suppressionFile,
- 'workdir': self.getWorkdir(),
- 'writer': self.myFileWriter,
- 'maxsize': None,
- 'blocksize': 32*1024,
- }
- cmd = buildstep.RemoteCommand('uploadFile', args, ignore_updates=True)
- d = self.runCommand(cmd)
- d.addCallback(self.uploadDone)
- d.addErrback(self.failed)
-
- def uploadDone(self, dummy):
- lines = self.myFileWriter.buffer.split("\n")
- del(self.myFileWriter)
-
- list = []
- for line in lines:
- if self.commentEmptyLineRe.match(line):
- continue
- match = self.suppressionLineRe.match(line)
- if (match):
- file, test, start, end = match.groups()
- if (end != None):
- end = int(end)
- if (start != None):
- start = int(start)
- if end == None:
- end = start
- list.append((file, test, start, end))
-
- self.addSuppression(list)
- return ShellCommand.start(self)
-
- def createSummary(self, log):
- """
- Match log lines against warningPattern.
-
- Warnings are collected into another log for this step, and the
- build-wide 'warnings-count' is updated."""
-
- self.warnCount = 0
-
- # Now compile a regular expression from whichever warning pattern we're
- # using
- wre = self.warningPattern
- if isinstance(wre, str):
- wre = re.compile(wre)
-
- directoryEnterRe = self.directoryEnterPattern
- if (directoryEnterRe != None
- and isinstance(directoryEnterRe, basestring)):
- directoryEnterRe = re.compile(directoryEnterRe)
-
- directoryLeaveRe = self.directoryLeavePattern
- if (directoryLeaveRe != None
- and isinstance(directoryLeaveRe, basestring)):
- directoryLeaveRe = re.compile(directoryLeaveRe)
-
- # Check if each line in the output from this command matched our
- # warnings regular expressions. If did, bump the warnings count and
- # add the line to the collection of lines with warnings
- warnings = []
- # TODO: use log.readlines(), except we need to decide about stdout vs
- # stderr
- for line in log.getText().split("\n"):
- if directoryEnterRe:
- match = directoryEnterRe.search(line)
- if match:
- self.directoryStack.append(match.group(1))
- continue
- if (directoryLeaveRe and
- self.directoryStack and
- directoryLeaveRe.search(line)):
- self.directoryStack.pop()
- continue
-
- match = wre.match(line)
- if match:
- self.maybeAddWarning(warnings, line, match)
-
- # If there were any warnings, make the log if lines with warnings
- # available
- if self.warnCount:
- self.addCompleteLog("warnings (%d)" % self.warnCount,
- "\n".join(warnings) + "\n")
-
- warnings_stat = self.step_status.getStatistic('warnings', 0)
- self.step_status.setStatistic('warnings', warnings_stat + self.warnCount)
-
- old_count = self.getProperty("warnings-count", 0)
- self.setProperty("warnings-count", old_count + self.warnCount, "WarningCountingShellCommand")
-
-
- def evaluateCommand(self, cmd):
- if ( cmd.didFail() or
- ( self.maxWarnCount != None and self.warnCount > self.maxWarnCount ) ):
- return FAILURE
- if self.warnCount:
- return WARNINGS
- return SUCCESS
-
-
-class Compile(WarningCountingShellCommand):
-
- name = "compile"
- haltOnFailure = 1
- flunkOnFailure = 1
- description = ["compiling"]
- descriptionDone = ["compile"]
- command = ["make", "all"]
-
-class Test(WarningCountingShellCommand):
-
- name = "test"
- warnOnFailure = 1
- description = ["testing"]
- descriptionDone = ["test"]
- command = ["make", "test"]
-
- def setTestResults(self, total=0, failed=0, passed=0, warnings=0):
- """
- Called by subclasses to set the relevant statistics; this actually
- adds to any statistics already present
- """
- total += self.step_status.getStatistic('tests-total', 0)
- self.step_status.setStatistic('tests-total', total)
- failed += self.step_status.getStatistic('tests-failed', 0)
- self.step_status.setStatistic('tests-failed', failed)
- warnings += self.step_status.getStatistic('tests-warnings', 0)
- self.step_status.setStatistic('tests-warnings', warnings)
- passed += self.step_status.getStatistic('tests-passed', 0)
- self.step_status.setStatistic('tests-passed', passed)
-
- def describe(self, done=False):
- description = WarningCountingShellCommand.describe(self, done)
- if done:
- description = description[:] # make a private copy
- if self.step_status.hasStatistic('tests-total'):
- total = self.step_status.getStatistic("tests-total", 0)
- failed = self.step_status.getStatistic("tests-failed", 0)
- passed = self.step_status.getStatistic("tests-passed", 0)
- warnings = self.step_status.getStatistic("tests-warnings", 0)
- if not total:
- total = failed + passed + warnings
-
- if total:
- description.append('%d tests' % total)
- if passed:
- description.append('%d passed' % passed)
- if warnings:
- description.append('%d warnings' % warnings)
- if failed:
- description.append('%d failed' % failed)
- return description
-
-class PerlModuleTest(Test):
- command=["prove", "--lib", "lib", "-r", "t"]
- total = 0
-
- def evaluateCommand(self, cmd):
- # Get stdio, stripping pesky newlines etc.
- lines = map(
- lambda line : line.replace('\r\n','').replace('\r','').replace('\n',''),
- self.getLog('stdio').readlines()
- )
-
- total = 0
- passed = 0
- failed = 0
- rc = SUCCESS
- if cmd.didFail():
- rc = FAILURE
-
- # New version of Test::Harness?
- if "Test Summary Report" in lines:
- test_summary_report_index = lines.index("Test Summary Report")
- del lines[0:test_summary_report_index + 2]
-
- re_test_result = re.compile("^Result: (PASS|FAIL)$|Tests: \d+ Failed: (\d+)\)|Files=\d+, Tests=(\d+)")
-
- mos = map(lambda line: re_test_result.search(line), lines)
- test_result_lines = [mo.groups() for mo in mos if mo]
-
- for line in test_result_lines:
- if line[0] == 'FAIL':
- rc = FAILURE
-
- if line[1]:
- failed += int(line[1])
- if line[2]:
- total = int(line[2])
-
- else: # Nope, it's the old version
- re_test_result = re.compile("^(All tests successful)|(\d+)/(\d+) subtests failed|Files=\d+, Tests=(\d+),")
-
- mos = map(lambda line: re_test_result.search(line), lines)
- test_result_lines = [mo.groups() for mo in mos if mo]
-
- if test_result_lines:
- test_result_line = test_result_lines[0]
-
- success = test_result_line[0]
-
- if success:
- failed = 0
-
- test_totals_line = test_result_lines[1]
- total_str = test_totals_line[3]
- else:
- failed_str = test_result_line[1]
- failed = int(failed_str)
-
- total_str = test_result_line[2]
-
- rc = FAILURE
-
- total = int(total_str)
-
- warnings = 0
- if self.warningPattern:
- wre = self.warningPattern
- if isinstance(wre, str):
- wre = re.compile(wre)
-
- warnings = len([l for l in lines if wre.search(l)])
-
- # Because there are two paths that are used to determine
- # the success/fail result, I have to modify it here if
- # there were warnings.
- if rc == SUCCESS and warnings:
- rc = WARNINGS
-
- if total:
- passed = total - failed
-
- self.setTestResults(total=total, failed=failed, passed=passed,
- warnings=warnings)
-
- return rc
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/slave.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/slave.py
deleted file mode 100644
index 3b5a20f6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/slave.py
+++ /dev/null
@@ -1,270 +0,0 @@
-# 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 stat
-from twisted.internet import defer
-from buildbot.process import buildstep
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.interfaces import BuildSlaveTooOldError
-
-class SlaveBuildStep(buildstep.BuildStep):
- def describe(self, done=False):
- return self.descriptionDone if done else self.description
-
-class SetPropertiesFromEnv(SlaveBuildStep):
- """
- Sets properties from envirionment variables on the slave.
-
- Note this is transfered when the slave first connects
- """
- name='SetPropertiesFromEnv'
- description=['Setting']
- descriptionDone=['Set']
-
- def __init__(self, variables, source="SlaveEnvironment", **kwargs):
- buildstep.BuildStep.__init__(self, **kwargs)
- self.variables = variables
- self.source = source
-
- def start(self):
- # on Windows, environment variables are case-insensitive, but we have
- # a case-sensitive dictionary in slave_environ. Fortunately, that
- # dictionary is also folded to uppercase, so we can simply fold the
- # variable names to uppercase to duplicate the case-insensitivity.
- fold_to_uppercase = (self.buildslave.slave_system == 'win32')
-
- properties = self.build.getProperties()
- environ = self.buildslave.slave_environ
- variables = self.variables
- log = []
- if isinstance(variables, str):
- variables = [self.variables]
- for variable in variables:
- key = variable
- if fold_to_uppercase:
- key = variable.upper()
- value = environ.get(key, None)
- if value:
- # note that the property is not uppercased
- properties.setProperty(variable, value, self.source,
- runtime=True)
- log.append("%s = %r" % (variable, value))
- self.addCompleteLog("properties", "\n".join(log))
- self.step_status.setText(self.describe(done=True))
- self.finished(SUCCESS)
-
-class FileExists(SlaveBuildStep):
- """
- Check for the existence of a file on the slave.
- """
- name='FileExists'
- description='Checking'
- descriptionDone='Checked'
-
- renderables = [ 'file' ]
-
- haltOnFailure = True
- flunkOnFailure = True
-
-
- def __init__(self, file, **kwargs):
- buildstep.BuildStep.__init__(self, **kwargs)
- self.file = file
-
- def start(self):
- slavever = self.slaveVersion('stat')
- if not slavever:
- raise BuildSlaveTooOldError("slave is too old, does not know "
- "about stat")
- cmd = buildstep.RemoteCommand('stat', {'file': self.file })
- d = self.runCommand(cmd)
- d.addCallback(lambda res: self.commandComplete(cmd))
- d.addErrback(self.failed)
-
- def commandComplete(self, cmd):
- if cmd.didFail():
- self.step_status.setText(["File not found."])
- self.finished(FAILURE)
- return
- s = cmd.updates["stat"][-1]
- if stat.S_ISREG(s[stat.ST_MODE]):
- self.step_status.setText(["File found."])
- self.finished(SUCCESS)
- else:
- self.step_status.setText(["Not a file."])
- self.finished(FAILURE)
-
-class CopyDirectory(SlaveBuildStep):
- """
- Copy a directory tree on the slave.
- """
- name='CopyDirectory'
- description=['Copying']
- descriptionDone=['Copied']
-
- renderables = [ 'src', 'dest' ]
-
- haltOnFailure = True
- flunkOnFailure = True
-
- def __init__(self, src, dest, timeout=None, maxTime=None, **kwargs):
- buildstep.BuildStep.__init__(self, **kwargs)
- self.src = src
- self.dest = dest
- self.timeout = timeout
- self.maxTime = maxTime
-
- def start(self):
- slavever = self.slaveVersion('cpdir')
- if not slavever:
- raise BuildSlaveTooOldError("slave is too old, does not know "
- "about cpdir")
-
- args = {'fromdir': self.src, 'todir': self.dest }
- if self.timeout:
- args['timeout'] = self.timeout
- if self.maxTime:
- args['maxTime'] = self.maxTime
-
- cmd = buildstep.RemoteCommand('cpdir', args)
- d = self.runCommand(cmd)
- d.addCallback(lambda res: self.commandComplete(cmd))
- d.addErrback(self.failed)
-
- def commandComplete(self, cmd):
- if cmd.didFail():
- self.step_status.setText(["Copying", self.src, "to", self.dest, "failed."])
- self.finished(FAILURE)
- return
- self.step_status.setText(self.describe(done=True))
- self.finished(SUCCESS)
-
- def describe(self, done=False):
- desc = self.descriptionDone if done else self.description
- desc = desc[:]
- desc.extend([self.src, "to", self.dest])
- return desc
-
-class RemoveDirectory(SlaveBuildStep):
- """
- Remove a directory tree on the slave.
- """
- name='RemoveDirectory'
- description=['Deleting']
- descriptionDone=['Deleted']
-
- renderables = [ 'dir' ]
-
- haltOnFailure = True
- flunkOnFailure = True
-
- def __init__(self, dir, **kwargs):
- buildstep.BuildStep.__init__(self, **kwargs)
- self.dir = dir
-
- def start(self):
- slavever = self.slaveVersion('rmdir')
- if not slavever:
- raise BuildSlaveTooOldError("slave is too old, does not know "
- "about rmdir")
- cmd = buildstep.RemoteCommand('rmdir', {'dir': self.dir })
- d = self.runCommand(cmd)
- d.addCallback(lambda res: self.commandComplete(cmd))
- d.addErrback(self.failed)
-
- def commandComplete(self, cmd):
- if cmd.didFail():
- self.step_status.setText(["Delete failed."])
- self.finished(FAILURE)
- return
- self.step_status.setText(self.describe(done=True))
- self.finished(SUCCESS)
-
-class MakeDirectory(SlaveBuildStep):
- """
- Create a directory on the slave.
- """
- name='MakeDirectory'
- description=['Creating']
- descriptionDone=['Created']
-
- renderables = [ 'dir' ]
-
- haltOnFailure = True
- flunkOnFailure = True
-
- def __init__(self, dir, **kwargs):
- buildstep.BuildStep.__init__(self, **kwargs)
- self.dir = dir
-
- def start(self):
- slavever = self.slaveVersion('mkdir')
- if not slavever:
- raise BuildSlaveTooOldError("slave is too old, does not know "
- "about mkdir")
- cmd = buildstep.RemoteCommand('mkdir', {'dir': self.dir })
- d = self.runCommand(cmd)
- d.addCallback(lambda res: self.commandComplete(cmd))
- d.addErrback(self.failed)
-
- def commandComplete(self, cmd):
- if cmd.didFail():
- self.step_status.setText(["Create failed."])
- self.finished(FAILURE)
- return
- self.step_status.setText(self.describe(done=True))
- self.finished(SUCCESS)
-
-class CompositeStepMixin():
- """I define utils for composite steps, factorizing basic remote commands"""
- def addLogForRemoteCommands(self, logname):
- """This method must be called by user classes
- composite steps could create several logs, this mixin functions will write
- to the last one.
- """
- self.rc_log = self.addLog(logname)
- return self.rc_log
-
- def runRemoteCommand(self, cmd, args, abandonOnFailure=True):
- """generic RemoteCommand boilerplate"""
- cmd = buildstep.RemoteCommand(cmd, args)
- cmd.useLog(self.rc_log, False)
- d = self.runCommand(cmd)
- def commandComplete(cmd):
- if abandonOnFailure and cmd.didFail():
- raise buildstep.BuildStepFailed()
- return cmd.didFail()
- d.addCallback(lambda res: commandComplete(cmd))
- return d
-
- def runRmdir(self, dir, **kwargs):
- """ remove a directory from the slave """
- return self.runRemoteCommand('rmdir',
- {'dir': dir, 'logEnviron': self.logEnviron },
- **kwargs)
-
- @defer.inlineCallbacks
- def pathExists(self, path):
- """ test whether path exists"""
- res = yield self.runRemoteCommand('stat', {'file': path,
- 'logEnviron': self.logEnviron,},
- abandonOnFailure=False)
- defer.returnValue(not res)
-
- def runMkdir(self, _dir, **kwargs):
- """ create a directory and its parents"""
- return self.runRemoteCommand('mkdir', {'dir': _dir,
- 'logEnviron': self.logEnviron,},
- **kwargs)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/__init__.py
deleted file mode 100644
index 57fa1107..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/__init__.py
+++ /dev/null
@@ -1,21 +0,0 @@
-# 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
-
-from buildbot.steps.source.base import Source
-from buildbot.steps.source.oldsource import CVS, \
- SVN, Git, Darcs, Repo, Bzr, Mercurial, P4, Monotone, BK
-
-_hush_pyflakes = [ Source, CVS, SVN, \
- Git, Darcs, Repo, Bzr, Mercurial, P4, Monotone, BK ]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/base.py
deleted file mode 100644
index 13da81c3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/base.py
+++ /dev/null
@@ -1,230 +0,0 @@
-# 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
-
-
-from twisted.python import log
-from buildbot.process.buildstep import LoggingBuildStep
-from buildbot.status.builder import SKIPPED, FAILURE
-from buildbot.steps.slave import CompositeStepMixin
-
-class Source(LoggingBuildStep, CompositeStepMixin):
- """This is a base class to generate a source tree in the buildslave.
- Each version control system has a specialized subclass, and is expected
- to override __init__ and implement computeSourceRevision() and
- startVC(). The class as a whole builds up the self.args dictionary, then
- starts a RemoteCommand with those arguments.
- """
-
- renderables = LoggingBuildStep.renderables + [
- 'description', 'descriptionDone', 'descriptionSuffix',
- 'workdir' ]
-
- description = None # set this to a list of short strings to override
- descriptionDone = None # alternate description when the step is complete
- descriptionSuffix = None # extra information to append to suffix
-
- # if the checkout fails, there's no point in doing anything else
- haltOnFailure = True
- flunkOnFailure = True
- notReally = False
-
- branch = None # the default branch, should be set in __init__
-
- def __init__(self, workdir=None, mode='update', alwaysUseLatest=False,
- timeout=20*60, retry=None, env=None, logEnviron=True,
- description=None, descriptionDone=None, descriptionSuffix=None,
- codebase='', **kwargs):
- """
- @type workdir: string
- @param workdir: local directory (relative to the Builder's root)
- where the tree should be placed
-
- @type alwaysUseLatest: boolean
- @param alwaysUseLatest: whether to always update to the most
- recent available sources for this build.
-
- Normally the Source step asks its Build for a list of all
- Changes that are supposed to go into the build, then computes a
- 'source stamp' (revision number or timestamp) that will cause
- exactly that set of changes to be present in the checked out
- tree. This is turned into, e.g., 'cvs update -D timestamp', or
- 'svn update -r revnum'. If alwaysUseLatest=True, bypass this
- computation and always update to the latest available sources
- for each build.
-
- The source stamp helps avoid a race condition in which someone
- commits a change after the master has decided to start a build
- but before the slave finishes checking out the sources. At best
- this results in a build which contains more changes than the
- buildmaster thinks it has (possibly resulting in the wrong
- person taking the blame for any problems that result), at worst
- is can result in an incoherent set of sources (splitting a
- non-atomic commit) which may not build at all.
-
- @type logEnviron: boolean
- @param logEnviron: If this option is true (the default), then the
- step's logfile will describe the environment
- variables on the slave. In situations where the
- environment is not relevant and is long, it may
- be easier to set logEnviron=False.
-
- @type codebase: string
- @param codebase: Specifies which changes in a build are processed by
- the step. The default codebase value is ''. The codebase must correspond
- to a codebase assigned by the codebaseGenerator. If no codebaseGenerator
- is defined in the master then codebase doesn't need to be set, the
- default value will then match all changes.
- """
-
- LoggingBuildStep.__init__(self, **kwargs)
-
- # This will get added to args later, after properties are rendered
- self.workdir = workdir
-
- self.sourcestamp = None
-
- self.codebase = codebase
- if self.codebase:
- self.name = ' '.join((self.name, self.codebase))
-
- self.alwaysUseLatest = alwaysUseLatest
-
- self.logEnviron = logEnviron
- self.env = env
- self.timeout = timeout
-
- descriptions_for_mode = {
- "clobber": "checkout",
- "export": "exporting"}
- descriptionDones_for_mode = {
- "clobber": "checkout",
- "export": "export"}
- if description:
- self.description = description
- else:
- self.description = [
- descriptions_for_mode.get(mode, "updating")]
- if isinstance(self.description, str):
- self.description = [self.description]
-
- if descriptionDone:
- self.descriptionDone = descriptionDone
- else:
- self.descriptionDone = [
- descriptionDones_for_mode.get(mode, "update")]
- if isinstance(self.descriptionDone, str):
- self.descriptionDone = [self.descriptionDone]
-
- if descriptionSuffix:
- self.descriptionSuffix = descriptionSuffix
- else:
- self.descriptionSuffix = self.codebase or None # want None in lieu of ''
- if isinstance(self.descriptionSuffix, str):
- self.descriptionSuffix = [self.descriptionSuffix]
-
- def updateSourceProperty(self, name, value, source=''):
- """
- Update a property, indexing the property by codebase if codebase is not
- ''. Source steps should generally use this instead of setProperty.
- """
- # pick a decent source name
- if source == '':
- source = self.__class__.__name__
-
- if self.codebase != '':
- assert not isinstance(self.getProperty(name, None), str), \
- "Sourcestep %s has a codebase, other sourcesteps don't" \
- % self.name
- property_dict = self.getProperty(name, {})
- property_dict[self.codebase] = value
- LoggingBuildStep.setProperty(self, name, property_dict, source)
- else:
- assert not isinstance(self.getProperty(name, None), dict), \
- "Sourcestep %s does not have a codebase, other sourcesteps do" \
- % self.name
- LoggingBuildStep.setProperty(self, name, value, source)
-
- def setStepStatus(self, step_status):
- LoggingBuildStep.setStepStatus(self, step_status)
-
- def setDefaultWorkdir(self, workdir):
- self.workdir = self.workdir or workdir
-
- def describe(self, done=False):
- desc = self.descriptionDone if done else self.description
- if self.descriptionSuffix:
- desc = desc[:]
- desc.extend(self.descriptionSuffix)
- return desc
-
- def computeSourceRevision(self, changes):
- """Each subclass must implement this method to do something more
- precise than -rHEAD every time. For version control systems that use
- repository-wide change numbers (SVN, P4), this can simply take the
- maximum such number from all the changes involved in this build. For
- systems that do not (CVS), it needs to create a timestamp based upon
- the latest Change, the Build's treeStableTimer, and an optional
- self.checkoutDelay value."""
- return None
-
- def start(self):
- if self.notReally:
- log.msg("faking %s checkout/update" % self.name)
- self.step_status.setText(["fake", self.name, "successful"])
- self.addCompleteLog("log",
- "Faked %s checkout/update 'successful'\n" \
- % self.name)
- return SKIPPED
-
- if not self.alwaysUseLatest:
- # what source stamp would this step like to use?
- s = self.build.getSourceStamp(self.codebase)
- self.sourcestamp = s
-
- if self.sourcestamp:
- # if branch is None, then use the Step's "default" branch
- branch = s.branch or self.branch
- # if revision is None, use the latest sources (-rHEAD)
- revision = s.revision
- if not revision:
- revision = self.computeSourceRevision(s.changes)
- # the revision property is currently None, so set it to something
- # more interesting
- if revision is not None:
- self.updateSourceProperty('revision', str(revision))
-
- # if patch is None, then do not patch the tree after checkout
-
- # 'patch' is None or a tuple of (patchlevel, diff, root)
- # root is optional.
- patch = s.patch
- if patch:
- self.addCompleteLog("patch", patch[1])
- else:
- log.msg("No sourcestamp found in build for codebase '%s'" % self.codebase)
- self.step_status.setText(["Codebase", '%s' % self.codebase ,"not", "in", "build" ])
- self.addCompleteLog("log",
- "No sourcestamp found in build for codebase '%s'" \
- % self.codebase)
- self.finished(FAILURE)
- return FAILURE
-
- else:
- revision = None
- branch = self.branch
- patch = None
-
- self.startVC(branch, revision, patch)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/bzr.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/bzr.py
deleted file mode 100644
index a7deed93..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/bzr.py
+++ /dev/null
@@ -1,244 +0,0 @@
-# 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 os
-
-from twisted.python import log
-from twisted.internet import defer
-
-from buildbot.process import buildstep
-from buildbot.steps.source.base import Source
-from buildbot.interfaces import BuildSlaveTooOldError
-
-class Bzr(Source):
-
- name = 'bzr'
- renderables = [ 'repourl', 'baseURL' ]
-
- def __init__(self, repourl=None, baseURL=None, mode='incremental',
- method=None, defaultBranch=None, **kwargs):
-
- self.repourl = repourl
- self.baseURL = baseURL
- self.branch = defaultBranch
- self.mode = mode
- self.method = method
- Source.__init__(self, **kwargs)
- if repourl and baseURL:
- raise ValueError("you must provide exactly one of repourl and"
- " baseURL")
-
- if repourl is None and baseURL is None:
- raise ValueError("you must privide at least one of repourl and"
- " baseURL")
-
- if baseURL is not None and defaultBranch is None:
- raise ValueError("you must provide defaultBranch with baseURL")
-
- assert self.mode in ['incremental', 'full']
-
- if self.mode == 'full':
- assert self.method in ['clean', 'fresh', 'clobber', 'copy', None]
-
- def startVC(self, branch, revision, patch):
- if branch:
- self.branch = branch
- self.revision = revision
- self.method = self._getMethod()
- self.stdio_log = self.addLogForRemoteCommands("stdio")
-
- if self.repourl is None:
- self.repourl = os.path.join(self.baseURL, self.branch)
-
- d = self.checkBzr()
- def checkInstall(bzrInstalled):
- if not bzrInstalled:
- raise BuildSlaveTooOldError("bzr is not installed on slave")
- return 0
-
- d.addCallback(checkInstall)
- if self.mode == 'full':
- d.addCallback(lambda _: self.full())
- elif self.mode == 'incremental':
- d.addCallback(lambda _: self.incremental())
-
- d.addCallback(self.parseGotRevision)
- d.addCallback(self.finish)
- d.addErrback(self.failed)
- return d
-
- def incremental(self):
- d = self._sourcedirIsUpdatable()
- def _cmd(updatable):
- if updatable:
- command = ['update']
- else:
- command = ['checkout', self.repourl, '.']
-
- if self.revision:
- command.extend(['-r', self.revision])
- return command
-
- d.addCallback(_cmd)
- d.addCallback(self._dovccmd)
- return d
-
- @defer.inlineCallbacks
- def full(self):
- if self.method == 'clobber':
- yield self.clobber()
- return
- elif self.method == 'copy':
- self.workdir = 'source'
- yield self.copy()
- return
-
- updatable = self._sourcedirIsUpdatable()
- if not updatable:
- log.msg("No bzr repo present, making full checkout")
- yield self._doFull()
- elif self.method == 'clean':
- yield self.clean()
- elif self.method == 'fresh':
- yield self.fresh()
- else:
- raise ValueError("Unknown method, check your configuration")
-
- def clobber(self):
- cmd = buildstep.RemoteCommand('rmdir', {'dir': self.workdir,
- 'logEnviron': self.logEnviron,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def checkRemoval(res):
- if res != 0:
- raise RuntimeError("Failed to delete directory")
- return res
- d.addCallback(lambda _: checkRemoval(cmd.rc))
- d.addCallback(lambda _: self._doFull())
- return d
-
- def copy(self):
- cmd = buildstep.RemoteCommand('rmdir', {'dir': 'build',
- 'logEnviron': self.logEnviron,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- d.addCallback(lambda _: self.incremental())
- def copy(_):
- cmd = buildstep.RemoteCommand('cpdir',
- {'fromdir': 'source',
- 'todir':'build',
- 'logEnviron': self.logEnviron,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- return d
- d.addCallback(copy)
- return d
-
- def clean(self):
- d = self._dovccmd(['clean-tree', '--ignored', '--force'])
- command = ['update']
- if self.revision:
- command.extend(['-r', self.revision])
- d.addCallback(lambda _: self._dovccmd(command))
- return d
-
- def fresh(self):
- d = self._dovccmd(['clean-tree', '--force'])
- command = ['update']
- if self.revision:
- command.extend(['-r', self.revision])
- d.addCallback(lambda _: self._dovccmd(command))
- return d
-
- def _doFull(self):
- command = ['checkout', self.repourl, '.']
- if self.revision:
- command.extend(['-r', self.revision])
- d = self._dovccmd(command)
- return d
-
- def finish(self, res):
- d = defer.succeed(res)
- def _gotResults(results):
- self.setStatus(self.cmd, results)
- log.msg("Closing log, sending result of the command %s " % \
- (self.cmd))
- return results
- d.addCallback(_gotResults)
- d.addCallbacks(self.finished, self.checkDisconnect)
- return d
-
- def _sourcedirIsUpdatable(self):
- return self.pathExists(self.build.path_module.join(self.workdir, '.bzr'))
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- lastChange = max([int(c.revision) for c in changes])
- return lastChange
-
- def _dovccmd(self, command, abandonOnFailure=True, collectStdout=False):
- cmd = buildstep.RemoteShellCommand(self.workdir, ['bzr'] + command,
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout,
- collectStdout=collectStdout)
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def evaluateCommand(cmd):
- if abandonOnFailure and cmd.didFail():
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- if collectStdout:
- return cmd.stdout
- else:
- return cmd.rc
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- def checkBzr(self):
- d = self._dovccmd(['--version'])
- def check(res):
- if res == 0:
- return True
- return False
- d.addCallback(check)
- return d
-
- def _getMethod(self):
- if self.method is not None and self.mode != 'incremental':
- return self.method
- elif self.mode == 'incremental':
- return None
- elif self.method is None and self.mode == 'full':
- return 'fresh'
-
- def parseGotRevision(self, _):
- d = self._dovccmd(["version-info", "--custom", "--template='{revno}"],
- collectStdout=True)
- def setrev(stdout):
- revision = stdout.strip("'")
- try:
- int(revision)
- except ValueError:
- log.msg("Invalid revision number")
- raise buildstep.BuildStepFailed()
-
- log.msg("Got Git revision %s" % (revision, ))
- self.updateSourceProperty('got_revision', revision)
- return 0
- d.addCallback(setrev)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/cvs.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/cvs.py
deleted file mode 100644
index 3fbb40e4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/cvs.py
+++ /dev/null
@@ -1,302 +0,0 @@
-# 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
-
-from email.Utils import formatdate
-import time
-import re
-
-from twisted.python import log
-from twisted.internet import defer
-
-from buildbot.process import buildstep
-from buildbot.steps.shell import StringFileWriter
-from buildbot.steps.source.base import Source
-from buildbot.interfaces import BuildSlaveTooOldError
-
-class CVS(Source):
-
- name = "cvs"
-
- renderables = [ "cvsroot" ]
-
- def __init__(self, cvsroot=None, cvsmodule='', mode='incremental',
- method=None, branch=None, global_options=[], extra_options=[],
- login=None, **kwargs):
-
- self.cvsroot = cvsroot
- self.cvsmodule = cvsmodule
- self.branch = branch
- self.global_options = global_options
- self.extra_options = extra_options
- self.login = login
- self.mode = mode
- self.method = method
- self.srcdir = 'source'
- Source.__init__(self, **kwargs)
-
- def startVC(self, branch, revision, patch):
- self.branch = branch
- self.revision = revision
- self.stdio_log = self.addLog("stdio")
- self.method = self._getMethod()
- d = self.checkCvs()
- def checkInstall(cvsInstalled):
- if not cvsInstalled:
- raise BuildSlaveTooOldError("CVS is not installed on slave")
- return 0
- d.addCallback(checkInstall)
- d.addCallback(self.checkLogin)
-
- if self.mode == 'incremental':
- d.addCallback(lambda _: self.incremental())
- elif self.mode == 'full':
- d.addCallback(lambda _: self.full())
-
- d.addCallback(self.parseGotRevision)
- d.addCallback(self.finish)
- d.addErrback(self.failed)
- return d
-
- @defer.inlineCallbacks
- def incremental(self):
- updatable = yield self._sourcedirIsUpdatable()
- if updatable:
- rv = yield self.doUpdate()
- else:
- rv = yield self.clobber()
- defer.returnValue(rv)
-
- @defer.inlineCallbacks
- def full(self):
- if self.method == 'clobber':
- rv = yield self.clobber()
- defer.returnValue(rv)
- return
-
- elif self.method == 'copy':
- rv = yield self.copy()
- defer.returnValue(rv)
- return
-
- updatable = yield self._sourcedirIsUpdatable()
- if not updatable:
- log.msg("CVS repo not present, making full checkout")
- rv = yield self.doCheckout(self.workdir)
- elif self.method == 'clean':
- rv = yield self.clean()
- elif self.method == 'fresh':
- rv = yield self.fresh()
- else:
- raise ValueError("Unknown method, check your configuration")
- defer.returnValue(rv)
-
- def clobber(self):
- cmd = buildstep.RemoteCommand('rmdir', {'dir': self.workdir,
- 'logEnviron': self.logEnviron})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def checkRemoval(res):
- if res != 0:
- raise RuntimeError("Failed to delete directory")
- return res
- d.addCallback(lambda _: checkRemoval(cmd.rc))
- d.addCallback(lambda _: self.doCheckout(self.workdir))
- return d
-
- def fresh(self, ):
- d = self.purge(True)
- d.addCallback(lambda _: self.doUpdate())
- return d
-
- def clean(self, ):
- d = self.purge(False)
- d.addCallback(lambda _: self.doUpdate())
- return d
-
- def copy(self):
- cmd = buildstep.RemoteCommand('rmdir', {'dir': self.workdir,
- 'logEnviron': self.logEnviron})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- self.workdir = 'source'
- d.addCallback(lambda _: self.incremental())
- def copy(_):
- cmd = buildstep.RemoteCommand('cpdir',
- {'fromdir': 'source',
- 'todir':'build',
- 'logEnviron': self.logEnviron,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- return d
- d.addCallback(copy)
- def resetWorkdir(_):
- self.workdir = 'build'
- return 0
- d.addCallback(resetWorkdir)
- return d
-
- def purge(self, ignore_ignores):
- command = ['cvsdiscard']
- if ignore_ignores:
- command += ['--ignore']
- cmd = buildstep.RemoteShellCommand(self.workdir, command,
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout)
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def evaluate(cmd):
- if cmd.didFail():
- raise buildstep.BuildStepFailed()
- return cmd.rc
- d.addCallback(evaluate)
- return d
-
- def doCheckout(self, dir):
- command = ['-d', self.cvsroot, '-z3', 'checkout', '-d', dir ]
- command = self.global_options + command + self.extra_options
- if self.branch:
- command += ['-r', self.branch]
- if self.revision:
- command += ['-D', self.revision]
- command += [ self.cvsmodule ]
- d = self._dovccmd(command, '')
- return d
-
- def doUpdate(self):
- command = ['-z3', 'update', '-dP']
- branch = self.branch
- # special case. 'cvs update -r HEAD -D today' gives no files; see #2351
- if branch == 'HEAD' and self.revision:
- branch = None
- if branch:
- command += ['-r', self.branch]
- if self.revision:
- command += ['-D', self.revision]
- d = self._dovccmd(command)
- return d
-
- def finish(self, res):
- d = defer.succeed(res)
- def _gotResults(results):
- self.setStatus(self.cmd, results)
- return results
- d.addCallback(_gotResults)
- d.addCallbacks(self.finished, self.checkDisconnect)
- return d
-
- def checkLogin(self, _):
- if self.login:
- d = defer.succeed(0)
- else:
- d = self._dovccmd(['-d', self.cvsroot, 'login'])
- def setLogin(res):
- # this happens only if the login command succeeds.
- self.login = True
- return res
- d.addCallback(setLogin)
-
- return d
-
- def _dovccmd(self, command, workdir=None):
- if workdir is None:
- workdir = self.workdir
- if not command:
- raise ValueError("No command specified")
- cmd = buildstep.RemoteShellCommand(workdir, ['cvs'] +
- command,
- env=self.env,
- timeout=self.timeout,
- logEnviron=self.logEnviron)
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def evaluateCommand(cmd):
- if cmd.rc != 0:
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- return cmd.rc
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- @defer.inlineCallbacks
- def _sourcedirIsUpdatable(self):
- myFileWriter = StringFileWriter()
- args = {
- 'workdir': self.build.path_module.join(self.workdir, 'CVS'),
- 'writer': myFileWriter,
- 'maxsize': None,
- 'blocksize': 32*1024,
- }
-
- cmd = buildstep.RemoteCommand('uploadFile',
- dict(slavesrc='Root', **args),
- ignore_updates=True)
- yield self.runCommand(cmd)
- if cmd.rc is not None and cmd.rc != 0:
- defer.returnValue(False)
- return
-
- # on Windows, the cvsroot may not contain the password, so compare to
- # both
- cvsroot_without_pw = re.sub("(:pserver:[^:]*):[^@]*(@.*)",
- r"\1\2", self.cvsroot)
- if myFileWriter.buffer.strip() not in (self.cvsroot,
- cvsroot_without_pw):
- defer.returnValue(False)
- return
-
- myFileWriter.buffer = ""
- cmd = buildstep.RemoteCommand('uploadFile',
- dict(slavesrc='Repository', **args),
- ignore_updates=True)
- yield self.runCommand(cmd)
- if cmd.rc is not None and cmd.rc != 0:
- defer.returnValue(False)
- return
- if myFileWriter.buffer.strip() != self.cvsmodule:
- defer.returnValue(False)
- return
-
- defer.returnValue(True)
-
- def parseGotRevision(self, res):
- revision = time.strftime("%Y-%m-%d %H:%M:%S +0000", time.gmtime())
- self.updateSourceProperty('got_revision', revision)
- return res
-
- def checkCvs(self):
- d = self._dovccmd(['--version'])
- def check(res):
- if res == 0:
- return True
- return False
- d.addCallback(check)
- return d
-
- def _getMethod(self):
- if self.method is not None and self.mode != 'incremental':
- return self.method
- elif self.mode == 'incremental':
- return None
- elif self.method is None and self.mode == 'full':
- return 'fresh'
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- lastChange = max([c.when for c in changes])
- lastSubmit = max([br.submittedAt for br in self.build.requests])
- when = (lastChange + lastSubmit) / 2
- return formatdate(when)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/git.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/git.py
deleted file mode 100644
index 21fcc8e5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/git.py
+++ /dev/null
@@ -1,481 +0,0 @@
-# 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
-
-from twisted.python import log
-from twisted.internet import defer
-
-from buildbot import config as bbconfig
-from buildbot.process import buildstep
-from buildbot.steps.source.base import Source
-from buildbot.interfaces import BuildSlaveTooOldError
-
-def isTrueOrIsExactlyZero(v):
- # nonzero values are true...
- if v:
- return True
-
- # ... and True for the number zero, but we have to
- # explicitly guard against v==False, since
- # isinstance(False, int) is surprisingly True
- if isinstance(v, int) and v is not False:
- return True
-
- # all other false-ish values are false
- return False
-
-git_describe_flags = [
- # on or off
- ('all', lambda v: ['--all'] if v else None),
- ('always', lambda v: ['--always'] if v else None),
- ('contains', lambda v: ['--contains'] if v else None),
- ('debug', lambda v: ['--debug'] if v else None),
- ('long', lambda v: ['--long'] if v else None),
- ('exact-match', lambda v: ['--exact-match'] if v else None),
- ('tags', lambda v: ['--tags'] if v else None),
- # string parameter
- ('match', lambda v: ['--match', v] if v else None),
- # numeric parameter
- ('abbrev', lambda v: ['--abbrev=%s' % v] if isTrueOrIsExactlyZero(v) else None),
- ('candidates', lambda v: ['--candidates=%s' % v] if isTrueOrIsExactlyZero(v) else None),
- # optional string parameter
- ('dirty', lambda v: ['--dirty'] if (v is True or v=='') else None),
- ('dirty', lambda v: ['--dirty=%s' % v] if (v and v is not True) else None),
-]
-
-class Git(Source):
- """ Class for Git with all the smarts """
- name='git'
- renderables = [ "repourl"]
-
- def __init__(self, repourl=None, branch='HEAD', mode='incremental',
- method=None, submodules=False, shallow=False, progress=False,
- retryFetch=False, clobberOnFailure=False, getDescription=False,
- config=None, **kwargs):
- """
- @type repourl: string
- @param repourl: the URL which points at the git repository
-
- @type branch: string
- @param branch: The branch or tag to check out by default. If
- a build specifies a different branch, it will
- be used instead of this.
-
- @type submodules: boolean
- @param submodules: Whether or not to update (and initialize)
- git submodules.
-
- @type mode: string
- @param mode: Type of checkout. Described in docs.
-
- @type method: string
- @param method: Full builds can be done is different ways. This parameter
- specifies which method to use.
-
- @type progress: boolean
- @param progress: Pass the --progress option when fetching. This
- can solve long fetches getting killed due to
- lack of output, but requires Git 1.7.2+.
- @type shallow: boolean
- @param shallow: Use a shallow or clone, if possible
-
- @type retryFetch: boolean
- @param retryFetch: Retry fetching before failing source checkout.
-
- @type getDescription: boolean or dict
- @param getDescription: Use 'git describe' to describe the fetched revision
-
- @type config: dict
- @param config: Git configuration options to enable when running git
- """
- if not getDescription and not isinstance(getDescription, dict):
- getDescription = False
-
- self.branch = branch
- self.method = method
- self.prog = progress
- self.repourl = repourl
- self.retryFetch = retryFetch
- self.submodules = submodules
- self.shallow = shallow
- self.fetchcount = 0
- self.clobberOnFailure = clobberOnFailure
- self.mode = mode
- self.getDescription = getDescription
- self.config = config
- Source.__init__(self, **kwargs)
-
- if self.mode not in ['incremental', 'full']:
- bbconfig.error("Git: mode must be 'incremental' or 'full'.")
- if not self.repourl:
- bbconfig.error("Git: must provide repourl.")
- if (self.mode == 'full' and
- self.method not in ['clean', 'fresh', 'clobber', 'copy', None]):
- bbconfig.error("Git: invalid method for mode 'full'.")
- if self.shallow and (self.mode != 'full' or self.method != 'clobber'):
- bbconfig.error("Git: shallow only possible with mode 'full' and method 'clobber'.")
- if not isinstance(self.getDescription, (bool, dict)):
- bbconfig.error("Git: getDescription must be a boolean or a dict.")
-
- def startVC(self, branch, revision, patch):
- self.branch = branch or 'HEAD'
- self.revision = revision
- self.method = self._getMethod()
- self.stdio_log = self.addLogForRemoteCommands("stdio")
-
- d = self.checkGit()
- def checkInstall(gitInstalled):
- if not gitInstalled:
- raise BuildSlaveTooOldError("git is not installed on slave")
- return 0
- d.addCallback(checkInstall)
-
- if self.mode == 'incremental':
- d.addCallback(lambda _: self.incremental())
- elif self.mode == 'full':
- d.addCallback(lambda _: self.full())
- if patch:
- d.addCallback(self.patch, patch)
- d.addCallback(self.parseGotRevision)
- d.addCallback(self.parseCommitDescription)
- d.addCallback(self.finish)
- d.addErrback(self.failed)
- return d
-
- @defer.inlineCallbacks
- def full(self):
- if self.method == 'clobber':
- yield self.clobber()
- return
- elif self.method == 'copy':
- yield self.copy()
- return
-
- updatable = yield self._sourcedirIsUpdatable()
- if not updatable:
- log.msg("No git repo present, making full clone")
- yield self._fullCloneOrFallback()
- elif self.method == 'clean':
- yield self.clean()
- elif self.method == 'fresh':
- yield self.fresh()
- else:
- raise ValueError("Unknown method, check your configuration")
-
- @defer.inlineCallbacks
- def incremental(self):
- updatable = yield self._sourcedirIsUpdatable()
-
- # if not updateable, do a full checkout
- if not updatable:
- yield self._fullCloneOrFallback()
- return
-
- # test for existence of the revision; rc=1 indicates it does not exist
- if self.revision:
- rc = yield self._dovccmd(['cat-file', '-e', self.revision],
- abandonOnFailure=False)
- else:
- rc = 1
-
- # if revision exists checkout to that revision
- # else fetch and update
- if rc == 0:
- yield self._dovccmd(['reset', '--hard', self.revision, '--'])
-
- if self.branch != 'HEAD':
- yield self._dovccmd(['branch', '-M', self.branch],
- abandonOnFailure=False)
- else:
- yield self._fetchOrFallback(None)
-
- yield self._updateSubmodule(None)
-
- def clean(self):
- command = ['clean', '-f', '-d']
- d = self._dovccmd(command)
- d.addCallback(self._fetchOrFallback)
- d.addCallback(self._updateSubmodule)
- d.addCallback(self._cleanSubmodule)
- return d
-
- def clobber(self):
- d = self._doClobber()
- d.addCallback(lambda _: self._fullClone(shallowClone=self.shallow))
- return d
-
- def fresh(self):
- command = ['clean', '-f', '-d', '-x']
- d = self._dovccmd(command)
- d.addCallback(self._fetchOrFallback)
- d.addCallback(self._updateSubmodule)
- d.addCallback(self._cleanSubmodule)
- return d
-
- def copy(self):
- cmd = buildstep.RemoteCommand('rmdir', {'dir': self.workdir,
- 'logEnviron': self.logEnviron,
- 'timeout': self.timeout,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
-
- self.workdir = 'source'
- d.addCallback(lambda _: self.incremental())
- def copy(_):
- cmd = buildstep.RemoteCommand('cpdir',
- {'fromdir': 'source',
- 'todir':'build',
- 'logEnviron': self.logEnviron,
- 'timeout': self.timeout,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- return d
- d.addCallback(copy)
- def resetWorkdir(_):
- self.workdir = 'build'
- return 0
-
- d.addCallback(resetWorkdir)
- return d
-
- def finish(self, res):
- d = defer.succeed(res)
- def _gotResults(results):
- self.setStatus(self.cmd, results)
- log.msg("Closing log, sending result of the command %s " % \
- (self.cmd))
- return results
- d.addCallback(_gotResults)
- d.addCallbacks(self.finished, self.checkDisconnect)
- return d
-
- @defer.inlineCallbacks
- def parseGotRevision(self, _=None):
- stdout = yield self._dovccmd(['rev-parse', 'HEAD'], collectStdout=True)
- revision = stdout.strip()
- if len(revision) != 40:
- raise buildstep.BuildStepFailed()
- log.msg("Got Git revision %s" % (revision, ))
- self.updateSourceProperty('got_revision', revision)
-
- defer.returnValue(0)
-
- @defer.inlineCallbacks
- def parseCommitDescription(self, _=None):
- if self.getDescription==False: # dict() should not return here
- defer.returnValue(0)
- return
-
- cmd = ['describe']
- if isinstance(self.getDescription, dict):
- for opt, arg in git_describe_flags:
- opt = self.getDescription.get(opt, None)
- arg = arg(opt)
- if arg:
- cmd.extend(arg)
- cmd.append('HEAD')
-
- try:
- stdout = yield self._dovccmd(cmd, collectStdout=True)
- desc = stdout.strip()
- self.updateSourceProperty('commit-description', desc)
- except:
- pass
-
- defer.returnValue(0)
-
- def _dovccmd(self, command, abandonOnFailure=True, collectStdout=False, initialStdin=None):
- full_command = ['git']
- if self.config is not None:
- for name, value in self.config.iteritems():
- full_command.append('-c')
- full_command.append('%s=%s' % (name, value))
- full_command.extend(command)
- cmd = buildstep.RemoteShellCommand(self.workdir,
- full_command,
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout,
- collectStdout=collectStdout,
- initialStdin=initialStdin)
- cmd.useLog(self.stdio_log, False)
- log.msg("Starting git command : git %s" % (" ".join(command), ))
- d = self.runCommand(cmd)
- def evaluateCommand(cmd):
- if abandonOnFailure and cmd.didFail():
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- if collectStdout:
- return cmd.stdout
- else:
- return cmd.rc
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- def _fetch(self, _):
- command = ['fetch', '-t', self.repourl, self.branch]
- # If the 'progress' option is set, tell git fetch to output
- # progress information to the log. This can solve issues with
- # long fetches killed due to lack of output, but only works
- # with Git 1.7.2 or later.
- if self.prog:
- command.append('--progress')
-
- d = self._dovccmd(command)
- def checkout(_):
- if self.revision:
- rev = self.revision
- else:
- rev = 'FETCH_HEAD'
- command = ['reset', '--hard', rev, '--']
- abandonOnFailure = not self.retryFetch and not self.clobberOnFailure
- return self._dovccmd(command, abandonOnFailure)
- d.addCallback(checkout)
- def renameBranch(res):
- if res != 0:
- return res
- d = self._dovccmd(['branch', '-M', self.branch], abandonOnFailure=False)
- # Ignore errors
- d.addCallback(lambda _: res)
- return d
-
- if self.branch != 'HEAD':
- d.addCallback(renameBranch)
- return d
-
- @defer.inlineCallbacks
- def _fetchOrFallback(self, _):
- """
- Handles fallbacks for failure of fetch,
- wrapper for self._fetch
- """
- res = yield self._fetch(None)
- if res == 0:
- defer.returnValue(res)
- return
- elif self.retryFetch:
- yield self._fetch(None)
- elif self.clobberOnFailure:
- yield self._doClobber()
- yield self._fullClone()
- else:
- raise buildstep.BuildStepFailed()
-
- def _fullClone(self, shallowClone=False):
- """Perform full clone and checkout to the revision if specified
- In the case of shallow clones if any of the step fail abort whole build step.
- """
- args = []
- if self.branch != 'HEAD':
- args += ['--branch', self.branch]
- if shallowClone:
- args += ['--depth', '1']
- command = ['clone'] + args + [self.repourl, '.']
-
- #Fix references
- if self.prog:
- command.append('--progress')
-
- # If it's a shallow clone abort build step
- d = self._dovccmd(command, shallowClone)
- # If revision specified checkout that revision
- if self.revision:
- d.addCallback(lambda _: self._dovccmd(['reset', '--hard',
- self.revision, '--'],
- shallowClone))
- # init and update submodules, recurisively. If there's not recursion
- # it will not do it.
- if self.submodules:
- d.addCallback(lambda _: self._dovccmd(['submodule', 'update',
- '--init', '--recursive'],
- shallowClone))
- return d
-
- def _fullCloneOrFallback(self):
- """Wrapper for _fullClone(). In the case of failure, if clobberOnFailure
- is set to True remove the build directory and try a full clone again.
- """
-
- d = self._fullClone()
- def clobber(res):
- if res != 0:
- if self.clobberOnFailure:
- d = self._doClobber()
- d.addCallback(lambda _: self._fullClone())
- return d
- else:
- raise buildstep.BuildStepFailed()
- else:
- return res
- d.addCallback(clobber)
- return d
-
- def _doClobber(self):
- """Remove the work directory"""
- cmd = buildstep.RemoteCommand('rmdir', {'dir': self.workdir,
- 'logEnviron': self.logEnviron,
- 'timeout': self.timeout,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def checkRemoval(res):
- if res != 0:
- raise RuntimeError("Failed to delete directory")
- return res
- d.addCallback(lambda _: checkRemoval(cmd.rc))
- return d
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- return changes[-1].revision
-
- def _sourcedirIsUpdatable(self):
- return self.pathExists(self.build.path_module.join(self.workdir, '.git'))
-
- def _updateSubmodule(self, _):
- if self.submodules:
- return self._dovccmd(['submodule', 'update', '--recursive'])
- else:
- return defer.succeed(0)
-
- def _cleanSubmodule(self, _):
- if self.submodules:
- command = ['submodule', 'foreach', 'git', 'clean', '-f', '-d']
- if self.mode == 'full' and self.method == 'fresh':
- command.append('-x')
- return self._dovccmd(command)
- else:
- return defer.succeed(0)
-
- def _getMethod(self):
- if self.method is not None and self.mode != 'incremental':
- return self.method
- elif self.mode == 'incremental':
- return None
- elif self.method is None and self.mode == 'full':
- return 'fresh'
-
- def checkGit(self):
- d = self._dovccmd(['--version'])
- def check(res):
- if res == 0:
- return True
- return False
- d.addCallback(check)
- return d
-
- def patch(self, _, patch):
- d = self._dovccmd(['apply', '--index', '-p', str(patch[0])],
- initialStdin=patch[1])
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/mercurial.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/mercurial.py
deleted file mode 100644
index cbf872b1..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/mercurial.py
+++ /dev/null
@@ -1,338 +0,0 @@
-# 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
-
-## Source step code for mercurial
-
-from twisted.python import log
-from twisted.internet import defer
-
-from buildbot.process import buildstep
-from buildbot.steps.source.base import Source
-from buildbot.interfaces import BuildSlaveTooOldError
-from buildbot.config import ConfigErrors
-from buildbot.status.results import SUCCESS
-
-class Mercurial(Source):
- """ Class for Mercurial with all the smarts """
- name = "hg"
-
- renderables = [ "repourl" ]
- possible_modes = ('incremental', 'full')
- possible_methods = (None, 'clean', 'fresh', 'clobber')
- possible_branchTypes = ('inrepo', 'dirname')
-
- def __init__(self, repourl=None, mode='incremental',
- method=None, defaultBranch=None, branchType='dirname',
- clobberOnBranchChange=True, **kwargs):
-
- """
- @type repourl: string
- @param repourl: the URL which points at the Mercurial repository.
- if 'dirname' branches are enabled, this is the base URL
- to which a branch name will be appended. It should
- probably end in a slash.
-
- @param defaultBranch: if branches are enabled, this is the branch
- to use if the Build does not specify one
- explicitly.
- For 'dirname' branches, It will simply be
- appended to C{repourl} and the result handed to
- the 'hg update' command.
- For 'inrepo' branches, this specifies the named
- revision to which the tree will update after a
- clone.
-
- @param branchType: either 'dirname' or 'inrepo' depending on whether
- the branch name should be appended to the C{repourl}
- or the branch is a mercurial named branch and can be
- found within the C{repourl}
-
- @param clobberOnBranchChange: boolean, defaults to True. If set and
- using inrepos branches, clobber the tree
- at each branch change. Otherwise, just
- update to the branch.
- """
-
- self.repourl = repourl
- self.defaultBranch = self.branch = defaultBranch
- self.branchType = branchType
- self.method = method
- self.clobberOnBranchChange = clobberOnBranchChange
- self.mode = mode
- Source.__init__(self, **kwargs)
-
- errors = []
- if self.mode not in self.possible_modes:
- errors.append("mode %s is not one of %s" %
- (self.mode, self.possible_modes))
- if self.method not in self.possible_methods:
- errors.append("method %s is not one of %s" %
- (self.method, self.possible_methods))
- if self.branchType not in self.possible_branchTypes:
- errors.append("branchType %s is not one of %s" %
- (self.branchType, self.possible_branchTypes))
-
- if repourl is None:
- errors.append("you must provide a repourl")
-
- if errors:
- raise ConfigErrors(errors)
-
- def startVC(self, branch, revision, patch):
- self.revision = revision
- self.method = self._getMethod()
- self.stdio_log = self.addLogForRemoteCommands("stdio")
- d = self.checkHg()
- def checkInstall(hgInstalled):
- if not hgInstalled:
- raise BuildSlaveTooOldError("Mercurial is not installed on slave")
- return 0
- d.addCallback(checkInstall)
-
- if self.branchType == 'dirname':
- self.repourl = self.repourl + (branch or '')
- self.branch = self.defaultBranch
- self.update_branch = branch
- elif self.branchType == 'inrepo':
- self.update_branch = (branch or 'default')
-
- if self.mode == 'full':
- d.addCallback(lambda _: self.full())
- elif self.mode == 'incremental':
- d.addCallback(lambda _: self.incremental())
-
- if patch:
- d.addCallback(self.patch, patch)
-
- d.addCallback(self.parseGotRevision)
- d.addCallback(self.finish)
- d.addErrback(self.failed)
-
- @defer.inlineCallbacks
- def full(self):
- if self.method == 'clobber':
- yield self.clobber(None)
- return
-
- updatable = yield self._sourcedirIsUpdatable()
- if not updatable:
- yield self._dovccmd(['clone', self.repourl, '.'])
- elif self.method == 'clean':
- yield self.clean(None)
- elif self.method == 'fresh':
- yield self.fresh(None)
- else:
- raise ValueError("Unknown method, check your configuration")
-
- def incremental(self):
- if self.method is not None:
- raise ValueError(self.method)
-
- d = self._sourcedirIsUpdatable()
- def _cmd(updatable):
- if updatable:
- command = ['pull', self.repourl]
- else:
- command = ['clone', self.repourl, '.', '--noupdate']
- return command
-
- d.addCallback(_cmd)
- d.addCallback(self._dovccmd)
- d.addCallback(self._checkBranchChange)
- return d
-
- def clean(self, _):
- command = ['--config', 'extensions.purge=', 'purge']
- d = self._dovccmd(command)
- d.addCallback(self._pullUpdate)
- return d
-
- def clobber(self, _):
- cmd = buildstep.RemoteCommand('rmdir', {'dir': self.workdir,
- 'logEnviron':self.logEnviron})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- d.addCallback(lambda _: self._dovccmd(['clone', '--noupdate'
- , self.repourl, "."]))
- d.addCallback(self._update)
- return d
-
- def fresh(self, _):
- command = ['--config', 'extensions.purge=', 'purge', '--all']
- d = self._dovccmd(command)
- d.addCallback(self._pullUpdate)
- return d
-
- def finish(self, res):
- d = defer.succeed(res)
- def _gotResults(results):
- self.setStatus(self.cmd, results)
- return results
- d.addCallback(_gotResults)
- d.addCallbacks(self.finished, self.checkDisconnect)
- return d
-
- def parseGotRevision(self, _):
- d = self._dovccmd(['parents', '--template', '{node}\\n'], collectStdout=True)
- def _setrev(stdout):
- revision = stdout.strip()
- if len(revision) != 40:
- raise ValueError("Incorrect revision id")
- log.msg("Got Mercurial revision %s" % (revision, ))
- self.updateSourceProperty('got_revision', revision)
- return 0
- d.addCallback(_setrev)
- return d
-
- @defer.inlineCallbacks
- def _checkBranchChange(self, _):
- current_branch = yield self._getCurrentBranch()
- msg = "Working dir is on in-repo branch '%s' and build needs '%s'." % \
- (current_branch, self.update_branch)
- if current_branch != self.update_branch and self.clobberOnBranchChange:
- msg += ' Clobbering.'
- log.msg(msg)
- yield self.clobber(None)
- return
- msg += ' Updating.'
- log.msg(msg)
- yield self._removeAddedFilesAndUpdate(None)
-
- def _pullUpdate(self, res):
- command = ['pull' , self.repourl]
- if self.revision:
- command.extend(['--rev', self.revision])
- d = self._dovccmd(command)
- d.addCallback(self._checkBranchChange)
- return d
-
- def _dovccmd(self, command, collectStdout=False, initialStdin=None, decodeRC={0:SUCCESS}):
- if not command:
- raise ValueError("No command specified")
- cmd = buildstep.RemoteShellCommand(self.workdir, ['hg', '--verbose'] + command,
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout,
- collectStdout=collectStdout,
- initialStdin=initialStdin,
- decodeRC=decodeRC)
- cmd.useLog(self.stdio_log, False)
- log.msg("Starting mercurial command : hg %s" % (" ".join(command), ))
- d = self.runCommand(cmd)
- def evaluateCommand(cmd):
- if cmd.didFail():
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- if collectStdout:
- return cmd.stdout
- else:
- return cmd.rc
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- # without knowing the revision ancestry graph, we can't sort the
- # changes at all. So for now, assume they were given to us in sorted
- # order, and just pay attention to the last one. See ticket #103 for
- # more details.
- if len(changes) > 1:
- log.msg("Mercurial.computeSourceRevision: warning: "
- "there are %d changes here, assuming the last one is "
- "the most recent" % len(changes))
- return changes[-1].revision
-
- def patch(self, _, patch):
- d = self._dovccmd(['import', '--no-commit', '-p', str(patch[0]), '-'],
- initialStdin=patch[1])
- return d
-
- def _getCurrentBranch(self):
- if self.branchType == 'dirname':
- return defer.succeed(self.branch)
- else:
- d = self._dovccmd(['identify', '--branch'], collectStdout=True)
- def _getbranch(stdout):
- return stdout.strip()
- d.addCallback(_getbranch).addErrback
- return d
-
- def _getMethod(self):
- if self.method is not None and self.mode != 'incremental':
- return self.method
- elif self.mode == 'incremental':
- return None
- elif self.method is None and self.mode == 'full':
- return 'fresh'
-
- def _sourcedirIsUpdatable(self):
- return self.pathExists(self.build.path_module.join(self.workdir, '.hg'))
-
- def _removeAddedFilesAndUpdate(self, _):
- command = ['locate', 'set:added()']
- d = self._dovccmd(command, collectStdout=True, decodeRC={0:SUCCESS,1:SUCCESS})
- def parseAndRemove(stdout):
- files = []
- for filename in stdout.splitlines() :
- filename = self.workdir+'/'+filename
- files.append(filename)
- if len(files) == 0:
- d = defer.succeed(0)
- else:
- if self.slaveVersionIsOlderThan('rmdir', '2.14'):
- d = self.removeFiles(files)
- else:
- cmd = buildstep.RemoteCommand('rmdir', {'dir': files,
- 'logEnviron':
- self.logEnviron,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- d.addCallback(lambda _: cmd.rc)
- return d
- d.addCallback(parseAndRemove)
- d.addCallback(self._update)
- return d
-
- @defer.inlineCallbacks
- def removeFiles(self, files):
- for filename in files:
- cmd = buildstep.RemoteCommand('rmdir', {'dir': filename,
- 'logEnviron': self.logEnviron,})
- cmd.useLog(self.stdio_log, False)
- yield self.runCommand(cmd)
- if cmd.rc != 0:
- defer.returnValue(cmd.rc)
- return
- defer.returnValue(0)
-
- def _update(self, _):
- command = ['update', '--clean']
- if self.revision:
- command += ['--rev', self.revision]
- elif self.branchType == 'inrepo':
- command += ['--rev', self.update_branch]
- d = self._dovccmd(command)
- return d
-
- def checkHg(self):
- d = self._dovccmd(['--version'])
- def check(res):
- if res == 0:
- return True
- return False
- d.addCallback(check)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/oldsource.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/oldsource.py
deleted file mode 100644
index 4bfe645f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/oldsource.py
+++ /dev/null
@@ -1,1173 +0,0 @@
-# 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
-
-
-from warnings import warn
-from email.Utils import formatdate
-from twisted.python import log
-from twisted.internet import defer
-from zope.interface import implements
-from buildbot.process.buildstep import RemoteCommand
-from buildbot.interfaces import BuildSlaveTooOldError, IRenderable
-from buildbot.steps.source.base import Source
-
-class _ComputeRepositoryURL(object):
- implements(IRenderable)
-
- def __init__(self, step, repository):
- self.step = step
- self.repository = repository
-
- def getRenderingFor(self, props):
- '''
- Helper function that the repository URL based on the parameter the
- source step took and the Change 'repository' property
- '''
-
- build = props.getBuild()
- assert build is not None, "Build should be available *during* a build?"
- s = build.getSourceStamp(self.step.codebase)
-
- repository = self.repository
-
- if not repository:
- return str(s.repository)
- else:
- if callable(repository):
- d = props.render(repository(s.repository))
- elif isinstance(repository, dict):
- d = props.render(repository.get(s.repository))
- elif isinstance(repository, str) or isinstance(repository, unicode):
- try:
- return str(repository % s.repository)
- except TypeError:
- # that's the backward compatibility case
- d = props.render(repository)
- else:
- d = props.render(repository)
-
- d.addCallback(str)
- return d
-
-class SlaveSource(Source):
-
- def __init__(self, mode='update', retry=None, **kwargs):
- """
- @type mode: string
- @param mode: the kind of VC operation that is desired:
- - 'update': specifies that the checkout/update should be
- performed directly into the workdir. Each build is performed
- in the same directory, allowing for incremental builds. This
- minimizes disk space, bandwidth, and CPU time. However, it
- may encounter problems if the build process does not handle
- dependencies properly (if you must sometimes do a 'clean
- build' to make sure everything gets compiled), or if source
- files are deleted but generated files can influence test
- behavior (e.g. python's .pyc files), or when source
- directories are deleted but generated files prevent CVS from
- removing them. When used with a patched checkout, from a
- previous buildbot try for instance, it will try to "revert"
- the changes first and will do a clobber if it is unable to
- get a clean checkout. The behavior is SCM-dependent.
-
- - 'copy': specifies that the source-controlled workspace
- should be maintained in a separate directory (called the
- 'copydir'), using checkout or update as necessary. For each
- build, a new workdir is created with a copy of the source
- tree (rm -rf workdir; cp -R -P -p copydir workdir). This
- doubles the disk space required, but keeps the bandwidth low
- (update instead of a full checkout). A full 'clean' build
- is performed each time. This avoids any generated-file
- build problems, but is still occasionally vulnerable to
- problems such as a CVS repository being manually rearranged
- (causing CVS errors on update) which are not an issue with
- a full checkout.
-
- - 'clobber': specifies that the working directory should be
- deleted each time, necessitating a full checkout for each
- build. This insures a clean build off a complete checkout,
- avoiding any of the problems described above, but is
- bandwidth intensive, as the whole source tree must be
- pulled down for each build.
-
- - 'export': is like 'clobber', except that e.g. the 'cvs
- export' command is used to create the working directory.
- This command removes all VC metadata files (the
- CVS/.svn/{arch} directories) from the tree, which is
- sometimes useful for creating source tarballs (to avoid
- including the metadata in the tar file). Not all VC systems
- support export.
-
- @type retry: tuple of ints (delay, repeats) (or None)
- @param retry: if provided, VC update failures are re-attempted up
- to REPEATS times, with DELAY seconds between each
- attempt. Some users have slaves with poor connectivity
- to their VC repository, and they say that up to 80% of
- their build failures are due to transient network
- failures that could be handled by simply retrying a
- couple times.
- """
- Source.__init__(self, **kwargs)
-
- assert mode in ("update", "copy", "clobber", "export")
- if retry:
- delay, repeats = retry
- assert isinstance(repeats, int)
- assert repeats > 0
- self.args = {'mode': mode,
- 'retry': retry,
- }
-
- def start(self):
- self.args['workdir'] = self.workdir
- self.args['logEnviron'] = self.logEnviron
- self.args['env'] = self.env
- self.args['timeout'] = self.timeout
- Source.start(self)
-
- def commandComplete(self, cmd):
- if not cmd.updates.has_key("got_revision"):
- return
- got_revision = cmd.updates["got_revision"][-1]
- if got_revision is None:
- return
-
- self.updateSourceProperty('got_revision', str(got_revision))
-
-
-class BK(SlaveSource):
- """I perform BitKeeper checkout/update operations."""
-
- name = 'bk'
-
- renderables = [ 'bkurl', 'baseURL' ]
-
- def __init__(self, bkurl=None, baseURL=None,
- directory=None, extra_args=None, **kwargs):
- """
- @type bkurl: string
- @param bkurl: the URL which points to the BitKeeper server.
-
- @type baseURL: string
- @param baseURL: if branches are enabled, this is the base URL to
- which a branch name will be appended. It should
- probably end in a slash. Use exactly one of
- C{bkurl} and C{baseURL}.
- """
-
- self.bkurl = _ComputeRepositoryURL(bkurl)
- self.baseURL = _ComputeRepositoryURL(baseURL)
- self.extra_args = extra_args
-
- Source.__init__(self, **kwargs)
-
- if bkurl and baseURL:
- raise ValueError("you must use exactly one of bkurl and baseURL")
-
-
- def computeSourceRevision(self, changes):
- return changes.revision
-
-
- def startVC(self, branch, revision, patch):
-
- warnings = []
- slavever = self.slaveVersion("bk")
- if not slavever:
- m = "slave does not have the 'bk' command"
- raise BuildSlaveTooOldError(m)
-
- if self.bkurl:
- assert not branch # we need baseURL= to use branches
- self.args['bkurl'] = self.bkurl
- else:
- self.args['bkurl'] = self.baseURL + branch
- self.args['revision'] = revision
- self.args['patch'] = patch
- self.args['branch'] = branch
- if self.extra_args is not None:
- self.args['extra_args'] = self.extra_args
-
- revstuff = []
- revstuff.append("[branch]")
- if revision is not None:
- revstuff.append("r%s" % revision)
- if patch is not None:
- revstuff.append("[patch]")
- self.description.extend(revstuff)
- self.descriptionDone.extend(revstuff)
-
- cmd = RemoteCommand("bk", self.args)
- self.startCommand(cmd, warnings)
-
-
-
-class CVS(SlaveSource):
- """I do CVS checkout/update operations.
-
- Note: if you are doing anonymous/pserver CVS operations, you will need
- to manually do a 'cvs login' on each buildslave before the slave has any
- hope of success. XXX: fix then, take a cvs password as an argument and
- figure out how to do a 'cvs login' on each build
- """
-
- name = "cvs"
-
- renderables = [ "cvsroot" ]
-
- #progressMetrics = ('output',)
- #
- # additional things to track: update gives one stderr line per directory
- # (starting with 'cvs server: Updating ') (and is fairly stable if files
- # is empty), export gives one line per directory (starting with 'cvs
- # export: Updating ') and another line per file (starting with U). Would
- # be nice to track these, requires grepping LogFile data for lines,
- # parsing each line. Might be handy to have a hook in LogFile that gets
- # called with each complete line.
-
- def __init__(self, cvsroot=None, cvsmodule="",
- global_options=[], branch=None, checkoutDelay=None,
- checkout_options=[], export_options=[], extra_options=[],
- login=None,
- **kwargs):
-
- """
- @type cvsroot: string
- @param cvsroot: CVS Repository from which the source tree should
- be obtained. '/home/warner/Repository' for local
- or NFS-reachable repositories,
- ':pserver:anon@foo.com:/cvs' for anonymous CVS,
- 'user@host.com:/cvs' for non-anonymous CVS or
- CVS over ssh. Lots of possibilities, check the
- CVS documentation for more.
-
- @type cvsmodule: string
- @param cvsmodule: subdirectory of CVS repository that should be
- retrieved
-
- @type login: string or None
- @param login: if not None, a string which will be provided as a
- password to the 'cvs login' command, used when a
- :pserver: method is used to access the repository.
- This login is only needed once, but must be run
- each time (just before the CVS operation) because
- there is no way for the buildslave to tell whether
- it was previously performed or not.
-
- @type branch: string
- @param branch: the default branch name, will be used in a '-r'
- argument to specify which branch of the source tree
- should be used for this checkout. Defaults to None,
- which means to use 'HEAD'.
-
- @type checkoutDelay: int or None
- @param checkoutDelay: if not None, the number of seconds to put
- between the last known Change and the
- timestamp given to the -D argument. This
- defaults to exactly half of the parent
- Build's .treeStableTimer, but it could be
- set to something else if your CVS change
- notification has particularly weird
- latency characteristics.
-
- @type global_options: list of strings
- @param global_options: these arguments are inserted in the cvs
- command line, before the
- 'checkout'/'update' command word. See
- 'cvs --help-options' for a list of what
- may be accepted here. ['-r'] will make
- the checked out files read only. ['-r',
- '-R'] will also assume the repository is
- read-only (I assume this means it won't
- use locks to insure atomic access to the
- ,v files).
-
- @type checkout_options: list of strings
- @param checkout_options: these arguments are inserted in the cvs
- command line, after 'checkout' but before
- branch or revision specifiers.
-
- @type export_options: list of strings
- @param export_options: these arguments are inserted in the cvs
- command line, after 'export' but before
- branch or revision specifiers.
-
- @type extra_options: list of strings
- @param extra_options: these arguments are inserted in the cvs
- command line, after 'checkout' or 'export' but before
- branch or revision specifiers.
- """
-
- self.checkoutDelay = checkoutDelay
- self.branch = branch
- self.cvsroot = _ComputeRepositoryURL(self, cvsroot)
-
- SlaveSource.__init__(self, **kwargs)
-
- self.args.update({'cvsmodule': cvsmodule,
- 'global_options': global_options,
- 'checkout_options':checkout_options,
- 'export_options':export_options,
- 'extra_options':extra_options,
- 'login': login,
- })
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- lastChange = max([c.when for c in changes])
- if self.checkoutDelay is not None:
- when = lastChange + self.checkoutDelay
- else:
- lastSubmit = max([br.submittedAt for br in self.build.requests])
- when = (lastChange + lastSubmit) / 2
- return formatdate(when)
-
- def startVC(self, branch, revision, patch):
- if self.slaveVersionIsOlderThan("cvs", "1.39"):
- # the slave doesn't know to avoid re-using the same sourcedir
- # when the branch changes. We have no way of knowing which branch
- # the last build used, so if we're using a non-default branch and
- # either 'update' or 'copy' modes, it is safer to refuse to
- # build, and tell the user they need to upgrade the buildslave.
- if (branch != self.branch
- and self.args['mode'] in ("update", "copy")):
- m = ("This buildslave (%s) does not know about multiple "
- "branches, and using mode=%s would probably build the "
- "wrong tree. "
- "Refusing to build. Please upgrade the buildslave to "
- "buildbot-0.7.0 or newer." % (self.build.slavename,
- self.args['mode']))
- log.msg(m)
- raise BuildSlaveTooOldError(m)
-
- if self.slaveVersionIsOlderThan("cvs", "2.10"):
- if self.args['extra_options'] or self.args['export_options']:
- m = ("This buildslave (%s) does not support export_options "
- "or extra_options arguments to the CVS step."
- % (self.build.slavename))
- log.msg(m)
- raise BuildSlaveTooOldError(m)
- # the unwanted args are empty, and will probably be ignored by
- # the slave, but delete them just to be safe
- del self.args['export_options']
- del self.args['extra_options']
-
- if branch is None:
- branch = "HEAD"
- self.args['cvsroot'] = self.cvsroot
- self.args['branch'] = branch
- self.args['revision'] = revision
- self.args['patch'] = patch
-
- if self.args['branch'] == "HEAD" and self.args['revision']:
- # special case. 'cvs update -r HEAD -D today' gives no files
- # TODO: figure out why, see if it applies to -r BRANCH
- self.args['branch'] = None
-
- # deal with old slaves
- warnings = []
- slavever = self.slaveVersion("cvs", "old")
-
- if slavever == "old":
- # 0.5.0
- if self.args['mode'] == "export":
- self.args['export'] = 1
- elif self.args['mode'] == "clobber":
- self.args['clobber'] = 1
- elif self.args['mode'] == "copy":
- self.args['copydir'] = "source"
- self.args['tag'] = self.args['branch']
- assert not self.args['patch'] # 0.5.0 slave can't do patch
-
- cmd = RemoteCommand("cvs", self.args)
- self.startCommand(cmd, warnings)
-
-
-class SVN(SlaveSource):
- """I perform Subversion checkout/update operations."""
-
- name = 'svn'
- branch_placeholder = '%%BRANCH%%'
-
- renderables = [ 'svnurl', 'baseURL' ]
-
- def __init__(self, svnurl=None, baseURL=None, defaultBranch=None,
- directory=None, username=None, password=None,
- extra_args=None, keep_on_purge=None, ignore_ignores=None,
- always_purge=None, depth=None, **kwargs):
- """
- @type svnurl: string
- @param svnurl: the URL which points to the Subversion server,
- combining the access method (HTTP, ssh, local file),
- the repository host/port, the repository path, the
- sub-tree within the repository, and the branch to
- check out. Use exactly one of C{svnurl} and C{baseURL}.
-
- @param baseURL: if branches are enabled, this is the base URL to
- which a branch name will be appended. It should
- probably end in a slash. Use exactly one of
- C{svnurl} and C{baseURL}.
-
- @param defaultBranch: if branches are enabled, this is the branch
- to use if the Build does not specify one
- explicitly. It will simply be appended
- to C{baseURL} and the result handed to
- the SVN command.
-
- @type username: string
- @param username: username to pass to svn's --username
-
- @type password: string
- @param password: password to pass to svn's --password
- """
-
- if not 'workdir' in kwargs and directory is not None:
- # deal with old configs
- warn("Please use workdir=, not directory=", DeprecationWarning)
- kwargs['workdir'] = directory
-
- self.svnurl = svnurl and _ComputeRepositoryURL(self, svnurl)
- self.baseURL = _ComputeRepositoryURL(self, baseURL)
- self.branch = defaultBranch
- self.username = username
- self.password = password
- self.extra_args = extra_args
- self.keep_on_purge = keep_on_purge
- self.ignore_ignores = ignore_ignores
- self.always_purge = always_purge
- self.depth = depth
-
- SlaveSource.__init__(self, **kwargs)
-
- if svnurl and baseURL:
- raise ValueError("you must use either svnurl OR baseURL")
-
- def computeSourceRevision(self, changes):
- if not changes or None in [c.revision for c in changes]:
- return None
- lastChange = max([int(c.revision) for c in changes])
- return lastChange
-
- def checkCompatibility(self):
- ''' Handle compatibility between old slaves/svn clients '''
-
- slavever = self.slaveVersion("svn", "old")
-
- if not slavever:
- m = "slave does not have the 'svn' command"
- raise BuildSlaveTooOldError(m)
-
- if self.slaveVersionIsOlderThan("svn", "1.39"):
- # the slave doesn't know to avoid re-using the same sourcedir
- # when the branch changes. We have no way of knowing which branch
- # the last build used, so if we're using a non-default branch and
- # either 'update' or 'copy' modes, it is safer to refuse to
- # build, and tell the user they need to upgrade the buildslave.
- if (self.args['branch'] != self.branch
- and self.args['mode'] in ("update", "copy")):
- m = ("This buildslave (%s) does not know about multiple "
- "branches, and using mode=%s would probably build the "
- "wrong tree. "
- "Refusing to build. Please upgrade the buildslave to "
- "buildbot-0.7.0 or newer." % (self.build.slavename,
- self.args['mode']))
- raise BuildSlaveTooOldError(m)
-
- if (self.depth is not None) and self.slaveVersionIsOlderThan("svn","2.9"):
- m = ("This buildslave (%s) does not support svn depth "
- "arguments. Refusing to build. "
- "Please upgrade the buildslave." % (self.build.slavename))
- raise BuildSlaveTooOldError(m)
-
- if (self.username is not None or self.password is not None) \
- and self.slaveVersionIsOlderThan("svn", "2.8"):
- m = ("This buildslave (%s) does not support svn usernames "
- "and passwords. "
- "Refusing to build. Please upgrade the buildslave to "
- "buildbot-0.7.10 or newer." % (self.build.slavename,))
- raise BuildSlaveTooOldError(m)
-
- def getSvnUrl(self, branch):
- ''' Compute the svn url that will be passed to the svn remote command '''
- if self.svnurl:
- return self.svnurl
- else:
- if branch is None:
- m = ("The SVN source step belonging to builder '%s' does not know "
- "which branch to work with. This means that the change source "
- "did not specify a branch and that defaultBranch is None." \
- % self.build.builder.name)
- raise RuntimeError(m)
-
- computed = self.baseURL
-
- if self.branch_placeholder in self.baseURL:
- return computed.replace(self.branch_placeholder, branch)
- else:
- return computed + branch
-
- def startVC(self, branch, revision, patch):
- warnings = []
-
- self.checkCompatibility()
-
- self.args['svnurl'] = self.getSvnUrl(branch)
- self.args['revision'] = revision
- self.args['patch'] = patch
- self.args['always_purge'] = self.always_purge
-
- #Set up depth if specified
- if self.depth is not None:
- self.args['depth'] = self.depth
-
- if self.username is not None:
- self.args['username'] = self.username
- if self.password is not None:
- self.args['password'] = self.password
-
- if self.extra_args is not None:
- self.args['extra_args'] = self.extra_args
-
- revstuff = []
- #revstuff.append(self.args['svnurl'])
- if self.args['svnurl'].find('trunk') == -1:
- revstuff.append("[branch]")
- if revision is not None:
- revstuff.append("r%s" % revision)
- if patch is not None:
- revstuff.append("[patch]")
- self.description.extend(revstuff)
- self.descriptionDone.extend(revstuff)
-
- cmd = RemoteCommand("svn", self.args)
- self.startCommand(cmd, warnings)
-
-
-class Darcs(SlaveSource):
- """Check out a source tree from a Darcs repository at 'repourl'.
-
- Darcs has no concept of file modes. This means the eXecute-bit will be
- cleared on all source files. As a result, you may need to invoke
- configuration scripts with something like:
-
- C{s(step.Configure, command=['/bin/sh', './configure'])}
- """
-
- name = "darcs"
-
- renderables = [ 'repourl', 'baseURL' ]
-
- def __init__(self, repourl=None, baseURL=None, defaultBranch=None,
- **kwargs):
- """
- @type repourl: string
- @param repourl: the URL which points at the Darcs repository. This
- is used as the default branch. Using C{repourl} does
- not enable builds of alternate branches: use
- C{baseURL} to enable this. Use either C{repourl} or
- C{baseURL}, not both.
-
- @param baseURL: if branches are enabled, this is the base URL to
- which a branch name will be appended. It should
- probably end in a slash. Use exactly one of
- C{repourl} and C{baseURL}.
-
- @param defaultBranch: if branches are enabled, this is the branch
- to use if the Build does not specify one
- explicitly. It will simply be appended to
- C{baseURL} and the result handed to the
- 'darcs pull' command.
- """
- self.repourl = _ComputeRepositoryURL(self, repourl)
- self.baseURL = _ComputeRepositoryURL(self, baseURL)
- self.branch = defaultBranch
- SlaveSource.__init__(self, **kwargs)
- assert self.args['mode'] != "export", \
- "Darcs does not have an 'export' mode"
- if repourl and baseURL:
- raise ValueError("you must provide exactly one of repourl and"
- " baseURL")
-
- def startVC(self, branch, revision, patch):
- slavever = self.slaveVersion("darcs")
- if not slavever:
- m = "slave is too old, does not know about darcs"
- raise BuildSlaveTooOldError(m)
-
- if self.slaveVersionIsOlderThan("darcs", "1.39"):
- if revision:
- # TODO: revisit this once we implement computeSourceRevision
- m = "0.6.6 slaves can't handle args['revision']"
- raise BuildSlaveTooOldError(m)
-
- # the slave doesn't know to avoid re-using the same sourcedir
- # when the branch changes. We have no way of knowing which branch
- # the last build used, so if we're using a non-default branch and
- # either 'update' or 'copy' modes, it is safer to refuse to
- # build, and tell the user they need to upgrade the buildslave.
- if (branch != self.branch
- and self.args['mode'] in ("update", "copy")):
- m = ("This buildslave (%s) does not know about multiple "
- "branches, and using mode=%s would probably build the "
- "wrong tree. "
- "Refusing to build. Please upgrade the buildslave to "
- "buildbot-0.7.0 or newer." % (self.build.slavename,
- self.args['mode']))
- raise BuildSlaveTooOldError(m)
-
- if self.repourl:
- assert not branch # we need baseURL= to use branches
- self.args['repourl'] = self.repourl
- else:
- self.args['repourl'] = self.baseURL + branch
- self.args['revision'] = revision
- self.args['patch'] = patch
-
- revstuff = []
- if branch is not None and branch != self.branch:
- revstuff.append("[branch]")
- self.description.extend(revstuff)
- self.descriptionDone.extend(revstuff)
-
- cmd = RemoteCommand("darcs", self.args)
- self.startCommand(cmd)
-
-
-class Git(SlaveSource):
- """Check out a source tree from a git repository 'repourl'."""
-
- name = "git"
-
- renderables = [ 'repourl' ]
-
- def __init__(self, repourl=None,
- branch="master",
- submodules=False,
- ignore_ignores=None,
- reference=None,
- shallow=False,
- progress=False,
- **kwargs):
- """
- @type repourl: string
- @param repourl: the URL which points at the git repository
-
- @type branch: string
- @param branch: The branch or tag to check out by default. If
- a build specifies a different branch, it will
- be used instead of this.
-
- @type submodules: boolean
- @param submodules: Whether or not to update (and initialize)
- git submodules.
-
- @type reference: string
- @param reference: The path to a reference repository to obtain
- objects from, if any.
-
- @type shallow: boolean
- @param shallow: Use a shallow or clone, if possible
-
- @type progress: boolean
- @param progress: Pass the --progress option when fetching. This
- can solve long fetches getting killed due to
- lack of output, but requires Git 1.7.2+.
- """
- SlaveSource.__init__(self, **kwargs)
- self.repourl = _ComputeRepositoryURL(self, repourl)
- self.branch = branch
- self.args.update({'submodules': submodules,
- 'ignore_ignores': ignore_ignores,
- 'reference': reference,
- 'shallow': shallow,
- 'progress': progress,
- })
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- return changes[-1].revision
-
- def startVC(self, branch, revision, patch):
- self.args['branch'] = branch
- self.args['repourl'] = self.repourl
- self.args['revision'] = revision
- self.args['patch'] = patch
-
- # check if there is any patchset we should fetch from Gerrit
- if self.build.hasProperty("event.patchSet.ref"):
- # GerritChangeSource
- self.args['gerrit_branch'] = self.build.getProperty("event.patchSet.ref")
- self.updateSourceProperty("gerrit_branch",
- self.args['gerrit_branch'])
- else:
- try:
- # forced build
- change = self.build.getProperty("gerrit_change", '').split('/')
- if len(change) == 2:
- self.args['gerrit_branch'] = "refs/changes/%2.2d/%d/%d" \
- % (int(change[0]) % 100, int(change[0]), int(change[1]))
- self.updateSourceProperty("gerrit_branch",
- self.args['gerrit_branch'])
- except:
- pass
-
- slavever = self.slaveVersion("git")
- if not slavever:
- raise BuildSlaveTooOldError("slave is too old, does not know "
- "about git")
- cmd = RemoteCommand("git", self.args)
- self.startCommand(cmd)
-
-
-class Repo(SlaveSource):
- """Check out a source tree from a repo repository described by manifest."""
-
- name = "repo"
-
- renderables = [ "manifest_url" ]
-
- def __init__(self,
- manifest_url=None,
- manifest_branch="master",
- manifest_file="default.xml",
- tarball=None,
- jobs=None,
- **kwargs):
- """
- @type manifest_url: string
- @param manifest_url: The URL which points at the repo manifests repository.
-
- @type manifest_branch: string
- @param manifest_branch: The manifest branch to check out by default.
-
- @type manifest_file: string
- @param manifest_file: The manifest to use for sync.
-
- """
- SlaveSource.__init__(self, **kwargs)
- self.manifest_url = _ComputeRepositoryURL(self, manifest_url)
- self.args.update({'manifest_branch': manifest_branch,
- 'manifest_file': manifest_file,
- 'tarball': tarball,
- 'manifest_override_url': None,
- 'jobs': jobs
- })
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- return changes[-1].revision
-
- def parseDownloadProperty(self, s):
- """
- lets try to be nice in the format we want
- can support several instances of "repo download proj number/patch" (direct copy paste from gerrit web site)
- or several instances of "proj number/patch" (simpler version)
- This feature allows integrator to build with several pending interdependant changes.
- returns list of repo downloads sent to the buildslave
- """
- import re
- if s == None:
- return []
- re1 = re.compile("repo download ([^ ]+) ([0-9]+/[0-9]+)")
- re2 = re.compile("([^ ]+) ([0-9]+/[0-9]+)")
- re3 = re.compile("([^ ]+)/([0-9]+/[0-9]+)")
- ret = []
- for cur_re in [re1, re2, re3]:
- res = cur_re.search(s)
- while res:
- ret.append("%s %s" % (res.group(1), res.group(2)))
- s = s[:res.start(0)] + s[res.end(0):]
- res = cur_re.search(s)
- return ret
-
- def buildDownloadList(self):
- """taken the changesource and forcebuild property,
- build the repo download command to send to the slave
- making this a defereable allow config to tweak this
- in order to e.g. manage dependancies
- """
- downloads = self.build.getProperty("repo_downloads", [])
-
- # download patches based on GerritChangeSource events
- for change in self.build.allChanges():
- if (change.properties.has_key("event.type") and
- change.properties["event.type"] == "patchset-created"):
- downloads.append("%s %s/%s"% (change.properties["event.change.project"],
- change.properties["event.change.number"],
- change.properties["event.patchSet.number"]))
-
- # download patches based on web site forced build properties:
- # "repo_d", "repo_d0", .., "repo_d9"
- # "repo_download", "repo_download0", .., "repo_download9"
- for propName in ["repo_d"] + ["repo_d%d" % i for i in xrange(0,10)] + \
- ["repo_download"] + ["repo_download%d" % i for i in xrange(0,10)]:
- s = self.build.getProperty(propName)
- if s is not None:
- downloads.extend(self.parseDownloadProperty(s))
-
- if downloads:
- self.args["repo_downloads"] = downloads
- self.updateSourceProperty("repo_downloads", downloads)
- return defer.succeed(None)
-
- def startVC(self, branch, revision, patch):
- self.args['manifest_url'] = self.manifest_url
-
- # manifest override
- self.args['manifest_override_url'] = None
- try:
- self.args['manifest_override_url'] = self.build.getProperty("manifest_override_url")
- except KeyError:
- pass
- # only master has access to properties, so we must implement this here.
- d = self.buildDownloadList()
- d.addCallback(self.continueStartVC, branch, revision, patch)
- d.addErrback(self.failed)
-
- def continueStartVC(self, ignored, branch, revision, patch):
- slavever = self.slaveVersion("repo")
- if not slavever:
- raise BuildSlaveTooOldError("slave is too old, does not know "
- "about repo")
- cmd = RemoteCommand("repo", self.args)
- self.startCommand(cmd)
-
- def commandComplete(self, cmd):
- repo_downloaded = []
- if cmd.updates.has_key("repo_downloaded"):
- repo_downloaded = cmd.updates["repo_downloaded"][-1]
- if repo_downloaded:
- self.updateSourceProperty("repo_downloaded",
- str(repo_downloaded))
- else:
- repo_downloaded = []
- orig_downloads = self.getProperty("repo_downloads") or []
- if len(orig_downloads) != len(repo_downloaded):
- self.step_status.setText(["repo download issues"])
-
-
-class Bzr(SlaveSource):
- """Check out a source tree from a bzr (Bazaar) repository at 'repourl'.
-
- """
-
- name = "bzr"
-
- renderables = [ 'repourl', 'baseURL' ]
-
- def __init__(self, repourl=None, baseURL=None, defaultBranch=None,
- forceSharedRepo=None,
- **kwargs):
- """
- @type repourl: string
- @param repourl: the URL which points at the bzr repository. This
- is used as the default branch. Using C{repourl} does
- not enable builds of alternate branches: use
- C{baseURL} to enable this. Use either C{repourl} or
- C{baseURL}, not both.
-
- @param baseURL: if branches are enabled, this is the base URL to
- which a branch name will be appended. It should
- probably end in a slash. Use exactly one of
- C{repourl} and C{baseURL}.
-
- @param defaultBranch: if branches are enabled, this is the branch
- to use if the Build does not specify one
- explicitly. It will simply be appended to
- C{baseURL} and the result handed to the
- 'bzr checkout pull' command.
-
-
- @param forceSharedRepo: Boolean, defaults to False. If set to True,
- the working directory will be made into a
- bzr shared repository if it is not already.
- Shared repository greatly reduces the amount
- of history data that needs to be downloaded
- if not using update/copy mode, or if using
- update/copy mode with multiple branches.
- """
- self.repourl = _ComputeRepositoryURL(self, repourl)
- self.baseURL = _ComputeRepositoryURL(self, baseURL)
- self.branch = defaultBranch
- SlaveSource.__init__(self, **kwargs)
- self.args.update({'forceSharedRepo': forceSharedRepo})
- if repourl and baseURL:
- raise ValueError("you must provide exactly one of repourl and"
- " baseURL")
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- lastChange = max([int(c.revision) for c in changes])
- return lastChange
-
- def startVC(self, branch, revision, patch):
- slavever = self.slaveVersion("bzr")
- if not slavever:
- m = "slave is too old, does not know about bzr"
- raise BuildSlaveTooOldError(m)
-
- if self.repourl:
- assert not branch # we need baseURL= to use branches
- self.args['repourl'] = self.repourl
- else:
- self.args['repourl'] = self.baseURL + branch
- self.args['revision'] = revision
- self.args['patch'] = patch
-
- revstuff = []
- if branch is not None and branch != self.branch:
- revstuff.append("[" + branch + "]")
- if revision is not None:
- revstuff.append("r%s" % revision)
- self.description.extend(revstuff)
- self.descriptionDone.extend(revstuff)
-
- cmd = RemoteCommand("bzr", self.args)
- self.startCommand(cmd)
-
-
-class Mercurial(SlaveSource):
- """Check out a source tree from a mercurial repository 'repourl'."""
-
- name = "hg"
-
- renderables = [ 'repourl', 'baseURL' ]
-
- def __init__(self, repourl=None, baseURL=None, defaultBranch=None,
- branchType='dirname', clobberOnBranchChange=True, **kwargs):
- """
- @type repourl: string
- @param repourl: the URL which points at the Mercurial repository.
- This uses the 'default' branch unless defaultBranch is
- specified below and the C{branchType} is set to
- 'inrepo'. It is an error to specify a branch without
- setting the C{branchType} to 'inrepo'.
-
- @param baseURL: if 'dirname' branches are enabled, this is the base URL
- to which a branch name will be appended. It should
- probably end in a slash. Use exactly one of C{repourl}
- and C{baseURL}.
-
- @param defaultBranch: if branches are enabled, this is the branch
- to use if the Build does not specify one
- explicitly.
- For 'dirname' branches, It will simply be
- appended to C{baseURL} and the result handed to
- the 'hg update' command.
- For 'inrepo' branches, this specifies the named
- revision to which the tree will update after a
- clone.
-
- @param branchType: either 'dirname' or 'inrepo' depending on whether
- the branch name should be appended to the C{baseURL}
- or the branch is a mercurial named branch and can be
- found within the C{repourl}
-
- @param clobberOnBranchChange: boolean, defaults to True. If set and
- using inrepos branches, clobber the tree
- at each branch change. Otherwise, just
- update to the branch.
- """
- self.repourl = _ComputeRepositoryURL(self, repourl)
- self.baseURL = _ComputeRepositoryURL(self, baseURL)
- self.branch = defaultBranch
- self.branchType = branchType
- self.clobberOnBranchChange = clobberOnBranchChange
- SlaveSource.__init__(self, **kwargs)
- if repourl and baseURL:
- raise ValueError("you must provide exactly one of repourl and"
- " baseURL")
-
- def startVC(self, branch, revision, patch):
- slavever = self.slaveVersion("hg")
- if not slavever:
- raise BuildSlaveTooOldError("slave is too old, does not know "
- "about hg")
-
- if self.repourl:
- # we need baseURL= to use dirname branches
- assert self.branchType == 'inrepo' or not branch
- self.args['repourl'] = self.repourl
- if branch:
- self.args['branch'] = branch
- else:
- self.args['repourl'] = self.baseURL + (branch or '')
- self.args['revision'] = revision
- self.args['patch'] = patch
- self.args['clobberOnBranchChange'] = self.clobberOnBranchChange
- self.args['branchType'] = self.branchType
-
- revstuff = []
- if branch is not None and branch != self.branch:
- revstuff.append("[branch]")
- self.description.extend(revstuff)
- self.descriptionDone.extend(revstuff)
-
- cmd = RemoteCommand("hg", self.args)
- self.startCommand(cmd)
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- # without knowing the revision ancestry graph, we can't sort the
- # changes at all. So for now, assume they were given to us in sorted
- # order, and just pay attention to the last one. See ticket #103 for
- # more details.
- if len(changes) > 1:
- log.msg("Mercurial.computeSourceRevision: warning: "
- "there are %d changes here, assuming the last one is "
- "the most recent" % len(changes))
- return changes[-1].revision
-
-
-class P4(SlaveSource):
- """ P4 is a class for accessing perforce revision control"""
- name = "p4"
-
- renderables = [ 'p4base' ]
-
- def __init__(self, p4base=None, defaultBranch=None, p4port=None, p4user=None,
- p4passwd=None, p4extra_views=[], p4line_end='local',
- p4client='buildbot_%(slave)s_%(builder)s', **kwargs):
- """
- @type p4base: string
- @param p4base: A view into a perforce depot, typically
- "//depot/proj/"
-
- @type defaultBranch: string
- @param defaultBranch: Identify a branch to build by default. Perforce
- is a view based branching system. So, the branch
- is normally the name after the base. For example,
- branch=1.0 is view=//depot/proj/1.0/...
- branch=1.1 is view=//depot/proj/1.1/...
-
- @type p4port: string
- @param p4port: Specify the perforce server to connection in the format
- <host>:<port>. Example "perforce.example.com:1666"
-
- @type p4user: string
- @param p4user: The perforce user to run the command as.
-
- @type p4passwd: string
- @param p4passwd: The password for the perforce user.
-
- @type p4extra_views: list of tuples
- @param p4extra_views: Extra views to be added to
- the client that is being used.
-
- @type p4line_end: string
- @param p4line_end: value of the LineEnd client specification property
-
- @type p4client: string
- @param p4client: The perforce client to use for this buildslave.
- """
-
- self.p4base = _ComputeRepositoryURL(self, p4base)
- self.branch = defaultBranch
- SlaveSource.__init__(self, **kwargs)
- self.args['p4port'] = p4port
- self.args['p4user'] = p4user
- self.args['p4passwd'] = p4passwd
- self.args['p4extra_views'] = p4extra_views
- self.args['p4line_end'] = p4line_end
- self.p4client = p4client
-
- def setBuild(self, build):
- SlaveSource.setBuild(self, build)
- self.args['p4client'] = self.p4client % {
- 'slave': build.slavename,
- 'builder': build.builder.name,
- }
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- lastChange = max([int(c.revision) for c in changes])
- return lastChange
-
- def startVC(self, branch, revision, patch):
- slavever = self.slaveVersion("p4")
- assert slavever, "slave is too old, does not know about p4"
- args = dict(self.args)
- args['p4base'] = self.p4base
- args['branch'] = branch or self.branch
- args['revision'] = revision
- args['patch'] = patch
- cmd = RemoteCommand("p4", args)
- self.startCommand(cmd)
-
-class Monotone(SlaveSource):
- """Check out a source tree from a monotone repository 'repourl'."""
-
- name = "mtn"
-
- renderables = [ 'repourl' ]
-
- def __init__(self, repourl=None, branch=None, progress=False, **kwargs):
- """
- @type repourl: string
- @param repourl: the URI which points at the monotone repository.
-
- @type branch: string
- @param branch: The branch or tag to check out by default. If
- a build specifies a different branch, it will
- be used instead of this.
-
- @type progress: boolean
- @param progress: Pass the --ticker=dot option when pulling. This
- can solve long fetches getting killed due to
- lack of output.
- """
- SlaveSource.__init__(self, **kwargs)
- self.repourl = _ComputeRepositoryURL(self, repourl)
- if (not repourl):
- raise ValueError("you must provide a repository uri in 'repourl'")
- if (not branch):
- raise ValueError("you must provide a default branch in 'branch'")
- self.args.update({'branch': branch,
- 'progress': progress,
- })
-
- def startVC(self, branch, revision, patch):
- slavever = self.slaveVersion("mtn")
- if not slavever:
- raise BuildSlaveTooOldError("slave is too old, does not know "
- "about mtn")
-
- self.args['repourl'] = self.repourl
- if branch:
- self.args['branch'] = branch
- self.args['revision'] = revision
- self.args['patch'] = patch
-
- cmd = RemoteCommand("mtn", self.args)
- self.startCommand(cmd)
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- # without knowing the revision ancestry graph, we can't sort the
- # changes at all. So for now, assume they were given to us in sorted
- # order, and just pay attention to the last one. See ticket #103 for
- # more details.
- if len(changes) > 1:
- log.msg("Monotone.computeSourceRevision: warning: "
- "there are %d changes here, assuming the last one is "
- "the most recent" % len(changes))
- return changes[-1].revision
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/p4.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/p4.py
deleted file mode 100644
index b6d47daf..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/p4.py
+++ /dev/null
@@ -1,354 +0,0 @@
-# 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
-# Portions Copyright 2013 Bad Dog Consulting
-
-import re
-import os
-
-from twisted.python import log
-from twisted.internet import defer
-from buildbot import interfaces, config
-from buildbot.process import buildstep
-from buildbot.steps.source import Source
-from buildbot.interfaces import BuildSlaveTooOldError
-from buildbot.process.properties import Interpolate
-from types import StringType
-
-
-# Notes:
-# see
-# http://perforce.com/perforce/doc.current/manuals/cmdref/o.gopts.html#1040647
-# for getting p4 command to output marshalled python dictionaries as output
-# for commands.
-# Perhaps switch to using 'p4 -G' : From URL above:
-# -G Causes all output (and batch input for form commands with -i) to be
-# formatted as marshalled Python dictionary objects. This is most often used
-# when scripting.
-
-debug_logging = False
-
-
-class P4(Source):
- """Perform Perforce checkout/update operations."""
-
- name = 'p4'
-
- renderables = ['p4base', 'p4client', 'p4viewspec', 'p4branch']
- possible_modes = ('incremental', 'full')
-
- def __init__(self, mode='incremental',
- method=None, p4base=None, p4branch=None,
- p4port=None, p4user=None,
- p4passwd=None, p4extra_views=(), p4line_end='local',
- p4viewspec=None,
- p4client=Interpolate('buildbot_%(prop:slavename)s_%(prop:buildername)s'),
- p4bin='p4',
- **kwargs):
- self.method = method
- self.mode = mode
- self.p4branch = p4branch
- self.p4bin = p4bin
- self.p4base = p4base
- self.p4port = p4port
- self.p4user = p4user
- self.p4passwd = p4passwd
- self.p4extra_views = p4extra_views
- self.p4viewspec = p4viewspec
- self.p4line_end = p4line_end
- self.p4client = p4client
-
- Source.__init__(self, **kwargs)
-
- if self.mode not in self.possible_modes:
- config.error("mode %s is not one of %s" % (self.mode, self.possible_modes))
-
- if not p4viewspec and p4base is None:
- config.error("You must provide p4base or p4viewspec")
-
- if p4viewspec and (p4base or p4branch or p4extra_views):
- config.error("Either provide p4viewspec or p4base and p4branch (and optionally p4extra_views")
-
- if p4viewspec and type(p4viewspec) is StringType:
- config.error("p4viewspec must not be a string, and should be a sequence of 2 element sequences")
-
- if not interfaces.IRenderable.providedBy(p4base) and p4base and p4base.endswith('/'):
- config.error('p4base should not end with a trailing / [p4base = %s]' % p4base)
-
- if not interfaces.IRenderable.providedBy(p4branch) and p4branch and p4branch.endswith('/'):
- config.error('p4branch should not end with a trailing / [p4branch = %s]' % p4branch)
-
- if (p4branch or p4extra_views) and not p4base:
- config.error('If you specify either p4branch or p4extra_views you must also specify p4base')
-
- def startVC(self, branch, revision, patch):
- if debug_logging:
- log.msg('in startVC')
-
- self.revision = revision
- self.method = self._getMethod()
- self.stdio_log = self.addLogForRemoteCommands("stdio")
-
- d = self.checkP4()
-
- def checkInstall(p4Installed):
- if not p4Installed:
- raise BuildSlaveTooOldError("p4 is not installed on slave")
- return 0
- d.addCallback(checkInstall)
-
- if self.mode == 'full':
- d.addCallback(self.full)
- elif self.mode == 'incremental':
- d.addCallback(self.incremental)
-
- d.addCallback(self.parseGotRevision)
- d.addCallback(self.finish)
- d.addErrback(self.failed)
- return d
-
- @defer.inlineCallbacks
- def full(self, _):
- if debug_logging:
- log.msg("P4:full()..")
-
- # First we need to create the client
- yield self._createClientSpec()
-
- # Then p4 sync #none
- yield self._dovccmd(['sync', '#none'])
-
- # Then remove directory.
- yield self.runRmdir(self.workdir)
-
- # Then we need to sync the client
- if self.revision:
- if debug_logging:
- log.msg("P4: full() sync command based on :base:%s changeset:%d", self.p4base, int(self.revision))
- yield self._dovccmd(['sync', '%s...@%d' % (self.p4base, int(self.revision))], collectStdout=True)
- else:
- if debug_logging:
- log.msg("P4: full() sync command based on :base:%s no revision", self.p4base)
- yield self._dovccmd(['sync'], collectStdout=True)
-
- if debug_logging:
- log.msg("P4: full() sync done.")
-
- @defer.inlineCallbacks
- def incremental(self, _):
- if debug_logging:
- log.msg("P4:incremental()")
-
- # First we need to create the client
- yield self._createClientSpec()
-
- # and plan to do a checkout
- command = ['sync', ]
-
- if self.revision:
- command.extend(['%s...@%d' % (self.p4base, int(self.revision))])
-
- if debug_logging:
- log.msg("P4:incremental() command:%s revision:%s", command, self.revision)
- yield self._dovccmd(command)
-
- def finish(self, res):
- d = defer.succeed(res)
-
- def _gotResults(results):
- self.setStatus(self.cmd, results)
- return results
- d.addCallback(_gotResults)
- d.addCallbacks(self.finished, self.checkDisconnect)
- return d
-
- def _buildVCCommand(self, doCommand):
- assert doCommand, "No command specified"
-
- command = [self.p4bin, ]
-
- if self.p4port:
- command.extend(['-p', self.p4port])
- if self.p4user:
- command.extend(['-u', self.p4user])
- if self.p4passwd:
- # Need to find out if there's a way to obfuscate this
- command.extend(['-P', self.p4passwd])
- if self.p4client:
- command.extend(['-c', self.p4client])
-
- command.extend(doCommand)
-
- command = [c.encode('utf-8') for c in command]
- return command
-
- def _dovccmd(self, command, collectStdout=False, initialStdin=None):
- command = self._buildVCCommand(command)
-
- if debug_logging:
- log.msg("P4:_dovccmd():workdir->%s" % self.workdir)
- cmd = buildstep.RemoteShellCommand(self.workdir, command,
- env=self.env,
- logEnviron=self.logEnviron,
- collectStdout=collectStdout,
- initialStdin=initialStdin,)
- cmd.useLog(self.stdio_log, False)
- if debug_logging:
- log.msg("Starting p4 command : p4 %s" % (" ".join(command),))
-
- d = self.runCommand(cmd)
-
- def evaluateCommand(cmd):
- if cmd.rc != 0:
- if debug_logging:
- log.msg("P4:_dovccmd():Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- if collectStdout:
- return cmd.stdout
- else:
- return cmd.rc
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- def _getMethod(self):
- if self.method is not None and self.mode != 'incremental':
- return self.method
- elif self.mode == 'incremental':
- return None
- elif self.method is None and self.mode == 'full':
- return 'fresh'
-
- def _sourcedirIsUpdatable(self):
- # In general you should always be able to write to the directory
- # You just specified as the root of your client
- # So just return.
- # If we find a case where this is no longer true, then this
- # needs to be implemented
- return defer.succeed(True)
-
- @defer.inlineCallbacks
- def _createClientSpec(self):
- builddir = self.getProperty('builddir')
-
- if debug_logging:
- log.msg("P4:_createClientSpec() builddir:%s" % builddir)
- log.msg("P4:_createClientSpec() SELF.workdir:%s" % self.workdir)
-
- prop_dict = self.getProperties().asDict()
- prop_dict['p4client'] = self.p4client
-
- client_spec = ''
- client_spec += "Client: %s\n\n" % self.p4client
- client_spec += "Owner: %s\n\n" % self.p4user
- client_spec += "Description:\n\tCreated by %s\n\n" % self.p4user
- client_spec += "Root:\t%s\n\n" % os.path.join(builddir, self.workdir)
- client_spec += "Options:\tallwrite rmdir\n\n"
- if self.p4line_end:
- client_spec += "LineEnd:\t%s\n\n" % self.p4line_end
- else:
- client_spec += "LineEnd:\tlocal\n\n"
-
- # Setup a view
- client_spec += "View:\n"
-
- if self.p4viewspec:
- # uses only p4viewspec array of tuples to build view
- # If the user specifies a viewspec via an array of tuples then
- # Ignore any specified p4base,p4branch, and/or p4extra_views
- for k, v in self.p4viewspec:
- if debug_logging:
- log.msg('P4:_createClientSpec():key:%s value:%s' % (k, v))
- client_spec += '\t%s... //%s/%s...\n' % (k, self.p4client, v)
- else:
- # Uses p4base, p4branch, p4extra_views
- client_spec += "\t%s" % (self.p4base)
-
- if self.p4branch:
- client_spec += "/%s" % (self.p4branch)
-
- client_spec += "/... //%s/...\n" % (self.p4client)
-
- if self.p4extra_views:
- for k, v in self.p4extra_views:
- client_spec += "\t%s/... //%s/%s/...\n" % (k, self.p4client, v)
-
- client_spec = client_spec.encode('utf-8') # resolve unicode issues
- if debug_logging:
- log.msg(client_spec)
-
- stdout = yield self._dovccmd(['client', '-i'], collectStdout=True, initialStdin=client_spec)
- mo = re.search(r'Client (\S+) (.+)$', stdout, re.M)
- defer.returnValue(mo and (mo.group(2) == 'saved.' or mo.group(2) == 'not changed.'))
-
- def parseGotRevision(self, _):
- command = self._buildVCCommand(['changes', '-m1', '#have'])
-
- cmd = buildstep.RemoteShellCommand(self.workdir, command,
- env=self.env,
- logEnviron=self.logEnviron,
- collectStdout=True)
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
-
- def _setrev(_):
- stdout = cmd.stdout.strip()
- # Example output from p4 changes -m1 #have
- # Change 212798 on 2012/04/13 by user@user-unix-bldng2 'change to pickup build'
- revision = stdout.split()[1]
- try:
- int(revision)
- except ValueError:
- msg = ("p4.parseGotRevision unable to parse output "
- "of 'p4 changes -m1 \"#have\"': '%s'" % stdout)
- log.msg(msg)
- raise buildstep.BuildStepFailed()
-
- if debug_logging:
- log.msg("Got p4 revision %s" % (revision,))
- self.updateSourceProperty('got_revision', revision)
- return 0
- d.addCallback(lambda _: _setrev(cmd.rc))
- return d
-
- def purge(self, ignore_ignores):
- """Delete everything that shown up on status."""
- command = ['sync', '#none']
- if ignore_ignores:
- command.append('--no-ignore')
- d = self._dovccmd(command, collectStdout=True)
-
- # add deferred to rm tree
-
- # then add defer to sync to revision
- return d
-
- def checkP4(self):
- cmd = buildstep.RemoteShellCommand(self.workdir, ['p4', '-V'],
- env=self.env,
- logEnviron=self.logEnviron)
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
-
- def evaluate(cmd):
- if cmd.rc != 0:
- return False
- return True
- d.addCallback(lambda _: evaluate(cmd))
- return d
-
- def computeSourceRevision(self, changes):
- if not changes or None in [c.revision for c in changes]:
- return None
- lastChange = max([int(c.revision) for c in changes])
- return lastChange
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/repo.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/repo.py
deleted file mode 100644
index f1a75e18..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/repo.py
+++ /dev/null
@@ -1,434 +0,0 @@
-# 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 re
-import textwrap
-
-from twisted.internet import defer, reactor
-
-from buildbot import util
-from buildbot.process import buildstep
-from buildbot.steps.source.base import Source
-from buildbot.interfaces import IRenderable
-from zope.interface import implements
-
-
-class RepoDownloadsFromProperties(util.ComparableMixin, object):
- implements(IRenderable)
- parse_download_re = (re.compile(r"repo download ([^ ]+) ([0-9]+/[0-9]+)"),
- re.compile(r"([^ ]+) ([0-9]+/[0-9]+)"),
- re.compile(r"([^ ]+)/([0-9]+/[0-9]+)"),
- )
-
- compare_attrs = ('names',)
-
- def __init__(self, names):
- self.names = names
-
- def getRenderingFor(self, props):
- downloads = []
- for propName in self.names:
- s = props.getProperty(propName)
- if s is not None:
- downloads.extend(self.parseDownloadProperty(s))
- return downloads
-
- def parseDownloadProperty(self, s):
- """
- lets try to be nice in the format we want
- can support several instances of "repo download proj number/patch" (direct copy paste from gerrit web site)
- or several instances of "proj number/patch" (simpler version)
- This feature allows integrator to build with several pending interdependant changes.
- returns list of repo downloads sent to the buildslave
- """
- if s is None:
- return []
- ret = []
- for cur_re in self.parse_download_re:
- res = cur_re.search(s)
- while res:
- ret.append("%s %s" % (res.group(1), res.group(2)))
- s = s[:res.start(0)] + s[res.end(0):]
- res = cur_re.search(s)
- return ret
-
-
-class RepoDownloadsFromChangeSource(util.ComparableMixin, object):
- implements(IRenderable)
- compare_attrs = ('codebase',)
-
- def __init__(self, codebase=None):
- self.codebase = codebase
-
- def getRenderingFor(self, props):
- downloads = []
- if self.codebase is None:
- changes = props.getBuild().allChanges()
- else:
- changes = props.getBuild().getSourceStamp(self.codebase).changes
- for change in changes:
- if ("event.type" in change.properties and
- change.properties["event.type"] == "patchset-created"):
- downloads.append("%s %s/%s" % (change.properties["event.change.project"],
- change.properties["event.change.number"],
- change.properties["event.patchSet.number"]))
- return downloads
-
-
-class Repo(Source):
- """ Class for Repo with all the smarts """
- name = 'repo'
- renderables = ["manifestURL", "manifestFile", "tarball", "jobs",
- "syncAllBranches", "updateTarballAge", "manifestOverrideUrl",
- "repoDownloads"]
-
- ref_not_found_re = re.compile(r"fatal: Couldn't find remote ref")
- cherry_pick_error_re = re.compile(r"|".join([r"Automatic cherry-pick failed",
- r"error: "
- r"fatal: "
- r"possibly due to conflict resolution."]))
- re_change = re.compile(r".* refs/changes/\d\d/(\d+)/(\d+) -> FETCH_HEAD$")
- re_head = re.compile(r"^HEAD is now at ([0-9a-f]+)...")
- mirror_sync_retry = 10 # number of retries, if we detect mirror desynchronization
- mirror_sync_sleep = 60 # wait 1min between retries (thus default total retry time is 10min)
-
- def __init__(self,
- manifestURL=None,
- manifestBranch="master",
- manifestFile="default.xml",
- tarball=None,
- jobs=None,
- syncAllBranches=False,
- updateTarballAge=7*24.0*3600.0,
- manifestOverrideUrl=None,
- repoDownloads=None,
- **kwargs):
- """
- @type manifestURL: string
- @param manifestURL: The URL which points at the repo manifests repository.
-
- @type manifestBranch: string
- @param manifestBranch: The manifest branch to check out by default.
-
- @type manifestFile: string
- @param manifestFile: The manifest to use for sync.
-
- @type syncAllBranches: bool.
- @param syncAllBranches: true, then we must slowly synchronize all branches.
-
- @type updateTarballAge: float
- @param updateTarballAge: renderable to determine the update tarball policy,
- given properties
- Returns: max age of tarball in seconds, or None, if we
- want to skip tarball update
-
- @type manifestOverrideUrl: string
- @param manifestOverrideUrl: optional http URL for overriding the manifest
- usually coming from Property setup by a ForceScheduler
-
- @type repoDownloads: list of strings
- @param repoDownloads: optional repo download to perform after the repo sync
-
- """
- self.manifestURL = manifestURL
- self.manifestBranch = manifestBranch
- self.manifestFile = manifestFile
- self.tarball = tarball
- self.jobs = jobs
- self.syncAllBranches = syncAllBranches
- self.updateTarballAge = updateTarballAge
- self.manifestOverrideUrl = manifestOverrideUrl
- if repoDownloads is None:
- repoDownloads = []
- self.repoDownloads = repoDownloads
- Source.__init__(self, **kwargs)
-
- assert self.manifestURL is not None
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- return changes[-1].revision
-
- def filterManifestPatches(self):
- """
- Patches to manifest projects are a bit special.
- repo does not support a way to download them automatically,
- so we need to implement the boilerplate manually.
- This code separates the manifest patches from the other patches,
- and generates commands to import those manifest patches.
- """
- manifest_unrelated_downloads = []
- manifest_related_downloads = []
- for download in self.repoDownloads:
- project, ch_ps = download.split(" ")[-2:]
- if (self.manifestURL.endswith("/"+project) or
- self.manifestURL.endswith("/"+project+".git")):
- ch, ps = map(int, ch_ps.split("/"))
- branch = "refs/changes/%02d/%d/%d" % (ch % 100, ch, ps)
- manifest_related_downloads.append(
- ["git", "fetch", self.manifestURL, branch])
- manifest_related_downloads.append(
- ["git", "cherry-pick", "FETCH_HEAD"])
- else:
- manifest_unrelated_downloads.append(download)
- self.repoDownloads = manifest_unrelated_downloads
- self.manifestDownloads = manifest_related_downloads
-
- def _repoCmd(self, command, abandonOnFailure=True, **kwargs):
- return self._Cmd(["repo"]+command, abandonOnFailure=abandonOnFailure, **kwargs)
-
- def _Cmd(self, command, abandonOnFailure=True, workdir=None, **kwargs):
- if workdir is None:
- workdir = self.workdir
- self.cmd = cmd = buildstep.RemoteShellCommand(workdir, command,
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout, **kwargs)
- # does not make sense to logEnviron for each command (just for first)
- self.logEnviron = False
- cmd.useLog(self.stdio_log, False)
- self.stdio_log.addHeader("Starting command: %s\n" % (" ".join(command), ))
- self.step_status.setText(["%s" % (" ".join(command[:2]))])
- d = self.runCommand(cmd)
-
- def evaluateCommand(cmd):
- if abandonOnFailure and cmd.didFail():
- self.step_status.setText(["repo failed at: %s" % (" ".join(command[:2]))])
- self.stdio_log.addStderr("Source step failed while running command %s\n" % cmd)
- raise buildstep.BuildStepFailed()
- return cmd.rc
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- def repoDir(self):
- return self.build.path_module.join(self.workdir, ".repo")
-
- def sourcedirIsUpdateable(self):
- return self.pathExists(self.repoDir())
-
- def startVC(self, branch, revision, patch):
- d = self.doStartVC()
- d.addErrback(self.failed)
-
- @defer.inlineCallbacks
- def doStartVC(self):
- self.stdio_log = self.addLogForRemoteCommands("stdio")
-
- self.filterManifestPatches()
-
- if self.repoDownloads:
- self.stdio_log.addHeader("will download:\n" + "repo download " + "\nrepo download ".join(self.repoDownloads) + "\n")
-
- self.willRetryInCaseOfFailure = True
-
- d = self.doRepoSync()
-
- def maybeRetry(why):
- # in case the tree was corrupted somehow because of previous build
- # we clobber one time, and retry everything
- if why.check(buildstep.BuildStepFailed) and self.willRetryInCaseOfFailure:
- self.stdio_log.addStderr("got issue at first try:\n" + str(why) +
- "\nRetry after clobber...")
- return self.doRepoSync(forceClobber=True)
- return why # propagate to self.failed
- d.addErrback(maybeRetry)
- yield d
- yield self.maybeUpdateTarball()
-
- # starting from here, clobbering will not help
- yield self.doRepoDownloads()
- self.setStatus(self.cmd, 0)
- yield self.finished(0)
-
- @defer.inlineCallbacks
- def doClobberStart(self):
- yield self.runRmdir(self.workdir)
- yield self.runMkdir(self.workdir)
- yield self.maybeExtractTarball()
-
- @defer.inlineCallbacks
- def doRepoSync(self, forceClobber=False):
- updatable = yield self.sourcedirIsUpdateable()
- if not updatable or forceClobber:
- # no need to re-clobber in case of failure
- self.willRetryInCaseOfFailure = False
- yield self.doClobberStart()
- yield self.doCleanup()
- yield self._repoCmd(['init',
- '-u', self.manifestURL,
- '-b', self.manifestBranch,
- '-m', self.manifestFile])
-
- if self.manifestOverrideUrl:
- self.stdio_log.addHeader("overriding manifest with %s\n" % (self.manifestOverrideUrl))
- local_file = yield self.pathExists(self.build.path_module.join(self.workdir,
- self.manifestOverrideUrl))
- if local_file:
- yield self._Cmd(["cp", "-f", self.manifestOverrideUrl, "manifest_override.xml"])
- else:
- yield self._Cmd(["wget", self.manifestOverrideUrl, "-O", "manifest_override.xml"])
- yield self._Cmd(["ln", "-sf", "../manifest_override.xml", "manifest.xml"],
- workdir=self.build.path_module.join(self.workdir, ".repo"))
-
- for command in self.manifestDownloads:
- yield self._Cmd(command, workdir=self.build.path_module.join(self.workdir, ".repo", "manifests"))
-
- command = ['sync']
- if self.jobs:
- command.append('-j' + str(self.jobs))
- if not self.syncAllBranches:
- command.append('-c')
- self.step_status.setText(["repo sync"])
- self.stdio_log.addHeader("synching manifest %s from branch %s from %s\n"
- % (self.manifestFile, self.manifestBranch, self.manifestURL))
- yield self._repoCmd(command)
-
- command = ['manifest', '-r', '-o', 'manifest-original.xml']
- yield self._repoCmd(command)
-
- # check whether msg matches one of the
- # compiled regexps in self.re_error_messages
- def _findErrorMessages(self, error_re):
- for logname in ['stderr', 'stdout']:
- if not hasattr(self.cmd, logname):
- continue
- msg = getattr(self.cmd, logname)
- if not (re.search(error_re, msg) is None):
- return True
- return False
-
- def _sleep(self, delay):
- d = defer.Deferred()
- reactor.callLater(delay, d.callback, 1)
- return d
-
- @defer.inlineCallbacks
- def doRepoDownloads(self):
- self.repo_downloaded = ""
- for download in self.repoDownloads:
- command = ['download'] + download.split(' ')
- self.stdio_log.addHeader("downloading changeset %s\n"
- % (download))
-
- retry = self.mirror_sync_retry + 1
- while retry > 0:
- yield self._repoCmd(command, abandonOnFailure=False,
- collectStdout=True, collectStderr=True)
- if not self._findErrorMessages(self.ref_not_found_re):
- break
- retry -= 1
- self.stdio_log.addStderr("failed downloading changeset %s\n" % (download))
- self.stdio_log.addHeader("wait one minute for mirror sync\n")
- yield self._sleep(self.mirror_sync_sleep)
-
- if retry == 0:
- self.step_status.setText(["repo: change %s does not exist" % download])
- self.step_status.setText2(["repo: change %s does not exist" % download])
- raise buildstep.BuildStepFailed()
-
- if self.cmd.didFail() or self._findErrorMessages(self.cherry_pick_error_re):
- # cherry pick error! We create a diff with status current workdir
- # in stdout, which reveals the merge errors and exit
- command = ['forall', '-c', 'git', 'diff', 'HEAD']
- yield self._repoCmd(command, abandonOnFailure=False)
- self.step_status.setText(["download failed: %s" % download])
- raise buildstep.BuildStepFailed()
-
- if hasattr(self.cmd, 'stderr'):
- lines = self.cmd.stderr.split("\n")
- match1 = match2 = False
- for line in lines:
- if not match1:
- match1 = self.re_change.match(line)
- if not match2:
- match2 = self.re_head.match(line)
- if match1 and match2:
- self.repo_downloaded += "%s/%s %s " % (match1.group(1),
- match1.group(2),
- match2.group(1))
-
- self.setProperty("repo_downloaded", self.repo_downloaded, "Source")
-
- def computeTarballOptions(self):
- # Keep in mind that the compression part of tarball generation
- # can be non negligible
- tar = ['tar']
- if self.tarball.endswith("gz"):
- tar.append('-z')
- if self.tarball.endswith("bz2") or self.tarball.endswith("bz"):
- tar.append('-j')
- if self.tarball.endswith("lzma"):
- tar.append('--lzma')
- if self.tarball.endswith("lzop"):
- tar.append('--lzop')
- return tar
-
- @defer.inlineCallbacks
- def maybeExtractTarball(self):
- if self.tarball:
- tar = self.computeTarballOptions() + ['-xvf', self.tarball]
- res = yield self._Cmd(tar, abandonOnFailure=False)
- if res: # error with tarball.. erase repo dir and tarball
- yield self._Cmd(["rm", "-f", self.tarball], abandonOnFailure=False)
- yield self.runRmdir(self.repoDir(), abandonOnFailure=False)
-
- @defer.inlineCallbacks
- def maybeUpdateTarball(self):
- if not self.tarball or self.updateTarballAge is None:
- return
- # tarball path is absolute, so we cannot use slave's stat command
- # stat -c%Y gives mtime in second since epoch
- res = yield self._Cmd(["stat", "-c%Y", self.tarball], collectStdout=True, abandonOnFailure=False)
- if not res:
- tarball_mtime = int(self.cmd.stdout)
- yield self._Cmd(["stat", "-c%Y", "."], collectStdout=True)
- now_mtime = int(self.cmd.stdout)
- age = now_mtime - tarball_mtime
- if res or age > self.updateTarballAge:
- tar = self.computeTarballOptions() + ['-cvf', self.tarball, ".repo"]
- res = yield self._Cmd(tar, abandonOnFailure=False)
- if res: # error with tarball.. erase tarball, but dont fail
- yield self._Cmd(["rm", "-f", self.tarball], abandonOnFailure=False)
-
- # a simple shell script to gather all cleanup tweaks...
- # doing them one by one just complicate the stuff
- # and messup the stdio log
- def _getCleanupCommand(self):
- """also used by tests for expectations"""
- return textwrap.dedent("""\
- set -v
- if [ -d .repo/manifests ]
- then
- # repo just refuse to run if manifest is messed up
- # so ensure we are in a known state
- cd .repo/manifests
- rm -f .git/index.lock
- git fetch origin
- git reset --hard remotes/origin/%(manifestBranch)s
- git config branch.default.merge %(manifestBranch)s
- cd ..
- ln -sf manifests/%(manifestFile)s manifest.xml
- cd ..
- fi
- repo forall -c rm -f .git/index.lock
- repo forall -c git clean -f -d -x 2>/dev/null
- repo forall -c git reset --hard HEAD 2>/dev/null
- rm -f %(workdir)s/.repo/project.list
- """) % self.__dict__
-
- def doCleanup(self):
- command = self._getCleanupCommand()
- return self._Cmd(["bash", "-c", command], abandonOnFailure=False)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/svn.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/svn.py
deleted file mode 100644
index a49e9e07..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/svn.py
+++ /dev/null
@@ -1,381 +0,0 @@
-# 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 xml.dom.minidom
-import xml.parsers.expat
-
-from twisted.python import log
-from twisted.internet import defer
-
-from buildbot.process import buildstep
-from buildbot.steps.source.base import Source
-from buildbot.interfaces import BuildSlaveTooOldError
-from buildbot.config import ConfigErrors
-
-class SVN(Source):
- """I perform Subversion checkout/update operations."""
-
- name = 'svn'
-
- renderables = [ 'repourl' ]
- possible_modes = ('incremental', 'full')
- possible_methods = ('clean', 'fresh', 'clobber', 'copy', 'export', None)
-
- def __init__(self, repourl=None, mode='incremental',
- method=None, username=None,
- password=None, extra_args=None, keep_on_purge=None,
- depth=None, preferLastChangedRev=False, **kwargs):
-
- self.repourl = repourl
- self.username = username
- self.password = password
- self.extra_args = extra_args
- self.keep_on_purge = keep_on_purge or []
- self.depth = depth
- self.method = method
- self.mode = mode
- self.preferLastChangedRev = preferLastChangedRev
- Source.__init__(self, **kwargs)
- errors = []
- if self.mode not in self.possible_modes:
- errors.append("mode %s is not one of %s" % (self.mode, self.possible_modes))
- if self.method not in self.possible_methods:
- errors.append("method %s is not one of %s" % (self.method, self.possible_methods))
-
- if repourl is None:
- errors.append("you must provide repourl")
-
- if errors:
- raise ConfigErrors(errors)
-
- def startVC(self, branch, revision, patch):
- self.revision = revision
- self.method = self._getMethod()
- self.stdio_log = self.addLogForRemoteCommands("stdio")
-
- d = self.checkSvn()
- def checkInstall(svnInstalled):
- if not svnInstalled:
- raise BuildSlaveTooOldError("SVN is not installed on slave")
- return 0
- d.addCallback(checkInstall)
-
- if self.mode == 'full':
- d.addCallback(self.full)
- elif self.mode == 'incremental':
- d.addCallback(self.incremental)
- d.addCallback(self.parseGotRevision)
- d.addCallback(self.finish)
- d.addErrback(self.failed)
- return d
-
- @defer.inlineCallbacks
- def full(self, _):
- if self.method == 'clobber':
- yield self.clobber()
- return
- elif self.method in ['copy', 'export']:
- yield self.copy()
- return
-
- updatable = yield self._sourcedirIsUpdatable()
- if not updatable:
- # blow away the old (un-updatable) directory
- yield self.runRmdir(self.workdir)
-
- # then do a checkout
- checkout_cmd = ['checkout', self.repourl, '.']
- if self.revision:
- checkout_cmd.extend(["--revision", str(self.revision)])
- yield self._dovccmd(checkout_cmd)
- elif self.method == 'clean':
- yield self.clean()
- elif self.method == 'fresh':
- yield self.fresh()
-
- @defer.inlineCallbacks
- def incremental(self, _):
- updatable = yield self._sourcedirIsUpdatable()
-
- if not updatable:
- # blow away the old (un-updatable) directory
- yield self.runRmdir(self.workdir)
-
- # and plan to do a checkout
- command = ['checkout', self.repourl, '.']
- else:
- # otherwise, do an update
- command = ['update']
-
- if self.revision:
- command.extend(['--revision', str(self.revision)])
-
- yield self._dovccmd(command)
-
- @defer.inlineCallbacks
- def clobber(self):
- yield self.runRmdir(self.workdir)
-
- checkout_cmd = ['checkout', self.repourl, '.']
- if self.revision:
- checkout_cmd.extend(["--revision", str(self.revision)])
-
- yield self._dovccmd(checkout_cmd)
-
- def fresh(self):
- d = self.purge(True)
- cmd = ['update']
- if self.revision:
- cmd.extend(['--revision', str(self.revision)])
- d.addCallback(lambda _: self._dovccmd(cmd))
- return d
-
- def clean(self):
- d = self.purge(False)
- cmd = ['update']
- if self.revision:
- cmd.extend(['--revision', str(self.revision)])
- d.addCallback(lambda _: self._dovccmd(cmd))
- return d
-
- @defer.inlineCallbacks
- def copy(self):
- yield self.runRmdir(self.workdir)
-
- # temporarily set workdir = 'source' and do an incremental checkout
- try:
- old_workdir = self.workdir
- self.workdir = 'source'
- yield self.incremental(None)
- except: # finally doesn't work in python-2.4
- self.workdir = old_workdir
- raise
- self.workdir = old_workdir
-
- # if we're copying, copy; otherwise, export from source to build
- if self.method == 'copy':
- cmd = buildstep.RemoteCommand('cpdir',
- { 'fromdir': 'source', 'todir':self.workdir,
- 'logEnviron': self.logEnviron })
- else:
- export_cmd = ['svn', 'export']
- if self.revision:
- export_cmd.extend(["--revision", str(self.revision)])
- export_cmd.extend(['source', self.workdir])
-
- cmd = buildstep.RemoteShellCommand('', export_cmd,
- env=self.env, logEnviron=self.logEnviron, timeout=self.timeout)
- cmd.useLog(self.stdio_log, False)
-
- yield self.runCommand(cmd)
-
- if cmd.didFail():
- raise buildstep.BuildStepFailed()
-
- def finish(self, res):
- d = defer.succeed(res)
- def _gotResults(results):
- self.setStatus(self.cmd, results)
- return results
- d.addCallback(_gotResults)
- d.addCallbacks(self.finished, self.checkDisconnect)
- return d
-
-
- def _dovccmd(self, command, collectStdout=False):
- assert command, "No command specified"
- command.extend(['--non-interactive', '--no-auth-cache'])
- if self.username:
- command.extend(['--username', self.username])
- if self.password:
- command.extend(['--password', self.password])
- if self.depth:
- command.extend(['--depth', self.depth])
- if self.extra_args:
- command.extend(self.extra_args)
-
- cmd = buildstep.RemoteShellCommand(self.workdir, ['svn'] + command,
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout,
- collectStdout=collectStdout)
- cmd.useLog(self.stdio_log, False)
- log.msg("Starting SVN command : svn %s" % (" ".join(command), ))
- d = self.runCommand(cmd)
- def evaluateCommand(cmd):
- if cmd.didFail():
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- if collectStdout:
- return cmd.stdout
- else:
- return cmd.rc
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- def _getMethod(self):
- if self.method is not None and self.mode != 'incremental':
- return self.method
- elif self.mode == 'incremental':
- return None
- elif self.method is None and self.mode == 'full':
- return 'fresh'
-
- @defer.inlineCallbacks
- def _sourcedirIsUpdatable(self):
- # first, perform a stat to ensure that this is really an svn directory
- res = yield self.pathExists(self.build.path_module.join(self.workdir, '.svn'))
- if not res:
- defer.returnValue(False)
- return
-
- # then run 'svn info --xml' to check that the URL matches our repourl
- stdout = yield self._dovccmd(['info', '--xml'], collectStdout=True)
-
- try:
- stdout_xml = xml.dom.minidom.parseString(stdout)
- extractedurl = stdout_xml.getElementsByTagName('url')[0].firstChild.nodeValue
- except xml.parsers.expat.ExpatError:
- msg = "Corrupted xml, aborting step"
- self.stdio_log.addHeader(msg)
- raise buildstep.BuildStepFailed()
- defer.returnValue(extractedurl == self.repourl)
- return
-
- @defer.inlineCallbacks
- def parseGotRevision(self, _):
- # if this was a full/export, then we need to check svnversion in the
- # *source* directory, not the build directory
- svnversion_dir = self.workdir
- if self.mode == 'full' and self.method == 'export':
- svnversion_dir = 'source'
- cmd = buildstep.RemoteShellCommand(svnversion_dir, ['svn', 'info', '--xml'],
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout,
- collectStdout=True)
- cmd.useLog(self.stdio_log, False)
- yield self.runCommand(cmd)
-
- stdout = cmd.stdout
- try:
- stdout_xml = xml.dom.minidom.parseString(stdout)
- except xml.parsers.expat.ExpatError:
- msg = "Corrupted xml, aborting step"
- self.stdio_log.addHeader(msg)
- raise buildstep.BuildStepFailed()
-
- revision = None
- if self.preferLastChangedRev:
- try:
- revision = stdout_xml.getElementsByTagName('commit')[0].attributes['revision'].value
- except (KeyError, IndexError):
- msg =("SVN.parseGotRevision unable to detect Last Changed Rev in"
- " output of svn info")
- log.msg(msg)
- # fall through and try to get 'Revision' instead
-
- if revision is None:
- try:
- revision = stdout_xml.getElementsByTagName('entry')[0].attributes['revision'].value
- except (KeyError, IndexError):
- msg =("SVN.parseGotRevision unable to detect revision in"
- " output of svn info")
- log.msg(msg)
- raise buildstep.BuildStepFailed()
-
- msg = "Got SVN revision %s" % (revision, )
- self.stdio_log.addHeader(msg)
- self.updateSourceProperty('got_revision', revision)
-
- defer.returnValue(cmd.rc)
-
-
- def purge(self, ignore_ignores):
- """Delete everything that shown up on status."""
- command = ['status', '--xml']
- if ignore_ignores:
- command.append('--no-ignore')
- d = self._dovccmd(command, collectStdout=True)
- def parseAndRemove(stdout):
- files = []
- for filename in self.getUnversionedFiles(stdout, self.keep_on_purge):
- filename = self.workdir+'/'+str(filename)
- files.append(filename)
- if len(files) == 0:
- d = defer.succeed(0)
- else:
- if self.slaveVersionIsOlderThan('rmdir', '2.14'):
- d = self.removeFiles(files)
- else:
- d = self.runRmdir(files, abandonOnFailure=False)
- return d
- d.addCallback(parseAndRemove)
- def evaluateCommand(rc):
- if rc != 0:
- log.msg("Failed removing files")
- raise buildstep.BuildStepFailed()
- return rc
- d.addCallback(evaluateCommand)
- return d
-
- @staticmethod
- def getUnversionedFiles(xmlStr, keep_on_purge):
- try:
- result_xml = xml.dom.minidom.parseString(xmlStr)
- except xml.parsers.expat.ExpatError:
- log.err("Corrupted xml, aborting step")
- raise buildstep.BuildStepFailed()
-
- for entry in result_xml.getElementsByTagName('entry'):
- (wc_status,) = entry.getElementsByTagName('wc-status')
- if wc_status.getAttribute('item') == 'external':
- continue
- if wc_status.getAttribute('item') == 'missing':
- continue
- filename = entry.getAttribute('path')
- if filename in keep_on_purge or filename == '':
- continue
- yield filename
-
- @defer.inlineCallbacks
- def removeFiles(self, files):
- for filename in files:
- res = yield self.runRmdir(filename, abandonOnFailure=False)
- if res:
- defer.returnValue(res)
- return
- defer.returnValue(0)
-
- def checkSvn(self):
- cmd = buildstep.RemoteShellCommand(self.workdir, ['svn', '--version'],
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout)
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def evaluate(cmd):
- if cmd.rc != 0:
- return False
- return True
- d.addCallback(lambda _: evaluate(cmd))
- return d
-
- def computeSourceRevision(self, changes):
- if not changes or None in [c.revision for c in changes]:
- return None
- lastChange = max([int(c.revision) for c in changes])
- return lastChange
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/yoctogit.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/yoctogit.py
deleted file mode 100644
index ecf4d1a3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/source/yoctogit.py
+++ /dev/null
@@ -1,640 +0,0 @@
-# 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
-
-from twisted.python import log
-from twisted.internet import defer
-
-from buildbot import config as bbconfig
-from buildbot.process import buildstep
-from buildbot.steps.source.base import Source
-from buildbot.interfaces import BuildSlaveTooOldError
-
-def isTrueOrIsExactlyZero(v):
- # nonzero values are true...
- if v:
- return True
-
- # ... and True for the number zero, but we have to
- # explicitly guard against v==False, since
- # isinstance(False, int) is surprisingly True
- if isinstance(v, int) and v is not False:
- return True
-
- # all other false-ish values are false
- return False
-
-git_describe_flags = [
- # on or off
- ('all', lambda v: ['--all'] if v else None),
- ('always', lambda v: ['--always'] if v else None),
- ('contains', lambda v: ['--contains'] if v else None),
- ('debug', lambda v: ['--debug'] if v else None),
- ('long', lambda v: ['--long'] if v else None),
- ('exact-match', lambda v: ['--exact-match'] if v else None),
- ('tags', lambda v: ['--tags'] if v else None),
- # string parameter
- ('match', lambda v: ['--match', v] if v else None),
- # numeric parameter
- ('abbrev', lambda v: ['--abbrev=%s' % v] if isTrueOrIsExactlyZero(v) else None),
- ('candidates', lambda v: ['--candidates=%s' % v] if isTrueOrIsExactlyZero(v) else None),
- # optional string parameter
- ('dirty', lambda v: ['--dirty'] if (v is True or v=='') else None),
- ('dirty', lambda v: ['--dirty=%s' % v] if (v and v is not True) else None),
-]
-
-class YoctoGit(Source):
- """ Class for Git specific to the YoctoProject. Now with smarts and weird
- Yocto specific stuff like defining source directories """
- name='yoctogit'
- renderables = [ "repourl"]
-
- def __init__(self, repourl=None, branch='HEAD', mode='incremental',
- method=None, submodules=False, shallow=False, progress=False,
- retryFetch=False, clobberOnFailure=False, getDescription=False,
- workdir='build', layername=None, storedir="/tmp/junk", mirrordir=None,
- config=None, **kwargs):
- """
- @type repourl: string
- @param repourl: the URL which points at the git repository
-
- @type branch: string
- @param branch: The branch or tag to check out by default. If
- a build specifies a different branch, it will
- be used instead of this.
-
- @type submodules: boolean
- @param submodules: Whether or not to update (and initialize)
- git submodules.
-
- @type mode: string
- @param mode: Type of checkout. Described in docs.
-
- @type method: string
- @param method: Full builds can be done is different ways. This parameter
- specifies which method to use.
-
- @type progress: boolean
- @param progress: Pass the --progress option when fetching. This
- can solve long fetches getting killed due to
- lack of output, but requires Git 1.7.2+.
- @type shallow: boolean
- @param shallow: Use a shallow or clone, if possible
-
- @type retryFetch: boolean
- @param retryFetch: Retry fetching before failing source checkout.
-
- @type getDescription: boolean or dict
- @param getDescription: Use 'git describe' to describe the fetched revision
-
- @type workdir: string
- @param workdir: Used to indicate the destination of the copy of srcdir
-
- @type storedir: string
- @param storedir: where the old build dir gets moved to during a movecopy
-
- @type layername: string
- @param layername: Used in the yocto-autobuilder's movecopy as a way
- of moving the old build directory to a unique area for outside cleanup/
- review.
-
- @type config: dict
- @param config: Git configuration options to enable when running git
- """
- if not getDescription and not isinstance(getDescription, dict):
- getDescription = False
-
- self.branch = branch
- self.method = method
- self.prog = progress
- self.repourl = repourl.rstrip('/').strip()
- self.retryFetch = retryFetch
- self.submodules = submodules
- self.shallow = shallow
- self.workdir = workdir
- self.storedir = storedir
- self.mirrordir = mirrordir
- self.layername = layername
- self.fetchcount = 0
- self.clobberOnFailure = clobberOnFailure
- self.mode = mode
- self.getDescription = getDescription
- self.config = config
- self.timeout = 10*60
- # We no longer pass srcdir in. There are way too many ways to hang
- # yourself by doing that.
- if self.mirrordir:
- if self.method in ['barecopy', 'movecopy']:
- self.srcdir='source/'+self.repourl
- else:
- if "poky" in self.layername or \
- "oecore" in self.layername or \
- "eclipse" in self.layername:
- self.srcdir = "build"
- else:
- self.srcdir = 'build/'+self.layername
- else:
- self.srcdir = 'source'
- if self.method in ['barecopy', 'movecopy']:
- self.workdir='source/'+self.repourl
- else:
- self.workdir = 'build'
-
- Source.__init__(self, **kwargs)
-
- if self.mode not in ['incremental', 'full']:
- bbconfig.error("Git: mode must be 'incremental' or 'full'.")
- if not self.repourl:
- bbconfig.error("Git: must provide repourl.")
- if (self.mode == 'full' and
- self.method not in ['clean', 'fresh', 'clobber', 'movecopy', 'barecopy', None]):
- bbconfig.error("Git: invalid method for mode 'full'.")
- if self.shallow and (self.mode != 'full' or self.method != 'clobber'):
- bbconfig.error("Git: shallow only possible with mode 'full' and method 'clobber'.")
- if not isinstance(self.getDescription, (bool, dict)):
- bbconfig.error("Git: getDescription must be a boolean or a dict.")
-
- def startVC(self, branch, revision, patch):
- self.branch = branch or 'HEAD'
- self.revision = revision
- self.method = self._getMethod()
- self.stdio_log = self.addLogForRemoteCommands("stdio")
-
- d = self.checkGit()
- def checkInstall(gitInstalled):
- if not gitInstalled:
- raise BuildSlaveTooOldError("git is not installed on slave")
- return 0
- d.addCallback(checkInstall)
-
- if self.mode == 'incremental':
- d.addCallback(lambda _: self.incremental())
- elif self.mode == 'full':
- d.addCallback(lambda _: self.full())
- if patch:
- d.addCallback(self.patch, patch)
- d.addCallback(self.parseGotRevision)
- d.addCallback(self.parseCommitDescription)
- d.addCallback(self.finish)
- d.addErrback(self.failed)
- return d
-
- @defer.inlineCallbacks
- def full(self):
- updatable = yield self._sourcedirIsUpdatable()
- self.mirrorexists = yield self._mirrorExists()
-
- if self.method == 'clobber':
- yield self.clobber()
- return
- elif self.method == 'barecopy':
- yield self.barecopy()
- yield self._srccopy()
- return
- elif self.method == 'movecopy':
- yield self.movecopy()
- yield self._srccopy()
- return
-
- if not updatable:
- log.msg("No git repo present, making full clone")
- yield self._fullCloneOrFallback()
- elif self.method == 'clean':
- yield self.clean()
- elif self.method == 'fresh':
- yield self.fresh()
- else:
- raise ValueError("Unknown method, check your configuration")
-
- @defer.inlineCallbacks
- def incremental(self):
- updatable = yield self._sourcedirIsUpdatable()
- self.mirrorexists = yield self._mirrorExists()
-
- # if not updateable, do a full checkout
- if not updatable:
- yield self._fullCloneOrFallback()
- return
-
- # Just fetch everything and bring it up to date. This is because if you
- # pass "HEAD" in, you're not certain to get the most upto date as that ref
- # should always exist.
-
- yield self._fetchOrFallback(None)
- yield self._updateSubmodule(None)
-
- def clean(self):
- command = ['clean', '-f', '-d']
- d = self._dovccmd(command)
- d.addCallback(self._fetchOrFallback)
- d.addCallback(self._updateSubmodule)
- d.addCallback(self._cleanSubmodule)
- return d
-
- def clobber(self):
- d = self._doClobber()
- d.addCallback(lambda _: self._fullClone(shallowClone=self.shallow))
- return d
-
- def fresh(self):
- command = ['clean', '-f', '-d', '-x']
- d = self._dovccmd(command)
- d.addCallback(self._fetchOrFallback)
- d.addCallback(self._updateSubmodule)
- d.addCallback(self._cleanSubmodule)
- return d
-
- def barecopy(self):
- cmd = buildstep.RemoteCommand('mkdir', {'dir': 'build',
- 'logEnviron': self.logEnviron,
- 'timeout': self.timeout,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def evaluateCommand(cmd):
- if cmd.didFail():
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- d.addCallback(lambda _: evaluateCommand(cmd))
- d.addCallback(lambda _: self.incremental())
- return d
-
- def movecopy(self):
- # This relies on an external method of cleaning up the todir, like a cron job
- # it can be rather disk space intensive.
- import time
- import random
-
- # Let's make the todir difficult to have duplicate dir names. This
- # method probably won't work correctly crossing filesystems, so utilize
- # movecopy with caution.
-
- cmd = buildstep.RemoteCommand('mv', {'fromdir': 'build',
- 'todir': self.storedir + '/' + self.getProperty("DEST") + '/' +
- str(int(time.time())) + '-' +
- str(random.randrange(100, 100000, 2)) +
- self.layername,
- 'logEnviron':self.logEnviron,
- 'timeout': self.timeout,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def evaluateCommand(cmd):
- if cmd.didFail():
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- d.addCallback(lambda _: evaluateCommand(cmd))
- d.addCallback(lambda _: self.incremental())
- return d
-
- # Buildbot's standard copy has been removed from yoctogit.
- # We use _srccopy from either movecopy or barecopy as a callback
- # this uses self.srcdir to copy to the build dir.
-
- def _srccopy(self):
- if "poky" in self.layername or \
- "oecore" in self.layername or \
- "eclipse" in self.layername:
- todir = "build"
- else:
- todir = "build/" + self.layername
- fromdir='source/'+self.repourl
-
- cmd = buildstep.RemoteCommand('cpdir',
- {'fromdir': fromdir,
- 'todir': todir,
- 'logEnviron': self.logEnviron,
- 'timeout': self.timeout,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
-
- def evaluateCommand(cmd):
- if cmd.didFail():
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- def finish(self, res):
- d = defer.succeed(res)
- def _gotResults(results):
- self.setStatus(self.cmd, results)
- log.msg("Closing log, sending result of the command %s " % \
- (self.cmd))
- return results
- d.addCallback(_gotResults)
- d.addCallbacks(self.finished, self.checkDisconnect)
- return d
-
- @defer.inlineCallbacks
- def parseGotRevision(self, _=None):
- stdout = yield self._dovccmd(['rev-parse', 'HEAD'], collectStdout=True)
- revision = stdout.strip()
- if len(revision) != 40:
- raise buildstep.BuildStepFailed()
- log.msg("Got Git revision %s" % (revision, ))
- self.updateSourceProperty('got_revision', revision)
-
- defer.returnValue(0)
-
- @defer.inlineCallbacks
- def parseCommitDescription(self, _=None):
- if self.getDescription==False: # dict() should not return here
- defer.returnValue(0)
- return
-
- cmd = ['describe']
- if isinstance(self.getDescription, dict):
- for opt, arg in git_describe_flags:
- opt = self.getDescription.get(opt, None)
- arg = arg(opt)
- if arg:
- cmd.extend(arg)
- cmd.append('HEAD')
-
- try:
- stdout = yield self._dovccmd(cmd, collectStdout=True)
- desc = stdout.strip()
- self.updateSourceProperty('commit-description', desc)
- except:
- pass
-
- defer.returnValue(0)
-
- def _dovccmd(self, command, abandonOnFailure=True, collectStdout=False, initialStdin=None):
- full_command = ['git']
- if self.config is not None:
- for name, value in self.config.iteritems():
- full_command.append('-c')
- full_command.append('%s=%s' % (name, value))
- full_command.extend(command)
- if self.method in ['barecopy', 'movecopy']:
- self.workdir='source/'+self.repourl
- else:
- self.workdir = 'build'
- cmd = buildstep.RemoteShellCommand(self.workdir,
- full_command,
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout,
- collectStdout=collectStdout,
- initialStdin=initialStdin)
- cmd.useLog(self.stdio_log, False)
- log.msg("Starting git command : git %s" % (" ".join(command), ))
- d = self.runCommand(cmd)
- def evaluateCommand(cmd):
- if abandonOnFailure and cmd.didFail():
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- if collectStdout:
- return cmd.stdout
- else:
- return cmd.rc
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- def _dosimplecmd(self, command, abandonOnFailure=True, collectStdout=False, initialStdin=None):
- if self.method in ['barecopy', 'movecopy']:
- self.workdir='source/'+self.repourl
- else:
- self.workdir = 'build'
- cmd = buildstep.RemoteShellCommand(self.workdir,
- command,
- env=self.env,
- logEnviron=self.logEnviron,
- timeout=self.timeout,
- collectStdout=collectStdout,
- initialStdin=initialStdin)
- cmd.useLog(self.stdio_log, False)
- log.msg("Starting simple command : %s" % (" ".join(command), ))
- d = self.runCommand(cmd)
- def evaluateCommand(cmd):
- if abandonOnFailure and cmd.didFail():
- log.msg("Source step failed while running command %s" % cmd)
- raise buildstep.BuildStepFailed()
- if collectStdout:
- return cmd.stdout
- else:
- return cmd.rc
- d.addCallback(lambda _: evaluateCommand(cmd))
- return d
-
- def _fetch(self, _):
- # We can run git gc on the core clone directory which means references can disappear
- # leading to fetch failures like:
- # error: refs/heads/master-next does not point to a valid object!
- # error: refs/remotes/master-next does not point to a valid object!
- # fatal: bad object HEAD
- # error: git://git.yoctoproject.org/poky did not send all necessary objects
- # However if we remove all heads, we can't hit that error!
-
- command = ['rm', '.git/refs/', '-rf']
- d = self._dosimplecmd(command)
-
- def mkdir(res):
- if res != 0:
- return res
- mkdircommand = ['mkdir', '.git/refs/']
- return self._dosimplecmd(mkdircommand)
- d.addCallback(mkdir)
-
- def fetch(res):
- if res != 0:
- return res
- gitcommand = ['fetch', '-t', '--prune', self.repourl, '+refs/heads/' + self.branch + ':refs/remotes/' + self.branch]
- # If the 'progress' option is set, tell git fetch to output
- # progress information to the log. This can solve issues with
- # long fetches killed due to lack of output, but only works
- # with Git 1.7.2 or later.
- if self.prog:
- gitcommand.append('--progress')
- return self._dovccmd(gitcommand)
- d.addCallback(fetch)
-
- def checkout(res):
- if res != 0:
- return res
- if self.revision and self.revision != 'HEAD':
- rev = self.revision
- else:
- rev = 'FETCH_HEAD'
- gitcommand = ['reset', '--hard', rev, '--']
- abandonOnFailure = not self.retryFetch and not self.clobberOnFailure
- return self._dovccmd(gitcommand, abandonOnFailure)
- d.addCallback(checkout)
-
- def gitclean(res):
- if res != 0:
- return res
- gitcommand = ['clean', '-d', '-f']
- return self._dovccmd(gitcommand)
- d.addCallback(gitclean)
-
- def renameBranch(res):
- if res != 0:
- return res
- d = self._dovccmd(['branch', '-M', self.branch], abandonOnFailure=False)
- # Ignore errors
- d.addCallback(lambda _: res)
- return d
-
- if self.branch != 'HEAD':
- d.addCallback(renameBranch)
- return d
-
- @defer.inlineCallbacks
- def _fetchOrFallback(self, _):
- """
- Handles fallbacks for failure of fetch,
- wrapper for self._fetch
- """
- res = yield self._fetch(None)
- if res == 0:
- defer.returnValue(res)
- return
- if self.retryFetch:
- res = yield self._fetch(None)
- if res == 0:
- defer.returnValue(res)
- return
- if self.clobberOnFailure:
- yield self._doClobber()
- yield self._fullClone()
- else:
- raise buildstep.BuildStepFailed()
-
- def _fullClone(self, shallowClone=False):
- """Perform full clone and checkout to the revision if specified
- In the case of shallow clones if any of the step fail abort whole build step.
- """
- args = []
- if self.branch != 'HEAD':
- args += ['--branch', self.branch]
- if shallowClone:
- args += ['--depth', '1']
- command = ['clone'] + args + [self.repourl, '.']
-
- mirror = None
- if self.mirrordir:
- mirror = self.mirrordir + "/" + self.repourl.replace("git://", "") + "/"
- if self.mirrorexists:
- command = ['clone'] + ["-s", "-n"] + [mirror, '.']
- else:
- command = ['clone'] + ["-s", "-n"] + [self.repourl, '.']
-
- #Fix references
- if self.prog:
- command.append('--progress')
-
- # If it's a shallow clone abort build step
- d = self._dovccmd(command, shallowClone)
-
- if mirror:
- d.addCallback(lambda _: self._fetch(None))
-
- # If revision specified checkout that revision
- if self.revision:
- d.addCallback(lambda _: self._dovccmd(['reset', '--hard',
- self.revision, '--'],
- shallowClone))
- # init and update submodules, recurisively. If there's not recursion
- # it will not do it.
- if self.submodules:
- d.addCallback(lambda _: self._dovccmd(['submodule', 'update',
- '--init', '--recursive'],
- shallowClone))
- return d
-
- def _fullCloneOrFallback(self):
- """Wrapper for _fullClone(). In the case of failure, if clobberOnFailure
- is set to True remove the build directory and try a full clone again.
- """
-
- d = self._fullClone()
- def clobber(res):
- if res != 0:
- if self.clobberOnFailure:
- d = self._doClobber()
- d.addCallback(lambda _: self._fullClone())
- return d
- else:
- raise buildstep.BuildStepFailed()
- else:
- return res
- d.addCallback(clobber)
- return d
-
- def _doClobber(self):
- """Remove the work directory"""
- cmd = buildstep.RemoteCommand('rmdir', {'dir': self.workdir,
- 'logEnviron': self.logEnviron,
- 'timeout': self.timeout,})
- cmd.useLog(self.stdio_log, False)
- d = self.runCommand(cmd)
- def checkRemoval(res):
- if res != 0:
- raise RuntimeError("Failed to delete directory")
- return res
- d.addCallback(lambda _: checkRemoval(cmd.rc))
- return d
-
- def computeSourceRevision(self, changes):
- if not changes:
- return None
- return changes[-1].revision
-
- def _sourcedirIsUpdatable(self):
- return self.pathExists(self.build.path_module.join(self.workdir, '.git'))
-
- def _mirrorExists(self):
- if self.mirrordir:
- mirror = self.mirrordir + "/" + self.repourl.replace("git://", "") + "/"
- return self.pathExists(self.build.path_module.join(mirror, '.git'))
- else:
- return None
-
- def _updateSubmodule(self, _):
- if self.submodules:
- return self._dovccmd(['submodule', 'update', '--init', '--recursive'])
- else:
- return defer.succeed(0)
-
- def _cleanSubmodule(self, _):
- if self.submodules:
- command = ['submodule', 'foreach', 'git', 'clean', '-f', '-d']
- if self.mode == 'full' and self.method == 'fresh':
- command.append('-x')
- return self._dovccmd(command)
- else:
- return defer.succeed(0)
-
- def _getMethod(self):
- if self.method is not None and self.mode != 'incremental':
- return self.method
- elif self.mode == 'incremental':
- return None
- elif self.method is None and self.mode == 'full':
- return 'fresh'
-
- def checkGit(self):
- d = self._dovccmd(['--version'])
- def check(res):
- if res == 0:
- return True
- return False
- d.addCallback(check)
- return d
-
- def patch(self, _, patch):
- d = self._dovccmd(['apply', '--index', '-p', str(patch[0])],
- initialStdin=patch[1])
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/subunit.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/subunit.py
deleted file mode 100644
index f1e5749c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/subunit.py
+++ /dev/null
@@ -1,102 +0,0 @@
-# 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
-
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.status.results import SUCCESS, FAILURE
-
-class SubunitShellCommand(ShellCommand):
- """A ShellCommand that sniffs subunit output.
- """
-
- def __init__(self, failureOnNoTests=False, *args, **kwargs):
- ShellCommand.__init__(self, *args, **kwargs)
- self.failureOnNoTests = failureOnNoTests
-
- # importing here gets around an import loop
- from buildbot.process import subunitlogobserver
-
- self.ioObverser = subunitlogobserver.SubunitLogObserver()
- self.addLogObserver('stdio', self.ioObverser)
- self.progressMetrics = self.progressMetrics + ('tests', 'tests failed')
-
- def commandComplete(self, cmd):
- # figure out all statistics about the run
- ob = self.ioObverser
- failures = len(ob.failures)
- errors = len(ob.errors)
- skips = len(ob.skips)
- total = ob.testsRun
-
- count = failures + errors
-
- text = [self.name]
- text2 = ""
-
- if not count:
- results = SUCCESS
- if total:
- text += ["%d %s" % \
- (total,
- total == 1 and "test" or "tests"),
- "passed"]
- else:
- if self.failureOnNoTests:
- results = FAILURE
- text += ["no tests", "run"]
- else:
- results = FAILURE
- text.append("Total %d test(s)" % total)
- if failures:
- text.append("%d %s" % \
- (failures,
- failures == 1 and "failure" or "failures"))
- if errors:
- text.append("%d %s" % \
- (errors,
- errors == 1 and "error" or "errors"))
- text2 = "%d %s" % (count, (count == 1 and 'test' or 'tests'))
-
-
- if skips:
- text.append("%d %s" % (skips,
- skips == 1 and "skip" or "skips"))
-
- #TODO: expectedFailures/unexpectedSuccesses
-
- self.results = results
- self.text = text
- self.text2 = [text2]
-
- def evaluateCommand(self, cmd):
- if cmd.didFail():
- return FAILURE
- return self.results
-
- def createSummary(self, loog):
- ob = self.ioObverser
- problems = ""
- for test, err in ob.errors + ob.failures:
- problems += "%s\n%s" % (test.id(), err)
- if problems:
- self.addCompleteLog("problems", problems)
- warnings = ob.warningio.getvalue()
- if warnings:
- self.addCompleteLog("warnings", warnings)
-
- def getText(self, cmd, results):
- return self.text
- def getText2(self, cmd, results):
- return self.text2
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/transfer.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/transfer.py
deleted file mode 100644
index a2f7007f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/transfer.py
+++ /dev/null
@@ -1,632 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-
-import os.path, tarfile, tempfile
-try:
- from cStringIO import StringIO
- assert StringIO
-except ImportError:
- from StringIO import StringIO
-from twisted.spread import pb
-from twisted.python import log
-from buildbot.process import buildstep
-from buildbot.process.buildstep import BuildStep
-from buildbot.process.buildstep import SUCCESS, FAILURE, SKIPPED
-from buildbot.interfaces import BuildSlaveTooOldError
-from buildbot.util import json
-from buildbot.util.eventual import eventually
-from buildbot import config
-
-
-class _FileWriter(pb.Referenceable):
- """
- Helper class that acts as a file-object with write access
- """
-
- def __init__(self, destfile, maxsize, mode):
- # Create missing directories.
- destfile = os.path.abspath(destfile)
- dirname = os.path.dirname(destfile)
- if not os.path.exists(dirname):
- os.makedirs(dirname)
-
- self.destfile = destfile
- self.mode = mode
- fd, self.tmpname = tempfile.mkstemp(dir=dirname)
- self.fp = os.fdopen(fd, 'wb')
- self.remaining = maxsize
-
- def remote_write(self, data):
- """
- Called from remote slave to write L{data} to L{fp} within boundaries
- of L{maxsize}
-
- @type data: C{string}
- @param data: String of data to write
- """
- if self.remaining is not None:
- if len(data) > self.remaining:
- data = data[:self.remaining]
- self.fp.write(data)
- self.remaining = self.remaining - len(data)
- else:
- self.fp.write(data)
-
- def remote_utime(self, accessed_modified):
- os.utime(self.destfile,accessed_modified)
-
- def remote_close(self):
- """
- Called by remote slave to state that no more data will be transfered
- """
- self.fp.close()
- self.fp = None
- # on windows, os.rename does not automatically unlink, so do it manually
- if os.path.exists(self.destfile):
- os.unlink(self.destfile)
- os.rename(self.tmpname, self.destfile)
- self.tmpname = None
- if self.mode is not None:
- os.chmod(self.destfile, self.mode)
-
- def cancel(self):
- # unclean shutdown, the file is probably truncated, so delete it
- # altogether rather than deliver a corrupted file
- fp = getattr(self, "fp", None)
- if fp:
- fp.close()
- os.unlink(self.destfile)
- if self.tmpname and os.path.exists(self.tmpname):
- os.unlink(self.tmpname)
-
-
-def _extractall(self, path=".", members=None):
- """Fallback extractall method for TarFile, in case it doesn't have its own."""
-
- import copy
-
- directories = []
-
- if members is None:
- members = self
-
- for tarinfo in members:
- if tarinfo.isdir():
- # Extract directories with a safe mode.
- directories.append(tarinfo)
- tarinfo = copy.copy(tarinfo)
- tarinfo.mode = 0700
- self.extract(tarinfo, path)
-
- # Reverse sort directories.
- directories.sort(lambda a, b: cmp(a.name, b.name))
- directories.reverse()
-
- # Set correct owner, mtime and filemode on directories.
- for tarinfo in directories:
- dirpath = os.path.join(path, tarinfo.name)
- try:
- self.chown(tarinfo, dirpath)
- self.utime(tarinfo, dirpath)
- self.chmod(tarinfo, dirpath)
- except tarfile.ExtractError, e:
- if self.errorlevel > 1:
- raise
- else:
- self._dbg(1, "tarfile: %s" % e)
-
-class _DirectoryWriter(_FileWriter):
- """
- A DirectoryWriter is implemented as a FileWriter, with an added post-processing
- step to unpack the archive, once the transfer has completed.
- """
-
- def __init__(self, destroot, maxsize, compress, mode):
- self.destroot = destroot
- self.compress = compress
-
- self.fd, self.tarname = tempfile.mkstemp()
- os.close(self.fd)
-
- _FileWriter.__init__(self, self.tarname, maxsize, mode)
-
- def remote_unpack(self):
- """
- Called by remote slave to state that no more data will be transfered
- """
- # Make sure remote_close is called, otherwise atomic rename wont happen
- self.remote_close()
-
- # Map configured compression to a TarFile setting
- if self.compress == 'bz2':
- mode='r|bz2'
- elif self.compress == 'gz':
- mode='r|gz'
- else:
- mode = 'r'
-
- # Support old python
- if not hasattr(tarfile.TarFile, 'extractall'):
- tarfile.TarFile.extractall = _extractall
-
- # Unpack archive and clean up after self
- archive = tarfile.open(name=self.tarname, mode=mode)
- archive.extractall(path=self.destroot)
- archive.close()
- os.remove(self.tarname)
-
-def makeStatusRemoteCommand(step, remote_command, args):
- self = buildstep.RemoteCommand(remote_command, args, decodeRC={None:SUCCESS, 0:SUCCESS})
- callback = lambda arg: step.step_status.addLog('stdio')
- self.useLogDelayed('stdio', callback, True)
- return self
-
-class _TransferBuildStep(BuildStep):
- """
- Base class for FileUpload and FileDownload to factor out common
- functionality.
- """
- DEFAULT_WORKDIR = "build" # is this redundant?
-
- renderables = [ 'workdir' ]
-
- haltOnFailure = True
- flunkOnFailure = True
-
- def setDefaultWorkdir(self, workdir):
- if self.workdir is None:
- self.workdir = workdir
-
- def _getWorkdir(self):
- if self.workdir is None:
- workdir = self.DEFAULT_WORKDIR
- else:
- workdir = self.workdir
- return workdir
-
- def interrupt(self, reason):
- self.addCompleteLog('interrupt', str(reason))
- if self.cmd:
- d = self.cmd.interrupt(reason)
- return d
-
- def finished(self, result):
- # Subclasses may choose to skip a transfer. In those cases, self.cmd
- # will be None, and we should just let BuildStep.finished() handle
- # the rest
- if result == SKIPPED:
- return BuildStep.finished(self, SKIPPED)
-
- if self.cmd.didFail():
- return BuildStep.finished(self, FAILURE)
- return BuildStep.finished(self, SUCCESS)
-
-
-class FileUpload(_TransferBuildStep):
-
- name = 'upload'
-
- renderables = [ 'slavesrc', 'masterdest', 'url' ]
-
- def __init__(self, slavesrc, masterdest,
- workdir=None, maxsize=None, blocksize=16*1024, mode=None,
- keepstamp=False, url=None,
- **buildstep_kwargs):
- BuildStep.__init__(self, **buildstep_kwargs)
-
- self.slavesrc = slavesrc
- self.masterdest = masterdest
- self.workdir = workdir
- self.maxsize = maxsize
- self.blocksize = blocksize
- if not isinstance(mode, (int, type(None))):
- config.error(
- 'mode must be an integer or None')
- self.mode = mode
- self.keepstamp = keepstamp
- self.url = url
-
- def start(self):
- version = self.slaveVersion("uploadFile")
-
- if not version:
- m = "slave is too old, does not know about uploadFile"
- raise BuildSlaveTooOldError(m)
-
- source = self.slavesrc
- masterdest = self.masterdest
- # we rely upon the fact that the buildmaster runs chdir'ed into its
- # basedir to make sure that relative paths in masterdest are expanded
- # properly. TODO: maybe pass the master's basedir all the way down
- # into the BuildStep so we can do this better.
- masterdest = os.path.expanduser(masterdest)
- log.msg("FileUpload started, from slave %r to master %r"
- % (source, masterdest))
-
- self.step_status.setText(['uploading', os.path.basename(source)])
- if self.url is not None:
- self.addURL(os.path.basename(masterdest), self.url)
-
- # we use maxsize to limit the amount of data on both sides
- fileWriter = _FileWriter(masterdest, self.maxsize, self.mode)
-
- if self.keepstamp and self.slaveVersionIsOlderThan("uploadFile","2.13"):
- m = ("This buildslave (%s) does not support preserving timestamps. "
- "Please upgrade the buildslave." % self.build.slavename )
- raise BuildSlaveTooOldError(m)
-
- # default arguments
- args = {
- 'slavesrc': source,
- 'workdir': self._getWorkdir(),
- 'writer': fileWriter,
- 'maxsize': self.maxsize,
- 'blocksize': self.blocksize,
- 'keepstamp': self.keepstamp,
- }
-
- self.cmd = makeStatusRemoteCommand(self, 'uploadFile', args)
- d = self.runCommand(self.cmd)
- @d.addErrback
- def cancel(res):
- fileWriter.cancel()
- return res
- d.addCallback(self.finished).addErrback(self.failed)
-
-
-class DirectoryUpload(_TransferBuildStep):
-
- name = 'upload'
-
- renderables = [ 'slavesrc', 'masterdest', 'url' ]
-
- def __init__(self, slavesrc, masterdest,
- workdir=None, maxsize=None, blocksize=16*1024,
- compress=None, url=None, **buildstep_kwargs):
- BuildStep.__init__(self, **buildstep_kwargs)
-
- self.slavesrc = slavesrc
- self.masterdest = masterdest
- self.workdir = workdir
- self.maxsize = maxsize
- self.blocksize = blocksize
- if compress not in (None, 'gz', 'bz2'):
- config.error(
- "'compress' must be one of None, 'gz', or 'bz2'")
- self.compress = compress
- self.url = url
-
- def start(self):
- version = self.slaveVersion("uploadDirectory")
-
- if not version:
- m = "slave is too old, does not know about uploadDirectory"
- raise BuildSlaveTooOldError(m)
-
- source = self.slavesrc
- masterdest = self.masterdest
- # we rely upon the fact that the buildmaster runs chdir'ed into its
- # basedir to make sure that relative paths in masterdest are expanded
- # properly. TODO: maybe pass the master's basedir all the way down
- # into the BuildStep so we can do this better.
- masterdest = os.path.expanduser(masterdest)
- log.msg("DirectoryUpload started, from slave %r to master %r"
- % (source, masterdest))
-
- self.step_status.setText(['uploading', os.path.basename(source)])
- if self.url is not None:
- self.addURL(os.path.basename(masterdest), self.url)
-
- # we use maxsize to limit the amount of data on both sides
- dirWriter = _DirectoryWriter(masterdest, self.maxsize, self.compress, 0600)
-
- # default arguments
- args = {
- 'slavesrc': source,
- 'workdir': self._getWorkdir(),
- 'writer': dirWriter,
- 'maxsize': self.maxsize,
- 'blocksize': self.blocksize,
- 'compress': self.compress
- }
-
- self.cmd = makeStatusRemoteCommand(self, 'uploadDirectory', args)
- d = self.runCommand(self.cmd)
- @d.addErrback
- def cancel(res):
- dirWriter.cancel()
- return res
- d.addCallback(self.finished).addErrback(self.failed)
-
- def finished(self, result):
- # Subclasses may choose to skip a transfer. In those cases, self.cmd
- # will be None, and we should just let BuildStep.finished() handle
- # the rest
- if result == SKIPPED:
- return BuildStep.finished(self, SKIPPED)
-
- if self.cmd.didFail():
- return BuildStep.finished(self, FAILURE)
- return BuildStep.finished(self, SUCCESS)
-
-class _FileReader(pb.Referenceable):
- """
- Helper class that acts as a file-object with read access
- """
-
- def __init__(self, fp):
- self.fp = fp
-
- def remote_read(self, maxlength):
- """
- Called from remote slave to read at most L{maxlength} bytes of data
-
- @type maxlength: C{integer}
- @param maxlength: Maximum number of data bytes that can be returned
-
- @return: Data read from L{fp}
- @rtype: C{string} of bytes read from file
- """
- if self.fp is None:
- return ''
-
- data = self.fp.read(maxlength)
- return data
-
- def remote_close(self):
- """
- Called by remote slave to state that no more data will be transfered
- """
- if self.fp is not None:
- self.fp.close()
- self.fp = None
-
-
-class FileDownload(_TransferBuildStep):
-
- name = 'download'
-
- renderables = [ 'mastersrc', 'slavedest' ]
-
- def __init__(self, mastersrc, slavedest,
- workdir=None, maxsize=None, blocksize=16*1024, mode=None,
- **buildstep_kwargs):
- BuildStep.__init__(self, **buildstep_kwargs)
-
- self.mastersrc = mastersrc
- self.slavedest = slavedest
- self.workdir = workdir
- self.maxsize = maxsize
- self.blocksize = blocksize
- if not isinstance(mode, (int, type(None))):
- config.error(
- 'mode must be an integer or None')
- self.mode = mode
-
- def start(self):
- version = self.slaveVersion("downloadFile")
- if not version:
- m = "slave is too old, does not know about downloadFile"
- raise BuildSlaveTooOldError(m)
-
- # we are currently in the buildmaster's basedir, so any non-absolute
- # paths will be interpreted relative to that
- source = os.path.expanduser(self.mastersrc)
- slavedest = self.slavedest
- log.msg("FileDownload started, from master %r to slave %r" %
- (source, slavedest))
-
- self.step_status.setText(['downloading', "to",
- os.path.basename(slavedest)])
-
- # setup structures for reading the file
- try:
- fp = open(source, 'rb')
- except IOError:
- # if file does not exist, bail out with an error
- self.addCompleteLog('stderr',
- 'File %r not available at master' % source)
- # TODO: once BuildStep.start() gets rewritten to use
- # maybeDeferred, just re-raise the exception here.
- eventually(BuildStep.finished, self, FAILURE)
- return
- fileReader = _FileReader(fp)
-
- # default arguments
- args = {
- 'slavedest': slavedest,
- 'maxsize': self.maxsize,
- 'reader': fileReader,
- 'blocksize': self.blocksize,
- 'workdir': self._getWorkdir(),
- 'mode': self.mode,
- }
-
- self.cmd = makeStatusRemoteCommand(self, 'downloadFile', args)
- d = self.runCommand(self.cmd)
- d.addCallback(self.finished).addErrback(self.failed)
-
-class DirectoryDownload(_TransferBuildStep):
-
- name = 'download'
-
- renderables = [ 'mastersrc', 'slavedest' ]
-
- def __init__(self, mastersrc, slavedest,
- workdir=None, maxsize=None, blocksize=16*1024,
- compress=None, mode=None, **buildstep_kwargs):
- BuildStep.__init__(self, **buildstep_kwargs)
-
- self.mastersrc = mastersrc
- self.slavedest = slavedest
- self.workdir = workdir
- self.maxsize = maxsize
- self.blocksize = blocksize
- if compress not in (None, 'gz', 'bz2'):
- config.error(
- "'compress' must be one of None, 'gz', or 'bz2'")
- self.compress = compress
- self.mode = mode
-
- def start(self):
- version = self.slaveVersion("downloadDirectory")
-
- if not version:
- m = "slave is too old, does not know about downloadDirectory"
- raise BuildSlaveTooOldError(m)
-
- # we rely upon the fact that the buildmaster runs chdir'ed into its
- # basedir to make sure that relative paths in mastersrc are expanded
- # properly. TODO: maybe pass the master's basedir all the way down
- # into the BuildStep so we can do this better.
- source = os.path.expanduser(self.mastersrc)
-
- slavedest = self.slavedest
-
- log.msg("DirectoryDownload started, from master %r to slave %r"
- % (source, slavedest))
-
- self.step_status.setText(['downloading', "to", slavedest])
-
- # setup structures for reading the file
- try:
- fd, self.tarname = tempfile.mkstemp()
- fileobj = os.fdopen(fd, 'w')
- if self.compress == 'bz2':
- mode='w|bz2'
- elif self.compress == 'gz':
- mode='w|gz'
- else:
- mode = 'w'
- archive = tarfile.open(name=self.tarname, mode=mode, fileobj=fileobj)
- archive.add(source, '')
- archive.close()
- fileobj.close()
-
- fp = open(self.tarname, 'rb')
- except IOError:
- # if file does not exist, bail out with an error
- self.addCompleteLog('stderr',
- 'Directory %r not available at master' % source)
- # TODO: once BuildStep.start() gets rewritten to use
- # maybeDeferred, just re-raise the exception here.
- eventually(BuildStep.finished, self, FAILURE)
- return
-
- fileReader = _FileReader(fp)
-
- # default arguments
- args = {
- 'slavedest': slavedest,
- 'maxsize': self.maxsize,
- 'reader': fileReader,
- 'blocksize': self.blocksize,
- 'workdir': self._getWorkdir(),
- 'mode': self.mode,
- 'compress': self.compress,
- }
-
- self.cmd = makeStatusRemoteCommand(self, 'downloadDirectory', args)
- d = self.runCommand(self.cmd)
- d.addCallback(self.finished).addErrback(self.failed)
-
-class StringDownload(_TransferBuildStep):
-
- name = 'string_download'
-
- renderables = [ 'slavedest', 's' ]
-
- def __init__(self, s, slavedest,
- workdir=None, maxsize=None, blocksize=16*1024, mode=None,
- **buildstep_kwargs):
- BuildStep.__init__(self, **buildstep_kwargs)
-
- self.s = s
- self.slavedest = slavedest
- self.workdir = workdir
- self.maxsize = maxsize
- self.blocksize = blocksize
- if not isinstance(mode, (int, type(None))):
- config.error(
- 'mode must be an integer or None')
- self.mode = mode
-
- def start(self):
- version = self.slaveVersion("downloadFile")
- if not version:
- m = "slave is too old, does not know about downloadFile"
- raise BuildSlaveTooOldError(m)
-
- # we are currently in the buildmaster's basedir, so any non-absolute
- # paths will be interpreted relative to that
- slavedest = self.slavedest
- log.msg("StringDownload started, from master to slave %r" % slavedest)
-
- self.step_status.setText(['downloading', "to",
- os.path.basename(slavedest)])
-
- # setup structures for reading the file
- fp = StringIO(self.s)
- fileReader = _FileReader(fp)
-
- # default arguments
- args = {
- 'slavedest': slavedest,
- 'maxsize': self.maxsize,
- 'reader': fileReader,
- 'blocksize': self.blocksize,
- 'workdir': self._getWorkdir(),
- 'mode': self.mode,
- }
-
- self.cmd = makeStatusRemoteCommand(self, 'downloadFile', args)
- d = self.runCommand(self.cmd)
- d.addCallback(self.finished).addErrback(self.failed)
-
-class JSONStringDownload(StringDownload):
-
- name = "json_download"
-
- def __init__(self, o, slavedest, **buildstep_kwargs):
- if 's' in buildstep_kwargs:
- del buildstep_kwargs['s']
- s = json.dumps(o)
- StringDownload.__init__(self, s=s, slavedest=slavedest, **buildstep_kwargs)
-
-class JSONPropertiesDownload(StringDownload):
-
- name = "json_properties_download"
-
- def __init__(self, slavedest, **buildstep_kwargs):
- self.super_class = StringDownload
- if 's' in buildstep_kwargs:
- del buildstep_kwargs['s']
- StringDownload.__init__(self, s=None, slavedest=slavedest, **buildstep_kwargs)
-
- def start(self):
- properties = self.build.getProperties()
- props = {}
- for key, value, source in properties.asList():
- props[key] = value
-
- self.s = json.dumps(dict(
- properties=props,
- sourcestamp=self.build.getSourceStamp().asDict(),
- ),
- )
- return self.super_class.start(self)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/trigger.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/trigger.py
deleted file mode 100644
index 11f6078a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/trigger.py
+++ /dev/null
@@ -1,224 +0,0 @@
-# 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
-
-from buildbot.interfaces import ITriggerableScheduler
-from buildbot.process.buildstep import LoggingBuildStep, SUCCESS, FAILURE, EXCEPTION
-from buildbot.process.properties import Properties, Property
-from twisted.python import log
-from twisted.internet import defer
-from buildbot import config
-
-class Trigger(LoggingBuildStep):
- name = "trigger"
-
- renderables = [ 'set_properties', 'schedulerNames', 'sourceStamps',
- 'updateSourceStamp', 'alwaysUseLatest' ]
-
- flunkOnFailure = True
-
- def __init__(self, schedulerNames=[], sourceStamp = None, sourceStamps = None,
- updateSourceStamp=None, alwaysUseLatest=False,
- waitForFinish=False, set_properties={},
- copy_properties=[], noWait=[], **kwargs):
- if not schedulerNames:
- config.error(
- "You must specify a scheduler to trigger")
- if (sourceStamp or sourceStamps) and (updateSourceStamp is not None):
- config.error(
- "You can't specify both sourceStamps and updateSourceStamp")
- if (sourceStamp or sourceStamps) and alwaysUseLatest:
- config.error(
- "You can't specify both sourceStamps and alwaysUseLatest")
- if alwaysUseLatest and (updateSourceStamp is not None):
- config.error(
- "You can't specify both alwaysUseLatest and updateSourceStamp"
- )
- self.schedulerNames = schedulerNames
- self.noWait = noWait
- self.sourceStamps = sourceStamps or []
- if sourceStamp:
- self.sourceStamps.append(sourceStamp)
- if updateSourceStamp is not None:
- self.updateSourceStamp = updateSourceStamp
- else:
- self.updateSourceStamp = not (alwaysUseLatest or self.sourceStamps)
- self.alwaysUseLatest = alwaysUseLatest
- self.waitForFinish = waitForFinish
- properties = {}
- properties.update(set_properties)
- for i in copy_properties:
- properties[i] = Property(i)
- self.set_properties = properties
- self.running = False
- self.ended = False
- LoggingBuildStep.__init__(self, **kwargs)
-
- def interrupt(self, reason):
- if self.running and not self.ended:
- self.step_status.setText(["interrupted"])
- return self.end(EXCEPTION)
-
- def end(self, result):
- if not self.ended:
- self.ended = True
- return self.finished(result)
-
- # Create the properties that are used for the trigger
- def createTriggerProperties(self):
- # make a new properties object from a dict rendered by the old
- # properties object
- trigger_properties = Properties()
- trigger_properties.update(self.set_properties, "Trigger")
- for prop in trigger_properties.asDict():
- if prop not in self.set_properties:
- self.set_properties[prop] = Property(prop)
- return trigger_properties
-
- # Get all scheduler instances that were configured
- # A tuple of (triggerables, invalidnames) is returned
- def getSchedulers(self):
- all_schedulers = self.build.builder.botmaster.parent.allSchedulers()
- all_schedulers = dict([(sch.name, sch) for sch in all_schedulers])
- invalid_schedulers = []
- triggered_schedulers = []
- # don't fire any schedulers if we discover an unknown one
- for scheduler in self.schedulerNames:
- scheduler = scheduler
- if all_schedulers.has_key(scheduler):
- sch = all_schedulers[scheduler]
- if ITriggerableScheduler.providedBy(sch):
- triggered_schedulers.append(sch)
- else:
- invalid_schedulers.append(scheduler)
- else:
- invalid_schedulers.append(scheduler)
-
- return (triggered_schedulers, invalid_schedulers)
-
- def prepareSourcestampListForTrigger(self):
- if self.sourceStamps:
- ss_for_trigger = {}
- for ss in self.sourceStamps:
- codebase = ss.get('codebase','')
- assert codebase not in ss_for_trigger, "codebase specified multiple times"
- ss_for_trigger[codebase] = ss
- return ss_for_trigger
-
- if self.alwaysUseLatest:
- return {}
-
- # start with the sourcestamps from current build
- ss_for_trigger = {}
- objs_from_build = self.build.getAllSourceStamps()
- for ss in objs_from_build:
- ss_for_trigger[ss.codebase] = ss.asDict()
-
- # overrule revision in sourcestamps with got revision
- if self.updateSourceStamp:
- got = self.build.build_status.getAllGotRevisions()
- for codebase in ss_for_trigger:
- if codebase in got:
- ss_for_trigger[codebase]['revision'] = got[codebase]
-
- return ss_for_trigger
-
- @defer.inlineCallbacks
- def start(self):
- # Get all triggerable schedulers and check if there are invalid schedules
- (triggered_schedulers, invalid_schedulers) = self.getSchedulers()
- if invalid_schedulers:
- self.step_status.setText(['not valid scheduler:'] + invalid_schedulers)
- self.end(FAILURE)
- return
-
- self.running = True
-
- props_to_set = self.createTriggerProperties()
-
- ss_for_trigger = self.prepareSourcestampListForTrigger()
-
- dl = []
- nowait = []
- triggered_names = []
- for sch in triggered_schedulers:
- if sch.name in self.noWait:
- import time
- time.sleep(5)
- nowait.append(sch.trigger(ss_for_trigger, set_props=props_to_set))
- else:
- dl.append(sch.trigger(ss_for_trigger, set_props=props_to_set))
- triggered_names.append(sch.name)
- self.step_status.setText(['triggered'] + triggered_names)
-
- for d in nowait:
- d.addErrback(log.err,
- '(ignored) while invoking Triggerable schedulers:')
-
- if self.waitForFinish:
- rclist = yield defer.DeferredList(dl, consumeErrors=1)
- else:
- # do something to handle errors
- for d in dl:
- d.addErrback(log.err,
- '(ignored) while invoking Triggerable schedulers:')
- rclist = None
- self.end(SUCCESS)
- return
-
- was_exception = was_failure = False
- brids = {}
- for was_cb, results in rclist:
- if isinstance(results, tuple):
- results, some_brids = results
- brids.update(some_brids)
-
- if not was_cb:
- was_exception = True
- log.err(results)
- continue
-
- if results==FAILURE:
- was_failure = True
-
- if was_exception:
- result = EXCEPTION
- elif was_failure:
- result = FAILURE
- else:
- result = SUCCESS
-
- if brids:
- master = self.build.builder.botmaster.parent
- def add_links(res):
- # reverse the dictionary lookup for brid to builder name
- brid_to_bn = dict((_brid,_bn) for _bn,_brid in brids.iteritems())
-
- for was_cb, builddicts in res:
- if was_cb:
- for build in builddicts:
- bn = brid_to_bn[build['brid']]
- num = build['number']
-
- url = master.status.getURLForBuild(bn, num)
- self.step_status.addURL("%s #%d" % (bn,num), url)
-
- return self.end(result)
-
- builddicts = [master.db.builds.getBuildsForRequest(br) for br in brids.values()]
- dl = defer.DeferredList(builddicts, consumeErrors=1)
- dl.addCallback(add_links)
-
- self.end(result)
- return
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/vstudio.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/vstudio.py
deleted file mode 100644
index 5fad1f8d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/steps/vstudio.py
+++ /dev/null
@@ -1,408 +0,0 @@
-# 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
-
-# Visual studio steps
-
-from buildbot.steps.shell import ShellCommand
-from buildbot.process.buildstep import LogLineObserver
-from buildbot import config
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE
-
-import re
-
-
-def addEnvPath(env, name, value):
- """ concat a path for this name """
- try:
- oldval = env[name]
- if not oldval.endswith(';'):
- oldval = oldval + ';'
- except KeyError:
- oldval = ""
- if not value.endswith(';'):
- value = value + ';'
- env[name] = oldval + value
-
-class MSLogLineObserver(LogLineObserver):
-
- _re_delimiter = re.compile(r'^(\d+>)?-{5}.+-{5}$')
- _re_file = re.compile(r'^(\d+>)?[^ ]+\.(cpp|c)$')
- _re_warning = re.compile(r' ?: warning [A-Z]+[0-9]+:')
- _re_error = re.compile(r' ?error ([A-Z]+[0-9]+)?\s?: ')
-
- nbFiles = 0
- nbProjects = 0
- nbWarnings = 0
- nbErrors = 0
-
- logwarnings = None
- logerrors = None
-
- def __init__(self, logwarnings, logerrors, **kwargs):
- LogLineObserver.__init__(self, **kwargs)
- self.logwarnings = logwarnings
- self.logerrors = logerrors
- self.stdoutParser.delimiter = "\r\n"
- self.stderrParser.delimiter = "\r\n"
-
- def outLineReceived(self, line):
- if self._re_delimiter.search(line):
- self.nbProjects += 1
- self.logwarnings.addStdout("%s\n" % line)
- self.logerrors.addStdout("%s\n" % line)
- self.step.setProgress('projects', self.nbProjects)
- elif self._re_file.search(line):
- self.nbFiles += 1
- self.step.setProgress('files', self.nbFiles)
- elif self._re_warning.search(line):
- self.nbWarnings += 1
- self.logwarnings.addStdout("%s\n" % line)
- self.step.setProgress('warnings', self.nbWarnings)
- elif self._re_error.search("%s\n" % line):
- # error has no progress indication
- self.nbErrors += 1
- self.logerrors.addStderr("%s\n" % line)
-
-
-class VisualStudio(ShellCommand):
- # an *abstract* base class, which will not itself work as a buildstep
-
- name = "compile"
- description = "compiling"
- descriptionDone = "compile"
-
-
- progressMetrics = ( ShellCommand.progressMetrics +
- ('projects', 'files','warnings',))
-
- logobserver = None
-
- installdir = None
- default_installdir = None
-
- # One of build, or rebuild
- mode = "rebuild"
-
- projectfile = None
- config = None
- useenv = False
- project = None
- PATH = []
- INCLUDE = []
- LIB = []
-
- renderables = [ 'projectfile', 'config', 'project' ]
-
- def __init__(self,
- installdir = None,
- mode = "rebuild",
- projectfile = None,
- config = 'release',
- useenv = False,
- project = None,
- INCLUDE = [],
- LIB = [],
- PATH = [],
- **kwargs):
- self.installdir = installdir
- self.mode = mode
- self.projectfile = projectfile
- self.config = config
- self.useenv = useenv
- self.project = project
- if len(INCLUDE) > 0:
- self.INCLUDE = INCLUDE
- self.useenv = True
- if len(LIB) > 0:
- self.LIB = LIB
- self.useenv = True
- if len(PATH) > 0:
- self.PATH = PATH
- # always upcall !
- ShellCommand.__init__(self, **kwargs)
-
- def setupLogfiles(self, cmd, logfiles):
- logwarnings = self.addLog("warnings")
- logerrors = self.addLog("errors")
- self.logobserver = MSLogLineObserver(logwarnings, logerrors)
- self.addLogObserver('stdio', self.logobserver)
- ShellCommand.setupLogfiles(self, cmd, logfiles)
-
- def setupInstalldir(self):
- if not self.installdir:
- self.installdir = self.default_installdir
-
- def setupEnvironment(self, cmd):
- ShellCommand.setupEnvironment(self, cmd)
- if cmd.args['env'] is None:
- cmd.args['env'] = {}
-
- # setup the custom one, those one goes first
- for path in self.PATH:
- addEnvPath(cmd.args['env'], "PATH", path)
- for path in self.INCLUDE:
- addEnvPath(cmd.args['env'], "INCLUDE", path)
- for path in self.LIB:
- addEnvPath(cmd.args['env'], "LIB", path)
-
- self.setupInstalldir()
-
- def describe(self, done=False):
- description = ShellCommand.describe(self, done)
- if done:
- description.append('%d projects' % self.step_status.getStatistic('projects', 0))
- description.append('%d files' % self.step_status.getStatistic('files', 0))
- warnings = self.step_status.getStatistic('warnings', 0)
- if warnings > 0:
- description.append('%d warnings' % warnings)
- errors = self.step_status.getStatistic('errors', 0)
- if errors > 0:
- description.append('%d errors' % errors)
- return description
-
- def createSummary(self, log):
- self.step_status.setStatistic('projects', self.logobserver.nbProjects)
- self.step_status.setStatistic('files', self.logobserver.nbFiles)
- self.step_status.setStatistic('warnings', self.logobserver.nbWarnings)
- self.step_status.setStatistic('errors', self.logobserver.nbErrors)
-
- def evaluateCommand(self, cmd):
- if cmd.didFail():
- return FAILURE
- if self.logobserver.nbErrors > 0:
- return FAILURE
- if self.logobserver.nbWarnings > 0:
- return WARNINGS
- else:
- return SUCCESS
-
- def finished(self, result):
- self.getLog("warnings").finish()
- self.getLog("errors").finish()
- ShellCommand.finished(self, result)
-
-class VC6(VisualStudio):
-
- default_installdir = 'C:\\Program Files\\Microsoft Visual Studio'
-
- def setupEnvironment(self, cmd):
- VisualStudio.setupEnvironment(self, cmd)
-
- # Root of Visual Developer Studio Common files.
- VSCommonDir = self.installdir + '\\Common'
- MSVCDir = self.installdir + '\\VC98'
- MSDevDir = VSCommonDir + '\\msdev98'
-
- addEnvPath(cmd.args['env'], "PATH", MSDevDir + '\\BIN')
- addEnvPath(cmd.args['env'], "PATH", MSVCDir + '\\BIN')
- addEnvPath(cmd.args['env'], "PATH", VSCommonDir + '\\TOOLS\\WINNT')
- addEnvPath(cmd.args['env'], "PATH", VSCommonDir + '\\TOOLS')
-
- addEnvPath(cmd.args['env'], "INCLUDE", MSVCDir + '\\INCLUDE')
- addEnvPath(cmd.args['env'], "INCLUDE", MSVCDir + '\\ATL\\INCLUDE')
- addEnvPath(cmd.args['env'], "INCLUDE", MSVCDir + '\\MFC\\INCLUDE')
-
- addEnvPath(cmd.args['env'], "LIB", MSVCDir + '\\LIB')
- addEnvPath(cmd.args['env'], "LIB", MSVCDir + '\\MFC\\LIB')
-
- def start(self):
- command = ["msdev"]
- command.append(self.projectfile)
- command.append("/MAKE")
- if self.project is not None:
- command.append(self.project + " - " + self.config)
- else:
- command.append("ALL - " + self.config)
- if self.mode == "rebuild":
- command.append("/REBUILD")
- elif self.mode == "clean":
- command.append("/CLEAN")
- else:
- command.append("/BUILD")
- if self.useenv:
- command.append("/USEENV")
- self.setCommand(command)
- return VisualStudio.start(self)
-
-class VC7(VisualStudio):
- default_installdir = 'C:\\Program Files\\Microsoft Visual Studio .NET 2003'
-
- def setupEnvironment(self, cmd):
- VisualStudio.setupEnvironment(self, cmd)
-
- VSInstallDir = self.installdir + '\\Common7\\IDE'
- VCInstallDir = self.installdir
- MSVCDir = self.installdir + '\\VC7'
-
- addEnvPath(cmd.args['env'], "PATH", VSInstallDir)
- addEnvPath(cmd.args['env'], "PATH", MSVCDir + '\\BIN')
- addEnvPath(cmd.args['env'], "PATH", VCInstallDir + '\\Common7\\Tools')
- addEnvPath(cmd.args['env'], "PATH", VCInstallDir + '\\Common7\\Tools\\bin')
-
- addEnvPath(cmd.args['env'], "INCLUDE", MSVCDir + '\\INCLUDE')
- addEnvPath(cmd.args['env'], "INCLUDE", MSVCDir + '\\ATLMFC\\INCLUDE')
- addEnvPath(cmd.args['env'], "INCLUDE", MSVCDir + '\\PlatformSDK\\include')
- addEnvPath(cmd.args['env'], "INCLUDE", VCInstallDir + '\\SDK\\v1.1\\include')
-
- addEnvPath(cmd.args['env'], "LIB", MSVCDir + '\\LIB')
- addEnvPath(cmd.args['env'], "LIB", MSVCDir + '\\ATLMFC\\LIB')
- addEnvPath(cmd.args['env'], "LIB", MSVCDir + '\\PlatformSDK\\lib')
- addEnvPath(cmd.args['env'], "LIB", VCInstallDir + '\\SDK\\v1.1\\lib')
-
- def start(self):
- command = ["devenv.com"]
- command.append(self.projectfile)
- if self.mode == "rebuild":
- command.append("/Rebuild")
- elif self.mode == "clean":
- command.append("/Clean")
- else:
- command.append("/Build")
- command.append(self.config)
- if self.useenv:
- command.append("/UseEnv")
- if self.project is not None:
- command.append("/Project")
- command.append(self.project)
- self.setCommand(command)
- return VisualStudio.start(self)
-
-#alias VC7 as VS2003
-VS2003 = VC7
-
-class VC8(VC7):
-
- # Our ones
- arch = None
- default_installdir = 'C:\\Program Files\\Microsoft Visual Studio 8'
-
- renderables = ['arch']
-
- def __init__(self, arch = "x86", **kwargs):
- self.arch = arch
-
- # always upcall !
- VisualStudio.__init__(self, **kwargs)
-
- def setupEnvironment(self, cmd):
- VisualStudio.setupEnvironment(self, cmd)
-
- VSInstallDir = self.installdir
- VCInstallDir = self.installdir + '\\VC'
-
- addEnvPath(cmd.args['env'], "PATH", VSInstallDir + '\\Common7\\IDE')
- if self.arch == "x64":
- addEnvPath(cmd.args['env'], "PATH", VCInstallDir + '\\BIN\\x86_amd64')
- addEnvPath(cmd.args['env'], "PATH", VCInstallDir + '\\BIN')
- addEnvPath(cmd.args['env'], "PATH", VSInstallDir + '\\Common7\\Tools')
- addEnvPath(cmd.args['env'], "PATH", VSInstallDir + '\\Common7\\Tools\\bin')
- addEnvPath(cmd.args['env'], "PATH", VCInstallDir + '\\PlatformSDK\\bin')
- addEnvPath(cmd.args['env'], "PATH", VSInstallDir + '\\SDK\\v2.0\\bin')
- addEnvPath(cmd.args['env'], "PATH", VCInstallDir + '\\VCPackages')
- addEnvPath(cmd.args['env'], "PATH", r'${PATH}')
-
- addEnvPath(cmd.args['env'], "INCLUDE", VCInstallDir + '\\INCLUDE')
- addEnvPath(cmd.args['env'], "INCLUDE", VCInstallDir + '\\ATLMFC\\include')
- addEnvPath(cmd.args['env'], "INCLUDE", VCInstallDir + '\\PlatformSDK\\include')
-
- archsuffix = ''
- if self.arch == "x64":
- archsuffix = '\\amd64'
- addEnvPath(cmd.args['env'], "LIB", VCInstallDir + '\\LIB' + archsuffix)
- addEnvPath(cmd.args['env'], "LIB", VCInstallDir + '\\ATLMFC\\LIB' + archsuffix)
- addEnvPath(cmd.args['env'], "LIB", VCInstallDir + '\\PlatformSDK\\lib' + archsuffix)
- addEnvPath(cmd.args['env'], "LIB", VSInstallDir + '\\SDK\\v2.0\\lib' + archsuffix)
-
-#alias VC8 as VS2005
-VS2005 = VC8
-
-class VCExpress9(VC8):
- def start(self):
- command = ["vcexpress"]
- command.append(self.projectfile)
- if self.mode == "rebuild":
- command.append("/Rebuild")
- elif self.mode == "clean":
- command.append("/Clean")
- else:
- command.append("/Build")
- command.append(self.config)
- if self.useenv:
- command.append("/UseEnv")
- if self.project is not None:
- command.append("/Project")
- command.append(self.project)
- self.setCommand(command)
- return VisualStudio.start(self)
-
-# Add first support for VC9 (Same as VC8, with a different installdir)
-class VC9(VC8):
- default_installdir = 'C:\\Program Files\\Microsoft Visual Studio 9.0'
-
-VS2008 = VC9
-
-# VC10 doesn't look like it needs extra stuff.
-class VC10(VC9):
- default_installdir = 'C:\\Program Files\\Microsoft Visual Studio 10.0'
-
-VS2010 = VC10
-
-# VC11 doesn't look like it needs extra stuff.
-class VC11(VC10):
- default_installdir = 'C:\\Program Files\\Microsoft Visual Studio 11.0'
-
-VS2012 = VC11
-
-class MsBuild(VisualStudio):
- platform = None
-
- def __init__(self, platform, **kwargs):
- self.platform = platform
- VisualStudio.__init__(self, **kwargs)
-
- def setupEnvironment(self, cmd):
- VisualStudio.setupEnvironment(self, cmd)
- cmd.args['env']['VCENV_BAT'] = "\"${VS110COMNTOOLS}..\\..\\VC\\vcvarsall.bat\""
-
- def describe(self, done=False):
- rv = []
- if done:
- rv.append("built")
- else:
- rv.append("building")
- if self.project is not None:
- rv.append("%s for" % (self.project))
- else:
- rv.append("solution for")
- rv.append("%s|%s" % (self.config, self.platform))
- return rv
-
- def start(self):
- if self.platform is None:
- config.error('platform is mandatory. Please specify a string such as "Win32"')
-
- command = ["%VCENV_BAT%",
- "x86",
- "&&",
- "msbuild",
- self.projectfile,
- "/p:Configuration=%s" % (self.config),
- "/p:Platform=%s" % (self.platform)]
- if self.project is not None:
- command.append("/t:%s" % (self.project))
-
- self.setCommand(command)
-
- return VisualStudio.start(self)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/__init__.py
deleted file mode 100644
index 6812758b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/__init__.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# 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
-
-# apply the same patches the buildmaster does when it starts
-from buildbot import monkeypatches
-monkeypatches.patch_all(for_tests=True)
-
-# import mock so we bail out early if it's not installed
-try:
- import mock
- mock = mock
-except ImportError:
- raise ImportError("Buildbot tests require the 'mock' module; "
- "try 'pip install mock'")
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/botmaster.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/botmaster.py
deleted file mode 100644
index f04a2a79..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/botmaster.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# 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
-
-from twisted.application import service
-
-class FakeBotMaster(service.MultiService):
- def __init__(self, master):
- service.MultiService.__init__(self)
- self.setName("fake-botmaster")
- self.master = master
- self.locks = {}
-
- def getLockByID(self, lockid):
- if not lockid in self.locks:
- self.locks[lockid] = lockid.lockClass(lockid)
- # if the master.cfg file has changed maxCount= on the lock, the next
- # time a build is started, they'll get a new RealLock instance. Note
- # that this requires that MasterLock and SlaveLock (marker) instances
- # be hashable and that they should compare properly.
- return self.locks[lockid]
-
- def getLockFromLockAccess(self, access):
- return self.getLockByID(access.lockid)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakebuild.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakebuild.py
deleted file mode 100644
index 02f45717..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakebuild.py
+++ /dev/null
@@ -1,57 +0,0 @@
-# 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 mock
-import posixpath
-from twisted.python import components
-from buildbot.process import properties
-from buildbot import interfaces
-
-class FakeBuildStatus(properties.PropertiesMixin, mock.Mock):
-
- # work around http://code.google.com/p/mock/issues/detail?id=105
- def _get_child_mock(self, **kw):
- return mock.Mock(**kw)
-
- def getInterestedUsers(self):
- return []
-
-components.registerAdapter(
- lambda build_status : build_status.properties,
- FakeBuildStatus, interfaces.IProperties)
-
-
-class FakeBuild(properties.PropertiesMixin):
-
- def __init__(self, props=None):
- self.build_status = FakeBuildStatus()
- self.builder = mock.Mock(name='build.builder')
- self.path_module = posixpath
-
- self.sources = {}
- if props is None:
- props = properties.Properties()
- props.build = self
- self.build_status.properties = props
-
- def getSourceStamp(self, codebase):
- if codebase in self.sources:
- return self.sources[codebase]
- return None
-
-
-components.registerAdapter(
- lambda build : build.build_status.properties,
- FakeBuild, interfaces.IProperties)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakedb.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakedb.py
deleted file mode 100644
index db9b409c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakedb.py
+++ /dev/null
@@ -1,1224 +0,0 @@
-# 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
-
-"""
-A complete re-implementation of the database connector components, but without
-using a database. These classes should pass the same tests as are applied to
-the real connector components.
-"""
-
-import base64
-from buildbot.util import json, epoch2datetime, datetime2epoch
-from twisted.python import failure
-from twisted.internet import defer, reactor
-from buildbot.db import buildrequests
-
-# Fake DB Rows
-
-class Row(object):
- """
- Parent class for row classes, which are used to specify test data for
- database-related tests.
-
- @cvar defaults: default values for columns
- @type defaults: dictionary
-
- @cvar table: the table name
-
- @cvar id_column: specify a column that should be assigned an
- auto-incremented id. Auto-assigned id's begin at 1000, so any explicitly
- specified ID's should be less than 1000.
-
- @cvar required_columns: a tuple of columns that must be given in the
- constructor
-
- @ivar values: the values to be inserted into this row
- """
-
- id_column = ()
- required_columns = ()
- lists = ()
- dicts = ()
-
- def __init__(self, **kwargs):
- self.values = self.defaults.copy()
- self.values.update(kwargs)
- if self.id_column:
- if self.values[self.id_column] is None:
- self.values[self.id_column] = self.nextId()
- for col in self.required_columns:
- assert col in kwargs, "%s not specified" % col
- for col in self.lists:
- setattr(self, col, [])
- for col in self.dicts:
- setattr(self, col, {})
- for col in kwargs.keys():
- assert col in self.defaults, "%s is not a valid column" % col
- # make the values appear as attributes
- self.__dict__.update(self.values)
-
- def nextId(self):
- if not hasattr(self.__class__, '_next_id'):
- self.__class__._next_id = 1000
- else:
- self.__class__._next_id += 1
- return self.__class__._next_id
-
-
-class BuildRequest(Row):
- table = "buildrequests"
-
- defaults = dict(
- id = None,
- buildsetid = None,
- buildername = "bldr",
- priority = 0,
- complete = 0,
- results = -1,
- submitted_at = 0,
- complete_at = 0,
- )
-
- id_column = 'id'
- required_columns = ('buildsetid',)
-
-
-class BuildRequestClaim(Row):
- table = "buildrequest_claims"
-
- defaults = dict(
- brid = None,
- objectid = None,
- claimed_at = None
- )
-
- required_columns = ('brid', 'objectid', 'claimed_at')
-
-
-class Change(Row):
- table = "changes"
-
- defaults = dict(
- changeid = None,
- author = 'frank',
- comments = 'test change',
- is_dir = 0,
- branch = 'master',
- revision = 'abcd',
- revlink = 'http://vc/abcd',
- when_timestamp = 1200000,
- category = 'cat',
- repository = 'repo',
- codebase = '',
- project = 'proj',
- )
-
- lists = ('files',)
- dicts = ('properties',)
- id_column = 'changeid'
-
-
-class ChangeFile(Row):
- table = "change_files"
-
- defaults = dict(
- changeid = None,
- filename = None,
- )
-
- required_columns = ('changeid',)
-
-
-class ChangeProperty(Row):
- table = "change_properties"
-
- defaults = dict(
- changeid = None,
- property_name = None,
- property_value = None,
- )
-
- required_columns = ('changeid',)
-
-class ChangeUser(Row):
- table = "change_users"
-
- defaults = dict(
- changeid = None,
- uid = None,
- )
-
- required_columns = ('changeid',)
-
-class Patch(Row):
- table = "patches"
-
- defaults = dict(
- id = None,
- patchlevel = 0,
- patch_base64 = 'aGVsbG8sIHdvcmxk', # 'hello, world',
- patch_author = None,
- patch_comment = None,
- subdir = None,
- )
-
- id_column = 'id'
-
-
-class SourceStampChange(Row):
- table = "sourcestamp_changes"
-
- defaults = dict(
- sourcestampid = None,
- changeid = None,
- )
-
- required_columns = ('sourcestampid', 'changeid')
-
-class SourceStampSet(Row):
- table = "sourcestampsets"
- defaults = dict(
- id = None,
- )
- id_column = 'id'
-
-class SourceStamp(Row):
- table = "sourcestamps"
-
- defaults = dict(
- id = None,
- branch = 'master',
- revision = 'abcd',
- patchid = None,
- repository = 'repo',
- codebase = '',
- project = 'proj',
- sourcestampsetid = None,
- )
-
- id_column = 'id'
-
-
-class SchedulerChange(Row):
- table = "scheduler_changes"
-
- defaults = dict(
- objectid = None,
- changeid = None,
- important = 1,
- )
-
- required_columns = ( 'objectid', 'changeid' )
-
-
-class Buildset(Row):
- table = "buildsets"
-
- defaults = dict(
- id = None,
- external_idstring = 'extid',
- reason = 'because',
- sourcestampsetid = None,
- submitted_at = 12345678,
- complete = 0,
- complete_at = None,
- results = -1,
- )
-
- id_column = 'id'
- required_columns = ( 'sourcestampsetid', )
-
-
-class BuildsetProperty(Row):
- table = "buildset_properties"
-
- defaults = dict(
- buildsetid = None,
- property_name = 'prop',
- property_value = '[22, "fakedb"]',
- )
-
- required_columns = ( 'buildsetid', )
-
-
-class Object(Row):
- table = "objects"
-
- defaults = dict(
- id = None,
- name = 'nam',
- class_name = 'cls',
- )
-
- id_column = 'id'
-
-
-class ObjectState(Row):
- table = "object_state"
-
- defaults = dict(
- objectid = None,
- name = 'nam',
- value_json = '{}',
- )
-
- required_columns = ( 'objectid', )
-
-class User(Row):
- table = "users"
-
- defaults = dict(
- uid = None,
- identifier = 'soap',
- bb_username = None,
- bb_password = None,
- )
-
- id_column = 'uid'
-
-class UserInfo(Row):
- table = "users_info"
-
- defaults = dict(
- uid = None,
- attr_type = 'git',
- attr_data = 'Tyler Durden <tyler@mayhem.net>',
- )
-
- required_columns = ( 'uid', )
-
-class Build(Row):
- table = "builds"
-
- defaults = dict(
- id = None,
- number = 29,
- brid = 39,
- start_time = 1304262222,
- finish_time = None)
-
- id_column = 'id'
-
-# Fake DB Components
-
-# TODO: test these using the same test methods as are used against the real
-# database
-
-class FakeDBComponent(object):
-
- def __init__(self, db, testcase):
- self.db = db
- self.t = testcase
- self.setUp()
-
-
-class FakeChangesComponent(FakeDBComponent):
-
- def setUp(self):
- self.changes = {}
-
- def insertTestData(self, rows):
- for row in rows:
- if isinstance(row, Change):
- self.changes[row.changeid] = row
-
- elif isinstance(row, ChangeFile):
- ch = self.changes[row.changeid]
- ch.files.append(row.filename)
-
- elif isinstance(row, ChangeProperty):
- ch = self.changes[row.changeid]
- n, vs = row.property_name, row.property_value
- v, s = json.loads(vs)
- ch.properties.setProperty(n, v, s)
-
- elif isinstance(row, ChangeUser):
- ch = self.changes[row.changeid]
- ch.uid = row.uid
-
- # component methods
-
- def addChange(self, author=None, files=None, comments=None, is_dir=0,
- revision=None, when_timestamp=None, branch=None,
- category=None, revlink='', properties={}, repository='',
- project='', codebase='', uid=None):
- if self.changes:
- changeid = max(self.changes.iterkeys()) + 1
- else:
- changeid = 500
-
- self.changes[changeid] = ch = Change(
- changeid=changeid,
- author=author,
- comments=comments,
- is_dir=is_dir,
- revision=revision,
- when_timestamp=datetime2epoch(when_timestamp),
- branch=branch,
- category=category,
- revlink=revlink,
- repository=repository,
- project=project,
- codebase=codebase)
- ch.files = files
- ch.properties = properties
-
- return defer.succeed(changeid)
-
- def getLatestChangeid(self):
- if self.changes:
- return defer.succeed(max(self.changes.iterkeys()))
- return defer.succeed(None)
-
- def getChange(self, changeid):
- try:
- row = self.changes[changeid]
- except KeyError:
- return defer.succeed(None)
-
- chdict = dict(
- changeid=row.changeid,
- author=row.author,
- files=row.files,
- comments=row.comments,
- is_dir=row.is_dir,
- revision=row.revision,
- when_timestamp=epoch2datetime(row.when_timestamp),
- branch=row.branch,
- category=row.category,
- revlink=row.revlink,
- properties=row.properties,
- repository=row.repository,
- codebase=row.codebase,
- project=row.project)
-
- return defer.succeed(chdict)
-
- def getChangeUids(self, changeid):
- try:
- ch_uids = [self.changes[changeid].uid]
- except KeyError:
- ch_uids = []
- return defer.succeed(ch_uids)
-
- # TODO: getRecentChanges
-
- # fake methods
-
- def fakeAddChangeInstance(self, change):
- if not hasattr(change, 'number') or not change.number:
- if self.changes:
- changeid = max(self.changes.iterkeys()) + 1
- else:
- changeid = 500
- else:
- changeid = change.number
-
- # make a row from the change
- row = dict(
- changeid=changeid,
- author=change.who,
- files=change.files,
- comments=change.comments,
- is_dir=change.isdir,
- revision=change.revision,
- when_timestamp=change.when,
- branch=change.branch,
- category=change.category,
- revlink=change.revlink,
- properties=change.properties,
- repository=change.repository,
- codebase=change.codebase,
- project=change.project)
- self.changes[changeid] = row
-
-class FakeSchedulersComponent(FakeDBComponent):
-
- def setUp(self):
- self.states = {}
- self.classifications = {}
-
- def insertTestData(self, rows):
- for row in rows:
- if isinstance(row, SchedulerChange):
- cls = self.classifications.setdefault(row.objectid, {})
- cls[row.changeid] = row.important
-
- # component methods
-
- def classifyChanges(self, objectid, classifications):
- self.classifications.setdefault(objectid, {}).update(classifications)
- return defer.succeed(None)
-
- def flushChangeClassifications(self, objectid, less_than=None):
- if less_than is not None:
- classifications = self.classifications.setdefault(objectid, {})
- for changeid in classifications.keys():
- if changeid < less_than:
- del classifications[changeid]
- else:
- self.classifications[objectid] = {}
- return defer.succeed(None)
-
- def getChangeClassifications(self, objectid, branch=-1, repository=-1,
- project=-1, codebase=-1):
- classifications = self.classifications.setdefault(objectid, {})
-
- sentinel = dict(branch=object(), repository=object(),
- project=object(), codebase=object())
-
- if branch != -1:
- # filter out the classifications for the requested branch
- classifications = dict(
- (k,v) for (k,v) in classifications.iteritems()
- if self.db.changes.changes.get(k, sentinel)['branch'] == branch )
-
- if repository != -1:
- # filter out the classifications for the requested branch
- classifications = dict(
- (k,v) for (k,v) in classifications.iteritems()
- if self.db.changes.changes.get(k, sentinel)['repository'] == repository )
-
- if project != -1:
- # filter out the classifications for the requested branch
- classifications = dict(
- (k,v) for (k,v) in classifications.iteritems()
- if self.db.changes.changes.get(k, sentinel)['project'] == project )
-
- if codebase != -1:
- # filter out the classifications for the requested branch
- classifications = dict(
- (k,v) for (k,v) in classifications.iteritems()
- if self.db.changes.changes.get(k, sentinel)['codebase'] == codebase )
-
- return defer.succeed(classifications)
-
- # fake methods
-
- def fakeClassifications(self, objectid, classifications):
- """Set the set of classifications for a scheduler"""
- self.classifications[objectid] = classifications
-
- # assertions
-
- def assertClassifications(self, objectid, classifications):
- self.t.assertEqual(
- self.classifications.get(objectid, {}),
- classifications)
-
-
-class FakeSourceStampSetsComponent(FakeDBComponent):
- def setUp(self):
- self.sourcestampsets = {}
-
- def insertTestData(self, rows):
- for row in rows:
- if isinstance(row, SourceStampSet):
- self.sourcestampsets[row.id] = dict()
-
- def addSourceStampSet(self):
- id = len(self.sourcestampsets) + 100
- while id in self.sourcestampsets:
- id += 1
- self.sourcestampsets[id] = dict()
- return defer.succeed(id)
-
-class FakeSourceStampsComponent(FakeDBComponent):
-
- def setUp(self):
- self.sourcestamps = {}
- self.patches = {}
-
- def insertTestData(self, rows):
- for row in rows:
- if isinstance(row, Patch):
- self.patches[row.id] = dict(
- patch_level=row.patchlevel,
- patch_body=base64.b64decode(row.patch_base64),
- patch_author=row.patch_author,
- patch_comment=row.patch_comment,
- patch_subdir=row.subdir)
-
- for row in rows:
- if isinstance(row, SourceStamp):
- ss = self.sourcestamps[row.id] = row.values.copy()
- ss['changeids'] = set()
-
- for row in rows:
- if isinstance(row, SourceStampChange):
- ss = self.sourcestamps[row.sourcestampid]
- ss['changeids'].add(row.changeid)
-
- # component methods
-
- def addSourceStamp(self, branch, revision, repository, project, sourcestampsetid,
- codebase = '', patch_body=None, patch_level=0, patch_author=None,
- patch_comment=None, patch_subdir=None, changeids=[]):
- id = len(self.sourcestamps) + 100
- while id in self.sourcestamps:
- id += 1
-
- changeids = set(changeids)
-
- if patch_body:
- patchid = len(self.patches) + 100
- while patchid in self.patches:
- patchid += 1
- self.patches[patchid] = dict(
- patch_level=patch_level,
- patch_body=patch_body,
- patch_subdir=patch_subdir,
- patch_author=patch_author,
- patch_comment=patch_comment
- )
- else:
- patchid = None
-
- self.sourcestamps[id] = dict(id=id, sourcestampsetid=sourcestampsetid, branch=branch, revision=revision, codebase=codebase,
- patchid=patchid, repository=repository, project=project,
- changeids=changeids)
- return defer.succeed(id)
-
- def getSourceStamp(self, ssid):
- return defer.succeed(self._getSourceStamp(ssid))
-
- def _getSourceStamp(self, ssid):
- if ssid in self.sourcestamps:
- ssdict = self.sourcestamps[ssid].copy()
- del ssdict['id']
- ssdict['ssid'] = ssid
- patchid = ssdict['patchid']
- if patchid:
- ssdict.update(self.patches[patchid])
- else:
- ssdict['patch_body'] = None
- ssdict['patch_level'] = None
- ssdict['patch_subdir'] = None
- ssdict['patch_author'] = None
- ssdict['patch_comment'] = None
- del ssdict['patchid']
- return ssdict
- else:
- return None
-
- def getSourceStamps(self, sourcestampsetid):
- sslist = []
- for ssdict in self.sourcestamps.itervalues():
- if ssdict['sourcestampsetid'] == sourcestampsetid:
- ssdictcpy = self._getSourceStamp(ssdict['id'])
- sslist.append(ssdictcpy)
- return defer.succeed(sslist)
-
-class FakeBuildsetsComponent(FakeDBComponent):
-
- def setUp(self):
- self.buildsets = {}
- self.completed_bsids = set()
- self.buildset_subs = []
-
- def insertTestData(self, rows):
- for row in rows:
- if isinstance(row, Buildset):
- bs = self.buildsets[row.id] = row.values.copy()
- bs['properties'] = {}
-
- for row in rows:
- if isinstance(row, BuildsetProperty):
- assert row.buildsetid in self.buildsets
- n = row.property_name
- v, src = tuple(json.loads(row.property_value))
- self.buildsets[row.buildsetid]['properties'][n] = (v, src)
-
- # component methods
-
- def _newBsid(self):
- bsid = 200
- while bsid in self.buildsets:
- bsid += 1
- return bsid
-
- def addBuildset(self, sourcestampsetid, reason, properties, builderNames,
- external_idstring=None, _reactor=reactor):
- bsid = self._newBsid()
- br_rows = []
- for buildername in builderNames:
- br_rows.append(
- BuildRequest(buildsetid=bsid, buildername=buildername))
- self.db.buildrequests.insertTestData(br_rows)
-
- # make up a row and keep its dictionary, with the properties tacked on
- bsrow = Buildset(sourcestampsetid=sourcestampsetid, reason=reason, external_idstring=external_idstring)
- self.buildsets[bsid] = bsrow.values.copy()
- self.buildsets[bsid]['properties'] = properties
-
- return defer.succeed((bsid,
- dict([ (br.buildername, br.id) for br in br_rows ])))
-
- def completeBuildset(self, bsid, results, complete_at=None,
- _reactor=reactor):
- self.buildsets[bsid]['results'] = results
- self.buildsets[bsid]['complete'] = 1
- self.buildsets[bsid]['complete_at'] = complete_at or _reactor.seconds()
- return defer.succeed(None)
-
- def getBuildset(self, bsid):
- if bsid not in self.buildsets:
- return defer.succeed(None)
- row = self.buildsets[bsid]
- return defer.succeed(self._row2dict(row))
-
- def getBuildsets(self, complete=None):
- rv = []
- for bs in self.buildsets.itervalues():
- if complete is not None:
- if complete and bs['complete']:
- rv.append(self._row2dict(bs))
- elif not complete and not bs['complete']:
- rv.append(self._row2dict(bs))
- else:
- rv.append(self._row2dict(bs))
- return defer.succeed(rv)
-
- def _row2dict(self, row):
- row = row.copy()
- if row['complete_at']:
- row['complete_at'] = epoch2datetime(row['complete_at'])
- else:
- row['complete_at'] = None
- row['submitted_at'] = row['submitted_at'] and \
- epoch2datetime(row['submitted_at'])
- row['complete'] = bool(row['complete'])
- row['bsid'] = row['id']
- del row['id']
- return row
-
- def getBuildsetProperties(self, buildsetid):
- if buildsetid in self.buildsets:
- return defer.succeed(
- self.buildsets[buildsetid]['properties'])
- else:
- return defer.succeed({})
-
- # fake methods
-
- def fakeBuildsetCompletion(self, bsid, result):
- assert bsid in self.buildsets
- self.buildsets[bsid]['results'] = result
- self.completed_bsids.add(bsid)
-
- def flushBuildsets(self):
- """
- Flush the set of buildsets, for example after C{assertBuildset}
- """
- self.buildsets = {}
- self.completed_bsids = set()
-
- # assertions
-
- def assertBuildsets(self, count):
- """Assert that exactly COUNT buildsets were added"""
- self.t.assertEqual(len(self.buildsets), count,
- "buildsets are %r" % (self.buildsets,))
-
- def assertBuildset(self, bsid, expected_buildset, expected_sourcestamps):
- """Assert that the buildset and its attached sourcestamp look as
- expected; the ssid parameter of the buildset is omitted. Properties
- are converted with asList and sorted. Sourcestamp patches are inlined
- (patch_body, patch_level, patch_subdir), and changeids are represented
- as a set, but omitted if empty. If bsid is '?', then assert there is
- only one new buildset, and use that."""
- if bsid == '?':
- self.assertBuildsets(1)
- bsid = self.buildsets.keys()[0]
- else:
- self.t.assertIn(bsid, self.buildsets)
-
- buildset = self.buildsets[bsid].copy()
-
- dictOfssDict= {}
- for sourcestamp in self.db.sourcestamps.sourcestamps.itervalues():
- if sourcestamp['sourcestampsetid'] == buildset['sourcestampsetid']:
- ssdict = sourcestamp.copy()
- ss_repository = ssdict['codebase']
- dictOfssDict[ss_repository] = ssdict
-
- if 'id' in buildset:
- del buildset['id']
-
- # clear out some columns if the caller doesn't care
- for col in 'complete complete_at submitted_at results'.split():
- if col not in expected_buildset:
- del buildset[col]
-
- if buildset['properties']:
- buildset['properties'] = sorted(buildset['properties'].items())
-
- # only add brids if we're expecting them (sometimes they're unknown)
- if 'brids' in expected_buildset:
- buildset['brids'] = self.allBuildRequests(bsid)
-
- if 'builders' in expected_buildset:
- buildset['builders'] = self.allBuildRequests(bsid).keys()
-
- for ss in dictOfssDict.itervalues():
- if 'id' in ss:
- del ss['id']
- if not ss['changeids']:
- del ss['changeids']
-
- # incorporate patch info if we have it
- if 'patchid' in ss and ss['patchid']:
- ss.update(self.db.sourcestamps.patches[ss['patchid']])
- del ss['patchid']
-
- self.t.assertEqual(
- dict(buildset=buildset, sourcestamps=dictOfssDict),
- dict(buildset=expected_buildset, sourcestamps=expected_sourcestamps))
- return bsid
-
- def allBuildsetIds(self):
- return self.buildsets.keys()
-
- def allBuildRequests(self, bsid=None):
- if bsid is not None:
- is_same_bsid = lambda br: br.buildsetid==bsid
- else:
- is_same_bsid = lambda br: True
- return dict([ (br.buildername, br.id)
- for br in self.db.buildrequests.reqs.values()
- if is_same_bsid(br) ])
-
-
-class FakeStateComponent(FakeDBComponent):
-
- def setUp(self):
- self.objects = {}
- self.states = {}
-
- def insertTestData(self, rows):
- for row in rows:
- if isinstance(row, Object):
- self.objects[(row.name, row.class_name)] = row.id
- self.states[row.id] = {}
-
- for row in rows:
- if isinstance(row, ObjectState):
- assert row.objectid in self.objects.values()
- self.states[row.objectid][row.name] = row.value_json
-
- # component methods
-
- def _newId(self):
- id = 100
- while id in self.states:
- id += 1
- return id
-
- def getObjectId(self, name, class_name):
- try:
- id = self.objects[(name, class_name)]
- except:
- # invent a new id and add it
- id = self.objects[(name, class_name)] = self._newId()
- self.states[id] = {}
- return defer.succeed(id)
-
- def getState(self, objectid, name, default=object):
- try:
- json_value = self.states[objectid][name]
- except KeyError:
- if default is not object:
- return defer.succeed(default)
- raise
- return defer.succeed(json.loads(json_value))
-
- def setState(self, objectid, name, value):
- self.states[objectid][name] = json.dumps(value)
- return defer.succeed(None)
-
- # fake methods
-
- def fakeState(self, name, class_name, **kwargs):
- id = self.objects[(name, class_name)] = self._newId()
- self.objects[(name, class_name)] = id
- self.states[id] = dict( (k, json.dumps(v))
- for k,v in kwargs.iteritems() )
- return id
-
- # assertions
-
- def assertState(self, objectid, missing_keys=[], **kwargs):
- state = self.states[objectid]
- for k in missing_keys:
- self.t.assertFalse(k in state, "%s in %s" % (k, state))
- for k,v in kwargs.iteritems():
- self.t.assertIn(k, state)
- self.t.assertEqual(json.loads(state[k]), v,
- "state is %r" % (state,))
-
- def assertStateByClass(self, name, class_name, **kwargs):
- objectid = self.objects[(name, class_name)]
- state = self.states[objectid]
- for k,v in kwargs.iteritems():
- self.t.assertIn(k, state)
- self.t.assertEqual(json.loads(state[k]), v,
- "state is %r" % (state,))
-
-
-class FakeBuildRequestsComponent(FakeDBComponent):
-
- # for use in determining "my" requests
- MASTER_ID = 824
-
- # override this to set reactor.seconds
- _reactor = reactor
-
- def setUp(self):
- self.reqs = {}
- self.claims = {}
-
- def insertTestData(self, rows):
- for row in rows:
- if isinstance(row, BuildRequest):
- self.reqs[row.id] = row
-
- if isinstance(row, BuildRequestClaim):
- self.claims[row.brid] = row
-
- # component methods
-
- def getBuildRequest(self, brid):
- try:
- return defer.succeed(self._brdictFromRow(self.reqs[brid]))
- except:
- return defer.succeed(None)
-
- def getBuildRequests(self, buildername=None, complete=None, claimed=None,
- bsid=None):
- rv = []
- for br in self.reqs.itervalues():
- if buildername and br.buildername != buildername:
- continue
- if complete is not None:
- if complete and not br.complete:
- continue
- if not complete and br.complete:
- continue
- if claimed is not None:
- claim_row = self.claims.get(br.id)
- if claimed == "mine":
- if not claim_row or claim_row.objectid != self.MASTER_ID:
- continue
- elif claimed:
- if not claim_row:
- continue
- else:
- if claim_row:
- continue
- if bsid is not None:
- if br.buildsetid != bsid:
- continue
- rv.append(self._brdictFromRow(br))
- return defer.succeed(rv)
-
- def claimBuildRequests(self, brids, claimed_at=None):
- for brid in brids:
- if brid not in self.reqs or brid in self.claims:
- return defer.fail(
- failure.Failure(buildrequests.AlreadyClaimedError))
-
- claimed_at = datetime2epoch(claimed_at)
- if not claimed_at:
- claimed_at = self._reactor.seconds()
-
- # now that we've thrown any necessary exceptions, get started
- for brid in brids:
- self.claims[brid] = BuildRequestClaim(brid=brid,
- objectid=self.MASTER_ID, claimed_at=claimed_at)
- return defer.succeed(None)
-
- def reclaimBuildRequests(self, brids):
- for brid in brids:
- if brid not in self.claims:
- print "trying to reclaim brid %d, but it's not claimed" % brid
- return defer.fail(
- failure.Failure(buildrequests.AlreadyClaimedError))
- # now that we've thrown any necessary exceptions, get started
- for brid in brids:
- self.claims[brid] = BuildRequestClaim(brid=brid,
- objectid=self.MASTER_ID, claimed_at=self._reactor.seconds())
- return defer.succeed(None)
-
- def unclaimBuildRequests(self, brids):
- for brid in brids:
- try:
- self.claims.pop(brid)
- except KeyError:
- print "trying to unclaim brid %d, but it's not claimed" % brid
- return defer.fail(
- failure.Failure(buildrequests.AlreadyClaimedError))
-
- return defer.succeed(None)
-
- # Code copied from buildrequests.BuildRequestConnectorComponent
- def _brdictFromRow(self, row):
- claimed = mine = False
- claimed_at = None
- claim_row = self.claims.get(row.id, None)
- if claim_row:
- claimed = True
- claimed_at = claim_row.claimed_at
- mine = claim_row.objectid == self.MASTER_ID
-
- submitted_at = epoch2datetime(row.submitted_at)
- complete_at = epoch2datetime(row.complete_at)
-
- return dict(brid=row.id, buildsetid=row.buildsetid,
- buildername=row.buildername, priority=row.priority,
- claimed=claimed, claimed_at=claimed_at, mine=mine,
- complete=bool(row.complete), results=row.results,
- submitted_at=submitted_at, complete_at=complete_at)
-
- # fake methods
-
- def fakeClaimBuildRequest(self, brid, claimed_at=None, objectid=None):
- if objectid is None:
- objectid = self.MASTER_ID
- self.claims[brid] = BuildRequestClaim(brid=brid,
- objectid=objectid, claimed_at=self._reactor.seconds())
-
- def fakeUnclaimBuildRequest(self, brid):
- del self.claims[brid]
-
- # assertions
-
- def assertMyClaims(self, claimed_brids):
- self.t.assertEqual(
- [ id for (id, brc) in self.claims.iteritems()
- if brc.objectid == self.MASTER_ID ],
- claimed_brids)
-
-
-class FakeBuildsComponent(FakeDBComponent):
-
- def setUp(self):
- self.builds = {}
-
- def insertTestData(self, rows):
- for row in rows:
- if isinstance(row, Build):
- self.builds[row.id] = row
-
- # component methods
-
- def _newId(self):
- id = 100
- while id in self.builds:
- id += 1
- return id
-
- def getBuild(self, bid):
- row = self.builds.get(bid)
- if not row:
- return defer.succeed(None)
-
- return defer.succeed(dict(
- bid=row.id,
- brid=row.brid,
- number=row.number,
- start_time=epoch2datetime(row.start_time),
- finish_time=epoch2datetime(row.finish_time)))
-
- def getBuildsForRequest(self, brid):
- ret = []
-
- for (id, row) in self.builds.items():
- if row.brid == brid:
- ret.append(dict(bid = row.id,
- brid=row.brid,
- number=row.number,
- start_time=epoch2datetime(row.start_time),
- finish_time=epoch2datetime(row.finish_time)))
-
- return defer.succeed(ret)
-
- def addBuild(self, brid, number, _reactor=reactor):
- bid = self._newId()
- self.builds[bid] = Build(id=bid, number=number, brid=brid,
- start_time=_reactor.seconds, finish_time=None)
- return bid
-
- def finishBuilds(self, bids, _reactor=reactor):
- now = _reactor.seconds()
- for bid in bids:
- b = self.builds.get(bid)
- if b:
- b.finish_time = now
-
-class FakeUsersComponent(FakeDBComponent):
-
- def setUp(self):
- self.users = {}
- self.users_info = {}
- self.id_num = 0
-
- def insertTestData(self, rows):
- for row in rows:
- if isinstance(row, User):
- self.users[row.uid] = dict(identifier=row.identifier,
- bb_username=row.bb_username,
- bb_password=row.bb_password)
-
- if isinstance(row, UserInfo):
- assert row.uid in self.users
- if row.uid not in self.users_info:
- self.users_info[row.uid] = [dict(attr_type=row.attr_type,
- attr_data=row.attr_data)]
- else:
- self.users_info[row.uid].append(
- dict(attr_type=row.attr_type,
- attr_data=row.attr_data))
-
- def _user2dict(self, uid):
- usdict = None
- if uid in self.users:
- usdict = self.users[uid]
- if uid in self.users_info:
- infos = self.users_info[uid]
- for attr in infos:
- usdict[attr['attr_type']] = attr['attr_data']
- usdict['uid'] = uid
- return usdict
-
- def nextId(self):
- self.id_num += 1
- return self.id_num
-
- # component methods
-
- def findUserByAttr(self, identifier, attr_type, attr_data):
- for uid in self.users_info:
- attrs = self.users_info[uid]
- for attr in attrs:
- if (attr_type == attr['attr_type'] and
- attr_data == attr['attr_data']):
- return defer.succeed(uid)
-
- uid = self.nextId()
- self.db.insertTestData([User(uid=uid, identifier=identifier)])
- self.db.insertTestData([UserInfo(uid=uid,
- attr_type=attr_type,
- attr_data=attr_data)])
- return defer.succeed(uid)
-
- def getUser(self, uid):
- usdict = None
- if uid in self.users:
- usdict = self._user2dict(uid)
- return defer.succeed(usdict)
-
- def getUserByUsername(self, username):
- usdict = None
- for uid in self.users:
- user = self.users[uid]
- if user['bb_username'] == username:
- usdict = self._user2dict(uid)
- return defer.succeed(usdict)
-
- def updateUser(self, uid=None, identifier=None, bb_username=None,
- bb_password=None, attr_type=None, attr_data=None):
- assert uid is not None
-
- if identifier is not None:
- self.users[uid]['identifier'] = identifier
-
- if bb_username is not None:
- assert bb_password is not None
- try:
- user = self.users[uid]
- user['bb_username'] = bb_username
- user['bb_password'] = bb_password
- except KeyError:
- pass
-
- if attr_type is not None:
- assert attr_data is not None
- try:
- infos = self.users_info[uid]
- for attr in infos:
- if attr_type == attr['attr_type']:
- attr['attr_data'] = attr_data
- break
- else:
- infos.append(dict(attr_type=attr_type,
- attr_data=attr_data))
- except KeyError:
- pass
-
- return defer.succeed(None)
-
- def removeUser(self, uid):
- if uid in self.users:
- self.users.pop(uid)
- self.users_info.pop(uid)
- return defer.succeed(None)
-
- def identifierToUid(self, identifier):
- for uid in self.users:
- if identifier == self.users[uid]['identifier']:
- return defer.succeed(uid)
- return defer.succeed(None)
-
-class FakeDBConnector(object):
- """
- A stand-in for C{master.db} that operates without an actual database
- backend. This also implements a test-data interface similar to the
- L{buildbot.test.util.db.RealDatabaseMixin.insertTestData} method.
-
- The child classes implement various useful assertions and faking methods;
- see their documentation for more.
- """
-
- def __init__(self, testcase):
- self._components = []
- self.changes = comp = FakeChangesComponent(self, testcase)
- self._components.append(comp)
- self.schedulers = comp = FakeSchedulersComponent(self, testcase)
- self._components.append(comp)
- self.sourcestampsets = comp = FakeSourceStampSetsComponent(self,testcase)
- self._components.append(comp)
- self.sourcestamps = comp = FakeSourceStampsComponent(self, testcase)
- self._components.append(comp)
- self.buildsets = comp = FakeBuildsetsComponent(self, testcase)
- self._components.append(comp)
- self.state = comp = FakeStateComponent(self, testcase)
- self._components.append(comp)
- self.buildrequests = comp = FakeBuildRequestsComponent(self, testcase)
- self._components.append(comp)
- self.builds = comp = FakeBuildsComponent(self, testcase)
- self._components.append(comp)
- self.users = comp = FakeUsersComponent(self, testcase)
- self._components.append(comp)
-
- def setup(self):
- self.is_setup = True
- return defer.succeed(None)
-
- def insertTestData(self, rows):
- """Insert a list of Row instances into the database; this method can be
- called synchronously or asynchronously (it completes immediately) """
- for comp in self._components:
- comp.insertTestData(rows)
- return defer.succeed(None)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakemaster.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakemaster.py
deleted file mode 100644
index 0187bedc..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/fakemaster.py
+++ /dev/null
@@ -1,112 +0,0 @@
-# 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 weakref
-from twisted.internet import defer
-from buildbot.test.fake import fakedb
-from buildbot.test.fake import pbmanager
-from buildbot.test.fake.botmaster import FakeBotMaster
-from buildbot import config
-import mock
-
-class FakeCache(object):
- """Emulate an L{AsyncLRUCache}, but without any real caching. This
- I{does} do the weakref part, to catch un-weakref-able objects."""
- def __init__(self, name, miss_fn):
- self.name = name
- self.miss_fn = miss_fn
-
- def get(self, key, **kwargs):
- d = self.miss_fn(key, **kwargs)
- def mkref(x):
- if x is not None:
- weakref.ref(x)
- return x
- d.addCallback(mkref)
- return d
-
-
-class FakeCaches(object):
-
- def get_cache(self, name, miss_fn):
- return FakeCache(name, miss_fn)
-
-
-class FakeStatus(object):
-
- def builderAdded(self, name, basedir, category=None, description=None):
- return FakeBuilderStatus()
-
-
-class FakeBuilderStatus(object):
-
- def setDescription(self, description):
- self._description = description
-
- def getDescription(self):
- return self._description
-
- def setCategory(self, category):
- self._category = category
-
- def getCategory(self):
- return self._category
-
- def setSlavenames(self, names):
- pass
-
- def setCacheSize(self, size):
- pass
-
- def setBigState(self, state):
- pass
-
-
-class FakeMaster(object):
- """
- Create a fake Master instance: a Mock with some convenience
- implementations:
-
- - Non-caching implementation for C{self.caches}
- """
-
- def __init__(self, master_id=fakedb.FakeBuildRequestsComponent.MASTER_ID):
- self._master_id = master_id
- self.config = config.MasterConfig()
- self.caches = FakeCaches()
- self.pbmanager = pbmanager.FakePBManager()
- self.basedir = 'basedir'
- self.botmaster = FakeBotMaster(master=self)
- self.botmaster.parent = self
- self.status = FakeStatus()
- self.status.master = self
-
- def getObjectId(self):
- return defer.succeed(self._master_id)
-
- def subscribeToBuildRequests(self, callback):
- pass
-
- # work around http://code.google.com/p/mock/issues/detail?id=105
- def _get_child_mock(self, **kw):
- return mock.Mock(**kw)
-
-# Leave this alias, in case we want to add more behavior later
-def make_master(wantDb=False, testcase=None, **kwargs):
- master = FakeMaster(**kwargs)
- if wantDb:
- assert testcase is not None, "need testcase for wantDb"
- master.db = fakedb.FakeDBConnector(testcase)
- return master
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/libvirt.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/libvirt.py
deleted file mode 100644
index 2a32f6e7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/libvirt.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# 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
-
-class Domain(object):
-
- def __init__(self, name, conn):
- self.conn = conn
- self._name = name
- self.running = False
-
- def name(self):
- return self._name
-
- def create(self):
- self.running = True
-
- def shutdown(self):
- self.running = False
-
- def destroy(self):
- self.running = False
- del self.conn[self._name]
-
-
-class Connection(object):
-
- def __init__(self, uri):
- self.uri = uri
- self.domains = {}
-
- def createXML(self, xml, flags):
- #FIXME: This should really parse the name out of the xml, i guess
- d = self.fake_add("instance")
- d.running = True
- return d
-
- def listDomainsID(self):
- return self.domains.keys()
-
- def lookupByName(self, name):
- return self.domains[name]
-
- def lookupByID(self, ID):
- return self.domains[ID]
-
- def fake_add(self, name):
- d = Domain(name, self)
- self.domains[name] = d
- return d
-
-
-def open(uri):
- return Connection(uri)
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/openstack.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/openstack.py
deleted file mode 100644
index 6681ae3f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/openstack.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# 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.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright 2013 Cray Inc.
-
-import uuid
-
-ACTIVE = 'ACTIVE'
-BUILD = 'BUILD'
-DELETED = 'DELETED'
-ERROR = 'ERROR'
-UNKNOWN = 'UNKNOWN'
-
-
-# Parts used from novaclient.v1_1.
-class Client():
- def __init__(self, username, password, tenant_name, auth_url):
- self.images = Images()
- self.servers = Servers()
-
-class Images():
- images = []
-
- def list(self):
- return self.images
-
-class Servers():
- fail_to_get = False
- fail_to_start = False
- gets_until_active = 2
-
- def __init__(self):
- self.instances = {}
-
- def create(self, *boot_args, **boot_kwargs):
- instance_id = uuid.uuid4()
- instance = Instance(instance_id, self, boot_args, boot_kwargs)
- self.instances[instance_id] = instance
- return instance
-
- def get(self, instance_id):
- if not self.fail_to_get and instance_id in self.instances:
- inst = self.instances[instance_id]
- inst.gets += 1
- if inst.gets >= self.gets_until_active:
- if not self.fail_to_start:
- inst.status = ACTIVE
- else:
- inst.status = ERROR
- return inst
- else:
- raise NotFound
-
- def delete(self, instance_id):
- if instance_id in self.instances:
- del self.instances[instance_id]
-
-
-# This is returned by Servers.create().
-class Instance():
- def __init__(self, id, servers, boot_args, boot_kwargs):
- self.id = id
- self.servers = servers
- self.boot_args = boot_args
- self.boot_kwargs = boot_kwargs
- self.gets = 0
- self.status = BUILD
- self.name = 'name'
-
- def delete(self):
- self.servers.delete(self.id)
-
-# Parts used from novaclient.exceptions.
-class NotFound():
- pass
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/pbmanager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/pbmanager.py
deleted file mode 100644
index e91b7e5e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/pbmanager.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# 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
-
-from twisted.application import service
-from twisted.internet import defer
-
-class FakePBManager(service.MultiService):
-
- def __init__(self):
- service.MultiService.__init__(self)
- self.setName("fake-pbmanager")
- self._registrations = []
- self._unregistrations = []
-
- def register(self, portstr, username, password, pfactory):
- if (portstr, username) not in self._registrations:
- reg = FakeRegistration(self, portstr, username)
- self._registrations.append((portstr,username,password))
- return reg
- else:
- raise KeyError, ("username '%s' is already registered on port %s"
- % (username, portstr))
-
- def _unregister(self, portstr, username):
- self._unregistrations.append((portstr, username))
- return defer.succeed(None)
-
-class FakeRegistration(object):
- def __init__(self, pbmanager, portstr, username):
- self._portstr = portstr
- self._username = username
- self._pbmanager = pbmanager
-
- def unregister(self):
- self._pbmanager._unregister(self._portstr, self._username)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/remotecommand.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/remotecommand.py
deleted file mode 100644
index 9c583c92..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/remotecommand.py
+++ /dev/null
@@ -1,294 +0,0 @@
-# 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
-
-from twisted.internet import defer
-from twisted.python import failure
-from buildbot.status.logfile import STDOUT, STDERR, HEADER
-from cStringIO import StringIO
-from buildbot.status.results import SUCCESS, FAILURE
-
-
-class FakeRemoteCommand(object):
-
- # callers should set this to the running TestCase instance
- testcase = None
-
- active = False
-
- def __init__(self, remote_command, args,
- ignore_updates=False, collectStdout=False, collectStderr=False, decodeRC={0:SUCCESS}):
- # copy the args and set a few defaults
- self.remote_command = remote_command
- self.args = args.copy()
- self.logs = {}
- self.delayedLogs = {}
- self.rc = -999
- self.collectStdout = collectStdout
- self.collectStderr = collectStderr
- self.updates = {}
- self.decodeRC = decodeRC
- if collectStdout:
- self.stdout = ''
- if collectStderr:
- self.stderr = ''
-
- def run(self, step, remote):
- # delegate back to the test case
- return self.testcase._remotecommand_run(self, step, remote)
-
- def useLog(self, log, closeWhenFinished=False, logfileName=None):
- if not logfileName:
- logfileName = log.getName()
- self.logs[logfileName] = log
-
- def useLogDelayed(self, logfileName, activateCallBack, closeWhenFinished=False):
- self.delayedLogs[logfileName] = (activateCallBack, closeWhenFinished)
-
- def interrupt(self, why):
- raise NotImplementedError
-
- def results(self):
- if self.rc in self.decodeRC:
- return self.decodeRC[self.rc]
- return FAILURE
-
- def didFail(self):
- return self.results() == FAILURE
-
- def fakeLogData(self, step, log, header='', stdout='', stderr=''):
- # note that this should not be used in the same test as useLog(Delayed)
- self.logs[log] = l = FakeLogFile(log, step)
- l.fakeData(header=header, stdout=stdout, stderr=stderr)
-
- def __repr__(self):
- return "FakeRemoteCommand("+repr(self.remote_command)+","+repr(self.args)+")"
-class FakeRemoteShellCommand(FakeRemoteCommand):
-
- def __init__(self, workdir, command, env=None,
- want_stdout=1, want_stderr=1,
- timeout=20*60, maxTime=None, logfiles={},
- usePTY="slave-config", logEnviron=True, collectStdout=False,
- collectStderr=False,
- interruptSignal=None, initialStdin=None, decodeRC={0:SUCCESS}):
- args = dict(workdir=workdir, command=command, env=env or {},
- want_stdout=want_stdout, want_stderr=want_stderr,
- initial_stdin=initialStdin,
- timeout=timeout, maxTime=maxTime, logfiles=logfiles,
- usePTY=usePTY, logEnviron=logEnviron)
- FakeRemoteCommand.__init__(self, "shell", args,
- collectStdout=collectStdout,
- collectStderr=collectStderr,
- decodeRC=decodeRC)
-
-
-class FakeLogFile(object):
-
- def __init__(self, name, step):
- self.name = name
- self.header = ''
- self.stdout = ''
- self.stderr = ''
- self.chunks = []
- self.step = step
-
- def getName(self):
- return self.name
-
- def addHeader(self, text):
- self.header += text
- self.chunks.append((HEADER, text))
-
- def addStdout(self, text):
- self.stdout += text
- self.chunks.append((STDOUT, text))
- if self.name in self.step.logobservers:
- for obs in self.step.logobservers[self.name]:
- obs.outReceived(text)
-
- def addStderr(self, text):
- self.stderr += text
- self.chunks.append((STDERR, text))
- if self.name in self.step.logobservers:
- for obs in self.step.logobservers[self.name]:
- obs.errReceived(text)
-
- def readlines(self):
- io = StringIO(self.stdout)
- return io.readlines()
-
- def getText(self):
- return ''.join([ c for str,c in self.chunks
- if str in (STDOUT, STDERR)])
- def getTextWithHeaders(self):
- return ''.join([ c for str,c in self.chunks])
-
- def getChunks(self, channels=[], onlyText=False):
- if onlyText:
- return [ data
- for (ch, data) in self.chunks
- if not channels or ch in channels ]
- else:
- return [ (ch, data)
- for (ch, data) in self.chunks
- if not channels or ch in channels ]
-
- def finish(self):
- pass
-
- def fakeData(self, header='', stdout='', stderr=''):
- if header:
- self.header += header
- self.chunks.append((HEADER, header))
- if stdout:
- self.stdout += stdout
- self.chunks.append((STDOUT, stdout))
- if stderr:
- self.stderr += stderr
- self.chunks.append((STDERR, stderr))
-
-class ExpectRemoteRef(object):
- """
- Define an expected RemoteReference in the args to an L{Expect} class
- """
-
- def __init__(self, rrclass):
- self.rrclass = rrclass
-
- def __eq__(self, other):
- return isinstance(other, self.rrclass)
-
-class Expect(object):
- """
- Define an expected L{RemoteCommand}, with the same arguments
-
- Extra behaviors of the remote command can be added to the instance, using
- class methods. Use L{Expect.log} to add a logfile, L{Expect.update} to add
- an arbitrary update, or add an integer to specify the return code (rc), or
- add a Failure instance to raise an exception. Additionally, use
- L{Expect.behavior}, passing a callable that will be invoked with the real
- command and can do what it likes:
-
- def custom_behavior(command):
- ...
- Expect('somecommand', { args='foo' })
- + Expect.behavior(custom_behavior),
- ...
-
- Expect('somecommand', { args='foo' })
- + Expect.log('stdio', stdout='foo!')
- + Expect.log('config.log', stdout='some info')
- + Expect.update('status', 'running')
- + 0, # (specifies the rc)
- ...
-
- """
-
- def __init__(self, remote_command, args, incomparable_args=[]):
- """
-
- Expect a command named C{remote_command}, with args C{args}. Any args
- in C{incomparable_args} are not cmopared, but must exist.
-
- """
- self.remote_command = remote_command
- self.incomparable_args = incomparable_args
- self.args = args
- self.result = None
- self.behaviors = []
-
- @classmethod
- def behavior(cls, callable):
- """
- Add an arbitrary behavior that is expected of this command.
- C{callable} will be invoked with the real command as an argument, and
- can do what it wishes. It will be invoked with maybeDeferred, in case
- the operation is asynchronous.
- """
- return ('callable', callable)
-
- @classmethod
- def log(self, name, **streams):
- return ('log', name, streams)
-
- @classmethod
- def update(self, name, value):
- return ('update', name, value)
-
- def __add__(self, other):
- # special-case adding an integer (return code) or failure (error)
- if isinstance(other, int):
- self.behaviors.append(('rc', other))
- elif isinstance(other, failure.Failure):
- self.behaviors.append(('err', other))
- else:
- self.behaviors.append(other)
- return self
-
- def runBehavior(self, behavior, args, command):
- """
- Implement the given behavior. Returns a Deferred.
- """
- if behavior == 'rc':
- command.rc = args[0]
- elif behavior == 'err':
- return defer.fail(args[0])
- elif behavior == 'update':
- command.updates.setdefault(args[0], []).append(args[1])
- elif behavior == 'log':
- name, streams = args
- if 'header' in streams:
- command.logs[name].addHeader(streams['header'])
- if 'stdout' in streams:
- command.logs[name].addStdout(streams['stdout'])
- if command.collectStdout:
- command.stdout += streams['stdout']
- if 'stderr' in streams:
- command.logs[name].addStderr(streams['stderr'])
- if command.collectStderr:
- command.stderr += streams['stderr']
- elif behavior == 'callable':
- return defer.maybeDeferred(lambda : args[0](command))
- else:
- return defer.fail(failure.Failure(
- AssertionError('invalid behavior %s' % behavior)))
- return defer.succeed(None)
-
- @defer.inlineCallbacks
- def runBehaviors(self, command):
- """
- Run all expected behaviors for this command
- """
- for behavior in self.behaviors:
- yield self.runBehavior(behavior[0], behavior[1:], command)
- def __repr__(self):
- return "Expect("+repr(self.remote_command)+")"
-
-class ExpectShell(Expect):
- """
- Define an expected L{RemoteShellCommand}, with the same arguments Any
- non-default arguments must be specified explicitly (e.g., usePTY).
- """
- def __init__(self, workdir, command, env={},
- want_stdout=1, want_stderr=1, initialStdin=None,
- timeout=20*60, maxTime=None, logfiles={},
- usePTY="slave-config", logEnviron=True):
- args = dict(workdir=workdir, command=command, env=env,
- want_stdout=want_stdout, want_stderr=want_stderr,
- initial_stdin=initialStdin,
- timeout=timeout, maxTime=maxTime, logfiles=logfiles,
- usePTY=usePTY, logEnviron=logEnviron)
- Expect.__init__(self, "shell", args)
- def __repr__(self):
- return "ExpectShell("+repr(self.remote_command)+repr(self.args['command'])+")"
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/slave.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/slave.py
deleted file mode 100644
index e95efc50..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/slave.py
+++ /dev/null
@@ -1,17 +0,0 @@
-# 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
-
-class FakeSlave(object):
- slave_system = 'posix'
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/state.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/state.py
deleted file mode 100644
index 7b0f3f44..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/state.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# 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
-
-class State(object):
- """
- A simple class you can use to keep track of state throughout
- a test. Just assign whatever you want to its attributes. Its
- constructor provides a shortcut to setting initial values for
- attributes
- """
- def __init__(self, **kwargs):
- self.__dict__.update(kwargs)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/web.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/web.py
deleted file mode 100644
index 2adaee44..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/fake/web.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# 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
-
-from mock import Mock
-
-from twisted.internet import defer
-from twisted.web import server
-
-class FakeRequest(Mock):
- """
- A fake Twisted Web Request object, including some pointers to the
- buildmaster and an addChange method on that master which will append its
- arguments to self.addedChanges.
- """
-
- written = ''
- finished = False
- redirected_to = None
- failure = None
-
- def __init__(self, args={}):
- Mock.__init__(self)
-
- self.args = args
- self.site = Mock()
- self.site.buildbot_service = Mock()
- master = self.site.buildbot_service.master = Mock()
-
- self.addedChanges = []
- def addChange(**kwargs):
- self.addedChanges.append(kwargs)
- return defer.succeed(Mock())
- master.addChange = addChange
-
- self.deferred = defer.Deferred()
-
- def write(self, data):
- self.written = self.written + data
-
- def redirect(self, url):
- self.redirected_to = url
-
- def finish(self):
- self.finished = True
- self.deferred.callback(None)
-
- def processingFailed(self, f):
- self.deferred.errback(f)
-
- # work around http://code.google.com/p/mock/issues/detail?id=105
- def _get_child_mock(self, **kw):
- return Mock(**kw)
-
- # cribed from twisted.web.test._util._render
- def test_render(self, resource):
- result = resource.render(self)
- if isinstance(result, str):
- self.write(result)
- self.finish()
- return self.deferred
- elif result is server.NOT_DONE_YET:
- return self.deferred
- else:
- raise ValueError("Unexpected return value: %r" % (result,))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_bad_change_properties_rows.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_bad_change_properties_rows.py
deleted file mode 100644
index e68c7e6f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_bad_change_properties_rows.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.test.util import connector_component
-from buildbot.db import changes
-from buildbot.test.fake import fakedb
-
-class TestBadRows(connector_component.ConnectorComponentMixin,
- unittest.TestCase):
- # See bug #1952 for details. This checks that users who used a development
- # version between 0.8.3 and 0.8.4 get reasonable behavior even though some
- # rows in the change_properties database do not contain a proper [value,
- # source] tuple.
- def setUp(self):
- d = self.setUpConnectorComponent(
- table_names=['changes', 'change_properties', 'change_files'])
- def finish_setup(_):
- self.db.changes = changes.ChangesConnectorComponent(self.db)
- d.addCallback(finish_setup)
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- def test_bogus_row_no_source(self):
- d = self.insertTestData([
- fakedb.ChangeProperty(changeid=13, property_name='devel',
- property_value='"no source"'),
- fakedb.Change(changeid=13),
- ])
- def get13(_):
- return self.db.changes.getChange(13)
- d.addCallback(get13)
- def check13(c):
- self.assertEqual(c['properties'],
- dict(devel=('no source', 'Change')))
- d.addCallback(check13)
- return d
-
- def test_bogus_row_jsoned_list(self):
- d = self.insertTestData([
- fakedb.ChangeProperty(changeid=13, property_name='devel',
- property_value='[1, 2]'),
- fakedb.Change(changeid=13),
- ])
- def get13(_):
- return self.db.changes.getChange(13)
- d.addCallback(get13)
- def check13(c):
- self.assertEqual(c['properties'],
- dict(devel=([1,2], 'Change')))
- d.addCallback(check13)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_import_unicode_changes.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_import_unicode_changes.py
deleted file mode 100644
index c8d3b2a7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_import_unicode_changes.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.db.connector import DBConnector
-from buildbot.test.util import change_import
-from buildbot.test.fake import fakemaster
-
-class TestUnicodeChanges(change_import.ChangeImportMixin, unittest.TestCase):
- def setUp(self):
- d = self.setUpChangeImport()
- def make_dbc(_):
- master = fakemaster.make_master()
- master.config.db['db_url'] = self.db_url
- self.db = DBConnector(master, self.basedir)
- return self.db.setup(check_version=False)
-
- d.addCallback(make_dbc)
- # note the connector isn't started, as we're testing upgrades
- return d
-
- def tearDown(self):
- return self.tearDownChangeImport()
-
- # tests
-
- def testUnicodeChange(self):
- self.make_pickle(
- self.make_change(
- who=u"Frosty the \N{SNOWMAN}".encode("utf8"),
- files=["foo"],
- comments=u"Frosty the \N{SNOWMAN}".encode("utf8"),
- branch="b1",
- revision=12345))
-
- d = self.db.model.upgrade()
- d.addCallback(lambda _ : self.db.changes.getChange(1))
- def check(c):
- self.failIf(c is None)
- self.assertEquals(c['author'], u"Frosty the \N{SNOWMAN}")
- self.assertEquals(c['comments'], u"Frosty the \N{SNOWMAN}")
- d.addCallback(check)
- return d
-
- def testNonUnicodeChange(self):
- self.make_pickle(
- self.make_change(
- who="\xff\xff\x00",
- files=["foo"],
- comments="\xff\xff\x00",
- branch="b1",
- revision=12345))
-
- d = self.db.model.upgrade()
- return self.assertFailure(d, UnicodeError)
-
- def testAsciiChange(self):
- self.make_pickle(
- self.make_change(
- who="Frosty the Snowman",
- files=["foo"],
- comments="Frosty the Snowman",
- branch="b1",
- revision=12345))
-
- d = self.db.model.upgrade()
- d.addCallback(lambda _ : self.db.changes.getChange(1))
- def check(c):
- self.failIf(c is None)
- self.assertEquals(c['author'], "Frosty the Snowman")
- self.assertEquals(c['comments'], "Frosty the Snowman")
- d.addCallback(check)
- return d
-
- def testUTF16Change(self):
- self.make_pickle(
- self.make_change(
- who=u"Frosty the \N{SNOWMAN}".encode("utf16"),
- files=[u"foo".encode('utf16')],
- comments=u"Frosty the \N{SNOWMAN}".encode("utf16"),
- branch="b1",
- revision=12345),
- # instead of running contrib/fix_changes_pickle_encoding.py, we
- # just call the changemanager's recode_changes directly - it's
- # the function at the heart of the script anyway.
- recode_fn=lambda cm : cm.recode_changes('utf16', quiet=True))
-
- d = self.db.model.upgrade()
- d.addCallback(lambda _ : self.db.changes.getChange(1))
- def check(c):
- self.failIf(c is None)
- self.assertEquals(c['author'], u"Frosty the \N{SNOWMAN}")
- self.assertEquals(c['comments'], u"Frosty the \N{SNOWMAN}")
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_oldpaths.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_oldpaths.py
deleted file mode 100644
index 14a474ff..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_oldpaths.py
+++ /dev/null
@@ -1,191 +0,0 @@
-# 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
-
-
-from twisted.trial import unittest
-
-class OldImportPaths(unittest.TestCase):
- """
- Test that old, deprecated import paths still work.
- """
-
- def test_scheduler_Scheduler(self):
- from buildbot.scheduler import Scheduler
- assert Scheduler
-
- def test_schedulers_basic_Scheduler(self):
- # renamed to basic.SingleBranchScheduler
- from buildbot.schedulers.basic import Scheduler
- assert Scheduler
-
- def test_scheduler_AnyBranchScheduler(self):
- from buildbot.scheduler import AnyBranchScheduler
- assert AnyBranchScheduler
-
- def test_scheduler_basic_Dependent(self):
- from buildbot.schedulers.basic import Dependent
- assert Dependent
-
- def test_scheduler_Dependent(self):
- from buildbot.scheduler import Dependent
- assert Dependent
-
- def test_scheduler_Periodic(self):
- from buildbot.scheduler import Periodic
- assert Periodic
-
- def test_scheduler_Nightly(self):
- from buildbot.scheduler import Nightly
- assert Nightly
-
- def test_scheduler_Triggerable(self):
- from buildbot.scheduler import Triggerable
- assert Triggerable
-
- def test_scheduler_Try_Jobdir(self):
- from buildbot.scheduler import Try_Jobdir
- assert Try_Jobdir
-
- def test_scheduler_Try_Userpass(self):
- from buildbot.scheduler import Try_Userpass
- assert Try_Userpass
-
- def test_changes_changes_ChangeMaster(self):
- # this must exist to open old changes pickles
- from buildbot.changes.changes import ChangeMaster
- assert ChangeMaster
-
- def test_changes_changes_Change(self):
- # this must exist to open old changes pickles
- from buildbot.changes.changes import Change
- assert Change
-
- def test_status_html_Webstatus(self):
- from buildbot.status.html import WebStatus
- assert WebStatus
-
- def test_schedulers_filter_ChangeFilter(self):
- # this was the location of ChangeFilter until 0.8.4
- from buildbot.schedulers.filter import ChangeFilter
- assert ChangeFilter
-
- def test_process_base_Build(self):
- from buildbot.process.base import Build
- assert Build
-
- def test_buildrequest_BuildRequest(self):
- from buildbot.buildrequest import BuildRequest
- assert BuildRequest
-
- def test_sourcestamp_SourceStamp(self):
- # this must exist, and the class must be defined at this package path,
- # in order for old build pickles to be loaded.
- from buildbot.sourcestamp import SourceStamp
- assert SourceStamp
-
- def test_process_subunitlogobserver_SubunitShellCommand(self):
- from buildbot.process.subunitlogobserver import SubunitShellCommand
- assert SubunitShellCommand
-
- def test_status_builder_results(self):
- # these symbols are now in buildbot.status.results, but lots of user
- # code references them here:
- from buildbot.status.builder import SUCCESS, WARNINGS, FAILURE, SKIPPED
- from buildbot.status.builder import EXCEPTION, RETRY, Results
- from buildbot.status.builder import worst_status
- # reference the symbols to avoid failure from pyflakes
- (SUCCESS, WARNINGS, FAILURE, SKIPPED,EXCEPTION, RETRY, Results,
- worst_status)
-
- def test_status_builder_BuildStepStatus(self):
- from buildbot.status.builder import BuildStepStatus
- assert BuildStepStatus
-
- def test_status_builder_BuildSetStatus(self):
- from buildbot.status.builder import BuildSetStatus
- assert BuildSetStatus
-
- def test_status_builder_TestResult(self):
- from buildbot.status.builder import TestResult
- assert TestResult
-
- def test_status_builder_LogFile(self):
- from buildbot.status.builder import LogFile
- assert LogFile
-
- def test_status_builder_HTMLLogFile(self):
- from buildbot.status.builder import HTMLLogFile
- assert HTMLLogFile
-
- def test_status_builder_SlaveStatus(self):
- from buildbot.status.builder import SlaveStatus
- assert SlaveStatus
-
- def test_status_builder_Status(self):
- from buildbot.status.builder import Status
- assert Status
-
- def test_status_builder_Event(self):
- from buildbot.status.builder import Event
- assert Event
-
- def test_status_builder_BuildStatus(self):
- from buildbot.status.builder import BuildStatus
- assert BuildStatus
-
- def test_steps_source_Source(self):
- from buildbot.steps.source import Source
- assert Source
-
- def test_steps_source_CVS(self):
- from buildbot.steps.source import CVS
- assert CVS
-
- def test_steps_source_SVN(self):
- from buildbot.steps.source import SVN
- assert SVN
-
- def test_steps_source_Git(self):
- from buildbot.steps.source import Git
- assert Git
-
- def test_steps_source_Darcs(self):
- from buildbot.steps.source import Darcs
- assert Darcs
-
- def test_steps_source_Repo(self):
- from buildbot.steps.source import Repo
- assert Repo
-
- def test_steps_source_Bzr(self):
- from buildbot.steps.source import Bzr
- assert Bzr
-
- def test_steps_source_Mercurial(self):
- from buildbot.steps.source import Mercurial
- assert Mercurial
-
- def test_steps_source_P4(self):
- from buildbot.steps.source import P4
- assert P4
-
- def test_steps_source_Monotone(self):
- from buildbot.steps.source import Monotone
- assert Monotone
-
- def test_steps_source_BK(self):
- from buildbot.steps.source import BK
- assert BK
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_shell_command_properties.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_shell_command_properties.py
deleted file mode 100644
index 8c575a34..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_shell_command_properties.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-
-from buildbot.steps.shell import ShellCommand, SetPropertyFromCommand
-from buildbot.process.properties import WithProperties, Properties
-from buildbot.process.factory import BuildFactory
-from buildbot.sourcestamp import SourceStamp
-from buildbot import config
-
-class FakeSlaveBuilder:
- slave = None
-
-
-class FakeBuildStatus:
- def __init__(self):
- self.names = []
-
- def addStepWithName(self, name):
- self.names.append(name)
- return FakeStepStatus()
-
- def getProperties(self):
- return Properties()
-
- def setSourceStamps(self, ss_list):
- self.ss_list = ss_list
-
- def setReason(self, reason):
- self.reason = reason
-
- def setBlamelist(self, bl):
- self.bl = bl
-
- def setProgress(self, p):
- self.progress = p
-
-
-class FakeStepStatus:
- txt = None
- def setText(self, txt):
- self.txt = txt
-
- def setProgress(self, sp):
- pass
-
-
-class FakeBuildRequest:
- def __init__(self, reason, sources, buildername):
- self.reason = reason
- self.sources = sources
- self.buildername = buildername
- self.changes = []
- self.properties = Properties()
-
- def mergeSourceStampsWith(self, others):
- return [source for source in self.sources.itervalues()]
-
- def mergeReasons(self, others):
- return self.reason
-
-
-class TestShellCommandProperties(unittest.TestCase):
- def testCommand(self):
- f = BuildFactory()
- f.addStep(SetPropertyFromCommand(command=["echo", "value"], property="propname"))
- f.addStep(ShellCommand(command=["echo", WithProperties("%(propname)s")]))
-
- ss = SourceStamp()
-
- req = FakeBuildRequest("Testing", {ss.repository:ss}, None)
-
- b = f.newBuild([req])
- b.build_status = FakeBuildStatus()
- b.slavebuilder = FakeSlaveBuilder()
-
- # This shouldn't raise an exception
- b.setupBuild(None)
-
-
-class TestSetProperty(unittest.TestCase):
- def testGoodStep(self):
- f = BuildFactory()
- f.addStep(SetPropertyFromCommand(command=["echo", "value"], property="propname"))
-
- ss = SourceStamp()
-
- req = FakeBuildRequest("Testing", {ss.repository:ss}, None)
-
- b = f.newBuild([req])
- b.build_status = FakeBuildStatus()
- b.slavebuilder = FakeSlaveBuilder()
-
- # This shouldn't raise an exception
- b.setupBuild(None)
-
- def testErrorBothSet(self):
- self.assertRaises(config.ConfigErrors,
- SetPropertyFromCommand, command=["echo", "value"], property="propname", extract_fn=lambda x:{"propname": "hello"})
-
- def testErrorNoneSet(self):
- self.assertRaises(config.ConfigErrors,
- SetPropertyFromCommand, command=["echo", "value"])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_sourcestamp_revision.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_sourcestamp_revision.py
deleted file mode 100644
index 66d62a8a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_sourcestamp_revision.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-
-from buildbot.sourcestamp import SourceStamp
-from buildbot.changes.changes import Change
-
-class TestSourceStampRevision(unittest.TestCase):
- def testNoRevision(self):
- c = Change(who="catlee", files=["foo"], comments="", branch="b1", revision=None)
- ss = SourceStamp(changes=[c])
-
- self.assertEquals(ss.revision, None)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_steps_shell_WarningCountingShellCommand.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_steps_shell_WarningCountingShellCommand.py
deleted file mode 100644
index cea65b84..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_steps_shell_WarningCountingShellCommand.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-
-import re
-from buildbot.steps.shell import WarningCountingShellCommand
-
-class TestWarningCountingShellCommand(unittest.TestCase):
-
- # Makes sure that it is possible to supress warnings even if the
- # warning extractor does not provie line information
- def testSuppressingLinelessWarningsPossible(self):
- # Use a warningExtractor that does not provide line
- # information
- w = WarningCountingShellCommand(
- warningExtractor=WarningCountingShellCommand.warnExtractWholeLine)
-
- # Add suppression manually instead of using suppressionFile
- fileRe = None
- warnRe = ".*SUPPRESS.*"
- start = None
- end = None
- suppression = (fileRe, warnRe, start, end)
- w.addSuppression([suppression])
-
- # Now call maybeAddWarning
- warnings = []
- line = "this warning should be SUPPRESSed"
- match = re.match(".*warning.*", line)
- w.maybeAddWarning(warnings, line, match)
-
- # Finally make the suppressed warning was *not* added to the
- # list of warnings
- expectedWarnings = 0
- self.assertEquals(len(warnings), expectedWarnings)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_unpickling.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_unpickling.py
deleted file mode 100644
index 0791d1f3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/regressions/test_unpickling.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# 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 base64
-import cPickle
-from twisted.trial import unittest
-from twisted.persisted import styles
-from buildbot.status.buildstep import BuildStepStatus
-from buildbot.status.build import BuildStatus
-from buildbot.status.builder import BuilderStatus
-
-class StatusPickles(unittest.TestCase):
- # This pickle was created with Buildbot tag v0.8.1:
- # >>> bs = BuildStatus(BuilderStatus('test'), 1)
- # >>> bss = BuildStepStatus(bs)
- # >>> pkl = pickle.dumps(dict(buildstatus=bs, buildstepstatus=bss))
- pickle_b64 = """
- KGRwMQpTJ2J1aWxkc3RlcHN0YXR1cycKcDIKKGlidWlsZGJvdC5zdGF0dXMuYnVpbGRlcgp
- CdWlsZFN0ZXBTdGF0dXMKcDMKKGRwNApTJ2xvZ3MnCnA1CihscDYKc1MndXJscycKcDcKKG
- RwOApzUydzdGF0aXN0aWNzJwpwOQooZHAxMApzUydidWlsZGJvdC5zdGF0dXMuYnVpbGRlc
- i5CdWlsZFN0ZXBTdGF0dXMucGVyc2lzdGVuY2VWZXJzaW9uJwpwMTEKSTIKc2JzUydidWls
- ZHN0YXR1cycKcDEyCihpYnVpbGRib3Quc3RhdHVzLmJ1aWxkZXIKQnVpbGRTdGF0dXMKcDE
- zCihkcDE0ClMnbnVtYmVyJwpwMTUKSTEKc1MnYnVpbGRib3Quc3RhdHVzLmJ1aWxkZXIuQn
- VpbGRTdGF0dXMucGVyc2lzdGVuY2VWZXJzaW9uJwpwMTYKSTMKc1MnZmluaXNoZWQnCnAxN
- wpJMDEKc1Mnc3RlcHMnCnAxOAoobHAxOQpzUydwcm9wZXJ0aWVzJwpwMjAKKGlidWlsZGJv
- dC5wcm9jZXNzLnByb3BlcnRpZXMKUHJvcGVydGllcwpwMjEKKGRwMjIKZzIwCihkcDIzCnN
- ic1MndGVzdFJlc3VsdHMnCnAyNAooZHAyNQpzYnMu"""
- pickle_data = base64.b64decode(pickle_b64)
-
- # In 0.8.1, the following persistence versions were in effect:
- #
- # BuildStepStatus: 2
- # BuildStatus: 3
- # BuilderStatus: 1
- #
- # the regression that can occur here is that if the classes are renamed,
- # then older upgradeToVersionX may be run in cases where it should not;
- # this error can be "silent" since the upgrade will not fail.
-
- def test_upgrade(self):
- self.patch(BuildStepStatus, 'upgradeToVersion1', lambda _ :
- self.fail("BuildStepStatus.upgradeToVersion1 called"))
- self.patch(BuildStatus, 'upgradeToVersion1', lambda _ :
- self.fail("BuildStatus.upgradeToVersion1 called"))
- self.patch(BuilderStatus, 'upgradeToVersion1', lambda _ :
- self.fail("BuilderStatus.upgradeToVersion1 called"))
- pkl_result = cPickle.loads(self.pickle_data)
- styles.doUpgrade()
- del pkl_result
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/test_extra_coverage.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/test_extra_coverage.py
deleted file mode 100644
index 7a3509ff..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/test_extra_coverage.py
+++ /dev/null
@@ -1,65 +0,0 @@
-# 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
-
-# this file imports a number of source files that are not
-# included in the coverage because none of the tests import
-# them; this results in a more accurate total coverage percent.
-
-modules = [] # for the benefit of pyflakes
-
-from buildbot import buildslave
-modules.extend([buildslave])
-from buildbot.changes import p4poller, svnpoller
-modules.extend([p4poller, svnpoller])
-from buildbot.clients import base, sendchange, tryclient
-modules.extend([base, sendchange, tryclient])
-from buildbot.process import mtrlogobserver, subunitlogobserver
-modules.extend([mtrlogobserver, subunitlogobserver])
-from buildbot.scripts import checkconfig, logwatcher, reconfig, runner
-modules.extend([checkconfig, logwatcher, reconfig, runner])
-from buildbot.status import client, html, status_gerrit, status_push
-modules.extend([client, html, status_gerrit, status_push])
-from buildbot.status import tinderbox, words
-modules.extend([tinderbox, words])
-from buildbot.status.web import baseweb, build, builder, buildstatus, changes
-modules.extend([baseweb, build, builder, buildstatus, changes])
-from buildbot.status.web import console, feeds, grid, logs, olpb, root, slaves
-modules.extend([console, feeds, grid, logs, olpb, root, slaves])
-from buildbot.status.web import status_json, step, tests, waterfall
-modules.extend([status_json, step, tests, waterfall])
-from buildbot.steps import master, maxq, python, python_twisted, subunit
-modules.extend([master, maxq, python, python_twisted, subunit])
-from buildbot.steps import trigger, vstudio
-modules.extend([trigger, vstudio])
-from buildbot.steps.package.rpm import rpmbuild, rpmlint, rpmspec
-modules.extend([rpmbuild, rpmlint, rpmspec])
-from buildbot.util import eventual
-modules.extend([eventual])
-
-# require gobject
-#import buildbot.clients.gtkPanes
-#import buildbot.clients.debug
-
-# requires mercurial
-#import buildbot.changes.hgbuildbot
-
-# requires libboto
-#import buildbot.ec2buildslave
-
-# requires libvirt
-#import buildbot.libvirtbuildslave
-
-# requires pycrypto
-#import buildbot.manhole
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_base.py
deleted file mode 100644
index 250115aa..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_base.py
+++ /dev/null
@@ -1,228 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot import config, locks
-from buildbot.buildslave import base
-from buildbot.test.fake import fakemaster, pbmanager
-from buildbot.test.fake.botmaster import FakeBotMaster
-
-class TestAbstractBuildSlave(unittest.TestCase):
-
- class ConcreteBuildSlave(base.AbstractBuildSlave):
- pass
-
- def test_constructor_minimal(self):
- bs = self.ConcreteBuildSlave('bot', 'pass')
- self.assertEqual(bs.slavename, 'bot')
- self.assertEqual(bs.password, 'pass')
- self.assertEqual(bs.max_builds, None)
- self.assertEqual(bs.notify_on_missing, [])
- self.assertEqual(bs.missing_timeout, 3600)
- self.assertEqual(bs.properties.getProperty('slavename'), 'bot')
- self.assertEqual(bs.access, [])
- self.assertEqual(bs.keepalive_interval, 3600)
-
- def test_constructor_full(self):
- lock1, lock2 = mock.Mock(name='lock1'), mock.Mock(name='lock2')
- bs = self.ConcreteBuildSlave('bot', 'pass',
- max_builds=2,
- notify_on_missing=['me@me.com'],
- missing_timeout=120,
- properties={'a':'b'},
- locks=[lock1, lock2],
- keepalive_interval=60)
- self.assertEqual(bs.max_builds, 2)
- self.assertEqual(bs.notify_on_missing, ['me@me.com'])
- self.assertEqual(bs.missing_timeout, 120)
- self.assertEqual(bs.properties.getProperty('a'), 'b')
- self.assertEqual(bs.access, [lock1, lock2])
- self.assertEqual(bs.keepalive_interval, 60)
-
- def test_constructor_notify_on_missing_not_list(self):
- bs = self.ConcreteBuildSlave('bot', 'pass',
- notify_on_missing='foo@foo.com')
- # turned into a list:
- self.assertEqual(bs.notify_on_missing, ['foo@foo.com'])
-
- def test_constructor_notify_on_missing_not_string(self):
- self.assertRaises(config.ConfigErrors, lambda :
- self.ConcreteBuildSlave('bot', 'pass',
- notify_on_missing=['a@b.com', 13]))
-
- @defer.inlineCallbacks
- def do_test_reconfigService(self, old, old_port, new, new_port):
- master = self.master = fakemaster.make_master()
- old.master = master
- if old_port:
- self.old_registration = old.registration = \
- pbmanager.FakeRegistration(master.pbmanager, old_port, old.slavename)
- old.registered_port = old_port
- old.missing_timer = mock.Mock(name='missing_timer')
- old.startService()
-
- new_config = mock.Mock()
- new_config.slavePortnum = new_port
- new_config.slaves = [ new ]
-
- yield old.reconfigService(new_config)
-
- @defer.inlineCallbacks
- def test_reconfigService_attrs(self):
- old = self.ConcreteBuildSlave('bot', 'pass',
- max_builds=2,
- notify_on_missing=['me@me.com'],
- missing_timeout=120,
- properties={'a':'b'},
- keepalive_interval=60)
- new = self.ConcreteBuildSlave('bot', 'pass',
- max_builds=3,
- notify_on_missing=['her@me.com'],
- missing_timeout=121,
- properties={'a':'c'},
- keepalive_interval=61)
-
- old.updateSlave = mock.Mock(side_effect=lambda : defer.succeed(None))
-
- yield self.do_test_reconfigService(old, 'tcp:1234', new, 'tcp:1234')
-
- self.assertEqual(old.max_builds, 3)
- self.assertEqual(old.notify_on_missing, ['her@me.com'])
- self.assertEqual(old.missing_timeout, 121)
- self.assertEqual(old.properties.getProperty('a'), 'c')
- self.assertEqual(old.keepalive_interval, 61)
- self.assertEqual(self.master.pbmanager._registrations, [])
- self.assertTrue(old.updateSlave.called)
-
- @defer.inlineCallbacks
- def test_reconfigService_has_properties(self):
- old = self.ConcreteBuildSlave('bot', 'pass')
- yield self.do_test_reconfigService(old, 'tcp:1234', old, 'tcp:1234')
- self.assertTrue(old.properties.getProperty('slavename'), 'bot')
-
- @defer.inlineCallbacks
- def test_reconfigService_initial_registration(self):
- old = self.ConcreteBuildSlave('bot', 'pass')
- yield self.do_test_reconfigService(old, None, old, 'tcp:1234')
- self.assertEqual(self.master.pbmanager._registrations, [('tcp:1234', 'bot', 'pass')])
-
- @defer.inlineCallbacks
- def test_reconfigService_reregister_password(self):
- old = self.ConcreteBuildSlave('bot', 'pass')
- new = self.ConcreteBuildSlave('bot', 'newpass')
-
- yield self.do_test_reconfigService(old, 'tcp:1234', new, 'tcp:1234')
-
- self.assertEqual(old.password, 'newpass')
- self.assertEqual(self.master.pbmanager._unregistrations, [('tcp:1234', 'bot')])
- self.assertEqual(self.master.pbmanager._registrations, [('tcp:1234', 'bot', 'newpass')])
-
- @defer.inlineCallbacks
- def test_reconfigService_reregister_port(self):
- old = self.ConcreteBuildSlave('bot', 'pass')
- new = self.ConcreteBuildSlave('bot', 'pass')
-
- yield self.do_test_reconfigService(old, 'tcp:1234', new, 'tcp:5678')
-
- self.assertEqual(self.master.pbmanager._unregistrations, [('tcp:1234', 'bot')])
- self.assertEqual(self.master.pbmanager._registrations, [('tcp:5678', 'bot', 'pass')])
-
- @defer.inlineCallbacks
- def test_stopService(self):
- master = self.master = fakemaster.make_master()
- slave = self.ConcreteBuildSlave('bot', 'pass')
- slave.master = master
- slave.startService()
-
- config = mock.Mock()
- config.slavePortnum = "tcp:1234"
- config.slaves = [ slave ]
-
- yield slave.reconfigService(config)
- yield slave.stopService()
-
- self.assertEqual(self.master.pbmanager._unregistrations, [('tcp:1234', 'bot')])
- self.assertEqual(self.master.pbmanager._registrations, [('tcp:1234', 'bot', 'pass')])
-
- # FIXME: Test that reconfig properly deals with
- # 1) locks
- # 2) telling slave about builder
- # 3) missing timer
- # in both the initial config and a reconfiguration.
-
- def test_startMissingTimer_no_parent(self):
- bs = self.ConcreteBuildSlave('bot', 'pass',
- notify_on_missing=['abc'],
- missing_timeout=10)
- bs.startMissingTimer()
- self.assertEqual(bs.missing_timer, None)
-
- def test_startMissingTimer_no_timeout(self):
- bs = self.ConcreteBuildSlave('bot', 'pass',
- notify_on_missing=['abc'],
- missing_timeout=0)
- bs.parent = mock.Mock()
- bs.startMissingTimer()
- self.assertEqual(bs.missing_timer, None)
-
- def test_startMissingTimer_no_notify(self):
- bs = self.ConcreteBuildSlave('bot', 'pass',
- missing_timeout=3600)
- bs.parent = mock.Mock()
- bs.startMissingTimer()
- self.assertEqual(bs.missing_timer, None)
-
- def test_missing_timer(self):
- bs = self.ConcreteBuildSlave('bot', 'pass',
- notify_on_missing=['abc'],
- missing_timeout=100)
- bs.parent = mock.Mock()
- bs.startMissingTimer()
- self.assertNotEqual(bs.missing_timer, None)
- bs.stopMissingTimer()
- self.assertEqual(bs.missing_timer, None)
-
- def test_setServiceParent_started(self):
- master = self.master = fakemaster.make_master()
- botmaster = FakeBotMaster(master)
- botmaster.startService()
- bs = self.ConcreteBuildSlave('bot', 'pass')
- bs.setServiceParent(botmaster)
- self.assertEqual(bs.botmaster, botmaster)
- self.assertEqual(bs.master, master)
-
- def test_setServiceParent_masterLocks(self):
- """
- http://trac.buildbot.net/ticket/2278
- """
- master = self.master = fakemaster.make_master()
- botmaster = FakeBotMaster(master)
- botmaster.startService()
- lock = locks.MasterLock('masterlock')
- bs = self.ConcreteBuildSlave('bot', 'pass', locks = [lock.access("counting")])
- bs.setServiceParent(botmaster)
-
- def test_setServiceParent_slaveLocks(self):
- """
- http://trac.buildbot.net/ticket/2278
- """
- master = self.master = fakemaster.make_master()
- botmaster = FakeBotMaster(master)
- botmaster.startService()
- lock = locks.SlaveLock('lock')
- bs = self.ConcreteBuildSlave('bot', 'pass', locks = [lock.access("counting")])
- bs.setServiceParent(botmaster)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_libvirt.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_libvirt.py
deleted file mode 100644
index 2478e46c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_libvirt.py
+++ /dev/null
@@ -1,282 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-from twisted.internet import defer, reactor, utils
-from twisted.python import failure
-from buildbot import config
-from buildbot.test.fake import libvirt
-from buildbot.test.util import compat
-from buildbot.buildslave import libvirt as libvirtbuildslave
-
-
-class TestLibVirtSlave(unittest.TestCase):
-
- class ConcreteBuildSlave(libvirtbuildslave.LibVirtSlave):
- pass
-
- def setUp(self):
- self.patch(libvirtbuildslave, "libvirt", libvirt)
- self.conn = libvirtbuildslave.Connection("test://")
- self.lvconn = self.conn.connection
-
- def test_constructor_nolibvirt(self):
- self.patch(libvirtbuildslave, "libvirt", None)
- self.assertRaises(config.ConfigErrors, self.ConcreteBuildSlave,
- 'bot', 'pass', None, 'path', 'path')
-
- def test_constructor_minimal(self):
- bs = self.ConcreteBuildSlave('bot', 'pass', self.conn, 'path', 'otherpath')
- yield bs._find_existing_deferred
- self.assertEqual(bs.slavename, 'bot')
- self.assertEqual(bs.password, 'pass')
- self.assertEqual(bs.connection, self.conn)
- self.assertEqual(bs.image, 'path')
- self.assertEqual(bs.base_image, 'otherpath')
- self.assertEqual(bs.keepalive_interval, 3600)
-
- @defer.inlineCallbacks
- def test_find_existing(self):
- d = self.lvconn.fake_add("bot")
-
- bs = self.ConcreteBuildSlave('bot', 'pass', self.conn, 'p', 'o')
- yield bs._find_existing_deferred
-
- self.assertEqual(bs.domain.domain, d)
- self.assertEqual(bs.substantiated, True)
-
- @defer.inlineCallbacks
- def test_prepare_base_image_none(self):
- self.patch(utils, "getProcessValue", mock.Mock())
- utils.getProcessValue.side_effect = lambda x,y: defer.succeed(0)
-
- bs = self.ConcreteBuildSlave('bot', 'pass', self.conn, 'p', None)
- yield bs._find_existing_deferred
- yield bs._prepare_base_image()
-
- self.assertEqual(utils.getProcessValue.call_count, 0)
-
- @defer.inlineCallbacks
- def test_prepare_base_image_cheap(self):
- self.patch(utils, "getProcessValue", mock.Mock())
- utils.getProcessValue.side_effect = lambda x,y: defer.succeed(0)
-
- bs = self.ConcreteBuildSlave('bot', 'pass', self.conn, 'p', 'o')
- yield bs._find_existing_deferred
- yield bs._prepare_base_image()
-
- utils.getProcessValue.assert_called_with(
- "qemu-img", ["create", "-b", "o", "-f", "qcow2", "p"])
-
- @defer.inlineCallbacks
- def test_prepare_base_image_full(self):
- pass
- self.patch(utils, "getProcessValue", mock.Mock())
- utils.getProcessValue.side_effect = lambda x,y: defer.succeed(0)
-
- bs = self.ConcreteBuildSlave('bot', 'pass', self.conn, 'p', 'o')
- yield bs._find_existing_deferred
- bs.cheap_copy = False
- yield bs._prepare_base_image()
-
- utils.getProcessValue.assert_called_with(
- "cp", ["o", "p"])
-
- @defer.inlineCallbacks
- def test_start_instance(self):
- bs = self.ConcreteBuildSlave('b', 'p', self.conn, 'p', 'o',
- xml='<xml/>')
-
- prep = mock.Mock()
- prep.side_effect = lambda: defer.succeed(0)
- self.patch(bs, "_prepare_base_image", prep)
-
- yield bs._find_existing_deferred
- started = yield bs.start_instance(mock.Mock())
-
- self.assertEqual(started, True)
-
- @compat.usesFlushLoggedErrors
- @defer.inlineCallbacks
- def test_start_instance_create_fails(self):
- bs = self.ConcreteBuildSlave('b', 'p', self.conn, 'p', 'o',
- xml='<xml/>')
-
- prep = mock.Mock()
- prep.side_effect = lambda: defer.succeed(0)
- self.patch(bs, "_prepare_base_image", prep)
-
- create = mock.Mock()
- create.side_effect = lambda self : defer.fail(
- failure.Failure(RuntimeError('oh noes')))
- self.patch(libvirtbuildslave.Connection, 'create', create)
-
- yield bs._find_existing_deferred
- started = yield bs.start_instance(mock.Mock())
-
- self.assertEqual(bs.domain, None)
- self.assertEqual(started, False)
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
-
- @defer.inlineCallbacks
- def setup_canStartBuild(self):
- bs = self.ConcreteBuildSlave('b', 'p', self.conn, 'p', 'o')
- yield bs._find_existing_deferred
- bs.updateLocks()
- defer.returnValue(bs)
-
- @defer.inlineCallbacks
- def test_canStartBuild(self):
- bs = yield self.setup_canStartBuild()
- self.assertEqual(bs.canStartBuild(), True)
-
- @defer.inlineCallbacks
- def test_canStartBuild_notready(self):
- """
- If a LibVirtSlave hasnt finished scanning for existing VMs then we shouldn't
- start builds on it as it might create a 2nd VM when we want to reuse the existing
- one.
- """
- bs = yield self.setup_canStartBuild()
- bs.ready = False
- self.assertEqual(bs.canStartBuild(), False)
-
- @defer.inlineCallbacks
- def test_canStartBuild_domain_and_not_connected(self):
- """
- If we've found that the VM this slave would instance already exists but hasnt
- connected then we shouldn't start builds or we'll end up with a dupe.
- """
- bs = yield self.setup_canStartBuild()
- bs.domain = mock.Mock()
- self.assertEqual(bs.canStartBuild(), False)
-
- @defer.inlineCallbacks
- def test_canStartBuild_domain_and_connected(self):
- """
- If we've found an existing VM and it is connected then we should start builds
- """
- bs = yield self.setup_canStartBuild()
- bs.domain = mock.Mock()
- isconnected = mock.Mock()
- isconnected.return_value = True
- self.patch(bs, "isConnected", isconnected)
- self.assertEqual(bs.canStartBuild(), True)
-
-
-class TestWorkQueue(unittest.TestCase):
-
- def setUp(self):
- self.queue = libvirtbuildslave.WorkQueue()
-
- def delayed_success(self):
- def work():
- d = defer.Deferred()
- reactor.callLater(0, d.callback, True)
- return d
- return work
-
- def delayed_errback(self):
- def work():
- d = defer.Deferred()
- reactor.callLater(0, d.errback,
- failure.Failure(RuntimeError("Test failure")))
- return d
- return work
-
- def expect_errback(self, d):
- def shouldnt_get_called(f):
- self.failUnlessEqual(True, False)
- d.addCallback(shouldnt_get_called)
- def errback(f):
- #log.msg("errback called?")
- pass
- d.addErrback(errback)
- return d
-
- def test_handle_exceptions(self):
- def work():
- raise ValueError
- return self.expect_errback(self.queue.execute(work))
-
- def test_handle_immediate_errback(self):
- def work():
- return defer.fail(RuntimeError("Sad times"))
- return self.expect_errback(self.queue.execute(work))
-
- def test_handle_delayed_errback(self):
- work = self.delayed_errback()
- return self.expect_errback(self.queue.execute(work))
-
- def test_handle_immediate_success(self):
- def work():
- return defer.succeed(True)
- return self.queue.execute(work)
-
- def test_handle_delayed_success(self):
- work = self.delayed_success()
- return self.queue.execute(work)
-
- def test_single_pow_fires(self):
- return self.queue.execute(self.delayed_success())
-
- def test_single_pow_errors_gracefully(self):
- d = self.queue.execute(self.delayed_errback())
- return self.expect_errback(d)
-
- def test_fail_doesnt_break_further_work(self):
- self.expect_errback(self.queue.execute(self.delayed_errback()))
- return self.queue.execute(self.delayed_success())
-
- def test_second_pow_fires(self):
- self.queue.execute(self.delayed_success())
- return self.queue.execute(self.delayed_success())
-
- def test_work(self):
- # We want these deferreds to fire in order
- flags = {1: False, 2: False, 3: False }
-
- # When first deferred fires, flags[2] and flags[3] should still be false
- # flags[1] shouldnt already be set, either
- d1 = self.queue.execute(self.delayed_success())
- def cb1(res):
- self.failUnlessEqual(flags[1], False)
- flags[1] = True
- self.failUnlessEqual(flags[2], False)
- self.failUnlessEqual(flags[3], False)
- d1.addCallback(cb1)
-
- # When second deferred fires, only flags[3] should be set
- # flags[2] should definitely be False
- d2 = self.queue.execute(self.delayed_success())
- def cb2(res):
- assert flags[2] == False
- flags[2] = True
- assert flags[1] == True
- assert flags[3] == False
- d2.addCallback(cb2)
-
- # When third deferred fires, only flags[3] should be unset
- d3 = self.queue.execute(self.delayed_success())
- def cb3(res):
- assert flags[3] == False
- flags[3] = True
- assert flags[1] == True
- assert flags[2] == True
- d3.addCallback(cb3)
-
- return defer.DeferredList([d1, d2, d3], fireOnOneErrback=True)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_openstack.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_openstack.py
deleted file mode 100644
index dcb0916f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_buildslave_openstack.py
+++ /dev/null
@@ -1,110 +0,0 @@
-# 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.
-#
-# Portions Copyright Buildbot Team Members
-# Portions Copyright 2013 Cray Inc.
-
-import mock
-from twisted.trial import unittest
-from buildbot import config, interfaces
-from buildbot.buildslave import openstack
-import buildbot.test.fake.openstack as novaclient
-
-class TestOpenStackBuildSlave(unittest.TestCase):
-
- def setUp(self):
- self.patch(openstack, "nce", novaclient)
- self.patch(openstack, "client", novaclient)
-
- def test_constructor_nonova(self):
- self.patch(openstack, "nce", None)
- self.patch(openstack, "client", None)
- self.assertRaises(config.ConfigErrors,
- openstack.OpenStackLatentBuildSlave, 'bot', 'pass', flavor=1,
- image='image', os_username='user', os_password='pass',
- os_tenant_name='tenant', os_auth_url='auth')
-
- def test_constructor_minimal(self):
- bs = openstack.OpenStackLatentBuildSlave('bot', 'pass', flavor=1,
- image='image', os_username='user', os_password='pass',
- os_tenant_name='tenant', os_auth_url='auth')
- self.assertEqual(bs.slavename, 'bot')
- self.assertEqual(bs.password, 'pass')
- self.assertEqual(bs.flavor, 1)
- self.assertEqual(bs.image, 'image')
- self.assertEqual(bs.os_username, 'user')
- self.assertEqual(bs.os_password, 'pass')
- self.assertEqual(bs.os_tenant_name, 'tenant')
- self.assertEqual(bs.os_auth_url, 'auth')
-
- def test_getImage_string(self):
- bs = openstack.OpenStackLatentBuildSlave('bot', 'pass', flavor=1,
- image='image-uuid', os_username='user', os_password='pass',
- os_tenant_name='tenant', os_auth_url='auth')
- self.assertEqual('image-uuid', bs._getImage(None))
-
- def test_getImage_callable(self):
- def image_callable(images):
- return images[0]
-
- bs = openstack.OpenStackLatentBuildSlave('bot', 'pass', flavor=1,
- image=image_callable, os_username='user', os_password='pass',
- os_tenant_name='tenant', os_auth_url='auth')
- os_client = novaclient.Client('user', 'pass', 'tenant', 'auth')
- os_client.images.images = ['uuid1', 'uuid2', 'uuid2']
- self.assertEqual('uuid1', bs._getImage(os_client))
-
- def test_start_instance_already_exists(self):
- bs = openstack.OpenStackLatentBuildSlave('bot', 'pass', flavor=1,
- image='image-uuid', os_username='user', os_password='pass',
- os_tenant_name='tenant', os_auth_url='auth')
- bs.instance = mock.Mock()
- self.assertRaises(ValueError, bs.start_instance, None)
-
- def test_start_instance_fail_to_find(self):
- bs = openstack.OpenStackLatentBuildSlave('bot', 'pass', flavor=1,
- image='image-uuid', os_username='user', os_password='pass',
- os_tenant_name='tenant', os_auth_url='auth')
- bs._poll_resolution = 0
- self.patch(novaclient.Servers, 'fail_to_get', True)
- self.assertRaises(interfaces.LatentBuildSlaveFailedToSubstantiate,
- bs._start_instance)
-
- def test_start_instance_fail_to_start(self):
- bs = openstack.OpenStackLatentBuildSlave('bot', 'pass', flavor=1,
- image='image-uuid', os_username='user', os_password='pass',
- os_tenant_name='tenant', os_auth_url='auth')
- bs._poll_resolution = 0
- self.patch(novaclient.Servers, 'fail_to_start', True)
- self.assertRaises(interfaces.LatentBuildSlaveFailedToSubstantiate,
- bs._start_instance)
-
- def test_start_instance_success(self):
- bs = openstack.OpenStackLatentBuildSlave('bot', 'pass', flavor=1,
- image='image-uuid', os_username='user', os_password='pass',
- os_tenant_name='tenant', os_auth_url='auth')
- bs._poll_resolution = 0
- uuid, image_uuid, time_waiting = bs._start_instance()
- self.assertTrue(uuid)
- self.assertEqual(image_uuid, 'image-uuid')
- self.assertTrue(time_waiting)
-
- def test_start_instance_check_meta(self):
- meta_arg = {'some_key': 'some-value'}
- bs = openstack.OpenStackLatentBuildSlave('bot', 'pass', flavor=1,
- image='image-uuid', os_username='user', os_password='pass',
- os_tenant_name='tenant', os_auth_url='auth', meta=meta_arg)
- bs._poll_resolution = 0
- uuid, image_uuid, time_waiting = bs._start_instance()
- self.assertIn('meta', bs.instance.boot_kwargs)
- self.assertIdentical(bs.instance.boot_kwargs['meta'], meta_arg)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_base.py
deleted file mode 100644
index 5024b3c6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_base.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from twisted.internet import defer, reactor, task
-from buildbot.test.util import changesource, compat
-from buildbot.changes import base
-
-class TestPollingChangeSource(changesource.ChangeSourceMixin, unittest.TestCase):
- class Subclass(base.PollingChangeSource):
- pass
-
- def setUp(self):
- # patch in a Clock so we can manipulate the reactor's time
- self.clock = task.Clock()
- self.patch(reactor, 'callLater', self.clock.callLater)
- self.patch(reactor, 'seconds', self.clock.seconds)
-
- d = self.setUpChangeSource()
- def create_changesource(_):
- self.attachChangeSource(self.Subclass())
- d.addCallback(create_changesource)
- return d
-
- def tearDown(self):
- return self.tearDownChangeSource()
-
- def runClockFor(self, _, secs):
- self.clock.pump([1.0] * secs)
-
- def test_loop_loops(self):
- # track when poll() gets called
- loops = []
- self.changesource.poll = \
- lambda : loops.append(self.clock.seconds())
-
- self.changesource.pollInterval = 5
- self.startChangeSource()
-
- d = defer.Deferred()
- d.addCallback(self.runClockFor, 12)
- def check(_):
- # note that it does *not* poll at time 0
- self.assertEqual(loops, [5.0, 10.0])
- d.addCallback(check)
- reactor.callWhenRunning(d.callback, None)
- return d
-
- @compat.usesFlushLoggedErrors
- def test_loop_exception(self):
- # track when poll() gets called
- loops = []
- def poll():
- loops.append(self.clock.seconds())
- raise RuntimeError("oh noes")
- self.changesource.poll = poll
-
- self.changesource.pollInterval = 5
- self.startChangeSource()
-
- d = defer.Deferred()
- d.addCallback(self.runClockFor, 12)
- def check(_):
- # note that it keeps looping after error
- self.assertEqual(loops, [5.0, 10.0])
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 2)
- d.addCallback(check)
- reactor.callWhenRunning(d.callback, None)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_bonsaipoller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_bonsaipoller.py
deleted file mode 100644
index 03338876..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_bonsaipoller.py
+++ /dev/null
@@ -1,283 +0,0 @@
-# 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
-
-from copy import deepcopy
-import re
-
-from twisted.trial import unittest
-from twisted.internet import defer
-from twisted.web import client
-from buildbot.test.util import changesource
-from buildbot.util import epoch2datetime
-from buildbot.changes.bonsaipoller import FileNode, CiNode, BonsaiResult, \
- BonsaiParser, BonsaiPoller, InvalidResultError, EmptyResult
-
-log1 = "Add Bug 338541a"
-who1 = "sar@gmail.com"
-date1 = 1161908700
-log2 = "bug 357427 add static ctor/dtor methods"
-who2 = "aarrg@ooacm.org"
-date2 = 1161910620
-log3 = "Testing log #3 lbah blah"
-who3 = "huoents@hueont.net"
-date3 = 1089822728
-rev1 = "1.8"
-file1 = "mozilla/testing/mochitest/tests/index.html"
-rev2 = "1.1"
-file2 = "mozilla/testing/mochitest/tests/test_bug338541.xhtml"
-rev3 = "1.1812"
-file3 = "mozilla/xpcom/threads/nsAutoLock.cpp"
-rev4 = "1.3"
-file4 = "mozilla/xpcom/threads/nsAutoLock.h"
-rev5 = "2.4"
-file5 = "mozilla/xpcom/threads/test.cpp"
-
-nodes = []
-files = []
-files.append(FileNode(rev1,file1))
-nodes.append(CiNode(log1, who1, date1, files))
-
-files = []
-files.append(FileNode(rev2, file2))
-files.append(FileNode(rev3, file3))
-nodes.append(CiNode(log2, who2, date2, files))
-
-nodes.append(CiNode(log3, who3, date3, []))
-
-goodParsedResult = BonsaiResult(nodes)
-
-goodUnparsedResult = """\
-<?xml version="1.0"?>
-<queryResults>
-<ci who="%s" date="%d">
- <log>%s</log>
- <files>
- <f rev="%s">%s</f>
- </files>
-</ci>
-<ci who="%s" date="%d">
- <log>%s</log>
- <files>
- <f rev="%s">%s</f>
- <f rev="%s">%s</f>
- </files>
-</ci>
-<ci who="%s" date="%d">
- <log>%s</log>
- <files>
- </files>
-</ci>
-</queryResults>
-""" % (who1, date1, log1, rev1, file1,
- who2, date2, log2, rev2, file2, rev3, file3,
- who3, date3, log3)
-
-badUnparsedResult = deepcopy(goodUnparsedResult)
-badUnparsedResult = badUnparsedResult.replace("</queryResults>", "")
-
-invalidDateResult = deepcopy(goodUnparsedResult)
-invalidDateResult = invalidDateResult.replace(str(date1), "foobar")
-
-missingFilenameResult = deepcopy(goodUnparsedResult)
-missingFilenameResult = missingFilenameResult.replace(file2, "")
-
-duplicateLogResult = deepcopy(goodUnparsedResult)
-duplicateLogResult = re.sub("<log>"+log1+"</log>",
- "<log>blah</log><log>blah</log>",
- duplicateLogResult)
-
-duplicateFilesResult = deepcopy(goodUnparsedResult)
-duplicateFilesResult = re.sub("<files>\s*</files>",
- "<files></files><files></files>",
- duplicateFilesResult)
-
-missingCiResult = deepcopy(goodUnparsedResult)
-r = re.compile("<ci.*</ci>", re.DOTALL | re.MULTILINE)
-missingCiResult = re.sub(r, "", missingCiResult)
-
-badResultMsgs = { 'badUnparsedResult':
- "BonsaiParser did not raise an exception when given a bad query",
- 'invalidDateResult':
- "BonsaiParser did not raise an exception when given an invalid date",
- 'missingRevisionResult':
- "BonsaiParser did not raise an exception when a revision was missing",
- 'missingFilenameResult':
- "BonsaiParser did not raise an exception when a filename was missing",
- 'duplicateLogResult':
- "BonsaiParser did not raise an exception when there was two <log> tags",
- 'duplicateFilesResult':
- "BonsaiParser did not raise an exception when there was two <files> tags",
- 'missingCiResult':
- "BonsaiParser did not raise an exception when there was no <ci> tags"
-}
-
-noCheckinMsgResult = """\
-<?xml version="1.0"?>
-<queryResults>
-<ci who="johndoe@domain.tld" date="12345678">
- <log></log>
- <files>
- <f rev="1.1">first/file.ext</f>
- </files>
-</ci>
-<ci who="johndoe@domain.tld" date="12345678">
- <log></log>
- <files>
- <f rev="1.2">second/file.ext</f>
- </files>
-</ci>
-<ci who="johndoe@domain.tld" date="12345678">
- <log></log>
- <files>
- <f rev="1.3">third/file.ext</f>
- </files>
-</ci>
-</queryResults>
-"""
-
-noCheckinMsgRef = [dict(filename="first/file.ext",
- revision="1.1"),
- dict(filename="second/file.ext",
- revision="1.2"),
- dict(filename="third/file.ext",
- revision="1.3")]
-
-class TestBonsaiParser(unittest.TestCase):
- def testFullyFormedResult(self):
- br = BonsaiParser(goodUnparsedResult)
- result = br.getData()
- # make sure the result is a BonsaiResult
- self.failUnless(isinstance(result, BonsaiResult))
- # test for successful parsing
- self.failUnlessEqual(goodParsedResult, result,
- "BonsaiParser did not return the expected BonsaiResult")
-
- def testBadUnparsedResult(self):
- try:
- BonsaiParser(badUnparsedResult)
- self.fail(badResultMsgs["badUnparsedResult"])
- except InvalidResultError:
- pass
-
- def testInvalidDateResult(self):
- try:
- BonsaiParser(invalidDateResult)
- self.fail(badResultMsgs["invalidDateResult"])
- except InvalidResultError:
- pass
-
- def testMissingFilenameResult(self):
- try:
- BonsaiParser(missingFilenameResult)
- self.fail(badResultMsgs["missingFilenameResult"])
- except InvalidResultError:
- pass
-
- def testDuplicateLogResult(self):
- try:
- BonsaiParser(duplicateLogResult)
- self.fail(badResultMsgs["duplicateLogResult"])
- except InvalidResultError:
- pass
-
- def testDuplicateFilesResult(self):
- try:
- BonsaiParser(duplicateFilesResult)
- self.fail(badResultMsgs["duplicateFilesResult"])
- except InvalidResultError:
- pass
-
- def testMissingCiResult(self):
- try:
- BonsaiParser(missingCiResult)
- self.fail(badResultMsgs["missingCiResult"])
- except EmptyResult:
- pass
-
- def testMergeEmptyLogMsg(self):
- """Ensure that BonsaiPoller works around the bonsai xml output
- issue when the check-in comment is empty"""
- bp = BonsaiParser(noCheckinMsgResult)
- result = bp.getData()
- self.failUnlessEqual(len(result.nodes), 1)
- self.failUnlessEqual(result.nodes[0].who, "johndoe@domain.tld")
- self.failUnlessEqual(result.nodes[0].date, 12345678)
- self.failUnlessEqual(result.nodes[0].log, "")
- for file, ref in zip(result.nodes[0].files, noCheckinMsgRef):
- self.failUnlessEqual(file.filename, ref['filename'])
- self.failUnlessEqual(file.revision, ref['revision'])
-
-class TestBonsaiPoller(changesource.ChangeSourceMixin, unittest.TestCase):
- def setUp(self):
- d = self.setUpChangeSource()
- def create_poller(_):
- self.attachChangeSource(BonsaiPoller('http://bonsai.mozilla.org',
- 'all', 'seamonkey'))
- d.addCallback(create_poller)
- return d
-
- def tearDown(self):
- return self.tearDownChangeSource()
-
- def fakeGetPage(self, result):
- """Install a fake getPage that puts the requested URL in C{self.getPage_got_url}
- and return C{result}"""
- self.getPage_got_url = None
- def fake(url, timeout=None):
- self.getPage_got_url = url
- return defer.succeed(result)
- self.patch(client, "getPage", fake)
-
- # tests
-
- def test_describe(self):
- assert re.search(r'bonsai\.mozilla\.org', self.changesource.describe())
-
- def test_poll_bad(self):
- # Make sure a change is not submitted if the BonsaiParser fails, and
- # that the poll operation catches the exception correctly
- self.fakeGetPage(badUnparsedResult)
- d = self.changesource.poll()
- def check(_):
- self.assertEqual(len(self.changes_added), 0)
- d.addCallback(check)
- return d
-
- def test_poll_good(self):
- self.fakeGetPage(goodUnparsedResult)
- d = self.changesource.poll()
- def check(_):
- self.assertEqual(len(self.changes_added), 3)
- self.assertEqual(self.changes_added[0]['author'], who1)
- self.assertEqual(self.changes_added[0]['when_timestamp'],
- epoch2datetime(date1))
- self.assertEqual(self.changes_added[0]['comments'], log1)
- self.assertEqual(self.changes_added[0]['branch'], 'seamonkey')
- self.assertEqual(self.changes_added[0]['files'],
- [ '%s (revision %s)' % (file1, rev1) ])
- self.assertEqual(self.changes_added[1]['author'], who2)
- self.assertEqual(self.changes_added[1]['when_timestamp'],
- epoch2datetime(date2))
- self.assertEqual(self.changes_added[1]['comments'], log2)
- self.assertEqual(self.changes_added[1]['files'],
- [ '%s (revision %s)' % (file2, rev2),
- '%s (revision %s)' % (file3, rev3) ])
- self.assertEqual(self.changes_added[2]['author'], who3)
- self.assertEqual(self.changes_added[2]['comments'], log3)
- self.assertEqual(self.changes_added[2]['when_timestamp'],
- epoch2datetime(date3))
- self.assertEqual(self.changes_added[2]['files'], [])
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_changes.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_changes.py
deleted file mode 100644
index 6dcee925..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_changes.py
+++ /dev/null
@@ -1,113 +0,0 @@
-# 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 textwrap
-import re
-from twisted.trial import unittest
-from buildbot.test.fake import fakedb
-from buildbot.changes import changes
-
-class Change(unittest.TestCase):
-
- change23_rows = [
- fakedb.Change(changeid=23, author="dustin", comments="fix whitespace",
- is_dir=0, 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='slave/README.txt'),
-
- fakedb.ChangeProperty(changeid=23, property_name='notest',
- property_value='["no","Change"]'),
-
- fakedb.ChangeUser(changeid=23, uid=27),
- ]
-
- def setUp(self):
- self.change23 = changes.Change(**dict( # using **dict(..) forces kwargs
- category='devel',
- isdir=0,
- repository=u'git://warner',
- codebase=u'mainapp',
- who=u'dustin',
- when=266738404,
- comments=u'fix whitespace',
- project=u'Buildbot',
- branch=u'warnerdb',
- revlink=u'http://warner/0e92a098b',
- properties={'notest':"no"},
- files=[u'master/README.txt', u'slave/README.txt'],
- revision=u'deadbeef'))
- self.change23.number = 23
-
- 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(u'''\
- Files:
- master/README.txt
- slave/README.txt
- On: git://warner
- For: Buildbot
- At: .*
- Changed 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': u'warnerdb',
- 'category': u'devel',
- 'codebase': u'mainapp',
- 'comments': u'fix whitespace',
- 'files': [{'name': u'master/README.txt'},
- {'name': u'slave/README.txt'}],
- 'number': 23,
- 'project': u'Buildbot',
- 'properties': [('notest', 'no', 'Change')],
- 'repository': u'git://warner',
- 'rev': u'deadbeef',
- 'revision': u'deadbeef',
- 'revlink': u'http://warner/0e92a098b',
- 'when': 266738404,
- 'who': u'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(), {})
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_filter.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_filter.py
deleted file mode 100644
index 35c2d316..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_filter.py
+++ /dev/null
@@ -1,129 +0,0 @@
-# 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 re
-
-from twisted.trial import unittest
-
-from buildbot.changes import filter
-from buildbot.test.fake.state import State
-
-class Change(State):
- project = ''
- repository = ''
- branch = ''
- category = ''
- codebase = ''
-
-class ChangeFilter(unittest.TestCase):
-
- def setUp(self):
- self.results = [] # (got, expected, msg)
- self.filt = None
-
- def tearDown(self):
- if self.results:
- raise RuntimeError("test forgot to call check()")
-
- def setfilter(self, **kwargs):
- self.filt = filter.ChangeFilter(**kwargs)
-
- def yes(self, change, msg):
- self.results.append((self.filt.filter_change(change), True, msg))
-
- def no(self, change, msg):
- self.results.append((self.filt.filter_change(change), False, msg))
-
- def check(self):
- errs = []
- for r in self.results:
- if (r[0] or r[1]) and not (r[0] and r[1]):
- errs.append(r[2])
- self.results = []
- if errs:
- self.fail("; ".join(errs))
-
- def test_filter_change_filter_fn(self):
- self.setfilter(filter_fn = lambda ch : ch.x > 3)
- self.no(Change(x=2), "filter_fn returns False")
- self.yes(Change(x=4), "filter_fn returns True")
- self.check()
-
- def test_filter_change_filt_str(self):
- self.setfilter(project = "myproj")
- self.no(Change(project="yourproj"), "non-matching PROJECT returns False")
- self.yes(Change(project="myproj"), "matching PROJECT returns True")
- self.check()
-
- def test_filter_change_filt_list(self):
- self.setfilter(repository = ["vc://a", "vc://b"])
- self.yes(Change(repository="vc://a"), "matching REPOSITORY vc://a returns True")
- self.yes(Change(repository="vc://b"), "matching REPOSITORY vc://b returns True")
- self.no(Change(repository="vc://c"), "non-matching REPOSITORY returns False")
- self.no(Change(repository=None), "None for REPOSITORY returns False")
- self.check()
-
- def test_filter_change_filt_list_None(self):
- self.setfilter(branch = ["mybr", None])
- self.yes(Change(branch="mybr"), "matching BRANCH mybr returns True")
- self.yes(Change(branch=None), "matching BRANCH None returns True")
- self.no(Change(branch="misc"), "non-matching BRANCH returns False")
- self.check()
-
- def test_filter_change_filt_re(self):
- self.setfilter(category_re = "^a.*")
- self.yes(Change(category="albert"), "matching CATEGORY returns True")
- self.no(Change(category="boris"), "non-matching CATEGORY returns False")
- self.check()
-
- def test_filter_change_branch_re(self): # regression - see #927
- self.setfilter(branch_re = "^t.*")
- self.yes(Change(branch="trunk"), "matching BRANCH returns True")
- self.no(Change(branch="development"), "non-matching BRANCH returns False")
- self.no(Change(branch=None), "branch=None returns False")
- self.check()
-
- def test_filter_change_filt_re_compiled(self):
- self.setfilter(category_re = re.compile("^b.*", re.I))
- self.no(Change(category="albert"), "non-matching CATEGORY returns False")
- self.yes(Change(category="boris"), "matching CATEGORY returns True")
- self.yes(Change(category="Bruce"), "matching CATEGORY returns True, using re.I")
- self.check()
-
- def test_filter_change_combination(self):
- self.setfilter(project='p', repository='r', branch='b', category='c',
- codebase='cb')
- self.no(Change(project='x', repository='x', branch='x', category='x'),
- "none match -> False")
- self.no(Change(project='p', repository='r', branch='b', category='x'),
- "three match -> False")
- self.no(Change(project='p', repository='r', branch='b', category='c',
- codebase='x'), "four match -> False")
- self.yes(Change(project='p', repository='r', branch='b', category='c',
- codebase='cb'), "all match -> True")
- self.check()
-
- def test_filter_change_combination_filter_fn(self):
- self.setfilter(project='p', repository='r', branch='b', category='c',
- filter_fn = lambda c : c.ff)
- self.no(Change(project='x', repository='x', branch='x', category='x', ff=False),
- "none match and fn returns False -> False")
- self.no(Change(project='p', repository='r', branch='b', category='c', ff=False),
- "all match and fn returns False -> False")
- self.no(Change(project='x', repository='x', branch='x', category='x', ff=True),
- "none match and fn returns True -> False")
- self.yes(Change(project='p', repository='r', branch='b', category='c', ff=True),
- "all match and fn returns True -> False")
- self.check()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_gerritchangesource.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_gerritchangesource.py
deleted file mode 100644
index bcd8fe32..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_gerritchangesource.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.util import json
-from buildbot.test.util import changesource
-from buildbot.changes import gerritchangesource
-
-class TestGerritChangeSource(changesource.ChangeSourceMixin,
- unittest.TestCase):
- def setUp(self):
- return self.setUpChangeSource()
-
- def tearDown(self):
- return self.tearDownChangeSource()
-
- def newChangeSource(self, host, user):
- s = gerritchangesource.GerritChangeSource(host, user)
- self.attachChangeSource(s)
- return s
-
- # tests
-
- def test_describe(self):
- s = self.newChangeSource('somehost', 'someuser')
- self.assertSubstring("GerritChangeSource", s.describe())
-
- # TODO: test the backoff algorithm
-
- # this variable is reused in test_steps_source_repo
- # to ensure correct integration between change source and repo step
- expected_change = {'category': u'patchset-created',
- 'files': ['unknown'],
- 'repository': u'ssh://someuser@somehost:29418/pr',
- 'author': u'Dustin <dustin@mozilla.com>',
- 'comments': u'fix 1234',
- 'project': u'pr',
- 'branch': u'br/4321',
- 'revlink': u'http://buildbot.net',
- 'properties': {u'event.change.owner.email': u'dustin@mozilla.com',
- u'event.change.subject': u'fix 1234',
- u'event.change.project': u'pr',
- u'event.change.owner.name': u'Dustin',
- u'event.change.number': u'4321',
- u'event.change.url': u'http://buildbot.net',
- u'event.change.branch': u'br',
- u'event.type': u'patchset-created',
- u'event.patchSet.revision': u'abcdef',
- u'event.patchSet.number': u'12'},
- u'revision': u'abcdef'}
-
- def test_lineReceived_patchset_created(self):
- s = self.newChangeSource('somehost', 'someuser')
- d = s.lineReceived(json.dumps(dict(
- type="patchset-created",
- change=dict(
- branch="br",
- project="pr",
- number="4321",
- owner=dict(name="Dustin", email="dustin@mozilla.com"),
- url="http://buildbot.net",
- subject="fix 1234"
- ),
- patchSet=dict(revision="abcdef", number="12")
- )))
-
- def check(_):
- self.failUnlessEqual(len(self.changes_added), 1)
- c = self.changes_added[0]
- for k, v in c.items():
- self.assertEqual(self.expected_change[k], v)
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_gitpoller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_gitpoller.py
deleted file mode 100644
index 3067492a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_gitpoller.py
+++ /dev/null
@@ -1,580 +0,0 @@
-# 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 os
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.changes import base, gitpoller
-from buildbot.test.util import changesource, config, gpo
-from buildbot.util import epoch2datetime
-
-# Test that environment variables get propagated to subprocesses (See #2116)
-os.environ['TEST_THAT_ENVIRONMENT_GETS_PASSED_TO_SUBPROCESSES'] = 'TRUE'
-
-class GitOutputParsing(gpo.GetProcessOutputMixin, unittest.TestCase):
- """Test GitPoller methods for parsing git output"""
- def setUp(self):
- self.poller = gitpoller.GitPoller('git@example.com:foo/baz.git')
- self.setUpGetProcessOutput()
-
- dummyRevStr = '12345abcde'
- def _perform_git_output_test(self, methodToTest, args,
- desiredGoodOutput, desiredGoodResult,
- emptyRaisesException=True):
-
- # make this call to self.patch here so that we raise a SkipTest if it
- # is not supported
- self.expectCommands(
- gpo.Expect('git', *args)
- .path('gitpoller-work'),
- )
-
- d = defer.succeed(None)
- def call_empty(_):
- # we should get an Exception with empty output from git
- return methodToTest(self.dummyRevStr)
- d.addCallback(call_empty)
-
- def cb_empty(_):
- if emptyRaisesException:
- self.fail("getProcessOutput should have failed on empty output")
- def eb_empty(f):
- if not emptyRaisesException:
- self.fail("getProcessOutput should NOT have failed on empty output")
- d.addCallbacks(cb_empty, eb_empty)
- d.addCallback(lambda _: self.assertAllCommandsRan())
-
- # and the method shouldn't supress any exceptions
- self.expectCommands(
- gpo.Expect('git', *args)
- .path('gitpoller-work')
- .exit(1),
- )
- def call_exception(_):
- return methodToTest(self.dummyRevStr)
- d.addCallback(call_exception)
-
- def cb_exception(_):
- self.fail("getProcessOutput should have failed on stderr output")
- def eb_exception(f):
- pass
- d.addCallbacks(cb_exception, eb_exception)
- d.addCallback(lambda _: self.assertAllCommandsRan())
-
- # finally we should get what's expected from good output
- self.expectCommands(
- gpo.Expect('git', *args)
- .path('gitpoller-work')
- .stdout(desiredGoodOutput)
- )
- def call_desired(_):
- return methodToTest(self.dummyRevStr)
- d.addCallback(call_desired)
-
- def cb_desired(r):
- self.assertEquals(r, desiredGoodResult)
- d.addCallback(cb_desired)
- d.addCallback(lambda _: self.assertAllCommandsRan())
-
- def test_get_commit_author(self):
- authorStr = 'Sammy Jankis <email@example.com>'
- return self._perform_git_output_test(self.poller._get_commit_author,
- ['log', '--no-walk', '--format=%aN <%aE>', self.dummyRevStr, '--'],
- authorStr, authorStr)
-
- def test_get_commit_comments(self):
- commentStr = 'this is a commit message\n\nthat is multiline'
- return self._perform_git_output_test(self.poller._get_commit_comments,
- ['log', '--no-walk', '--format=%s%n%b', self.dummyRevStr, '--'],
- commentStr, commentStr)
-
- def test_get_commit_files(self):
- filesStr = 'file1\nfile2'
- return self._perform_git_output_test(self.poller._get_commit_files,
- ['log', '--name-only', '--no-walk', '--format=%n', self.dummyRevStr, '--'],
- filesStr, filesStr.split(), emptyRaisesException=False)
-
- def test_get_commit_timestamp(self):
- stampStr = '1273258009'
- return self._perform_git_output_test(self.poller._get_commit_timestamp,
- ['log', '--no-walk', '--format=%ct', self.dummyRevStr, '--'],
- stampStr, float(stampStr))
-
- # _get_changes is tested in TestGitPoller, below
-
-class TestGitPoller(gpo.GetProcessOutputMixin,
- changesource.ChangeSourceMixin,
- unittest.TestCase):
-
- REPOURL = 'git@example.com:foo/baz.git'
- REPOURL_QUOTED = 'git%40example.com%3Afoo%2Fbaz.git'
-
- def setUp(self):
- self.setUpGetProcessOutput()
- d = self.setUpChangeSource()
- def create_poller(_):
- self.poller = gitpoller.GitPoller(self.REPOURL)
- self.poller.master = self.master
- d.addCallback(create_poller)
- return d
-
- def tearDown(self):
- return self.tearDownChangeSource()
-
- def test_describe(self):
- self.assertSubstring("GitPoller", self.poller.describe())
-
- def test_poll_initial(self):
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work'),
- gpo.Expect('git', 'fetch', self.REPOURL,
- '+master:refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work'),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('bf0b01df6d00ae8d1ffa0b2e2acbe642a6cd35d5\n'),
- )
-
- d = self.poller.poll()
- @d.addCallback
- def cb(_):
- self.assertAllCommandsRan()
- self.assertEqual(self.poller.lastRev, {
- 'master': 'bf0b01df6d00ae8d1ffa0b2e2acbe642a6cd35d5'
- })
- self.master.db.state.assertStateByClass(
- name=self.REPOURL, class_name='GitPoller',
- lastRev={
- 'master': 'bf0b01df6d00ae8d1ffa0b2e2acbe642a6cd35d5'
- })
- return d
-
- def test_poll_failInit(self):
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work')
- .exit(1),
- )
-
- d = self.assertFailure(self.poller.poll(), EnvironmentError)
-
- d.addCallback(lambda _: self.assertAllCommandsRan)
- return d
-
- def test_poll_failFetch(self):
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work'),
- gpo.Expect('git', 'fetch', self.REPOURL,
- '+master:refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .exit(1),
- )
-
- d = self.assertFailure(self.poller.poll(), EnvironmentError)
- d.addCallback(lambda _: self.assertAllCommandsRan)
- return d
-
- def test_poll_failRevParse(self):
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work'),
- gpo.Expect('git', 'fetch', self.REPOURL,
- '+master:refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work'),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .exit(1),
- )
-
- d = self.poller.poll()
- @d.addCallback
- def cb(_):
- self.assertAllCommandsRan()
- self.assertEqual(len(self.flushLoggedErrors()), 1)
- self.assertEqual(self.poller.lastRev, {})
-
- def test_poll_failLog(self):
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work'),
- gpo.Expect('git', 'fetch', self.REPOURL,
- '+master:refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work'),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('4423cdbcbb89c14e50dd5f4152415afd686c5241\n'),
- gpo.Expect('git', 'log',
- '--format=%H',
- 'fa3ae8ed68e664d4db24798611b352e3c6509930..4423cdbcbb89c14e50dd5f4152415afd686c5241',
- '--')
- .path('gitpoller-work')
- .exit(1),
- )
-
- # do the poll
- self.poller.lastRev = {
- 'master': 'fa3ae8ed68e664d4db24798611b352e3c6509930'
- }
- d = self.poller.poll()
-
- @d.addCallback
- def cb(_):
- self.assertAllCommandsRan()
- self.assertEqual(len(self.flushLoggedErrors()), 1)
- self.assertEqual(self.poller.lastRev, {
- 'master': '4423cdbcbb89c14e50dd5f4152415afd686c5241'
- })
-
- def test_poll_nothingNew(self):
- # Test that environment variables get propagated to subprocesses
- # (See #2116)
- self.patch(os, 'environ', {'ENVVAR': 'TRUE'})
- self.addGetProcessOutputExpectEnv({'ENVVAR': 'TRUE'})
-
-
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work'),
- gpo.Expect('git', 'fetch', self.REPOURL,
- '+master:refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('no interesting output'),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('4423cdbcbb89c14e50dd5f4152415afd686c5241\n'),
- gpo.Expect('git', 'log',
- '--format=%H',
- '4423cdbcbb89c14e50dd5f4152415afd686c5241..4423cdbcbb89c14e50dd5f4152415afd686c5241',
- '--')
- .path('gitpoller-work')
- .stdout(''),
- )
-
- self.poller.lastRev = {
- 'master': '4423cdbcbb89c14e50dd5f4152415afd686c5241'
- }
- d = self.poller.poll()
- @d.addCallback
- def cb(_):
- self.assertAllCommandsRan()
- self.master.db.state.assertStateByClass(
- name=self.REPOURL, class_name='GitPoller',
- lastRev={
- 'master': '4423cdbcbb89c14e50dd5f4152415afd686c5241'
- })
- return d
-
- def test_poll_multipleBranches_initial(self):
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work'),
- gpo.Expect('git', 'fetch', self.REPOURL,
- '+master:refs/buildbot/%s/master' % self.REPOURL_QUOTED,
- '+release:refs/buildbot/%s/release' % self.REPOURL_QUOTED)
- .path('gitpoller-work'),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('4423cdbcbb89c14e50dd5f4152415afd686c5241\n'),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/release' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('9118f4ab71963d23d02d4bdc54876ac8bf05acf2'),
- )
-
- # do the poll
- self.poller.branches = ['master', 'release']
- d = self.poller.poll()
- @d.addCallback
- def cb(_):
- self.assertAllCommandsRan()
- self.assertEqual(self.poller.lastRev, {
- 'master': '4423cdbcbb89c14e50dd5f4152415afd686c5241',
- 'release': '9118f4ab71963d23d02d4bdc54876ac8bf05acf2'
- })
-
- return d
-
-
- def test_poll_multipleBranches(self):
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work'),
- gpo.Expect('git', 'fetch', self.REPOURL,
- '+master:refs/buildbot/%s/master' % self.REPOURL_QUOTED,
- '+release:refs/buildbot/%s/release' % self.REPOURL_QUOTED)
- .path('gitpoller-work'),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('4423cdbcbb89c14e50dd5f4152415afd686c5241\n'),
- gpo.Expect('git', 'log',
- '--format=%H',
- 'fa3ae8ed68e664d4db24798611b352e3c6509930..4423cdbcbb89c14e50dd5f4152415afd686c5241',
- '--')
- .path('gitpoller-work')
- .stdout('\n'.join([
- '64a5dc2a4bd4f558b5dd193d47c83c7d7abc9a1a',
- '4423cdbcbb89c14e50dd5f4152415afd686c5241'])),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/release' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('9118f4ab71963d23d02d4bdc54876ac8bf05acf2'),
- gpo.Expect('git', 'log',
- '--format=%H',
- 'bf0b01df6d00ae8d1ffa0b2e2acbe642a6cd35d5..9118f4ab71963d23d02d4bdc54876ac8bf05acf2',
- '--')
- .path('gitpoller-work')
- .stdout( '\n'.join([
- '9118f4ab71963d23d02d4bdc54876ac8bf05acf2'
- ])),
- )
-
- # and patch out the _get_commit_foo methods which were already tested
- # above
- def timestamp(rev):
- return defer.succeed(1273258009.0)
- self.patch(self.poller, '_get_commit_timestamp', timestamp)
- def author(rev):
- return defer.succeed('by:' + rev[:8])
- self.patch(self.poller, '_get_commit_author', author)
- def files(rev):
- return defer.succeed(['/etc/' + rev[:3]])
- self.patch(self.poller, '_get_commit_files', files)
- def comments(rev):
- return defer.succeed('hello!')
- self.patch(self.poller, '_get_commit_comments', comments)
-
- # do the poll
- self.poller.branches = ['master', 'release']
- self.poller.lastRev = {
- 'master': 'fa3ae8ed68e664d4db24798611b352e3c6509930',
- 'release': 'bf0b01df6d00ae8d1ffa0b2e2acbe642a6cd35d5'
- }
- d = self.poller.poll()
- @d.addCallback
- def cb(_):
- self.assertAllCommandsRan()
- self.assertEqual(self.poller.lastRev, {
- 'master': '4423cdbcbb89c14e50dd5f4152415afd686c5241',
- 'release': '9118f4ab71963d23d02d4bdc54876ac8bf05acf2'
- })
-
- self.assertEqual(len(self.changes_added), 3)
-
- self.assertEqual(self.changes_added[0]['author'], 'by:4423cdbc')
- self.assertEqual(self.changes_added[0]['when_timestamp'],
- epoch2datetime(1273258009))
- self.assertEqual(self.changes_added[0]['comments'], 'hello!')
- self.assertEqual(self.changes_added[0]['branch'], 'master')
- self.assertEqual(self.changes_added[0]['files'], [ '/etc/442' ])
- self.assertEqual(self.changes_added[0]['src'], 'git')
-
- self.assertEqual(self.changes_added[1]['author'], 'by:64a5dc2a')
- self.assertEqual(self.changes_added[1]['when_timestamp'],
- epoch2datetime(1273258009))
- self.assertEqual(self.changes_added[1]['comments'], 'hello!')
- self.assertEqual(self.changes_added[1]['files'], [ '/etc/64a' ])
- self.assertEqual(self.changes_added[1]['src'], 'git')
-
- self.assertEqual(self.changes_added[2]['author'], 'by:9118f4ab')
- self.assertEqual(self.changes_added[2]['when_timestamp'],
- epoch2datetime(1273258009))
- self.assertEqual(self.changes_added[2]['comments'], 'hello!')
- self.assertEqual(self.changes_added[2]['files'], [ '/etc/911' ])
- self.assertEqual(self.changes_added[2]['src'], 'git')
-
- return d
-
-
- def test_poll_noChanges(self):
- # Test that environment variables get propagated to subprocesses
- # (See #2116)
- self.patch(os, 'environ', {'ENVVAR': 'TRUE'})
- self.addGetProcessOutputExpectEnv({'ENVVAR': 'TRUE'})
-
-
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work'),
- gpo.Expect('git', 'fetch', self.REPOURL,
- '+master:refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('no interesting output'),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('4423cdbcbb89c14e50dd5f4152415afd686c5241\n'),
- gpo.Expect('git', 'log',
- '--format=%H',
- '4423cdbcbb89c14e50dd5f4152415afd686c5241..4423cdbcbb89c14e50dd5f4152415afd686c5241',
- '--')
- .path('gitpoller-work')
- .stdout(''),
- )
-
- self.poller.lastRev = {
- 'master': '4423cdbcbb89c14e50dd5f4152415afd686c5241'
- }
- d = self.poller.poll()
- @d.addCallback
- def cb(_):
- self.assertAllCommandsRan()
- self.assertEqual(self.poller.lastRev, {
- 'master': '4423cdbcbb89c14e50dd5f4152415afd686c5241'
- })
- return d
-
- def test_poll_old(self):
- # Test that environment variables get propagated to subprocesses
- # (See #2116)
- self.patch(os, 'environ', {'ENVVAR': 'TRUE'})
- self.addGetProcessOutputExpectEnv({'ENVVAR': 'TRUE'})
-
- # patch out getProcessOutput and getProcessOutputAndValue for the
- # benefit of the _get_changes method
- self.expectCommands(
- gpo.Expect('git', 'init', '--bare', 'gitpoller-work'),
- gpo.Expect('git', 'fetch', self.REPOURL,
- '+master:refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('no interesting output'),
- gpo.Expect('git', 'rev-parse',
- 'refs/buildbot/%s/master' % self.REPOURL_QUOTED)
- .path('gitpoller-work')
- .stdout('4423cdbcbb89c14e50dd5f4152415afd686c5241\n'),
- gpo.Expect('git', 'log',
- '--format=%H',
- 'fa3ae8ed68e664d4db24798611b352e3c6509930..4423cdbcbb89c14e50dd5f4152415afd686c5241',
- '--')
- .path('gitpoller-work')
- .stdout('\n'.join([
- '64a5dc2a4bd4f558b5dd193d47c83c7d7abc9a1a',
- '4423cdbcbb89c14e50dd5f4152415afd686c5241'
- ])),
- )
-
- # and patch out the _get_commit_foo methods which were already tested
- # above
- def timestamp(rev):
- return defer.succeed(1273258009.0)
- self.patch(self.poller, '_get_commit_timestamp', timestamp)
- def author(rev):
- return defer.succeed('by:' + rev[:8])
- self.patch(self.poller, '_get_commit_author', author)
- def files(rev):
- return defer.succeed(['/etc/' + rev[:3]])
- self.patch(self.poller, '_get_commit_files', files)
- def comments(rev):
- return defer.succeed('hello!')
- self.patch(self.poller, '_get_commit_comments', comments)
-
- # do the poll
- self.poller.lastRev = {
- 'master': 'fa3ae8ed68e664d4db24798611b352e3c6509930'
- }
- d = self.poller.poll()
-
- # check the results
- def check_changes(_):
- self.assertEqual(self.poller.lastRev, {
- 'master': '4423cdbcbb89c14e50dd5f4152415afd686c5241'
- })
- self.assertEqual(len(self.changes_added), 2)
- self.assertEqual(self.changes_added[0]['author'], 'by:4423cdbc')
- self.assertEqual(self.changes_added[0]['when_timestamp'],
- epoch2datetime(1273258009))
- self.assertEqual(self.changes_added[0]['comments'], 'hello!')
- self.assertEqual(self.changes_added[0]['branch'], 'master')
- self.assertEqual(self.changes_added[0]['files'], [ '/etc/442' ])
- self.assertEqual(self.changes_added[0]['src'], 'git')
- self.assertEqual(self.changes_added[1]['author'], 'by:64a5dc2a')
- self.assertEqual(self.changes_added[1]['when_timestamp'],
- epoch2datetime(1273258009))
- self.assertEqual(self.changes_added[1]['comments'], 'hello!')
- self.assertEqual(self.changes_added[1]['files'], [ '/etc/64a' ])
- self.assertEqual(self.changes_added[1]['src'], 'git')
- self.assertAllCommandsRan()
-
- self.master.db.state.assertStateByClass(
- name=self.REPOURL, class_name='GitPoller',
- lastRev={
- 'master': '4423cdbcbb89c14e50dd5f4152415afd686c5241'
- })
- d.addCallback(check_changes)
-
- return d
-
- # We mock out base.PollingChangeSource.startService, since it calls
- # reactor.callWhenRunning, which leaves a dirty reactor if a synchronous
- # deferred is returned from a test method.
- def test_startService(self):
- startService = mock.Mock()
- self.patch(base.PollingChangeSource, "startService", startService)
- d = self.poller.startService()
- def check(_):
- self.assertEqual(self.poller.workdir, os.path.join('basedir', 'gitpoller-work'))
- self.assertEqual(self.poller.lastRev, {})
- startService.assert_called_once_with(self.poller)
- d.addCallback(check)
- return d
-
- def test_startService_loadLastRev(self):
- startService = mock.Mock()
- self.patch(base.PollingChangeSource, "startService", startService)
- self.master.db.state.fakeState(
- name=self.REPOURL, class_name='GitPoller',
- lastRev={"master": "fa3ae8ed68e664d4db24798611b352e3c6509930"},
- )
-
- d = self.poller.startService()
- def check(_):
- self.assertEqual(self.poller.lastRev, {
- "master": "fa3ae8ed68e664d4db24798611b352e3c6509930"
- })
- startService.assert_called_once_with(self.poller)
- d.addCallback(check)
- return d
-
-
-class TestGitPollerConstructor(unittest.TestCase, config.ConfigErrorsMixin):
- def test_deprecatedFetchRefspec(self):
- self.assertRaisesConfigError("fetch_refspec is no longer supported",
- lambda: gitpoller.GitPoller("/tmp/git.git",
- fetch_refspec='not-supported'))
-
- def test_oldPollInterval(self):
- poller = gitpoller.GitPoller("/tmp/git.git", pollinterval=10)
- self.assertEqual(poller.pollInterval, 10)
-
- def test_branches_default(self):
- poller = gitpoller.GitPoller("/tmp/git.git")
- self.assertEqual(poller.branches, ["master"])
-
- def test_branches_oldBranch(self):
- poller = gitpoller.GitPoller("/tmp/git.git", branch='magic')
- self.assertEqual(poller.branches, ["magic"])
-
- def test_branches(self):
- poller = gitpoller.GitPoller("/tmp/git.git",
- branches=['magic', 'marker'])
- self.assertEqual(poller.branches, ["magic", "marker"])
-
- def test_branches_andBranch(self):
- self.assertRaisesConfigError("can't specify both branch and branches",
- lambda: gitpoller.GitPoller("/tmp/git.git",
- branch='bad', branches=['listy']))
-
- def test_gitbin_default(self):
- poller = gitpoller.GitPoller("/tmp/git.git")
- self.assertEqual(poller.gitbin, "git")
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_hgpoller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_hgpoller.py
deleted file mode 100644
index c6bf128b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_hgpoller.py
+++ /dev/null
@@ -1,178 +0,0 @@
-# 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 os
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.changes import hgpoller
-from buildbot.test.util import changesource, gpo
-from buildbot.test.fake.fakedb import FakeDBConnector
-from buildbot.util import epoch2datetime
-
-ENVIRON_2116_KEY = 'TEST_THAT_ENVIRONMENT_GETS_PASSED_TO_SUBPROCESSES'
-
-class TestHgPoller(gpo.GetProcessOutputMixin,
- changesource.ChangeSourceMixin,
- unittest.TestCase):
-
- def setUp(self):
- # To test that environment variables get propagated to subprocesses
- # (See #2116)
- os.environ[ENVIRON_2116_KEY] = 'TRUE'
- self.setUpGetProcessOutput()
- d = self.setUpChangeSource()
- self.remote_repo = 'ssh://example.com/foo/baz'
- self.repo_ready = True
- def _isRepositoryReady():
- return self.repo_ready
- def create_poller(_):
- self.poller = hgpoller.HgPoller(self.remote_repo,
- workdir='/some/dir')
- self.poller.master = self.master
- self.poller._isRepositoryReady = _isRepositoryReady
- def create_db(_):
- db = self.master.db = FakeDBConnector(self)
- return db.setup()
- d.addCallback(create_poller)
- d.addCallback(create_db)
- return d
-
- def tearDown(self):
- del os.environ[ENVIRON_2116_KEY]
- return self.tearDownChangeSource()
-
- def gpoFullcommandPattern(self, commandName, *expected_args):
- """Match if the command is commandName and arg list start as expected.
-
- This allows to test a bit more if expected GPO are issued, be it
- by obscure failures due to the result not being given.
- """
- def matchesSubcommand(bin, given_args, **kwargs):
- return bin == commandName and tuple(
- given_args[:len(expected_args)]) == expected_args
- return matchesSubcommand
-
- def test_describe(self):
- self.assertSubstring("HgPoller", self.poller.describe())
-
- def test_hgbin_default(self):
- self.assertEqual(self.poller.hgbin, "hg")
-
- def test_poll_initial(self):
- self.repo_ready = False
- # Test that environment variables get propagated to subprocesses
- # (See #2116)
- expected_env = {ENVIRON_2116_KEY: 'TRUE'}
- self.addGetProcessOutputExpectEnv(expected_env)
- self.expectCommands(
- gpo.Expect('hg', 'init', '/some/dir'),
- gpo.Expect('hg', 'pull', '-b', 'default',
- 'ssh://example.com/foo/baz')
- .path('/some/dir'),
- gpo.Expect('hg', 'heads', 'default', '--template={rev}' + os.linesep)
- .path('/some/dir').stdout("73591"),
- gpo.Expect('hg', 'log', '-b', 'default', '-r', '73591:73591', # only fetches that head
- '--template={rev}:{node}\\n')
- .path('/some/dir').stdout(os.linesep.join(['73591:4423cdb'])),
- gpo.Expect('hg', 'log', '-r', '4423cdb',
- '--template={date|hgdate}' + os.linesep + '{author}' + os.linesep + '{files}' + os.linesep + '{desc|strip}')
- .path('/some/dir').stdout(os.linesep.join([
- '1273258100.0 -7200',
- 'Bob Test <bobtest@example.org>',
- 'file1 dir/file2',
- 'This is rev 73591',
- ''])),
- )
-
- # do the poll
- d = self.poller.poll()
-
- # check the results
- def check_changes(_):
- self.assertEqual(len(self.changes_added), 1)
-
- change = self.changes_added[0]
- self.assertEqual(change['revision'], '4423cdb')
- self.assertEqual(change['author'],
- 'Bob Test <bobtest@example.org>')
- self.assertEqual(change['when_timestamp'],
- epoch2datetime(1273258100)),
- self.assertEqual(change['files'], ['file1', 'dir/file2'])
- self.assertEqual(change['src'], 'hg')
- self.assertEqual(change['branch'], 'default')
- self.assertEqual(change['comments'], 'This is rev 73591')
-
- d.addCallback(check_changes)
- d.addCallback(self.check_current_rev(73591))
- return d
-
- def check_current_rev(self, wished):
- def check_on_rev(_):
- d = self.poller._getCurrentRev()
- d.addCallback(lambda oid_rev: self.assertEqual(oid_rev[1], wished))
- return check_on_rev
-
- @defer.inlineCallbacks
- def test_poll_several_heads(self):
- # If there are several heads on the named branch, the poller musn't
- # climb (good enough for now, ideally it should even go to the common
- # ancestor)
- self.expectCommands(
- gpo.Expect('hg', 'pull', '-b', 'default',
- 'ssh://example.com/foo/baz')
- .path('/some/dir'),
- gpo.Expect('hg', 'heads', 'default', '--template={rev}' + os.linesep)
- .path('/some/dir').stdout('5' + os.linesep + '6' + os.linesep),
- )
-
- yield self.poller._setCurrentRev(3)
-
- # do the poll: we must stay at rev 3
- d = self.poller.poll()
- d.addCallback(self.check_current_rev(3))
-
- @defer.inlineCallbacks
- def test_poll_regular(self):
- # normal operation. There's a previous revision, we get a new one.
- self.expectCommands(
- gpo.Expect('hg', 'pull', '-b', 'default',
- 'ssh://example.com/foo/baz')
- .path('/some/dir'),
- gpo.Expect('hg', 'heads', 'default', '--template={rev}' + os.linesep)
- .path('/some/dir').stdout('5' + os.linesep),
- gpo.Expect('hg', 'log', '-b', 'default', '-r', '5:5',
- '--template={rev}:{node}\\n')
- .path('/some/dir').stdout('5:784bd' + os.linesep),
- gpo.Expect('hg', 'log', '-r', '784bd',
- '--template={date|hgdate}' + os.linesep + '{author}' + os.linesep + '{files}' + os.linesep + '{desc|strip}')
- .path('/some/dir').stdout(os.linesep.join([
- '1273258009.0 -7200',
- 'Joe Test <joetest@example.org>',
- 'file1 file2',
- 'Comment for rev 5',
- ''])),
- )
-
- yield self.poller._setCurrentRev(4)
-
- d = self.poller.poll()
- d.addCallback(self.check_current_rev(5))
-
- def check_changes(_):
- self.assertEquals(len(self.changes_added), 1)
- change = self.changes_added[0]
- self.assertEqual(change['revision'], '784bd')
- self.assertEqual(change['comments'], 'Comment for rev 5')
- d.addCallback(check_changes)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_mail.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_mail.py
deleted file mode 100644
index d4c7d210..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_mail.py
+++ /dev/null
@@ -1,99 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os
-from twisted.trial import unittest
-from buildbot.test.util import changesource, dirs
-from buildbot.changes import mail
-
-class TestMaildirSource(changesource.ChangeSourceMixin, dirs.DirsMixin,
- unittest.TestCase):
-
- def setUp(self):
- self.maildir = os.path.abspath("maildir")
-
- d = self.setUpChangeSource()
- d.addCallback(lambda _ : self.setUpDirs(self.maildir))
- return d
-
- def populateMaildir(self):
- "create a fake maildir with a fake new message ('newmsg') in it"
- newdir = os.path.join(self.maildir, "new")
- os.makedirs(newdir)
-
- curdir = os.path.join(self.maildir, "cur")
- os.makedirs(curdir)
-
- fake_message = "Subject: test\n\nthis is a test"
- mailfile = os.path.join(newdir, "newmsg")
- with open(mailfile, "w") as f:
- f.write(fake_message)
-
- def assertMailProcessed(self):
- self.assertFalse(os.path.exists(os.path.join(self.maildir, "new", "newmsg")))
- self.assertTrue(os.path.exists(os.path.join(self.maildir, "cur", "newmsg")))
-
- def tearDown(self):
- d = self.tearDownDirs()
- d.addCallback(lambda _ : self.tearDownChangeSource())
- return d
-
- # tests
-
- def test_describe(self):
- mds = mail.MaildirSource(self.maildir)
- self.assertSubstring(self.maildir, mds.describe())
-
- def test_messageReceived_svn(self):
- self.populateMaildir()
- mds = mail.MaildirSource(self.maildir)
- self.attachChangeSource(mds)
-
- # monkey-patch in a parse method
- def parse(message, prefix):
- assert 'this is a test' in message.get_payload()
- return ('svn', dict(fake_chdict=1))
- mds.parse = parse
-
- d = mds.messageReceived('newmsg')
- def check(_):
- self.assertMailProcessed()
- self.assertEqual(len(self.changes_added), 1)
- self.assertEqual(self.changes_added[0]['fake_chdict'], 1)
- self.assertEqual(self.changes_added[0]['src'], 'svn')
- d.addCallback(check)
- return d
-
- def test_messageReceived_bzr(self):
- self.populateMaildir()
- mds = mail.MaildirSource(self.maildir)
- self.attachChangeSource(mds)
-
- # monkey-patch in a parse method
- def parse(message, prefix):
- assert 'this is a test' in message.get_payload()
- return ('bzr', dict(fake_chdict=1))
- mds.parse = parse
-
- d = mds.messageReceived('newmsg')
- def check(_):
- self.assertMailProcessed()
- self.assertEqual(len(self.changes_added), 1)
- self.assertEqual(self.changes_added[0]['fake_chdict'], 1)
- self.assertEqual(self.changes_added[0]['src'], 'bzr')
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_mail_CVSMaildirSource.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_mail_CVSMaildirSource.py
deleted file mode 100644
index 44e3c7ef..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_mail_CVSMaildirSource.py
+++ /dev/null
@@ -1,214 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-
-from email import message_from_string
-from email.Utils import parsedate_tz, mktime_tz
-from buildbot.changes.mail import CVSMaildirSource
-
-#
-# Sample message from CVS version 1.11
-#
-
-cvs1_11_msg = """From: Andy Howell <andy@example.com>
-To: buildbot@example.com
-Subject: cvs module MyModuleName
-Date: Sat, 07 Aug 2010 11:11:49 +0000
-X-Mailer: Python buildbot-cvs-mail $Revision: 1.3 $
-
-Cvsmode: 1.11
-Category: None
-CVSROOT: :ext:cvshost.example.com:/cvsroot
-Files: base/module/src/make GNUmakefile,1.362,1.363
-Project: MyModuleName
-Update of /cvsroot/base/moduel/src/make
-In directory cvshost:/tmp/cvs-serv10922
-
-Modified Files:
- GNUmakefile
-Log Message:
-Commented out some stuff.
-"""
-
-#
-# Sample message from CVS version 1.12
-#
-# Paths are handled differently by the two versions
-#
-
-cvs1_12_msg="""Date: Wed, 11 Aug 2010 04:56:44 +0000
-From: andy@example.com
-To: buildbot@example.com
-Subject: cvs update for project RaiCore
-X-Mailer: Python buildbot-cvs-mail $Revision: 1.3 $
-
-Cvsmode: 1.12
-Category: None
-CVSROOT: :ext:cvshost.example.com:/cvsroot
-Files: file1.cpp 1.77 1.78 file2.cpp 1.75 1.76
-Path: base/module/src
-Project: MyModuleName
-Update of /cvsroot/base/module/src
-In directory example.com:/tmp/cvs-serv26648/InsightMonAgent
-
-Modified Files:
- file1.cpp file2.cpp
-Log Message:
-Changes for changes sake
-"""
-
-class TestCVSMaildirSource(unittest.TestCase):
- def test_CVSMaildirSource_create_change_from_cvs1_11msg(self):
- m = message_from_string(cvs1_11_msg)
- src = CVSMaildirSource('/dev/null')
- try:
- src, chdict = src.parse( m )
- except:
- self.fail('Failed to get change from email message.')
- self.assert_(chdict != None)
- self.assert_(chdict['author'] == 'andy')
- self.assert_(len(chdict['files']) == 1)
- self.assert_(chdict['files'][0] == 'base/module/src/make/GNUmakefile')
- self.assert_(chdict['comments'] == 'Commented out some stuff.\n')
- self.assert_(chdict['isdir'] == False)
- self.assert_(chdict['revision'] == '2010-08-07 11:11:49')
- dateTuple = parsedate_tz('Sat, 07 Aug 2010 11:11:49 +0000')
- self.assert_(chdict['when'] == mktime_tz(dateTuple))
- self.assert_(chdict['branch'] == None)
- self.assert_(chdict['repository'] == ':ext:cvshost.example.com:/cvsroot')
- self.assert_(chdict['project'] == 'MyModuleName')
- self.assert_(len(chdict['properties']) == 0)
- self.assert_(src == 'cvs')
-
- def test_CVSMaildirSource_create_change_from_cvs1_12msg(self):
- m = message_from_string(cvs1_12_msg)
- src = CVSMaildirSource('/dev/null')
- try:
- src, chdict = src.parse( m )
- except:
- self.fail('Failed to get change from email message.')
- self.assert_(chdict != None)
- self.assert_(chdict['author'] == 'andy')
- self.assert_(len(chdict['files']) == 2)
- self.assert_(chdict['files'][0] == 'base/module/src/file1.cpp')
- self.assert_(chdict['files'][1] == 'base/module/src/file2.cpp')
- self.assert_(chdict['comments'] == 'Changes for changes sake\n')
- self.assert_(chdict['isdir'] == False)
- self.assert_(chdict['revision'] == '2010-08-11 04:56:44')
- dateTuple = parsedate_tz('Wed, 11 Aug 2010 04:56:44 +0000')
- self.assert_(chdict['when'] == mktime_tz(dateTuple))
- self.assert_(chdict['branch'] == None)
- self.assert_(chdict['repository'] == ':ext:cvshost.example.com:/cvsroot')
- self.assert_(chdict['project'] == 'MyModuleName')
- self.assert_(len(chdict['properties']) == 0)
- self.assert_(src == 'cvs')
-
- def test_CVSMaildirSource_create_change_from_cvs1_12_with_no_path(self):
- msg = cvs1_12_msg.replace('Path: base/module/src', '')
- m = message_from_string(msg)
- src = CVSMaildirSource('/dev/null')
- try:
- assert src.parse( m )[1]
- except ValueError:
- pass
- else:
- self.fail('Expect ValueError.')
-
- def test_CVSMaildirSource_create_change_with_bad_cvsmode(self):
- # Branch is indicated afer 'Tag:' in modified file list
- msg = cvs1_11_msg.replace('Cvsmode: 1.11', 'Cvsmode: 9.99')
- m = message_from_string(msg)
- src = CVSMaildirSource('/dev/null')
- try:
- assert src.parse( m )[1]
- except ValueError:
- pass
- else:
- self.fail('Expected ValueError')
-
- def test_CVSMaildirSource_create_change_with_branch(self):
- # Branch is indicated afer 'Tag:' in modified file list
- msg = cvs1_11_msg.replace(' GNUmakefile',
- ' Tag: Test_Branch\n GNUmakefile')
- m = message_from_string(msg)
- src = CVSMaildirSource('/dev/null')
- try:
- chdict = src.parse( m )[1]
- except:
- self.fail('Failed to get change from email message.')
- self.assert_(chdict['branch'] == 'Test_Branch')
-
- def test_CVSMaildirSource_create_change_with_category(self):
- msg = cvs1_11_msg.replace('Category: None', 'Category: Test category')
- m = message_from_string(msg)
- src = CVSMaildirSource('/dev/null')
- try:
- chdict = src.parse( m )[1]
- except:
- self.fail('Failed to get change from email message.')
- self.assert_(chdict['category'] == 'Test category')
-
- def test_CVSMaildirSource_create_change_with_no_comment(self):
- # Strip off comments
- msg = cvs1_11_msg[:cvs1_11_msg.find('Commented out some stuff')]
- m = message_from_string(msg)
- src = CVSMaildirSource('/dev/null')
- try:
- chdict = src.parse( m )[1]
- except:
- self.fail('Failed to get change from email message.')
- self.assert_(chdict['comments'] == None )
-
- def test_CVSMaildirSource_create_change_with_no_files(self):
- # A message with no files is likely not for us
- msg = cvs1_11_msg.replace('Files: base/module/src/make GNUmakefile,1.362,1.363','')
- m = message_from_string(msg)
- src = CVSMaildirSource('/dev/null')
- try:
- chdict = src.parse( m )
- except:
- self.fail('Failed to get change from email message.')
- self.assert_(chdict == None )
-
- def test_CVSMaildirSource_create_change_with_no_project(self):
- msg = cvs1_11_msg.replace('Project: MyModuleName', '')
- m = message_from_string(msg)
- src = CVSMaildirSource('/dev/null')
- try:
- chdict = src.parse( m )[1]
- except:
- self.fail('Failed to get change from email message.')
- self.assert_(chdict['project'] == None )
-
- def test_CVSMaildirSource_create_change_with_no_repository(self):
- msg = cvs1_11_msg.replace('CVSROOT: :ext:cvshost.example.com:/cvsroot', '')
- m = message_from_string(msg)
- src = CVSMaildirSource('/dev/null')
- try:
- chdict = src.parse( m )[1]
- except:
- self.fail('Failed to get change from email message.')
- self.assert_(chdict['repository'] == None )
-
- def test_CVSMaildirSource_create_change_with_property(self):
- m = message_from_string(cvs1_11_msg)
- propDict = { 'foo' : 'bar' }
- src = CVSMaildirSource('/dev/null', properties=propDict)
- try:
- chdict = src.parse( m )[1]
- except:
- self.fail('Failed to get change from email message.')
- self.assert_(chdict['properties']['foo'] == 'bar')
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_manager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_manager.py
deleted file mode 100644
index 7eaec2ee..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_manager.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-from twisted.application import service
-from buildbot.changes import manager
-
-class FakeChangeSource(service.Service):
- pass
-
-class TestChangeManager(unittest.TestCase):
- def setUp(self):
- self.master = mock.Mock()
- self.cm = manager.ChangeManager(self.master)
- self.new_config = mock.Mock()
-
- def make_sources(self, n):
- for i in range(n):
- src = FakeChangeSource()
- src.setName('ChangeSource %d' % i)
- yield src
-
- def test_reconfigService_add(self):
- src1, src2 = self.make_sources(2)
- src1.setServiceParent(self.cm)
- self.new_config.change_sources = [ src1, src2 ]
-
- d = self.cm.reconfigService(self.new_config)
- @d.addCallback
- def check(_):
- self.assertIdentical(src2.parent, self.cm)
- self.assertIdentical(src2.master, self.master)
- return d
-
- def test_reconfigService_remove(self):
- src1, = self.make_sources(1)
- src1.setServiceParent(self.cm)
- self.new_config.change_sources = [ ]
-
- d = self.cm.reconfigService(self.new_config)
- @d.addCallback
- def check(_):
- self.assertIdentical(src1.parent, None)
- self.assertIdentical(src1.master, None)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_p4poller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_p4poller.py
deleted file mode 100644
index 02e0f67f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_p4poller.py
+++ /dev/null
@@ -1,238 +0,0 @@
-# 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 time
-from twisted.trial import unittest
-from buildbot.changes.p4poller import P4Source, get_simple_split, P4PollerError
-from buildbot.test.util import changesource, gpo
-from buildbot.util import epoch2datetime
-
-first_p4changes = \
-"""Change 1 on 2006/04/13 by slamb@testclient 'first rev'
-"""
-
-second_p4changes = \
-"""Change 3 on 2006/04/13 by bob@testclient 'short desc truncated'
-Change 2 on 2006/04/13 by slamb@testclient 'bar'
-"""
-
-third_p4changes = \
-"""Change 5 on 2006/04/13 by mpatel@testclient 'first rev'
-"""
-
-change_4_log = \
-"""Change 4 by mpatel@testclient on 2006/04/13 21:55:39
-
- short desc truncated because this is a long description.
-"""
-
-change_3_log = \
-u"""Change 3 by bob@testclient on 2006/04/13 21:51:39
-
- short desc truncated because this is a long description.
- ASDF-GUI-P3-\u2018Upgrade Icon\u2019 disappears sometimes.
-"""
-
-change_2_log = \
-"""Change 2 by slamb@testclient on 2006/04/13 21:46:23
-
- creation
-"""
-
-p4change = {
- 3: change_3_log +
-"""Affected files ...
-
-... //depot/myproject/branch_b/branch_b_file#1 add
-... //depot/myproject/branch_b/whatbranch#1 branch
-... //depot/myproject/branch_c/whatbranch#1 branch
-""",
- 2: change_2_log +
-"""Affected files ...
-
-... //depot/myproject/trunk/whatbranch#1 add
-... //depot/otherproject/trunk/something#1 add
-""",
- 5: change_4_log +
-"""Affected files ...
-
-... //depot/myproject/branch_b/branch_b_file#1 add
-... //depot/myproject/branch_b#75 edit
-... //depot/myproject/branch_c/branch_c_file#1 add
-""",
-}
-
-
-class TestP4Poller(changesource.ChangeSourceMixin,
- gpo.GetProcessOutputMixin,
- unittest.TestCase):
- def setUp(self):
- self.setUpGetProcessOutput()
- return self.setUpChangeSource()
-
- def tearDown(self):
- return self.tearDownChangeSource()
-
- def add_p4_describe_result(self, number, result):
- self.expectCommands(
- gpo.Expect('p4', 'describe', '-s', str(number)).stdout(result))
-
- def makeTime(self, timestring):
- datefmt = '%Y/%m/%d %H:%M:%S'
- when = time.mktime(time.strptime(timestring, datefmt))
- return epoch2datetime(when)
-
- # tests
-
- def test_describe(self):
- self.attachChangeSource(
- P4Source(p4port=None, p4user=None,
- p4base='//depot/myproject/',
- split_file=lambda x: x.split('/', 1)))
- self.assertSubstring("p4source", self.changesource.describe())
-
- def do_test_poll_successful(self, **kwargs):
- encoding = kwargs.get('encoding', 'utf8')
- self.attachChangeSource(
- P4Source(p4port=None, p4user=None,
- p4base='//depot/myproject/',
- split_file=lambda x: x.split('/', 1),
- **kwargs))
- self.expectCommands(
- gpo.Expect('p4', 'changes', '-m', '1', '//depot/myproject/...').stdout(first_p4changes),
- gpo.Expect('p4', 'changes', '//depot/myproject/...@2,now').stdout(second_p4changes),
- )
- encoded_p4change = p4change.copy()
- encoded_p4change[3] = encoded_p4change[3].encode(encoding)
- self.add_p4_describe_result(2, encoded_p4change[2])
- self.add_p4_describe_result(3, encoded_p4change[3])
-
- # The first time, it just learns the change to start at.
- self.assert_(self.changesource.last_change is None)
- d = self.changesource.poll()
- def check_first_check(_):
- self.assertEquals(self.changes_added, [])
- self.assertEquals(self.changesource.last_change, 1)
- d.addCallback(check_first_check)
-
- # Subsequent times, it returns Change objects for new changes.
- d.addCallback(lambda _ : self.changesource.poll())
- def check_second_check(res):
- self.assertEquals(len(self.changes_added), 3)
- self.assertEquals(self.changesource.last_change, 3)
-
- # They're supposed to go oldest to newest, so this one must be first.
- self.assertEquals(self.changes_added[0],
- dict(author='slamb',
- files=['whatbranch'],
- project='',
- comments=change_2_log,
- revision='2',
- when_timestamp=self.makeTime("2006/04/13 21:46:23"),
- branch='trunk'))
-
- # These two can happen in either order, since they're from the same
- # Perforce change.
- if self.changes_added[1]['branch'] == 'branch_c':
- self.changes_added[1:] = reversed(self.changes_added[1:])
-
- self.assertEquals(self.changes_added[1],
- dict(author='bob',
- files=['branch_b_file',
- 'whatbranch'],
- project='',
- comments=change_3_log, # converted to unicode correctly
- revision='3',
- when_timestamp=self.makeTime("2006/04/13 21:51:39"),
- branch='branch_b'))
- self.assertEquals(self.changes_added[2],
- dict(author='bob',
- files=['whatbranch'],
- project='',
- comments=change_3_log, # converted to unicode correctly
- revision='3',
- when_timestamp=self.makeTime("2006/04/13 21:51:39"),
- branch='branch_c'))
- self.assertAllCommandsRan()
- d.addCallback(check_second_check)
- return d
-
- def test_poll_successful_default_encoding(self):
- return self.do_test_poll_successful()
-
- def test_poll_successful_macroman_encoding(self):
- return self.do_test_poll_successful(encoding='macroman')
-
- def test_poll_failed_changes(self):
- self.attachChangeSource(
- P4Source(p4port=None, p4user=None,
- p4base='//depot/myproject/',
- split_file=lambda x: x.split('/', 1)))
- self.expectCommands(
- gpo.Expect('p4', 'changes', '-m', '1', '//depot/myproject/...').stdout('Perforce client error:\n...'))
-
- # call _poll, so we can catch the failure
- d = self.changesource._poll()
- return self.assertFailure(d, P4PollerError)
-
- def test_poll_failed_describe(self):
- self.attachChangeSource(
- P4Source(p4port=None, p4user=None,
- p4base='//depot/myproject/',
- split_file=lambda x: x.split('/', 1)))
- self.expectCommands(
- gpo.Expect('p4', 'changes', '//depot/myproject/...@3,now').stdout(second_p4changes),
- )
- self.add_p4_describe_result(2, p4change[2])
- self.add_p4_describe_result(3, 'Perforce client error:\n...')
-
- self.changesource.last_change = 2 # tell poll() that it's already been called once
-
- # call _poll, so we can catch the failure
- d = self.changesource._poll()
- self.assertFailure(d, P4PollerError)
- @d.addCallback
- def check(_):
- # check that 2 was processed OK
- self.assertEquals(self.changesource.last_change, 2)
- self.assertAllCommandsRan()
- return d
-
- def test_poll_split_file(self):
- """Make sure split file works on branch only changes"""
- self.attachChangeSource(
- P4Source(p4port=None, p4user=None,
- p4base='//depot/myproject/',
- split_file=get_simple_split))
- self.expectCommands(
- gpo.Expect('p4', 'changes', '//depot/myproject/...@51,now').stdout(third_p4changes),
- )
- self.add_p4_describe_result(5, p4change[5])
-
- self.changesource.last_change = 50
- d = self.changesource.poll()
- def check(res):
- self.assertEquals(len(self.changes_added), 2)
- self.assertEquals(self.changesource.last_change, 5)
- self.assertAllCommandsRan()
- d.addCallback(check)
- return d
-
-class TestSplit(unittest.TestCase):
- def test_get_simple_split(self):
- self.assertEqual(get_simple_split('foo/bar'), ('foo', 'bar'))
- self.assertEqual(get_simple_split('foo-bar'), (None, None))
- self.assertEqual(get_simple_split('/bar'), ('', 'bar'))
- self.assertEqual(get_simple_split('foo/'), ('foo', ''))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_pb.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_pb.py
deleted file mode 100644
index 6a34b5d6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_pb.py
+++ /dev/null
@@ -1,265 +0,0 @@
-# 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
-
-
-"""
-Test the PB change source.
-"""
-
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.changes import pb
-from buildbot.test.util import changesource, pbmanager
-from buildbot.util import epoch2datetime
-
-class TestPBChangeSource(
- changesource.ChangeSourceMixin,
- pbmanager.PBManagerMixin,
- unittest.TestCase):
-
- def setUp(self):
- self.setUpPBChangeSource()
- d = self.setUpChangeSource()
- @d.addCallback
- def setup(_):
- self.master.pbmanager = self.pbmanager
-
- return d
-
- def test_registration_no_slaveport(self):
- return self._test_registration(None,
- user='alice', passwd='sekrit')
-
- def test_registration_global_slaveport(self):
- return self._test_registration(('9999', 'alice', 'sekrit'),
- slavePort='9999', user='alice', passwd='sekrit')
-
- def test_registration_custom_port(self):
- return self._test_registration(('8888', 'alice', 'sekrit'),
- user='alice', passwd='sekrit', port='8888')
-
- def test_registration_no_userpass(self):
- return self._test_registration(('9939', 'change', 'changepw'),
- slavePort='9939')
-
- def test_registration_no_userpass_no_global(self):
- return self._test_registration(None)
-
- @defer.inlineCallbacks
- def _test_registration(self, exp_registration, slavePort=None,
- **constr_kwargs):
- config = mock.Mock()
- config.slavePortnum = slavePort
- self.attachChangeSource(pb.PBChangeSource(**constr_kwargs))
-
- self.startChangeSource()
- yield self.changesource.reconfigService(config)
-
- if exp_registration:
- self.assertRegistered(*exp_registration)
- else:
- self.assertNotRegistered()
-
- yield self.stopChangeSource()
-
- if exp_registration:
- self.assertUnregistered(*exp_registration)
- self.assertEqual(self.changesource.registration, None)
-
- def test_perspective(self):
- self.attachChangeSource(pb.PBChangeSource('alice', 'sekrit', port='8888'))
- persp = self.changesource.getPerspective(mock.Mock(), 'alice')
- self.assertIsInstance(persp, pb.ChangePerspective)
-
- def test_describe(self):
- cs = pb.PBChangeSource()
- self.assertSubstring("PBChangeSource", cs.describe())
-
- def test_describe_prefix(self):
- cs = pb.PBChangeSource(prefix="xyz")
- self.assertSubstring("PBChangeSource", cs.describe())
- self.assertSubstring("xyz", cs.describe())
-
- def test_describe_int(self):
- cs = pb.PBChangeSource(port=9989)
- self.assertSubstring("PBChangeSource", cs.describe())
-
- @defer.inlineCallbacks
- def test_reconfigService_no_change(self):
- config = mock.Mock()
- self.attachChangeSource(pb.PBChangeSource(port='9876'))
-
- self.startChangeSource()
- yield self.changesource.reconfigService(config)
-
- self.assertRegistered('9876', 'change', 'changepw')
-
- yield self.stopChangeSource()
-
- self.assertUnregistered('9876', 'change', 'changepw')
-
- @defer.inlineCallbacks
- def test_reconfigService_default_changed(self):
- config = mock.Mock()
- config.slavePortnum = '9876'
- self.attachChangeSource(pb.PBChangeSource())
-
- self.startChangeSource()
- yield self.changesource.reconfigService(config)
-
- self.assertRegistered('9876', 'change', 'changepw')
-
- config.slavePortnum = '1234'
-
- yield self.changesource.reconfigService(config)
-
- self.assertUnregistered('9876', 'change', 'changepw')
- self.assertRegistered('1234', 'change', 'changepw')
-
- yield self.stopChangeSource()
-
- self.assertUnregistered('1234', 'change', 'changepw')
-
-
-class TestChangePerspective(unittest.TestCase):
- def setUp(self):
- self.added_changes = []
- self.master = mock.Mock()
-
- def addChange(**chdict):
- self.added_changes.append(chdict)
- return defer.succeed(mock.Mock())
- self.master.addChange = addChange
-
- def test_addChange_noprefix(self):
- cp = pb.ChangePerspective(self.master, None)
- d = cp.perspective_addChange(dict(who="bar", files=['a']))
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(author="bar", files=['a']) ])
- d.addCallback(check)
- return d
-
- def test_addChange_codebase(self):
- cp = pb.ChangePerspective(self.master, None)
- d = cp.perspective_addChange(dict(who="bar", files=[], codebase='cb'))
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(author="bar", files=[], codebase='cb') ])
- d.addCallback(check)
- return d
-
- def test_addChange_prefix(self):
- cp = pb.ChangePerspective(self.master, 'xx/')
- d = cp.perspective_addChange(
- dict(who="bar", files=['xx/a', 'yy/b']))
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(author="bar", files=['a']) ])
- d.addCallback(check)
- return d
-
- def test_addChange_sanitize_None(self):
- cp = pb.ChangePerspective(self.master, None)
- d = cp.perspective_addChange(
- dict(project=None, revlink=None, repository=None)
- )
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(project="", revlink="", repository="",
- files=[]) ])
- d.addCallback(check)
- return d
-
- def test_addChange_when_None(self):
- cp = pb.ChangePerspective(self.master, None)
- d = cp.perspective_addChange(
- dict(when=None)
- )
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(when_timestamp=None, files=[]) ])
- d.addCallback(check)
- return d
-
- def test_addChange_files_tuple(self):
- cp = pb.ChangePerspective(self.master, None)
- d = cp.perspective_addChange(
- dict(files=('a', 'b'))
- )
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(files=['a', 'b']) ])
- d.addCallback(check)
- return d
-
- def test_addChange_unicode(self):
- cp = pb.ChangePerspective(self.master, None)
- d = cp.perspective_addChange(dict(author=u"\N{SNOWMAN}",
- comments=u"\N{SNOWMAN}",
- files=[u'\N{VERY MUCH GREATER-THAN}']))
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(author=u"\N{SNOWMAN}",
- comments=u"\N{SNOWMAN}",
- files=[u'\N{VERY MUCH GREATER-THAN}']) ])
- d.addCallback(check)
- return d
-
- def test_addChange_unicode_as_bytestring(self):
- cp = pb.ChangePerspective(self.master, None)
- d = cp.perspective_addChange(dict(author=u"\N{SNOWMAN}".encode('utf8'),
- comments=u"\N{SNOWMAN}".encode('utf8'),
- files=[u'\N{VERY MUCH GREATER-THAN}'.encode('utf8')]))
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(author=u"\N{SNOWMAN}",
- comments=u"\N{SNOWMAN}",
- files=[u'\N{VERY MUCH GREATER-THAN}']) ])
- d.addCallback(check)
- return d
-
- def test_addChange_non_utf8_bytestring(self):
- cp = pb.ChangePerspective(self.master, None)
- bogus_utf8 = '\xff\xff\xff\xff'
- replacement = bogus_utf8.decode('utf8', 'replace')
- d = cp.perspective_addChange(dict(author=bogus_utf8, files=['a']))
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(author=replacement, files=['a']) ])
- d.addCallback(check)
- return d
-
- def test_addChange_old_param_names(self):
- cp = pb.ChangePerspective(self.master, None)
- d = cp.perspective_addChange(dict(isdir=1, who='me', when=1234,
- files=[]))
- def check(_):
- self.assertEqual(self.added_changes,
- [ dict(is_dir=1, author='me', files=[],
- when_timestamp=epoch2datetime(1234)) ])
- d.addCallback(check)
- return d
-
- def test_createUserObject_git_src(self):
- cp = pb.ChangePerspective(self.master, None)
- d = cp.perspective_addChange(dict(who="c <h@c>", src='git'))
- def check_change(_):
- self.assertEqual(self.added_changes, [ dict(author="c <h@c>",
- files=[],
- src='git') ])
- d.addCallback(check_change)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_svnpoller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_svnpoller.py
deleted file mode 100644
index be288d8d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_changes_svnpoller.py
+++ /dev/null
@@ -1,627 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os
-import xml.dom.minidom
-from twisted.internet import defer
-from twisted.trial import unittest
-from buildbot.test.util import changesource, gpo, compat
-from buildbot.changes import svnpoller
-
-# this is the output of "svn info --xml
-# svn+ssh://svn.twistedmatrix.com/svn/Twisted/trunk"
-prefix_output = """\
-<?xml version="1.0"?>
-<info>
-<entry
- kind="dir"
- path="trunk"
- revision="18354">
-<url>svn+ssh://svn.twistedmatrix.com/svn/Twisted/trunk</url>
-<repository>
-<root>svn+ssh://svn.twistedmatrix.com/svn/Twisted</root>
-<uuid>bbbe8e31-12d6-0310-92fd-ac37d47ddeeb</uuid>
-</repository>
-<commit
- revision="18352">
-<author>jml</author>
-<date>2006-10-01T02:37:34.063255Z</date>
-</commit>
-</entry>
-</info>
-"""
-
-# and this is "svn info --xml svn://svn.twistedmatrix.com/svn/Twisted". I
-# think this is kind of a degenerate case.. it might even be a form of error.
-prefix_output_2 = """\
-<?xml version="1.0"?>
-<info>
-</info>
-"""
-
-# this is the svn info output for a local repository, svn info --xml
-# file:///home/warner/stuff/Projects/BuildBot/trees/svnpoller/_trial_temp/test_vc/repositories/SVN-Repository
-prefix_output_3 = """\
-<?xml version="1.0"?>
-<info>
-<entry
- kind="dir"
- path="SVN-Repository"
- revision="3">
-<url>file:///home/warner/stuff/Projects/BuildBot/trees/svnpoller/_trial_temp/test_vc/repositories/SVN-Repository</url>
-<repository>
-<root>file:///home/warner/stuff/Projects/BuildBot/trees/svnpoller/_trial_temp/test_vc/repositories/SVN-Repository</root>
-<uuid>c0f47ff4-ba1e-0410-96b5-d44cc5c79e7f</uuid>
-</repository>
-<commit
- revision="3">
-<author>warner</author>
-<date>2006-10-01T07:37:04.182499Z</date>
-</commit>
-</entry>
-</info>
-"""
-
-# % svn info --xml file:///home/warner/stuff/Projects/BuildBot/trees/svnpoller/_trial_temp/test_vc/repositories/SVN-Repository/sample/trunk
-
-prefix_output_4 = """\
-<?xml version="1.0"?>
-<info>
-<entry
- kind="dir"
- path="trunk"
- revision="3">
-<url>file:///home/warner/stuff/Projects/BuildBot/trees/svnpoller/_trial_temp/test_vc/repositories/SVN-Repository/sample/trunk</url>
-<repository>
-<root>file:///home/warner/stuff/Projects/BuildBot/trees/svnpoller/_trial_temp/test_vc/repositories/SVN-Repository</root>
-<uuid>c0f47ff4-ba1e-0410-96b5-d44cc5c79e7f</uuid>
-</repository>
-<commit
- revision="1">
-<author>warner</author>
-<date>2006-10-01T07:37:02.286440Z</date>
-</commit>
-</entry>
-</info>
-"""
-
-
-
-# output from svn log on .../SVN-Repository/sample
-# (so it includes trunk and branches)
-sample_base = ("file:///usr/home/warner/stuff/Projects/BuildBot/trees/misc/" +
- "_trial_temp/test_vc/repositories/SVN-Repository/sample")
-sample_logentries = [None] * 6
-
-sample_logentries[5] = """\
-<logentry
- revision="6">
-<author>warner</author>
-<date>2006-10-01T19:35:16.165664Z</date>
-<paths>
-<path
- action="D">/sample/branch/version.c</path>
-</paths>
-<msg>revised_to_2</msg>
-</logentry>
-"""
-
-sample_logentries[4] = """\
-<logentry
- revision="5">
-<author>warner</author>
-<date>2006-10-01T19:35:16.165664Z</date>
-<paths>
-<path
- action="D">/sample/branch</path>
-</paths>
-<msg>revised_to_2</msg>
-</logentry>
-"""
-
-sample_logentries[3] = """\
-<logentry
- revision="4">
-<author>warner</author>
-<date>2006-10-01T19:35:16.165664Z</date>
-<paths>
-<path
- action="M">/sample/trunk/version.c</path>
-</paths>
-<msg>revised_to_2</msg>
-</logentry>
-"""
-
-sample_logentries[2] = """\
-<logentry
- revision="3">
-<author>warner</author>
-<date>2006-10-01T19:35:10.215692Z</date>
-<paths>
-<path
- action="M">/sample/branch/main.c</path>
-</paths>
-<msg>commit_on_branch</msg>
-</logentry>
-"""
-
-sample_logentries[1] = """\
-<logentry
- revision="2">
-<author>warner</author>
-<date>2006-10-01T19:35:09.154973Z</date>
-<paths>
-<path
- copyfrom-path="/sample/trunk"
- copyfrom-rev="1"
- action="A">/sample/branch</path>
-</paths>
-<msg>make_branch</msg>
-</logentry>
-"""
-
-sample_logentries[0] = """\
-<logentry
- revision="1">
-<author>warner</author>
-<date>2006-10-01T19:35:08.642045Z</date>
-<paths>
-<path
- action="A">/sample</path>
-<path
- action="A">/sample/trunk</path>
-<path
- action="A">/sample/trunk/subdir/subdir.c</path>
-<path
- action="A">/sample/trunk/main.c</path>
-<path
- action="A">/sample/trunk/version.c</path>
-<path
- action="A">/sample/trunk/subdir</path>
-</paths>
-<msg>sample_project_files</msg>
-</logentry>
-"""
-
-sample_info_output = """\
-<?xml version="1.0"?>
-<info>
-<entry
- kind="dir"
- path="sample"
- revision="4">
-<url>file:///usr/home/warner/stuff/Projects/BuildBot/trees/misc/_trial_temp/test_vc/repositories/SVN-Repository/sample</url>
-<repository>
-<root>file:///usr/home/warner/stuff/Projects/BuildBot/trees/misc/_trial_temp/test_vc/repositories/SVN-Repository</root>
-<uuid>4f94adfc-c41e-0410-92d5-fbf86b7c7689</uuid>
-</repository>
-<commit
- revision="4">
-<author>warner</author>
-<date>2006-10-01T19:35:16.165664Z</date>
-</commit>
-</entry>
-</info>
-"""
-
-
-changes_output_template = """\
-<?xml version="1.0"?>
-<log>
-%s</log>
-"""
-
-def make_changes_output(maxrevision):
- # return what 'svn log' would have just after the given revision was
- # committed
- logs = sample_logentries[0:maxrevision]
- assert len(logs) == maxrevision
- logs.reverse()
- output = changes_output_template % ("".join(logs))
- return output
-
-def make_logentry_elements(maxrevision):
- "return the corresponding logentry elements for the given revisions"
- doc = xml.dom.minidom.parseString(make_changes_output(maxrevision))
- return doc.getElementsByTagName("logentry")
-
-def split_file(path):
- pieces = path.split("/")
- if pieces[0] == "branch":
- return dict(branch="branch", path="/".join(pieces[1:]))
- if pieces[0] == "trunk":
- return dict(path="/".join(pieces[1:]))
- raise RuntimeError("there shouldn't be any files like %r" % path)
-
-
-class TestSVNPoller(gpo.GetProcessOutputMixin,
- changesource.ChangeSourceMixin,
- unittest.TestCase):
-
- def setUp(self):
- self.setUpGetProcessOutput()
- return self.setUpChangeSource()
-
- def tearDown(self):
- return self.tearDownChangeSource()
-
- def attachSVNPoller(self, *args, **kwargs):
- s = svnpoller.SVNPoller(*args, **kwargs)
- self.attachChangeSource(s)
- return s
-
- def add_svn_command_result(self, command, result):
- self.expectCommands(
- gpo.Expect('svn', command).stdout(result))
-
-
- # tests
-
- def test_describe(self):
- s = self.attachSVNPoller('file://')
- self.assertSubstring("SVNPoller", s.describe())
-
- def test_strip_svnurl(self):
- base = "svn+ssh://svn.twistedmatrix.com/svn/Twisted/trunk"
- s = self.attachSVNPoller(base + "/")
- self.failUnlessEqual(s.svnurl, base)
-
- def do_test_get_prefix(self, base, output, expected):
- s = self.attachSVNPoller(base)
- self.expectCommands(gpo.Expect('svn', 'info', '--xml', '--non-interactive', base).stdout(output))
- d = s.get_prefix()
- def check(prefix):
- self.failUnlessEqual(prefix, expected)
- self.assertAllCommandsRan()
- d.addCallback(check)
- return d
-
- def test_get_prefix_1(self):
- base = "svn+ssh://svn.twistedmatrix.com/svn/Twisted/trunk"
- return self.do_test_get_prefix(base, prefix_output, 'trunk')
-
- def test_get_prefix_2(self):
- base = "svn+ssh://svn.twistedmatrix.com/svn/Twisted"
- return self.do_test_get_prefix(base, prefix_output_2, '')
-
- def test_get_prefix_3(self):
- base = ("file:///home/warner/stuff/Projects/BuildBot/trees/" +
- "svnpoller/_trial_temp/test_vc/repositories/SVN-Repository")
- return self.do_test_get_prefix(base, prefix_output_3, '')
-
- def test_get_prefix_4(self):
- base = ("file:///home/warner/stuff/Projects/BuildBot/trees/" +
- "svnpoller/_trial_temp/test_vc/repositories/SVN-Repository/sample/trunk")
- return self.do_test_get_prefix(base, prefix_output_3, 'sample/trunk')
-
- def test_log_parsing(self):
- s = self.attachSVNPoller('file:///foo')
- output = make_changes_output(4)
- entries = s.parse_logs(output)
- # no need for elaborate assertions here; this is minidom's logic
- self.assertEqual(len(entries), 4)
-
- def test_get_new_logentries(self):
- s = self.attachSVNPoller('file:///foo')
- entries = make_logentry_elements(4)
-
- s.last_change = 4
- new = s.get_new_logentries(entries)
- self.assertEqual(s.last_change, 4)
- self.assertEqual(len(new), 0)
-
- s.last_change = 3
- new = s.get_new_logentries(entries)
- self.assertEqual(s.last_change, 4)
- self.assertEqual(len(new), 1)
-
- s.last_change = 1
- new = s.get_new_logentries(entries)
- self.assertEqual(s.last_change, 4)
- self.assertEqual(len(new), 3)
-
- # special case: if last_change is None, then no new changes are queued
- s.last_change = None
- new = s.get_new_logentries(entries)
- self.assertEqual(s.last_change, 4)
- self.assertEqual(len(new), 0)
-
- def test_create_changes(self):
- base = ("file:///home/warner/stuff/Projects/BuildBot/trees/" +
- "svnpoller/_trial_temp/test_vc/repositories/SVN-Repository/sample")
- s = self.attachSVNPoller(base, split_file=split_file)
- s._prefix = "sample"
-
- logentries = dict(zip(xrange(1, 7), reversed(make_logentry_elements(6))))
- changes = s.create_changes(reversed([ logentries[3], logentries[2] ]))
- self.failUnlessEqual(len(changes), 2)
- # note that parsing occurs in reverse
- self.failUnlessEqual(changes[0]['branch'], "branch")
- self.failUnlessEqual(changes[0]['revision'], '2')
- self.failUnlessEqual(changes[0]['project'], '')
- self.failUnlessEqual(changes[0]['repository'], base)
- self.failUnlessEqual(changes[1]['branch'], "branch")
- self.failUnlessEqual(changes[1]['files'], ["main.c"])
- self.failUnlessEqual(changes[1]['revision'], '3')
- self.failUnlessEqual(changes[1]['project'], '')
- self.failUnlessEqual(changes[1]['repository'], base)
-
- changes = s.create_changes([ logentries[4] ])
- self.failUnlessEqual(len(changes), 1)
- self.failUnlessEqual(changes[0]['branch'], None)
- self.failUnlessEqual(changes[0]['revision'], '4')
- self.failUnlessEqual(changes[0]['files'], ["version.c"])
-
- # r5 should *not* create a change as it's a branch deletion
- changes = s.create_changes([ logentries[5] ])
- self.failUnlessEqual(len(changes), 0)
-
- # r6 should create a change as it's not deleting an entire branch
- changes = s.create_changes([ logentries[6] ])
- self.failUnlessEqual(len(changes), 1)
- self.failUnlessEqual(changes[0]['branch'], 'branch')
- self.failUnlessEqual(changes[0]['revision'], '6')
- self.failUnlessEqual(changes[0]['files'], ["version.c"])
-
- def makeInfoExpect(self):
- return gpo.Expect('svn', 'info', '--xml', '--non-interactive', sample_base,
- '--username=dustin', '--password=bbrocks')
-
- def makeLogExpect(self):
- return gpo.Expect('svn', 'log', '--xml', '--verbose', '--non-interactive',
- '--username=dustin', '--password=bbrocks',
- '--limit=100', sample_base)
- def test_create_changes_overriden_project(self):
- def custom_split_file(path):
- f = split_file(path)
- if f:
- f["project"] = "overriden-project"
- f["repository"] = "overriden-repository"
- f["codebase"] = "overriden-codebase"
- return f
-
- base = ("file:///home/warner/stuff/Projects/BuildBot/trees/" +
- "svnpoller/_trial_temp/test_vc/repositories/SVN-Repository/sample")
- s = self.attachSVNPoller(base, split_file=custom_split_file)
- s._prefix = "sample"
-
- logentries = dict(zip(xrange(1, 7), reversed(make_logentry_elements(6))))
- changes = s.create_changes(reversed([ logentries[3], logentries[2] ]))
- self.failUnlessEqual(len(changes), 2)
-
- # note that parsing occurs in reverse
- self.failUnlessEqual(changes[0]['branch'], "branch")
- self.failUnlessEqual(changes[0]['revision'], '2')
- self.failUnlessEqual(changes[0]['project'], "overriden-project")
- self.failUnlessEqual(changes[0]['repository'], "overriden-repository")
- self.failUnlessEqual(changes[0]['codebase'], "overriden-codebase")
-
- self.failUnlessEqual(changes[1]['branch'], "branch")
- self.failUnlessEqual(changes[1]['files'], ["main.c"])
- self.failUnlessEqual(changes[1]['revision'], '3')
- self.failUnlessEqual(changes[1]['project'], "overriden-project")
- self.failUnlessEqual(changes[1]['repository'], "overriden-repository")
- self.failUnlessEqual(changes[1]['codebase'], "overriden-codebase")
-
- def test_poll(self):
- s = self.attachSVNPoller(sample_base, split_file=split_file,
- svnuser='dustin', svnpasswd='bbrocks')
-
- d = defer.succeed(None)
-
-
- self.expectCommands(
- self.makeInfoExpect().stdout(sample_info_output),
- self.makeLogExpect().stdout(make_changes_output(1)),
- self.makeLogExpect().stdout(make_changes_output(1)),
- self.makeLogExpect().stdout(make_changes_output(2)),
- self.makeLogExpect().stdout(make_changes_output(4)),
- )
- # fire it the first time; it should do nothing
- d.addCallback(lambda _ : s.poll())
- def check_first(_):
- # no changes generated on the first iteration
- self.assertEqual(self.changes_added, [])
- self.failUnlessEqual(s.last_change, 1)
- d.addCallback(check_first)
-
- # now fire it again, nothing changing
- d.addCallback(lambda _ : s.poll())
- def check_second(_):
- self.assertEqual(self.changes_added, [])
- self.failUnlessEqual(s.last_change, 1)
- d.addCallback(check_second)
-
- # and again, with r2 this time
- d.addCallback(lambda _ : s.poll())
- def check_third(_):
- self.assertEqual(len(self.changes_added), 1)
- c = self.changes_added[0]
- self.failUnlessEqual(c['branch'], "branch")
- self.failUnlessEqual(c['revision'], '2')
- self.failUnlessEqual(c['files'], ['']) # signals a new branch
- self.failUnlessEqual(c['comments'], "make_branch")
- self.failUnlessEqual(c['src'], "svn")
- self.failUnlessEqual(s.last_change, 2)
- d.addCallback(check_third)
-
- # and again with both r3 and r4 appearing together
- def setup_fourth(_):
- self.changes_added = []
- d.addCallback(setup_fourth)
- d.addCallback(lambda _ : s.poll())
- def check_fourth(_):
- self.assertEqual(len(self.changes_added), 2)
- c = self.changes_added[0]
- self.failUnlessEqual(c['branch'], "branch")
- self.failUnlessEqual(c['revision'], '3')
- self.failUnlessEqual(c['files'], ["main.c"])
- self.failUnlessEqual(c['comments'], "commit_on_branch")
- self.failUnlessEqual(c['src'], "svn")
- c = self.changes_added[1]
- self.failUnlessEqual(c['branch'], None)
- self.failUnlessEqual(c['revision'], '4')
- self.failUnlessEqual(c['files'], ["version.c"])
- self.failUnlessEqual(c['comments'], "revised_to_2")
- self.failUnlessEqual(c['src'], "svn")
- self.failUnlessEqual(s.last_change, 4)
- self.assertAllCommandsRan()
- d.addCallback(check_fourth)
-
- return d
-
- @compat.usesFlushLoggedErrors
- def test_poll_get_prefix_exception(self):
- s = self.attachSVNPoller(sample_base, split_file=split_file,
- svnuser='dustin', svnpasswd='bbrocks')
-
- self.expectCommands(
- self.makeInfoExpect().stderr("error"))
- d = s.poll()
- @d.addCallback
- def check(_):
- # should have logged the RuntimeError, but not errback'd from poll
- self.assertEqual(len(self.flushLoggedErrors(IOError)), 1)
- self.assertAllCommandsRan()
- return d
-
- @compat.usesFlushLoggedErrors
- def test_poll_get_logs_exception(self):
- s = self.attachSVNPoller(sample_base, split_file=split_file,
- svnuser='dustin', svnpasswd='bbrocks')
- s._prefix = "abc" # skip the get_prefix stuff
-
- self.expectCommands(
- self.makeLogExpect().stderr("some error"))
- d = s.poll()
- @d.addCallback
- def check(_):
- # should have logged the RuntimeError, but not errback'd from poll
- self.assertEqual(len(self.flushLoggedErrors(IOError)), 1)
- self.assertAllCommandsRan()
- return d
-
- def test_cachepath_empty(self):
- cachepath = os.path.abspath('revcache')
- if os.path.exists(cachepath):
- os.unlink(cachepath)
- s = self.attachSVNPoller(sample_base, cachepath=cachepath)
- self.assertEqual(s.last_change, None)
-
- def test_cachepath_full(self):
- cachepath = os.path.abspath('revcache')
- with open(cachepath, "w") as f:
- f.write('33')
- s = self.attachSVNPoller(sample_base, cachepath=cachepath)
- self.assertEqual(s.last_change, 33)
-
- s.last_change = 44
- s.finished_ok(None)
- with open(cachepath) as f:
- self.assertEqual(f.read().strip(), '44')
-
- @compat.usesFlushLoggedErrors
- def test_cachepath_bogus(self):
- cachepath = os.path.abspath('revcache')
- with open(cachepath, "w") as f:
- f.write('nine')
- s = self.attachSVNPoller(sample_base, cachepath=cachepath)
- self.assertEqual(s.last_change, None)
- self.assertEqual(s.cachepath, None)
- # it should have called log.err once with a ValueError
- self.assertEqual(len(self.flushLoggedErrors(ValueError)), 1)
-
- def test_constructor_pollinterval(self):
- self.attachSVNPoller(sample_base, pollinterval=100) # just don't fail!
-
- def test_extra_args(self):
- extra_args = ['--no-auth-cache',]
- base = "svn+ssh://svn.twistedmatrix.com/svn/Twisted/trunk"
-
- s = self.attachSVNPoller(svnurl=base, extra_args=extra_args)
- self.failUnlessEqual(s.extra_args, extra_args)
-
-class TestSplitFile(unittest.TestCase):
- def test_split_file_alwaystrunk(self):
- self.assertEqual(svnpoller.split_file_alwaystrunk('foo'), dict(path='foo'))
-
- def test_split_file_branches_trunk(self):
- self.assertEqual(
- svnpoller.split_file_branches('trunk/'),
- (None, ''))
-
- def test_split_file_branches_trunk_subdir(self):
- self.assertEqual(
- svnpoller.split_file_branches('trunk/subdir/'),
- (None, 'subdir/'))
-
- def test_split_file_branches_trunk_subfile(self):
- self.assertEqual(
- svnpoller.split_file_branches('trunk/subdir/file.c'),
- (None, 'subdir/file.c'))
-
- def test_split_file_branches_trunk_invalid(self):
- # file named trunk (not a directory):
- self.assertEqual(
- svnpoller.split_file_branches('trunk'),
- None)
-
- def test_split_file_branches_branch(self):
- self.assertEqual(
- svnpoller.split_file_branches('branches/1.5.x/'),
- ('branches/1.5.x', ''))
-
- def test_split_file_branches_branch_subdir(self):
- self.assertEqual(
- svnpoller.split_file_branches('branches/1.5.x/subdir/'),
- ('branches/1.5.x', 'subdir/'))
-
- def test_split_file_branches_branch_subfile(self):
- self.assertEqual(
- svnpoller.split_file_branches('branches/1.5.x/subdir/file.c'),
- ('branches/1.5.x', 'subdir/file.c'))
-
- def test_split_file_branches_branch_invalid(self):
- # file named branches/1.5.x (not a directory):
- self.assertEqual(
- svnpoller.split_file_branches('branches/1.5.x'),
- None)
-
- def test_split_file_branches_otherdir(self):
- # other dirs are ignored:
- self.assertEqual(
- svnpoller.split_file_branches('tags/testthis/subdir/'),
- None)
-
- def test_split_file_branches_otherfile(self):
- # other files are ignored:
- self.assertEqual(
- svnpoller.split_file_branches('tags/testthis/subdir/file.c'),
- None)
-
- def test_split_file_projects_branches(self):
- self.assertEqual(
- svnpoller.split_file_projects_branches('buildbot/trunk/subdir/file.c'),
- dict(project='buildbot', path='subdir/file.c'))
- self.assertEqual(
- svnpoller.split_file_projects_branches('buildbot/branches/1.5.x/subdir/file.c'),
- dict(project='buildbot', branch='branches/1.5.x', path='subdir/file.c'))
- # tags are ignored:
- self.assertEqual(
- svnpoller.split_file_projects_branches('buildbot/tags/testthis/subdir/file.c'),
- None)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_sendchange.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_sendchange.py
deleted file mode 100644
index a403694d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_sendchange.py
+++ /dev/null
@@ -1,237 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-from twisted.spread import pb
-from twisted.internet import defer, reactor
-from buildbot.clients import sendchange
-
-class Sender(unittest.TestCase):
-
- def setUp(self):
- # patch out some PB components and make up some mocks
- self.patch(pb, 'PBClientFactory', self._fake_PBClientFactory)
- self.patch(reactor, 'connectTCP', self._fake_connectTCP)
-
- self.factory = mock.Mock(name='PBClientFactory')
- self.factory.login = self._fake_login
- self.factory.login_d = defer.Deferred()
-
- self.remote = mock.Mock(name='PB Remote')
- self.remote.callRemote = self._fake_callRemote
- self.remote.broker.transport.loseConnection = self._fake_loseConnection
-
- # results
- self.creds = None
- self.conn_host = self.conn_port = None
- self.lostConnection = False
- self.added_changes = []
- self.vc_used = None
-
- def _fake_PBClientFactory(self):
- return self.factory
-
- def _fake_login(self, creds):
- self.creds = creds
- return self.factory.login_d
-
- def _fake_connectTCP(self, host, port, factory):
- self.conn_host = host
- self.conn_port = port
- self.assertIdentical(factory, self.factory)
- self.factory.login_d.callback(self.remote)
-
- def _fake_callRemote(self, method, change):
- self.assertEqual(method, 'addChange')
- self.added_changes.append(change)
- return defer.succeed(None)
-
- def _fake_loseConnection(self):
- self.lostConnection = True
-
- def assertProcess(self, host, port, username, password, changes):
- self.assertEqual([host, port, username, password, changes],
- [ self.conn_host, self.conn_port,
- self.creds.username, self.creds.password,
- self.added_changes])
-
- def test_send_minimal(self):
- s = sendchange.Sender('localhost:1234')
- d = s.send('branch', 'rev', 'comm', ['a'])
- def check(_):
- self.assertProcess('localhost', 1234, 'change', 'changepw', [
- dict(project='', repository='', who=None, files=['a'],
- comments='comm', branch='branch', revision='rev',
- category=None, when=None, properties={}, revlink='',
- src=None)])
- d.addCallback(check)
- return d
-
- def test_send_auth(self):
- s = sendchange.Sender('localhost:1234', auth=('me','sekrit'))
- d = s.send('branch', 'rev', 'comm', ['a'])
- def check(_):
- self.assertProcess('localhost', 1234, 'me', 'sekrit', [
- dict(project='', repository='', who=None, files=['a'],
- comments='comm', branch='branch', revision='rev',
- category=None, when=None, properties={}, revlink='',
- src=None)])
- d.addCallback(check)
- return d
-
- def test_send_full(self):
- s = sendchange.Sender('localhost:1234')
- d = s.send('branch', 'rev', 'comm', ['a'], who='me', category='cats',
- when=1234, properties={'a':'b'}, repository='r', vc='git',
- project='p', revlink='rl')
- def check(_):
- self.assertProcess('localhost', 1234, 'change', 'changepw', [
- dict(project='p', repository='r', who='me', files=['a'],
- comments='comm', branch='branch', revision='rev',
- category='cats', when=1234, properties={'a':'b'},
- revlink='rl', src='git')])
- d.addCallback(check)
- return d
-
- def test_send_files_tuple(self):
- # 'buildbot sendchange' sends files as a tuple, rather than a list..
- s = sendchange.Sender('localhost:1234')
- d = s.send('branch', 'rev', 'comm', ('a', 'b'))
- def check(_):
- self.assertProcess('localhost', 1234, 'change', 'changepw', [
- dict(project='', repository='', who=None, files=['a', 'b'],
- comments='comm', branch='branch', revision='rev',
- category=None, when=None, properties={}, revlink='',
- src=None)])
- d.addCallback(check)
- return d
-
- def test_send_codebase(self):
- s = sendchange.Sender('localhost:1234')
- d = s.send('branch', 'rev', 'comm', ['a'], codebase='mycb')
- def check(_):
- self.assertProcess('localhost', 1234, 'change', 'changepw', [
- dict(project='', repository='', who=None, files=['a'],
- comments='comm', branch='branch', revision='rev',
- category=None, when=None, properties={}, revlink='',
- src=None, codebase='mycb')])
- d.addCallback(check)
- return d
-
- def test_send_unicode(self):
- s = sendchange.Sender('localhost:1234')
- d = s.send(u'\N{DEGREE SIGN}',
- u'\U0001f49e',
- u'\N{POSTAL MARK FACE}',
- [u'\U0001F4C1'],
- project=u'\N{SKULL AND CROSSBONES}',
- repository=u'\N{SNOWMAN}',
- who=u'\N{THAI CHARACTER KHOMUT}',
- category=u'\U0001F640',
- when=1234,
- properties={u'\N{LATIN SMALL LETTER A WITH MACRON}':'b'},
- revlink=u'\U0001F517')
-
- def check(_):
- self.assertProcess('localhost', 1234, 'change', 'changepw', [
- dict(project=u'\N{SKULL AND CROSSBONES}',
- repository=u'\N{SNOWMAN}',
- who=u'\N{THAI CHARACTER KHOMUT}',
- files=[u'\U0001F4C1'], # FILE FOLDER
- comments=u'\N{POSTAL MARK FACE}',
- branch=u'\N{DEGREE SIGN}',
- revision=u'\U0001f49e', # REVOLVING HEARTS
- category=u'\U0001F640', # WEARY CAT FACE
- when=1234,
- properties={u'\N{LATIN SMALL LETTER A WITH MACRON}':'b'},
- revlink=u'\U0001F517', # LINK SYMBOL
- src=None)])
- d.addCallback(check)
- return d
-
- def test_send_unicode_utf8(self):
- s = sendchange.Sender('localhost:1234')
-
- d = s.send(u'\N{DEGREE SIGN}'.encode('utf8'),
- u'\U0001f49e'.encode('utf8'),
- u'\N{POSTAL MARK FACE}'.encode('utf8'),
- [u'\U0001F4C1'.encode('utf8')],
- project=u'\N{SKULL AND CROSSBONES}'.encode('utf8'),
- repository=u'\N{SNOWMAN}'.encode('utf8'),
- who=u'\N{THAI CHARACTER KHOMUT}'.encode('utf8'),
- category=u'\U0001F640'.encode('utf8'),
- when=1234,
- properties={
- u'\N{LATIN SMALL LETTER A WITH MACRON}'.encode('utf8')
- : 'b'},
- revlink=u'\U0001F517'.encode('utf8'))
-
- def check(_):
- self.assertProcess('localhost', 1234, 'change', 'changepw', [
- dict(project=u'\N{SKULL AND CROSSBONES}',
- repository=u'\N{SNOWMAN}',
- who=u'\N{THAI CHARACTER KHOMUT}',
- files=[u'\U0001F4C1'], # FILE FOLDER
- comments=u'\N{POSTAL MARK FACE}',
- branch=u'\N{DEGREE SIGN}',
- revision=u'\U0001f49e', # REVOLVING HEARTS
- category=u'\U0001F640', # WEARY CAT FACE
- when=1234,
- ## NOTE: not decoded!
- properties={'\xc4\x81':'b'},
- revlink=u'\U0001F517', # LINK SYMBOL
- src=None)])
- d.addCallback(check)
- return d
-
- def test_send_unicode_latin1(self):
- # hand send() a bunch of latin1 strings, and expect them recoded
- # to unicode
- s = sendchange.Sender('localhost:1234', encoding='latin1')
-
- d = s.send(u'\N{YEN SIGN}'.encode('latin1'),
- u'\N{POUND SIGN}'.encode('latin1'),
- u'\N{BROKEN BAR}'.encode('latin1'),
- [u'\N{NOT SIGN}'.encode('latin1')],
- project=u'\N{DEGREE SIGN}'.encode('latin1'),
- repository=u'\N{SECTION SIGN}'.encode('latin1'),
- who=u'\N{MACRON}'.encode('latin1'),
- category=u'\N{PILCROW SIGN}'.encode('latin1'),
- when=1234,
- properties={
- u'\N{SUPERSCRIPT ONE}'.encode('latin1')
- : 'b'},
- revlink=u'\N{INVERTED QUESTION MARK}'.encode('latin1'))
-
- def check(_):
- self.assertProcess('localhost', 1234, 'change', 'changepw', [
- dict(project=u'\N{DEGREE SIGN}',
- repository=u'\N{SECTION SIGN}',
- who=u'\N{MACRON}',
- files=[u'\N{NOT SIGN}'],
- comments=u'\N{BROKEN BAR}',
- branch=u'\N{YEN SIGN}',
- revision=u'\N{POUND SIGN}',
- category=u'\N{PILCROW SIGN}',
- when=1234,
- ## NOTE: not decoded!
- properties={'\xb9':'b'},
- revlink=u'\N{INVERTED QUESTION MARK}',
- src=None)])
- d.addCallback(check)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_tryclient.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_tryclient.py
deleted file mode 100644
index e4f61d3c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_tryclient.py
+++ /dev/null
@@ -1,135 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-from twisted.trial import unittest
-
-from buildbot.clients import tryclient
-from buildbot.util import json
-
-
-class createJobfile(unittest.TestCase):
-
- def makeNetstring(self, *strings):
- return ''.join(['%d:%s,' % (len(s), s) for s in strings])
-
- # version 1 is deprecated and not produced by the try client
-
- def test_createJobfile_v2_one_builder(self):
- jobid = '123-456'
- branch = 'branch'
- baserev = 'baserev'
- patch_level = 0
- patch_body = 'diff...'
- repository = 'repo'
- project = 'proj'
- who = None
- comment = None
- builderNames = ['runtests']
- properties = {}
- job = tryclient.createJobfile(
- jobid, branch, baserev, patch_level, patch_body, repository,
- project, who, comment, builderNames, properties)
- jobstr = self.makeNetstring(
- '2', jobid, branch, baserev, str(patch_level), patch_body,
- repository, project, builderNames[0])
- self.assertEqual(job, jobstr)
-
- def test_createJobfile_v2_two_builders(self):
- jobid = '123-456'
- branch = 'branch'
- baserev = 'baserev'
- patch_level = 0
- patch_body = 'diff...'
- repository = 'repo'
- project = 'proj'
- who = None
- comment = None
- builderNames = ['runtests', 'moretests']
- properties = {}
- job = tryclient.createJobfile(
- jobid, branch, baserev, patch_level, patch_body, repository,
- project, who, comment, builderNames, properties)
- jobstr = self.makeNetstring(
- '2', jobid, branch, baserev, str(patch_level), patch_body,
- repository, project, builderNames[0], builderNames[1])
- self.assertEqual(job, jobstr)
-
- def test_createJobfile_v3(self):
- jobid = '123-456'
- branch = 'branch'
- baserev = 'baserev'
- patch_level = 0
- patch_body = 'diff...'
- repository = 'repo'
- project = 'proj'
- who = 'someuser'
- comment = None
- builderNames = ['runtests']
- properties = {}
- job = tryclient.createJobfile(
- jobid, branch, baserev, patch_level, patch_body, repository,
- project, who, comment, builderNames, properties)
- jobstr = self.makeNetstring(
- '3', jobid, branch, baserev, str(patch_level), patch_body,
- repository, project, who, builderNames[0])
- self.assertEqual(job, jobstr)
-
- def test_createJobfile_v4(self):
- jobid = '123-456'
- branch = 'branch'
- baserev = 'baserev'
- patch_level = 0
- patch_body = 'diff...'
- repository = 'repo'
- project = 'proj'
- who = 'someuser'
- comment = 'insightful comment'
- builderNames = ['runtests']
- properties = {}
- job = tryclient.createJobfile(
- jobid, branch, baserev, patch_level, patch_body, repository,
- project, who, comment, builderNames, properties)
- jobstr = self.makeNetstring(
- '4', jobid, branch, baserev, str(patch_level), patch_body,
- repository, project, who, comment, builderNames[0])
- self.assertEqual(job, jobstr)
-
- def test_createJobfile_v5(self):
- jobid = '123-456'
- branch = 'branch'
- baserev = 'baserev'
- patch_level = 0
- patch_body = 'diff...'
- repository = 'repo'
- project = 'proj'
- who = 'someuser'
- comment = 'insightful comment'
- builderNames = ['runtests']
- properties = {'foo': 'bar'}
- job = tryclient.createJobfile(
- jobid, branch, baserev, patch_level, patch_body, repository,
- project, who, comment, builderNames, properties)
- jobstr = self.makeNetstring(
- '5',
- json.dumps({
- 'jobid': jobid, 'branch': branch, 'baserev': baserev,
- 'patch_level': patch_level, 'patch_body': patch_body,
- 'repository': repository, 'project': project, 'who': who,
- 'comment': comment, 'builderNames': builderNames,
- 'properties': properties,
- }))
- self.assertEqual(job, jobstr)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_usersclient.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_usersclient.py
deleted file mode 100644
index 23f1ea1a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_clients_usersclient.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-from twisted.spread import pb
-from twisted.internet import defer, reactor
-from buildbot.clients import usersclient
-
-class TestUsersClient(unittest.TestCase):
-
- def setUp(self):
- # patch out some PB components and make up some mocks
- self.patch(pb, 'PBClientFactory', self._fake_PBClientFactory)
- self.patch(reactor, 'connectTCP', self._fake_connectTCP)
-
- self.factory = mock.Mock(name='PBClientFactory')
- self.factory.login = self._fake_login
- self.factory.login_d = defer.Deferred()
-
- self.remote = mock.Mock(name='PB Remote')
- self.remote.callRemote = self._fake_callRemote
- self.remote.broker.transport.loseConnection = self._fake_loseConnection
-
- # results
- self.conn_host = self.conn_port = None
- self.lostConnection = False
-
- def _fake_PBClientFactory(self):
- return self.factory
-
- def _fake_login(self, creds):
- return self.factory.login_d
-
- def _fake_connectTCP(self, host, port, factory):
- self.conn_host = host
- self.conn_port = port
- self.assertIdentical(factory, self.factory)
- self.factory.login_d.callback(self.remote)
-
- def _fake_callRemote(self, method, op, bb_username, bb_password, ids, info):
- self.assertEqual(method, 'commandline')
- self.called_with = dict(op=op, bb_username=bb_username,
- bb_password=bb_password, ids=ids, info=info)
- return defer.succeed(None)
-
- def _fake_loseConnection(self):
- self.lostConnection = True
-
- def assertProcess(self, host, port, called_with):
- self.assertEqual([host, port, called_with],
- [self.conn_host, self.conn_port, self.called_with])
-
- def test_usersclient_info(self):
- uc = usersclient.UsersClient('localhost', "user", "userpw", 1234)
- d = uc.send('update', 'bb_user', 'hashed_bb_pass', None,
- [{'identifier':'x', 'svn':'x'}])
- def check(_):
- self.assertProcess('localhost', 1234,
- dict(op='update', bb_username='bb_user',
- bb_password='hashed_bb_pass', ids=None,
- info=[dict(identifier='x', svn='x')]))
- d.addCallback(check)
- return d
-
- def test_usersclient_ids(self):
- uc = usersclient.UsersClient('localhost', "user", "userpw", 1234)
- d = uc.send('remove', None, None, ['x'], None)
- def check(_):
- self.assertProcess('localhost', 1234,
- dict(op='remove', bb_username=None,
- bb_password=None, ids=['x'], info=None))
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_config.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_config.py
deleted file mode 100644
index 9b6f6c1d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_config.py
+++ /dev/null
@@ -1,1207 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import re
-import os
-import textwrap
-import mock
-import __builtin__
-from zope.interface import implements
-from twisted.trial import unittest
-from twisted.application import service
-from twisted.internet import defer
-from buildbot import config, buildslave, interfaces, revlinks, locks
-from buildbot.process import properties, factory
-from buildbot.test.util import dirs, compat
-from buildbot.test.util.config import ConfigErrorsMixin
-from buildbot.changes import base as changes_base
-from buildbot.schedulers import base as schedulers_base
-from buildbot.status import base as status_base
-
-global_defaults = dict(
- title='Buildbot',
- titleURL='http://buildbot.net',
- buildbotURL='http://localhost:8080/',
- changeHorizon=None,
- eventHorizon=50,
- logHorizon=None,
- buildHorizon=None,
- logCompressionLimit=4096,
- logCompressionMethod='bz2',
- logMaxTailSize=None,
- logMaxSize=None,
- properties=properties.Properties(),
- mergeRequests=None,
- prioritizeBuilders=None,
- slavePortnum=None,
- multiMaster=False,
- debugPassword=None,
- manhole=None,
-)
-
-
-class FakeChangeSource(changes_base.ChangeSource):
- pass
-
-
-class FakeStatusReceiver(status_base.StatusReceiver):
- pass
-
-
-class FakeScheduler(object):
- implements(interfaces.IScheduler)
- def __init__(self, name):
- self.name = name
-
-class FakeBuilder(object):
-
- def __init__(self, **kwargs):
- self.__dict__.update(kwargs)
-
-
-class ConfigErrors(unittest.TestCase):
-
- def test_constr(self):
- ex = config.ConfigErrors(['a', 'b'])
- self.assertEqual(ex.errors, ['a', 'b'])
-
- def test_addError(self):
- ex = config.ConfigErrors(['a'])
- ex.addError('c')
- self.assertEqual(ex.errors, ['a', 'c'])
-
- def test_nonempty(self):
- empty = config.ConfigErrors()
- full = config.ConfigErrors(['a'])
- self.failUnless(not empty)
- self.failIf(not full)
-
- def test_error_raises(self):
- e = self.assertRaises(config.ConfigErrors, config.error, "message")
- self.assertEqual(e.errors, ["message"])
-
- def test_error_no_raise(self):
- e = config.ConfigErrors()
- self.patch(config, "_errors", e)
- config.error("message")
- self.assertEqual(e.errors, ["message"])
-
- def test_str(self):
- ex = config.ConfigErrors()
- self.assertEqual(str(ex), "")
-
- ex = config.ConfigErrors(["a"])
- self.assertEqual(str(ex), "a")
-
- ex = config.ConfigErrors(["a", "b"])
- self.assertEqual(str(ex), "a\nb")
-
- ex = config.ConfigErrors(["a"])
- ex.addError('c')
- self.assertEqual(str(ex), "a\nc")
-
-
-class MasterConfig(ConfigErrorsMixin, dirs.DirsMixin, unittest.TestCase):
-
- def setUp(self):
- self.basedir = os.path.abspath('basedir')
- self.filename = os.path.join(self.basedir, 'test.cfg')
- return self.setUpDirs('basedir')
-
- def tearDown(self):
- return self.tearDownDirs()
-
- # utils
-
- def patch_load_helpers(self):
- # patch out all of the "helpers" for laodConfig with null functions
- for n in dir(config.MasterConfig):
- if n.startswith('load_'):
- typ = 'loader'
- elif n.startswith('check_'):
- typ = 'checker'
- else:
- continue
-
- v = getattr(config.MasterConfig, n)
- if callable(v):
- if typ == 'loader':
- self.patch(config.MasterConfig, n,
- mock.Mock(side_effect=
- lambda filename, config_dict: None))
- else:
- self.patch(config.MasterConfig, n,
- mock.Mock(side_effect=
- lambda: None))
-
-
- def install_config_file(self, config_file, other_files={}):
- config_file = textwrap.dedent(config_file)
- with open(os.path.join(self.basedir, self.filename), "w") as f:
- f.write(config_file)
- for file, contents in other_files.items():
- with open(file, "w") as f:
- f.write(contents)
-
-
- # tests
-
- def test_defaults(self):
- cfg = config.MasterConfig()
- expected = dict(
- #validation,
- db=dict(
- db_url='sqlite:///state.sqlite',
- db_poll_interval=None),
- metrics = None,
- caches = dict(Changes=10, Builds=15),
- schedulers = {},
- builders = [],
- slaves = [],
- change_sources = [],
- status = [],
- user_managers = [],
- revlink = revlinks.default_revlink_matcher
- )
- expected.update(global_defaults)
- got = dict([
- (attr, getattr(cfg, attr))
- for attr, exp in expected.iteritems() ])
- self.assertEqual(got, expected)
-
- def test_defaults_validation(self):
- # re's aren't comparable, but we can make sure the keys match
- cfg = config.MasterConfig()
- self.assertEqual(sorted(cfg.validation.keys()),
- sorted([
- 'branch', 'revision', 'property_name', 'property_value',
- ]))
-
- def test_loadConfig_missing_file(self):
- self.assertRaisesConfigError(
- re.compile("configuration file .* does not exist"),
- lambda : config.MasterConfig.loadConfig(
- self.basedir, self.filename))
-
- def test_loadConfig_missing_basedir(self):
- self.assertRaisesConfigError(
- re.compile("basedir .* does not exist"),
- lambda : config.MasterConfig.loadConfig(
- os.path.join(self.basedir, 'NO'), 'test.cfg'))
-
- def test_loadConfig_open_error(self):
- """
- Check that loadConfig() raises correct ConfigError exception in cases
- when configure file is found, but we fail to open it.
- """
-
- def raise_IOError(*args):
- raise IOError("error_msg")
-
- self.install_config_file('#dummy')
-
- # override build-in open() function to always rise IOError
- self.patch(__builtin__, "open", raise_IOError)
-
- # check that we got the expected ConfigError exception
- self.assertRaisesConfigError(
- re.compile("unable to open configuration file .*: error_msg"),
- lambda : config.MasterConfig.loadConfig(
- self.basedir, self.filename))
-
- @compat.usesFlushLoggedErrors
- def test_loadConfig_parse_error(self):
- self.install_config_file('def x:\nbar')
- self.assertRaisesConfigError(
- re.compile("error while parsing.*traceback in logfile"),
- lambda : config.MasterConfig.loadConfig(
- self.basedir, self.filename))
- self.assertEqual(len(self.flushLoggedErrors(SyntaxError)), 1)
-
- def test_loadConfig_eval_ConfigError(self):
- self.install_config_file("""\
- from buildbot import config
- BuildmasterConfig = { 'multiMaster': True }
- config.error('oh noes!')""")
- self.assertRaisesConfigError("oh noes",
- lambda : config.MasterConfig.loadConfig(
- self.basedir, self.filename))
-
- def test_loadConfig_eval_ConfigErrors(self):
- # We test a config that has embedded errors, as well
- # as semantic errors that get added later. If an exception is raised
- # prematurely, then the semantic errors wouldn't get reported.
- self.install_config_file("""\
- from buildbot import config
- BuildmasterConfig = {}
- config.error('oh noes!')
- config.error('noes too!')""")
- e = self.assertRaises(config.ConfigErrors,
- lambda : config.MasterConfig.loadConfig(
- self.basedir, self.filename))
- self.assertEqual(e.errors, ['oh noes!', 'noes too!',
- 'no slaves are configured',
- 'no builders are configured'])
-
- def test_loadConfig_no_BuildmasterConfig(self):
- self.install_config_file('x=10')
- self.assertRaisesConfigError("does not define 'BuildmasterConfig'",
- lambda : config.MasterConfig.loadConfig(
- self.basedir, self.filename))
-
- def test_loadConfig_unknown_key(self):
- self.patch_load_helpers()
- self.install_config_file("""\
- BuildmasterConfig = dict(foo=10)
- """)
- self.assertRaisesConfigError("Unknown BuildmasterConfig key foo",
- lambda : config.MasterConfig.loadConfig(
- self.basedir, self.filename))
-
- def test_loadConfig_unknown_keys(self):
- self.patch_load_helpers()
- self.install_config_file("""\
- BuildmasterConfig = dict(foo=10, bar=20)
- """)
- self.assertRaisesConfigError("Unknown BuildmasterConfig keys bar, foo",
- lambda : config.MasterConfig.loadConfig(
- self.basedir, self.filename))
-
- def test_loadConfig_success(self):
- self.patch_load_helpers()
- self.install_config_file("""\
- BuildmasterConfig = dict()
- """)
- rv = config.MasterConfig.loadConfig(
- self.basedir, self.filename)
- self.assertIsInstance(rv, config.MasterConfig)
-
- # make sure all of the loaders and checkers are called
- self.failUnless(rv.load_global.called)
- self.failUnless(rv.load_validation.called)
- self.failUnless(rv.load_db.called)
- self.failUnless(rv.load_metrics.called)
- self.failUnless(rv.load_caches.called)
- self.failUnless(rv.load_schedulers.called)
- self.failUnless(rv.load_builders.called)
- self.failUnless(rv.load_slaves.called)
- self.failUnless(rv.load_change_sources.called)
- self.failUnless(rv.load_status.called)
- self.failUnless(rv.load_user_managers.called)
-
- self.failUnless(rv.check_single_master.called)
- self.failUnless(rv.check_schedulers.called)
- self.failUnless(rv.check_locks.called)
- self.failUnless(rv.check_builders.called)
- self.failUnless(rv.check_status.called)
- self.failUnless(rv.check_horizons.called)
- self.failUnless(rv.check_slavePortnum.called)
-
- def test_loadConfig_with_local_import(self):
- self.patch_load_helpers()
- self.install_config_file("""\
- from subsidiary_module import x
- BuildmasterConfig = dict()
- """,
- {'basedir/subsidiary_module.py' : "x = 10"})
- rv = config.MasterConfig.loadConfig(
- self.basedir, self.filename)
- self.assertIsInstance(rv, config.MasterConfig)
-
-
-class MasterConfig_loaders(ConfigErrorsMixin, unittest.TestCase):
-
- filename = 'test.cfg'
-
- def setUp(self):
- self.cfg = config.MasterConfig()
- self.errors = config.ConfigErrors()
- self.patch(config, '_errors', self.errors)
-
- # utils
-
- def assertResults(self, **expected):
- self.failIf(self.errors, self.errors.errors)
- got = dict([
- (attr, getattr(self.cfg, attr))
- for attr, exp in expected.iteritems() ])
- self.assertEqual(got, expected)
-
- # tests
-
- def test_load_global_defaults(self):
- self.cfg.load_global(self.filename, {})
- self.assertResults(**global_defaults)
-
- def test_load_global_string_param_not_string(self):
- self.cfg.load_global(self.filename,
- dict(title=10))
- self.assertConfigError(self.errors, 'must be a string')
-
- def test_load_global_int_param_not_int(self):
- self.cfg.load_global(self.filename,
- dict(changeHorizon='yes'))
- self.assertConfigError(self.errors, 'must be an int')
-
- def do_test_load_global(self, config_dict, **expected):
- self.cfg.load_global(self.filename, config_dict)
- self.assertResults(**expected)
-
- def test_load_global_title(self):
- self.do_test_load_global(dict(title='hi'), title='hi')
-
- def test_load_global_projectURL(self):
- self.do_test_load_global(dict(projectName='hey'), title='hey')
-
- def test_load_global_titleURL(self):
- self.do_test_load_global(dict(titleURL='hi'), titleURL='hi')
-
- def test_load_global_buildbotURL(self):
- self.do_test_load_global(dict(buildbotURL='hey'), buildbotURL='hey')
-
- def test_load_global_changeHorizon(self):
- self.do_test_load_global(dict(changeHorizon=10), changeHorizon=10)
-
- def test_load_global_changeHorizon_none(self):
- self.do_test_load_global(dict(changeHorizon=None), changeHorizon=None)
-
- def test_load_global_eventHorizon(self):
- self.do_test_load_global(dict(eventHorizon=10), eventHorizon=10)
-
- def test_load_global_logHorizon(self):
- self.do_test_load_global(dict(logHorizon=10), logHorizon=10)
-
- def test_load_global_buildHorizon(self):
- self.do_test_load_global(dict(buildHorizon=10), buildHorizon=10)
-
- def test_load_global_logCompressionLimit(self):
- self.do_test_load_global(dict(logCompressionLimit=10),
- logCompressionLimit=10)
-
- def test_load_global_logCompressionMethod(self):
- self.do_test_load_global(dict(logCompressionMethod='gz'),
- logCompressionMethod='gz')
-
- def test_load_global_logCompressionMethod_invalid(self):
- self.cfg.load_global(self.filename,
- dict(logCompressionMethod='foo'))
- self.assertConfigError(self.errors, "must be 'bz2' or 'gz'")
-
- def test_load_global_codebaseGenerator(self):
- func = lambda _: "dummy"
- self.do_test_load_global(dict(codebaseGenerator=func),
- codebaseGenerator=func)
-
- def test_load_global_codebaseGenerator_invalid(self):
- self.cfg.load_global(self.filename,
- dict(codebaseGenerator='dummy'))
- self.assertConfigError(self.errors,
- "codebaseGenerator must be a callable "
- "accepting a dict and returning a str")
-
- def test_load_global_logMaxSize(self):
- self.do_test_load_global(dict(logMaxSize=123), logMaxSize=123)
-
- def test_load_global_logMaxTailSize(self):
- self.do_test_load_global(dict(logMaxTailSize=123), logMaxTailSize=123)
-
- def test_load_global_properties(self):
- exp = properties.Properties()
- exp.setProperty('x', 10, self.filename)
- self.do_test_load_global(dict(properties=dict(x=10)), properties=exp)
-
- def test_load_global_properties_invalid(self):
- self.cfg.load_global(self.filename,
- dict(properties='yes'))
- self.assertConfigError(self.errors, "must be a dictionary")
-
- def test_load_global_mergeRequests_bool(self):
- self.do_test_load_global(dict(mergeRequests=False),
- mergeRequests=False)
-
- def test_load_global_mergeRequests_callable(self):
- callable = lambda : None
- self.do_test_load_global(dict(mergeRequests=callable),
- mergeRequests=callable)
-
- def test_load_global_mergeRequests_invalid(self):
- self.cfg.load_global(self.filename,
- dict(mergeRequests='yes'))
- self.assertConfigError(self.errors,
- "must be a callable, True, or False")
-
- def test_load_global_prioritizeBuilders_callable(self):
- callable = lambda : None
- self.do_test_load_global(dict(prioritizeBuilders=callable),
- prioritizeBuilders=callable)
-
- def test_load_global_prioritizeBuilders_invalid(self):
- self.cfg.load_global(self.filename,
- dict(prioritizeBuilders='yes'))
- self.assertConfigError(self.errors, "must be a callable")
-
- def test_load_global_slavePortnum_int(self):
- self.do_test_load_global(dict(slavePortnum=123),
- slavePortnum='tcp:123')
-
- def test_load_global_slavePortnum_str(self):
- self.do_test_load_global(dict(slavePortnum='udp:123'),
- slavePortnum='udp:123')
-
- def test_load_global_multiMaster(self):
- self.do_test_load_global(dict(multiMaster=1), multiMaster=1)
-
- def test_load_global_debugPassword(self):
- self.do_test_load_global(dict(debugPassword='xyz'),
- debugPassword='xyz')
-
- def test_load_global_manhole(self):
- mh = mock.Mock(name='manhole')
- self.do_test_load_global(dict(manhole=mh), manhole=mh)
-
- def test_load_global_revlink_callable(self):
- callable = lambda : None
- self.do_test_load_global(dict(revlink=callable),
- revlink=callable)
-
- def test_load_global_revlink_invalid(self):
- self.cfg.load_global(self.filename, dict(revlink=''))
- self.assertConfigError(self.errors, "must be a callable")
-
- def test_load_validation_defaults(self):
- self.cfg.load_validation(self.filename, {})
- self.assertEqual(sorted(self.cfg.validation.keys()),
- sorted([
- 'branch', 'revision', 'property_name', 'property_value',
- ]))
-
- def test_load_validation_invalid(self):
- self.cfg.load_validation(self.filename,
- dict(validation='plz'))
- self.assertConfigError(self.errors, "must be a dictionary")
-
- def test_load_validation_unk_keys(self):
- self.cfg.load_validation(self.filename,
- dict(validation=dict(users='.*')))
- self.assertConfigError(self.errors, "unrecognized validation key(s)")
-
- def test_load_validation(self):
- r = re.compile('.*')
- self.cfg.load_validation(self.filename,
- dict(validation=dict(branch=r)))
- self.assertEqual(self.cfg.validation['branch'], r)
- # check that defaults are still around
- self.assertIn('revision', self.cfg.validation)
-
-
- def test_load_db_defaults(self):
- self.cfg.load_db(self.filename, {})
- self.assertResults(
- db=dict(db_url='sqlite:///state.sqlite', db_poll_interval=None))
-
- def test_load_db_db_url(self):
- self.cfg.load_db(self.filename, dict(db_url='abcd'))
- self.assertResults(db=dict(db_url='abcd', db_poll_interval=None))
-
- def test_load_db_db_poll_interval(self):
- self.cfg.load_db(self.filename, dict(db_poll_interval=2))
- self.assertResults(
- db=dict(db_url='sqlite:///state.sqlite', db_poll_interval=2))
-
- def test_load_db_dict(self):
- self.cfg.load_db(self.filename,
- dict(db=dict(db_url='abcd', db_poll_interval=10)))
- self.assertResults(db=dict(db_url='abcd', db_poll_interval=10))
-
- def test_load_db_unk_keys(self):
- self.cfg.load_db(self.filename,
- dict(db=dict(db_url='abcd', db_poll_interval=10, bar='bar')))
- self.assertConfigError(self.errors, "unrecognized keys in")
-
- def test_load_db_not_int(self):
- self.cfg.load_db(self.filename,
- dict(db=dict(db_url='abcd', db_poll_interval='ten')))
- self.assertConfigError(self.errors, "must be an int")
-
-
- def test_load_metrics_defaults(self):
- self.cfg.load_metrics(self.filename, {})
- self.assertResults(metrics=None)
-
- def test_load_metrics_invalid(self):
- self.cfg.load_metrics(self.filename, dict(metrics=13))
- self.assertConfigError(self.errors, "must be a dictionary")
-
- def test_load_metrics(self):
- self.cfg.load_metrics(self.filename,
- dict(metrics=dict(foo=1)))
- self.assertResults(metrics=dict(foo=1))
-
-
- def test_load_caches_defaults(self):
- self.cfg.load_caches(self.filename, {})
- self.assertResults(caches=dict(Changes=10, Builds=15))
-
- def test_load_caches_invalid(self):
- self.cfg.load_caches(self.filename, dict(caches=13))
- self.assertConfigError(self.errors, "must be a dictionary")
-
- def test_load_caches_buildCacheSize(self):
- self.cfg.load_caches(self.filename,
- dict(buildCacheSize=13))
- self.assertResults(caches=dict(Builds=13, Changes=10))
-
- def test_load_caches_buildCacheSize_and_caches(self):
- self.cfg.load_caches(self.filename,
- dict(buildCacheSize=13, caches=dict(builds=11)))
- self.assertConfigError(self.errors, "cannot specify")
-
- def test_load_caches_changeCacheSize(self):
- self.cfg.load_caches(self.filename,
- dict(changeCacheSize=13))
- self.assertResults(caches=dict(Changes=13, Builds=15))
-
- def test_load_caches_changeCacheSize_and_caches(self):
- self.cfg.load_caches(self.filename,
- dict(changeCacheSize=13, caches=dict(changes=11)))
- self.assertConfigError(self.errors, "cannot specify")
-
- def test_load_caches(self):
- self.cfg.load_caches(self.filename,
- dict(caches=dict(foo=1)))
- self.assertResults(caches=dict(Changes=10, Builds=15, foo=1))
-
- def test_load_caches_entries_test(self):
- self.cfg.load_caches(self.filename,
- dict(caches=dict(foo="1")))
- self.assertConfigError(self.errors,
- "value for cache size 'foo' must be an integer")
-
- def test_load_schedulers_defaults(self):
- self.cfg.load_schedulers(self.filename, {})
- self.assertResults(schedulers={})
-
- def test_load_schedulers_not_list(self):
- self.cfg.load_schedulers(self.filename,
- dict(schedulers=dict()))
- self.assertConfigError(self.errors, "must be a list of")
-
- def test_load_schedulers_not_instance(self):
- self.cfg.load_schedulers(self.filename,
- dict(schedulers=[mock.Mock()]))
- self.assertConfigError(self.errors, "must be a list of")
-
- def test_load_schedulers_dupe(self):
- sch1 = FakeScheduler(name='sch')
- sch2 = FakeScheduler(name='sch')
- self.cfg.load_schedulers(self.filename,
- dict(schedulers=[ sch1, sch2 ]))
- self.assertConfigError(self.errors,
- "scheduler name 'sch' used multiple times")
-
- def test_load_schedulers(self):
- class Sch(schedulers_base.BaseScheduler):
- def __init__(self, name):
- self.name = name
- sch = Sch('sch')
- self.cfg.load_schedulers(self.filename,
- dict(schedulers=[sch]))
- self.assertResults(schedulers=dict(sch=sch))
-
-
- def test_load_builders_defaults(self):
- self.cfg.load_builders(self.filename, {})
- self.assertResults(builders=[])
-
- def test_load_builders_not_list(self):
- self.cfg.load_builders(self.filename,
- dict(builders=dict()))
- self.assertConfigError(self.errors, "must be a list")
-
- def test_load_builders_not_instance(self):
- self.cfg.load_builders(self.filename,
- dict(builders=[mock.Mock()]))
- self.assertConfigError(self.errors, "is not a builder config (in c['builders']")
-
- def test_load_builders(self):
- bldr = config.BuilderConfig(name='x',
- factory=factory.BuildFactory(), slavename='x')
- self.cfg.load_builders(self.filename,
- dict(builders=[bldr]))
- self.assertResults(builders=[bldr])
-
- def test_load_builders_dict(self):
- bldr = dict(name='x', factory=factory.BuildFactory(), slavename='x')
- self.cfg.load_builders(self.filename,
- dict(builders=[bldr]))
- self.assertIsInstance(self.cfg.builders[0], config.BuilderConfig)
- self.assertEqual(self.cfg.builders[0].name, 'x')
-
- @compat.usesFlushWarnings
- def test_load_builders_abs_builddir(self):
- bldr = dict(name='x', factory=factory.BuildFactory(), slavename='x',
- builddir=os.path.abspath('.'))
- self.cfg.load_builders(self.filename,
- dict(builders=[bldr]))
- self.assertEqual(
- len(self.flushWarnings([self.cfg.load_builders])),
- 1)
-
- def test_load_slaves_defaults(self):
- self.cfg.load_slaves(self.filename, {})
- self.assertResults(slaves=[])
-
- def test_load_slaves_not_list(self):
- self.cfg.load_slaves(self.filename,
- dict(slaves=dict()))
- self.assertConfigError(self.errors, "must be a list")
-
- def test_load_slaves_not_instance(self):
- self.cfg.load_slaves(self.filename,
- dict(slaves=[mock.Mock()]))
- self.assertConfigError(self.errors, "must be a list of")
-
- def test_load_slaves_reserved_names(self):
- for name in 'debug', 'change', 'status':
- self.cfg.load_slaves(self.filename,
- dict(slaves=[buildslave.BuildSlave(name, 'x')]))
- self.assertConfigError(self.errors, "is reserved")
- self.errors.errors[:] = [] # clear out the errors
-
- def test_load_slaves(self):
- sl = buildslave.BuildSlave('foo', 'x')
- self.cfg.load_slaves(self.filename,
- dict(slaves=[sl]))
- self.assertResults(slaves=[sl])
-
-
- def test_load_change_sources_defaults(self):
- self.cfg.load_change_sources(self.filename, {})
- self.assertResults(change_sources=[])
-
- def test_load_change_sources_not_instance(self):
- self.cfg.load_change_sources(self.filename,
- dict(change_source=[mock.Mock()]))
- self.assertConfigError(self.errors, "must be a list of")
-
- def test_load_change_sources_single(self):
- chsrc = FakeChangeSource()
- self.cfg.load_change_sources(self.filename,
- dict(change_source=chsrc))
- self.assertResults(change_sources=[chsrc])
-
- def test_load_change_sources_list(self):
- chsrc = FakeChangeSource()
- self.cfg.load_change_sources(self.filename,
- dict(change_source=[chsrc]))
- self.assertResults(change_sources=[chsrc])
-
- def test_load_status_not_list(self):
- self.cfg.load_status(self.filename, dict(status="not-list"))
- self.assertConfigError(self.errors, "must be a list of")
-
- def test_load_status_not_status_rec(self):
- self.cfg.load_status(self.filename, dict(status=['fo']))
- self.assertConfigError(self.errors, "must be a list of")
-
- def test_load_user_managers_defaults(self):
- self.cfg.load_user_managers(self.filename, {})
- self.assertResults(user_managers=[])
-
- def test_load_user_managers_not_list(self):
- self.cfg.load_user_managers(self.filename,
- dict(user_managers='foo'))
- self.assertConfigError(self.errors, "must be a list")
-
- def test_load_user_managers(self):
- um = mock.Mock()
- self.cfg.load_user_managers(self.filename,
- dict(user_managers=[um]))
- self.assertResults(user_managers=[um])
-
-class MasterConfig_checkers(ConfigErrorsMixin, unittest.TestCase):
-
- def setUp(self):
- self.cfg = config.MasterConfig()
- self.errors = config.ConfigErrors()
- self.patch(config, '_errors', self.errors)
-
- # utils
-
- def setup_basic_attrs(self):
- # set up a basic config for checking; this will be modified below
- sch = mock.Mock()
- sch.name = 'sch'
- sch.listBuilderNames = lambda : [ 'b1', 'b2' ]
-
- b1 = mock.Mock()
- b1.name = 'b1'
-
- b2 = mock.Mock()
- b2.name = 'b2'
-
- self.cfg.schedulers = dict(sch=sch)
- self.cfg.slaves = [ mock.Mock() ]
- self.cfg.builders = [ b1, b2 ]
-
- def setup_builder_locks(self,
- builder_lock=None,
- dup_builder_lock=False,
- bare_builder_lock=False):
- """Set-up two mocked builders with specified locks.
-
- @type builder_lock: string or None
- @param builder_lock: Name of the lock to add to first builder.
- If None, no lock is added.
-
- @type dup_builder_lock: boolean
- @param dup_builder_lock: if True, add a lock with duplicate name
- to the second builder
-
- @type dup_builder_lock: boolean
- @param bare_builder_lock: if True, add bare lock objects, don't wrap
- them into locks.LockAccess object
- """
- def bldr(name):
- b = mock.Mock()
- b.name = name
- b.locks = []
- b.factory.steps = [ ('cls', (), dict(locks=[])) ]
- return b
-
- def lock(name):
- l = mock.Mock(spec=locks.MasterLock)
- l.name = name
- if bare_builder_lock:
- return l
- return locks.LockAccess(l, "counting", _skipChecks=True)
-
- b1, b2 = bldr('b1'), bldr('b2')
- self.cfg.builders = [ b1, b2 ]
- if builder_lock:
- b1.locks.append(lock(builder_lock))
- if dup_builder_lock:
- b2.locks.append(lock(builder_lock))
-
- # tests
-
- def test_check_single_master_multimaster(self):
- self.cfg.multiMaster = True
- self.cfg.check_single_master()
- self.assertNoConfigErrors(self.errors)
-
- def test_check_single_master_no_builders(self):
- self.setup_basic_attrs()
- self.cfg.builders = [ ]
- self.cfg.check_single_master()
- self.assertConfigError(self.errors, "no builders are configured")
-
- def test_check_single_master_no_slaves(self):
- self.setup_basic_attrs()
- self.cfg.slaves = [ ]
- self.cfg.check_single_master()
- self.assertConfigError(self.errors, "no slaves are configured")
-
- def test_check_single_master_unsch_builder(self):
- self.setup_basic_attrs()
- b3 = mock.Mock()
- b3.name = 'b3'
- self.cfg.builders.append(b3)
- self.cfg.check_single_master()
- self.assertConfigError(self.errors, "have no schedulers to drive them")
-
-
- def test_check_schedulers_unknown_builder(self):
- self.setup_basic_attrs()
- del self.cfg.builders[1] # remove b2, leaving b1
-
- self.cfg.check_schedulers()
- self.assertConfigError(self.errors, "Unknown builder 'b2'")
-
- def test_check_schedulers_ignored_in_multiMaster(self):
- self.setup_basic_attrs()
- del self.cfg.builders[1] # remove b2, leaving b1
- self.cfg.multiMaster = True
- self.cfg.check_schedulers()
- self.assertNoConfigErrors(self.errors)
-
- def test_check_schedulers(self):
- self.setup_basic_attrs()
- self.cfg.check_schedulers()
- self.assertNoConfigErrors(self.errors)
-
-
- def test_check_locks_dup_builder_lock(self):
- self.setup_builder_locks(builder_lock='l', dup_builder_lock=True)
- self.cfg.check_locks()
- self.assertConfigError(self.errors, "Two locks share")
-
- def test_check_locks(self):
- self.setup_builder_locks(builder_lock='bl')
- self.cfg.check_locks()
- self.assertNoConfigErrors(self.errors)
-
- def test_check_locks_none(self):
- # no locks in the whole config, should be fine
- self.setup_builder_locks()
- self.cfg.check_locks()
- self.assertNoConfigErrors(self.errors)
-
- def test_check_locks_bare(self):
- # check_locks() should be able to handle bare lock object,
- # lock objects that are not wrapped into LockAccess() object
- self.setup_builder_locks(builder_lock='oldlock',
- bare_builder_lock=True)
- self.cfg.check_locks()
- self.assertNoConfigErrors(self.errors)
-
-
- def test_check_builders_unknown_slave(self):
- sl = mock.Mock()
- sl.slavename = 'xyz'
- self.cfg.slaves = [ sl ]
-
- b1 = FakeBuilder(slavenames=[ 'xyz', 'abc' ], builddir='x', name='b1')
- self.cfg.builders = [ b1 ]
-
- self.cfg.check_builders()
- self.assertConfigError(self.errors,
- "builder 'b1' uses unknown slaves 'abc'")
-
- def test_check_builders_duplicate_name(self):
- b1 = FakeBuilder(slavenames=[], name='b1', builddir='1')
- b2 = FakeBuilder(slavenames=[], name='b1', builddir='2')
- self.cfg.builders = [ b1, b2 ]
-
- self.cfg.check_builders()
- self.assertConfigError(self.errors,
- "duplicate builder name 'b1'")
-
- def test_check_builders_duplicate_builddir(self):
- b1 = FakeBuilder(slavenames=[], name='b1', builddir='dir')
- b2 = FakeBuilder(slavenames=[], name='b2', builddir='dir')
- self.cfg.builders = [ b1, b2 ]
-
- self.cfg.check_builders()
- self.assertConfigError(self.errors,
- "duplicate builder builddir 'dir'")
-
- def test_check_builders(self):
- sl = mock.Mock()
- sl.slavename = 'a'
- self.cfg.slaves = [ sl ]
-
- b1 = FakeBuilder(slavenames=[ 'a' ], name='b1', builddir='dir1')
- b2 = FakeBuilder(slavenames=[ 'a' ], name='b2', builddir='dir2')
- self.cfg.builders = [ b1, b2 ]
-
- self.cfg.check_builders()
- self.assertNoConfigErrors(self.errors)
-
-
- def test_check_status_fails(self):
- st = FakeStatusReceiver()
- st.checkConfig = lambda status: config.error("oh noes")
- self.cfg.status = [ st ]
-
- self.cfg.check_status()
-
- self.assertConfigError(self.errors, "oh noes")
-
- def test_check_status(self):
- st = FakeStatusReceiver()
- st.checkConfig = mock.Mock()
- self.cfg.status = [ st ]
-
- self.cfg.check_status()
-
- self.assertNoConfigErrors(self.errors)
- st.checkConfig.assert_called_once_with(self.cfg.status)
-
- def test_check_horizons(self):
- self.cfg.logHorizon = 100
- self.cfg.buildHorizon = 50
- self.cfg.check_horizons()
-
- self.assertConfigError(self.errors, "logHorizon must be less")
-
- def test_check_slavePortnum_set(self):
- self.cfg.slavePortnum = 10
- self.cfg.check_slavePortnum()
- self.assertNoConfigErrors(self.errors)
-
- def test_check_slavePortnum_not_set_slaves(self):
- self.cfg.slaves = [ mock.Mock() ]
- self.cfg.check_slavePortnum()
- self.assertConfigError(self.errors,
- "slaves are configured, but no slavePortnum is set")
-
- def test_check_slavePortnum_not_set_debug(self):
- self.cfg.debugPassword = 'ssh'
- self.cfg.check_slavePortnum()
- self.assertConfigError(self.errors,
- "debug client is configured, but no slavePortnum is set")
-
-
-class BuilderConfig(ConfigErrorsMixin, unittest.TestCase):
-
- factory = factory.BuildFactory()
-
- # utils
-
- def assertAttributes(self, cfg, **expected):
- got = dict([
- (attr, getattr(cfg, attr))
- for attr, exp in expected.iteritems() ])
- self.assertEqual(got, expected)
-
- # tests
-
- def test_no_name(self):
- self.assertRaisesConfigError(
- "builder's name is required",
- lambda : config.BuilderConfig(
- factory=self.factory, slavenames=['a']))
-
- def test_reserved_name(self):
- self.assertRaisesConfigError(
- "builder names must not start with an underscore: '_a'",
- lambda : config.BuilderConfig(name='_a',
- factory=self.factory, slavenames=['a']))
-
- def test_no_factory(self):
- self.assertRaisesConfigError(
- "builder 'a' has no factory",
- lambda : config.BuilderConfig(
- name='a', slavenames=['a']))
-
- def test_wrong_type_factory(self):
- self.assertRaisesConfigError(
- "builder 'a's factory is not",
- lambda : config.BuilderConfig(
- factory=[], name='a', slavenames=['a']))
-
- def test_no_slavenames(self):
- self.assertRaisesConfigError(
- "builder 'a': at least one slavename is required",
- lambda : config.BuilderConfig(
- name='a', factory=self.factory))
-
- def test_bogus_slavenames(self):
- self.assertRaisesConfigError(
- "slavenames must be a list or a string",
- lambda : config.BuilderConfig(
- name='a', slavenames={1:2}, factory=self.factory))
-
- def test_bogus_slavename(self):
- self.assertRaisesConfigError(
- "slavename must be a string",
- lambda : config.BuilderConfig(
- name='a', slavename=1, factory=self.factory))
-
- def test_bogus_category(self):
- self.assertRaisesConfigError(
- "category must be a string",
- lambda : config.BuilderConfig(category=13,
- name='a', slavenames=['a'], factory=self.factory))
-
- def test_inv_nextSlave(self):
- self.assertRaisesConfigError(
- "nextSlave must be a callable",
- lambda : config.BuilderConfig(nextSlave="foo",
- name="a", slavenames=['a'], factory=self.factory))
-
- def test_inv_nextBuild(self):
- self.assertRaisesConfigError(
- "nextBuild must be a callable",
- lambda : config.BuilderConfig(nextBuild="foo",
- name="a", slavenames=['a'], factory=self.factory))
-
- def test_inv_canStartBuild(self):
- self.assertRaisesConfigError(
- "canStartBuild must be a callable",
- lambda : config.BuilderConfig(canStartBuild="foo",
- name="a", slavenames=['a'], factory=self.factory))
-
- def test_inv_env(self):
- self.assertRaisesConfigError(
- "builder's env must be a dictionary",
- lambda : config.BuilderConfig(env="foo",
- name="a", slavenames=['a'], factory=self.factory))
-
- def test_defaults(self):
- cfg = config.BuilderConfig(
- name='a b c', slavename='a', factory=self.factory)
- self.assertIdentical(cfg.factory, self.factory)
- self.assertAttributes(cfg,
- name='a b c',
- slavenames=['a'],
- builddir='a_b_c',
- slavebuilddir='a_b_c',
- category='',
- nextSlave=None,
- locks=[],
- env={},
- properties={},
- mergeRequests=None,
- description=None)
-
- def test_args(self):
- cfg = config.BuilderConfig(
- name='b', slavename='s1', slavenames='s2', builddir='bd',
- slavebuilddir='sbd', factory=self.factory, category='c',
- nextSlave=lambda : 'ns', nextBuild=lambda : 'nb', locks=['l'],
- env=dict(x=10), properties=dict(y=20), mergeRequests='mr',
- description='buzz')
- self.assertIdentical(cfg.factory, self.factory)
- self.assertAttributes(cfg,
- name='b',
- slavenames=['s2', 's1'],
- builddir='bd',
- slavebuilddir='sbd',
- category='c',
- locks=['l'],
- env={'x':10},
- properties={'y':20},
- mergeRequests='mr',
- description='buzz')
-
- def test_getConfigDict(self):
- ns = lambda : 'ns'
- nb = lambda : 'nb'
- cfg = config.BuilderConfig(
- name='b', slavename='s1', slavenames='s2', builddir='bd',
- slavebuilddir='sbd', factory=self.factory, category='c',
- nextSlave=ns, nextBuild=nb, locks=['l'],
- env=dict(x=10), properties=dict(y=20), mergeRequests='mr',
- description='buzz')
- self.assertEqual(cfg.getConfigDict(), {'builddir': 'bd',
- 'category': 'c',
- 'description': 'buzz',
- 'env': {'x': 10},
- 'factory': self.factory,
- 'locks': ['l'],
- 'mergeRequests': 'mr',
- 'name': 'b',
- 'nextBuild': nb,
- 'nextSlave': ns,
- 'properties': {'y': 20},
- 'slavebuilddir': 'sbd',
- 'slavenames': ['s2', 's1'],
- })
-
-
-
-class FakeService(config.ReconfigurableServiceMixin,
- service.Service):
-
- succeed = True
- call_index = 1
-
- def reconfigService(self, new_config):
- self.called = FakeService.call_index
- FakeService.call_index += 1
- d = config.ReconfigurableServiceMixin.reconfigService(self, new_config)
- if not self.succeed:
- @d.addCallback
- def fail(_):
- raise ValueError("oh noes")
- return d
-
-
-
-class FakeMultiService(config.ReconfigurableServiceMixin,
- service.MultiService):
-
- def reconfigService(self, new_config):
- self.called = True
- d = config.ReconfigurableServiceMixin.reconfigService(self, new_config)
- return d
-
-
-
-class ReconfigurableServiceMixin(unittest.TestCase):
-
- def test_service(self):
- svc = FakeService()
- d = svc.reconfigService(mock.Mock())
- @d.addCallback
- def check(_):
- self.assertTrue(svc.called)
- return d
-
- @defer.inlineCallbacks
- def test_service_failure(self):
- svc = FakeService()
- svc.succeed = False
- try:
- yield svc.reconfigService(mock.Mock())
- except ValueError:
- pass
- else:
- self.fail("should have raised ValueError")
-
- def test_multiservice(self):
- svc = FakeMultiService()
- ch1 = FakeService()
- ch1.setServiceParent(svc)
- ch2 = FakeMultiService()
- ch2.setServiceParent(svc)
- ch3 = FakeService()
- ch3.setServiceParent(ch2)
- d = svc.reconfigService(mock.Mock())
- @d.addCallback
- def check(_):
- self.assertTrue(svc.called)
- self.assertTrue(ch1.called)
- self.assertTrue(ch2.called)
- self.assertTrue(ch3.called)
- return d
-
- def test_multiservice_priority(self):
- parent = FakeMultiService()
- svc128 = FakeService()
- svc128.setServiceParent(parent)
-
- services = [ svc128 ]
- for i in range(20, 1, -1):
- svc = FakeService()
- svc.reconfig_priority = i
- svc.setServiceParent(parent)
- services.append(svc)
-
- d = parent.reconfigService(mock.Mock())
- @d.addCallback
- def check(_):
- prio_order = [ svc.called for svc in services ]
- called_order = sorted(prio_order)
- self.assertEqual(prio_order, called_order)
- return d
-
- @compat.usesFlushLoggedErrors
- @defer.inlineCallbacks
- def test_multiservice_nested_failure(self):
- svc = FakeMultiService()
- ch1 = FakeService()
- ch1.setServiceParent(svc)
- ch1.succeed = False
- try:
- yield svc.reconfigService(mock.Mock())
- except ValueError:
- pass
- else:
- self.fail("should have raised ValueError")
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_contrib_buildbot_cvs_mail.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_contrib_buildbot_cvs_mail.py
deleted file mode 100644
index 30aaad07..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_contrib_buildbot_cvs_mail.py
+++ /dev/null
@@ -1,191 +0,0 @@
-# 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 sys
-import re
-import os
-
-from twisted.python import log
-from twisted.trial import unittest
-from twisted.internet import protocol, defer, utils, reactor
-
-test = '''
-Update of /cvsroot/test
-In directory example:/tmp/cvs-serv21085
-
-Modified Files:
- README hello.c
-Log Message:
-two files checkin
-
-'''
-golden_1_11_regex=[
- '^From:',
- '^To: buildbot@example.com$',
- '^Reply-To: noreply@example.com$',
- '^Subject: cvs update for project test$',
- '^Date:',
- '^X-Mailer: Python buildbot-cvs-mail',
- '^$',
- '^Cvsmode: 1.11$',
- '^Category: None',
- '^CVSROOT: \"ext:example:/cvsroot\"',
- '^Files: test README 1.1,1.2 hello.c 2.2,2.3$',
- '^Project: test$',
- '^$',
- '^Update of /cvsroot/test$',
- '^In directory example:/tmp/cvs-serv21085$',
- '^$',
- '^Modified Files:$',
- 'README hello.c$',
- 'Log Message:$',
- '^two files checkin',
- '^$',
- '^$']
-
-golden_1_12_regex=[
- '^From: ',
- '^To: buildbot@example.com$',
- '^Reply-To: noreply@example.com$',
- '^Subject: cvs update for project test$',
- '^Date: ',
- '^X-Mailer: Python buildbot-cvs-mail',
- '^$',
- '^Cvsmode: 1.12$',
- '^Category: None$',
- '^CVSROOT: \"ext:example.com:/cvsroot\"$',
- '^Files: README 1.1 1.2 hello.c 2.2 2.3$',
- '^Path: test$',
- '^Project: test$',
- '^$',
- '^Update of /cvsroot/test$',
- '^In directory example:/tmp/cvs-serv21085$',
- '^$',
- '^Modified Files:$',
- 'README hello.c$',
- '^Log Message:$',
- 'two files checkin',
- '^$',
- '^$' ]
-
-class _SubprocessProtocol(protocol.ProcessProtocol):
- def __init__(self, input, deferred):
- self.input = input
- self.deferred = deferred
- self.output = ''
-
- def outReceived(self, s):
- self.output += s
- errReceived = outReceived
-
- def connectionMade(self):
- # push the input and send EOF
- self.transport.write(self.input)
- self.transport.closeStdin()
-
- def processEnded(self, reason):
- self.deferred.callback((self.output, reason.value.exitCode))
-
-def getProcessOutputAndValueWithInput(executable, args, input):
- "similar to getProcessOutputAndValue, but also allows injection of input on stdin"
- d = defer.Deferred()
- p = _SubprocessProtocol(input, d)
- reactor.spawnProcess(p, executable, (executable,) + tuple(args))
- return d
-
-class TestBuildbotCvsMail(unittest.TestCase):
- buildbot_cvs_mail_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../../contrib/buildbot_cvs_mail.py'))
- if not os.path.exists(buildbot_cvs_mail_path):
- skip = ("'%s' does not exist (normal unless run from git)"
- % buildbot_cvs_mail_path)
-
- def assertOutputOk(self, (output, code), regexList):
- "assert that the output from getProcessOutputAndValueWithInput matches expectations"
- try:
- self.failUnlessEqual(code, 0, "subprocess exited uncleanly")
- lines = output.splitlines()
- self.failUnlessEqual(len(lines), len(regexList),
- "got wrong number of lines of output")
-
- misses = []
- for line, regex in zip(lines, regexList):
- m = re.search(regex, line)
- if not m:
- misses.append((regex,line))
- self.assertEqual(misses, [], "got non-matching lines")
- except:
- log.msg("got output:\n" + output)
- raise
-
- def test_buildbot_cvs_mail_from_cvs1_11(self):
- # Simulate CVS 1.11
- d = getProcessOutputAndValueWithInput(sys.executable,
- [ self.buildbot_cvs_mail_path, '--cvsroot=\"ext:example:/cvsroot\"',
- '--email=buildbot@example.com', '-P', 'test', '-R', 'noreply@example.com', '-t',
- 'test', 'README', '1.1,1.2', 'hello.c', '2.2,2.3' ],
- input=test)
- d.addCallback(self.assertOutputOk, golden_1_11_regex)
- return d
-
- def test_buildbot_cvs_mail_from_cvs1_12(self):
- # Simulate CVS 1.12, with --path option
- d = getProcessOutputAndValueWithInput(sys.executable,
- [ self.buildbot_cvs_mail_path, '--cvsroot=\"ext:example.com:/cvsroot\"',
- '--email=buildbot@example.com', '-P', 'test', '--path', 'test',
- '-R', 'noreply@example.com', '-t',
- 'README', '1.1', '1.2', 'hello.c', '2.2', '2.3' ],
- input=test)
- d.addCallback(self.assertOutputOk, golden_1_12_regex)
- return d
-
- def test_buildbot_cvs_mail_no_args_exits_with_error(self):
- d = utils.getProcessOutputAndValue(sys.executable, [ self.buildbot_cvs_mail_path ])
- def check((stdout, stderr, code)):
- self.assertEqual(code, 2)
- d.addCallback(check)
- return d
-
- def test_buildbot_cvs_mail_without_email_opt_exits_with_error(self):
- d = utils.getProcessOutputAndValue(sys.executable, [ self.buildbot_cvs_mail_path,
- '--cvsroot=\"ext:example.com:/cvsroot\"',
- '-P', 'test', '--path', 'test',
- '-R', 'noreply@example.com', '-t',
- 'README', '1.1', '1.2', 'hello.c', '2.2', '2.3'])
- def check((stdout, stderr, code)):
- self.assertEqual(code, 2)
- d.addCallback(check)
- return d
-
- def test_buildbot_cvs_mail_without_cvsroot_opt_exits_with_error(self):
- d = utils.getProcessOutputAndValue(sys.executable, [ self.buildbot_cvs_mail_path,
- '--complete-garbage-opt=gomi',
- '--cvsroot=\"ext:example.com:/cvsroot\"',
- '--email=buildbot@example.com','-P', 'test', '--path',
- 'test', '-R', 'noreply@example.com', '-t',
- 'README', '1.1', '1.2', 'hello.c', '2.2', '2.3'])
- def check((stdout, stderr, code)):
- self.assertEqual(code, 2)
- d.addCallback(check)
- return d
-
- def test_buildbot_cvs_mail_with_unknown_opt_exits_with_error(self):
- d = utils.getProcessOutputAndValue(sys.executable, [ self.buildbot_cvs_mail_path,
- '--email=buildbot@example.com','-P', 'test', '--path',
- 'test', '-R', 'noreply@example.com', '-t',
- 'README', '1.1', '1.2', 'hello.c', '2.2', '2.3'])
- def check((stdout, stderr, code)):
- self.assertEqual(code, 2)
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_base.py
deleted file mode 100644
index 24c8492c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_base.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# 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
-import mock
-from buildbot.db import base
-from twisted.trial import unittest
-from twisted.internet import defer
-
-class TestBase(unittest.TestCase):
-
- def setUp(self):
- meta = sa.MetaData()
- self.tbl = sa.Table('tbl', meta,
- sa.Column('str32', sa.String(length=32)),
- sa.Column('txt', sa.Text))
- self.db = mock.Mock()
- self.db.pool.engine.dialect.name = 'mysql'
- self.comp = base.DBConnectorComponent(self.db)
-
- def test_check_length_ok(self):
- self.comp.check_length(self.tbl.c.str32, "short string")
-
- def test_check_length_long(self):
- self.assertRaises(RuntimeError, lambda :
- self.comp.check_length(self.tbl.c.str32, "long string" * 5))
-
- def test_check_length_text(self):
- self.assertRaises(AssertionError, lambda :
- self.comp.check_length(self.tbl.c.txt, "long string" * 5))
-
- def test_check_length_long_not_mysql(self):
- self.db.pool.engine.dialect.name = 'sqlite'
- self.comp.check_length(self.tbl.c.str32, "long string" * 5)
- # run that again since the method gets stubbed out
- self.comp.check_length(self.tbl.c.str32, "long string" * 5)
-
-class TestCachedDecorator(unittest.TestCase):
-
- def setUp(self):
- # set this to True to check that cache.get isn't called (for
- # no_cache=1)
- self.cache_get_raises_exception = False
-
- class TestConnectorComponent(base.DBConnectorComponent):
- invocations = None
- @base.cached("mycache")
- def getThing(self, key):
- if self.invocations is None:
- self.invocations = []
- self.invocations.append(key)
- return defer.succeed(key * 2)
-
- def get_cache(self, cache_name, miss_fn):
- self.assertEqual(cache_name, "mycache")
- cache = mock.Mock(name="mycache")
- if self.cache_get_raises_exception:
- def ex(key):
- raise RuntimeError("cache.get called unexpectedly")
- cache.get = ex
- else:
- cache.get = miss_fn
- return cache
-
- # tests
-
- @defer.inlineCallbacks
- def test_cached(self):
- # attach it to the connector
- connector = mock.Mock(name="connector")
- connector.master.caches.get_cache = self.get_cache
-
- # build an instance
- comp = self.TestConnectorComponent(connector)
-
- # test it twice (to test an implementation detail)
- res1 = yield comp.getThing("foo")
-
- res2 = yield comp.getThing("bar")
-
- self.assertEqual((res1, res2, comp.invocations),
- ('foofoo', 'barbar', ['foo', 'bar']))
-
- @defer.inlineCallbacks
- def test_cached_no_cache(self):
- # attach it to the connector
- connector = mock.Mock(name="connector")
- connector.master.caches.get_cache = self.get_cache
- self.cache_get_raises_exception = True
-
- # build an instance
- comp = self.TestConnectorComponent(connector)
-
- yield comp.getThing("foo", no_cache=1)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_buildrequests.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_buildrequests.py
deleted file mode 100644
index a4b1c001..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_buildrequests.py
+++ /dev/null
@@ -1,729 +0,0 @@
-# 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 datetime
-import sqlalchemy as sa
-from twisted.trial import unittest
-from twisted.internet import task, defer
-from buildbot.db import buildrequests
-from buildbot.test.util import connector_component, db
-from buildbot.test.fake import fakedb
-from buildbot.util import UTC, epoch2datetime
-
-class TestBuildsetsConnectorComponent(
- connector_component.ConnectorComponentMixin,
- unittest.TestCase):
-
- # test that the datetime translations are done correctly by specifying
- # the epoch timestamp and datetime objects explicitly. These should
- # pass regardless of the local timezone used while running tests!
- CLAIMED_AT = datetime.datetime(1978, 6, 15, 12, 31, 15, tzinfo=UTC)
- CLAIMED_AT_EPOCH = 266761875
- SUBMITTED_AT = datetime.datetime(1979, 6, 15, 12, 31, 15, tzinfo=UTC)
- SUBMITTED_AT_EPOCH = 298297875
- COMPLETE_AT = datetime.datetime(1980, 6, 15, 12, 31, 15, tzinfo=UTC)
- COMPLETE_AT_EPOCH = 329920275
- BSID = 567
- BSID2 = 5670
- MASTER_ID = "set in setUp"
- OTHER_MASTER_ID = "set in setUp"
-
- MASTER_NAME = "testmaster"
- MASTER_INCARN = "pid123-boot456789"
-
- def setUp(self):
- self.MASTER_ID = fakedb.FakeBuildRequestsComponent.MASTER_ID
- self.OTHER_MASTER_ID = self.MASTER_ID + 1111
- d = self.setUpConnectorComponent(
- table_names=[ 'patches', 'changes', 'sourcestamp_changes',
- 'buildsets', 'buildset_properties', 'buildrequests',
- 'objects', 'buildrequest_claims', 'sourcestamps', 'sourcestampsets' ])
-
- def finish_setup(_):
- self.db.buildrequests = \
- buildrequests.BuildRequestsConnectorComponent(self.db)
- self.db.master.getObjectId = lambda : defer.succeed(self.MASTER_ID)
- d.addCallback(finish_setup)
-
- # set up a sourcestamp and buildset for use below
- d.addCallback(lambda _ :
- self.insertTestData([
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234),
- fakedb.Object(id=self.MASTER_ID, name="fake master",
- class_name="BuildMaster"),
- fakedb.Object(id=self.OTHER_MASTER_ID, name="other master",
- class_name="BuildMaster"),
- fakedb.Buildset(id=self.BSID, sourcestampsetid=234),
- ]))
-
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- # tests
-
- def test_getBuildRequest(self):
- # ned fakedb.BuildRequestClaim
- d = self.insertTestData([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID, buildername="bbb",
- complete=1, results=75, priority=7,
- submitted_at=self.SUBMITTED_AT_EPOCH,
- complete_at=self.COMPLETE_AT_EPOCH),
- fakedb.BuildRequestClaim(
- brid=44, objectid=self.MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
- ])
- d.addCallback(lambda _ :
- self.db.buildrequests.getBuildRequest(44))
- def check(brdict):
- self.assertEqual(brdict,
- dict(brid=44, buildsetid=self.BSID, buildername="bbb",
- priority=7, claimed=True, mine=True, complete=True,
- results=75, claimed_at=self.CLAIMED_AT,
- submitted_at=self.SUBMITTED_AT,
- complete_at=self.COMPLETE_AT))
- d.addCallback(check)
- return d
-
- def test_getBuildRequest_missing(self):
- d = self.db.buildrequests.getBuildRequest(44)
- def check(brdict):
- self.assertEqual(brdict, None)
- d.addCallback(check)
- return d
-
- def do_test_getBuildRequests_claim_args(self, **kwargs):
- expected = kwargs.pop('expected')
- d = self.insertTestData([
- # 50: claimed by this master
- fakedb.BuildRequest(id=50, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=50, objectid=self.MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
-
- # 51: claimed by another master
- fakedb.BuildRequest(id=51, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=51, objectid=self.OTHER_MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
-
- # 52: unclaimed
- fakedb.BuildRequest(id=52, buildsetid=self.BSID),
-
- # 53: unclaimed but complete (should not appear for claimed=False)
- fakedb.BuildRequest(id=53, buildsetid=self.BSID, complete=1),
- ])
- d.addCallback(lambda _ :
- self.db.buildrequests.getBuildRequests(**kwargs))
- def check(brlist):
- self.assertEqual(sorted([ br['brid'] for br in brlist ]),
- sorted(expected))
- d.addCallback(check)
- return d
-
- def test_getBuildRequests_no_claimed_arg(self):
- return self.do_test_getBuildRequests_claim_args(
- expected=[50, 51, 52, 53])
-
- def test_getBuildRequests_claimed_mine(self):
- return self.do_test_getBuildRequests_claim_args(
- claimed="mine",
- expected=[50])
-
- def test_getBuildRequests_claimed_true(self):
- return self.do_test_getBuildRequests_claim_args(
- claimed=True,
- expected=[50, 51])
-
- def test_getBuildRequests_unclaimed(self):
- return self.do_test_getBuildRequests_claim_args(
- claimed=False,
- expected=[52])
-
- def do_test_getBuildRequests_buildername_arg(self, **kwargs):
- expected = kwargs.pop('expected')
- d = self.insertTestData([
- # 8: 'bb'
- fakedb.BuildRequest(id=8, buildsetid=self.BSID, buildername='bb'),
- # 9: 'cc'
- fakedb.BuildRequest(id=9, buildsetid=self.BSID, buildername='cc'),
- # 10: 'cc'
- fakedb.BuildRequest(id=10, buildsetid=self.BSID, buildername='cc'),
- ])
- d.addCallback(lambda _ :
- self.db.buildrequests.getBuildRequests(**kwargs))
- def check(brlist):
- self.assertEqual(sorted([ br['brid'] for br in brlist ]),
- sorted(expected))
- d.addCallback(check)
- return d
-
- def test_getBuildRequests_buildername_single(self):
- return self.do_test_getBuildRequests_buildername_arg(
- buildername='bb',
- expected=[8])
-
- def test_getBuildRequests_buildername_multiple(self):
- return self.do_test_getBuildRequests_buildername_arg(
- buildername='cc',
- expected=[9,10])
-
- def test_getBuildRequests_buildername_none(self):
- return self.do_test_getBuildRequests_buildername_arg(
- buildername='dd',
- expected=[])
-
- def do_test_getBuildRequests_complete_arg(self, **kwargs):
- expected = kwargs.pop('expected')
- d = self.insertTestData([
- # 70: incomplete
- fakedb.BuildRequest(id=70, buildsetid=self.BSID,
- complete=0, complete_at=None),
- # 80: complete
- fakedb.BuildRequest(id=80, buildsetid=self.BSID,
- complete=1,
- complete_at=self.COMPLETE_AT_EPOCH),
- # 81: complete but no complete_at
- fakedb.BuildRequest(id=81, buildsetid=self.BSID,
- complete=1, complete_at=0),
- # 82: complete_at set but complete is false, so not complete
- fakedb.BuildRequest(id=82, buildsetid=self.BSID,
- complete=0,
- complete_at=self.COMPLETE_AT_EPOCH),
- ])
- d.addCallback(lambda _ :
- self.db.buildrequests.getBuildRequests(**kwargs))
- def check(brlist):
- self.assertEqual(sorted([ br['brid'] for br in brlist ]),
- sorted(expected))
- d.addCallback(check)
- return d
-
- def test_getBuildRequests_complete_none(self):
- return self.do_test_getBuildRequests_complete_arg(
- expected=[ 70, 80, 81, 82])
-
- def test_getBuildRequests_complete_true(self):
- return self.do_test_getBuildRequests_complete_arg(
- complete=True,
- expected=[ 80, 81 ])
-
- def test_getBuildRequests_complete_false(self):
- return self.do_test_getBuildRequests_complete_arg(
- complete=False,
- expected=[ 70, 82 ])
-
- def test_getBuildRequests_bsid_arg(self):
- d = self.insertTestData([
- # the buildset that we are *not* looking for
- fakedb.Buildset(id=self.BSID+1, sourcestampsetid=234),
-
- fakedb.BuildRequest(id=70, buildsetid=self.BSID,
- complete=0, complete_at=None),
- fakedb.BuildRequest(id=71, buildsetid=self.BSID+1,
- complete=0, complete_at=None),
- fakedb.BuildRequest(id=72, buildsetid=self.BSID,
- complete=0, complete_at=None),
- ])
- d.addCallback(lambda _ :
- self.db.buildrequests.getBuildRequests(bsid=self.BSID))
- def check(brlist):
- self.assertEqual(sorted([ br['brid'] for br in brlist ]),
- sorted([70, 72]))
- d.addCallback(check)
- return d
-
- def test_getBuildRequests_combo(self):
- d = self.insertTestData([
- # 44: everything we want
- fakedb.BuildRequest(id=44, buildsetid=self.BSID, buildername="bbb",
- complete=1, results=92,
- complete_at=self.COMPLETE_AT_EPOCH),
- fakedb.BuildRequestClaim(brid=44, objectid=self.MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
-
- # 45: different buildername
- fakedb.BuildRequest(id=45, buildsetid=self.BSID, buildername="ccc",
- complete=1,
- complete_at=self.COMPLETE_AT_EPOCH),
- fakedb.BuildRequestClaim(brid=45, objectid=self.MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
-
- # 46: incomplete
- fakedb.BuildRequest(id=46, buildsetid=self.BSID, buildername="bbb",
- complete=0, results=92,
- complete_at=0),
- fakedb.BuildRequestClaim(brid=46, objectid=self.MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
-
- # 47: unclaimed
- fakedb.BuildRequest(id=47, buildsetid=self.BSID, buildername="bbb",
- complete=1, results=92,
- complete_at=self.COMPLETE_AT_EPOCH),
-
- # 48: claimed by other
- fakedb.BuildRequest(id=48, buildsetid=self.BSID, buildername="bbb",
- complete=1, results=92,
- complete_at=self.COMPLETE_AT_EPOCH),
- fakedb.BuildRequestClaim(brid=48, objectid=self.OTHER_MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
-
- # 49: different bsid
- fakedb.Buildset(id=self.BSID+1, sourcestampsetid=234),
- fakedb.BuildRequest(id=49, buildsetid=self.BSID+1,
- buildername="bbb", complete=1, results=92,
- complete_at=self.COMPLETE_AT_EPOCH),
- fakedb.BuildRequestClaim(brid=49, objectid=self.MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
- ])
- d.addCallback(lambda _ :
- self.db.buildrequests.getBuildRequests(buildername="bbb",
- claimed="mine", complete=True, bsid=self.BSID))
- def check(brlist):
- self.assertEqual([ br['brid'] for br in brlist ], [ 44 ])
- d.addCallback(check)
- return d
-
- def do_test_getBuildRequests_branch_arg(self, **kwargs):
- expected = kwargs.pop('expected')
- d = self.insertTestData([
- fakedb.BuildRequest(id=70, buildsetid=self.BSID+1),
- fakedb.Buildset(id=self.BSID+1, sourcestampsetid=self.BSID+1),
- fakedb.SourceStampSet(id=self.BSID+1),
- fakedb.SourceStamp(sourcestampsetid=self.BSID+1,
- branch='branch_A'),
-
- fakedb.BuildRequest(id=80, buildsetid=self.BSID+2),
- fakedb.Buildset(id=self.BSID+2, sourcestampsetid=self.BSID+2),
- fakedb.SourceStampSet(id=self.BSID+2),
- fakedb.SourceStamp(sourcestampsetid=self.BSID+2,
- repository='repository_A'),
-
- fakedb.BuildRequest(id=90, buildsetid=self.BSID+3),
- fakedb.Buildset(id=self.BSID+3, sourcestampsetid=self.BSID+3),
- fakedb.SourceStampSet(id=self.BSID+3),
- fakedb.SourceStamp(sourcestampsetid=self.BSID+3,
- branch='branch_A', repository='repository_A'),
- ])
- d.addCallback(lambda _ :
- self.db.buildrequests.getBuildRequests(**kwargs))
- def check(brlist):
- self.assertEqual(sorted([ br['brid'] for br in brlist ]),
- sorted(expected))
- d.addCallback(check)
- return d
-
- def test_getBuildRequests_branch(self):
- return self.do_test_getBuildRequests_branch_arg(branch='branch_A',
- expected=[70, 90])
-
- def test_getBuildRequests_branch_empty(self):
- return self.do_test_getBuildRequests_branch_arg(branch='absent_branch',
- expected=[])
-
- def test_getBuildRequests_repository(self):
- return self.do_test_getBuildRequests_branch_arg(
- repository='repository_A', expected=[80, 90])
-
- def test_getBuildRequests_repository_empty(self):
- return self.do_test_getBuildRequests_branch_arg(
- repository='absent_repository', expected=[])
-
- def test_getBuildRequests_repository_and_branch(self):
- return self.do_test_getBuildRequests_branch_arg(
- repository='repository_A', branch='branch_A', expected=[90])
-
- def test_getBuildRequests_no_repository_nor_branch(self):
- return self.do_test_getBuildRequests_branch_arg(expected=[70, 80, 90])
-
- def do_test_claimBuildRequests(self, rows, now, brids, expected=None,
- expfailure=None, claimed_at=None):
- clock = task.Clock()
- clock.advance(now)
-
- d = self.insertTestData(rows)
- d.addCallback(lambda _ :
- self.db.buildrequests.claimBuildRequests(brids=brids,
- claimed_at=claimed_at, _reactor=clock))
- def check(brlist):
- self.assertNotEqual(expected, None,
- "unexpected success from claimBuildRequests")
- def thd(conn):
- reqs_tbl = self.db.model.buildrequests
- claims_tbl = self.db.model.buildrequest_claims
- q = sa.select([ reqs_tbl.outerjoin(claims_tbl,
- reqs_tbl.c.id == claims_tbl.c.brid) ])
- results = conn.execute(q).fetchall()
- self.assertEqual(
- sorted([ (r.id, r.claimed_at, r.objectid)
- for r in results ]),
- sorted(expected))
- return self.db.pool.do(thd)
- d.addCallback(check)
- def fail(f):
- if not expfailure:
- raise f
- f.trap(expfailure)
- d.addErrback(fail)
- return d
-
- def test_claimBuildRequests_single(self):
- return self.do_test_claimBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- ], 1300305712, [ 44 ],
- [ (44, 1300305712, self.MASTER_ID) ])
-
- def test_claimBuildRequests_single_explicit_claimed_at(self):
- return self.do_test_claimBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- ], 1300305712, [ 44 ],
- [ (44, 14000000, self.MASTER_ID) ],
- claimed_at=epoch2datetime(14000000))
-
- def test_claimBuildRequests_multiple(self):
- return self.do_test_claimBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- fakedb.BuildRequest(id=45, buildsetid=self.BSID),
- fakedb.BuildRequest(id=46, buildsetid=self.BSID),
- ], 1300305712, [ 44, 46 ],
- [
- (44, 1300305712, self.MASTER_ID),
- (45, None, None),
- (46, 1300305712, self.MASTER_ID),
- ])
-
- def test_claimBuildRequests_stress(self):
- return self.do_test_claimBuildRequests([
- fakedb.BuildRequest(id=id, buildsetid=self.BSID)
- for id in xrange(1, 1000)
- ], 1300305713, range(1, 1000),
- [
- (id, 1300305713, self.MASTER_ID)
- for id in xrange(1, 1000)
- ])
-
- def test_claimBuildRequests_other_master_claim(self):
- return self.do_test_claimBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=44,
- objectid=self.OTHER_MASTER_ID,
- claimed_at=1300103810),
- ], 1300305712, [ 44 ],
- expfailure=buildrequests.AlreadyClaimedError)
-
- @db.skip_for_dialect('mysql')
- def test_claimBuildRequests_other_master_claim_stress(self):
- d = self.do_test_claimBuildRequests(
- [ fakedb.BuildRequest(id=id, buildsetid=self.BSID)
- for id in range(1, 1000) ] +
- [
- fakedb.BuildRequest(id=1000, buildsetid=self.BSID),
- # the fly in the ointment..
- fakedb.BuildRequestClaim(brid=1000,
- objectid=self.OTHER_MASTER_ID, claimed_at=1300103810),
- ], 1300305712, range(1, 1001),
- expfailure=buildrequests.AlreadyClaimedError)
- def check(_):
- # check that [1,1000) were not claimed, and 1000 is still claimed
- def thd(conn):
- tbl = self.db.model.buildrequest_claims
- q = tbl.select()
- results = conn.execute(q).fetchall()
- self.assertEqual([ (r.brid, r.objectid, r.claimed_at)
- for r in results ][:10],
- [ (1000, self.OTHER_MASTER_ID, 1300103810) ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_claimBuildRequests_sequential(self):
- now = 120350934
- clock = task.Clock()
- clock.advance(now)
-
- d = self.insertTestData([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- fakedb.BuildRequest(id=45, buildsetid=self.BSID),
- ])
- d.addCallback(lambda _ :
- self.db.buildrequests.claimBuildRequests(brids=[44],
- _reactor=clock))
- d.addCallback(lambda _ :
- self.db.buildrequests.claimBuildRequests(brids=[45],
- _reactor=clock))
- def check(brlist):
- def thd(conn):
- reqs_tbl = self.db.model.buildrequests
- claims_tbl = self.db.model.buildrequest_claims
- join = reqs_tbl.outerjoin(claims_tbl,
- reqs_tbl.c.id == claims_tbl.c.brid)
- q = join.select(claims_tbl.c.claimed_at == None)
- results = conn.execute(q).fetchall()
- self.assertEqual(results, [])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def do_test_reclaimBuildRequests(self, rows, now, brids, expected=None,
- expfailure=None):
- clock = task.Clock()
- clock.advance(now)
-
- d = self.insertTestData(rows)
- d.addCallback(lambda _ :
- self.db.buildrequests.reclaimBuildRequests(brids=brids,
- _reactor=clock))
- def check(brlist):
- self.assertNotEqual(expected, None,
- "unexpected success from claimBuildRequests")
- def thd(conn):
- reqs_tbl = self.db.model.buildrequests
- claims_tbl = self.db.model.buildrequest_claims
- q = sa.select([ reqs_tbl.outerjoin(claims_tbl,
- reqs_tbl.c.id == claims_tbl.c.brid) ])
- results = conn.execute(q).fetchall()
- self.assertEqual(
- sorted([ (r.id, r.claimed_at, r.objectid)
- for r in results ]),
- sorted(expected))
- return self.db.pool.do(thd)
- d.addCallback(check)
- def fail(f):
- if not expfailure:
- raise f
- f.trap(expfailure)
- d.addErrback(fail)
- return d
-
- def test_reclaimBuildRequests(self):
- return self.do_test_reclaimBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=44, objectid=self.MASTER_ID,
- claimed_at=1300103810),
- ], 1300305712, [ 44 ],
- # note that the time is updated
- [ (44, 1300305712, self.MASTER_ID) ])
-
- def test_reclaimBuildRequests_fail(self):
- d = self.do_test_reclaimBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=44, objectid=self.MASTER_ID,
- claimed_at=1300103810),
- fakedb.BuildRequest(id=45, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=45, objectid=self.OTHER_MASTER_ID,
- claimed_at=1300103810),
- ], 1300305712, [ 44, 45 ],
- expfailure=buildrequests.AlreadyClaimedError)
- def check(_):
- # check that the time wasn't updated on 44, noting that MySQL does
- # not support this.
- if self.db_engine.dialect.name == 'mysql':
- return
- def thd(conn):
- tbl = self.db.model.buildrequest_claims
- q = tbl.select(order_by=tbl.c.brid)
- results = conn.execute(q).fetchall()
- self.assertEqual([ (r.brid, r.claimed_at, r.objectid)
- for r in results ], [
- (44, 1300103810, self.MASTER_ID),
- (45, 1300103810, self.OTHER_MASTER_ID),
- ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def do_test_completeBuildRequests(self, rows, now, expected=None,
- expfailure=None, brids=[44],
- complete_at=None):
- clock = task.Clock()
- clock.advance(now)
-
- d = self.insertTestData(rows)
- d.addCallback(lambda _ :
- self.db.buildrequests.completeBuildRequests(brids=brids,
- results=7, complete_at=complete_at,
- _reactor=clock))
- def check(brlist):
- self.assertNotEqual(expected, None,
- "unexpected success from completeBuildRequests")
- def thd(conn):
- tbl = self.db.model.buildrequests
- q = sa.select([ tbl.c.id, tbl.c.complete,
- tbl.c.results, tbl.c.complete_at ])
- results = conn.execute(q).fetchall()
- self.assertEqual(sorted(map(tuple, results)), sorted(expected))
- return self.db.pool.do(thd)
- d.addCallback(check)
- def fail(f):
- if not expfailure:
- raise f
- f.trap(expfailure)
- d.addErrback(fail)
- return d
-
- def test_completeBuildRequests(self):
- return self.do_test_completeBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=44, objectid=self.MASTER_ID,
- claimed_at=1300103810),
- ], 1300305712,
- [ (44, 1, 7, 1300305712) ])
-
- def test_completeBuildRequests_explicit_time(self):
- return self.do_test_completeBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=44, objectid=self.MASTER_ID,
- claimed_at=1300103810),
- ], 1300305712,
- [ (44, 1, 7, 999999) ],
- complete_at=epoch2datetime(999999))
-
- def test_completeBuildRequests_multiple(self):
- return self.do_test_completeBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=44, objectid=self.MASTER_ID,
- claimed_at=1300103810),
- fakedb.BuildRequest(id=45, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=45, objectid=self.OTHER_MASTER_ID,
- claimed_at=1300103811),
- fakedb.BuildRequest(id=46, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=46, objectid=self.MASTER_ID,
- claimed_at=1300103812),
- ], 1300305712,
- [ (44, 1, 7, 1300305712),
- (45, 0, -1, 0),
- (46, 1, 7, 1300305712),
- ], brids=[44, 46])
-
- def test_completeBuildRequests_stress(self):
- return self.do_test_completeBuildRequests([
- fakedb.BuildRequest(id=id, buildsetid=self.BSID)
- for id in range(1, 280)
- ] + [
- fakedb.BuildRequestClaim(brid=id, objectid=self.MASTER_ID,
- claimed_at=1300103810)
- for id in range(1, 280)
- ], 1300305712,
- [ (id, 1, 7, 1300305712)
- for id in range(1, 280)
- ], brids=range(1, 280))
-
- def test_completeBuildRequests_multiple_notmine(self):
- # note that the requests are completed even though they are not mine!
- return self.do_test_completeBuildRequests([
- # two unclaimed requests
- fakedb.BuildRequest(id=44, buildsetid=self.BSID),
- fakedb.BuildRequest(id=45, buildsetid=self.BSID),
- # and one claimed by another master
- fakedb.BuildRequest(id=46, buildsetid=self.BSID),
- fakedb.BuildRequestClaim(brid=46, objectid=self.OTHER_MASTER_ID,
- claimed_at=1300103812),
- ], 1300305712,
- [ (44, 1, 7, 1300305712),
- (45, 1, 7, 1300305712),
- (46, 1, 7, 1300305712), ],
- brids=[44, 45, 46])
-
- def test_completeBuildRequests_already_completed(self):
- return self.do_test_completeBuildRequests([
- fakedb.BuildRequest(id=44, buildsetid=self.BSID,
- complete=1, complete_at=1300104190),
- ], 1300305712,
- expfailure=buildrequests.NotClaimedError)
-
- def test_completeBuildRequests_no_such(self):
- return self.do_test_completeBuildRequests([
- fakedb.BuildRequest(id=45, buildsetid=self.BSID),
- ], 1300305712,
- expfailure=buildrequests.NotClaimedError)
-
- def do_test_unclaimMethod(self, method, expected):
- d = self.insertTestData([
- # 44: a complete build (should not be unclaimed)
- fakedb.BuildRequest(id=44, buildsetid=self.BSID,
- complete=1, results=92,
- complete_at=self.COMPLETE_AT_EPOCH),
- fakedb.BuildRequestClaim(brid=44, objectid=self.MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
-
- # 45: incomplete build belonging to this incarnation
- fakedb.BuildRequest(id=45, buildsetid=self.BSID,
- complete=0, complete_at=0),
- fakedb.BuildRequestClaim(brid=45, objectid=self.MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
-
- # 46: incomplete build belonging to another master
- fakedb.BuildRequest(id=46, buildsetid=self.BSID,
- complete=0, complete_at=0),
- fakedb.BuildRequestClaim(brid=46, objectid=self.OTHER_MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH),
-
- # 47: unclaimed
- fakedb.BuildRequest(id=47, buildsetid=self.BSID,
- complete=0, complete_at=0),
-
- # 48: claimed by this master, but recently
- fakedb.BuildRequest(id=48, buildsetid=self.BSID,
- complete=0, complete_at=0),
- fakedb.BuildRequestClaim(brid=48, objectid=self.MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH-50),
-
- # 49: incomplete old build belonging to another master
- fakedb.BuildRequest(id=49, buildsetid=self.BSID,
- complete=0, complete_at=0),
- fakedb.BuildRequestClaim(brid=49, objectid=self.OTHER_MASTER_ID,
- claimed_at=self.CLAIMED_AT_EPOCH - 1000),
- ])
- d.addCallback(lambda _ : method())
- def check(brlist):
- def thd(conn):
- # just select the unclaimed requests
- reqs_tbl = self.db.model.buildrequests
- claims_tbl = self.db.model.buildrequest_claims
- join = reqs_tbl.outerjoin(claims_tbl,
- reqs_tbl.c.id == claims_tbl.c.brid)
- q = sa.select([ reqs_tbl.c.id ],
- from_obj=[ join ],
- whereclause=claims_tbl.c.claimed_at == None)
- results = conn.execute(q).fetchall()
- self.assertEqual(sorted([ r.id for r in results ]),
- sorted(expected))
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_unclaimExpiredRequests(self):
- clock = task.Clock()
- clock.advance(self.CLAIMED_AT_EPOCH)
-
- meth = self.db.buildrequests.unclaimExpiredRequests
- return self.do_test_unclaimMethod(
- lambda : meth(100, _reactor=clock),
- [47, 49])
-
- def test_unclaimBuildRequests(self):
- to_unclaim = [
- 44, # completed -> unclaimed anyway
- 45, # incomplete -> unclaimed
- 46, # from another master -> not unclaimed
- 47, # unclaimed -> still unclaimed
- 48, # claimed -> unclaimed
- 49, # another master -> not unclaimed
- 50 # no such buildrequest -> no error
- ]
- return self.do_test_unclaimMethod(
- lambda : self.db.buildrequests.unclaimBuildRequests(to_unclaim),
- [44, 45, 47, 48])
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_builds.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_builds.py
deleted file mode 100644
index 1773e1d1..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_builds.py
+++ /dev/null
@@ -1,159 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from twisted.internet import defer, task
-from buildbot.db import builds
-from buildbot.test.util import connector_component
-from buildbot.test.fake import fakedb
-from buildbot.util import epoch2datetime
-
-class TestBuildsConnectorComponent(
- connector_component.ConnectorComponentMixin,
- unittest.TestCase):
-
- def setUp(self):
- d = self.setUpConnectorComponent(
- table_names=['builds', 'buildrequests', 'buildsets',
- 'sourcestamps', 'sourcestampsets', 'patches' ])
-
- def finish_setup(_):
- self.db.builds = builds.BuildsConnectorComponent(self.db)
- d.addCallback(finish_setup)
-
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- # common sample data
-
- background_data = [
- fakedb.SourceStampSet(id=27),
- fakedb.SourceStamp(id=27, sourcestampsetid=27, revision='abcd'),
- fakedb.Buildset(id=20, sourcestampsetid=27),
- fakedb.Buildset(id=30, sourcestampsetid=27),
- fakedb.BuildRequest(id=41, buildsetid=20, buildername='b1'),
- fakedb.BuildRequest(id=42, buildsetid=30, buildername='b1'),
- ]
-
- # tests
-
- def test_getBuild(self):
- d = self.insertTestData(self.background_data + [
- fakedb.Build(id=50, brid=42, number=5, start_time=1304262222),
- ])
- d.addCallback(lambda _ :
- self.db.builds.getBuild(50))
- def check(bdict):
- self.assertEqual(bdict, dict(bid=50, number=5, brid=42,
- start_time=epoch2datetime(1304262222), finish_time=None))
- d.addCallback(check)
- return d
-
- def test_getBuild_missing(self):
- d = defer.succeed(None)
- d.addCallback(lambda _ :
- self.db.builds.getBuild(50))
- def check(bdict):
- self.assertEqual(bdict, None)
- d.addCallback(check)
- return d
-
- def test_getBuildsForRequest(self):
- d = self.insertTestData(self.background_data + [
- fakedb.Build(id=50, brid=42, number=5, start_time=1304262222),
- fakedb.Build(id=51, brid=41, number=6, start_time=1304262223),
- fakedb.Build(id=52, brid=42, number=7, start_time=1304262224,
- finish_time=1304262235),
- ])
- d.addCallback(lambda _ :
- self.db.builds.getBuildsForRequest(42))
- def check(bdicts):
- self.assertEqual(sorted(bdicts), sorted([
- dict(bid=50, number=5, brid=42,
- start_time=epoch2datetime(1304262222), finish_time=None),
- dict(bid=52, number=7, brid=42,
- start_time=epoch2datetime(1304262224),
- finish_time=epoch2datetime(1304262235)),
- ]))
- d.addCallback(check)
- return d
-
- def test_addBuild(self):
- clock = task.Clock()
- clock.advance(1302222222)
- d = self.insertTestData(self.background_data)
- d.addCallback(lambda _ :
- self.db.builds.addBuild(brid=41, number=119, _reactor=clock))
- def check(_):
- def thd(conn):
- r = conn.execute(self.db.model.builds.select())
- rows = [ (row.brid, row.number, row.start_time,
- row.finish_time) for row in r.fetchall() ]
- self.assertEqual(rows,
- [ (41, 119, 1302222222, None) ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_finishBuilds(self):
- clock = task.Clock()
- clock.advance(1305555555)
-
- d = self.insertTestData(self.background_data + [
- fakedb.Build(id=50, brid=41, number=5, start_time=1304262222),
- fakedb.Build(id=51, brid=42, number=5, start_time=1304262222),
- fakedb.Build(id=52, brid=42, number=6, start_time=1304262222),
- ])
- d.addCallback(lambda _ :
- self.db.builds.finishBuilds([50,51], _reactor=clock))
- def check(_):
- def thd(conn):
- r = conn.execute(self.db.model.builds.select())
- rows = [ (row.id, row.brid, row.number, row.start_time,
- row.finish_time) for row in r.fetchall() ]
- self.assertEqual(sorted(rows), [
- (50, 41, 5, 1304262222, 1305555555),
- (51, 42, 5, 1304262222, 1305555555),
- (52, 42, 6, 1304262222, None),
- ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_finishBuilds_big(self):
- clock = task.Clock()
- clock.advance(1305555555)
-
- d = self.insertTestData(self.background_data + [
- fakedb.Build(id=nn, brid=41, number=nn, start_time=1304262222)
- for nn in xrange(50,200)
- ])
- d.addCallback(lambda _ :
- self.db.builds.finishBuilds(range(50,200), _reactor=clock))
- def check(_):
- def thd(conn):
- r = conn.execute(self.db.model.builds.select())
- rows = [ (row.id, row.brid, row.number, row.start_time,
- row.finish_time) for row in r.fetchall() ]
- self.assertEqual(sorted(rows), [
- (nn, 41, nn, 1304262222, 1305555555)
- for nn in xrange(50,200)
- ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_buildsets.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_buildsets.py
deleted file mode 100644
index 714a7ab0..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_buildsets.py
+++ /dev/null
@@ -1,430 +0,0 @@
-# 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 datetime
-from twisted.trial import unittest
-from twisted.internet import defer, task
-from buildbot.db import buildsets
-from buildbot.util import json, UTC, epoch2datetime
-from buildbot.test.util import connector_component
-from buildbot.test.fake import fakedb
-
-class TestBuildsetsConnectorComponent(
- connector_component.ConnectorComponentMixin,
- unittest.TestCase):
-
- def setUp(self):
- self.now = 9272359
- self.clock = task.Clock()
- self.clock.advance(self.now)
-
- d = self.setUpConnectorComponent(
- table_names=[ 'patches', 'changes', 'sourcestamp_changes',
- 'buildsets', 'buildset_properties', 'objects',
- 'buildrequests', 'sourcestamps', 'sourcestampsets' ])
-
- def finish_setup(_):
- self.db.buildsets = buildsets.BuildsetsConnectorComponent(self.db)
- d.addCallback(finish_setup)
-
- # set up a sourcestamp with id 234 for use below
- d.addCallback(lambda _ :
- self.insertTestData([
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234),
- ]))
-
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- # tests
-
- def test_addBuildset_simple(self):
- d = defer.succeed(None)
- d.addCallback(lambda _ :
- self.db.buildsets.addBuildset(sourcestampsetid=234, reason='because',
- properties={}, builderNames=['bldr'], external_idstring='extid',
- _reactor=self.clock))
- def check((bsid, brids)):
- def thd(conn):
- # we should only have one brid
- self.assertEqual(len(brids), 1)
-
- # should see one buildset row
- r = conn.execute(self.db.model.buildsets.select())
- rows = [ (row.id, row.external_idstring, row.reason,
- row.sourcestampsetid, row.complete, row.complete_at,
- row.submitted_at, row.results) for row in r.fetchall() ]
- self.assertEqual(rows,
- [ ( bsid, 'extid', 'because', 234, 0, None, self.now, -1) ])
-
- # and one buildrequests row
- r = conn.execute(self.db.model.buildrequests.select())
-
- rows = [ (row.buildsetid, row.id, row.buildername,
- row.priority, row.complete, row.results,
- row.submitted_at, row.complete_at)
- for row in r.fetchall() ]
- self.assertEqual(rows,
- [ ( bsid, brids['bldr'], 'bldr', 0, 0,
- -1, self.now, None) ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_addBuildset_bigger(self):
- props = dict(prop=(['list'], 'test'))
- d = defer.succeed(None)
- d.addCallback(lambda _ :
- self.db.buildsets.addBuildset(sourcestampsetid=234, reason='because',
- properties=props, builderNames=['a', 'b']))
- def check((bsid, brids)):
- def thd(conn):
- self.assertEqual(len(brids), 2)
-
- # should see one buildset row
- r = conn.execute(self.db.model.buildsets.select())
- rows = [ (row.id, row.external_idstring, row.reason,
- row.sourcestampsetid, row.complete,
- row.complete_at, row.results)
- for row in r.fetchall() ]
- self.assertEqual(rows,
- [ ( bsid, None, u'because', 234, 0, None, -1) ])
-
- # one property row
- r = conn.execute(self.db.model.buildset_properties.select())
- rows = [ (row.buildsetid, row.property_name, row.property_value)
- for row in r.fetchall() ]
- self.assertEqual(rows,
- [ ( bsid, 'prop', json.dumps([ ['list'], 'test' ]) ) ])
-
- # and two buildrequests rows (and don't re-check the default columns)
- r = conn.execute(self.db.model.buildrequests.select())
- rows = [ (row.buildsetid, row.id, row.buildername)
- for row in r.fetchall() ]
-
- # we don't know which of the brids is assigned to which
- # buildername, but either one will do
- self.assertEqual(sorted(rows),
- [ ( bsid, brids['a'], 'a'), (bsid, brids['b'], 'b') ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def do_test_getBuildsetProperties(self, buildsetid, rows, expected):
- d = self.insertTestData(rows)
- d.addCallback(lambda _ :
- self.db.buildsets.getBuildsetProperties(buildsetid))
- def check(props):
- self.assertEqual(props, expected)
- d.addCallback(check)
- return d
-
- def test_getBuildsetProperties_multiple(self):
- return self.do_test_getBuildsetProperties(91, [
- fakedb.Buildset(id=91, sourcestampsetid=234, complete=0,
- results=-1, submitted_at=0),
- fakedb.BuildsetProperty(buildsetid=91, property_name='prop1',
- property_value='["one", "fake1"]'),
- fakedb.BuildsetProperty(buildsetid=91, property_name='prop2',
- property_value='["two", "fake2"]'),
- ], dict(prop1=("one", "fake1"), prop2=("two", "fake2")))
-
- def test_getBuildsetProperties_empty(self):
- return self.do_test_getBuildsetProperties(91, [
- fakedb.Buildset(id=91, sourcestampsetid=234, complete=0,
- results=-1, submitted_at=0),
- ], dict())
-
- def test_getBuildsetProperties_nosuch(self):
- "returns an empty dict even if no such buildset exists"
- return self.do_test_getBuildsetProperties(91, [], dict())
-
- def test_getBuildset_incomplete_None(self):
- d = self.insertTestData([
- fakedb.Buildset(id=91, sourcestampsetid=234, complete=0,
- complete_at=None, results=-1, submitted_at=266761875,
- external_idstring='extid', reason='rsn'),
- ])
- d.addCallback(lambda _ :
- self.db.buildsets.getBuildset(91))
- def check(bsdict):
- self.assertEqual(bsdict, dict(external_idstring='extid',
- reason='rsn', sourcestampsetid=234,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- complete=False, complete_at=None, results=-1,
- bsid=91))
- d.addCallback(check)
- return d
-
- def test_getBuildset_incomplete_zero(self):
- d = self.insertTestData([
- fakedb.Buildset(id=91, sourcestampsetid=234, complete=0,
- complete_at=0, results=-1, submitted_at=266761875,
- external_idstring='extid', reason='rsn'),
- ])
- d.addCallback(lambda _ :
- self.db.buildsets.getBuildset(91))
- def check(bsdict):
- self.assertEqual(bsdict, dict(external_idstring='extid',
- reason='rsn', sourcestampsetid=234,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- complete=False, complete_at=None, results=-1,
- bsid=91))
- d.addCallback(check)
- return d
-
- def test_getBuildset_complete(self):
- d = self.insertTestData([
- fakedb.Buildset(id=91, sourcestampsetid=234, complete=1,
- complete_at=298297875, results=-1, submitted_at=266761875,
- external_idstring='extid', reason='rsn'),
- ])
- d.addCallback(lambda _ :
- self.db.buildsets.getBuildset(91))
- def check(bsdict):
- self.assertEqual(bsdict, dict(external_idstring='extid',
- reason='rsn', sourcestampsetid=234,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- complete=True,
- complete_at=datetime.datetime(1979, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- results=-1,
- bsid=91))
- d.addCallback(check)
- return d
-
- def test_getBuildset_nosuch(self):
- d = self.db.buildsets.getBuildset(91)
- def check(bsdict):
- self.assertEqual(bsdict, None)
- d.addCallback(check)
- return d
-
- def insert_test_getBuildsets_data(self):
- return self.insertTestData([
- fakedb.Buildset(id=91, sourcestampsetid=234, complete=0,
- complete_at=298297875, results=-1, submitted_at=266761875,
- external_idstring='extid', reason='rsn1'),
- fakedb.Buildset(id=92, sourcestampsetid=234, complete=1,
- complete_at=298297876, results=7, submitted_at=266761876,
- external_idstring='extid', reason='rsn2'),
- ])
-
- def test_getBuildsets_empty(self):
- d = self.db.buildsets.getBuildsets()
- def check(bsdictlist):
- self.assertEqual(bsdictlist, [])
- d.addCallback(check)
- return d
-
- def test_getBuildsets_all(self):
- d = self.insert_test_getBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.getBuildsets())
- def check(bsdictlist):
- self.assertEqual(sorted(bsdictlist), sorted([
- dict(external_idstring='extid', reason='rsn1', sourcestampsetid=234,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- complete_at=datetime.datetime(1979, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- complete=False, results=-1, bsid=91),
- dict(external_idstring='extid', reason='rsn2', sourcestampsetid=234,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 16,
- tzinfo=UTC),
- complete_at=datetime.datetime(1979, 6, 15, 12, 31, 16,
- tzinfo=UTC),
- complete=True, results=7, bsid=92),
- ]))
- d.addCallback(check)
- return d
-
- def test_getBuildsets_complete(self):
- d = self.insert_test_getBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.getBuildsets(complete=True))
- def check(bsdictlist):
- self.assertEqual(bsdictlist, [
- dict(external_idstring='extid', reason='rsn2', sourcestampsetid=234,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 16,
- tzinfo=UTC),
- complete_at=datetime.datetime(1979, 6, 15, 12, 31, 16,
- tzinfo=UTC),
- complete=True, results=7, bsid=92),
- ])
- d.addCallback(check)
- return d
-
- def test_getBuildsets_incomplete(self):
- d = self.insert_test_getBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.getBuildsets(complete=False))
- def check(bsdictlist):
- self.assertEqual(bsdictlist, [
- dict(external_idstring='extid', reason='rsn1', sourcestampsetid=234,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- complete_at=datetime.datetime(1979, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- complete=False, results=-1, bsid=91),
- ])
- d.addCallback(check)
- return d
-
- def test_completeBuildset(self):
- d = self.insert_test_getBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.completeBuildset(bsid=91, results=6,
- _reactor=self.clock))
- def check(_):
- def thd(conn):
- # should see one buildset row
- r = conn.execute(self.db.model.buildsets.select())
- rows = [ (row.id, row.complete, row.complete_at, row.results)
- for row in r.fetchall() ]
- self.assertEqual(sorted(rows), sorted([
- ( 91, 1, self.now, 6),
- ( 92, 1, 298297876, 7) ]))
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_completeBuildset_explicit_complete_at(self):
- d = self.insert_test_getBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.completeBuildset(bsid=91, results=6,
- complete_at=epoch2datetime(72759)))
- def check(_):
- def thd(conn):
- # should see one buildset row
- r = conn.execute(self.db.model.buildsets.select())
- rows = [ (row.id, row.complete, row.complete_at, row.results)
- for row in r.fetchall() ]
- self.assertEqual(sorted(rows), sorted([
- ( 91, 1, 72759, 6),
- ( 92, 1, 298297876, 7) ]))
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_completeBuildset_already_completed(self):
- d = self.insert_test_getBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.completeBuildset(bsid=92, results=6,
- _reactor=self.clock))
- return self.assertFailure(d, KeyError)
-
- def test_completeBuildset_missing(self):
- d = self.insert_test_getBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.completeBuildset(bsid=93, results=6,
- _reactor=self.clock))
- return self.assertFailure(d, KeyError)
-
- def insert_test_getRecentBuildsets_data(self):
- return self.insertTestData([
- fakedb.SourceStamp(id=91, branch='branch_a', repository='repo_a',
- sourcestampsetid=91),
- fakedb.SourceStampSet(id=91),
-
- fakedb.Buildset(id=91, sourcestampsetid=91, complete=0,
- complete_at=298297875, results=-1, submitted_at=266761875,
- external_idstring='extid', reason='rsn1'),
- fakedb.Buildset(id=92, sourcestampsetid=91, complete=1,
- complete_at=298297876, results=7, submitted_at=266761876,
- external_idstring='extid', reason='rsn2'),
-
- # buildset unrelated to the change
- fakedb.SourceStampSet(id=1),
- fakedb.Buildset(id=93, sourcestampsetid=1, complete=1,
- complete_at=298297877, results=7, submitted_at=266761877,
- external_idstring='extid', reason='rsn2'),
- ])
-
- def test_getRecentBuildsets_all(self):
- d = self.insert_test_getRecentBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.getRecentBuildsets(2, branch='branch_a',
- repository='repo_a'))
- def check(bsdictlist):
- self.assertEqual(bsdictlist, [
- dict(external_idstring='extid', reason='rsn1', sourcestampsetid=91,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- complete_at=datetime.datetime(1979, 6, 15, 12, 31, 15,
- tzinfo=UTC),
- complete=False, results=-1, bsid=91),
- dict(external_idstring='extid', reason='rsn2', sourcestampsetid=91,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 16,
- tzinfo=UTC),
- complete_at=datetime.datetime(1979, 6, 15, 12, 31, 16,
- tzinfo=UTC),
- complete=True, results=7, bsid=92),
- ])
- d.addCallback(check)
- return d
-
- def test_getRecentBuildsets_one(self):
- d = self.insert_test_getRecentBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.getRecentBuildsets(1, branch='branch_a',
- repository='repo_a'))
- def check(bsdictlist):
- self.assertEqual(bsdictlist, [
- dict(external_idstring='extid', reason='rsn2', sourcestampsetid=91,
- submitted_at=datetime.datetime(1978, 6, 15, 12, 31, 16,
- tzinfo=UTC),
- complete_at=datetime.datetime(1979, 6, 15, 12, 31, 16,
- tzinfo=UTC),
- complete=True, results=7, bsid=92),
- ])
- d.addCallback(check)
- return d
-
- def test_getRecentBuildsets_zero(self):
- d = self.insert_test_getRecentBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.getRecentBuildsets(0, branch='branch_a',
- repository='repo_a'))
- def check(bsdictlist):
- self.assertEqual(bsdictlist, [])
- d.addCallback(check)
- return d
-
- def test_getRecentBuildsets_noBranchMatch(self):
- d = self.insert_test_getRecentBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.getRecentBuildsets(2, branch='bad_branch',
- repository='repo_a'))
- def check(bsdictlist):
- self.assertEqual(bsdictlist, [])
- d.addCallback(check)
- return d
-
- def test_getRecentBuildsets_noRepoMatch(self):
- d = self.insert_test_getRecentBuildsets_data()
- d.addCallback(lambda _ :
- self.db.buildsets.getRecentBuildsets(2, branch='branch_a',
- repository='bad_repo'))
- def check(bsdictlist):
- self.assertEqual(bsdictlist, [])
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_changes.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_changes.py
deleted file mode 100644
index f7427875..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_changes.py
+++ /dev/null
@@ -1,522 +0,0 @@
-# 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 mock
-import pprint
-import sqlalchemy as sa
-from twisted.trial import unittest
-from twisted.internet import defer, task
-from buildbot.changes.changes import Change
-from buildbot.db import changes
-from buildbot.test.util import connector_component
-from buildbot.test.fake import fakedb
-from buildbot.util import epoch2datetime
-
-class TestChangesConnectorComponent(
- connector_component.ConnectorComponentMixin,
- unittest.TestCase):
-
- def setUp(self):
- d = self.setUpConnectorComponent(
- table_names=['changes', 'change_files',
- 'change_properties', 'scheduler_changes', 'objects',
- 'sourcestampsets', 'sourcestamps', 'sourcestamp_changes',
- 'patches', 'change_users', 'users'])
-
- def finish_setup(_):
- self.db.changes = changes.ChangesConnectorComponent(self.db)
- d.addCallback(finish_setup)
-
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- # common sample data
-
- change13_rows = [
- fakedb.Change(changeid=13, author="dustin", comments="fix spelling",
- is_dir=0, branch="master", revision="deadbeef",
- when_timestamp=266738400, revlink=None, category=None,
- repository='', codebase='', project=''),
-
- fakedb.ChangeFile(changeid=13, filename='master/README.txt'),
- fakedb.ChangeFile(changeid=13, filename='slave/README.txt'),
-
- fakedb.ChangeProperty(changeid=13, property_name='notest',
- property_value='["no","Change"]'),
- ]
-
- change14_rows = [
- fakedb.Change(changeid=14, author="warner", comments="fix whitespace",
- is_dir=0, branch="warnerdb", revision="0e92a098b",
- when_timestamp=266738404, revlink='http://warner/0e92a098b',
- category='devel', repository='git://warner', codebase='mainapp',
- project='Buildbot'),
-
- fakedb.ChangeFile(changeid=14, filename='master/buildbot/__init__.py'),
- ]
-
- change14_dict = {
- 'changeid': 14,
- 'author': u'warner',
- 'branch': u'warnerdb',
- 'category': u'devel',
- 'comments': u'fix whitespace',
- 'files': [u'master/buildbot/__init__.py'],
- 'is_dir': 0,
- 'project': u'Buildbot',
- 'properties': {},
- 'repository': u'git://warner',
- 'codebase': u'mainapp',
- 'revision': u'0e92a098b',
- 'revlink': u'http://warner/0e92a098b',
- 'when_timestamp': epoch2datetime(266738404),
- }
-
- def change14(self):
- c = Change(**dict(
- category='devel',
- isdir=0,
- repository=u'git://warner',
- codebase=u'mainapp',
- who=u'warner',
- when=266738404,
- comments=u'fix whitespace',
- project=u'Buildbot',
- branch=u'warnerdb',
- revlink=u'http://warner/0e92a098b',
- properties={},
- files=[u'master/buildbot/__init__.py'],
- revision=u'0e92a098b'))
- c.number = 14
- return c
-
- # assertions
-
- def assertChangesEqual(self, ca, cb):
- ok = True
- ok = ok and ca.number == cb.number
- ok = ok and ca.who == cb.who
- ok = ok and sorted(ca.files) == sorted(cb.files)
- ok = ok and ca.comments == cb.comments
- ok = ok and bool(ca.isdir) == bool(cb.isdir)
- ok = ok and ca.revision == cb.revision
- ok = ok and ca.when == cb.when
- ok = ok and ca.branch == cb.branch
- ok = ok and ca.category == cb.category
- ok = ok and ca.revlink == cb.revlink
- ok = ok and ca.properties == cb.properties
- ok = ok and ca.repository == cb.repository
- ok = ok and ca.codebase == cb.codebase
- ok = ok and ca.project == cb.project
- if not ok:
- def printable(c):
- return pprint.pformat(c.__dict__)
- self.fail("changes do not match; expected\n%s\ngot\n%s" %
- (printable(ca), printable(cb)))
-
- # tests
-
- def test_getChange(self):
- d = self.insertTestData(self.change14_rows)
- def get14(_):
- return self.db.changes.getChange(14)
- d.addCallback(get14)
- def check14(chdict):
- self.assertEqual(chdict, self.change14_dict)
- d.addCallback(check14)
- return d
-
- def test_Change_fromChdict_with_chdict(self):
- # test that the chdict getChange returns works with Change.fromChdict
- d = Change.fromChdict(mock.Mock(), self.change14_dict)
- def check(c):
- self.assertChangesEqual(c, self.change14())
- d.addCallback(check)
- return d
-
- def test_getChange_missing(self):
- d = defer.succeed(None)
- def get14(_):
- return self.db.changes.getChange(14)
- d.addCallback(get14)
- def check14(chdict):
- self.failUnless(chdict is None)
- d.addCallback(check14)
- return d
-
- def test_getLatestChangeid(self):
- d = self.insertTestData(self.change13_rows)
- def get(_):
- return self.db.changes.getLatestChangeid()
- d.addCallback(get)
- def check(changeid):
- self.assertEqual(changeid, 13)
- d.addCallback(check)
- return d
-
- def test_getLatestChangeid_empty(self):
- d = defer.succeed(None)
- def get(_):
- return self.db.changes.getLatestChangeid()
- d.addCallback(get)
- def check(changeid):
- self.assertEqual(changeid, None)
- d.addCallback(check)
- return d
-
- def test_addChange(self):
- d = self.db.changes.addChange(
- author=u'dustin',
- files=[u'master/LICENSING.txt', u'slave/LICENSING.txt'],
- comments=u'fix spelling',
- is_dir=0,
- revision=u'2d6caa52',
- when_timestamp=epoch2datetime(266738400),
- branch=u'master',
- category=None,
- revlink=None,
- properties={u'platform': (u'linux', 'Change')},
- repository=u'',
- codebase=u'',
- project=u'')
- # check all of the columns of the four relevant tables
- def check_change(changeid):
- def thd(conn):
- self.assertEqual(changeid, 1)
- r = conn.execute(self.db.model.changes.select())
- r = r.fetchall()
- self.assertEqual(len(r), 1)
- self.assertEqual(r[0].changeid, changeid)
- self.assertEqual(r[0].author, 'dustin')
- self.assertEqual(r[0].comments, 'fix spelling')
- self.assertFalse(r[0].is_dir)
- self.assertEqual(r[0].branch, 'master')
- self.assertEqual(r[0].revision, '2d6caa52')
- self.assertEqual(r[0].when_timestamp, 266738400)
- self.assertEqual(r[0].category, None)
- self.assertEqual(r[0].repository, '')
- self.assertEqual(r[0].codebase, '')
- self.assertEqual(r[0].project, '')
- return self.db.pool.do(thd)
- d.addCallback(check_change)
- def check_change_files(_):
- def thd(conn):
- query = self.db.model.change_files.select()
- query.where(self.db.model.change_files.c.changeid == 1)
- query.order_by(self.db.model.change_files.c.filename)
- r = conn.execute(query)
- r = r.fetchall()
- self.assertEqual(len(r), 2)
- self.assertEqual(r[0].filename, 'master/LICENSING.txt')
- self.assertEqual(r[1].filename, 'slave/LICENSING.txt')
- return self.db.pool.do(thd)
- d.addCallback(check_change_files)
- def check_change_properties(_):
- def thd(conn):
- query = self.db.model.change_properties.select()
- query.where(self.db.model.change_properties.c.changeid == 1)
- query.order_by(self.db.model.change_properties.c.property_name)
- r = conn.execute(query)
- r = r.fetchall()
- self.assertEqual(len(r), 1)
- self.assertEqual(r[0].property_name, 'platform')
- self.assertEqual(r[0].property_value, '["linux", "Change"]')
- return self.db.pool.do(thd)
- d.addCallback(check_change_properties)
- def check_change_users(_):
- def thd(conn):
- query = self.db.model.change_users.select()
- r = conn.execute(query)
- r = r.fetchall()
- self.assertEqual(len(r), 0)
- return self.db.pool.do(thd)
- d.addCallback(check_change_users)
- return d
-
- def test_addChange_when_timestamp_None(self):
- clock = task.Clock()
- clock.advance(1239898353)
- d = self.db.changes.addChange(
- author=u'dustin',
- files=[],
- comments=u'fix spelling',
- is_dir=0,
- revision=u'2d6caa52',
- when_timestamp=None,
- branch=u'master',
- category=None,
- revlink=None,
- properties={},
- repository=u'',
- codebase=u'',
- project=u'',
- _reactor=clock)
- # check all of the columns of the four relevant tables
- def check_change(changeid):
- def thd(conn):
- r = conn.execute(self.db.model.changes.select())
- r = r.fetchall()
- self.assertEqual(len(r), 1)
- self.assertEqual(r[0].changeid, changeid)
- self.assertEqual(r[0].when_timestamp, 1239898353)
- return self.db.pool.do(thd)
- d.addCallback(check_change)
- def check_change_files(_):
- def thd(conn):
- query = self.db.model.change_files.select()
- r = conn.execute(query)
- r = r.fetchall()
- self.assertEqual(len(r), 0)
- return self.db.pool.do(thd)
- d.addCallback(check_change_files)
- def check_change_properties(_):
- def thd(conn):
- query = self.db.model.change_properties.select()
- r = conn.execute(query)
- r = r.fetchall()
- self.assertEqual(len(r), 0)
- return self.db.pool.do(thd)
- d.addCallback(check_change_properties)
- def check_change_users(_):
- def thd(conn):
- query = self.db.model.change_users.select()
- r = conn.execute(query)
- r = r.fetchall()
- self.assertEqual(len(r), 0)
- return self.db.pool.do(thd)
- d.addCallback(check_change_users)
- return d
-
- def test_addChange_with_uid(self):
- d = self.insertTestData([
- fakedb.User(uid=1, identifier="one"),
- ])
- d.addCallback(lambda _ :
- self.db.changes.addChange(
- author=u'dustin',
- files=[],
- comments=u'fix spelling',
- is_dir=0,
- revision=u'2d6caa52',
- when_timestamp=epoch2datetime(1239898353),
- branch=u'master',
- category=None,
- revlink=None,
- properties={},
- repository=u'',
- codebase=u'',
- project=u'',
- uid=1))
- # check all of the columns of the five relevant tables
- def check_change(changeid):
- def thd(conn):
- r = conn.execute(self.db.model.changes.select())
- r = r.fetchall()
- self.assertEqual(len(r), 1)
- self.assertEqual(r[0].changeid, changeid)
- self.assertEqual(r[0].when_timestamp, 1239898353)
- return self.db.pool.do(thd)
- d.addCallback(check_change)
- def check_change_files(_):
- def thd(conn):
- query = self.db.model.change_files.select()
- r = conn.execute(query)
- r = r.fetchall()
- self.assertEqual(len(r), 0)
- return self.db.pool.do(thd)
- d.addCallback(check_change_files)
- def check_change_properties(_):
- def thd(conn):
- query = self.db.model.change_properties.select()
- r = conn.execute(query)
- r = r.fetchall()
- self.assertEqual(len(r), 0)
- return self.db.pool.do(thd)
- d.addCallback(check_change_properties)
- def check_change_users(_):
- def thd(conn):
- query = self.db.model.change_users.select()
- r = conn.execute(query)
- r = r.fetchall()
- self.assertEqual(len(r), 1)
- self.assertEqual(r[0].changeid, 1)
- self.assertEqual(r[0].uid, 1)
- return self.db.pool.do(thd)
- d.addCallback(check_change_users)
- return d
-
- def test_getChangeUids_missing(self):
- d = self.db.changes.getChangeUids(1)
- def check(res):
- self.assertEqual(res, [])
- d.addCallback(check)
- return d
-
- def test_getChangeUids_found(self):
- d = self.insertTestData(self.change14_rows + [
- fakedb.User(uid=1),
- fakedb.ChangeUser(changeid=14, uid=1),
- ])
- d.addCallback(lambda _ : self.db.changes.getChangeUids(14))
- def check(res):
- self.assertEqual(res, [1])
- d.addCallback(check)
- return d
-
- def test_getChangeUids_multi(self):
- d = 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
- ])
- d.addCallback(lambda _ : self.db.changes.getChangeUids(14))
- def check(res):
- self.assertEqual(sorted(res), [1, 2])
- d.addCallback(check)
- return d
-
- def test_pruneChanges(self):
- d = self.insertTestData([
- fakedb.Object(id=29),
- fakedb.SourceStamp(id=234),
-
- fakedb.Change(changeid=11),
-
- fakedb.Change(changeid=12),
- fakedb.SchedulerChange(objectid=29, changeid=12),
- fakedb.SourceStampChange(sourcestampid=234, changeid=12),
- ] +
-
- self.change13_rows + [
- fakedb.SchedulerChange(objectid=29, changeid=13),
- ] +
-
- self.change14_rows + [
- fakedb.SchedulerChange(objectid=29, changeid=14),
-
- fakedb.Change(changeid=15),
- fakedb.SourceStampChange(sourcestampid=234, changeid=15),
- ]
- )
-
- # pruning with a horizon of 2 should delete changes 11, 12 and 13
- d.addCallback(lambda _ : self.db.changes.pruneChanges(2))
- def check(_):
- def thd(conn):
- results = {}
- for tbl_name in ('scheduler_changes', 'sourcestamp_changes',
- 'change_files', 'change_properties',
- 'changes'):
- tbl = self.db.model.metadata.tables[tbl_name]
- r = conn.execute(sa.select([tbl.c.changeid]))
- results[tbl_name] = sorted([ r[0] for r in r.fetchall() ])
- self.assertEqual(results, {
- 'scheduler_changes': [14],
- 'sourcestamp_changes': [15],
- 'change_files': [14],
- 'change_properties': [],
- 'changes': [14, 15],
- })
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_pruneChanges_lots(self):
- d = self.insertTestData([
- fakedb.Change(changeid=n)
- for n in xrange(1, 151)
- ])
-
- d.addCallback(lambda _ : self.db.changes.pruneChanges(1))
- def check(_):
- def thd(conn):
- results = {}
- for tbl_name in ('scheduler_changes', 'sourcestamp_changes',
- 'change_files', 'change_properties',
- 'changes'):
- tbl = self.db.model.metadata.tables[tbl_name]
- r = conn.execute(sa.select([tbl.c.changeid]))
- results[tbl_name] = len([ r for r in r.fetchall() ])
- self.assertEqual(results, {
- 'scheduler_changes': 0,
- 'sourcestamp_changes': 0,
- 'change_files': 0,
- 'change_properties': 0,
- 'changes': 1,
- })
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_pruneChanges_None(self):
- d = self.insertTestData(self.change13_rows)
-
- d.addCallback(lambda _ : self.db.changes.pruneChanges(None))
- def check(_):
- def thd(conn):
- tbl = self.db.model.changes
- r = conn.execute(tbl.select())
- self.assertEqual([ row.changeid for row in r.fetchall() ],
- [ 13 ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_getRecentChanges_subset(self):
- d = self.insertTestData([
- fakedb.Change(changeid=8),
- fakedb.Change(changeid=9),
- fakedb.Change(changeid=10),
- fakedb.Change(changeid=11),
- fakedb.Change(changeid=12),
- ] + self.change13_rows + self.change14_rows)
- d.addCallback(lambda _ :
- self.db.changes.getRecentChanges(5))
- def check(changes):
- changeids = [ c['changeid'] for c in changes ]
- self.assertEqual(changeids, [10, 11, 12, 13, 14])
- d.addCallback(check)
- return d
-
- def test_getRecentChanges_empty(self):
- d = defer.succeed(None)
- d.addCallback(lambda _ :
- self.db.changes.getRecentChanges(5))
- def check(changes):
- changeids = [ c['changeid'] for c in changes ]
- self.assertEqual(changeids, [])
- d.addCallback(check)
- return d
-
- def test_getRecentChanges_missing(self):
- d = self.insertTestData(self.change13_rows + self.change14_rows)
- d.addCallback(lambda _ :
- self.db.changes.getRecentChanges(5))
- def check(changes):
- # requested 5, but only got 2
- 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', 'slave/README.txt']))
- self.assertEqual(changes[0]['properties'],
- { 'notest' : ('no', 'Change') })
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_connector.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_connector.py
deleted file mode 100644
index 3c3083cd..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_connector.py
+++ /dev/null
@@ -1,87 +0,0 @@
-# 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 os
-import mock
-from twisted.internet import defer
-from twisted.trial import unittest
-from buildbot.db import connector
-from buildbot import config
-from buildbot.test.util import db
-from buildbot.test.fake import fakemaster
-
-class DBConnector(db.RealDatabaseMixin, unittest.TestCase):
- """
- Basic tests of the DBConnector class - all start with an empty DB
- """
-
- @defer.inlineCallbacks
- def setUp(self):
- yield self.setUpRealDatabase(table_names=[
- 'changes', 'change_properties', 'change_files', 'patches',
- 'sourcestamps', 'buildset_properties', 'buildsets',
- 'sourcestampsets' ])
-
- self.master = fakemaster.make_master()
- self.master.config = config.MasterConfig()
- self.db = connector.DBConnector(self.master,
- os.path.abspath('basedir'))
-
- @defer.inlineCallbacks
- def tearDown(self):
- if self.db.running:
- yield self.db.stopService()
-
- yield self.tearDownRealDatabase()
-
- @defer.inlineCallbacks
- def startService(self, check_version=False):
- self.master.config.db['db_url'] = self.db_url
- yield self.db.setup(check_version=check_version)
- self.db.startService()
- yield self.db.reconfigService(self.master.config)
-
-
- # tests
-
- def test_doCleanup_service(self):
- d = self.startService()
- @d.addCallback
- def check(_):
- self.assertTrue(self.db.cleanup_timer.running)
-
- def test_doCleanup_unconfigured(self):
- self.db.changes.pruneChanges = mock.Mock(
- return_value=defer.succeed(None))
- self.db._doCleanup()
- self.assertFalse(self.db.changes.pruneChanges.called)
-
- def test_doCleanup_configured(self):
- self.db.changes.pruneChanges = mock.Mock(
- return_value=defer.succeed(None))
- d = self.startService()
- @d.addCallback
- def check(_):
- self.db._doCleanup()
- self.assertTrue(self.db.changes.pruneChanges.called)
- return d
-
- def test_setup_check_version_bad(self):
- d = self.startService(check_version=True)
- return self.assertFailure(d, connector.DatabaseNotReadyError)
-
- def test_setup_check_version_good(self):
- self.db.model.is_current = lambda : defer.succeed(True)
- return self.startService(check_version=True)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_enginestrategy.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_enginestrategy.py
deleted file mode 100644
index d9693979..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_enginestrategy.py
+++ /dev/null
@@ -1,176 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from twisted.python import runtime
-from sqlalchemy.engine import url
-from sqlalchemy.pool import NullPool
-from buildbot.db import enginestrategy
-
-class BuildbotEngineStrategy_special_cases(unittest.TestCase):
- "Test the special case methods, without actually creating a db"
-
- # used several times below
- mysql_kwargs = dict(basedir='my-base-dir',
- connect_args=dict(init_command='SET storage_engine=MyISAM'),
- pool_recycle=3600)
- sqlite_kwargs = dict(basedir='/my-base-dir', poolclass=NullPool)
-
- def setUp(self):
- self.strat = enginestrategy.BuildbotEngineStrategy()
-
- # utility
-
- def filter_kwargs(self, kwargs):
- # filter out the listeners list to just include the class name
- if 'listeners' in kwargs:
- kwargs['listeners'] = [ lstnr.__class__.__name__
- for lstnr in kwargs['listeners'] ]
- return kwargs
-
- # tests
-
- def test_sqlite_pct_sub(self):
- u = url.make_url("sqlite:///%(basedir)s/x/state.sqlite")
- kwargs = dict(basedir='/my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_sqlite(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "sqlite:////my-base-dir/x/state.sqlite", None,
- self.sqlite_kwargs ])
-
- def test_sqlite_relpath(self):
- url_src = "sqlite:///x/state.sqlite"
- basedir = "/my-base-dir"
- expected_url = "sqlite:////my-base-dir/x/state.sqlite"
-
- # this looks a whole lot different on windows
- if runtime.platformType == 'win32':
- url_src = r'sqlite:///X\STATE.SQLITE'
- basedir = r'C:\MYBASE~1'
- expected_url = r'sqlite:///C:\MYBASE~1\X\STATE.SQLITE'
-
- exp_kwargs = self.sqlite_kwargs.copy()
- exp_kwargs['basedir'] = basedir
-
- u = url.make_url(url_src)
- kwargs = dict(basedir=basedir)
- u, kwargs, max_conns = self.strat.special_case_sqlite(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ expected_url, None, exp_kwargs ])
-
- def test_sqlite_abspath(self):
- u = url.make_url("sqlite:////x/state.sqlite")
- kwargs = dict(basedir='/my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_sqlite(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "sqlite:////x/state.sqlite", None, self.sqlite_kwargs ])
-
- def test_sqlite_memory(self):
- u = url.make_url("sqlite://")
- kwargs = dict(basedir='my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_sqlite(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "sqlite://", 1, # only one conn at a time
- dict(basedir='my-base-dir',
- # note: no poolclass= argument
- pool_size=1) ]) # extra in-memory args
-
- def test_mysql_simple(self):
- u = url.make_url("mysql://host/dbname")
- kwargs = dict(basedir='my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_mysql(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "mysql://host/dbname?charset=utf8&use_unicode=True", None,
- self.mysql_kwargs ])
-
- def test_mysql_userport(self):
- u = url.make_url("mysql://user:pass@host:1234/dbname")
- kwargs = dict(basedir='my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_mysql(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "mysql://user:pass@host:1234/dbname?"
- "charset=utf8&use_unicode=True", None, self.mysql_kwargs ])
-
- def test_mysql_local(self):
- u = url.make_url("mysql:///dbname")
- kwargs = dict(basedir='my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_mysql(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "mysql:///dbname?charset=utf8&use_unicode=True", None,
- self.mysql_kwargs ])
-
- def test_mysql_args(self):
- u = url.make_url("mysql:///dbname?foo=bar")
- kwargs = dict(basedir='my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_mysql(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "mysql:///dbname?charset=utf8&foo=bar&use_unicode=True",
- None, self.mysql_kwargs ])
-
- def test_mysql_max_idle(self):
- u = url.make_url("mysql:///dbname?max_idle=1234")
- kwargs = dict(basedir='my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_mysql(u, kwargs)
- exp = self.mysql_kwargs.copy()
- exp['pool_recycle'] = 1234
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "mysql:///dbname?charset=utf8&use_unicode=True", None,
- exp ])
-
- def test_mysql_good_charset(self):
- u = url.make_url("mysql:///dbname?charset=utf8")
- kwargs = dict(basedir='my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_mysql(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "mysql:///dbname?charset=utf8&use_unicode=True", None,
- self.mysql_kwargs ])
-
- def test_mysql_bad_charset(self):
- u = url.make_url("mysql:///dbname?charset=ebcdic")
- kwargs = dict(basedir='my-base-dir')
- self.assertRaises(TypeError,
- lambda : self.strat.special_case_mysql(u, kwargs))
-
- def test_mysql_good_use_unicode(self):
- u = url.make_url("mysql:///dbname?use_unicode=True")
- kwargs = dict(basedir='my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_mysql(u, kwargs)
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "mysql:///dbname?charset=utf8&use_unicode=True", None,
- self.mysql_kwargs ])
-
- def test_mysql_bad_use_unicode(self):
- u = url.make_url("mysql:///dbname?use_unicode=maybe")
- kwargs = dict(basedir='my-base-dir')
- self.assertRaises(TypeError,
- lambda : self.strat.special_case_mysql(u, kwargs))
-
- def test_mysql_storage_engine(self):
- u = url.make_url("mysql:///dbname?storage_engine=foo")
- kwargs = dict(basedir='my-base-dir')
- u, kwargs, max_conns = self.strat.special_case_mysql(u, kwargs)
- exp = self.mysql_kwargs.copy()
- exp['connect_args'] = dict(init_command='SET storage_engine=foo')
- self.assertEqual([ str(u), max_conns, self.filter_kwargs(kwargs) ],
- [ "mysql:///dbname?charset=utf8&use_unicode=True", None,
- exp ])
-
-
-class BuildbotEngineStrategy(unittest.TestCase):
- "Test create_engine by creating a sqlite in-memory db"
-
- def test_create_engine(self):
- engine = enginestrategy.create_engine('sqlite://', basedir="/base")
- self.assertEqual(engine.scalar("SELECT 13 + 14"), 27)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_011_add_buildrequest_claims.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_011_add_buildrequest_claims.py
deleted file mode 100644
index ea895983..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_011_add_buildrequest_claims.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.test.util import migration
-import sqlalchemy as sa
-from sqlalchemy.engine import reflection
-
-class Migration(migration.MigrateTestMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpMigrateTest()
-
- def tearDown(self):
- return self.tearDownMigrateTest()
-
- def create_tables_thd(self, conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- self.buildsets = sa.Table('buildsets', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('external_idstring', sa.String(256)),
- sa.Column('reason', sa.String(256)),
- sa.Column('sourcestampid', sa.Integer,
- nullable=False), # NOTE: foreign key omitted
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete', sa.SmallInteger, nullable=False,
- server_default=sa.DefaultClause("0")),
- sa.Column('complete_at', sa.Integer),
- sa.Column('results', sa.SmallInteger),
- )
- self.buildsets.create(bind=conn)
-
- self.buildrequests = sa.Table('buildrequests', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('buildsetid', sa.Integer, sa.ForeignKey("buildsets.id"),
- nullable=False),
- sa.Column('buildername', sa.String(length=256), nullable=False),
- sa.Column('priority', sa.Integer, nullable=False,
- server_default=sa.DefaultClause("0")),
- sa.Column('claimed_at', sa.Integer,
- server_default=sa.DefaultClause("0")),
- sa.Column('claimed_by_name', sa.String(length=256)),
- sa.Column('claimed_by_incarnation', sa.String(length=256)),
- sa.Column('complete', sa.Integer,
- server_default=sa.DefaultClause("0")),
- sa.Column('results', sa.SmallInteger),
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete_at', sa.Integer),
- )
- self.buildrequests.create(bind=conn)
-
- idx = sa.Index('buildrequests_buildsetid',
- self.buildrequests.c.buildsetid)
- idx.create()
-
- idx = sa.Index('buildrequests_buildername',
- self.buildrequests.c.buildername)
- idx.create()
-
- idx = sa.Index('buildrequests_complete',
- self.buildrequests.c.complete)
- idx.create()
-
- self.objects = sa.Table("objects", metadata,
- sa.Column("id", sa.Integer, primary_key=True),
- sa.Column('name', sa.String(128), nullable=False),
- sa.Column('class_name', sa.String(128), nullable=False),
- sa.UniqueConstraint('name', 'class_name', name='object_identity'),
- )
- self.objects.create(bind=conn)
-
- # tests
-
- def test_migrate(self):
- def setup_thd(conn):
- self.create_tables_thd(conn)
-
- def verify_thd(conn):
- # regression test for bug #2158; this is known to be broken on
- # sqlite (and fixed in db version 016) but expected to work on
- # other engines.
- if conn.dialect.name != 'sqlite':
- insp = reflection.Inspector.from_engine(conn)
- indexes = insp.get_indexes('buildrequests')
- self.assertEqual(
- sorted([ i['name'] for i in indexes ]),
- sorted([
- 'buildrequests_buildername',
- 'buildrequests_buildsetid',
- 'buildrequests_complete',
- ]))
-
- return self.do_test_migration(10, 11, setup_thd, verify_thd)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_015_remove_bad_master_objectid.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_015_remove_bad_master_objectid.py
deleted file mode 100644
index 1ee7be07..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_015_remove_bad_master_objectid.py
+++ /dev/null
@@ -1,140 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.test.util import migration
-import sqlalchemy as sa
-
-class Migration(migration.MigrateTestMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpMigrateTest()
-
- def tearDown(self):
- return self.tearDownMigrateTest()
-
- def create_tables_thd(self, conn):
- metadata = sa.MetaData()
- self.objects = sa.Table("objects", metadata,
- sa.Column("id", sa.Integer, primary_key=True),
- sa.Column('name', sa.String(128), nullable=False),
- sa.Column('class_name', sa.String(128), nullable=False),
- sa.UniqueConstraint('name', 'class_name', name='object_identity'),
- )
- self.object_state = sa.Table("object_state", metadata,
- sa.Column("objectid", sa.Integer, sa.ForeignKey('objects.id'),
- nullable=False),
- sa.Column("name", sa.String(length=256), nullable=False),
- sa.Column("value_json", sa.Text, nullable=False),
- sa.UniqueConstraint('objectid', 'name', name='name_per_object'),
- )
- self.objects.create(bind=conn)
- self.object_state.create(bind=conn)
-
- def insert_old_obj(self, conn):
- conn.execute(self.objects.insert(),
- id=21,
- name='master',
- class_name='buildbot.master.BuildMaster')
- conn.execute(self.object_state.insert(),
- objectid=21,
- name='last_processed_change',
- value_json='938')
-
- def insert_new_objs(self, conn, count):
- for id in range(50, 50+count):
- conn.execute(self.objects.insert(),
- id=id,
- name='some_hostname:/base/dir/%d' % id,
- class_name='BuildMaster')
- # (this id would be referenced from buildrequests, but that table
- # doesn't change)
-
- def assertObjectState_thd(self, conn, exp_objects=[],
- exp_object_state=[]):
- tbl = self.objects
- res = conn.execute(tbl.select(order_by=tbl.c.id))
- got_objects = res.fetchall()
-
- tbl = self.object_state
- res = conn.execute(tbl.select(
- order_by=[tbl.c.objectid, tbl.c.name]))
- got_object_state = res.fetchall()
-
- self.assertEqual(
- dict(objects=exp_objects, object_state=exp_object_state),
- dict(objects=got_objects, object_state=got_object_state))
-
- # tests
-
- def test_no_old_id(self):
- def setup_thd(conn):
- self.create_tables_thd(conn)
- self.insert_new_objs(conn, 2)
-
- def verify_thd(conn):
- self.assertObjectState_thd(conn, [
- (50, 'some_hostname:/base/dir/50',
- 'buildbot.master.BuildMaster'),
- (51, 'some_hostname:/base/dir/51',
- 'buildbot.master.BuildMaster'),
- ], [])
-
- return self.do_test_migration(14, 15, setup_thd, verify_thd)
-
- def test_no_new_id(self):
- def setup_thd(conn):
- self.create_tables_thd(conn)
- self.insert_old_obj(conn)
-
- def verify_thd(conn):
- self.assertObjectState_thd(conn, [], [])
-
- return self.do_test_migration(14, 15, setup_thd, verify_thd)
-
- def test_one_new_id(self):
- def setup_thd(conn):
- self.create_tables_thd(conn)
- self.insert_old_obj(conn)
- self.insert_new_objs(conn, 1)
-
- def verify_thd(conn):
- self.assertObjectState_thd(conn, [
- (50, 'some_hostname:/base/dir/50',
- 'buildbot.master.BuildMaster'),
- ], [
- (50, 'last_processed_change', '938'),
- ])
-
- return self.do_test_migration(14, 15, setup_thd, verify_thd)
-
- def test_two_new_ids(self):
- def setup_thd(conn):
- self.create_tables_thd(conn)
- self.insert_old_obj(conn)
- self.insert_new_objs(conn, 2)
-
- def verify_thd(conn):
- self.assertObjectState_thd(conn, [
- (50, 'some_hostname:/base/dir/50',
- 'buildbot.master.BuildMaster'),
- (51, 'some_hostname:/base/dir/51',
- 'buildbot.master.BuildMaster'),
- ], [
- # last_processed_change is just deleted
- ])
-
- return self.do_test_migration(14, 15, setup_thd, verify_thd)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_016_restore_buildrequest_indices.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_016_restore_buildrequest_indices.py
deleted file mode 100644
index 0cb03645..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_016_restore_buildrequest_indices.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.test.util import migration
-import sqlalchemy as sa
-from sqlalchemy.engine import reflection
-
-class Migration(migration.MigrateTestMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpMigrateTest()
-
- def tearDown(self):
- return self.tearDownMigrateTest()
-
- def create_tables_thd(self, conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- self.buildrequests = sa.Table('buildrequests', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('buildsetid', sa.Integer, # foreign key removed
- nullable=False),
- sa.Column('buildername', sa.String(length=256), nullable=False),
- sa.Column('priority', sa.Integer, nullable=False,
- server_default=sa.DefaultClause("0")),
- sa.Column('complete', sa.Integer,
- server_default=sa.DefaultClause("0")),
- sa.Column('results', sa.SmallInteger),
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete_at', sa.Integer),
- )
- self.buildrequests.create(bind=conn)
-
- # these indices should already exist everywhere but on sqlite
- if conn.dialect.name != 'sqlite':
- idx = sa.Index('buildrequests_buildsetid',
- self.buildrequests.c.buildsetid)
- idx.create()
-
- idx = sa.Index('buildrequests_buildername',
- self.buildrequests.c.buildername)
- idx.create()
-
- idx = sa.Index('buildrequests_complete',
- self.buildrequests.c.complete)
- idx.create()
-
- # tests
-
- def test_migrate(self):
- def setup_thd(conn):
- self.create_tables_thd(conn)
-
- def verify_thd(conn):
- insp = reflection.Inspector.from_engine(conn)
- indexes = insp.get_indexes('buildrequests')
- self.assertEqual(
- sorted([ i['name'] for i in indexes ]),
- sorted([
- 'buildrequests_buildername',
- 'buildrequests_buildsetid',
- 'buildrequests_complete',
- ]))
-
-
- return self.do_test_migration(15, 16, setup_thd, verify_thd)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_017_restore_other_indices.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_017_restore_other_indices.py
deleted file mode 100644
index e8dcd6b5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_017_restore_other_indices.py
+++ /dev/null
@@ -1,124 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.test.util import migration
-import sqlalchemy as sa
-from sqlalchemy.engine import reflection
-
-class Migration(migration.MigrateTestMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpMigrateTest()
-
- def tearDown(self):
- return self.tearDownMigrateTest()
-
- def create_tables_thd(self, conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- self.changes = sa.Table('changes', metadata,
- sa.Column('changeid', sa.Integer, primary_key=True),
- sa.Column('author', sa.String(256), nullable=False),
- sa.Column('comments', sa.String(1024), nullable=False),
- sa.Column('is_dir', sa.SmallInteger, nullable=False),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('revlink', sa.String(256)),
- sa.Column('when_timestamp', sa.Integer, nullable=False),
- sa.Column('category', sa.String(256)),
- sa.Column('repository', sa.String(length=512), nullable=False,
- server_default=''),
- sa.Column('project', sa.String(length=512), nullable=False,
- server_default=''),
- )
- self.changes.create(bind=conn)
-
- self.schedulers = sa.Table("schedulers", metadata,
- sa.Column('schedulerid', sa.Integer, primary_key=True),
- sa.Column('name', sa.String(128), nullable=False),
- sa.Column('class_name', sa.String(128), nullable=False),
- )
- self.schedulers.create(bind=conn)
-
- self.users = sa.Table("users", metadata,
- sa.Column("uid", sa.Integer, primary_key=True),
- sa.Column("identifier", sa.String(256), nullable=False),
- sa.Column("bb_username", sa.String(128)),
- sa.Column("bb_password", sa.String(128)),
- )
- self.users.create(bind=conn)
-
- self.objects = sa.Table("objects", metadata,
- sa.Column("id", sa.Integer, primary_key=True),
- sa.Column('name', sa.String(128), nullable=False),
- sa.Column('class_name', sa.String(128), nullable=False),
- )
- self.objects.create()
-
- self.object_state = sa.Table("object_state", metadata,
- sa.Column("objectid", sa.Integer, sa.ForeignKey('objects.id'),
- nullable=False),
- sa.Column("name", sa.String(length=256), nullable=False),
- sa.Column("value_json", sa.Text, nullable=False),
- )
- self.object_state.create()
-
- # these indices should already exist everywhere but on sqlite
- if conn.dialect.name != 'sqlite':
- sa.Index('name_and_class', self.schedulers.c.name,
- self.schedulers.c.class_name).create()
- sa.Index('changes_branch', self.changes.c.branch).create()
- sa.Index('changes_revision', self.changes.c.revision).create()
- sa.Index('changes_author', self.changes.c.author).create()
- sa.Index('changes_category', self.changes.c.category).create()
- sa.Index('changes_when_timestamp',
- self.changes.c.when_timestamp).create()
-
- # create this index without the unique attribute
- sa.Index('users_identifier', self.users.c.identifier).create()
-
- # tests
-
- def test_migrate(self):
- def setup_thd(conn):
- self.create_tables_thd(conn)
-
- def verify_thd(conn):
- insp = reflection.Inspector.from_engine(conn)
- indexes = (insp.get_indexes('changes')
- + insp.get_indexes('schedulers'))
- self.assertEqual(
- sorted([ i['name'] for i in indexes ]),
- sorted([
- 'changes_author',
- 'changes_branch',
- 'changes_category',
- 'changes_revision',
- 'changes_when_timestamp',
- 'name_and_class',
- ]))
- indexes = insp.get_indexes('users')
- for idx in indexes:
- if idx['name'] == 'users_identifier':
- self.assertTrue(idx['unique'])
- break
- else:
- self.fail("no users_identifier index")
-
- return self.do_test_migration(16, 17, setup_thd, verify_thd)
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_018_add_sourcestampset.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_018_add_sourcestampset.py
deleted file mode 100644
index 790bf1ac..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_018_add_sourcestampset.py
+++ /dev/null
@@ -1,234 +0,0 @@
-# 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
-from sqlalchemy.engine import reflection
-from twisted.python import log
-from twisted.trial import unittest
-from buildbot.test.util import migration
-
-class Migration(migration.MigrateTestMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpMigrateTest()
-
- def tearDown(self):
- return self.tearDownMigrateTest()
-
- def create_tables_thd(self, conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- self.buildsets = sa.Table('buildsets', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('external_idstring', sa.String(256)),
- sa.Column('reason', sa.String(256)),
- sa.Column('sourcestampid', sa.Integer,
- nullable=False), # NOTE: foreign key omitted
- sa.Column('submitted_at', sa.Integer, nullable=False),
- sa.Column('complete', sa.SmallInteger, nullable=False,
- server_default=sa.DefaultClause("0")),
- sa.Column('complete_at', sa.Integer),
- sa.Column('results', sa.SmallInteger),
- )
- self.buildsets.create(bind=conn)
- sa.Index('buildsets_complete', self.buildsets.c.complete).create()
- sa.Index('buildsets_submitted_at', self.buildsets.c.submitted_at).create()
-
- self.patches = sa.Table('patches', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('patchlevel', sa.Integer, nullable=False),
- sa.Column('patch_base64', sa.Text, nullable=False),
- sa.Column('patch_author', sa.Text, nullable=False),
- sa.Column('patch_comment', sa.Text, nullable=False),
- sa.Column('subdir', sa.Text),
- )
- self.patches.create(bind=conn)
-
- self.sourcestamps = sa.Table('sourcestamps', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('patchid', sa.Integer, sa.ForeignKey('patches.id')),
- sa.Column('repository', sa.String(length=512), nullable=False, server_default=''),
- sa.Column('project', sa.String(length=512), nullable=False, server_default=''),
- sa.Column('sourcestampid', sa.Integer, sa.ForeignKey('sourcestamps.id')),
- )
- self.sourcestamps.create(bind=conn)
-
- def fill_tables_with_testdata(self, conn, testdata):
- for bsid, ssid in testdata:
- self.insert_buildset_sourcestamp(conn, bsid, ssid)
-
- def insert_buildset_sourcestamp(self, conn, bsid, sourcestampid):
- conn.execute(self.buildsets.insert(),
- id=bsid,
- externalid_string='',
- reason = 'just',
- sourcestampid=sourcestampid,
- submitted_at=22417200,
- complete = 0,
- complete_at=22417200,
- results=0)
- conn.execute(self.sourcestamps.insert(),
- id=sourcestampid,
- branch='this_branch',
- revision='this_revision',
- patchid = None,
- repository='repo_a',
- project='')
-
- def assertBuildsetSourceStamp_thd(self, conn, exp_buildsets=[],
- exp_sourcestamps=[]):
- metadata = sa.MetaData()
- metadata.bind = conn
- tbl = sa.Table('buildsets', metadata, autoload=True)
- res = conn.execute(sa.select([tbl.c.id, tbl.c.sourcestampsetid], order_by=tbl.c.id))
- got_buildsets = res.fetchall()
-
- tbl = sa.Table('sourcestamps', metadata, autoload=True)
- res = conn.execute(sa.select([tbl.c.id, tbl.c.sourcestampsetid],
- order_by=[tbl.c.sourcestampsetid, tbl.c.id]))
- got_sourcestamps = res.fetchall()
-
- self.assertEqual(
- dict(buildsets=exp_buildsets, sourcestamps=exp_sourcestamps),
- dict(buildsets=got_buildsets, sourcestamps=got_sourcestamps))
-
- # tests
-
- def thd_assertForeignKeys(self, conn, exp, with_constrained_columns=[]):
- # MySQL does not reflect or use foreign keys, so we can't check..
- if conn.dialect.name == 'mysql':
- return
-
- insp = reflection.Inspector.from_engine(conn)
- fks = orig_fks = insp.get_foreign_keys('buildsets')
-
- # filter out constraints including all of the given columns
- with_constrained_columns = set(with_constrained_columns)
- fks = sorted([ fk
- for fk in fks
- if not with_constrained_columns - set(fk['constrained_columns'])
- ])
-
- # clean up
- for fk in fks:
- del fk['name'] # schema dependent
- del fk['referred_schema'] # idem
-
- # finally, assert
- if fks != exp:
- log.msg("got: %r" % (orig_fks,))
- self.assertEqual(fks, exp)
-
- def test_1_buildsets(self):
- buildsetdata = [(10, 100),(20, 200),(30, 300)]
- def setup_thd(conn):
- self.create_tables_thd(conn)
- self.fill_tables_with_testdata(conn, buildsetdata)
-
- def verify_thd(conn):
- metadata = sa.MetaData()
- metadata.bind = conn
- tbl = sa.Table('buildsets', metadata, autoload=True)
- self.assertTrue(hasattr(tbl.c, 'sourcestampsetid'))
-
- self.thd_assertForeignKeys(conn, [ {
- 'constrained_columns':['sourcestampsetid'],
- 'referred_table':'sourcestampsets',
- 'referred_columns':['id']},
- ], with_constrained_columns=['sourcestampsetid'])
-
- res = conn.execute(sa.select([tbl.c.id, tbl.c.sourcestampsetid], order_by=tbl.c.id))
- got_buildsets = res.fetchall()
- self.assertEqual(got_buildsets, buildsetdata)
-
- return self.do_test_migration(17, 18, setup_thd, verify_thd)
-
- def test_2_sourcestamp(self):
- buildsetdata = [(10, 100),(20, 200),(30, 300)]
- sourcestampdata = [ (ssid, ssid) for bsid, ssid in buildsetdata ]
- def setup_thd(conn):
- self.create_tables_thd(conn)
- self.fill_tables_with_testdata(conn, buildsetdata)
-
- def verify_thd(conn):
- metadata = sa.MetaData()
- metadata.bind = conn
- tbl = sa.Table('sourcestamps', metadata, autoload=True)
- self.assertTrue(hasattr(tbl.c, 'sourcestampsetid'))
-
- self.thd_assertForeignKeys(conn, [ {
- 'constrained_columns':['sourcestampsetid'],
- 'referred_table':'sourcestampsets',
- 'referred_columns':['id']},
- ], with_constrained_columns=['sourcestampsetid'])
-
- res = conn.execute(sa.select([tbl.c.id, tbl.c.sourcestampsetid],
- order_by=[tbl.c.sourcestampsetid, tbl.c.id]))
- got_sourcestamps = res.fetchall()
- self.assertEqual(got_sourcestamps, sourcestampdata)
-
- return self.do_test_migration(17, 18, setup_thd, verify_thd)
-
- def test_3_sourcestampset(self):
- buildsetdata = [(10, 100),(20, 200),(30, 300)]
- sourcestampsetdata = [ (ssid,) for bsid, ssid in buildsetdata ]
- def setup_thd(conn):
- self.create_tables_thd(conn)
- self.fill_tables_with_testdata(conn, buildsetdata)
-
- def verify_thd(conn):
- metadata = sa.MetaData()
- metadata.bind = conn
- tbl = sa.Table('sourcestampsets', metadata, autoload=True)
- self.assertTrue(hasattr(tbl.c, 'id'))
- res = conn.execute(sa.select([tbl.c.id],order_by=[tbl.c.id]))
- got_sourcestampsets = res.fetchall()
- self.assertEqual(got_sourcestampsets, sourcestampsetdata)
-
- return self.do_test_migration(17, 18, setup_thd, verify_thd)
-
- def test_4_integrated_migration(self):
- buildsetdata = [(10, 100),(20, 200),(30, 300)]
- sourcestampdata = [ (ssid, ssid) for bsid, ssid in buildsetdata ]
- sourcestampsetdata = [ (ssid,) for bsid, ssid in buildsetdata ]
- def setup_thd(conn):
- self.create_tables_thd(conn)
- self.fill_tables_with_testdata(conn, buildsetdata)
-
- def verify_thd(conn):
- metadata = sa.MetaData()
- metadata.bind = conn
- # Test for the buildsets
- tbl = sa.Table('buildsets', metadata, autoload=True)
- res = conn.execute(sa.select([tbl.c.id, tbl.c.sourcestampsetid], order_by=tbl.c.id))
- got_buildsets = res.fetchall()
- self.assertEqual(got_buildsets, buildsetdata)
-
- # Test for the sourcestamps
- tbl = sa.Table('sourcestamps', metadata, autoload=True)
- res = conn.execute(sa.select([tbl.c.id, tbl.c.sourcestampsetid],
- order_by=[tbl.c.sourcestampsetid, tbl.c.id]))
- got_sourcestamps = res.fetchall()
- self.assertEqual(got_sourcestamps, sourcestampdata)
-
- tbl = sa.Table('sourcestampsets', metadata, autoload=True)
- res = conn.execute(sa.select([tbl.c.id],order_by=[tbl.c.id]))
- got_sourcestampsets = res.fetchall()
- self.assertEqual(got_sourcestampsets, sourcestampsetdata)
-
- return self.do_test_migration(17, 18, setup_thd, verify_thd)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_019_merge_schedulers_to_objects.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_019_merge_schedulers_to_objects.py
deleted file mode 100644
index 452fc743..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_019_merge_schedulers_to_objects.py
+++ /dev/null
@@ -1,120 +0,0 @@
-# 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
-from twisted.trial import unittest
-from buildbot.test.util import migration
-
-class Migration(migration.MigrateTestMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpMigrateTest()
-
- def tearDown(self):
- return self.tearDownMigrateTest()
-
- def create_tables_thd(self, conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- changes = sa.Table('changes', metadata,
- sa.Column('changeid', sa.Integer, primary_key=True),
- # the rest is unimportant
- )
- changes.create()
-
- buildsets = sa.Table('buildsets', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- # the rest is unimportant
- )
- buildsets.create()
-
- self.schedulers = sa.Table("schedulers", metadata,
- sa.Column('schedulerid', sa.Integer, primary_key=True),
- sa.Column('name', sa.String(128), nullable=False),
- sa.Column('class_name', sa.String(128), nullable=False),
- )
- self.schedulers.create(bind=conn)
- sa.Index('name_and_class', self.schedulers.c.name,
- self.schedulers.c.class_name).create()
-
- self.scheduler_changes = sa.Table('scheduler_changes', metadata,
- sa.Column('schedulerid', sa.Integer,
- sa.ForeignKey('schedulers.schedulerid')),
- sa.Column('changeid', sa.Integer,
- sa.ForeignKey('changes.changeid')),
- sa.Column('important', sa.SmallInteger),
- )
- self.scheduler_changes.create()
- sa.Index('scheduler_changes_schedulerid',
- self.scheduler_changes.c.schedulerid).create()
- sa.Index('scheduler_changes_changeid',
- self.scheduler_changes.c.changeid).create()
- sa.Index('scheduler_changes_unique',
- self.scheduler_changes.c.schedulerid,
- self.scheduler_changes.c.changeid, unique=True).create()
-
- self.scheduler_upstream_buildsets = sa.Table(
- 'scheduler_upstream_buildsets', metadata,
- sa.Column('buildsetid', sa.Integer, sa.ForeignKey('buildsets.id')),
- sa.Column('schedulerid', sa.Integer,
- sa.ForeignKey('schedulers.schedulerid')),
- )
- self.scheduler_upstream_buildsets.create()
-
- sa.Index('scheduler_upstream_buildsets_buildsetid',
- self.scheduler_upstream_buildsets.c.buildsetid).create()
- sa.Index('scheduler_upstream_buildsets_schedulerid',
- self.scheduler_upstream_buildsets.c.schedulerid).create()
-
- self.objects = sa.Table("objects", metadata,
- sa.Column("id", sa.Integer, primary_key=True),
- sa.Column('name', sa.String(128), nullable=False),
- sa.Column('class_name', sa.String(128), nullable=False),
- )
- self.objects.create(bind=conn)
-
- sa.Index('object_identity', self.objects.c.name,
- self.objects.c.class_name, unique=True).create()
-
- # tests
-
- def test_update(self):
- # this upgrade script really just drops a bunch of tables, so
- # there's not much to test!
- def setup_thd(conn):
- self.create_tables_thd(conn)
-
- def verify_thd(conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- # these tables are gone
- for tbl in 'schedulers', 'scheduler_upstream_buildsets':
- try:
- conn.execute("select * from %s" % tbl)
- except:
- pass
- else:
- self.fail("%s table still exists" % tbl)
-
- # but scheduler_changes is not
- s_c_tbl = sa.Table("scheduler_changes", metadata,
- autoload=True)
- q = sa.select(
- [ s_c_tbl.c.objectid, s_c_tbl.c.changeid, s_c_tbl.c.important ])
- self.assertEqual(conn.execute(q).fetchall(), [])
-
- return self.do_test_migration(18, 19, setup_thd, verify_thd)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_020_remove_change_links.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_020_remove_change_links.py
deleted file mode 100644
index fedd3535..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_020_remove_change_links.py
+++ /dev/null
@@ -1,66 +0,0 @@
-# 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
-from twisted.trial import unittest
-from buildbot.test.util import migration
-
-class Migration(migration.MigrateTestMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpMigrateTest()
-
- def tearDown(self):
- return self.tearDownMigrateTest()
-
- def create_tables_thd(self, conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- changes = sa.Table('changes', metadata,
- sa.Column('changeid', sa.Integer, primary_key=True),
- # the rest is unimportant
- )
- changes.create()
-
- # Links (URLs) for changes
- change_links = sa.Table('change_links', metadata,
- sa.Column('changeid', sa.Integer,
- sa.ForeignKey('changes.changeid'), nullable=False),
- sa.Column('link', sa.String(1024), nullable=False),
- )
- change_links.create()
-
- sa.Index('change_links_changeid', change_links.c.changeid).create()
-
- # tests
-
- def test_update(self):
- def setup_thd(conn):
- self.create_tables_thd(conn)
-
- def verify_thd(conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- try:
- conn.execute("select * from change_links")
- except:
- pass
- else:
- self.fail("change_links still exists")
-
- return self.do_test_migration(19, 20, setup_thd, verify_thd)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_021_fix_postgres_sequences.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_021_fix_postgres_sequences.py
deleted file mode 100644
index 5cc3c980..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_021_fix_postgres_sequences.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# 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
-from twisted.trial import unittest
-from buildbot.test.util import migration
-
-class Migration(migration.MigrateTestMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpMigrateTest()
-
- def tearDown(self):
- return self.tearDownMigrateTest()
-
- cols = [
- 'buildrequests.id',
- 'builds.id',
- 'buildsets.id',
- 'changes.changeid',
- 'patches.id',
- 'sourcestampsets.id',
- 'sourcestamps.id',
- 'objects.id',
- 'users.uid',
- ]
-
- # tests
-
- def test_update(self):
- def setup_thd(conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- # insert a row into each table, giving an explicit id column so
- # that the sequence is not advanced correctly, but leave no rows in
- # one table to test that corner case
- for i, col in enumerate(self.cols):
- tbl_name, col_name = col.split('.')
- tbl = sa.Table(tbl_name, metadata,
- sa.Column(col_name, sa.Integer, primary_key=True))
- tbl.create()
- if i > 1:
- conn.execute(tbl.insert(), { col_name : i })
-
- def verify_thd(conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- # try inserting *without* an ID, and verify that the resulting ID
- # is as expected
- for i, col in enumerate(self.cols):
- tbl_name, col_name = col.split('.')
- tbl = sa.Table(tbl_name, metadata,
- sa.Column(col_name, sa.Integer, primary_key=True))
- r = conn.execute(tbl.insert(), {})
- if i > 1:
- exp = i+1
- else:
- exp = 1
- self.assertEqual(r.inserted_primary_key[0], exp)
-
- return self.do_test_migration(20, 21, setup_thd, verify_thd)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_022_add_codebase.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_022_add_codebase.py
deleted file mode 100644
index 95e154f5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_migrate_versions_022_add_codebase.py
+++ /dev/null
@@ -1,135 +0,0 @@
-# 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 datetime
-import sqlalchemy as sa
-from twisted.trial import unittest
-from buildbot.test.util import migration
-from buildbot.util import UTC, datetime2epoch
-
-class Migration(migration.MigrateTestMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpMigrateTest()
-
- def tearDown(self):
- return self.tearDownMigrateTest()
-
- # create tables as they are before migrating to version 019
- def create_tables_thd(self, conn):
- metadata = sa.MetaData()
- metadata.bind = conn
-
- self.sourcestamps = sa.Table('sourcestamps', metadata,
- sa.Column('id', sa.Integer, primary_key=True),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('patchid', sa.Integer),
- sa.Column('repository', sa.String(length=512), nullable=False, server_default=''),
- sa.Column('project', sa.String(length=512), nullable=False, server_default=''),
- sa.Column('sourcestampsetid', sa.Integer),
- )
- self.sourcestamps.create(bind=conn)
-
- self.changes = sa.Table('changes', metadata,
- sa.Column('changeid', sa.Integer, primary_key=True),
- sa.Column('author', sa.String(256), nullable=False),
- sa.Column('comments', sa.String(1024), nullable=False),
- sa.Column('is_dir', sa.SmallInteger, nullable=False),
- sa.Column('branch', sa.String(256)),
- sa.Column('revision', sa.String(256)),
- sa.Column('revlink', sa.String(256)),
- sa.Column('when_timestamp', sa.Integer, nullable=False),
- sa.Column('category', sa.String(256)),
- sa.Column('repository', sa.String(length=512), nullable=False, server_default=''),
- sa.Column('project', sa.String(length=512), nullable=False, server_default=''),
- )
- self.changes.create(bind=conn)
-
- def reload_tables_after_migration(self, conn):
- metadata = sa.MetaData()
- metadata.bind = conn
- self.sourcestamps = sa.Table('sourcestamps', metadata, autoload=True)
- self.changes = sa.Table('changes', metadata, autoload=True)
-
- def fill_tables_with_testdata(self, conn, testdata):
- for ssid, repo, codebase, cid in testdata:
- self.insert_sourcestamps_changes(conn, ssid, repo, codebase, cid)
-
- def insert_sourcestamps_changes(self, conn, sourcestampid, repository, codebase, changeid):
- conn.execute(self.sourcestamps.insert(),
- id=sourcestampid,
- sourcestampsetid=sourcestampid,
- branch='this_branch',
- revision='this_revision',
- patchid = None,
- repository=repository,
- project='',
- codebase=codebase)
-
- dt_when = datetime.datetime(1978, 6, 15, 12, 31, 15, tzinfo=UTC)
- conn.execute(self.changes.insert(),
- changeid = changeid,
- author = 'develop',
- comments = 'no comment',
- is_dir = 0,
- branch = 'default',
- revision = 'FD56A89',
- revling = None,
- when_timestamp = datetime2epoch(dt_when),
- category = None,
- repository = repository,
- codebase = codebase,
- project = '')
-
- def test_changes_has_codebase(self):
- changesdata = [(1000, 'https://svn.com/repo_a', 'repo_a', 1)]
- def setup_thd(conn):
- self.create_tables_thd(conn)
-
- def verify_thd(conn):
- self.reload_tables_after_migration(conn)
- tbl = self.changes
- self.assertTrue(hasattr(tbl.c, 'codebase'), 'Column codebase not found')
-
- # insert data in the table and new column
- self.fill_tables_with_testdata(conn, changesdata)
-
- res = conn.execute(sa.select([tbl.c.changeid, tbl.c.repository,
- tbl.c.codebase, ]))
- got_changes = res.fetchall()
- self.assertEqual(got_changes, [(1, 'https://svn.com/repo_a', 'repo_a')])
-
- return self.do_test_migration(21, 22, setup_thd, verify_thd)
-
- def test_sourcestamps_has_codebase(self):
- changesdata = [(1000, 'https://svn.com/repo_a', 'repo_a', 1)]
- def setup_thd(conn):
- self.create_tables_thd(conn)
-
- def verify_thd(conn):
- self.reload_tables_after_migration(conn)
- tbl = self.sourcestamps
- self.assertTrue(hasattr(tbl.c, 'codebase'), 'Column codebase not found')
-
- # insert data in the table and new column
- self.fill_tables_with_testdata(conn, changesdata)
-
- res = conn.execute(sa.select([tbl.c.id, tbl.c.repository,
- tbl.c.codebase,]))
- got_sourcestamps = res.fetchall()
- self.assertEqual(got_sourcestamps, [(1000, 'https://svn.com/repo_a', 'repo_a')])
-
- return self.do_test_migration(21, 22, setup_thd, verify_thd)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_model.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_model.py
deleted file mode 100644
index 99af34ef..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_model.py
+++ /dev/null
@@ -1,58 +0,0 @@
-# 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 os
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.db import model, enginestrategy
-from buildbot.test.util import db
-
-class DBConnector_Basic(db.RealDatabaseMixin, unittest.TestCase):
- """
- Basic tests of the DBConnector class - all start with an empty DB
- """
-
- def setUp(self):
- d = self.setUpRealDatabase()
- def make_fake_pool(_):
- engine = enginestrategy.create_engine(self.db_url,
- basedir=os.path.abspath('basedir'))
-
- # mock out the pool, and set up the model
- self.db = mock.Mock()
- self.db.pool.do_with_engine = lambda thd : defer.maybeDeferred(thd,engine)
- self.db.model = model.Model(self.db)
- self.db.start()
- d.addCallback(make_fake_pool)
- return d
-
- def tearDown(self):
- self.db.stop()
- return self.tearDownRealDatabase()
-
- def test_is_current_empty(self):
- d = self.db.model.is_current()
- d.addCallback(lambda r : self.assertFalse(r))
- return d
-
- def test_is_current_full(self):
- d = self.db.model.upgrade()
- d.addCallback(lambda _ : self.db.model.is_current())
- d.addCallback(lambda r : self.assertTrue(r))
- return d
-
- # the upgrade method is very well-tested by the integration tests; the
- # remainder of the object is just tables.
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_pool.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_pool.py
deleted file mode 100644
index 67d6a7e3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_pool.py
+++ /dev/null
@@ -1,185 +0,0 @@
-# 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 os
-import time
-import sqlalchemy as sa
-from twisted.trial import unittest
-from twisted.internet import defer, reactor
-from buildbot.db import pool
-from buildbot.test.util import db
-
-class Basic(unittest.TestCase):
-
- # basic tests, just using an in-memory SQL db and one thread
-
- def setUp(self):
- self.engine = sa.create_engine('sqlite://')
- self.engine.optimal_thread_pool_size = 1
- self.pool = pool.DBThreadPool(self.engine)
-
- def tearDown(self):
- self.pool.shutdown()
-
- def test_do(self):
- def add(conn, addend1, addend2):
- rp = conn.execute("SELECT %d + %d" % (addend1, addend2))
- return rp.scalar()
- d = self.pool.do(add, 10, 11)
- def check(res):
- self.assertEqual(res, 21)
- d.addCallback(check)
- return d
-
- def test_do_error(self):
- def fail(conn):
- rp = conn.execute("EAT COOKIES")
- return rp.scalar()
- d = self.pool.do(fail)
- return self.assertFailure(d, sa.exc.OperationalError)
-
- def test_do_exception(self):
- def raise_something(conn):
- raise RuntimeError("oh noes")
- d = self.pool.do(raise_something)
- return self.assertFailure(d, RuntimeError)
-
- def test_do_with_engine(self):
- def add(engine, addend1, addend2):
- rp = engine.execute("SELECT %d + %d" % (addend1, addend2))
- return rp.scalar()
- d = self.pool.do_with_engine(add, 10, 11)
- def check(res):
- self.assertEqual(res, 21)
- d.addCallback(check)
- return d
-
- def test_do_with_engine_exception(self):
- def fail(engine):
- rp = engine.execute("EAT COOKIES")
- return rp.scalar()
- d = self.pool.do_with_engine(fail)
- return self.assertFailure(d, sa.exc.OperationalError)
-
- def test_persistence_across_invocations(self):
- # NOTE: this assumes that both methods are called with the same
- # connection; if they run in parallel threads then it is not valid to
- # assume that the database engine will have finalized the first
- # transaction (and thus created the table) by the time the second
- # transaction runs. This is why we set optimal_thread_pool_size in
- # setUp.
- d = defer.succeed(None)
- def create_table(engine):
- engine.execute("CREATE TABLE tmp ( a integer )")
- d.addCallback( lambda r : self.pool.do_with_engine(create_table))
- def insert_into_table(engine):
- engine.execute("INSERT INTO tmp values ( 1 )")
- d.addCallback( lambda r : self.pool.do_with_engine(insert_into_table))
- return d
-
-
-class Stress(unittest.TestCase):
-
- def setUp(self):
- setup_engine = sa.create_engine('sqlite:///test.sqlite')
- setup_engine.execute("pragma journal_mode = wal")
- setup_engine.execute("CREATE TABLE test (a integer, b integer)")
-
- self.engine = sa.create_engine('sqlite:///test.sqlite')
- self.engine.optimal_thread_pool_size = 2
- self.pool = pool.DBThreadPool(self.engine)
-
- def tearDown(self):
- self.pool.shutdown()
- os.unlink("test.sqlite")
-
- @defer.inlineCallbacks
- def test_inserts(self):
- def write(conn):
- trans = conn.begin()
- conn.execute("INSERT INTO test VALUES (1, 1)")
- time.sleep(31)
- trans.commit()
- d1 = self.pool.do(write)
-
- def write2(conn):
- trans = conn.begin()
- conn.execute("INSERT INTO test VALUES (1, 1)")
- trans.commit()
- d2 = defer.Deferred()
- d2.addCallback(lambda _ :
- self.pool.do(write2))
- reactor.callLater(0.1, d2.callback, None)
-
- yield defer.DeferredList([ d1, d2 ])
-
- # don't run this test, since it takes 30s
- del test_inserts
-
-
-class BasicWithDebug(Basic):
-
- # same thing, but with debug=True
-
- def setUp(self):
- pool.debug = True
- return Basic.setUp(self)
-
- def tearDown(self):
- pool.debug = False
- return Basic.tearDown(self)
-
-
-class Native(unittest.TestCase, db.RealDatabaseMixin):
-
- # similar tests, but using the BUILDBOT_TEST_DB_URL
-
- def setUp(self):
- d = self.setUpRealDatabase(want_pool=False)
- def make_pool(_):
- self.pool = pool.DBThreadPool(self.db_engine)
- d.addCallback(make_pool)
- return d
-
- def tearDown(self):
- # try to delete the 'native_tests' table
- meta = sa.MetaData()
- native_tests = sa.Table("native_tests", meta)
- def thd(conn):
- native_tests.drop(bind=self.db_engine, checkfirst=True)
- d = self.pool.do(thd)
- d.addCallback(lambda _ : self.pool.shutdown())
- d.addCallback(lambda _ : self.tearDownRealDatabase())
- return d
-
- def test_ddl_and_queries(self):
- meta = sa.MetaData()
- native_tests = sa.Table("native_tests", meta,
- sa.Column('name', sa.String(length=200)))
-
- # perform a DDL operation and immediately try to access that table;
- # this has caused problems in the past, so this is basically a
- # regression test.
- def ddl(conn):
- t = conn.begin()
- native_tests.create(bind=conn)
- t.commit()
- d = self.pool.do(ddl)
- def access(conn):
- native_tests.insert(bind=conn).execute([ {'name':'foo'} ])
- d.addCallback(lambda _ :
- self.pool.do(access))
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_schedulers.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_schedulers.py
deleted file mode 100644
index 395fbb79..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_schedulers.py
+++ /dev/null
@@ -1,161 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.db import schedulers
-from buildbot.test.util import connector_component
-from buildbot.test.fake import fakedb
-
-class TestSchedulersConnectorComponent(
- connector_component.ConnectorComponentMixin,
- unittest.TestCase):
-
- def setUp(self):
- d = self.setUpConnectorComponent(
- table_names=['changes', 'objects', 'scheduler_changes' ])
-
- def finish_setup(_):
- self.db.schedulers = \
- schedulers.SchedulersConnectorComponent(self.db)
- d.addCallback(finish_setup)
-
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- def checkScheduler(self, objectid, name, class_name):
- def thd(conn):
- q = self.db.model.schedulers.select(
- whereclause=(self.db.model.schedulers.c.objectid == objectid))
- for row in conn.execute(q):
- self.assertEqual([ row.objectid, row.name, row.class_name],
- [ objectid, name, class_name])
- return self.db.pool.do(thd)
-
- # test data
-
- change3 = fakedb.Change(changeid=3)
- change4 = fakedb.Change(changeid=4)
- change5 = fakedb.Change(changeid=5)
- change6 = fakedb.Change(changeid=6, branch='sql')
-
- scheduler24 = fakedb.Object(id=24)
-
- def addClassifications(self, _, objectid, *classifications):
- def thd(conn):
- q = self.db.model.scheduler_changes.insert()
- conn.execute(q, [
- dict(changeid=c[0], objectid=objectid, important=c[1])
- for c in classifications ])
- return self.db.pool.do(thd)
-
- # tests
- def test_classifyChanges(self):
- d = self.insertTestData([ self.change3, self.change4,
- self.scheduler24 ])
- d.addCallback(lambda _ :
- self.db.schedulers.classifyChanges(24,
- { 3 : False, 4: True }))
- def check(_):
- def thd(conn):
- sch_chgs_tbl = self.db.model.scheduler_changes
- q = sch_chgs_tbl.select(order_by=sch_chgs_tbl.c.changeid)
- r = conn.execute(q)
- rows = [ (row.objectid, row.changeid, row.important)
- for row in r.fetchall() ]
- self.assertEqual(rows, [ (24, 3, 0), (24, 4, 1) ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_classifyChanges_again(self):
- # test reclassifying changes, which may happen during some timing
- # conditions
- d = self.insertTestData([
- self.change3,
- self.scheduler24,
- fakedb.SchedulerChange(objectid=24, changeid=3, important=0),
- ])
- d.addCallback(lambda _ :
- self.db.schedulers.classifyChanges(24, { 3 : True }))
- def check(_):
- def thd(conn):
- sch_chgs_tbl = self.db.model.scheduler_changes
- q = sch_chgs_tbl.select(order_by=sch_chgs_tbl.c.changeid)
- r = conn.execute(q)
- rows = [ (row.objectid, row.changeid, row.important)
- for row in r.fetchall() ]
- self.assertEqual(rows, [ (24, 3, 1) ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_flushChangeClassifications(self):
- d = self.insertTestData([ self.change3, self.change4,
- self.change5, self.scheduler24 ])
- d.addCallback(self.addClassifications, 24,
- (3, 1), (4, 0), (5, 1))
- d.addCallback(lambda _ :
- self.db.schedulers.flushChangeClassifications(24))
- def check(_):
- def thd(conn):
- q = self.db.model.scheduler_changes.select()
- rows = conn.execute(q).fetchall()
- self.assertEqual(rows, [])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_flushChangeClassifications_less_than(self):
- d = self.insertTestData([ self.change3, self.change4,
- self.change5, self.scheduler24 ])
- d.addCallback(self.addClassifications, 24,
- (3, 1), (4, 0), (5, 1))
- d.addCallback(lambda _ :
- self.db.schedulers.flushChangeClassifications(24, less_than=5))
- def check(_):
- def thd(conn):
- q = self.db.model.scheduler_changes.select()
- rows = conn.execute(q).fetchall()
- self.assertEqual([ (r.changeid, r.important) for r in rows],
- [ (5, 1) ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_getChangeClassifications(self):
- d = self.insertTestData([ self.change3, self.change4, self.change5,
- self.change6, self.scheduler24 ])
- d.addCallback(self.addClassifications, 24,
- (3, 1), (4, 0), (5, 1), (6, 1))
- d.addCallback(lambda _ :
- self.db.schedulers.getChangeClassifications(24))
- def check(cls):
- self.assertEqual(cls, { 3 : True, 4 : False, 5 : True, 6: True })
- d.addCallback(check)
- return d
-
- def test_getChangeClassifications_branch(self):
- d = self.insertTestData([ self.change3, self.change4, self.change5,
- self.change6, self.scheduler24 ])
- d.addCallback(self.addClassifications, 24,
- (3, 1), (4, 0), (5, 1), (6, 1))
- d.addCallback(lambda _ :
- self.db.schedulers.getChangeClassifications(24, branch='sql'))
- def check(cls):
- self.assertEqual(cls, { 6 : True })
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_sourcestamps.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_sourcestamps.py
deleted file mode 100644
index 01346a2c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_sourcestamps.py
+++ /dev/null
@@ -1,212 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.db import sourcestamps
-from buildbot.test.util import connector_component
-from buildbot.test.fake import fakedb
-
-class TestSourceStampsConnectorComponent(
- connector_component.ConnectorComponentMixin,
- unittest.TestCase):
-
- def setUp(self):
- d = self.setUpConnectorComponent(
- table_names=['changes', 'change_files', 'patches',
- 'sourcestamp_changes', 'sourcestamps', 'sourcestampsets' ])
-
- def finish_setup(_):
- self.db.sourcestamps = \
- sourcestamps.SourceStampsConnectorComponent(self.db)
- d.addCallback(finish_setup)
-
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- # tests
-
- def test_addSourceStamp_simple(self):
- # add a sourcestampset for referential integrity
- d = self.insertTestData([
- fakedb.SourceStampSet(id=1),
- ])
- d.addCallback(lambda _ :
- self.db.sourcestamps.addSourceStamp(branch = 'production', revision='abdef',
- repository='test://repo', codebase='cb', project='stamper', sourcestampsetid=1))
- def check(ssid):
- def thd(conn):
- # should see one sourcestamp row
- ss_tbl = self.db.model.sourcestamps
- r = conn.execute(ss_tbl.select())
- rows = [ (row.id, row.branch, row.revision,
- row.patchid, row.repository, row.codebase, row.project, row.sourcestampsetid)
- for row in r.fetchall() ]
- self.assertEqual(rows,
- [ ( ssid, 'production', 'abdef', None, 'test://repo', 'cb', 'stamper', 1) ])
-
- # .. and no sourcestamp_changes
- ssc_tbl = self.db.model.sourcestamp_changes
- r = conn.execute(ssc_tbl.select())
- rows = [ 1 for row in r.fetchall() ]
- self.assertEqual(rows, [])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_addSourceStamp_changes(self):
- # add some sample changes and a sourcestampset for referential integrity
- d = self.insertTestData([
- fakedb.SourceStampSet(id=1),
- fakedb.Change(changeid=3),
- fakedb.Change(changeid=4),
- ])
-
- d.addCallback(lambda _ :
- self.db.sourcestamps.addSourceStamp(branch = 'production', revision='abdef',
- repository='test://repo', codebase='cb', project='stamper', sourcestampsetid=1, changeids=[3,4]))
-
- def check(ssid):
- def thd(conn):
- # should see one sourcestamp row
- ss_tbl = self.db.model.sourcestamps
- r = conn.execute(ss_tbl.select())
- rows = [ (row.id, row.branch, row.revision,
- row.patchid, row.repository, row.codebase, row.project, row.sourcestampsetid)
- for row in r.fetchall() ]
- self.assertEqual(rows,
- [ ( ssid, 'production', 'abdef', None, 'test://repo', 'cb', 'stamper', 1) ])
-
- # .. and two sourcestamp_changes
- ssc_tbl = self.db.model.sourcestamp_changes
- r = conn.execute(ssc_tbl.select())
- rows = [ (row.sourcestampid, row.changeid) for row in r.fetchall() ]
- self.assertEqual(sorted(rows), [ (ssid, 3), (ssid, 4) ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_addSourceStamp_patch(self):
- # add a sourcestampset for referential integrity
- d = self.insertTestData([
- fakedb.SourceStampSet(id=1),
- ])
- d.addCallback(lambda _ :
- self.db.sourcestamps.addSourceStamp(branch = 'production', revision='abdef',
- repository='test://repo', codebase='cb', project='stamper', sourcestampsetid=1, patch_body='my patch', patch_level=3,
- patch_subdir='master/', patch_author='me',
- patch_comment="comment"))
- def check(ssid):
- def thd(conn):
- # should see one sourcestamp row
- ss_tbl = self.db.model.sourcestamps
- r = conn.execute(ss_tbl.select())
- rows = [ (row.id, row.branch, row.revision,
- row.patchid, row.repository, row.codebase, row.project, row.sourcestampsetid)
- for row in r.fetchall() ]
- patchid = row.patchid
- self.assertNotEqual(patchid, None)
- self.assertEqual(rows,
- [ ( ssid, 'production', 'abdef', patchid, 'test://repo', 'cb',
- 'stamper', 1) ])
-
- # .. and a single patch
- patches_tbl = self.db.model.patches
- r = conn.execute(patches_tbl.select())
- rows = [ (row.id, row.patchlevel, row.patch_base64, row.subdir,
- row.patch_author, row.patch_comment)
- for row in r.fetchall() ]
- self.assertEqual(rows, [(patchid, 3, 'bXkgcGF0Y2g=', 'master/',
- 'me', 'comment')])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_getSourceStamp_simple(self):
- d = self.insertTestData([
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234, branch='br', revision='rv', repository='rep', codebase='cb', project='prj'),
- ])
- d.addCallback(lambda _ :
- self.db.sourcestamps.getSourceStamp(234))
- def check(ssdict):
- self.assertEqual(ssdict, dict(ssid=234, branch='br', revision='rv',
- sourcestampsetid=234, repository='rep', codebase = 'cb',
- project='prj', patch_body=None,
- patch_level=None, patch_subdir=None,
- patch_author=None, patch_comment=None, changeids=set([])))
- d.addCallback(check)
- return d
-
- def test_getSourceStamp_simple_None(self):
- "check that NULL branch and revision are handled correctly"
- d = self.insertTestData([
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234, branch=None, revision=None,
- repository='rep', codebase='cb', project='prj'),
- ])
- d.addCallback(lambda _ :
- self.db.sourcestamps.getSourceStamp(234))
- def check(ssdict):
- self.assertEqual((ssdict['branch'], ssdict['revision']),
- (None, None))
- d.addCallback(check)
- return d
-
- def test_getSourceStamp_changes(self):
- d = self.insertTestData([
- fakedb.Change(changeid=16),
- fakedb.Change(changeid=19),
- fakedb.Change(changeid=20),
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234),
- fakedb.SourceStampChange(sourcestampid=234, changeid=16),
- fakedb.SourceStampChange(sourcestampid=234, changeid=20),
- ])
- d.addCallback(lambda _ :
- self.db.sourcestamps.getSourceStamp(234))
- def check(ssdict):
- self.assertEqual(ssdict['changeids'], set([16,20]))
- d.addCallback(check)
- return d
-
- def test_getSourceStamp_patch(self):
- d = self.insertTestData([
- fakedb.Patch(id=99, patch_base64='aGVsbG8sIHdvcmxk',
- patch_author='bar', patch_comment='foo', subdir='/foo',
- patchlevel=3),
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234, patchid=99),
- ])
- d.addCallback(lambda _ :
- self.db.sourcestamps.getSourceStamp(234))
- def check(ssdict):
- self.assertEqual(dict((k,v) for k,v in ssdict.iteritems()
- if k.startswith('patch_')),
- dict(patch_body='hello, world',
- patch_level=3,
- patch_author='bar',
- patch_comment='foo',
- patch_subdir='/foo'))
- d.addCallback(check)
- return d
-
- def test_getSourceStamp_nosuch(self):
- d = self.db.sourcestamps.getSourceStamp(234)
- def check(ssdict):
- self.assertEqual(ssdict, None)
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_sourcestampsets.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_sourcestampsets.py
deleted file mode 100644
index 217b3ed3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_sourcestampsets.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.db import sourcestampsets
-from buildbot.test.util import connector_component
-
-class TestSourceStampSetsConnectorComponent(
- connector_component.ConnectorComponentMixin,
- unittest.TestCase):
-
- def setUp(self):
- d = self.setUpConnectorComponent(
- table_names=[ 'patches', 'buildsets', 'sourcestamps',
- 'sourcestampsets' ])
-
- def finish_setup(_):
- self.db.sourcestampsets = \
- sourcestampsets.SourceStampSetsConnectorComponent(self.db)
- d.addCallback(finish_setup)
-
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- # tests
- def test_addSourceStampSet_simple(self):
- d = defer.succeed(None)
-
- d.addCallback(lambda _ :
- self.db.sourcestampsets.addSourceStampSet())
-
- def check(sourcestampsetid):
- def thd(conn):
- # should see one sourcestamp row
- ssset_tbl = self.db.model.sourcestampsets
- r = conn.execute(ssset_tbl.select())
- rows = [ (row.id)
- for row in r.fetchall() ]
- # Test if returned setid is in database
- self.assertEqual(rows,
- [ ( sourcestampsetid) ])
- # Test if returned set id starts with
- self.assertEqual(sourcestampsetid, 1)
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_state.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_state.py
deleted file mode 100644
index 8002222e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_state.py
+++ /dev/null
@@ -1,182 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.db import state
-from buildbot.test.util import connector_component
-from buildbot.test.fake import fakedb
-
-class TestStateConnectorComponent(
- connector_component.ConnectorComponentMixin,
- unittest.TestCase):
-
- def setUp(self):
- d = self.setUpConnectorComponent(
- table_names=['objects', 'object_state' ])
-
- def finish_setup(_):
- self.db.state = \
- state.StateConnectorComponent(self.db)
- d.addCallback(finish_setup)
-
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- def test_getObjectId_new(self):
- d = self.db.state.getObjectId('someobj', 'someclass')
- def check(objectid):
- self.assertNotEqual(objectid, None)
- def thd(conn):
- q = self.db.model.objects.select()
- rows = conn.execute(q).fetchall()
- self.assertEqual(
- [ (r.id, r.name, r.class_name) for r in rows ],
- [ (objectid, 'someobj', 'someclass') ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_getObjectId_existing(self):
- d = self.insertTestData([
- fakedb.Object(id=19, name='someobj',
- class_name='someclass') ])
- d.addCallback(lambda _ :
- self.db.state.getObjectId('someobj', 'someclass'))
- def check(objectid):
- self.assertEqual(objectid, 19)
- d.addCallback(check)
- return d
-
-
- def test_getObjectId_conflict(self):
- # set up to insert a row between looking for an existing object
- # and adding a new one, triggering the fallback to re-running
- # the select.
- def hook(conn):
- conn.execute(self.db.model.objects.insert(),
- id=27, name='someobj', class_name='someclass')
- self.db.state._test_timing_hook = hook
-
- d = self.db.state.getObjectId('someobj', 'someclass')
- def check(objectid):
- self.assertEqual(objectid, 27)
- d.addCallback(check)
- return d
-
- def test_getState_missing(self):
- d = self.db.state.getState(10, 'nosuch')
- return self.assertFailure(d, KeyError)
-
- def test_getState_missing_default(self):
- d = self.db.state.getState(10, 'nosuch', 'abc')
- def check(val):
- self.assertEqual(val, 'abc')
- d.addCallback(check)
- return d
-
- def test_getState_missing_default_None(self):
- d = self.db.state.getState(10, 'nosuch', None)
- def check(val):
- self.assertEqual(val, None)
- d.addCallback(check)
- return d
-
- def test_getState_present(self):
- d = self.insertTestData([
- fakedb.Object(id=10, name='x', class_name='y'),
- fakedb.ObjectState(objectid=10, name='x', value_json='[1,2]'),
- ])
- d.addCallback(lambda _ :
- self.db.state.getState(10, 'x'))
- def check(val):
- self.assertEqual(val, [1,2])
- d.addCallback(check)
- return d
-
- def test_getState_badjson(self):
- d = self.insertTestData([
- fakedb.Object(id=10, name='x', class_name='y'),
- fakedb.ObjectState(objectid=10, name='x', value_json='ff[1'),
- ])
- d.addCallback(lambda _ :
- self.db.state.getState(10, 'x'))
- return self.assertFailure(d, TypeError)
-
- def test_setState(self):
- d = self.insertTestData([
- fakedb.Object(id=10, name='-', class_name='-'),
- ])
- d.addCallback(lambda _ :
- self.db.state.setState(10, 'x', [1,2]))
- def check(_):
- def thd(conn):
- q = self.db.model.object_state.select()
- rows = conn.execute(q).fetchall()
- self.assertEqual(
- [ (r.objectid, r.name, r.value_json) for r in rows ],
- [ (10, 'x', '[1, 2]') ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_setState_badjson(self):
- d = self.insertTestData([
- fakedb.Object(id=10, name='x', class_name='y'),
- ])
- d.addCallback(lambda _ :
- self.db.state.setState(10, 'x', self)) # self is not JSON-able..
- return self.assertFailure(d, TypeError)
-
- def test_setState_existing(self):
- d = self.insertTestData([
- fakedb.Object(id=10, name='-', class_name='-'),
- fakedb.ObjectState(objectid=10, name='x', value_json='99'),
- ])
- d.addCallback(lambda _ :
- self.db.state.setState(10, 'x', [1,2]))
- def check(_):
- def thd(conn):
- q = self.db.model.object_state.select()
- rows = conn.execute(q).fetchall()
- self.assertEqual(
- [ (r.objectid, r.name, r.value_json) for r in rows ],
- [ (10, 'x', '[1, 2]') ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
- def test_setState_conflict(self):
- d = self.insertTestData([
- fakedb.Object(id=10, name='-', class_name='-'),
- ])
- def hook(conn):
- conn.execute(self.db.model.object_state.insert(),
- objectid=10, name='x', value_json='22')
- self.db.state._test_timing_hook = hook
- d.addCallback(lambda _ :
- self.db.state.setState(10, 'x', [1,2]))
- def check(_):
- def thd(conn):
- q = self.db.model.object_state.select()
- rows = conn.execute(q).fetchall()
- self.assertEqual(
- [ (r.objectid, r.name, r.value_json) for r in rows ],
- [ (10, 'x', '22') ])
- return self.db.pool.do(thd)
- d.addCallback(check)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_users.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_users.py
deleted file mode 100644
index 63e2c0de..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_db_users.py
+++ /dev/null
@@ -1,473 +0,0 @@
-# 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
-from twisted.trial import unittest
-from buildbot.db import users
-from buildbot.test.util import connector_component
-from buildbot.test.fake import fakedb
-
-class TestUsersConnectorComponent(connector_component.ConnectorComponentMixin,
- unittest.TestCase):
-
- def setUp(self):
- d = self.setUpConnectorComponent(
- table_names=['users', 'users_info', 'changes', 'change_users'])
- def finish_setup(_):
- self.db.users = users.UsersConnectorComponent(self.db)
- d.addCallback(finish_setup)
- return d
-
- def tearDown(self):
- return self.tearDownConnectorComponent()
-
- # sample user data
-
- user1_rows = [
- fakedb.User(uid=1, identifier='soap'),
- fakedb.UserInfo(uid=1, attr_type='IPv9', attr_data='0578cc6.8db024'),
- ]
-
- user2_rows = [
- fakedb.User(uid=2, identifier='lye'),
- fakedb.UserInfo(uid=2, attr_type='git',
- attr_data='Tyler Durden <tyler@mayhem.net>'),
- fakedb.UserInfo(uid=2, attr_type='irc', attr_data='durden')
- ]
-
- user3_rows = [
- fakedb.User(uid=3, identifier='marla', bb_username='marla',
- bb_password='cancer')
- ]
-
- user1_dict = {
- 'uid': 1,
- 'identifier': u'soap',
- 'bb_username': None,
- 'bb_password': None,
- 'IPv9': u'0578cc6.8db024',
- }
-
- user2_dict = {
- 'uid': 2,
- 'identifier': u'lye',
- 'bb_username': None,
- 'bb_password': None,
- 'irc': u'durden',
- 'git': u'Tyler Durden <tyler@mayhem.net>'
- }
-
- user3_dict = {
- 'uid': 3,
- 'identifier': u'marla',
- 'bb_username': u'marla',
- 'bb_password': u'cancer',
- }
-
- # tests
-
- def test_addUser_new(self):
- d = self.db.users.findUserByAttr(identifier='soap',
- attr_type='subspace_net_handle',
- attr_data='Durden0924')
- def check_user(uid):
- def thd(conn):
- users_tbl = self.db.model.users
- users_info_tbl = self.db.model.users_info
- users = conn.execute(users_tbl.select()).fetchall()
- infos = conn.execute(users_info_tbl.select()).fetchall()
- self.assertEqual(len(users), 1)
- self.assertEqual(users[0].uid, uid)
- self.assertEqual(users[0].identifier, 'soap')
- self.assertEqual(len(infos), 1)
- self.assertEqual(infos[0].uid, uid)
- self.assertEqual(infos[0].attr_type, 'subspace_net_handle')
- self.assertEqual(infos[0].attr_data, 'Durden0924')
- return self.db.pool.do(thd)
- d.addCallback(check_user)
- return d
-
- def test_addUser_existing(self):
- d = self.insertTestData(self.user1_rows)
- d.addCallback(lambda _ : self.db.users.findUserByAttr(
- identifier='soapy',
- attr_type='IPv9',
- attr_data='0578cc6.8db024'))
- def check_user(uid):
- self.assertEqual(uid, 1)
- def thd(conn):
- users_tbl = self.db.model.users
- users_info_tbl = self.db.model.users_info
- users = conn.execute(users_tbl.select()).fetchall()
- infos = conn.execute(users_info_tbl.select()).fetchall()
- self.assertEqual(len(users), 1)
- self.assertEqual(users[0].uid, uid)
- self.assertEqual(users[0].identifier, 'soap') # not changed!
- self.assertEqual(len(infos), 1)
- self.assertEqual(infos[0].uid, uid)
- self.assertEqual(infos[0].attr_type, 'IPv9')
- self.assertEqual(infos[0].attr_data, '0578cc6.8db024')
- return self.db.pool.do(thd)
- d.addCallback(check_user)
- return d
-
- def test_findUser_existing(self):
- d = self.insertTestData(
- self.user1_rows + self.user2_rows + self.user3_rows)
- d.addCallback(lambda _ : self.db.users.findUserByAttr(
- identifier='lye',
- attr_type='git',
- attr_data='Tyler Durden <tyler@mayhem.net>'))
- def check_user(uid):
- self.assertEqual(uid, 2)
- def thd(conn):
- users_tbl = self.db.model.users
- users_info_tbl = self.db.model.users_info
- users = conn.execute(users_tbl.select()).fetchall()
- infos = conn.execute(users_info_tbl.select()).fetchall()
- self.assertEqual((
- sorted([ tuple(u) for u in users]),
- sorted([ tuple(i) for i in infos])
- ), (
- [
- (1L, u'soap', None, None),
- (2L, u'lye', None, None),
- (3L, u'marla', u'marla', u'cancer'),
- ], [
- (1L, u'IPv9', u'0578cc6.8db024'),
- (2L, u'git', u'Tyler Durden <tyler@mayhem.net>'),
- (2L, u'irc', u'durden')
- ]))
- return self.db.pool.do(thd)
- d.addCallback(check_user)
- return d
-
- def test_addUser_race(self):
- def race_thd(conn):
- # note that this assumes that both inserts can happen "at once".
- # This is the case for DB engines that support transactions, but
- # not for MySQL. so this test does not detect the potential MySQL
- # failure, which will generally result in a spurious failure.
- conn.execute(self.db.model.users.insert(),
- uid=99, identifier='soap')
- conn.execute(self.db.model.users_info.insert(),
- uid=99, attr_type='subspace_net_handle',
- attr_data='Durden0924')
- d = self.db.users.findUserByAttr(identifier='soap',
- attr_type='subspace_net_handle',
- attr_data='Durden0924',
- _race_hook=race_thd)
- def check_user(uid):
- self.assertEqual(uid, 99)
- def thd(conn):
- users_tbl = self.db.model.users
- users_info_tbl = self.db.model.users_info
- users = conn.execute(users_tbl.select()).fetchall()
- infos = conn.execute(users_info_tbl.select()).fetchall()
- self.assertEqual(len(users), 1)
- self.assertEqual(users[0].uid, uid)
- self.assertEqual(users[0].identifier, 'soap')
- self.assertEqual(len(infos), 1)
- self.assertEqual(infos[0].uid, uid)
- self.assertEqual(infos[0].attr_type, 'subspace_net_handle')
- self.assertEqual(infos[0].attr_data, 'Durden0924')
- return self.db.pool.do(thd)
- d.addCallback(check_user)
- return d
-
- def test_addUser_existing_identifier(self):
- d = self.insertTestData(self.user1_rows)
- d.addCallback(lambda _ : self.db.users.findUserByAttr(
- identifier='soap',
- attr_type='telepathIO(tm)',
- attr_data='hmm,lye'))
- return self.assertFailure(d, sa.exc.IntegrityError,
- sa.exc.ProgrammingError)
-
- def test_getUser(self):
- d = self.insertTestData(self.user1_rows)
- def get1(_):
- return self.db.users.getUser(1)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict, self.user1_dict)
- d.addCallback(check1)
- return d
-
- def test_getUser_bb(self):
- d = self.insertTestData(self.user3_rows)
- def get3(_):
- return self.db.users.getUser(3)
- d.addCallback(get3)
- def check3(usdict):
- self.assertEqual(usdict, self.user3_dict)
- d.addCallback(check3)
- return d
-
- def test_getUser_multi_attr(self):
- d = self.insertTestData(self.user2_rows)
- def get1(_):
- return self.db.users.getUser(2)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict, self.user2_dict)
- d.addCallback(check1)
- return d
-
- def test_getUser_no_match(self):
- d = self.insertTestData(self.user1_rows)
- def get3(_):
- return self.db.users.getUser(3)
- d.addCallback(get3)
- def check3(none):
- self.assertEqual(none, None)
- d.addCallback(check3)
- return d
-
- def test_getUsers_none(self):
- d = self.db.users.getUsers()
- def check(res):
- self.assertEqual(res, [])
- d.addCallback(check)
- return d
-
- def test_getUsers(self):
- d = self.insertTestData(self.user1_rows)
- def get(_):
- return self.db.users.getUsers()
- d.addCallback(get)
- def check(res):
- self.assertEqual(res, [dict(uid=1, identifier='soap')])
- d.addCallback(check)
- return d
-
- def test_getUsers_multiple(self):
- d = self.insertTestData(self.user1_rows + self.user2_rows)
- def get(_):
- return self.db.users.getUsers()
- d.addCallback(get)
- def check(res):
- self.assertEqual(res, [dict(uid=1, identifier='soap'),
- dict(uid=2, identifier='lye')])
- d.addCallback(check)
- return d
-
- def test_getUserByUsername(self):
- d = self.insertTestData(self.user3_rows)
- def get3(_):
- return self.db.users.getUserByUsername("marla")
- d.addCallback(get3)
- def check3(res):
- self.assertEqual(res, self.user3_dict)
- d.addCallback(check3)
- return d
-
- def test_getUserByUsername_no_match(self):
- d = self.insertTestData(self.user3_rows)
- def get3(_):
- return self.db.users.getUserByUsername("tyler")
- d.addCallback(get3)
- def check3(none):
- self.assertEqual(none, None)
- d.addCallback(check3)
- return d
-
- def test_updateUser_existing_type(self):
- d = self.insertTestData(self.user1_rows)
- def update1(_):
- return self.db.users.updateUser(
- uid=1, attr_type='IPv9', attr_data='abcd.1234')
- d.addCallback(update1)
- def get1(_):
- return self.db.users.getUser(1)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict['IPv9'], 'abcd.1234')
- self.assertEqual(usdict['identifier'], 'soap') # no change
- d.addCallback(check1)
- return d
-
- def test_updateUser_new_type(self):
- d = self.insertTestData(self.user1_rows)
- def update1(_):
- return self.db.users.updateUser(
- uid=1, attr_type='IPv4', attr_data='123.134.156.167')
- d.addCallback(update1)
- def get1(_):
- return self.db.users.getUser(1)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict['IPv4'], '123.134.156.167')
- self.assertEqual(usdict['IPv9'], '0578cc6.8db024') # no change
- self.assertEqual(usdict['identifier'], 'soap') # no change
- d.addCallback(check1)
- return d
-
- def test_updateUser_identifier(self):
- d = self.insertTestData(self.user1_rows)
- def update1(_):
- return self.db.users.updateUser(
- uid=1, identifier='lye')
- d.addCallback(update1)
- def get1(_):
- return self.db.users.getUser(1)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict['identifier'], 'lye')
- self.assertEqual(usdict['IPv9'], '0578cc6.8db024') # no change
- d.addCallback(check1)
- return d
-
- def test_updateUser_bb(self):
- d = self.insertTestData(self.user3_rows)
- def update3(_):
- return self.db.users.updateUser(
- uid=3, bb_username='boss', bb_password='fired')
- d.addCallback(update3)
- def get3(_):
- return self.db.users.getUser(3)
- d.addCallback(get3)
- def check3(usdict):
- self.assertEqual(usdict['bb_username'], 'boss')
- self.assertEqual(usdict['bb_password'], 'fired')
- self.assertEqual(usdict['identifier'], 'marla') # no change
- d.addCallback(check3)
- return d
-
- def test_updateUser_all(self):
- d = self.insertTestData(self.user1_rows)
- def update1(_):
- return self.db.users.updateUser(
- uid=1, identifier='lye', bb_username='marla',
- bb_password='cancer', attr_type='IPv4', attr_data='123.134.156.167')
- d.addCallback(update1)
- def get1(_):
- return self.db.users.getUser(1)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict['identifier'], 'lye')
- self.assertEqual(usdict['bb_username'], 'marla')
- self.assertEqual(usdict['bb_password'], 'cancer')
- self.assertEqual(usdict['IPv4'], '123.134.156.167')
- self.assertEqual(usdict['IPv9'], '0578cc6.8db024') # no change
- d.addCallback(check1)
- return d
-
- def test_updateUser_race(self):
- # called from the db thread, this opens a *new* connection (to avoid
- # the existing transaction) and executes a conflicting insert in that
- # connection. This will cause the insert in the db method to fail, and
- # the data in this insert (8.8.8.8) will appear below.
- def race_thd(conn):
- conn = self.db.pool.engine.connect()
- conn.execute(self.db.model.users_info.insert(),
- uid=1, attr_type='IPv4',
- attr_data='8.8.8.8')
-
- d = self.insertTestData(self.user1_rows)
- def update1(_):
- return self.db.users.updateUser(
- uid=1, attr_type='IPv4', attr_data='123.134.156.167',
- _race_hook=race_thd)
- d.addCallback(update1)
- def get1(_):
- return self.db.users.getUser(1)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict['identifier'], 'soap')
- self.assertEqual(usdict['IPv4'], '8.8.8.8')
- self.assertEqual(usdict['IPv9'], '0578cc6.8db024') # no change
- d.addCallback(check1)
- return d
-
- def test_update_NoMatch_identifier(self):
- d = self.insertTestData(self.user1_rows)
- def update3(_):
- return self.db.users.updateUser(
- uid=3, identifier='abcd')
- d.addCallback(update3)
- def get1(_):
- return self.db.users.getUser(1)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict['identifier'], 'soap') # no change
- d.addCallback(check1)
- return d
-
- def test_update_NoMatch_attribute(self):
- d = self.insertTestData(self.user1_rows)
- def update3(_):
- return self.db.users.updateUser(
- uid=3, attr_type='abcd', attr_data='efgh')
- d.addCallback(update3)
- def get1(_):
- return self.db.users.getUser(1)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict['IPv9'], '0578cc6.8db024') # no change
- d.addCallback(check1)
- return d
-
- def test_update_NoMatch_bb(self):
- d = self.insertTestData(self.user1_rows)
- def update3(_):
- return self.db.users.updateUser(
- uid=3, attr_type='marla', attr_data='cancer')
- d.addCallback(update3)
- def get1(_):
- return self.db.users.getUser(1)
- d.addCallback(get1)
- def check1(usdict):
- self.assertEqual(usdict['IPv9'], '0578cc6.8db024') # no change
- d.addCallback(check1)
- return d
-
- def test_removeUser_uid(self):
- d = self.insertTestData(self.user1_rows)
- def remove1(_):
- return self.db.users.removeUser(1)
- d.addCallback(remove1)
- def check1(_):
- def thd(conn):
- r = conn.execute(self.db.model.users.select())
- r = r.fetchall()
- self.assertEqual(len(r), 0)
- return self.db.pool.do(thd)
- d.addCallback(check1)
- return d
-
- def test_removeNoMatch(self):
- d = self.insertTestData(self.user1_rows)
- def check(_):
- return self.db.users.removeUser(uid=3)
- d.addCallback(check)
- return d
-
- def test_identifierToUid_NoMatch(self):
- d = self.db.users.identifierToUid(identifier="soap")
- def check(res):
- self.assertEqual(res, None)
- d.addCallback(check)
- return d
-
- def test_identifierToUid_match(self):
- d = self.insertTestData(self.user1_rows)
- def ident2uid(_):
- return self.db.users.identifierToUid(identifier="soap")
- d.addCallback(ident2uid)
- def check(res):
- self.assertEqual(res, 1)
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_master.py
deleted file mode 100644
index c170382e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_master.py
+++ /dev/null
@@ -1,567 +0,0 @@
-# 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 os
-import mock
-import signal
-from twisted.internet import defer, reactor, task
-from twisted.trial import unittest
-from twisted.python import log
-from buildbot import master, monkeypatches, config
-from buildbot.util import subscription
-from buildbot.db import connector
-from buildbot.test.util import dirs, compat, misc, logging
-from buildbot.test.fake import fakedb
-from buildbot.util import epoch2datetime
-from buildbot.changes import changes
-from buildbot.process.users import users
-
-class Subscriptions(dirs.DirsMixin, unittest.TestCase):
-
- def setUp(self):
- basedir = os.path.abspath('basedir')
- d = self.setUpDirs(basedir)
- def set_master(_):
- self.master = master.BuildMaster(basedir)
- self.master.config.db['db_poll_interval'] = None
- d.addCallback(set_master)
- return d
-
- def tearDown(self):
- return self.tearDownDirs()
-
- def test_change_subscription(self):
- changeid = 918
- chdict = {
- 'changeid': 14,
- 'author': u'warner',
- 'branch': u'warnerdb',
- 'category': u'devel',
- 'comments': u'fix whitespace',
- 'files': [u'master/buildbot/__init__.py'],
- 'is_dir': 0,
- 'project': u'Buildbot',
- 'properties': {},
- 'repository': u'git://warner',
- 'revision': u'0e92a098b',
- 'revlink': u'http://warner/0e92a098b',
- 'when_timestamp': epoch2datetime(266738404),
- }
- newchange = mock.Mock(name='newchange')
-
- # patch out everything we're about to call
- self.master.db = mock.Mock()
- self.master.db.changes.addChange.return_value = \
- defer.succeed(changeid)
- self.master.db.changes.getChange.return_value = \
- defer.succeed(chdict)
- self.patch(changes.Change, 'fromChdict',
- classmethod(lambda cls, master, chdict :
- defer.succeed(newchange)))
-
- cb = mock.Mock()
- sub = self.master.subscribeToChanges(cb)
- self.assertIsInstance(sub, subscription.Subscription)
-
- d = self.master.addChange()
- def check(change):
- # master called the right thing in the db component, including with
- # appropriate default values
- self.master.db.changes.addChange.assert_called_with(author=None,
- files=None, comments=None, is_dir=0,
- revision=None, when_timestamp=None, branch=None, codebase='',
- category=None, revlink='', properties={}, repository='', project='', uid=None)
-
- self.master.db.changes.getChange.assert_called_with(changeid)
- # addChange returned the right value
- self.failUnless(change is newchange) # fromChdict's return value
- # and the notification sub was called correctly
- cb.assert_called_with(newchange)
- d.addCallback(check)
- return d
-
- def do_test_addChange_args(self, args=(), kwargs={}, exp_db_kwargs={}):
- # add default arguments
- default_db_kwargs = dict(files=None, comments=None, author=None,
- is_dir=0, revision=None, when_timestamp=None,
- branch=None, category=None, revlink='', properties={},
- repository='', codebase='', project='', uid=None)
- k = default_db_kwargs
- k.update(exp_db_kwargs)
- exp_db_kwargs = k
-
- self.master.db = mock.Mock()
- got = []
- def db_addChange(*args, **kwargs):
- got[:] = args, kwargs
- # use an exception as a quick way to bail out of the remainder
- # of the addChange method
- return defer.fail(RuntimeError)
- self.master.db.changes.addChange = db_addChange
-
- d = self.master.addChange(*args, **kwargs)
- d.addCallback(lambda _ : self.fail("should not succeed"))
- def check(f):
- self.assertEqual(got, [(), exp_db_kwargs])
- d.addErrback(check)
- return d
-
- def test_addChange_args_author(self):
- # who should come through as author
- return self.do_test_addChange_args(
- kwargs=dict(who='me'),
- exp_db_kwargs=dict(author='me'))
-
- def test_addChange_args_isdir(self):
- # isdir should come through as is_dir
- return self.do_test_addChange_args(
- kwargs=dict(isdir=1),
- exp_db_kwargs=dict(is_dir=1))
-
- def test_addChange_args_when(self):
- # when should come through as when_timestamp, as a datetime
- return self.do_test_addChange_args(
- kwargs=dict(when=892293875),
- exp_db_kwargs=dict(when_timestamp=epoch2datetime(892293875)))
-
- def test_addChange_args_properties(self):
- # properties should be qualified with a source
- return self.do_test_addChange_args(
- kwargs=dict(properties={ 'a' : 'b' }),
- exp_db_kwargs=dict(properties={ 'a' : ('b', 'Change') }))
-
- def test_addChange_args_properties_tuple(self):
- # properties should be qualified with a source, even if they
- # already look like they have a source
- return self.do_test_addChange_args(
- kwargs=dict(properties={ 'a' : ('b', 'Change') }),
- exp_db_kwargs=dict(properties={
- 'a' : (('b', 'Change'), 'Change') }))
-
- def test_addChange_args_positional(self):
- # master.addChange can take author, files, comments as positional
- # arguments
- return self.do_test_addChange_args(
- args=('me', ['a'], 'com'),
- exp_db_kwargs=dict(author='me', files=['a'], comments='com'))
-
- def do_test_createUserObjects_args(self, args=(), kwargs={}, exp_args=()):
- got = []
- def fake_createUserObject(*args, **kwargs):
- got[:] = args, kwargs
- # use an exception as a quick way to bail out of the remainder
- # of the createUserObject method
- return defer.fail(RuntimeError)
-
- self.patch(users, 'createUserObject', fake_createUserObject)
-
- d = self.master.addChange(*args, **kwargs)
- d.addCallback(lambda _ : self.fail("should not succeed"))
- def check(f):
- self.assertEqual(got, [exp_args, {}])
- d.addErrback(check)
- return d
-
- def test_addChange_createUserObject_args(self):
- # who should come through as author
- return self.do_test_createUserObjects_args(
- kwargs=dict(who='me', src='git'),
- exp_args=(self.master, 'me', 'git'))
-
- def test_buildset_subscription(self):
- self.master.db = mock.Mock()
- self.master.db.buildsets.addBuildset.return_value = \
- defer.succeed((938593, dict(a=19,b=20)))
-
- cb = mock.Mock()
- sub = self.master.subscribeToBuildsets(cb)
- self.assertIsInstance(sub, subscription.Subscription)
-
- d = self.master.addBuildset(ssid=999)
- def check((bsid,brids)):
- # master called the right thing in the db component
- self.master.db.buildsets.addBuildset.assert_called_with(ssid=999)
- # addBuildset returned the right value
- self.assertEqual((bsid,brids), (938593, dict(a=19,b=20)))
- # and the notification sub was called correctly
- cb.assert_called_with(bsid=938593, ssid=999)
- d.addCallback(check)
- return d
-
- def test_buildset_completion_subscription(self):
- self.master.db = mock.Mock()
-
- cb = mock.Mock()
- sub = self.master.subscribeToBuildsetCompletions(cb)
- self.assertIsInstance(sub, subscription.Subscription)
-
- self.master._buildsetComplete(938593, 999)
- # assert the notification sub was called correctly
- cb.assert_called_with(938593, 999)
-
-class StartupAndReconfig(dirs.DirsMixin, logging.LoggingMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpLogging()
- self.basedir = os.path.abspath('basedir')
- d = self.setUpDirs(self.basedir)
- @d.addCallback
- def make_master(_):
- # don't create child services
- self.patch(master.BuildMaster, 'create_child_services',
- lambda self : None)
-
- # patch out a few other annoying things the master likes to do
- self.patch(monkeypatches, 'patch_all', lambda : None)
- self.patch(signal, 'signal', lambda sig, hdlr : None)
- self.patch(master, 'Status', lambda master : mock.Mock()) # XXX temporary
- self.patch(config.MasterConfig, 'loadConfig',
- classmethod(lambda cls, b, f : cls()))
-
- self.master = master.BuildMaster(self.basedir)
- self.db = self.master.db = fakedb.FakeDBConnector(self)
-
- return d
-
- def tearDown(self):
- return self.tearDownDirs()
-
- def make_reactor(self):
- r = mock.Mock()
- r.callWhenRunning = reactor.callWhenRunning
- return r
-
- def patch_loadConfig_fail(self):
- @classmethod
- def loadConfig(cls, b, f):
- config.error('oh noes')
- self.patch(config.MasterConfig, 'loadConfig', loadConfig)
-
-
- # tests
-
- def test_startup_bad_config(self):
- reactor = self.make_reactor()
- self.patch_loadConfig_fail()
-
- d = self.master.startService(_reactor=reactor)
-
- @d.addCallback
- def check(_):
- reactor.stop.assert_called()
- self.assertLogged("oh noes")
- return d
-
- def test_startup_db_not_ready(self):
- reactor = self.make_reactor()
- def db_setup():
- log.msg("GOT HERE")
- raise connector.DatabaseNotReadyError()
- self.db.setup = db_setup
-
- d = self.master.startService(_reactor=reactor)
-
- @d.addCallback
- def check(_):
- reactor.stop.assert_called()
- self.assertLogged("GOT HERE")
- return d
-
- @compat.usesFlushLoggedErrors
- def test_startup_error(self):
- reactor = self.make_reactor()
- def db_setup():
- raise RuntimeError("oh noes")
- self.db.setup = db_setup
-
- d = self.master.startService(_reactor=reactor)
-
- @d.addCallback
- def check(_):
- reactor.stop.assert_called()
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
- return d
-
- def test_startup_ok(self):
- reactor = self.make_reactor()
-
- d = self.master.startService(_reactor=reactor)
- d.addCallback(lambda _ : self.master.stopService())
-
- @d.addCallback
- def check(_):
- self.failIf(reactor.stop.called)
- self.assertLogged("BuildMaster is running")
- return d
-
- def test_reconfig(self):
- reactor = self.make_reactor()
- self.master.reconfigService = mock.Mock(
- side_effect=lambda n : defer.succeed(None))
-
- d = self.master.startService(_reactor=reactor)
- d.addCallback(lambda _ : self.master.reconfig())
- d.addCallback(lambda _ : self.master.stopService())
-
- @d.addCallback
- def check(_):
- self.master.reconfigService.assert_called()
- return d
-
- @defer.inlineCallbacks
- def test_reconfig_bad_config(self):
- reactor = self.make_reactor()
- self.master.reconfigService = mock.Mock(
- side_effect=lambda n : defer.succeed(None))
-
- yield self.master.startService(_reactor=reactor)
-
- # reset, since startService called reconfigService
- self.master.reconfigService.reset_mock()
-
- # reconfig, with a failure
- self.patch_loadConfig_fail()
- yield self.master.reconfig()
-
- self.master.stopService()
-
- self.assertLogged("reconfig aborted without")
- self.failIf(self.master.reconfigService.called)
-
- @defer.inlineCallbacks
- def test_reconfigService_db_url_changed(self):
- old = self.master.config = config.MasterConfig()
- old.db['db_url'] = 'aaaa'
- yield self.master.reconfigService(old)
-
- new = config.MasterConfig()
- new.db['db_url'] = 'bbbb'
-
- self.assertRaises(config.ConfigErrors, lambda :
- self.master.reconfigService(new))
-
- def test_reconfigService_start_polling(self):
- loopingcall = mock.Mock()
- self.patch(task, 'LoopingCall', lambda fn : loopingcall)
-
- self.master.config = config.MasterConfig()
- new = config.MasterConfig()
- new.db['db_poll_interval'] = 120
-
- d = self.master.reconfigService(new)
- @d.addCallback
- def check(_):
- loopingcall.start.assert_called_with(120, now=False)
- return d
-
- @defer.inlineCallbacks
- def test_reconfigService_stop_polling(self):
- db_loop = self.master.db_loop = mock.Mock()
-
- old = self.master.config = config.MasterConfig()
- old.db['db_poll_interval'] = 120
- yield self.master.reconfigService(old)
-
- new = config.MasterConfig()
- new.db['db_poll_interval'] = None
- yield self.master.reconfigService(new)
-
- db_loop.stop.assert_called()
- self.assertEqual(self.master.db_loop, None)
-
-
-class Polling(dirs.DirsMixin, misc.PatcherMixin, unittest.TestCase):
-
- def setUp(self):
- self.gotten_changes = []
- self.gotten_buildset_additions = []
- self.gotten_buildset_completions = []
- self.gotten_buildrequest_additions = []
-
-
- basedir = os.path.abspath('basedir')
-
- # patch out os.uname so that we get a consistent hostname
- self.patch_os_uname(lambda : [ 0, 'testhost.localdomain' ])
- self.master_name = "testhost.localdomain:%s" % (basedir,)
-
- d = self.setUpDirs(basedir)
- def set_master(_):
- self.master = master.BuildMaster(basedir)
-
- self.db = self.master.db = fakedb.FakeDBConnector(self)
-
- self.master.config.db['db_poll_interval'] = 10
-
- # overridesubscription callbacks
- self.master._change_subs = sub = mock.Mock()
- sub.deliver = self.deliverChange
- self.master._new_buildset_subs = sub = mock.Mock()
- sub.deliver = self.deliverBuildsetAddition
- self.master._complete_buildset_subs = sub = mock.Mock()
- sub.deliver = self.deliverBuildsetCompletion
- self.master._new_buildrequest_subs = sub = mock.Mock()
- sub.deliver = self.deliverBuildRequestAddition
-
- d.addCallback(set_master)
- return d
-
- def tearDown(self):
- return self.tearDownDirs()
-
- def deliverChange(self, change):
- self.gotten_changes.append(change)
-
- def deliverBuildsetAddition(self, **kwargs):
- self.gotten_buildset_additions.append(kwargs)
-
- def deliverBuildsetCompletion(self, bsid, result):
- self.gotten_buildset_completions.append((bsid, result))
-
- def deliverBuildRequestAddition(self, notif):
- self.gotten_buildrequest_additions.append(notif)
-
- # tests
-
- def test_pollDatabaseChanges_empty(self):
- self.db.insertTestData([
- fakedb.Object(id=22, name=self.master_name,
- class_name='buildbot.master.BuildMaster'),
- ])
- d = self.master.pollDatabaseChanges()
- def check(_):
- self.assertEqual(self.gotten_changes, [])
- self.assertEqual(self.gotten_buildset_additions, [])
- self.assertEqual(self.gotten_buildset_completions, [])
- self.db.state.assertState(22, last_processed_change=0)
- d.addCallback(check)
- return d
-
- def test_pollDatabaseChanges_catchup(self):
- # with no existing state, it should catch up to the most recent change,
- # but not process anything
- self.db.insertTestData([
- fakedb.Object(id=22, name=self.master_name,
- class_name='buildbot.master.BuildMaster'),
- fakedb.Change(changeid=10),
- fakedb.Change(changeid=11),
- ])
- d = self.master.pollDatabaseChanges()
- def check(_):
- self.assertEqual(self.gotten_changes, [])
- self.assertEqual(self.gotten_buildset_additions, [])
- self.assertEqual(self.gotten_buildset_completions, [])
- self.db.state.assertState(22, last_processed_change=11)
- d.addCallback(check)
- return d
-
- def test_pollDatabaseChanges_multiple(self):
- self.db.insertTestData([
- fakedb.Object(id=53, name=self.master_name,
- class_name='buildbot.master.BuildMaster'),
- fakedb.ObjectState(objectid=53, name='last_processed_change',
- value_json='10'),
- fakedb.Change(changeid=10),
- fakedb.Change(changeid=11),
- fakedb.Change(changeid=12),
- ])
- d = self.master.pollDatabaseChanges()
- def check(_):
- self.assertEqual([ ch.number for ch in self.gotten_changes],
- [ 11, 12 ]) # note 10 was already seen
- self.assertEqual(self.gotten_buildset_additions, [])
- self.assertEqual(self.gotten_buildset_completions, [])
- self.db.state.assertState(53, last_processed_change=12)
- d.addCallback(check)
- return d
-
- def test_pollDatabaseChanges_nothing_new(self):
- self.db.insertTestData([
- fakedb.Object(id=53, name='master',
- class_name='buildbot.master.BuildMaster'),
- fakedb.ObjectState(objectid=53, name='last_processed_change',
- value_json='10'),
- fakedb.Change(changeid=10),
- ])
- d = self.master.pollDatabaseChanges()
- def check(_):
- self.assertEqual(self.gotten_changes, [])
- self.assertEqual(self.gotten_buildset_additions, [])
- self.assertEqual(self.gotten_buildset_completions, [])
- self.db.state.assertState(53, last_processed_change=10)
- d.addCallback(check)
- return d
-
- def test_pollDatabaseBuildRequests_empty(self):
- d = self.master.pollDatabaseBuildRequests()
- def check(_):
- self.assertEqual(self.gotten_buildrequest_additions, [])
- d.addCallback(check)
- return d
-
- def test_pollDatabaseBuildRequests_new(self):
- self.db.insertTestData([
- fakedb.SourceStampSet(id=127),
- fakedb.SourceStamp(id=127, sourcestampsetid=127),
- fakedb.Buildset(id=99, sourcestampsetid=127),
- fakedb.BuildRequest(id=19, buildsetid=99, buildername='9teen'),
- fakedb.BuildRequest(id=20, buildsetid=99, buildername='twenty')
- ])
- d = self.master.pollDatabaseBuildRequests()
- def check(_):
- self.assertEqual(sorted(self.gotten_buildrequest_additions),
- sorted([dict(bsid=99, brid=19, buildername='9teen'),
- dict(bsid=99, brid=20, buildername='twenty')]))
- d.addCallback(check)
- return d
-
- def test_pollDatabaseBuildRequests_incremental(self):
- d = defer.succeed(None)
- def insert1(_):
- self.db.insertTestData([
- fakedb.SourceStampSet(id=127),
- fakedb.SourceStamp(id=127, sourcestampsetid=127),
- fakedb.Buildset(id=99, sourcestampsetid=127),
- fakedb.BuildRequest(id=11, buildsetid=9, buildername='eleventy'),
- ])
- d.addCallback(insert1)
- d.addCallback(lambda _ : self.master.pollDatabaseBuildRequests())
- def insert2_and_claim(_):
- self.gotten_buildrequest_additions.append('MARK')
- self.db.insertTestData([
- fakedb.BuildRequest(id=20, buildsetid=9,
- buildername='twenty'),
- ])
- self.db.buildrequests.fakeClaimBuildRequest(11)
- d.addCallback(insert2_and_claim)
- d.addCallback(lambda _ : self.master.pollDatabaseBuildRequests())
- def unclaim(_):
- self.gotten_buildrequest_additions.append('MARK')
- self.db.buildrequests.fakeUnclaimBuildRequest(11)
- # note that at this point brid 20 is still unclaimed, but we do
- # not get a new notification about it
- d.addCallback(unclaim)
- d.addCallback(lambda _ : self.master.pollDatabaseBuildRequests())
- def check(_):
- self.assertEqual(self.gotten_buildrequest_additions, [
- dict(bsid=9, brid=11, buildername='eleventy'),
- 'MARK',
- dict(bsid=9, brid=20, buildername='twenty'),
- 'MARK',
- dict(bsid=9, brid=11, buildername='eleventy'),
- ])
- d.addCallback(check)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_pbmanager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_pbmanager.py
deleted file mode 100644
index 032c8ff9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_pbmanager.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# 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
-
-# Test clean shutdown functionality of the master
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from twisted.spread import pb
-from twisted.cred import credentials
-from buildbot import pbmanager
-
-class TestPBManager(unittest.TestCase):
-
- def setUp(self):
- self.pbm = pbmanager.PBManager()
- self.pbm.startService()
- self.connections = []
-
- def tearDown(self):
- return self.pbm.stopService()
-
- def perspectiveFactory(self, mind, username):
- persp = mock.Mock()
- persp.is_my_persp = True
- persp.attached = lambda mind : defer.succeed(None)
- self.connections.append(username)
- return defer.succeed(persp)
-
- def test_repr(self):
- reg = self.pbm.register('tcp:0:interface=127.0.0.1', "x", "y", self.perspectiveFactory)
- self.assertEqual(`self.pbm.dispatchers['tcp:0:interface=127.0.0.1']`,
- '<pbmanager.Dispatcher for x on tcp:0:interface=127.0.0.1>')
- self.assertEqual(`reg`, '<pbmanager.Registration for x on tcp:0:interface=127.0.0.1>')
-
- def test_register_unregister(self):
- portstr = "tcp:0:interface=127.0.0.1"
- reg = self.pbm.register(portstr, "boris", "pass", self.perspectiveFactory)
-
- # make sure things look right
- self.assertIn(portstr, self.pbm.dispatchers)
- disp = self.pbm.dispatchers[portstr]
- self.assertIn('boris', disp.users)
-
- # we can't actually connect to it, as that requires finding the
- # dynamically allocated port number which is buried out of reach;
- # however, we can try the requestAvatar and requestAvatarId methods.
-
- d = disp.requestAvatarId(credentials.UsernamePassword('boris', 'pass'))
- def check_avatarid(username):
- self.assertEqual(username, 'boris')
- d.addCallback(check_avatarid)
- d.addCallback(lambda _ :
- disp.requestAvatar('boris', mock.Mock(), pb.IPerspective))
- def check_avatar((iface, persp, detach_fn)):
- self.failUnless(persp.is_my_persp)
- self.assertIn('boris', self.connections)
- d.addCallback(check_avatar)
-
- d.addCallback(lambda _ : reg.unregister())
- return d
-
- def test_double_register_unregister(self):
- portstr = "tcp:0:interface=127.0.0.1"
- reg1 = self.pbm.register(portstr, "boris", "pass", None)
- reg2 = self.pbm.register(portstr, "ivona", "pass", None)
-
- # make sure things look right
- self.assertEqual(len(self.pbm.dispatchers), 1)
- self.assertIn(portstr, self.pbm.dispatchers)
- disp = self.pbm.dispatchers[portstr]
- self.assertIn('boris', disp.users)
- self.assertIn('ivona', disp.users)
-
- d = reg1.unregister()
- def check_boris_gone(_):
- self.assertEqual(len(self.pbm.dispatchers), 1)
- self.assertIn(portstr, self.pbm.dispatchers)
- disp = self.pbm.dispatchers[portstr]
- self.assertNotIn('boris', disp.users)
- self.assertIn('ivona', disp.users)
- d.addCallback(check_boris_gone)
- d.addCallback(lambda _ : reg2.unregister())
- def check_dispatcher_gone(_):
- self.assertEqual(len(self.pbm.dispatchers), 0)
- d.addCallback(check_dispatcher_gone)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_botmaster_BotMaster.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_botmaster_BotMaster.py
deleted file mode 100644
index ff45c907..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_botmaster_BotMaster.py
+++ /dev/null
@@ -1,259 +0,0 @@
-# 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 mock
-from zope.interface import implements
-from twisted.trial import unittest
-from twisted.internet import defer
-from twisted.application import service
-from buildbot.process.botmaster import BotMaster
-from buildbot.process import factory
-from buildbot import config, interfaces
-from buildbot.test.fake import fakemaster
-
-class TestCleanShutdown(unittest.TestCase):
- def setUp(self):
- self.botmaster = BotMaster(mock.Mock())
- self.reactor = mock.Mock()
- self.botmaster.startService()
-
- def assertReactorStopped(self, _=None):
- self.assertTrue(self.reactor.stop.called)
-
- def assertReactorNotStopped(self, _=None):
- self.assertFalse(self.reactor.stop.called)
-
- def makeFakeBuild(self):
- self.fake_builder = builder = mock.Mock()
- build = mock.Mock()
- builder.builder_status.getCurrentBuilds.return_value = [build]
-
- self.build_deferred = defer.Deferred()
- build.waitUntilFinished.return_value = self.build_deferred
-
- self.botmaster.builders = mock.Mock()
- self.botmaster.builders.values.return_value = [builder]
-
- def finishFakeBuild(self):
- self.fake_builder.builder_status.getCurrentBuilds.return_value = []
- self.build_deferred.callback(None)
-
- # tests
-
- def test_shutdown_idle(self):
- """Test that the master shuts down when it's idle"""
- self.botmaster.cleanShutdown(_reactor=self.reactor)
- self.assertReactorStopped()
-
- def test_shutdown_busy(self):
- """Test that the master shuts down after builds finish"""
- self.makeFakeBuild()
-
- self.botmaster.cleanShutdown(_reactor=self.reactor)
-
- # check that we haven't stopped yet, since there's a running build
- self.assertReactorNotStopped()
-
- # try to shut it down again, just to check that this does not fail
- self.botmaster.cleanShutdown(_reactor=self.reactor)
-
- # Now we cause the build to finish
- self.finishFakeBuild()
-
- # And now we should be stopped
- self.assertReactorStopped()
-
- def test_shutdown_cancel_not_shutting_down(self):
- """Test that calling cancelCleanShutdown when none is in progress
- works"""
- # this just shouldn't fail..
- self.botmaster.cancelCleanShutdown()
-
- def test_shutdown_cancel(self):
- """Test that we can cancel a shutdown"""
- self.makeFakeBuild()
-
- self.botmaster.cleanShutdown(_reactor=self.reactor)
-
- # Next we check that we haven't stopped yet, since there's a running
- # build.
- self.assertReactorNotStopped()
-
- # but the BuildRequestDistributor should not be running
- self.assertFalse(self.botmaster.brd.running)
-
- # Cancel the shutdown
- self.botmaster.cancelCleanShutdown()
-
- # Now we cause the build to finish
- self.finishFakeBuild()
-
- # We should still be running!
- self.assertReactorNotStopped()
-
- # and the BuildRequestDistributor should be, as well
- self.assertTrue(self.botmaster.brd.running)
-
-
-class FakeBuildSlave(config.ReconfigurableServiceMixin, service.Service):
-
- implements(interfaces.IBuildSlave)
-
- reconfig_count = 0
-
- def __init__(self, slavename):
- self.slavename = slavename
-
- def reconfigService(self, new_config):
- self.reconfig_count += 1
- return defer.succeed(None)
-
-
-class FakeBuildSlave2(FakeBuildSlave):
- pass
-
-
-class TestBotMaster(unittest.TestCase):
-
- def setUp(self):
- self.master = fakemaster.make_master()
- self.botmaster = BotMaster(self.master)
- self.new_config = mock.Mock()
- self.botmaster.startService()
-
- def tearDown(self):
- return self.botmaster.stopService()
-
- def test_reconfigService(self):
- # check that reconfigServiceSlaves and reconfigServiceBuilders are
- # both called; they will be tested invidually below
- self.patch(self.botmaster, 'reconfigServiceBuilders',
- mock.Mock(side_effect=lambda c : defer.succeed(None)))
- self.patch(self.botmaster, 'reconfigServiceSlaves',
- mock.Mock(side_effect=lambda c : defer.succeed(None)))
- self.patch(self.botmaster, 'maybeStartBuildsForAllBuilders',
- mock.Mock())
-
- old_config, new_config = mock.Mock(), mock.Mock()
- d = self.botmaster.reconfigService(new_config)
- @d.addCallback
- def check(_):
- self.botmaster.reconfigServiceBuilders.assert_called_with(
- new_config)
- self.botmaster.reconfigServiceSlaves.assert_called_with(
- new_config)
- self.assertTrue(
- self.botmaster.maybeStartBuildsForAllBuilders.called)
- return d
-
- @defer.inlineCallbacks
- def test_reconfigServiceSlaves_add_remove(self):
- sl = FakeBuildSlave('sl1')
- self.new_config.slaves = [ sl ]
-
- yield self.botmaster.reconfigServiceSlaves(self.new_config)
-
- self.assertIdentical(sl.parent, self.botmaster)
- self.assertEqual(self.botmaster.slaves, { 'sl1' : sl })
-
- self.new_config.slaves = [ ]
-
- yield self.botmaster.reconfigServiceSlaves(self.new_config)
-
- self.assertIdentical(sl.parent, None)
- self.assertIdentical(sl.master, None)
-
- @defer.inlineCallbacks
- def test_reconfigServiceSlaves_reconfig(self):
- sl = FakeBuildSlave('sl1')
- self.botmaster.slaves = dict(sl1=sl)
- sl.setServiceParent(self.botmaster)
- sl.master = self.master
- sl.botmaster = self.botmaster
-
- sl_new = FakeBuildSlave('sl1')
- self.new_config.slaves = [ sl_new ]
-
- yield self.botmaster.reconfigServiceSlaves(self.new_config)
-
- # sl was not replaced..
- self.assertIdentical(self.botmaster.slaves['sl1'], sl)
-
- @defer.inlineCallbacks
- def test_reconfigServiceSlaves_class_changes(self):
- sl = FakeBuildSlave('sl1')
- self.botmaster.slaves = dict(sl1=sl)
- sl.setServiceParent(self.botmaster)
- sl.master = self.master
- sl.botmaster = self.botmaster
-
- sl_new = FakeBuildSlave2('sl1')
- self.new_config.slaves = [ sl_new ]
-
- yield self.botmaster.reconfigServiceSlaves(self.new_config)
-
- # sl *was* replaced (different class)
- self.assertIdentical(self.botmaster.slaves['sl1'], sl_new)
-
- @defer.inlineCallbacks
- def test_reconfigServiceBuilders_add_remove(self):
- bc = config.BuilderConfig(name='bldr', factory=factory.BuildFactory(),
- slavename='f')
- self.new_config.builders = [ bc ]
-
- yield self.botmaster.reconfigServiceBuilders(self.new_config)
-
- bldr = self.botmaster.builders['bldr']
- self.assertIdentical(bldr.parent, self.botmaster)
- self.assertIdentical(bldr.master, self.master)
- self.assertEqual(self.botmaster.builderNames, [ 'bldr' ])
-
- self.new_config.builders = [ ]
-
- yield self.botmaster.reconfigServiceBuilders(self.new_config)
-
- self.assertIdentical(bldr.parent, None)
- self.assertIdentical(bldr.master, None)
- self.assertEqual(self.botmaster.builders, {})
- self.assertEqual(self.botmaster.builderNames, [])
-
- def test_maybeStartBuildsForBuilder(self):
- brd = self.botmaster.brd = mock.Mock()
-
- self.botmaster.maybeStartBuildsForBuilder('frank')
-
- brd.maybeStartBuildsOn.assert_called_once_with(['frank'])
-
- def test_maybeStartBuildsForSlave(self):
- brd = self.botmaster.brd = mock.Mock()
- b1 = mock.Mock(name='frank')
- b1.name = 'frank'
- b2 = mock.Mock(name='larry')
- b2.name = 'larry'
- self.botmaster.getBuildersForSlave = mock.Mock(return_value=[b1, b2])
-
- self.botmaster.maybeStartBuildsForSlave('centos')
-
- self.botmaster.getBuildersForSlave.assert_called_once_with('centos')
- brd.maybeStartBuildsOn.assert_called_once_with(['frank', 'larry'])
-
- def test_maybeStartBuildsForAll(self):
- brd = self.botmaster.brd = mock.Mock()
- self.botmaster.builderNames = ['frank', 'larry']
-
- self.botmaster.maybeStartBuildsForAllBuilders()
-
- brd.maybeStartBuildsOn.assert_called_once_with(['frank', 'larry'])
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_botmaster_DuplicateSlaveArbitrator.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_botmaster_DuplicateSlaveArbitrator.py
deleted file mode 100644
index 34e5af1e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_botmaster_DuplicateSlaveArbitrator.py
+++ /dev/null
@@ -1,213 +0,0 @@
-# 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 mock
-from twisted.python import failure, log
-from twisted.trial import unittest
-from twisted.internet import defer, reactor, task
-from twisted.spread import pb
-from buildbot.test.util import compat
-from buildbot.process import botmaster
-from buildbot.util.eventual import eventually
-
-# TODO: should do this with more of the Twisted machinery intact - maybe in a
-# separate integration test?
-
-class FakeAbstractBuildSlave(object):
-
- def __init__(self, slave, name, isConnected=True, reactor=reactor):
- self.slavename = name
- self.slave = slave
- self.isConnectedResult = isConnected
- self.reactor = reactor
- self.call_on_detach = lambda : None
-
- # set up for loseConnection to cause the slave to detach, but not
- # immediately
- def tport_loseConnection():
- self.isConnectedResult = False
- self.call_on_detach()
- self.call_on_detach = None
- self.slave.broker.transport.loseConnection = (lambda :
- eventually(tport_loseConnection))
-
- def subscribeToDetach(self, callback):
- self.call_on_detach = callback
-
- def isConnected(self):
- return self.isConnectedResult
-
-
-class FakeRemoteBuildSlave(object):
-
- def __init__(self, name, callRemoteFailure=False,
- callRemoteException=False,
- callRemoteHang=0,
- reactor=reactor):
- self.name = name
- self.callRemoteFailure = callRemoteFailure
- self.callRemoteException = callRemoteException
- self.callRemoteHang = callRemoteHang
- self.reactor = reactor
-
- self.broker = mock.Mock()
- self.broker.transport.getPeer = lambda : "<peer %s>" % name
-
- def _makePingResult(self):
- if self.callRemoteException:
- exc = self.callRemoteException()
- log.msg(" -> exception %r" % (exc,))
- raise exc
- if self.callRemoteFailure:
- f = defer.fail(self.callRemoteFailure())
- log.msg(" -> failure %r" % (f,))
- return f
- return defer.succeed(None)
-
- def callRemote(self, meth, *args, **kwargs):
- assert meth == "print"
- log.msg("%r.callRemote('print', %r)" % (self, args[0],))
- # if we're asked to hang, then set up to fire the deferred later
- if self.callRemoteHang:
- log.msg(" -> hang for %d s" % (self.callRemoteHang,))
- d = defer.Deferred()
- self.reactor.callLater(self.callRemoteHang, d.callback, None)
- def hangdone(_):
- log.msg("%r.callRemote hang finished" % (self,))
- return self._makePingResult()
- d.addCallback(hangdone)
- self.callRemote_d = d
- # otherwise, return a fired deferred
- else:
- self.callRemote_d = self._makePingResult()
- return self.callRemote_d
-
- def __repr__(self):
- return "<FakeRemoteBuildSlave %s>" % (self.name,)
-
-
-class DuplicateSlaveArbitrator(unittest.TestCase):
-
- def makeDeadReferenceError(self):
- return pb.DeadReferenceError("Calling Stale Broker (fake exception)")
-
- def makeRuntimeError(self):
- return RuntimeError("oh noes!")
-
- def makePBConnectionLostFailure(self):
- return failure.Failure(pb.PBConnectionLost("gone"))
-
- def test_old_slave_present(self):
- old_remote = FakeRemoteBuildSlave("old")
- new_remote = FakeRemoteBuildSlave("new")
- buildslave = FakeAbstractBuildSlave(old_remote, name="testslave")
- arb = botmaster.DuplicateSlaveArbitrator(buildslave)
- d = arb.getPerspective(new_remote, "testslave")
- def got_persp(bs):
- self.fail("shouldn't get here")
- def failed(f):
- f.trap(RuntimeError) # expected error
- d.addCallbacks(got_persp, failed)
- return d
-
- def test_old_slave_absent_deadref_exc(self):
- old_remote = FakeRemoteBuildSlave("old",
- callRemoteException=self.makeDeadReferenceError)
- new_remote = FakeRemoteBuildSlave("new")
- buildslave = FakeAbstractBuildSlave(old_remote, name="testslave")
- arb = botmaster.DuplicateSlaveArbitrator(buildslave)
- d = arb.getPerspective(new_remote, "testslave")
- def got_persp(bs):
- self.assertIdentical(bs, buildslave)
- d.addCallback(got_persp)
- return d
-
- def test_old_slave_absent_connlost_failure(self):
- old_remote = FakeRemoteBuildSlave("old",
- callRemoteFailure=self.makePBConnectionLostFailure)
- new_remote = FakeRemoteBuildSlave("new")
- buildslave = FakeAbstractBuildSlave(old_remote, name="testslave")
- arb = botmaster.DuplicateSlaveArbitrator(buildslave)
- d = arb.getPerspective(new_remote, "testslave")
- def got_persp(bs):
- self.assertIdentical(bs, buildslave)
- d.addCallback(got_persp)
- return d
-
- @compat.usesFlushLoggedErrors
- def test_old_slave_absent_unexpected_exc(self):
- old_remote = FakeRemoteBuildSlave("old",
- callRemoteException=self.makeRuntimeError)
- new_remote = FakeRemoteBuildSlave("new")
- buildslave = FakeAbstractBuildSlave(old_remote, name="testslave")
- arb = botmaster.DuplicateSlaveArbitrator(buildslave)
- d = arb.getPerspective(new_remote, "testslave")
- def got_persp(bs):
- # getPerspective has returned successfully:
- self.assertIdentical(bs, buildslave)
- # and the unexpected RuntimeError was logged:
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
- d.addCallback(got_persp)
- return d
-
- def do_test_old_slave_absent_timeout(self, callRemoteException=None):
- clock = task.Clock()
- PING_TIMEOUT = botmaster.DuplicateSlaveArbitrator.PING_TIMEOUT
-
- old_remote = FakeRemoteBuildSlave("old", reactor=clock,
- callRemoteHang=PING_TIMEOUT+1,
- callRemoteException=callRemoteException)
- new_remote = FakeRemoteBuildSlave("new")
- buildslave = FakeAbstractBuildSlave(old_remote, name="testslave",
- reactor=clock)
- arb = botmaster.DuplicateSlaveArbitrator(buildslave)
- arb._reactor = clock
- d = arb.getPerspective(new_remote, "testslave")
- def got_persp(bs):
- self.assertIdentical(bs, buildslave)
- d.addCallback(got_persp)
-
- # show the passage of time for 2s more than the PING_TIMEOUT, to allow
- # the old callRemote to return eventually
- clock.pump([.1] * 10 * (PING_TIMEOUT+4))
-
- # check that the timed-out call eventually returned (and was ignored,
- # even if there was an exception)
- self.failUnless(old_remote.callRemote_d.called)
-
- return d
-
- def test_old_slave_absent_timeout(self):
- return self.do_test_old_slave_absent_timeout()
-
- def test_old_slave_absent_timeout_exc(self):
- return self.do_test_old_slave_absent_timeout(
- callRemoteException=self.makeRuntimeError)
-
- @compat.usesFlushLoggedErrors
- def test_new_slave_ping_error(self):
- old_remote = FakeRemoteBuildSlave("old")
- new_remote = FakeRemoteBuildSlave("new",
- callRemoteException=self.makeRuntimeError)
- buildslave = FakeAbstractBuildSlave(old_remote, name="testslave")
- arb = botmaster.DuplicateSlaveArbitrator(buildslave)
- d = arb.getPerspective(new_remote, "testslave")
- def got_persp(bs):
- self.fail("shouldn't get here")
- def failed(f):
- pass #f.trap(RuntimeError) # expected error
- d.addCallbacks(got_persp, failed)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_build.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_build.py
deleted file mode 100644
index 784ea172..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_build.py
+++ /dev/null
@@ -1,823 +0,0 @@
-# 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
-
-from zope.interface import implements
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot import interfaces
-from buildbot.process.build import Build
-from buildbot.process.properties import Properties
-from buildbot.status.results import FAILURE, SUCCESS, WARNINGS, RETRY, EXCEPTION
-from buildbot.locks import SlaveLock
-from buildbot.process.buildstep import LoggingBuildStep
-from buildbot.test.fake.fakemaster import FakeBotMaster
-from buildbot import config
-
-from mock import Mock
-
-class FakeChange:
- properties = Properties()
- def __init__(self, number = None):
- self.number = number
- self.who = "me"
-
-class FakeSource:
- def __init__(self):
- self.sourcestampsetid = None
- self.changes = []
- self.branch = None
- self.revision = None
- self.repository = ''
- self.codebase = ''
- self.project = ''
- self.patch_info = None
- self.patch = None
-
- def getRepository(self):
- return self.repository
-
-class FakeRequest:
- def __init__(self):
- self.sources = []
- self.reason = "Because"
- self.properties = Properties()
-
- def mergeSourceStampsWith(self, others):
- return self.sources
-
- def mergeReasons(self, others):
- return self.reason
-
-class FakeBuildStep:
- def __init__(self):
- self.haltOnFailure = False
- self.flunkOnWarnings = False
- self.flunkOnFailure = True
- self.warnOnWarnings = True
- self.warnOnFailure = False
- self.alwaysRun = False
- self.name = 'fake'
-
-class FakeMaster:
- def __init__(self):
- self.locks = {}
- self.parent = Mock()
- self.config = config.MasterConfig()
-
- def getLockByID(self, lockid):
- if not lockid in self.locks:
- self.locks[lockid] = lockid.lockClass(lockid)
- return self.locks[lockid]
-
-class FakeBuildStatus(Mock):
- implements(interfaces.IProperties)
-
-class FakeBuilderStatus:
- implements(interfaces.IBuilderStatus)
-
-class FakeStepFactory(object):
- """Fake step factory that just returns a fixed step object."""
- implements(interfaces.IBuildStepFactory)
- def __init__(self, step):
- self.step = step
-
- def buildStep(self):
- return self.step
-
-class TestBuild(unittest.TestCase):
-
- def setUp(self):
- r = FakeRequest()
- r.sources = [FakeSource()]
- r.sources[0].changes = [FakeChange()]
- r.sources[0].revision = "12345"
-
- self.request = r
- self.master = FakeMaster()
-
- self.master.botmaster = FakeBotMaster(master=self.master)
-
- self.builder = self.createBuilder()
- self.build = Build([r])
- self.build.setBuilder(self.builder)
-
- def createBuilder(self):
- bldr = Mock()
- bldr.botmaster = self.master.botmaster
- return bldr
-
- def testRunSuccessfulBuild(self):
- b = self.build
-
- step = Mock()
- step.return_value = step
- step.startStep.return_value = SUCCESS
- b.setStepFactories([FakeStepFactory(step)])
-
- slavebuilder = Mock()
-
- b.startBuild(FakeBuildStatus(), None, slavebuilder)
-
- self.assertEqual(b.result, SUCCESS)
- self.assert_( ('startStep', (slavebuilder.remote,), {})
- in step.method_calls)
-
- def testStopBuild(self):
- b = self.build
-
- step = Mock()
- step.return_value = step
- b.setStepFactories([FakeStepFactory(step)])
-
- slavebuilder = Mock()
-
- def startStep(*args, **kw):
- # Now interrupt the build
- b.stopBuild("stop it")
- return defer.Deferred()
- step.startStep = startStep
-
- b.startBuild(FakeBuildStatus(), None, slavebuilder)
-
- self.assertEqual(b.result, EXCEPTION)
-
- self.assert_( ('interrupt', ('stop it',), {}) in step.method_calls)
-
- def testAlwaysRunStepStopBuild(self):
- """Test that steps marked with alwaysRun=True still get run even if
- the build is stopped."""
-
- # Create a build with 2 steps, the first one will get interrupted, and
- # the second one is marked with alwaysRun=True
- b = self.build
-
- step1 = Mock()
- step1.return_value = step1
- step1.alwaysRun = False
- step2 = Mock()
- step2.return_value = step2
- step2.alwaysRun = True
- b.setStepFactories([
- FakeStepFactory(step1),
- FakeStepFactory(step2),
- ])
-
- slavebuilder = Mock()
-
- def startStep1(*args, **kw):
- # Now interrupt the build
- b.stopBuild("stop it")
- return defer.succeed( SUCCESS )
- step1.startStep = startStep1
- step1.stepDone.return_value = False
-
- step2Started = [False]
- def startStep2(*args, **kw):
- step2Started[0] = True
- return defer.succeed( SUCCESS )
- step2.startStep = startStep2
- step1.stepDone.return_value = False
-
- d = b.startBuild(FakeBuildStatus(), None, slavebuilder)
- def check(ign):
- self.assertEqual(b.result, EXCEPTION)
- self.assert_( ('interrupt', ('stop it',), {}) in step1.method_calls)
- self.assert_(step2Started[0])
- d.addCallback(check)
- return d
-
- def testBuildcanStartWithSlavebuilder(self):
- b = self.build
-
- slavebuilder1 = Mock()
- slavebuilder2 = Mock()
-
- l = SlaveLock('lock')
- counting_access = l.access('counting')
- real_lock = b.builder.botmaster.getLockByID(l)
-
- # no locks, so both these pass (call twice to verify there's no state/memory)
- lock_list = [(real_lock, counting_access)]
- self.assertTrue(Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
- self.assertTrue(Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
- self.assertTrue(Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
- self.assertTrue(Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
-
- slave_lock_1 = real_lock.getLock(slavebuilder1.slave)
- slave_lock_2 = real_lock.getLock(slavebuilder2.slave)
-
- # then have slavebuilder2 claim its lock:
- slave_lock_2.claim(slavebuilder2, counting_access)
- self.assertTrue(Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
- self.assertTrue(Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
- self.assertFalse(Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
- self.assertFalse(Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
- slave_lock_2.release(slavebuilder2, counting_access)
-
- # then have slavebuilder1 claim its lock:
- slave_lock_1.claim(slavebuilder1, counting_access)
- self.assertFalse(Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
- self.assertFalse(Build.canStartWithSlavebuilder(lock_list, slavebuilder1))
- self.assertTrue(Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
- self.assertTrue(Build.canStartWithSlavebuilder(lock_list, slavebuilder2))
- slave_lock_1.release(slavebuilder1, counting_access)
-
-
- def testBuildLocksAcquired(self):
- b = self.build
-
- slavebuilder = Mock()
-
- l = SlaveLock('lock')
- claimCount = [0]
- lock_access = l.access('counting')
- l.access = lambda mode: lock_access
- real_lock = b.builder.botmaster.getLockByID(l).getLock(slavebuilder.slave)
- def claim(owner, access):
- claimCount[0] += 1
- return real_lock.old_claim(owner, access)
- real_lock.old_claim = real_lock.claim
- real_lock.claim = claim
- b.setLocks([lock_access])
-
- step = Mock()
- step.return_value = step
- step.startStep.return_value = SUCCESS
- b.setStepFactories([FakeStepFactory(step)])
-
- b.startBuild(FakeBuildStatus(), None, slavebuilder)
-
- self.assertEqual(b.result, SUCCESS)
- self.assert_( ('startStep', (slavebuilder.remote,), {})
- in step.method_calls)
- self.assertEquals(claimCount[0], 1)
-
- def testBuildLocksOrder(self):
- """Test that locks are acquired in FIFO order; specifically that
- counting locks cannot jump ahead of exclusive locks"""
- eBuild = self.build
-
- cBuilder = self.createBuilder()
- cBuild = Build([self.request])
- cBuild.setBuilder(cBuilder)
-
- eSlavebuilder = Mock()
- cSlavebuilder = Mock()
-
- slave = eSlavebuilder.slave
- cSlavebuilder.slave = slave
-
- l = SlaveLock('lock', 2)
- claimLog = []
- realLock = self.master.botmaster.getLockByID(l).getLock(slave)
- def claim(owner, access):
- claimLog.append(owner)
- return realLock.oldClaim(owner, access)
- realLock.oldClaim = realLock.claim
- realLock.claim = claim
-
- eBuild.setLocks([l.access('exclusive')])
- cBuild.setLocks([l.access('counting')])
-
- fakeBuild = Mock()
- fakeBuildAccess = l.access('counting')
- realLock.claim(fakeBuild, fakeBuildAccess)
-
- step = Mock()
- step.return_value = step
- step.startStep.return_value = SUCCESS
- eBuild.setStepFactories([FakeStepFactory(step)])
- cBuild.setStepFactories([FakeStepFactory(step)])
-
- e = eBuild.startBuild(FakeBuildStatus(), None, eSlavebuilder)
- c = cBuild.startBuild(FakeBuildStatus(), None, cSlavebuilder)
- d = defer.DeferredList([e, c])
-
- realLock.release(fakeBuild, fakeBuildAccess)
-
- def check(ign):
- self.assertEqual(eBuild.result, SUCCESS)
- self.assertEqual(cBuild.result, SUCCESS)
- self.assertEquals(claimLog, [fakeBuild, eBuild, cBuild])
-
- d.addCallback(check)
- return d
-
- def testBuildWaitingForLocks(self):
- b = self.build
-
- slavebuilder = Mock()
-
- l = SlaveLock('lock')
- claimCount = [0]
- lock_access = l.access('counting')
- l.access = lambda mode: lock_access
- real_lock = b.builder.botmaster.getLockByID(l).getLock(slavebuilder.slave)
- def claim(owner, access):
- claimCount[0] += 1
- return real_lock.old_claim(owner, access)
- real_lock.old_claim = real_lock.claim
- real_lock.claim = claim
- b.setLocks([lock_access])
-
- step = Mock()
- step.return_value = step
- step.startStep.return_value = SUCCESS
- b.setStepFactories([FakeStepFactory(step)])
-
- real_lock.claim(Mock(), l.access('counting'))
-
- b.startBuild(FakeBuildStatus(), None, slavebuilder)
-
- self.assert_( ('startStep', (slavebuilder.remote,), {})
- not in step.method_calls)
- self.assertEquals(claimCount[0], 1)
- self.assert_(b.currentStep is None)
- self.assert_(b._acquiringLock is not None)
-
- def testStopBuildWaitingForLocks(self):
- b = self.build
-
- slavebuilder = Mock()
-
- l = SlaveLock('lock')
- lock_access = l.access('counting')
- l.access = lambda mode: lock_access
- real_lock = b.builder.botmaster.getLockByID(l).getLock(slavebuilder)
- b.setLocks([lock_access])
-
- step = Mock()
- step.return_value = step
- step.startStep.return_value = SUCCESS
- step.alwaysRun = False
- b.setStepFactories([FakeStepFactory(step)])
-
- real_lock.claim(Mock(), l.access('counting'))
-
- def acquireLocks(res=None):
- retval = Build.acquireLocks(b, res)
- b.stopBuild('stop it')
- return retval
- b.acquireLocks = acquireLocks
-
- b.startBuild(FakeBuildStatus(), None, slavebuilder)
-
- self.assert_( ('startStep', (slavebuilder.remote,), {})
- not in step.method_calls)
- self.assert_(b.currentStep is None)
- self.assertEqual(b.result, EXCEPTION)
- self.assert_( ('interrupt', ('stop it',), {}) not in step.method_calls)
-
- def testStopBuildWaitingForLocks_lostRemote(self):
- b = self.build
-
- slavebuilder = Mock()
-
- l = SlaveLock('lock')
- lock_access = l.access('counting')
- l.access = lambda mode: lock_access
- real_lock = b.builder.botmaster.getLockByID(l).getLock(slavebuilder)
- b.setLocks([lock_access])
-
- step = Mock()
- step.return_value = step
- step.startStep.return_value = SUCCESS
- step.alwaysRun = False
- b.setStepFactories([FakeStepFactory(step)])
-
- real_lock.claim(Mock(), l.access('counting'))
-
- def acquireLocks(res=None):
- retval = Build.acquireLocks(b, res)
- b.lostRemote()
- return retval
- b.acquireLocks = acquireLocks
-
- b.startBuild(FakeBuildStatus(), None, slavebuilder)
-
- self.assert_( ('startStep', (slavebuilder.remote,), {})
- not in step.method_calls)
- self.assert_(b.currentStep is None)
- self.assertEqual(b.result, RETRY)
- self.assert_( ('interrupt', ('stop it',), {}) not in step.method_calls)
- self.build.build_status.setText.assert_called_with(["retry", "lost", "remote"])
- self.build.build_status.setResults.assert_called_with(RETRY)
-
- def testStopBuildWaitingForStepLocks(self):
- b = self.build
-
- slavebuilder = Mock()
-
- l = SlaveLock('lock')
- lock_access = l.access('counting')
- l.access = lambda mode: lock_access
- real_lock = b.builder.botmaster.getLockByID(l).getLock(slavebuilder)
-
- step = LoggingBuildStep(locks=[lock_access])
- b.setStepFactories([FakeStepFactory(step)])
-
- real_lock.claim(Mock(), l.access('counting'))
-
- gotLocks = [False]
-
- def acquireLocks(res=None):
- gotLocks[0] = True
- retval = LoggingBuildStep.acquireLocks(step, res)
- self.assert_(b.currentStep is step)
- b.stopBuild('stop it')
- return retval
- step.acquireLocks = acquireLocks
- step.setStepStatus = Mock()
- step.step_status = Mock()
- step.step_status.addLog().chunkSize = 10
- step.step_status.getLogs.return_value = []
-
- b.startBuild(FakeBuildStatus(), None, slavebuilder)
-
- self.assertEqual(gotLocks, [True])
- self.assert_(('stepStarted', (), {}) in step.step_status.method_calls)
- self.assertEqual(b.result, EXCEPTION)
-
- def testStepDone(self):
- b = self.build
- b.results = [SUCCESS]
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- terminate = b.stepDone(SUCCESS, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, SUCCESS)
-
- def testStepDoneHaltOnFailure(self):
- b = self.build
- b.results = []
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- step.haltOnFailure = True
- terminate = b.stepDone(FAILURE, step)
- self.assertEqual(terminate, True)
- self.assertEqual(b.result, FAILURE)
-
- def testStepDoneHaltOnFailureNoFlunkOnFailure(self):
- b = self.build
- b.results = []
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- step.flunkOnFailure = False
- step.haltOnFailure = True
- terminate = b.stepDone(FAILURE, step)
- self.assertEqual(terminate, True)
- self.assertEqual(b.result, SUCCESS)
-
- def testStepDoneFlunkOnWarningsFlunkOnFailure(self):
- b = self.build
- b.results = []
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- step.flunkOnFailure = True
- step.flunkOnWarnings = True
- b.stepDone(WARNINGS, step)
- terminate = b.stepDone(FAILURE, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, FAILURE)
-
- def testStepDoneNoWarnOnWarnings(self):
- b = self.build
- b.results = [SUCCESS]
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- step.warnOnWarnings = False
- terminate = b.stepDone(WARNINGS, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, SUCCESS)
-
- def testStepDoneWarnings(self):
- b = self.build
- b.results = [SUCCESS]
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- terminate = b.stepDone(WARNINGS, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, WARNINGS)
-
- def testStepDoneFail(self):
- b = self.build
- b.results = [SUCCESS]
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- terminate = b.stepDone(FAILURE, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, FAILURE)
-
- def testStepDoneFailOverridesWarnings(self):
- b = self.build
- b.results = [SUCCESS, WARNINGS]
- b.result = WARNINGS
- b.remote = Mock()
- step = FakeBuildStep()
- terminate = b.stepDone(FAILURE, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, FAILURE)
-
- def testStepDoneWarnOnFailure(self):
- b = self.build
- b.results = [SUCCESS]
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- step.warnOnFailure = True
- step.flunkOnFailure = False
- terminate = b.stepDone(FAILURE, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, WARNINGS)
-
- def testStepDoneFlunkOnWarnings(self):
- b = self.build
- b.results = [SUCCESS]
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- step.flunkOnWarnings = True
- terminate = b.stepDone(WARNINGS, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, FAILURE)
-
- def testStepDoneHaltOnFailureFlunkOnWarnings(self):
- b = self.build
- b.results = [SUCCESS]
- b.result = SUCCESS
- b.remote = Mock()
- step = FakeBuildStep()
- step.flunkOnWarnings = True
- self.haltOnFailure = True
- terminate = b.stepDone(WARNINGS, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, FAILURE)
-
- def testStepDoneWarningsDontOverrideFailure(self):
- b = self.build
- b.results = [FAILURE]
- b.result = FAILURE
- b.remote = Mock()
- step = FakeBuildStep()
- terminate = b.stepDone(WARNINGS, step)
- self.assertEqual(terminate, False)
- self.assertEqual(b.result, FAILURE)
-
- def testStepDoneRetryOverridesAnythingElse(self):
- b = self.build
- b.results = [RETRY]
- b.result = RETRY
- b.remote = Mock()
- step = FakeBuildStep()
- step.alwaysRun = True
- b.stepDone(WARNINGS, step)
- b.stepDone(FAILURE, step)
- b.stepDone(SUCCESS, step)
- terminate = b.stepDone(EXCEPTION, step)
- self.assertEqual(terminate, True)
- self.assertEqual(b.result, RETRY)
-
-class TestMultipleSourceStamps(unittest.TestCase):
-
- def setUp(self):
- r = FakeRequest()
- s1 = FakeSource()
- s1.repository = "repoA"
- s1.codebase = "A"
- s1.changes = [FakeChange(10), FakeChange(11)]
- s1.revision = "12345"
- s2 = FakeSource()
- s2.repository = "repoB"
- s2.codebase = "B"
- s2.changes = [FakeChange(12),FakeChange(13)]
- s2.revision = "67890"
- s3 = FakeSource()
- s3.repository = "repoC"
- # no codebase defined
- s3.changes = [FakeChange(14),FakeChange(15)]
- s3.revision = "111213"
- r.sources.extend([s1,s2,s3])
-
- self.build = Build([r])
-
- def test_buildReturnSourceStamp(self):
- """
- Test that a build returns the correct sourcestamp
- """
- source1 = self.build.getSourceStamp("A")
- source2 = self.build.getSourceStamp("B")
-
- self.assertEqual( [source1.repository, source1.revision], ["repoA", "12345"])
- self.assertEqual( [source2.repository, source2.revision], ["repoB", "67890"])
-
- def test_buildReturnSourceStamp_empty_codebase(self):
- """
- Test that a build returns the correct sourcestamp if codebase is empty
- """
- codebase = ''
- source3 = self.build.getSourceStamp(codebase)
- self.assertTrue(source3 is not None)
- self.assertEqual( [source3.repository, source3.revision], ["repoC", "111213"])
-
-
-class TestBuildBlameList(unittest.TestCase):
-
- def setUp(self):
- self.sourceByMe = FakeSource()
- self.sourceByMe.repository = "repoA"
- self.sourceByMe.codebase = "A"
- self.sourceByMe.changes = [FakeChange(10), FakeChange(11)]
- self.sourceByMe.changes[0].who = "me"
- self.sourceByMe.changes[1].who = "me"
-
- self.sourceByHim = FakeSource()
- self.sourceByHim.repository = "repoB"
- self.sourceByHim.codebase = "B"
- self.sourceByHim.changes = [FakeChange(12), FakeChange(13)]
- self.sourceByHim.changes[0].who = "him"
- self.sourceByHim.changes[1].who = "him"
-
- self.patchSource = FakeSource()
- self.patchSource.repository = "repoB"
- self.patchSource.codebase = "B"
- self.patchSource.changes = []
- self.patchSource.revision = "67890"
- self.patchSource.patch_info = ("jeff", "jeff's new feature")
-
- def test_blamelist_for_changes(self):
- r = FakeRequest()
- r.sources.extend([self.sourceByMe, self.sourceByHim])
- build = Build([r])
- blamelist = build.blamelist()
- self.assertEqual(blamelist, ['him', 'me'])
-
- def test_blamelist_for_patch(self):
- r = FakeRequest()
- r.sources.extend([self.patchSource])
- build = Build([r])
- blamelist = build.blamelist()
- self.assertEqual(blamelist, ['jeff'])
-
-class TestSetupProperties_MultipleSources(unittest.TestCase):
- """
- Test that the property values, based on the available requests, are
- initialized properly
- """
- def setUp(self):
- self.props = {}
- r = FakeRequest()
- r.sources = []
- r.sources.append(FakeSource())
- r.sources[0].changes = [FakeChange()]
- r.sources[0].repository = "http://svn-repo-A"
- r.sources[0].codebase = "A"
- r.sources[0].branch = "develop"
- r.sources[0].revision = "12345"
- r.sources.append(FakeSource())
- r.sources[1].changes = [FakeChange()]
- r.sources[1].repository = "http://svn-repo-B"
- r.sources[1].codebase = "B"
- r.sources[1].revision = "34567"
- self.build = Build([r])
- self.build.setStepFactories([])
- self.builder = Mock()
- self.build.setBuilder(self.builder)
- self.build.build_status = FakeBuildStatus()
- # record properties that will be set
- self.build.build_status.setProperty = self.setProperty
-
- def setProperty(self, n,v,s, runtime = False):
- if s not in self.props:
- self.props[s] = {}
- if not self.props[s]:
- self.props[s] = {}
- self.props[s][n] = v
-
- def test_sourcestamp_properties_not_set(self):
- self.build.setupProperties()
- self.assertTrue("codebase" not in self.props["Build"])
- self.assertTrue("revision" not in self.props["Build"])
- self.assertTrue("branch" not in self.props["Build"])
- self.assertTrue("project" not in self.props["Build"])
- self.assertTrue("repository" not in self.props["Build"])
-
-class TestSetupProperties_SingleSource(unittest.TestCase):
- """
- Test that the property values, based on the available requests, are
- initialized properly
- """
- def setUp(self):
- self.props = {}
- r = FakeRequest()
- r.sources = []
- r.sources.append(FakeSource())
- r.sources[0].changes = [FakeChange()]
- r.sources[0].repository = "http://svn-repo-A"
- r.sources[0].codebase = "A"
- r.sources[0].branch = "develop"
- r.sources[0].revision = "12345"
- self.build = Build([r])
- self.build.setStepFactories([])
- self.builder = Mock()
- self.build.setBuilder(self.builder)
- self.build.build_status = FakeBuildStatus()
- # record properties that will be set
- self.build.build_status.setProperty = self.setProperty
-
- def setProperty(self, n,v,s, runtime = False):
- if s not in self.props:
- self.props[s] = {}
- if not self.props[s]:
- self.props[s] = {}
- self.props[s][n] = v
-
- def test_properties_codebase(self):
- self.build.setupProperties()
- codebase = self.props["Build"]["codebase"]
- self.assertEqual(codebase, "A")
-
- def test_properties_repository(self):
- self.build.setupProperties()
- repository = self.props["Build"]["repository"]
- self.assertEqual(repository, "http://svn-repo-A")
-
- def test_properties_revision(self):
- self.build.setupProperties()
- revision = self.props["Build"]["revision"]
- self.assertEqual(revision, "12345")
-
- def test_properties_branch(self):
- self.build.setupProperties()
- branch = self.props["Build"]["branch"]
- self.assertEqual(branch, "develop")
-
- def test_property_project(self):
- self.build.setupProperties()
- project = self.props["Build"]["project"]
- self.assertEqual(project, '')
-
-class TestBuildProperties(unittest.TestCase):
- """
- Test that a Build has the necessary L{IProperties} methods, and that they
- properly delegate to the C{build_status} attribute - so really just a test
- of the L{IProperties} adapter.
- """
-
- def setUp(self):
- r = FakeRequest()
- r.sources = [FakeSource()]
- r.sources[0].changes = [FakeChange()]
- r.sources[0].revision = "12345"
- self.build = Build([r])
- self.build.setStepFactories([])
- self.builder = Mock()
- self.build.setBuilder(self.builder)
- self.build_status = FakeBuildStatus()
- self.build.startBuild(self.build_status, None, Mock())
-
- def test_getProperty(self):
- self.build.getProperty('x')
- self.build_status.getProperty.assert_called_with('x', None)
-
- def test_getProperty_default(self):
- self.build.getProperty('x', 'nox')
- self.build_status.getProperty.assert_called_with('x', 'nox')
-
- def test_setProperty(self):
- self.build.setProperty('n', 'v', 's')
- self.build_status.setProperty.assert_called_with('n', 'v', 's',
- runtime=True)
-
- def test_hasProperty(self):
- self.build_status.hasProperty.return_value = True
- self.assertTrue(self.build.hasProperty('p'))
- self.build_status.hasProperty.assert_called_with('p')
-
- def test_has_key(self):
- self.build_status.has_key.return_value = True
- self.assertTrue(self.build.has_key('p'))
- # has_key calls through to hasProperty
- self.build_status.hasProperty.assert_called_with('p')
-
- def test_render(self):
- self.build.render("xyz")
- self.build_status.render.assert_called_with("xyz")
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_builder.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_builder.py
deleted file mode 100644
index 462b5694..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_builder.py
+++ /dev/null
@@ -1,427 +0,0 @@
-# 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 mock
-import random
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot import config
-from buildbot.test.fake import fakedb, fakemaster
-from buildbot.process import builder, factory
-from buildbot.util import epoch2datetime
-
-class BuilderMixin(object):
- def makeBuilder(self, name="bldr", patch_random=False, **config_kwargs):
- """Set up C{self.bldr}"""
- self.factory = factory.BuildFactory()
- self.master = fakemaster.make_master()
- # only include the necessary required config, plus user-requested
- config_args = dict(name=name, slavename="slv", builddir="bdir",
- slavebuilddir="sbdir", factory=self.factory)
- config_args.update(config_kwargs)
- self.builder_config = config.BuilderConfig(**config_args)
- self.bldr = builder.Builder(self.builder_config.name, _addServices=False)
- self.master.db = self.db = fakedb.FakeDBConnector(self)
- self.bldr.master = self.master
- self.bldr.botmaster = self.master.botmaster
-
- # patch into the _startBuildsFor method
- self.builds_started = []
- def _startBuildFor(slavebuilder, buildrequests):
- self.builds_started.append((slavebuilder, buildrequests))
- return defer.succeed(True)
- self.bldr._startBuildFor = _startBuildFor
-
- if patch_random:
- # patch 'random.choice' to always take the slave that sorts
- # last, based on its name
- self.patch(random, "choice",
- lambda lst : sorted(lst, key=lambda m : m.name)[-1])
-
- self.bldr.startService()
-
- mastercfg = config.MasterConfig()
- mastercfg.builders = [ self.builder_config ]
- return self.bldr.reconfigService(mastercfg)
-
-class TestBuilderBuildCreation(BuilderMixin, unittest.TestCase):
-
- def setUp(self):
- # a collection of rows that would otherwise clutter up every test
- self.base_rows = [
- fakedb.SourceStampSet(id=21),
- fakedb.SourceStamp(id=21, sourcestampsetid=21),
- fakedb.Buildset(id=11, reason='because', sourcestampsetid=21),
- ]
-
- def makeBuilder(self, patch_random=False, startBuildsForSucceeds=True, **config_kwargs):
- d = BuilderMixin.makeBuilder(self, patch_random=patch_random, **config_kwargs)
- @d.addCallback
- def patch_startBuildsFor(_):
- # patch into the _startBuildsFor method
- self.builds_started = []
- def _startBuildFor(slavebuilder, buildrequests):
- self.builds_started.append((slavebuilder, buildrequests))
- return defer.succeed(startBuildsForSucceeds)
- self.bldr._startBuildFor = _startBuildFor
- return d
-
- def assertBuildsStarted(self, exp):
- # munge builds_started into a list of (slave, [brids])
- builds_started = [
- (sl.name, [ br.id for br in buildreqs ])
- for (sl, buildreqs) in self.builds_started ]
- self.assertEqual(sorted(builds_started), sorted(exp))
-
- def setSlaveBuilders(self, slavebuilders):
- """C{slaves} maps name : available"""
- self.bldr.slaves = []
- for name, avail in slavebuilders.iteritems():
- sb = mock.Mock(spec=['isAvailable'], name=name)
- sb.name = name
- sb.isAvailable.return_value = avail
- self.bldr.slaves.append(sb)
-
- # services
-
- @defer.inlineCallbacks
- def test_maybeStartBuild_builder_stopped(self):
- yield self.makeBuilder()
-
- # this will cause an exception if maybeStartBuild tries to start
- self.bldr.slaves = None
-
- # so we just hope this does not fail
- yield self.bldr.stopService()
- started = yield self.bldr.maybeStartBuild(None, [])
- self.assertEquals(started, False)
-
-
- # maybeStartBuild
-
- def _makeMocks(self):
- slave = mock.Mock()
- slave.name = 'slave'
- buildrequest = mock.Mock()
- buildrequest.id = 10
- buildrequests = [buildrequest]
- return slave, buildrequests
-
- @defer.inlineCallbacks
- def test_maybeStartBuild(self):
- yield self.makeBuilder()
-
- slave, buildrequests = self._makeMocks()
-
- started = yield self.bldr.maybeStartBuild(slave, buildrequests)
- self.assertEqual(started, True)
- self.assertBuildsStarted([('slave', [10])])
-
- @defer.inlineCallbacks
- def test_maybeStartBuild_failsToStart(self):
- yield self.makeBuilder(startBuildsForSucceeds=False)
-
- slave, buildrequests = self._makeMocks()
-
- started = yield self.bldr.maybeStartBuild(slave, buildrequests)
- self.assertEqual(started, False)
- self.assertBuildsStarted([('slave', [10])])
-
- @defer.inlineCallbacks
- def do_test_getMergeRequestsFn(self, builder_param=None,
- global_param=None, expected=0):
- cble = lambda : None
- builder_param = builder_param == 'callable' and cble or builder_param
- global_param = global_param == 'callable' and cble or global_param
-
- # omit the constructor parameter if None was given
- if builder_param is None:
- yield self.makeBuilder()
- else:
- yield self.makeBuilder(mergeRequests=builder_param)
-
- self.master.config.mergeRequests = global_param
-
- fn = self.bldr.getMergeRequestsFn()
-
- if fn == builder.Builder._defaultMergeRequestFn:
- fn = "default"
- elif fn is cble:
- fn = 'callable'
- self.assertEqual(fn, expected)
-
- def test_getMergeRequestsFn_defaults(self):
- self.do_test_getMergeRequestsFn(None, None, "default")
-
- def test_getMergeRequestsFn_global_True(self):
- self.do_test_getMergeRequestsFn(None, True, "default")
-
- def test_getMergeRequestsFn_global_False(self):
- self.do_test_getMergeRequestsFn(None, False, None)
-
- def test_getMergeRequestsFn_global_function(self):
- self.do_test_getMergeRequestsFn(None, 'callable', 'callable')
-
- def test_getMergeRequestsFn_builder_True(self):
- self.do_test_getMergeRequestsFn(True, False, "default")
-
- def test_getMergeRequestsFn_builder_False(self):
- self.do_test_getMergeRequestsFn(False, True, None)
-
- def test_getMergeRequestsFn_builder_function(self):
- self.do_test_getMergeRequestsFn('callable', None, 'callable')
-
-
- # other methods
-
- @defer.inlineCallbacks
- def test_reclaimAllBuilds_empty(self):
- yield self.makeBuilder()
-
- # just to be sure this doesn't crash
- yield self.bldr.reclaimAllBuilds()
-
- @defer.inlineCallbacks
- def test_reclaimAllBuilds(self):
- yield self.makeBuilder()
-
- claims = []
- def fakeClaimBRs(*args):
- claims.append(args)
- return defer.succeed(None)
- self.bldr.master.db.buildrequests.claimBuildRequests = fakeClaimBRs
- self.bldr.master.db.buildrequests.reclaimBuildRequests = fakeClaimBRs
-
- def mkbld(brids):
- bld = mock.Mock(name='Build')
- bld.requests = []
- for brid in brids:
- br = mock.Mock(name='BuildRequest %d' % brid)
- br.id = brid
- bld.requests.append(br)
- return bld
-
- old = mkbld([15]) # keep a reference to the "old" build
- self.bldr.old_building[old] = None
- self.bldr.building.append(mkbld([10,11,12]))
-
- yield self.bldr.reclaimAllBuilds()
-
- self.assertEqual(claims, [ (set([10,11,12,15]),) ])
-
- @defer.inlineCallbacks
- def test_canStartBuild(self):
- yield self.makeBuilder()
-
- # by default, it returns True
- startable = yield self.bldr.canStartBuild('slave', 100)
- self.assertEqual(startable, True)
-
- startable = yield self.bldr.canStartBuild('slave', 101)
- self.assertEqual(startable, True)
-
- # set a configurable one
- record = []
- def canStartBuild(bldr, slave, breq):
- record.append((bldr, slave, breq))
- return (slave,breq)==('slave',100)
- self.bldr.config.canStartBuild = canStartBuild
-
- startable = yield self.bldr.canStartBuild('slave', 100)
- self.assertEqual(startable, True)
- self.assertEqual(record, [(self.bldr, 'slave', 100)])
-
- startable = yield self.bldr.canStartBuild('slave', 101)
- self.assertEqual(startable, False)
- self.assertEqual(record, [(self.bldr, 'slave', 100), (self.bldr, 'slave', 101)])
-
- # set a configurable one to return Deferred
- record = []
- def canStartBuild_deferred(bldr, slave, breq):
- record.append((bldr, slave, breq))
- return (slave,breq)==('slave',100)
- return defer.succeed((slave,breq)==('slave',100))
- self.bldr.config.canStartBuild = canStartBuild_deferred
-
- startable = yield self.bldr.canStartBuild('slave', 100)
- self.assertEqual(startable, True)
- self.assertEqual(record, [(self.bldr, 'slave', 100)])
-
- startable = yield self.bldr.canStartBuild('slave', 101)
- self.assertEqual(startable, False)
- self.assertEqual(record, [(self.bldr, 'slave', 100), (self.bldr, 'slave', 101)])
-
- @defer.inlineCallbacks
- def test_enforceChosenSlave(self):
- """enforceChosenSlave rejects and accepts builds"""
- yield self.makeBuilder()
-
- self.bldr.config.canStartBuild = builder.enforceChosenSlave
-
- slave = mock.Mock()
- slave.slave.slavename = 'slave5'
-
- breq = mock.Mock()
-
- # no buildslave requested
- breq.properties = {}
- result = yield self.bldr.canStartBuild(slave, breq)
- self.assertIdentical(True, result)
-
- # buildslave requested as the right one
- breq.properties = { 'slavename': 'slave5' }
- result = yield self.bldr.canStartBuild(slave, breq)
- self.assertIdentical(True, result)
-
- # buildslave requested as the wrong one
- breq.properties = { 'slavename': 'slave4' }
- result = yield self.bldr.canStartBuild(slave, breq)
- self.assertIdentical(False, result)
-
- # buildslave set to non string value gets skipped
- breq.properties = { 'slavename': 0 }
- result = yield self.bldr.canStartBuild(slave, breq)
- self.assertIdentical(True, result)
-
-
-
-
-class TestGetOldestRequestTime(BuilderMixin, unittest.TestCase):
-
- def setUp(self):
- # a collection of rows that would otherwise clutter up every test
- master_id = fakedb.FakeBuildRequestsComponent.MASTER_ID
- self.base_rows = [
- fakedb.SourceStampSet(id=21),
- fakedb.SourceStamp(id=21, sourcestampsetid=21),
- fakedb.Buildset(id=11, reason='because', sourcestampsetid=21),
- fakedb.BuildRequest(id=111, submitted_at=1000,
- buildername='bldr1', buildsetid=11),
- fakedb.BuildRequest(id=222, submitted_at=2000,
- buildername='bldr1', buildsetid=11),
- fakedb.BuildRequestClaim(brid=222, objectid=master_id,
- claimed_at=2001),
- fakedb.BuildRequest(id=333, submitted_at=3000,
- buildername='bldr1', buildsetid=11),
- fakedb.BuildRequest(id=444, submitted_at=2500,
- buildername='bldr2', buildsetid=11),
- fakedb.BuildRequestClaim(brid=444, objectid=master_id,
- claimed_at=2501),
- ]
-
- def test_gort_unclaimed(self):
- d = self.makeBuilder(name='bldr1')
- d.addCallback(lambda _ : self.db.insertTestData(self.base_rows))
- d.addCallback(lambda _ : self.bldr.getOldestRequestTime())
- def check(rqtime):
- self.assertEqual(rqtime, epoch2datetime(1000))
- d.addCallback(check)
- return d
-
- def test_gort_all_claimed(self):
- d = self.makeBuilder(name='bldr2')
- d.addCallback(lambda _ : self.db.insertTestData(self.base_rows))
- d.addCallback(lambda _ : self.bldr.getOldestRequestTime())
- def check(rqtime):
- self.assertEqual(rqtime, None)
- d.addCallback(check)
- return d
-
-class TestRebuild(BuilderMixin, unittest.TestCase):
-
- def makeBuilder(self, name, sourcestamps):
- d = BuilderMixin.makeBuilder(self, name=name)
- @d.addCallback
- def setupBstatus(_):
- self.bstatus = mock.Mock()
- bstatus_properties = mock.Mock()
- bstatus_properties.properties = {}
- self.bstatus.getProperties.return_value = bstatus_properties
- self.bstatus.getSourceStamps.return_value = sourcestamps
- self.master.addBuildset = addBuildset = mock.Mock()
- addBuildset.return_value = (1, [100])
- return d
-
- @defer.inlineCallbacks
- def do_test_rebuild(self,
- sourcestampsetid,
- nr_of_sourcestamps):
-
- # Store combinations of sourcestampId and sourcestampSetId
- self.sslist = {}
- self.ssseq = 1
- def addSourceStampToDatabase(master, sourcestampsetid):
- self.sslist[self.ssseq] = sourcestampsetid
- self.ssseq += 1
- return defer.succeed(sourcestampsetid)
- def getSourceStampSetId(master):
- return addSourceStampToDatabase(master, sourcestampsetid = sourcestampsetid)
-
- sslist = []
- for x in range(nr_of_sourcestamps):
- ssx = mock.Mock()
- ssx.addSourceStampToDatabase = addSourceStampToDatabase
- ssx.getSourceStampSetId = getSourceStampSetId
- sslist.append(ssx)
-
- yield self.makeBuilder(name='bldr1', sourcestamps = sslist)
- control = mock.Mock(spec=['master'])
- control.master = self.master
- self.bldrctrl = builder.BuilderControl(self.bldr, control)
-
- yield self.bldrctrl.rebuildBuild(self.bstatus, reason = 'unit test', extraProperties = {})
-
- @defer.inlineCallbacks
- def test_rebuild_with_no_sourcestamps(self):
- yield self.do_test_rebuild(101, 0)
- self.assertEqual(self.sslist, {})
-
- @defer.inlineCallbacks
- def test_rebuild_with_single_sourcestamp(self):
- yield self.do_test_rebuild(101, 1)
- self.assertEqual(self.sslist, {1:101})
- self.master.addBuildset.assert_called_with(builderNames=['bldr1'],
- sourcestampsetid=101,
- reason = 'unit test',
- properties = {})
-
-
- @defer.inlineCallbacks
- def test_rebuild_with_multiple_sourcestamp(self):
- yield self.do_test_rebuild(101, 3)
- self.assertEqual(self.sslist, {1:101, 2:101, 3:101})
- self.master.addBuildset.assert_called_with(builderNames=['bldr1'],
- sourcestampsetid=101,
- reason = 'unit test',
- properties = {})
-
-
-class TestReconfig(BuilderMixin, unittest.TestCase):
- """Tests that a reconfig properly updates all attributes"""
-
- @defer.inlineCallbacks
- def test_reconfig(self):
- yield self.makeBuilder(description="Old", category="OldCat")
- self.builder_config.description = "New"
- self.builder_config.category = "NewCat"
-
- mastercfg = config.MasterConfig()
- mastercfg.builders = [ self.builder_config ]
- yield self.bldr.reconfigService(mastercfg)
- self.assertEqual(
- dict(description=self.bldr.builder_status.getDescription(),
- category=self.bldr.builder_status.getCategory()),
- dict(description="New",
- category="NewCat"))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildrequest.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildrequest.py
deleted file mode 100644
index 632be205..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildrequest.py
+++ /dev/null
@@ -1,346 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.test.fake import fakedb, fakemaster
-from buildbot.process import buildrequest
-
-class FakeSource:
- def __init__(self, mergeable = True):
- self.codebase = ''
- self.mergeable = mergeable
- self.changes = []
-
- def canBeMergedWith(self, other):
- return self.mergeable
-
-class TestBuildRequest(unittest.TestCase):
-
- def test_fromBrdict(self):
- master = fakemaster.make_master()
- master.db = fakedb.FakeDBConnector(self)
- master.db.insertTestData([
- fakedb.Change(changeid=13, branch='trunk', revision='9283',
- repository='svn://...', project='world-domination'),
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234, branch='trunk',
- revision='9284', repository='svn://...',
- project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=234, changeid=13),
- fakedb.Buildset(id=539, reason='triggered', sourcestampsetid=234),
- fakedb.BuildsetProperty(buildsetid=539, property_name='x',
- property_value='[1, "X"]'),
- fakedb.BuildsetProperty(buildsetid=539, property_name='y',
- property_value='[2, "Y"]'),
- fakedb.BuildRequest(id=288, buildsetid=539, buildername='bldr',
- priority=13, submitted_at=1200000000),
- ])
- # use getBuildRequest to minimize the risk from changes to the format
- # of the brdict
- d = master.db.buildrequests.getBuildRequest(288)
- d.addCallback(lambda brdict :
- buildrequest.BuildRequest.fromBrdict(master, brdict))
- def check(br):
- # check enough of the source stamp to verify it found the changes
- self.assertEqual(br.source.ssid, 234)
- self.assertEqual([ ch.number for ch in br.source.changes], [13])
-
- self.assertEqual(br.reason, 'triggered')
-
- self.assertEqual(br.properties.getProperty('x'), 1)
- self.assertEqual(br.properties.getProperty('y'), 2)
- self.assertEqual(br.submittedAt, 1200000000)
- self.assertEqual(br.buildername, 'bldr')
- self.assertEqual(br.priority, 13)
- self.assertEqual(br.id, 288)
- self.assertEqual(br.bsid, 539)
- d.addCallback(check)
- return d
-
- def test_fromBrdict_submittedAt_NULL(self):
- master = fakemaster.make_master()
- master.db = fakedb.FakeDBConnector(self)
- master.db.insertTestData([
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234, branch='trunk',
- revision='9284', repository='svn://...',
- project='world-domination'),
- fakedb.Buildset(id=539, reason='triggered', sourcestampsetid=234),
- fakedb.BuildRequest(id=288, buildsetid=539, buildername='bldr',
- priority=13, submitted_at=None),
- ])
- # use getBuildRequest to minimize the risk from changes to the format
- # of the brdict
- d = master.db.buildrequests.getBuildRequest(288)
- d.addCallback(lambda brdict :
- buildrequest.BuildRequest.fromBrdict(master, brdict))
- def check(br):
- # remaining fields assumed to be checked in test_fromBrdict
- self.assertEqual(br.submittedAt, None)
- d.addCallback(check)
- return d
-
- def test_fromBrdict_no_sourcestamps(self):
- master = fakemaster.make_master()
- master.db = fakedb.FakeDBConnector(self)
- master.db.insertTestData([
- fakedb.SourceStampSet(id=234),
- # Sourcestampset has no sourcestamps
- fakedb.Buildset(id=539, reason='triggered', sourcestampsetid=234),
- fakedb.BuildRequest(id=288, buildsetid=539, buildername='not important',
- priority=0, submitted_at=None),
- ])
- # use getBuildRequest to minimize the risk from changes to the format
- # of the brdict
- d = master.db.buildrequests.getBuildRequest(288)
- d.addCallback(lambda brdict:
- buildrequest.BuildRequest.fromBrdict(master, brdict))
- return self.assertFailure(d, AssertionError)
-
- def test_fromBrdict_multiple_sourcestamps(self):
- master = fakemaster.make_master()
- master.db = fakedb.FakeDBConnector(self)
- master.db.insertTestData([
- fakedb.SourceStampSet(id=234),
-
- fakedb.Change(changeid=13, branch='trunk', revision='9283',
- repository='svn://a..', codebase='A',
- project='world-domination'),
- fakedb.SourceStamp(id=234, sourcestampsetid=234, branch='trunk',
- revision='9283', repository='svn://a..',
- codebase='A', project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=234, changeid=13),
-
- fakedb.Change(changeid=14, branch='trunk', revision='9284',
- repository='svn://b..', codebase='B',
- project='world-domination'),
- fakedb.SourceStamp(id=235, sourcestampsetid=234, branch='trunk',
- revision='9284', repository='svn://b..',
- codebase='B', project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=235, changeid=14),
-
- fakedb.Buildset(id=539, reason='triggered', sourcestampsetid=234),
- fakedb.BuildsetProperty(buildsetid=539, property_name='x',
- property_value='[1, "X"]'),
- fakedb.BuildsetProperty(buildsetid=539, property_name='y',
- property_value='[2, "Y"]'),
- fakedb.BuildRequest(id=288, buildsetid=539, buildername='bldr',
- priority=13, submitted_at=1200000000),
- ])
- # use getBuildRequest to minimize the risk from changes to the format
- # of the brdict
- d = master.db.buildrequests.getBuildRequest(288)
- d.addCallback(lambda brdict :
- buildrequest.BuildRequest.fromBrdict(master, brdict))
- def check(br):
- # check enough of the source stamp to verify it found the changes
-
- # Test the single-sourcestamp interface
- self.assertEqual(br.source.ssid, 234)
-
- # Test the multiple sourcestamp interface
- self.assertEqual(br.sources['A'].ssid, 234)
- self.assertEqual(br.sources['B'].ssid, 235)
-
- self.assertEqual([ ch.number for ch in br.sources['A'].changes], [13])
- self.assertEqual([ ch.number for ch in br.sources['B'].changes], [14])
-
- self.assertEqual(br.reason, 'triggered')
-
- self.assertEqual(br.properties.getProperty('x'), 1)
- self.assertEqual(br.properties.getProperty('y'), 2)
- self.assertEqual(br.submittedAt, 1200000000)
- self.assertEqual(br.buildername, 'bldr')
- self.assertEqual(br.priority, 13)
- self.assertEqual(br.id, 288)
- self.assertEqual(br.bsid, 539)
- d.addCallback(check)
- return d
-
- def test_mergeSourceStampsWith_common_codebases(self):
- """ This testcase has two buildrequests
- Request Change Codebase Revision Comment
- ----------------------------------------------------------------------
- 288 13 A 9283
- 289 15 A 9284
- 288 14 B 9200
- 289 16 B 9201
- --------------------------------
- After merged in Build:
- Source1 has rev 9284 and contains changes 13 and 15 from repository svn://a
- Source2 has rev 9201 and contains changes 14 and 16 from repository svn://b
- """
- brs=[] # list of buildrequests
- master = fakemaster.make_master()
- master.db = fakedb.FakeDBConnector(self)
- master.db.insertTestData([
- fakedb.SourceStampSet(id=2340),
-
- fakedb.Change(changeid=13, branch='trunk', revision='9283',
- repository='svn://a..', codebase='A',
- project='world-domination'),
- fakedb.SourceStamp(id=234, sourcestampsetid=2340, branch='trunk',
- revision='9283', repository='svn://a..', codebase='A',
- project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=234, changeid=13),
-
- fakedb.Change(changeid=14, branch='trunk', revision='9200',
- repository='svn://b..', codebase='A',
- project='world-domination'),
- fakedb.SourceStamp(id=235, sourcestampsetid=2340, branch='trunk',
- revision='9200', repository='svn://b..', codebase='B',
- project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=235, changeid=14),
-
- fakedb.SourceStampSet(id=2360),
-
- fakedb.Change(changeid=15, branch='trunk', revision='9284',
- repository='svn://a..', codebase='A',
- project='world-domination'),
- fakedb.SourceStamp(id=236, sourcestampsetid=2360, branch='trunk',
- revision='9284', repository='svn://a..', codebase='A',
- project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=236, changeid=15),
-
- fakedb.Change(changeid=16, branch='trunk', revision='9201',
- repository='svn://b..', codebase='B',
- project='world-domination'),
- fakedb.SourceStamp(id=237, sourcestampsetid=2360, branch='trunk',
- revision='9201', repository='svn://b..', codebase='B',
- project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=237, changeid=16),
-
- fakedb.Buildset(id=539, reason='triggered', sourcestampsetid=2340),
- fakedb.BuildRequest(id=288, buildsetid=539, buildername='bldr'),
-
- fakedb.Buildset(id=540, reason='triggered', sourcestampsetid=2360),
- fakedb.BuildRequest(id=289, buildsetid=540, buildername='bldr'),
- ])
- # use getBuildRequest to minimize the risk from changes to the format
- # of the brdict
- d = master.db.buildrequests.getBuildRequest(288)
- d.addCallback(lambda brdict :
- buildrequest.BuildRequest.fromBrdict(master, brdict))
- d.addCallback(lambda br : brs.append(br))
- d.addCallback(lambda _ :
- master.db.buildrequests.getBuildRequest(289))
- d.addCallback(lambda brdict :
- buildrequest.BuildRequest.fromBrdict(master, brdict))
- d.addCallback(lambda br : brs.append(br))
- def check(_):
- sources = brs[0].mergeSourceStampsWith(brs[1:])
-
- source1 = source2 = None
- for source in sources:
- if source.codebase == 'A':
- source1 = source
- if source.codebase == 'B':
- source2 = source
-
- self.assertFalse(source1 == None)
- self.assertEqual(source1.revision,'9284')
-
- self.assertFalse(source2 == None)
- self.assertEqual(source2.revision,'9201')
-
- self.assertEqual([c.number for c in source1.changes], [13,15])
- self.assertEqual([c.number for c in source2.changes], [14,16])
-
- d.addCallback(check)
- return d
-
- def test_canBeMergedWith_different_codebases_raises_error(self):
- """ This testcase has two buildrequests
- Request Change Codebase Revision Comment
- ----------------------------------------------------------------------
- 288 17 C 1800 request 1 has repo not in request 2
- 289 18 D 2100 request 2 has repo not in request 1
- --------------------------------
- Merge cannot be performd and raises error:
- Merging requests requires both requests to have the same codebases
- """
- brs=[] # list of buildrequests
- master = fakemaster.make_master()
- master.db = fakedb.FakeDBConnector(self)
- master.db.insertTestData([
- fakedb.SourceStampSet(id=2340),
-
- fakedb.Change(changeid=17, branch='trunk', revision='1800',
- repository='svn://c..', codebase='C',
- project='world-domination'),
- fakedb.SourceStamp(id=238, sourcestampsetid=2340, branch='trunk',
- revision='1800', repository='svn://c..',
- codebase='C', project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=238, changeid=17),
-
- fakedb.SourceStampSet(id=2360),
-
- fakedb.Change(changeid=18, branch='trunk', revision='2100',
- repository='svn://d..', codebase='D',
- project='world-domination'),
- fakedb.SourceStamp(id=239, sourcestampsetid=2360, branch='trunk',
- revision='2100', repository='svn://d..',
- codebase='D', project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=239, changeid=18),
-
- fakedb.Buildset(id=539, reason='triggered', sourcestampsetid=2340),
- fakedb.BuildRequest(id=288, buildsetid=539, buildername='bldr'),
-
- fakedb.Buildset(id=540, reason='triggered', sourcestampsetid=2360),
- fakedb.BuildRequest(id=289, buildsetid=540, buildername='bldr'),
- ])
- # use getBuildRequest to minimize the risk from changes to the format
- # of the brdict
- d = master.db.buildrequests.getBuildRequest(288)
- d.addCallback(lambda brdict :
- buildrequest.BuildRequest.fromBrdict(master, brdict))
- d.addCallback(lambda br : brs.append(br))
- d.addCallback(lambda _ :
- master.db.buildrequests.getBuildRequest(289))
- d.addCallback(lambda brdict :
- buildrequest.BuildRequest.fromBrdict(master, brdict))
- d.addCallback(lambda br : brs.append(br))
- def check(_):
- self.assertEqual(brs[0].canBeMergedWith(brs[1]), False)
-
- d.addCallback(check)
- return d
-
- def test_build_can_be_merged_with_mergables_same_codebases(self):
- r1 = buildrequest.BuildRequest()
- r1.sources = {"A": FakeSource()}
- r2 = buildrequest.BuildRequest()
- r2.sources = {"A": FakeSource()}
- mergeable = r1.canBeMergedWith(r2)
- self.assertTrue(mergeable, "Both request should be able to merge")
-
- def test_build_can_be_merged_with_non_mergable_same_codebases(self):
- r1 = buildrequest.BuildRequest()
- r1.sources = {"A": FakeSource(mergeable = False)}
- r2 = buildrequest.BuildRequest()
- r2.sources = {"A": FakeSource(mergeable = False)}
- mergeable = r1.canBeMergedWith(r2)
- self.assertFalse(mergeable, "Both request should not be able to merge")
-
- def test_build_can_be_merged_with_non_mergables_different_codebases(self):
- r1 = buildrequest.BuildRequest()
- r1.sources = {"A": FakeSource(mergeable = False)}
- r2 = buildrequest.BuildRequest()
- r2.sources = {"B": FakeSource(mergeable = False)}
- mergeable = r1.canBeMergedWith(r2)
- self.assertFalse(mergeable, "Request containing different codebases " +
- "should never be able to merge")
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildrequestdistributor_BuildRequestDistributor.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildrequestdistributor_BuildRequestDistributor.py
deleted file mode 100644
index e27e6f1d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildrequestdistributor_BuildRequestDistributor.py
+++ /dev/null
@@ -1,1031 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-from twisted.internet import defer, reactor
-from twisted.python import failure
-from buildbot.test.util import compat
-from buildbot.test.fake import fakedb, fakemaster
-from buildbot.process import buildrequestdistributor
-from buildbot.util import epoch2datetime
-from buildbot.util.eventual import fireEventually
-from buildbot.db import buildrequests
-
-def nth_slave(n):
- def pick_nth_by_name(lst):
- slaves = lst[:]
- slaves.sort(cmp=lambda a,b: cmp(a.name, b.name))
- return slaves[n]
- return pick_nth_by_name
-
-class SkipSlavesThatCantGetLock(buildrequestdistributor.BasicBuildChooser):
- """This class disables the 'rejectedSlaves' feature"""
- def __init__(self, *args, **kwargs):
- buildrequestdistributor.BasicBuildChooser.__init__(self, *args, **kwargs)
- self.rejectedSlaves = None # disable this feature
-
-class Test(unittest.TestCase):
-
- def setUp(self):
- self.botmaster = mock.Mock(name='botmaster')
- self.botmaster.builders = {}
- def prioritizeBuilders(master, builders):
- # simple sort-by-name by default
- return sorted(builders, lambda b1,b2 : cmp(b1.name, b2.name))
- self.master = self.botmaster.master = mock.Mock(name='master')
- self.master.config.prioritizeBuilders = prioritizeBuilders
- self.master.db = fakedb.FakeDBConnector(self)
- self.brd = buildrequestdistributor.BuildRequestDistributor(self.botmaster)
- self.brd.startService()
-
- # TODO: this is a terrible way to detect the "end" of the test -
- # it regularly completes too early after a simple modification of
- # a test. Is there a better way?
- self.quiet_deferred = defer.Deferred()
- def _quiet():
- if self.quiet_deferred:
- d, self.quiet_deferred = self.quiet_deferred, None
- d.callback(None)
- else:
- self.fail("loop has already gone quiet once")
- self.brd._quiet = _quiet
-
- self.builders = {}
-
- def tearDown(self):
- if self.brd.running:
- return self.brd.stopService()
-
- def checkAllCleanedUp(self):
- # check that the BRD didnt end with a stuck lock or in the 'active' state (which would mean
- # it ended without unwinding correctly)
- self.assertEqual(self.brd.pending_builders_lock.locked, False)
- self.assertEqual(self.brd.activity_lock.locked, False)
- self.assertEqual(self.brd.active, False)
-
- def useMock_maybeStartBuildsOnBuilder(self):
- # sets up a mock "maybeStartBuildsOnBuilder" so we can track
- # how the method gets invoked
-
- # keep track of the calls to brd.maybeStartBuildsOnBuilder
- self.maybeStartBuildsOnBuilder_calls = []
-
- def maybeStartBuildsOnBuilder(bldr):
- self.assertIdentical(self.builders[bldr.name], bldr)
- self.maybeStartBuildsOnBuilder_calls.append(bldr.name)
- return fireEventually()
- self.brd._maybeStartBuildsOnBuilder = maybeStartBuildsOnBuilder
-
- def addBuilders(self, names):
- self.startedBuilds = []
-
- for name in names:
- bldr = mock.Mock(name=name)
- bldr.name = name
- self.botmaster.builders[name] = bldr
- self.builders[name] = bldr
-
- def maybeStartBuild(*args):
- self.startedBuilds.append((name, args))
- d = defer.Deferred()
- reactor.callLater(0, d.callback, None)
- return d
- bldr.maybeStartBuild = maybeStartBuild
- bldr.canStartWithSlavebuilder = lambda _: True
-
- bldr.slaves = []
- bldr.getAvailableSlaves = lambda : [ s for s in bldr.slaves if s.isAvailable ]
-
- def removeBuilder(self, name):
- del self.builders[name]
- del self.botmaster.builders[name]
-
- # tests
-
- def test_maybeStartBuildsOn_simple(self):
- self.useMock_maybeStartBuildsOnBuilder()
- self.addBuilders(['bldr1'])
- self.brd.maybeStartBuildsOn(['bldr1'])
- def check(_):
- self.assertEqual(self.maybeStartBuildsOnBuilder_calls, ['bldr1'])
- self.checkAllCleanedUp()
- self.quiet_deferred.addCallback(check)
- return self.quiet_deferred
-
- def test_maybeStartBuildsOn_parallel(self):
- # test 15 "parallel" invocations of maybeStartBuildsOn, with a
- # _sortBuilders that takes a while. This is a regression test for bug
- # #1979.
- builders = ['bldr%02d' % i for i in xrange(15) ]
-
- def slow_sorter(master, bldrs):
- bldrs.sort(lambda b1, b2 : cmp(b1.name, b2.name))
- d = defer.Deferred()
- reactor.callLater(0, d.callback, bldrs)
- def done(_):
- return _
- d.addCallback(done)
- return d
- self.master.config.prioritizeBuilders = slow_sorter
-
- self.useMock_maybeStartBuildsOnBuilder()
- self.addBuilders(builders)
- for bldr in builders:
- self.brd.maybeStartBuildsOn([bldr])
- def check(_):
- self.assertEqual(self.maybeStartBuildsOnBuilder_calls, builders)
- self.checkAllCleanedUp()
- self.quiet_deferred.addCallback(check)
- return self.quiet_deferred
-
- @compat.usesFlushLoggedErrors
- def test_maybeStartBuildsOn_exception(self):
- self.addBuilders(['bldr1'])
-
- def _maybeStartBuildsOnBuilder(n):
- # fail slowly, so that the activity loop doesn't go quiet too soon
- d = defer.Deferred()
- reactor.callLater(0,
- d.errback, failure.Failure(RuntimeError("oh noes")))
- return d
- self.brd._maybeStartBuildsOnBuilder = _maybeStartBuildsOnBuilder
-
- self.brd.maybeStartBuildsOn(['bldr1'])
- def check(_):
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
- self.checkAllCleanedUp()
- self.quiet_deferred.addCallback(check)
- return self.quiet_deferred
-
- def test_maybeStartBuildsOn_collapsing(self):
- self.useMock_maybeStartBuildsOnBuilder()
- self.addBuilders(['bldr1', 'bldr2', 'bldr3'])
- self.brd.maybeStartBuildsOn(['bldr3'])
- self.brd.maybeStartBuildsOn(['bldr2', 'bldr1'])
- self.brd.maybeStartBuildsOn(['bldr4']) # should be ignored
- self.brd.maybeStartBuildsOn(['bldr2']) # already queued - ignored
- self.brd.maybeStartBuildsOn(['bldr3', 'bldr2'])
- def check(_):
- # bldr3 gets invoked twice, since it's considered to have started
- # already when the first call to maybeStartBuildsOn returns
- self.assertEqual(self.maybeStartBuildsOnBuilder_calls,
- ['bldr3', 'bldr1', 'bldr2', 'bldr3'])
- self.checkAllCleanedUp()
- self.quiet_deferred.addCallback(check)
- return self.quiet_deferred
-
- def test_maybeStartBuildsOn_builders_missing(self):
- self.useMock_maybeStartBuildsOnBuilder()
- self.addBuilders(['bldr1', 'bldr2', 'bldr3'])
- self.brd.maybeStartBuildsOn(['bldr1', 'bldr2', 'bldr3'])
- # bldr1 is already run, so surreptitiously remove the other
- # two - nothing should crash, but the builders should not run
- self.removeBuilder('bldr2')
- self.removeBuilder('bldr3')
- def check(_):
- self.assertEqual(self.maybeStartBuildsOnBuilder_calls, ['bldr1'])
- self.checkAllCleanedUp()
- self.quiet_deferred.addCallback(check)
- return self.quiet_deferred
-
- def do_test_sortBuilders(self, prioritizeBuilders, oldestRequestTimes,
- expected, returnDeferred=False):
- self.useMock_maybeStartBuildsOnBuilder()
- self.addBuilders(oldestRequestTimes.keys())
- self.master.config.prioritizeBuilders = prioritizeBuilders
-
- def mklambda(t): # work around variable-binding issues
- if returnDeferred:
- return lambda : defer.succeed(t)
- else:
- return lambda : t
-
- for n, t in oldestRequestTimes.iteritems():
- if t is not None:
- t = epoch2datetime(t)
- self.builders[n].getOldestRequestTime = mklambda(t)
-
- d = self.brd._sortBuilders(oldestRequestTimes.keys())
- def check(result):
- self.assertEqual(result, expected)
- self.checkAllCleanedUp()
- d.addCallback(check)
- return d
-
- def test_sortBuilders_default_sync(self):
- return self.do_test_sortBuilders(None, # use the default sort
- dict(bldr1=777, bldr2=999, bldr3=888),
- ['bldr1', 'bldr3', 'bldr2'])
-
- def test_sortBuilders_default_asyn(self):
- return self.do_test_sortBuilders(None, # use the default sort
- dict(bldr1=777, bldr2=999, bldr3=888),
- ['bldr1', 'bldr3', 'bldr2'],
- returnDeferred=True)
-
- def test_sortBuilders_default_None(self):
- return self.do_test_sortBuilders(None, # use the default sort
- dict(bldr1=777, bldr2=None, bldr3=888),
- ['bldr1', 'bldr3', 'bldr2'])
-
- def test_sortBuilders_custom(self):
- def prioritizeBuilders(master, builders):
- self.assertIdentical(master, self.master)
- return sorted(builders, key=lambda b : b.name)
-
- return self.do_test_sortBuilders(prioritizeBuilders,
- dict(bldr1=1, bldr2=1, bldr3=1),
- ['bldr1', 'bldr2', 'bldr3'])
-
- def test_sortBuilders_custom_async(self):
- def prioritizeBuilders(master, builders):
- self.assertIdentical(master, self.master)
- return defer.succeed(sorted(builders, key=lambda b : b.name))
-
- return self.do_test_sortBuilders(prioritizeBuilders,
- dict(bldr1=1, bldr2=1, bldr3=1),
- ['bldr1', 'bldr2', 'bldr3'])
-
- @compat.usesFlushLoggedErrors
- def test_sortBuilders_custom_exception(self):
- self.useMock_maybeStartBuildsOnBuilder()
- self.addBuilders(['x', 'y'])
- def fail(m, b):
- raise RuntimeError("oh noes")
- self.master.config.prioritizeBuilders = fail
-
- # expect to get the builders back in the same order in the event of an
- # exception
- d = self.brd._sortBuilders(['y', 'x'])
- def check(result):
- self.assertEqual(result, ['y', 'x'])
-
- # and expect the exception to be logged
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
- d.addCallback(check)
- return d
-
- def test_stopService(self):
- # check that stopService waits for a builder run to complete, but does not
- # allow a subsequent run to start
- self.useMock_maybeStartBuildsOnBuilder()
- self.addBuilders(['A', 'B'])
-
- oldMSBOB = self.brd._maybeStartBuildsOnBuilder
- def maybeStartBuildsOnBuilder(bldr):
- d = oldMSBOB(bldr)
-
- stop_d = self.brd.stopService()
- stop_d.addCallback(lambda _ :
- self.maybeStartBuildsOnBuilder_calls.append('(stopped)'))
-
- d.addCallback(lambda _ :
- self.maybeStartBuildsOnBuilder_calls.append('finished'))
- return d
- self.brd._maybeStartBuildsOnBuilder = maybeStartBuildsOnBuilder
-
- # start both builds; A should start and complete *before* the service stops,
- # and B should not run.
- self.brd.maybeStartBuildsOn(['A', 'B'])
-
- def check(_):
- self.assertEqual(self.maybeStartBuildsOnBuilder_calls,
- ['A', 'finished', '(stopped)'])
- self.quiet_deferred.addCallback(check)
- return self.quiet_deferred
-
-
-class TestMaybeStartBuilds(unittest.TestCase):
-
- def setUp(self):
- self.botmaster = mock.Mock(name='botmaster')
- self.botmaster.builders = {}
- self.master = self.botmaster.master = mock.Mock(name='master')
- self.master.db = fakedb.FakeDBConnector(self)
- class getCache(object):
- def get_cache(self):
- return self
- def get(self, name):
- return
- self.master.caches = fakemaster.FakeCaches()
- self.brd = buildrequestdistributor.BuildRequestDistributor(self.botmaster)
- self.brd.startService()
-
- self.startedBuilds = []
-
- # TODO: this is a terrible way to detect the "end" of the test -
- # it regularly completes too early after a simple modification of
- # a test. Is there a better way?
- self.quiet_deferred = defer.Deferred()
- def _quiet():
- if self.quiet_deferred:
- d, self.quiet_deferred = self.quiet_deferred, None
- d.callback(None)
- else:
- self.fail("loop has already gone quiet once")
- self.brd._quiet = _quiet
-
- self.bldr = self.createBuilder('A')
-
- # a collection of rows that would otherwise clutter up every test
- self.base_rows = [
- fakedb.SourceStampSet(id=21),
- fakedb.SourceStamp(id=21, sourcestampsetid=21),
- fakedb.Buildset(id=11, reason='because', sourcestampsetid=21),
- ]
-
-
- def tearDown(self):
- if self.brd.running:
- return self.brd.stopService()
-
- def createBuilder(self, name):
- bldr = mock.Mock(name=name)
- bldr.name = name
- self.botmaster.builders[name] = bldr
-
- def maybeStartBuild(slave, builds):
- self.startedBuilds.append((slave.name, builds))
- return defer.succeed(True)
-
- bldr.maybeStartBuild = maybeStartBuild
- bldr.canStartWithSlavebuilder = lambda _: True
- bldr.getMergeRequestsFn = lambda : False
-
- bldr.slaves = []
- bldr.getAvailableSlaves = lambda : [ s for s in bldr.slaves if s.isAvailable() ]
- bldr.config.nextSlave = None
- bldr.config.nextBuild = None
-
- def canStartBuild(*args):
- can = bldr.config.canStartBuild
- return not can or can(*args)
- bldr.canStartBuild = canStartBuild
-
- return bldr
-
- def addSlaves(self, slavebuilders):
- """C{slaves} maps name : available"""
- for name, avail in slavebuilders.iteritems():
- sb = mock.Mock(spec=['isAvailable'], name=name)
- sb.name = name
- sb.isAvailable.return_value = avail
- self.bldr.slaves.append(sb)
-
- def assertBuildsStarted(self, exp):
- # munge builds_started into (slave, [brids])
- builds_started = [
- (slave, [br.id for br in breqs])
- for (slave, breqs) in self.startedBuilds ]
- self.assertEqual(sorted(builds_started), sorted(exp))
-
- # _maybeStartBuildsOnBuilder
-
- @defer.inlineCallbacks
- def do_test_maybeStartBuildsOnBuilder(self, rows=[], exp_claims=[], exp_builds=[]):
- yield self.master.db.insertTestData(rows)
-
- yield self.brd._maybeStartBuildsOnBuilder(self.bldr)
-
- self.master.db.buildrequests.assertMyClaims(exp_claims)
- self.assertBuildsStarted(exp_builds)
-
- @defer.inlineCallbacks
- def test_no_buildreqests(self):
- self.addSlaves({'test-slave11':1})
- yield self.do_test_maybeStartBuildsOnBuilder(exp_claims=[], exp_builds=[])
-
- @defer.inlineCallbacks
- def test_no_slavebuilders(self):
- rows = [
- fakedb.BuildRequest(id=11, buildsetid=10, buildername="bldr"),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[], exp_builds=[])
-
- @defer.inlineCallbacks
- def test_limited_by_slaves(self):
- self.master.config.mergeRequests = False
- self.addSlaves({'test-slave1':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[10], exp_builds=[('test-slave1', [10])])
-
- @defer.inlineCallbacks
- def test_sorted_by_submit_time(self):
- self.master.config.mergeRequests = False
-
- # same as "limited_by_slaves" but with rows swapped
- self.addSlaves({'test-slave1':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[10], exp_builds=[('test-slave1', [10])])
-
- @defer.inlineCallbacks
- def test_limited_by_available_slaves(self):
- self.master.config.mergeRequests = False
- self.addSlaves({'test-slave1':0, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[10], exp_builds=[('test-slave2', [10])])
-
- @defer.inlineCallbacks
- def test_slow_db(self):
- # test what happens if the "getBuildRequests" fetch takes a "long time"
-
- self.master.config.mergeRequests = False
- self.addSlaves({'test-slave1':1})
-
- # wrap to simulate a "long" db access
- old_getBuildRequests = self.master.db.buildrequests.getBuildRequests
- def longGetBuildRequests(*args, **kwargs):
- res_d = old_getBuildRequests(*args, **kwargs)
- long_d = defer.Deferred()
- long_d.addCallback(lambda _: res_d)
- reactor.callLater(0, long_d.callback, None)
- return long_d
- self.master.db.buildrequests.getBuildRequests = longGetBuildRequests
-
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[10], exp_builds=[('test-slave1', [10])])
-
- @mock.patch('random.choice', nth_slave(-1))
- @defer.inlineCallbacks
- def test_limited_by_canStartBuild(self):
- """Set the 'canStartBuild' value in the config to something
- that limits the possible options."""
-
- self.master.config.mergeRequests = False
-
- slaves_attempted = []
- def _canStartWithSlavebuilder(slavebuilder):
- slaves_attempted.append(slavebuilder.name)
- return True
- self.bldr.canStartWithSlavebuilder = _canStartWithSlavebuilder
-
- pairs_tested = []
- def _canStartBuild(slave, breq):
- result = (slave.name, breq.id)
- pairs_tested.append(result)
- allowed = [
- ("test-slave1", 10),
- ("test-slave3", 11),
- ]
- return result in allowed
- self.bldr.config.canStartBuild = _canStartBuild
-
- self.addSlaves({'test-slave1':1, 'test-slave2':1, 'test-slave3':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- fakedb.BuildRequest(id=12, buildsetid=11, buildername="A",
- submitted_at=140000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[10, 11], exp_builds=[('test-slave1', [10]), ('test-slave3', [11])])
-
- self.assertEqual(slaves_attempted, ['test-slave3', 'test-slave2', 'test-slave1'])
-
- # we expect brids in order (10-11-12),
- # with each searched in reverse order of slaves (3-2-1) available (due to nth_slave(-1))
- self.assertEqual(pairs_tested, [
- ('test-slave3', 10),
- ('test-slave2', 10),
- ('test-slave1', 10),
- ('test-slave3', 11),
- ('test-slave2', 12)])
-
- @mock.patch('random.choice', nth_slave(-1))
- @mock.patch('buildbot.process.buildrequestdistributor.BuildRequestDistributor.BuildChooser', SkipSlavesThatCantGetLock)
- @defer.inlineCallbacks
- def test_limited_by_canStartBuild_deferreds(self):
- """Another variant that:
- * returns Defered types,
- * use 'canStartWithSlavebuilder' to reject one of the slaves
- * patch using SkipSlavesThatCantGetLock to disable the 'rejectedSlaves' feature"""
-
- self.master.config.mergeRequests = False
-
- slaves_attempted = []
- def _canStartWithSlavebuilder(slavebuilder):
- slaves_attempted.append(slavebuilder.name)
- allowed = slavebuilder.name in ['test-slave2', 'test-slave1']
- return defer.succeed(allowed) # a defered here!
- self.bldr.canStartWithSlavebuilder = _canStartWithSlavebuilder
-
- pairs_tested = []
- def _canStartBuild(slave, breq):
- result = (slave.name, breq.id)
- pairs_tested.append(result)
- allowed = [
- ("test-slave1", 10),
- ("test-slave3", 11),
- ]
- return defer.succeed(result in allowed)
- self.bldr.config.canStartBuild = _canStartBuild
-
- self.addSlaves({'test-slave1':1, 'test-slave2':1, 'test-slave3':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- fakedb.BuildRequest(id=12, buildsetid=11, buildername="A",
- submitted_at=140000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[10], exp_builds=[('test-slave1', [10])])
-
- self.assertEqual(slaves_attempted, ['test-slave3', 'test-slave2', 'test-slave1'])
-
- # we expect brids in order (10-11-12),
- # with slave3 skipped, and slave2 unable to pair
- self.assertEqual(pairs_tested, [
- ('test-slave2', 10),
- ('test-slave1', 10),
- ('test-slave2', 11),
- ('test-slave2', 12)])
-
- @mock.patch('random.choice', nth_slave(-1))
- @defer.inlineCallbacks
- def test_limited_by_canStartWithSlavebuilder(self):
- self.master.config.mergeRequests = False
-
- slaves_attempted = []
- def _canStartWithSlavebuilder(slavebuilder):
- slaves_attempted.append(slavebuilder.name)
- return (slavebuilder.name == 'test-slave3')
- self.bldr.canStartWithSlavebuilder = _canStartWithSlavebuilder
- self.addSlaves({'test-slave1':0, 'test-slave2':1, 'test-slave3':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[10, 11], exp_builds=[('test-slave3', [10]), ('test-slave2', [11])])
-
- self.assertEqual(slaves_attempted, ['test-slave3', 'test-slave2'])
-
- @mock.patch('random.choice', nth_slave(-1))
- @defer.inlineCallbacks
- def test_unlimited(self):
- self.master.config.mergeRequests = False
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[10, 11],
- exp_builds=[('test-slave2', [10]), ('test-slave1', [11])])
-
- @mock.patch('random.choice', nth_slave(-1))
- @defer.inlineCallbacks
- def test_bldr_maybeStartBuild_fails_always(self):
- # the builder fails to start the build; we'll see that the build
- # was requested, but the brids will get reclaimed
- def maybeStartBuild(slave, builds):
- self.startedBuilds.append((slave.name, builds))
- return defer.succeed(False)
- self.bldr.maybeStartBuild = maybeStartBuild
-
- self.master.config.mergeRequests = False
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[], # reclaimed so none taken!
- exp_builds=[('test-slave2', [10]), ('test-slave1', [11])])
-
- @mock.patch('random.choice', nth_slave(-1))
- @defer.inlineCallbacks
- def test_bldr_maybeStartBuild_fails_once(self):
- # the builder fails to start the build; we'll see that the build
- # was requested, but the brids will get reclaimed
- def maybeStartBuild(slave, builds, _fail=[False]):
- self.startedBuilds.append((slave.name, builds))
- ret = _fail[0]
- _fail[0] = True
- return defer.succeed(ret)
- self.bldr.maybeStartBuild = maybeStartBuild
-
- self.master.config.mergeRequests = False
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000),
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- ]
-
- yield self.master.db.insertTestData(rows)
-
- # first time around, only #11 stays claimed
- yield self.brd._maybeStartBuildsOnBuilder(self.bldr)
- self.master.db.buildrequests.assertMyClaims([11]) # reclaimed so none taken!
- self.assertBuildsStarted([('test-slave2', [10]), ('test-slave1', [11])])
-
- # second time around the #10 will pass, adding another request and it is claimed
- yield self.brd._maybeStartBuildsOnBuilder(self.bldr)
- self.master.db.buildrequests.assertMyClaims([10, 11])
- self.assertBuildsStarted([('test-slave2', [10]), ('test-slave1', [11]), ('test-slave2', [10])])
-
-
- @mock.patch('random.choice', nth_slave(1))
- @defer.inlineCallbacks
- def test_limited_by_requests(self):
- self.master.config.mergeRequests = False
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A"),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[11], exp_builds=[('test-slave2', [11])])
-
-
- @defer.inlineCallbacks
- def test_nextSlave_None(self):
- self.bldr.config.nextSlave = lambda _1,_2 : defer.succeed(None)
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A"),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[], exp_builds=[])
-
- @defer.inlineCallbacks
- def test_nextSlave_bogus(self):
- self.bldr.config.nextSlave = lambda _1,_2 : defer.succeed(mock.Mock())
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A"),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[], exp_builds=[])
-
- @defer.inlineCallbacks
- def test_nextSlave_fails(self):
- def nextSlaveRaises(*args):
- raise RuntimeError("xx")
- self.bldr.config.nextSlave = nextSlaveRaises
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A"),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[], exp_builds=[])
-
-
- @defer.inlineCallbacks
- def test_nextBuild_None(self):
- self.bldr.config.nextBuild = lambda _1,_2 : defer.succeed(None)
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A"),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[], exp_builds=[])
-
- @defer.inlineCallbacks
- def test_nextBuild_bogus(self):
- self.bldr.config.nextBuild = lambda _1,_2 : mock.Mock()
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A"),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[], exp_builds=[])
-
- @defer.inlineCallbacks
- def test_nextBuild_fails(self):
- def nextBuildRaises(*args):
- raise RuntimeError("xx")
- self.bldr.config.nextBuild = nextBuildRaises
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A"),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[], exp_builds=[])
-
-
- # check concurrency edge cases
-
- @mock.patch('random.choice', nth_slave(0))
- @defer.inlineCallbacks
- def test_claim_race(self):
- # fake a race condition on the buildrequests table
- old_claimBuildRequests = self.master.db.buildrequests.claimBuildRequests
- def claimBuildRequests(brids):
- # first, ensure this only happens the first time
- self.master.db.buildrequests.claimBuildRequests = old_claimBuildRequests
- # claim brid 10 for some other master
- assert 10 in brids
- self.master.db.buildrequests.fakeClaimBuildRequest(10, 136000,
- objectid=9999) # some other objectid
- # ..and fail
- return defer.fail(buildrequests.AlreadyClaimedError())
- self.master.db.buildrequests.claimBuildRequests = claimBuildRequests
-
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=10, buildsetid=11, buildername="A",
- submitted_at=130000), # will turn out to be claimed!
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A",
- submitted_at=135000),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[11], exp_builds=[('test-slave1', [11])])
-
-
- # nextSlave
-
- @defer.inlineCallbacks
- def do_test_nextSlave(self, nextSlave, exp_choice=None):
- for i in range(4):
- self.addSlaves({'sb%d'%i: 1})
-
- self.bldr.config.nextSlave = nextSlave
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="A"),
- ]
-
- if exp_choice is None:
- exp_claims = []
- exp_builds = []
- else:
- exp_claims = [11]
- exp_builds = [('sb%d'%exp_choice, [11])]
-
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=exp_claims, exp_builds=exp_builds)
-
- @mock.patch('random.choice', nth_slave(2))
- def test_nextSlave_default(self):
- return self.do_test_nextSlave(None, exp_choice=2)
-
- def test_nextSlave_simple(self):
- def nextSlave(bldr, lst):
- self.assertIdentical(bldr, self.bldr)
- return lst[1]
- return self.do_test_nextSlave(nextSlave, exp_choice=1)
-
- def test_nextSlave_deferred(self):
- def nextSlave(bldr, lst):
- self.assertIdentical(bldr, self.bldr)
- return defer.succeed(lst[1])
- return self.do_test_nextSlave(nextSlave, exp_choice=1)
-
- def test_nextSlave_exception(self):
- def nextSlave(bldr, lst):
- raise RuntimeError("")
- return self.do_test_nextSlave(nextSlave)
-
- def test_nextSlave_failure(self):
- def nextSlave(bldr, lst):
- return defer.fail(failure.Failure(RuntimeError()))
- return self.do_test_nextSlave(nextSlave)
-
- # _nextBuild
-
- @mock.patch('random.choice', nth_slave(-1))
- @defer.inlineCallbacks
- def do_test_nextBuild(self, nextBuild, exp_choice=None):
- self.bldr.config.nextBuild = nextBuild
- self.master.config.mergeRequests = False
-
- rows = self.base_rows[:]
- for i in range(4):
- rows.append(fakedb.Buildset(id=100+i, reason='because', sourcestampsetid=21))
- rows.append(fakedb.BuildRequest(id=10+i, buildsetid=100+i, buildername="A"))
- self.addSlaves({'test-slave%d'%i:1})
-
- exp_claims = []
- exp_builds = []
- if exp_choice is not None:
- slave = 3
- for choice in exp_choice:
- exp_claims.append(choice)
- exp_builds.append(('test-slave%d'%slave, [choice]))
- slave = slave - 1
-
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=sorted(exp_claims), exp_builds=exp_builds)
-
- def test_nextBuild_default(self):
- "default chooses the first in the list, which should be the earliest"
- return self.do_test_nextBuild(None, exp_choice=[10, 11, 12, 13])
-
- def test_nextBuild_simple(self):
- def nextBuild(bldr, lst):
- self.assertIdentical(bldr, self.bldr)
- return lst[-1]
- return self.do_test_nextBuild(nextBuild, exp_choice=[13, 12, 11, 10])
-
- def test_nextBuild_deferred(self):
- def nextBuild(bldr, lst):
- self.assertIdentical(bldr, self.bldr)
- return defer.succeed(lst[-1])
- return self.do_test_nextBuild(nextBuild, exp_choice=[13, 12, 11, 10])
-
- def test_nextBuild_exception(self):
- def nextBuild(bldr, lst):
- raise RuntimeError("")
- return self.do_test_nextBuild(nextBuild)
-
- def test_nextBuild_failure(self):
- def nextBuild(bldr, lst):
- return defer.fail(failure.Failure(RuntimeError()))
- return self.do_test_nextBuild(nextBuild)
-
-
- # merge tests
-
- @defer.inlineCallbacks
- def test_merge_ordering(self):
- # (patch_random=True)
- self.bldr.getMergeRequestsFn = lambda : lambda _, req1, req2: req1.canBeMergedWith(req2)
-
- self.addSlaves({'test-slave1':1})
-
- # based on the build in bug #2249
- rows = [
- fakedb.SourceStampSet(id=1976),
- fakedb.SourceStamp(id=1976, sourcestampsetid=1976),
- fakedb.Buildset(id=1980, reason='scheduler', sourcestampsetid=1976,
- submitted_at=1332024020.67792),
- fakedb.BuildRequest(id=42880, buildsetid=1980,
- submitted_at=1332024020.67792, buildername="A"),
-
- fakedb.SourceStampSet(id=1977),
- fakedb.SourceStamp(id=1977, sourcestampsetid=1977),
- fakedb.Buildset(id=1981, reason='scheduler', sourcestampsetid=1977,
- submitted_at=1332025495.19141),
- fakedb.BuildRequest(id=42922, buildsetid=1981,
- buildername="A", submitted_at=1332025495.19141),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[42880, 42922],
- exp_builds=[('test-slave1', [42880, 42922])])
-
- @mock.patch('random.choice', nth_slave(0))
- @defer.inlineCallbacks
- def test_mergeRequests(self):
- # set up all of the data required for a BuildRequest object
- rows = [
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234),
- fakedb.Buildset(id=30, sourcestampsetid=234, reason='foo',
- submitted_at=1300305712, results=-1),
- fakedb.BuildRequest(id=19, buildsetid=30, buildername='A',
- priority=13, submitted_at=1300305712, results=-1),
- fakedb.BuildRequest(id=20, buildsetid=30, buildername='A',
- priority=13, submitted_at=1300305712, results=-1),
- fakedb.BuildRequest(id=21, buildsetid=30, buildername='A',
- priority=13, submitted_at=1300305712, results=-1),
- ]
-
- self.addSlaves({'test-slave1':1, 'test-slave2': 1})
-
- def mergeRequests_fn(builder, breq, other):
- # merge evens with evens, odds with odds
- self.assertIdentical(builder, self.bldr)
- return breq.id % 2 == other.id % 2
- self.bldr.getMergeRequestsFn = lambda : mergeRequests_fn
-
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[19, 20, 21],
- exp_builds=[
- ('test-slave1', [19, 21]),
- ('test-slave2', [20])
- ])
-
-
- @mock.patch('random.choice', nth_slave(0))
- @defer.inlineCallbacks
- def test_mergeRequest_no_other_request(self):
- """ Test if builder test for codebases in requests """
- # set up all of the data required for a BuildRequest object
- rows = [
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234, codebase='A'),
- fakedb.Change(changeid=14, codebase='A'),
- fakedb.SourceStampChange(sourcestampid=234, changeid=14),
- fakedb.Buildset(id=30, sourcestampsetid=234, reason='foo',
- submitted_at=1300305712, results=-1),
- fakedb.BuildRequest(id=19, buildsetid=30, buildername='A',
- priority=13, submitted_at=1300305712, results=-1),
- ]
-
- self.addSlaves({'test-slave1':1, 'test-slave2': 1})
-
- def mergeRequests_fn(builder, breq, other):
- # Allow all requests
- self.fail("Should never be called")
- return True
- self.bldr.getMergeRequestsFn = lambda : mergeRequests_fn
-
- # check if the request remains the same
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[19],
- exp_builds=[
- ('test-slave1', [19]),
- ])
-
- @mock.patch('random.choice', nth_slave(0))
- @defer.inlineCallbacks
- def test_mergeRequests_no_merging(self):
- """ Test if builder test for codebases in requests """
- # set up all of the data required for a BuildRequest object
- rows = [
- fakedb.SourceStampSet(id=234),
- fakedb.SourceStamp(id=234, sourcestampsetid=234, codebase='C'),
- fakedb.Buildset(id=30, sourcestampsetid=234, reason='foo',
- submitted_at=1300305712, results=-1),
- fakedb.SourceStampSet(id=235),
- fakedb.SourceStamp(id=235, sourcestampsetid=235, codebase='C'),
- fakedb.Buildset(id=31, sourcestampsetid=235, reason='foo',
- submitted_at=1300305712, results=-1),
- fakedb.SourceStampSet(id=236),
- fakedb.SourceStamp(id=236, sourcestampsetid=236, codebase='C'),
- fakedb.Buildset(id=32, sourcestampsetid=236, reason='foo',
- submitted_at=1300305712, results=-1),
- fakedb.BuildRequest(id=19, buildsetid=30, buildername='A',
- priority=13, submitted_at=1300305712, results=-1),
- fakedb.BuildRequest(id=20, buildsetid=31, buildername='A',
- priority=13, submitted_at=1300305712, results=-1),
- fakedb.BuildRequest(id=21, buildsetid=32, buildername='A',
- priority=13, submitted_at=1300305712, results=-1),
- ]
-
- self.addSlaves({'test-slave1':1, 'test-slave2': 1})
-
- def mergeRequests_fn(builder, breq, other):
- # Fail all merge attempts
- return False
- self.bldr.getMergeRequestsFn = lambda : mergeRequests_fn
-
- # check if all are merged
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[19, 20],
- exp_builds=[
- ('test-slave1', [19]),
- ('test-slave2', [20]),
- ])
-
- @defer.inlineCallbacks
- def test_mergeRequests_fails(self):
- def mergeRequests_fn(*args):
- raise RuntimeError("xx")
- self.bldr.getMergeRequestsFn = lambda : mergeRequests_fn
-
- self.addSlaves({'test-slave1':1, 'test-slave2':1})
- rows = self.base_rows + [
- fakedb.BuildRequest(id=11, buildsetid=11, buildername="bldr"),
- ]
- yield self.do_test_maybeStartBuildsOnBuilder(rows=rows,
- exp_claims=[], exp_builds=[])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildstep.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildstep.py
deleted file mode 100644
index 62dff108..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_buildstep.py
+++ /dev/null
@@ -1,272 +0,0 @@
-# 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 re
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from twisted.python import log
-from buildbot.process import buildstep
-from buildbot.process.buildstep import regex_log_evaluator
-from buildbot.status.results import FAILURE, SUCCESS, WARNINGS, EXCEPTION
-from buildbot.test.fake import fakebuild, remotecommand
-from buildbot.test.util import config, steps, compat
-from buildbot.util.eventual import eventually
-
-class FakeLogFile:
- def __init__(self, text):
- self.text = text
-
- def getText(self):
- return self.text
-
-class FakeStepStatus:
- pass
-
-class TestRegexLogEvaluator(unittest.TestCase):
-
- def makeRemoteCommand(self, rc, stdout, stderr=''):
- cmd = remotecommand.FakeRemoteCommand('cmd', {})
- cmd.fakeLogData(self, 'stdio', stdout=stdout, stderr=stderr)
- cmd.rc = rc
- return cmd
-
- def test_find_worse_status(self):
- cmd = self.makeRemoteCommand(0, 'This is a big step')
- step_status = FakeStepStatus()
- r = [(re.compile("This is"), WARNINGS)]
- new_status = regex_log_evaluator(cmd, step_status, r)
- self.assertEqual(new_status, WARNINGS,
- "regex_log_evaluator returned %d, expected %d"
- % (new_status, WARNINGS))
-
- def test_multiple_regexes(self):
- cmd = self.makeRemoteCommand(0, "Normal stdout text\nan error")
- step_status = FakeStepStatus()
- r = [(re.compile("Normal stdout"), SUCCESS),
- (re.compile("error"), FAILURE)]
- new_status = regex_log_evaluator(cmd, step_status, r)
- self.assertEqual(new_status, FAILURE,
- "regex_log_evaluator returned %d, expected %d"
- % (new_status, FAILURE))
-
- def test_exception_not_in_stdout(self):
- cmd = self.makeRemoteCommand(0,
- "Completely normal output", "exception output")
- step_status = FakeStepStatus()
- r = [(re.compile("exception"), EXCEPTION)]
- new_status = regex_log_evaluator(cmd, step_status, r)
- self.assertEqual(new_status, EXCEPTION,
- "regex_log_evaluator returned %d, expected %d"
- % (new_status, EXCEPTION))
-
- def test_pass_a_string(self):
- cmd = self.makeRemoteCommand(0, "Output", "Some weird stuff on stderr")
- step_status = FakeStepStatus()
- r = [("weird stuff", WARNINGS)]
- new_status = regex_log_evaluator(cmd, step_status, r)
- self.assertEqual(new_status, WARNINGS,
- "regex_log_evaluator returned %d, expected %d"
- % (new_status, WARNINGS))
-
-
-class TestBuildStep(steps.BuildStepMixin, config.ConfigErrorsMixin, unittest.TestCase):
-
- class FakeBuildStep(buildstep.BuildStep):
- def start(self):
- eventually(self.finished, 0)
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- # support
-
- def _setupWaterfallTest(self, hideStepIf, expect, expectedResult=SUCCESS):
- self.setupStep(TestBuildStep.FakeBuildStep(hideStepIf=hideStepIf))
- self.expectOutcome(result=expectedResult, status_text=["generic"])
- self.expectHidden(expect)
-
- # tests
-
- def test_nameIsntString(self):
- """
- When BuildStep is passed a name that isn't a string, it reports
- a config error.
- """
- self.assertRaisesConfigError("BuildStep name must be a string",
- lambda: buildstep.BuildStep(name=5))
-
- def test_unexpectedKeywordArgument(self):
- """
- When BuildStep is passed an unknown keyword argument, it reports
- a config error.
- """
- self.assertRaisesConfigError("__init__ got unexpected keyword argument(s) ['oogaBooga']",
- lambda: buildstep.BuildStep(oogaBooga=5))
-
-
- def test_getProperty(self):
- bs = buildstep.BuildStep()
- bs.build = fakebuild.FakeBuild()
- props = bs.build.build_status.properties = mock.Mock()
- bs.getProperty("xyz", 'b')
- props.getProperty.assert_called_with("xyz", 'b')
- bs.getProperty("xyz")
- props.getProperty.assert_called_with("xyz", None)
-
- def test_setProperty(self):
- bs = buildstep.BuildStep()
- bs.build = fakebuild.FakeBuild()
- props = bs.build.build_status.properties = mock.Mock()
- bs.setProperty("x", "y", "t")
- props.setProperty.assert_called_with("x", "y", "t", runtime=True)
- bs.setProperty("x", "abc", "test", runtime=True)
- props.setProperty.assert_called_with("x", "abc", "test", runtime=True)
-
- def test_hideStepIf_False(self):
- self._setupWaterfallTest(False, False)
- return self.runStep()
-
- def test_hideStepIf_True(self):
- self._setupWaterfallTest(True, True)
- return self.runStep()
-
- def test_hideStepIf_Callable_False(self):
- called = [False]
- def shouldHide(result, step):
- called[0] = True
- self.assertTrue(step is self.step)
- self.assertEquals(result, SUCCESS)
- return False
-
- self._setupWaterfallTest(shouldHide, False)
-
- d = self.runStep()
- d.addCallback(lambda _ : self.assertTrue(called[0]))
- return d
-
- def test_hideStepIf_Callable_True(self):
- called = [False]
- def shouldHide(result, step):
- called[0] = True
- self.assertTrue(step is self.step)
- self.assertEquals(result, SUCCESS)
- return True
-
- self._setupWaterfallTest(shouldHide, True)
-
- d = self.runStep()
- d.addCallback(lambda _ : self.assertTrue(called[0]))
- return d
-
- def test_hideStepIf_fails(self):
- # 0/0 causes DivideByZeroError, which should be flagged as an exception
- self._setupWaterfallTest(lambda : 0/0, False, expectedResult=EXCEPTION)
- return self.runStep()
-
- @compat.usesFlushLoggedErrors
- def test_hideStepIf_Callable_Exception(self):
- called = [False]
- def shouldHide(result, step):
- called[0] = True
- self.assertTrue(step is self.step)
- self.assertEquals(result, EXCEPTION)
- return True
-
- def createException(*args, **kwargs):
- raise RuntimeError()
-
- self.setupStep(self.FakeBuildStep(hideStepIf=shouldHide,
- doStepIf=createException))
- self.expectOutcome(result=EXCEPTION,
- status_text=['generic', 'exception'])
- self.expectHidden(True)
-
- d = self.runStep()
- d.addErrback(log.err)
- d.addCallback(lambda _ :
- self.assertEqual(len(self.flushLoggedErrors(defer.FirstError)), 1))
- d.addCallback(lambda _:
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1))
- d.addCallback(lambda _ : self.assertTrue(called[0]))
- return d
-
-
-class TestLoggingBuildStep(unittest.TestCase):
-
- def makeRemoteCommand(self, rc, stdout, stderr=''):
- cmd = remotecommand.FakeRemoteCommand('cmd', {})
- cmd.fakeLogData(self, 'stdio', stdout=stdout, stderr=stderr)
- cmd.rc = rc
- return cmd
-
- def test_evaluateCommand_success(self):
- cmd = self.makeRemoteCommand(0, "Log text", "Log text")
- lbs = buildstep.LoggingBuildStep()
- status = lbs.evaluateCommand(cmd)
- self.assertEqual(status, SUCCESS, "evaluateCommand returned %d, should've returned %d" % (status, SUCCESS))
-
- def test_evaluateCommand_failed(self):
- cmd = self.makeRemoteCommand(23, "Log text", "")
- lbs = buildstep.LoggingBuildStep()
- status = lbs.evaluateCommand(cmd)
- self.assertEqual(status, FAILURE, "evaluateCommand returned %d, should've returned %d" % (status, FAILURE))
-
- def test_evaluateCommand_log_eval_func(self):
- cmd = self.makeRemoteCommand(0, "Log text")
- def eval(cmd, step_status):
- return WARNINGS
- lbs = buildstep.LoggingBuildStep(log_eval_func=eval)
- status = lbs.evaluateCommand(cmd)
- self.assertEqual(status, WARNINGS, "evaluateCommand didn't call log_eval_func or overrode its results")
-
-
-class FailingCustomStep(buildstep.LoggingBuildStep):
-
- def __init__(self, exception=buildstep.BuildStepFailed, *args, **kwargs):
- buildstep.LoggingBuildStep.__init__(self, *args, **kwargs)
- self.exception = exception
-
- @defer.inlineCallbacks
- def start(self):
- yield defer.succeed(None)
- raise self.exception()
-
-
-class TestCustomStepExecution(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_step_raining_buildstepfailed_in_start(self):
- self.setupStep(FailingCustomStep())
- self.expectOutcome(result=FAILURE, status_text=["generic"])
- return self.runStep()
-
- def test_step_raising_exception_in_start(self):
- self.setupStep(FailingCustomStep(exception=ValueError))
- self.expectOutcome(result=EXCEPTION, status_text=["generic", "exception"])
- d = self.runStep()
- @d.addCallback
- def cb(_):
- self.assertEqual(len(self.flushLoggedErrors(ValueError)), 1)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_cache.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_cache.py
deleted file mode 100644
index 508d14a4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_cache.py
+++ /dev/null
@@ -1,53 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-from buildbot.process import cache
-
-class CacheManager(unittest.TestCase):
-
- def setUp(self):
- self.caches = cache.CacheManager()
-
- def make_config(self, **kwargs):
- cfg = mock.Mock()
- cfg.caches = kwargs
- return cfg
-
- def test_get_cache_idempotency(self):
- foo_cache = self.caches.get_cache("foo", None)
- bar_cache = self.caches.get_cache("bar", None)
- foo_cache2 = self.caches.get_cache("foo", None)
- self.assertIdentical(foo_cache, foo_cache2)
- self.assertNotIdentical(foo_cache, bar_cache)
-
- def test_reconfigService(self):
- # load config with one cache loaded and the other not
- foo_cache = self.caches.get_cache("foo", None)
- d = self.caches.reconfigService(
- self.make_config(foo=5, bar=6, bing=11))
- @d.addCallback
- def check(_):
- bar_cache = self.caches.get_cache("bar", None)
- self.assertEqual((foo_cache.max_size, bar_cache.max_size),
- (5, 6))
-
- def test_get_metrics(self):
- self.caches.get_cache("foo", None)
- self.assertIn('foo', self.caches.get_metrics())
- metric = self.caches.get_metrics()['foo']
- for k in 'hits', 'refhits', 'misses', 'max_size':
- self.assertIn(k, metric)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_debug.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_debug.py
deleted file mode 100644
index 1170ca66..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_debug.py
+++ /dev/null
@@ -1,146 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from twisted.application import service
-from buildbot.process import debug
-from buildbot import config
-
-class FakeManhole(service.Service):
- pass
-
-class TestDebugServices(unittest.TestCase):
-
- def setUp(self):
- self.master = mock.Mock(name='master')
- self.config = config.MasterConfig()
-
- @defer.inlineCallbacks
- def test_reconfigService_debug(self):
- # mock out PBManager
- self.master.pbmanager = pbmanager = mock.Mock()
- registration = mock.Mock(name='registration')
- registration.unregister = mock.Mock(name='unregister',
- side_effect=lambda : defer.succeed(None))
- pbmanager.register.return_value = registration
-
- ds = debug.DebugServices(self.master)
- ds.startService()
-
- # start off with no debug password
- self.config.slavePortnum = '9824'
- self.config.debugPassword = None
- yield ds.reconfigService(self.config)
-
- self.assertFalse(pbmanager.register.called)
-
- # set the password, and see it register
- self.config.debugPassword = 'seeeekrit'
- yield ds.reconfigService(self.config)
-
- self.assertTrue(pbmanager.register.called)
- self.assertEqual(pbmanager.register.call_args[0][:3],
- ('9824', 'debug', 'seeeekrit'))
- factory = pbmanager.register.call_args[0][3]
- self.assertIsInstance(factory(mock.Mock(), mock.Mock()),
- debug.DebugPerspective)
-
- # change the password, and see it re-register
- self.config.debugPassword = 'lies'
- pbmanager.register.reset_mock()
- yield ds.reconfigService(self.config)
-
- self.assertTrue(registration.unregister.called)
- self.assertTrue(pbmanager.register.called)
- self.assertEqual(pbmanager.register.call_args[0][:3],
- ('9824', 'debug', 'lies'))
-
- # remove the password, and see it unregister
- self.config.debugPassword = None
- pbmanager.register.reset_mock()
- registration.unregister.reset_mock()
- yield ds.reconfigService(self.config)
-
- self.assertTrue(registration.unregister.called)
- self.assertFalse(pbmanager.register.called)
-
- # re-register to test stopService
- self.config.debugPassword = 'confusion'
- pbmanager.register.reset_mock()
- yield ds.reconfigService(self.config)
-
- # stop the service, and see that it unregisters
- pbmanager.register.reset_mock()
- registration.unregister.reset_mock()
- yield ds.stopService()
-
- self.assertTrue(registration.unregister.called)
-
- @defer.inlineCallbacks
- def test_reconfigService_manhole(self):
- master = mock.Mock(name='master')
- ds = debug.DebugServices(master)
- ds.startService()
-
- # start off with no manhole
- yield ds.reconfigService(self.config)
-
- # set a manhole, fire it up
- self.config.manhole = manhole = FakeManhole()
- yield ds.reconfigService(self.config)
-
- self.assertTrue(manhole.running)
- self.assertIdentical(manhole.master, master)
-
- # unset it, see it stop
- self.config.manhole = None
- yield ds.reconfigService(self.config)
-
- self.assertFalse(manhole.running)
- self.assertIdentical(manhole.master, None)
-
- # re-start to test stopService
- self.config.manhole = manhole
- yield ds.reconfigService(self.config)
-
- # stop the service, and see that it unregisters
- yield ds.stopService()
-
- self.assertFalse(manhole.running)
- self.assertIdentical(manhole.master, None)
-
-
-class TestDebugPerspective(unittest.TestCase):
-
- def setUp(self):
- self.master = mock.Mock()
- self.persp = debug.DebugPerspective(self.master)
-
- def test_attached(self):
- self.assertIdentical(self.persp.attached(mock.Mock()), self.persp)
-
- def test_detached(self):
- self.persp.detached(mock.Mock()) # just shouldn't crash
-
- def test_perspective_reload(self):
- d = defer.maybeDeferred(lambda : self.persp.perspective_reload())
- def check(_):
- self.master.reconfig.assert_called_with()
- d.addCallback(check)
- return d
-
- # remaining methods require IControl adapters or other weird stuff.. TODO
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_factory.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_factory.py
deleted file mode 100644
index 2724f924..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_factory.py
+++ /dev/null
@@ -1,81 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-
-from buildbot.process.factory import BuildFactory, s
-from buildbot.process.buildstep import BuildStep, _BuildStepFactory
-
-class TestBuildFactory(unittest.TestCase):
-
- def test_init(self):
- step = BuildStep()
- factory = BuildFactory([step])
- self.assertEqual(factory.steps, [_BuildStepFactory(BuildStep)])
-
- def test_addStep(self):
- step = BuildStep()
- factory = BuildFactory()
- factory.addStep(step)
- self.assertEqual(factory.steps, [_BuildStepFactory(BuildStep)])
-
- def test_addStep_deprecated_withArguments(self):
- """
- Passing keyword arguments to L{BuildFactory.addStep} is deprecated,
- but pass the arguments to the first argument, to construct a step.
- """
- factory = BuildFactory()
- factory.addStep(BuildStep, name='test')
- self.assertEqual(factory.steps, [_BuildStepFactory(BuildStep, name='test')])
- warnings = self.flushWarnings([self.test_addStep_deprecated_withArguments])
- self.assertEqual(len(warnings), 1)
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
-
- def test_addStep_deprecated(self):
- """
- Passing keyword arguments to L{BuildFactory.addStep} is deprecated,
- but pass the arguments to the first argument, to construct a step.
- """
- factory = BuildFactory()
- factory.addStep(BuildStep)
- self.assertEqual(factory.steps, [_BuildStepFactory(BuildStep)])
- warnings = self.flushWarnings([self.test_addStep_deprecated])
- self.assertEqual(len(warnings), 1)
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
-
- def test_s(self):
- """
- L{s} is deprecated, but pass keyword arguments to the first argument,
- to construct a step.
- """
- stepFactory = s(BuildStep, name='test')
- self.assertEqual(stepFactory, _BuildStepFactory(BuildStep, name='test'))
- warnings = self.flushWarnings([self.test_s])
- self.assertEqual(len(warnings), 1)
- self.assertEqual(warnings[0]['category'], DeprecationWarning)
-
- def test_addStep_notAStep(self):
- factory = BuildFactory()
- # This fails because object isn't adaptable to IBuildStepFactory
- self.assertRaises(TypeError, factory.addStep, object())
-
- def test_addStep_ArgumentsInTheWrongPlace(self):
- factory = BuildFactory()
- self.assertRaises(TypeError, factory.addStep, BuildStep(), name="name")
-
- def test_addSteps(self):
- factory = BuildFactory()
- factory.addSteps([BuildStep(), BuildStep()])
- self.assertEqual(factory.steps, [_BuildStepFactory(BuildStep), _BuildStepFactory(BuildStep)])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_metrics.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_metrics.py
deleted file mode 100644
index 49d90011..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_metrics.py
+++ /dev/null
@@ -1,233 +0,0 @@
-# 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 gc, sys
-from twisted.trial import unittest
-from twisted.internet import task
-from buildbot.process import metrics
-from buildbot.test.fake import fakemaster
-
-class TestMetricBase(unittest.TestCase):
- def setUp(self):
- self.clock = task.Clock()
- self.observer = metrics.MetricLogObserver()
- self.observer.parent = self.master = fakemaster.make_master()
- self.master.config.db['db_poll_interval'] = 60
- self.master.config.metrics = dict(log_interval=0, periodic_interval=0)
- self.observer._reactor = self.clock
- self.observer.startService()
- self.observer.reconfigService(self.master.config)
-
- def tearDown(self):
- if self.observer.running:
- self.observer.stopService()
-
-class TestMetricCountEvent(TestMetricBase):
- def testIncrement(self):
- metrics.MetricCountEvent.log('num_widgets', 1)
- report = self.observer.asDict()
- self.assertEquals(report['counters']['num_widgets'], 1)
-
- metrics.MetricCountEvent.log('num_widgets', 1)
- report = self.observer.asDict()
- self.assertEquals(report['counters']['num_widgets'], 2)
-
- def testDecrement(self):
- metrics.MetricCountEvent.log('num_widgets', 1)
- report = self.observer.asDict()
- self.assertEquals(report['counters']['num_widgets'], 1)
-
- metrics.MetricCountEvent.log('num_widgets', -1)
- report = self.observer.asDict()
- self.assertEquals(report['counters']['num_widgets'], 0)
-
- def testAbsolute(self):
- metrics.MetricCountEvent.log('num_widgets', 10, absolute=True)
- report = self.observer.asDict()
- self.assertEquals(report['counters']['num_widgets'], 10)
-
- def testCountMethod(self):
- @metrics.countMethod('foo_called')
- def foo():
- return "foo!"
-
- for i in range(10):
- foo()
- report = self.observer.asDict()
- self.assertEquals(report['counters']['foo_called'], 10)
-
-class TestMetricTimeEvent(TestMetricBase):
- def testManualEvent(self):
- metrics.MetricTimeEvent.log('foo_time', 0.001)
- report = self.observer.asDict()
- self.assertEquals(report['timers']['foo_time'], 0.001)
-
- def testTimer(self):
- clock = task.Clock()
- t = metrics.Timer('foo_time')
- t._reactor = clock
- t.start()
-
- clock.advance(5)
- t.stop()
-
- report = self.observer.asDict()
- self.assertEquals(report['timers']['foo_time'], 5)
-
- def testStartStopDecorators(self):
- clock = task.Clock()
- t = metrics.Timer('foo_time')
- t._reactor = clock
-
- @t.startTimer
- def foo():
- clock.advance(5)
- return "foo!"
-
- @t.stopTimer
- def bar():
- clock.advance(5)
- return "bar!"
-
- foo()
- bar()
- report = self.observer.asDict()
- self.assertEquals(report['timers']['foo_time'], 10)
-
- def testTimeMethod(self):
- clock = task.Clock()
- @metrics.timeMethod('foo_time', _reactor=clock)
- def foo():
- clock.advance(5)
- return "foo!"
- foo()
- report = self.observer.asDict()
- self.assertEquals(report['timers']['foo_time'], 5)
-
- def testAverages(self):
- data = range(10)
- for i in data:
- metrics.MetricTimeEvent.log('foo_time', i)
- report = self.observer.asDict()
- self.assertEquals(report['timers']['foo_time'], sum(data)/float(len(data)))
-
-class TestPeriodicChecks(TestMetricBase):
- def testPeriodicCheck(self):
- # fake out that there's no garbage (since we can't rely on Python
- # not having any garbage while running tests)
- self.patch(gc, 'garbage', [])
-
- clock = task.Clock()
- metrics.periodicCheck(_reactor=clock)
- clock.pump([0.1, 0.1, 0.1])
-
- # We should have 0 reactor delay since we're using a fake clock
- report = self.observer.asDict()
- self.assertEquals(report['timers']['reactorDelay'], 0)
- self.assertEquals(report['counters']['gc.garbage'], 0)
- self.assertEquals(report['alarms']['gc.garbage'][0], 'OK')
-
- def testUncollectable(self):
- # make some fake garbage
- self.patch(gc, 'garbage', [ 1, 2 ])
-
- clock = task.Clock()
- metrics.periodicCheck(_reactor=clock)
- clock.pump([0.1, 0.1, 0.1])
-
- # We should have 0 reactor delay since we're using a fake clock
- report = self.observer.asDict()
- self.assertEquals(report['timers']['reactorDelay'], 0)
- self.assertEquals(report['counters']['gc.garbage'], 2)
- self.assertEquals(report['alarms']['gc.garbage'][0], 'WARN')
-
- def testGetRSS(self):
- self.assert_(metrics._get_rss() > 0)
- if sys.platform != 'linux2':
- testGetRSS.skip = "only available on linux2 platforms"
-
-class TestReconfig(TestMetricBase):
- def testReconfig(self):
- observer = self.observer
- new_config = self.master.config
-
- # starts up without running tasks
- self.assertEquals(observer.log_task, None)
- self.assertEquals(observer.periodic_task, None)
-
- # enable log_interval
- new_config.metrics = dict(log_interval=10, periodic_interval=0)
- observer.reconfigService(new_config)
- self.assert_(observer.log_task)
- self.assertEquals(observer.periodic_task, None)
-
- # disable that and enable periodic_interval
- new_config.metrics = dict(periodic_interval=10, log_interval=0)
- observer.reconfigService(new_config)
- self.assert_(observer.periodic_task)
- self.assertEquals(observer.log_task, None)
-
- # Make the periodic check run
- self.clock.pump([0.1])
-
- # disable the whole listener
- new_config.metrics = None
- observer.reconfigService(new_config)
- self.assertFalse(observer.enabled)
- self.assertEquals(observer.log_task, None)
- self.assertEquals(observer.periodic_task, None)
-
- # disable both
- new_config.metrics = dict(periodic_interval=0, log_interval=0)
- observer.reconfigService(new_config)
- self.assertEquals(observer.log_task, None)
- self.assertEquals(observer.periodic_task, None)
-
- # enable both
- new_config.metrics = dict(periodic_interval=10, log_interval=10)
- observer.reconfigService(new_config)
- self.assert_(observer.log_task)
- self.assert_(observer.periodic_task)
-
- # (service will be stopped by tearDown)
-
-class _LogObserver:
- def __init__(self):
- self.events = []
-
- def gotEvent(self, event):
- self.events.append(event)
-
-class TestReports(unittest.TestCase):
- def testMetricCountReport(self):
- handler = metrics.MetricCountHandler(None)
- handler.handle({}, metrics.MetricCountEvent('num_foo', 1))
-
- self.assertEquals("Counter num_foo: 1", handler.report())
- self.assertEquals({"counters": {"num_foo": 1}}, handler.asDict())
-
- def testMetricTimeReport(self):
- handler = metrics.MetricTimeHandler(None)
- handler.handle({}, metrics.MetricTimeEvent('time_foo', 1))
-
- self.assertEquals("Timer time_foo: 1", handler.report())
- self.assertEquals({"timers": {"time_foo": 1}}, handler.asDict())
-
- def testMetricAlarmReport(self):
- handler = metrics.MetricAlarmHandler(None)
- handler.handle({}, metrics.MetricAlarmEvent('alarm_foo', msg='Uh oh', level=metrics.ALARM_WARN))
-
- self.assertEquals("WARN alarm_foo: Uh oh", handler.report())
- self.assertEquals({"alarms": {"alarm_foo": ("WARN", "Uh oh")}}, handler.asDict())
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_properties.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_properties.py
deleted file mode 100644
index 040bedad..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_properties.py
+++ /dev/null
@@ -1,1407 +0,0 @@
-# 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 mock
-from zope.interface import implements
-from twisted.internet import defer
-from twisted.trial import unittest
-from twisted.python import components
-from buildbot.process.properties import Properties, WithProperties
-from buildbot.process.properties import Interpolate
-from buildbot.process.properties import _Lazy, _SourceStampDict, _Lookup
-from buildbot.process.properties import Property, PropertiesMixin, renderer
-from buildbot.interfaces import IRenderable, IProperties
-from buildbot.test.fake.fakebuild import FakeBuild
-from buildbot.test.util.config import ConfigErrorsMixin
-from buildbot.test.util.properties import ConstantRenderable
-from buildbot.test.util import compat
-
-class FakeSource:
- def __init__(self):
- self.branch = None
- self.codebase = ''
- self.project = ''
- self.repository = ''
- self.revision = None
-
- def asDict(self):
- ds = {}
- ds['branch'] = self.branch
- ds['codebase'] = self.codebase
- ds['project'] = self.project
- ds['repository'] = self.repository
- ds['revision'] = self.revision
- return ds
-
-class DeferredRenderable:
- implements (IRenderable)
- def __init__(self):
- self.d = defer.Deferred()
- def getRenderingFor(self, build):
- return self.d
- def callback(self, value):
- self.d.callback(value)
-
-class TestPropertyMap(unittest.TestCase):
- """
- Test the behavior of PropertyMap, using the external interace
- provided by WithProperties.
- """
-
- def setUp(self):
- self.props = Properties(
- prop_str='a-string',
- prop_none=None,
- prop_list=['a', 'b'],
- prop_zero=0,
- prop_one=1,
- prop_false=False,
- prop_true=True,
- prop_empty='',
- )
- self.build = FakeBuild(self.props)
-
- def doTestSimpleWithProperties(self, fmtstring, expect, **kwargs):
- d = self.build.render(WithProperties(fmtstring, **kwargs))
- d.addCallback(self.failUnlessEqual, "%s" % expect)
- return d
-
- def testSimpleStr(self):
- return self.doTestSimpleWithProperties('%(prop_str)s', 'a-string')
-
- def testSimpleNone(self):
- # None is special-cased to become an empty string
- return self.doTestSimpleWithProperties('%(prop_none)s', '')
-
- def testSimpleList(self):
- return self.doTestSimpleWithProperties('%(prop_list)s', ['a', 'b'])
-
- def testSimpleZero(self):
- return self.doTestSimpleWithProperties('%(prop_zero)s', 0)
-
- def testSimpleOne(self):
- return self.doTestSimpleWithProperties('%(prop_one)s', 1)
-
- def testSimpleFalse(self):
- return self.doTestSimpleWithProperties('%(prop_false)s', False)
-
- def testSimpleTrue(self):
- return self.doTestSimpleWithProperties('%(prop_true)s', True)
-
- def testSimpleEmpty(self):
- return self.doTestSimpleWithProperties('%(prop_empty)s', '')
-
- def testSimpleUnset(self):
- d = self.build.render(WithProperties('%(prop_nosuch)s'))
- return self.assertFailure(d, KeyError)
-
-
- def testColonMinusSet(self):
- return self.doTestSimpleWithProperties('%(prop_str:-missing)s', 'a-string')
-
- def testColonMinusNone(self):
- # None is special-cased here, too
- return self.doTestSimpleWithProperties('%(prop_none:-missing)s', '')
-
- def testColonMinusZero(self):
- return self.doTestSimpleWithProperties('%(prop_zero:-missing)s', 0)
-
- def testColonMinusOne(self):
- return self.doTestSimpleWithProperties('%(prop_one:-missing)s', 1)
-
- def testColonMinusFalse(self):
- return self.doTestSimpleWithProperties('%(prop_false:-missing)s', False)
-
- def testColonMinusTrue(self):
- return self.doTestSimpleWithProperties('%(prop_true:-missing)s', True)
-
- def testColonMinusEmpty(self):
- return self.doTestSimpleWithProperties('%(prop_empty:-missing)s', '')
-
- def testColonMinusUnset(self):
- return self.doTestSimpleWithProperties('%(prop_nosuch:-missing)s', 'missing')
-
-
- def testColonTildeSet(self):
- return self.doTestSimpleWithProperties('%(prop_str:~missing)s', 'a-string')
-
- def testColonTildeNone(self):
- # None is special-cased *differently* for ~:
- return self.doTestSimpleWithProperties('%(prop_none:~missing)s', 'missing')
-
- def testColonTildeZero(self):
- return self.doTestSimpleWithProperties('%(prop_zero:~missing)s', 'missing')
-
- def testColonTildeOne(self):
- return self.doTestSimpleWithProperties('%(prop_one:~missing)s', 1)
-
- def testColonTildeFalse(self):
- return self.doTestSimpleWithProperties('%(prop_false:~missing)s', 'missing')
-
- def testColonTildeTrue(self):
- return self.doTestSimpleWithProperties('%(prop_true:~missing)s', True)
-
- def testColonTildeEmpty(self):
- return self.doTestSimpleWithProperties('%(prop_empty:~missing)s', 'missing')
-
- def testColonTildeUnset(self):
- return self.doTestSimpleWithProperties('%(prop_nosuch:~missing)s', 'missing')
-
-
- def testColonPlusSet(self):
- return self.doTestSimpleWithProperties('%(prop_str:+present)s', 'present')
-
- def testColonPlusNone(self):
- return self.doTestSimpleWithProperties('%(prop_none:+present)s', 'present')
-
- def testColonPlusZero(self):
- return self.doTestSimpleWithProperties('%(prop_zero:+present)s', 'present')
-
- def testColonPlusOne(self):
- return self.doTestSimpleWithProperties('%(prop_one:+present)s', 'present')
-
- def testColonPlusFalse(self):
- return self.doTestSimpleWithProperties('%(prop_false:+present)s', 'present')
-
- def testColonPlusTrue(self):
- return self.doTestSimpleWithProperties('%(prop_true:+present)s', 'present')
-
- def testColonPlusEmpty(self):
- return self.doTestSimpleWithProperties('%(prop_empty:+present)s', 'present')
-
- def testColonPlusUnset(self):
- return self.doTestSimpleWithProperties('%(prop_nosuch:+present)s', '')
-
- def testClearTempValues(self):
- d = self.doTestSimpleWithProperties('', '',
- prop_temp=lambda b: 'present')
- d.addCallback(lambda _:
- self.doTestSimpleWithProperties('%(prop_temp:+present)s', ''))
- return d
-
- def testTempValue(self):
- self.doTestSimpleWithProperties('%(prop_temp)s', 'present',
- prop_temp=lambda b: 'present')
-
- def testTempValueOverrides(self):
- return self.doTestSimpleWithProperties('%(prop_one)s', 2,
- prop_one=lambda b: 2)
-
- def testTempValueColonMinusSet(self):
- return self.doTestSimpleWithProperties('%(prop_one:-missing)s', 2,
- prop_one=lambda b: 2)
-
- def testTempValueColonMinusUnset(self):
- return self.doTestSimpleWithProperties('%(prop_nosuch:-missing)s', 'temp',
- prop_nosuch=lambda b: 'temp')
-
- def testTempValueColonTildeTrueSet(self):
- return self.doTestSimpleWithProperties('%(prop_false:~nontrue)s', 'temp',
- prop_false=lambda b: 'temp')
-
- def testTempValueColonTildeTrueUnset(self):
- return self.doTestSimpleWithProperties('%(prop_nosuch:~nontrue)s', 'temp',
- prop_nosuch=lambda b: 'temp')
-
- def testTempValueColonTildeFalseFalse(self):
- return self.doTestSimpleWithProperties('%(prop_false:~nontrue)s', 'nontrue',
- prop_false=lambda b: False)
-
- def testTempValueColonTildeTrueFalse(self):
- return self.doTestSimpleWithProperties('%(prop_true:~nontrue)s', True,
- prop_true=lambda b: False)
-
- def testTempValueColonTildeNoneFalse(self):
- return self.doTestSimpleWithProperties('%(prop_nosuch:~nontrue)s', 'nontrue',
- prop_nosuch=lambda b: False)
-
-
- def testTempValueColonTildeFalseZero(self):
- return self.doTestSimpleWithProperties('%(prop_false:~nontrue)s', 'nontrue',
- prop_false=lambda b: 0)
-
- def testTempValueColonTildeTrueZero(self):
- return self.doTestSimpleWithProperties('%(prop_true:~nontrue)s', True,
- prop_true=lambda b: 0)
-
- def testTempValueColonTildeNoneZero(self):
- return self.doTestSimpleWithProperties('%(prop_nosuch:~nontrue)s', 'nontrue',
- prop_nosuch=lambda b: 0)
-
- def testTempValueColonTildeFalseBlank(self):
- return self.doTestSimpleWithProperties('%(prop_false:~nontrue)s', 'nontrue',
- prop_false=lambda b: '')
-
- def testTempValueColonTildeTrueBlank(self):
- return self.doTestSimpleWithProperties('%(prop_true:~nontrue)s', True,
- prop_true=lambda b: '')
-
- def testTempValueColonTildeNoneBlank(self):
- return self.doTestSimpleWithProperties('%(prop_nosuch:~nontrue)s', 'nontrue',
- prop_nosuch=lambda b: '')
-
- def testTempValuePlusSetSet(self):
- return self.doTestSimpleWithProperties('%(prop_one:+set)s', 'set',
- prop_one=lambda b: 2)
-
- def testTempValuePlusUnsetSet(self):
- return self.doTestSimpleWithProperties('%(prop_nosuch:+set)s', 'set',
- prop_nosuch=lambda b: 1)
-
-
-class TestInterpolateConfigure(unittest.TestCase, ConfigErrorsMixin):
- """
- Test that Interpolate reports erros in the interpolation string
- at configure time.
- """
-
- def test_invalid_args_and_kwargs(self):
- self.assertRaisesConfigError("Interpolate takes either positional",
- lambda : Interpolate("%s %(foo)s", 1, foo=2))
-
- def test_invalid_selector(self):
- self.assertRaisesConfigError("invalid Interpolate selector 'garbage'",
- lambda: Interpolate("%(garbage:test)s"))
-
- def test_no_selector(self):
- self.assertRaisesConfigError("invalid Interpolate substitution without selector 'garbage'",
- lambda: Interpolate("%(garbage)s"))
-
- def test_invalid_default_type(self):
- self.assertRaisesConfigError("invalid Interpolate default type '@'",
- lambda: Interpolate("%(prop:some_prop:@wacky)s"))
-
- def test_nested_invalid_selector(self):
- self.assertRaisesConfigError("invalid Interpolate selector 'garbage'",
- lambda: Interpolate("%(prop:some_prop:~%(garbage:test)s)s"))
-
- def test_colon_ternary_missing_delimeter(self):
- self.assertRaisesConfigError("invalid Interpolate ternary expression 'one' with delimiter ':'",
- lambda: Interpolate("echo '%(prop:P:?:one)s'"))
-
- def test_colon_ternary_paren_delimiter(self):
- self.assertRaisesConfigError("invalid Interpolate ternary expression 'one(:)' with delimiter ':'",
- lambda: Interpolate("echo '%(prop:P:?:one(:))s'"))
-
- def test_colon_ternary_hash_bad_delimeter(self):
- self.assertRaisesConfigError("invalid Interpolate ternary expression 'one' with delimiter '|'",
- lambda: Interpolate("echo '%(prop:P:#?|one)s'"))
-
- def test_prop_invalid_character(self):
- self.assertRaisesConfigError("Property name must be alphanumeric for prop Interpolation 'a+a'",
- lambda: Interpolate("echo '%(prop:a+a)s'"))
-
- def test_kw_invalid_character(self):
- self.assertRaisesConfigError("Keyword must be alphanumeric for kw Interpolation 'a+a'",
- lambda: Interpolate("echo '%(kw:a+a)s'"))
-
- def test_src_codebase_invalid_character(self):
- self.assertRaisesConfigError("Codebase must be alphanumeric for src Interpolation 'a+a:a'",
- lambda: Interpolate("echo '%(src:a+a:a)s'"))
-
- def test_src_attr_invalid_character(self):
- self.assertRaisesConfigError("Attribute must be alphanumeric for src Interpolation 'a:a+a'",
- lambda: Interpolate("echo '%(src:a:a+a)s'"))
-
- def test_src_missing_attr(self):
- self.assertRaisesConfigError("Must specify both codebase and attr",
- lambda: Interpolate("echo '%(src:a)s'"))
-
-
-class TestInterpolatePositional(unittest.TestCase):
- def setUp(self):
- self.props = Properties()
- self.build = FakeBuild(self.props)
-
- def test_string(self):
- command = Interpolate("test %s", "one fish")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "test one fish")
-
- def test_twoString(self):
- command = Interpolate("test %s, %s", "one fish", "two fish")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "test one fish, two fish")
-
- def test_deferred(self):
- renderable = DeferredRenderable()
- command = Interpolate("echo '%s'", renderable)
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'red fish'")
- renderable.callback("red fish")
- return d
-
- def test_renderable(self):
- self.props.setProperty("buildername", "blue fish", "test")
- command = Interpolate("echo '%s'", Property("buildername"))
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'blue fish'")
- return d
-
-
-
-class TestInterpolateProperties(unittest.TestCase):
- def setUp(self):
- self.props = Properties()
- self.build = FakeBuild(self.props)
-
- def test_properties(self):
- self.props.setProperty("buildername", "winbld", "test")
- command = Interpolate("echo buildby-%(prop:buildername)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo buildby-winbld")
- return d
-
- def test_properties_newline(self):
- self.props.setProperty("buildername", "winbld", "test")
- command = Interpolate("aa\n%(prop:buildername)s\nbb")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "aa\nwinbld\nbb")
- return d
-
- def test_property_not_set(self):
- command = Interpolate("echo buildby-%(prop:buildername)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo buildby-")
- return d
-
- def test_property_colon_minus(self):
- command = Interpolate("echo buildby-%(prop:buildername:-blddef)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo buildby-blddef")
- return d
-
- def test_property_colon_tilde_true(self):
- self.props.setProperty("buildername", "winbld", "test")
- command = Interpolate("echo buildby-%(prop:buildername:~blddef)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo buildby-winbld")
- return d
-
- def test_property_colon_tilde_false(self):
- self.props.setProperty("buildername", "", "test")
- command = Interpolate("echo buildby-%(prop:buildername:~blddef)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo buildby-blddef")
- return d
-
- def test_property_colon_plus(self):
- self.props.setProperty("project", "proj1", "test")
- command = Interpolate("echo %(prop:project:+projectdefined)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo projectdefined")
- return d
-
- def test_nested_property(self):
- self.props.setProperty("project", "so long!", "test")
- command = Interpolate("echo '%(prop:missing:~%(prop:project)s)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'so long!'")
- return d
-
- def test_property_substitute_recursively(self):
- self.props.setProperty("project", "proj1", "test")
- command = Interpolate("echo '%(prop:no_such:-%(prop:project)s)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'proj1'")
- return d
-
- def test_property_colon_ternary_present(self):
- self.props.setProperty("project", "proj1", "test")
- command = Interpolate("echo %(prop:project:?:defined:missing)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo defined")
- return d
-
- def test_property_colon_ternary_missing(self):
- command = Interpolate("echo %(prop:project:?|defined|missing)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo missing")
- return d
-
- def test_property_colon_ternary_hash_true(self):
- self.props.setProperty("project", "winbld", "test")
- command = Interpolate("echo buildby-%(prop:project:#?:T:F)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo buildby-T")
- return d
-
- def test_property_colon_ternary_hash_false(self):
- self.props.setProperty("project", "", "test")
- command = Interpolate("echo buildby-%(prop:project:#?|T|F)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo buildby-F")
- return d
-
- def test_property_colon_ternary_substitute_recursively_true(self):
- self.props.setProperty("P", "present", "test")
- self.props.setProperty("one", "proj1", "test")
- self.props.setProperty("two", "proj2", "test")
- command = Interpolate("echo '%(prop:P:?|%(prop:one)s|%(prop:two)s)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'proj1'")
- return d
-
- def test_property_colon_ternary_substitute_recursively_false(self):
- self.props.setProperty("one", "proj1", "test")
- self.props.setProperty("two", "proj2", "test")
- command = Interpolate("echo '%(prop:P:?|%(prop:one)s|%(prop:two)s)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'proj2'")
- return d
-
- def test_property_colon_ternary_substitute_recursively_delimited_true(self):
- self.props.setProperty("P", "present", "test")
- self.props.setProperty("one", "proj1", "test")
- self.props.setProperty("two", "proj2", "test")
- command = Interpolate("echo '%(prop:P:?|%(prop:one:?|true|false)s|%(prop:two:?|false|true)s)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'true'")
- return d
-
- def test_property_colon_ternary_substitute_recursively_delimited_false(self):
- self.props.setProperty("one", "proj1", "test")
- self.props.setProperty("two", "proj2", "test")
- command = Interpolate("echo '%(prop:P:?|%(prop:one:?|true|false)s|%(prop:two:?|false|true)s)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'false'")
- return d
-
-
-class TestInterpolateSrc(unittest.TestCase):
- def setUp(self):
- self.props = Properties()
- self.build = FakeBuild(self.props)
- sa = FakeSource()
- sb = FakeSource()
- sc = FakeSource()
-
- sa.repository = 'cvs://A..'
- sa.codebase = 'cbA'
- sa.project = "Project"
- self.build.sources['cbA'] = sa
-
- sb.repository = 'cvs://B..'
- sb.codebase = 'cbB'
- sb.project = "Project"
- self.build.sources['cbB'] = sb
-
- sc.repository = 'cvs://C..'
- sc.codebase = 'cbC'
- sc.project = None
- self.build.sources['cbC'] = sc
-
- def test_src(self):
- command = Interpolate("echo %(src:cbB:repository)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://B..")
- return d
-
- def test_src_src(self):
- command = Interpolate("echo %(src:cbB:repository)s %(src:cbB:project)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://B.. Project")
- return d
-
- def test_src_attr_empty(self):
- command = Interpolate("echo %(src:cbC:project)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo ")
- return d
-
- def test_src_attr_codebase_notfound(self):
- command = Interpolate("echo %(src:unknown_codebase:project)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo ")
- return d
-
- def test_src_colon_plus_false(self):
- command = Interpolate("echo '%(src:cbD:project:+defaultrepo)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo ''")
- return d
-
- def test_src_colon_plus_true(self):
- command = Interpolate("echo '%(src:cbB:project:+defaultrepo)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'defaultrepo'")
- return d
-
- def test_src_colon_minus(self):
- command = Interpolate("echo %(src:cbB:nonattr:-defaultrepo)s")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo defaultrepo")
- return d
-
- def test_src_colon_minus_false(self):
- command = Interpolate("echo '%(src:cbC:project:-noproject)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo ''")
- return d
-
- def test_src_colon_minus_true(self):
- command = Interpolate("echo '%(src:cbB:project:-noproject)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'Project'")
- return d
-
- def test_src_colon_minus_codebase_notfound(self):
- command = Interpolate("echo '%(src:unknown_codebase:project:-noproject)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'noproject'")
- return d
-
- def test_src_colon_tilde_true(self):
- command = Interpolate("echo '%(src:cbB:project:~noproject)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'Project'")
- return d
-
- def test_src_colon_tilde_false(self):
- command = Interpolate("echo '%(src:cbC:project:~noproject)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'noproject'")
- return d
-
- def test_src_colon_tilde_false_src_as_replacement(self):
- command = Interpolate("echo '%(src:cbC:project:~%(src:cbA:project)s)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'Project'")
- return d
-
- def test_src_colon_tilde_codebase_notfound(self):
- command = Interpolate("echo '%(src:unknown_codebase:project:~noproject)s'")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'noproject'")
- return d
-
-
-class TestInterpolateKwargs(unittest.TestCase):
- def setUp(self):
- self.props = Properties()
- self.build = FakeBuild(self.props)
- sa = FakeSource()
-
- sa.repository = 'cvs://A..'
- sa.codebase = 'cbA'
- sa.project = None
- sa.branch = "default"
- self.build.sources['cbA'] = sa
-
- def test_kwarg(self):
- command = Interpolate("echo %(kw:repository)s", repository = "cvs://A..")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://A..")
- return d
-
- def test_kwarg_kwarg(self):
- command = Interpolate("echo %(kw:repository)s %(kw:branch)s",
- repository = "cvs://A..", branch = "default")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://A.. default")
- return d
-
- def test_kwarg_not_mapped(self):
- command = Interpolate("echo %(kw:repository)s", project = "projectA")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo ")
- return d
-
- def test_kwarg_colon_minus_not_available(self):
- command = Interpolate("echo %(kw:repository)s", project = "projectA")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo ")
- return d
-
- def test_kwarg_colon_minus_not_available_default(self):
- command = Interpolate("echo %(kw:repository:-cvs://A..)s", project = "projectA")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://A..")
- return d
-
- def test_kwarg_colon_minus_available(self):
- command = Interpolate("echo %(kw:repository:-cvs://A..)s", repository = "cvs://B..")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://B..")
- return d
-
- def test_kwarg_colon_tilde_true(self):
- command = Interpolate("echo %(kw:repository:~cvs://B..)s", repository = "cvs://A..")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://A..")
- return d
-
- def test_kwarg_colon_tilde_false(self):
- command = Interpolate("echo %(kw:repository:~cvs://B..)s", repository = "")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://B..")
- return d
-
- def test_kwarg_colon_tilde_none(self):
- command = Interpolate("echo %(kw:repository:~cvs://B..)s", repository = None)
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://B..")
- return d
-
- def test_kwarg_colon_plus_false(self):
- command = Interpolate("echo %(kw:repository:+cvs://B..)s", project = "project")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo ")
- return d
-
- def test_kwarg_colon_plus_true(self):
- command = Interpolate("echo %(kw:repository:+cvs://B..)s", repository = None)
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo cvs://B..")
- return d
-
- def test_kwargs_colon_minus_false_src_as_replacement(self):
- command = Interpolate("echo '%(kw:text:-%(src:cbA:branch)s)s'", notext='ddd')
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'default'")
- return d
-
- def test_kwargs_renderable(self):
- command = Interpolate("echo '%(kw:test)s'", test = ConstantRenderable('testing'))
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'testing'")
- return d
-
- def test_kwargs_deferred(self):
- renderable = DeferredRenderable()
- command = Interpolate("echo '%(kw:test)s'", test = renderable)
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'testing'")
- renderable.callback('testing')
- return d
-
- def test_kwarg_deferred(self):
- renderable = DeferredRenderable()
- command = Interpolate("echo '%(kw:project)s'", project=renderable)
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'testing'")
- renderable.callback('testing')
- return d
-
- def test_nested_kwarg_deferred(self):
- renderable = DeferredRenderable()
- command = Interpolate("echo '%(kw:missing:~%(kw:fishy)s)s'", missing=renderable, fishy="so long!")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "echo 'so long!'")
- renderable.callback(False)
- return d
-
-class TestWithProperties(unittest.TestCase):
-
- def setUp(self):
- self.props = Properties()
- self.build = FakeBuild(self.props)
-
- def testInvalidParams(self):
- self.assertRaises(ValueError, lambda :
- WithProperties("%s %(foo)s", 1, foo=2))
-
- def testBasic(self):
- # test basic substitution with WithProperties
- self.props.setProperty("revision", "47", "test")
- command = WithProperties("build-%s.tar.gz", "revision")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "build-47.tar.gz")
- return d
-
- def testDict(self):
- # test dict-style substitution with WithProperties
- self.props.setProperty("other", "foo", "test")
- command = WithProperties("build-%(other)s.tar.gz")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "build-foo.tar.gz")
- return d
-
- def testDictColonMinus(self):
- # test dict-style substitution with WithProperties
- self.props.setProperty("prop1", "foo", "test")
- command = WithProperties("build-%(prop1:-empty)s-%(prop2:-empty)s.tar.gz")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "build-foo-empty.tar.gz")
- return d
-
- def testDictColonPlus(self):
- # test dict-style substitution with WithProperties
- self.props.setProperty("prop1", "foo", "test")
- command = WithProperties("build-%(prop1:+exists)s-%(prop2:+exists)s.tar.gz")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "build-exists-.tar.gz")
- return d
-
- def testEmpty(self):
- # None should render as ''
- self.props.setProperty("empty", None, "test")
- command = WithProperties("build-%(empty)s.tar.gz")
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- "build-.tar.gz")
- return d
-
- def testRecursiveList(self):
- self.props.setProperty("x", 10, "test")
- self.props.setProperty("y", 20, "test")
- command = [ WithProperties("%(x)s %(y)s"), "and",
- WithProperties("%(y)s %(x)s") ]
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- ["10 20", "and", "20 10"])
- return d
-
- def testRecursiveTuple(self):
- self.props.setProperty("x", 10, "test")
- self.props.setProperty("y", 20, "test")
- command = ( WithProperties("%(x)s %(y)s"), "and",
- WithProperties("%(y)s %(x)s") )
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- ("10 20", "and", "20 10"))
- return d
-
- def testRecursiveDict(self):
- self.props.setProperty("x", 10, "test")
- self.props.setProperty("y", 20, "test")
- command = { WithProperties("%(x)s %(y)s") :
- WithProperties("%(y)s %(x)s") }
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual,
- {"10 20" : "20 10"})
- return d
-
- def testLambdaSubst(self):
- command = WithProperties('%(foo)s', foo=lambda _: 'bar')
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual, 'bar')
- return d
-
- def testLambdaHasattr(self):
- command = WithProperties('%(foo)s',
- foo=lambda b : b.hasProperty('x') and 'x' or 'y')
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual, 'y')
- return d
-
- def testLambdaOverride(self):
- self.props.setProperty('x', 10, 'test')
- command = WithProperties('%(x)s', x=lambda _: 20)
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual, '20')
- return d
-
- def testLambdaCallable(self):
- self.assertRaises(ValueError, lambda: WithProperties('%(foo)s', foo='bar'))
-
- def testLambdaUseExisting(self):
- self.props.setProperty('x', 10, 'test')
- self.props.setProperty('y', 20, 'test')
- command = WithProperties('%(z)s', z=lambda props: props.getProperty('x') + props.getProperty('y'))
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual, '30')
- return d
-
- def testColon(self):
- self.props.setProperty('some:property', 10, 'test')
- command = WithProperties('%(some:property:-with-default)s')
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual, '10')
- return d
-
- def testColon_default(self):
- command = WithProperties('%(some:property:-with-default)s')
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual, 'with-default')
- return d
-
- def testColon_colon(self):
- command = WithProperties('%(some:property:-with:default)s')
- d = self.build.render(command)
- d.addCallback(self.failUnlessEqual, 'with:default')
- return d
-
-class TestProperties(unittest.TestCase):
- def setUp(self):
- self.props = Properties()
-
- def testDictBehavior(self):
- # note that dictionary-like behavior is deprecated and not exposed to
- # users!
- self.props.setProperty("do-tests", 1, "scheduler")
- self.props.setProperty("do-install", 2, "scheduler")
-
- self.assert_(self.props.has_key('do-tests'))
- self.failUnlessEqual(self.props['do-tests'], 1)
- self.failUnlessEqual(self.props['do-install'], 2)
- self.assertRaises(KeyError, lambda : self.props['do-nothing'])
- self.failUnlessEqual(self.props.getProperty('do-install'), 2)
- self.assertIn('do-tests', self.props)
- self.assertNotIn('missing-do-tests', self.props)
-
- def testAsList(self):
- self.props.setProperty("happiness", 7, "builder")
- self.props.setProperty("flames", True, "tester")
-
- self.assertEqual(sorted(self.props.asList()),
- [ ('flames', True, 'tester'), ('happiness', 7, 'builder') ])
-
- def testAsDict(self):
- self.props.setProperty("msi_filename", "product.msi", 'packager')
- self.props.setProperty("dmg_filename", "product.dmg", 'packager')
-
- self.assertEqual(self.props.asDict(),
- dict(msi_filename=('product.msi', 'packager'), dmg_filename=('product.dmg', 'packager')))
-
- def testUpdate(self):
- self.props.setProperty("x", 24, "old")
- newprops = { 'a' : 1, 'b' : 2 }
- self.props.update(newprops, "new")
-
- self.failUnlessEqual(self.props.getProperty('x'), 24)
- self.failUnlessEqual(self.props.getPropertySource('x'), 'old')
- self.failUnlessEqual(self.props.getProperty('a'), 1)
- self.failUnlessEqual(self.props.getPropertySource('a'), 'new')
-
- def testUpdateRuntime(self):
- self.props.setProperty("x", 24, "old")
- newprops = { 'a' : 1, 'b' : 2 }
- self.props.update(newprops, "new", runtime=True)
-
- self.failUnlessEqual(self.props.getProperty('x'), 24)
- self.failUnlessEqual(self.props.getPropertySource('x'), 'old')
- self.failUnlessEqual(self.props.getProperty('a'), 1)
- self.failUnlessEqual(self.props.getPropertySource('a'), 'new')
- self.assertEqual(self.props.runtime, set(['a', 'b']))
-
- def testUpdateFromProperties(self):
- self.props.setProperty("a", 94, "old")
- self.props.setProperty("x", 24, "old")
- newprops = Properties()
- newprops.setProperty('a', 1, "new")
- newprops.setProperty('b', 2, "new")
- self.props.updateFromProperties(newprops)
-
- self.failUnlessEqual(self.props.getProperty('x'), 24)
- self.failUnlessEqual(self.props.getPropertySource('x'), 'old')
- self.failUnlessEqual(self.props.getProperty('a'), 1)
- self.failUnlessEqual(self.props.getPropertySource('a'), 'new')
-
- def testUpdateFromPropertiesNoRuntime(self):
- self.props.setProperty("a", 94, "old")
- self.props.setProperty("b", 84, "old")
- self.props.setProperty("x", 24, "old")
- newprops = Properties()
- newprops.setProperty('a', 1, "new", runtime=True)
- newprops.setProperty('b', 2, "new", runtime=False)
- newprops.setProperty('c', 3, "new", runtime=True)
- newprops.setProperty('d', 3, "new", runtime=False)
- self.props.updateFromPropertiesNoRuntime(newprops)
-
- self.failUnlessEqual(self.props.getProperty('a'), 94)
- self.failUnlessEqual(self.props.getPropertySource('a'), 'old')
- self.failUnlessEqual(self.props.getProperty('b'), 2)
- self.failUnlessEqual(self.props.getPropertySource('b'), 'new')
- self.failUnlessEqual(self.props.getProperty('c'), None) # not updated
- self.failUnlessEqual(self.props.getProperty('d'), 3)
- self.failUnlessEqual(self.props.getPropertySource('d'), 'new')
- self.failUnlessEqual(self.props.getProperty('x'), 24)
- self.failUnlessEqual(self.props.getPropertySource('x'), 'old')
-
- @compat.usesFlushWarnings
- def test_setProperty_notJsonable(self):
- self.props.setProperty("project", ConstantRenderable('testing'), "test")
- self.props.setProperty("project", object, "test")
- self.assertEqual(len(self.flushWarnings([self.test_setProperty_notJsonable])), 2)
-
- # IProperties methods
-
- def test_getProperty(self):
- self.props.properties['p1'] = (['p', 1], 'test')
- self.assertEqual(self.props.getProperty('p1'), ['p', 1])
-
- def test_getProperty_default_None(self):
- self.assertEqual(self.props.getProperty('p1'), None)
-
- def test_getProperty_default(self):
- self.assertEqual(self.props.getProperty('p1', 2), 2)
-
- def test_hasProperty_false(self):
- self.assertFalse(self.props.hasProperty('x'))
-
- def test_hasProperty_true(self):
- self.props.properties['x'] = (False, 'test')
- self.assertTrue(self.props.hasProperty('x'))
-
- def test_has_key_false(self):
- self.assertFalse(self.props.has_key('x'))
-
- def test_setProperty(self):
- self.props.setProperty('x', 'y', 'test')
- self.assertEqual(self.props.properties['x'], ('y', 'test'))
- self.assertNotIn('x', self.props.runtime)
-
- def test_setProperty_runtime(self):
- self.props.setProperty('x', 'y', 'test', runtime=True)
- self.assertEqual(self.props.properties['x'], ('y', 'test'))
- self.assertIn('x', self.props.runtime)
-
- def test_setProperty_no_source(self):
- self.assertRaises(TypeError, lambda :
- self.props.setProperty('x', 'y'))
-
- def test_getProperties(self):
- self.assertIdentical(self.props.getProperties(), self.props)
-
- def test_getBuild(self):
- self.assertIdentical(self.props.getBuild(), self.props.build)
-
- def test_render(self):
- class Renderable(object):
- implements(IRenderable)
- def getRenderingFor(self, props):
- return props.getProperty('x') + 'z'
- self.props.setProperty('x', 'y', 'test')
- d = self.props.render(Renderable())
- d.addCallback(self.assertEqual, 'yz')
- return d
-
-
-class MyPropertiesThing(PropertiesMixin):
- set_runtime_properties = True
-
-def adaptMyProperties(mp):
- return mp.properties
-
-components.registerAdapter(adaptMyProperties, MyPropertiesThing, IProperties)
-
-
-class TestPropertiesMixin(unittest.TestCase):
-
- def setUp(self):
- self.mp = MyPropertiesThing()
- self.mp.properties = mock.Mock()
-
- def test_getProperty(self):
- self.mp.getProperty('abc')
- self.mp.properties.getProperty.assert_called_with('abc', None)
-
- def xtest_getProperty_default(self):
- self.mp.getProperty('abc', 'def')
- self.mp.properties.getProperty.assert_called_with('abc', 'def')
-
- def test_hasProperty(self):
- self.mp.properties.hasProperty.return_value = True
- self.assertTrue(self.mp.hasProperty('abc'))
- self.mp.properties.hasProperty.assert_called_with('abc')
-
- def test_has_key(self):
- self.mp.properties.hasProperty.return_value = True
- self.assertTrue(self.mp.has_key('abc'))
- self.mp.properties.hasProperty.assert_called_with('abc')
-
- def test_setProperty(self):
- self.mp.setProperty('abc', 'def', 'src')
- self.mp.properties.setProperty.assert_called_with('abc', 'def', 'src',
- runtime=True)
-
- def test_setProperty_no_source(self):
- # this compatibility is maintained for old code
- self.mp.setProperty('abc', 'def')
- self.mp.properties.setProperty.assert_called_with('abc', 'def',
- 'Unknown', runtime=True)
-
- def test_render(self):
- self.mp.render([1,2])
- self.mp.properties.render.assert_called_with([1,2])
-
-class TestProperty(unittest.TestCase):
-
- def setUp(self):
- self.props = Properties()
- self.build = FakeBuild(self.props)
-
- def testIntProperty(self):
- self.props.setProperty("do-tests", 1, "scheduler")
- value = Property("do-tests")
-
- d = self.build.render(value)
- d.addCallback(self.failUnlessEqual,
- 1)
- return d
-
- def testStringProperty(self):
- self.props.setProperty("do-tests", "string", "scheduler")
- value = Property("do-tests")
-
- d = self.build.render(value)
- d.addCallback(self.failUnlessEqual,
- "string")
- return d
-
- def testMissingProperty(self):
- value = Property("do-tests")
-
- d = self.build.render(value)
- d.addCallback(self.failUnlessEqual,
- None)
- return d
-
- def testDefaultValue(self):
- value = Property("do-tests", default="Hello!")
-
- d = self.build.render(value)
- d.addCallback(self.failUnlessEqual,
- "Hello!")
- return d
-
- def testDefaultValueNested(self):
- self.props.setProperty("xxx", 'yyy', "scheduler")
- value = Property("do-tests",
- default=WithProperties("a-%(xxx)s-b"))
-
- d = self.build.render(value)
- d.addCallback(self.failUnlessEqual,
- "a-yyy-b")
- return d
-
- def testIgnoreDefaultValue(self):
- self.props.setProperty("do-tests", "string", "scheduler")
- value = Property("do-tests", default="Hello!")
-
- d = self.build.render(value)
- d.addCallback(self.failUnlessEqual,
- "string")
- return d
-
- def testIgnoreFalseValue(self):
- self.props.setProperty("do-tests-string", "", "scheduler")
- self.props.setProperty("do-tests-int", 0, "scheduler")
- self.props.setProperty("do-tests-list", [], "scheduler")
- self.props.setProperty("do-tests-None", None, "scheduler")
-
- value = [ Property("do-tests-string", default="Hello!"),
- Property("do-tests-int", default="Hello!"),
- Property("do-tests-list", default="Hello!"),
- Property("do-tests-None", default="Hello!") ]
-
- d = self.build.render(value)
- d.addCallback(self.failUnlessEqual,
- ["Hello!"] * 4)
- return d
-
- def testDefaultWhenFalse(self):
- self.props.setProperty("do-tests-string", "", "scheduler")
- self.props.setProperty("do-tests-int", 0, "scheduler")
- self.props.setProperty("do-tests-list", [], "scheduler")
- self.props.setProperty("do-tests-None", None, "scheduler")
-
- value = [ Property("do-tests-string", default="Hello!", defaultWhenFalse=False),
- Property("do-tests-int", default="Hello!", defaultWhenFalse=False),
- Property("do-tests-list", default="Hello!", defaultWhenFalse=False),
- Property("do-tests-None", default="Hello!", defaultWhenFalse=False) ]
-
- d = self.build.render(value)
- d.addCallback(self.failUnlessEqual,
- ["", 0, [], None])
- return d
-
- def testDeferredDefault(self):
- default = DeferredRenderable()
- value = Property("no-such-property", default)
- d = self.build.render(value)
- d.addCallback(self.failUnlessEqual,
- "default-value")
- default.callback("default-value")
- return d
-
-
-class TestRenderalbeAdapters(unittest.TestCase):
- """
- Tests for list, tuple and dict renderers.
- """
-
- def setUp(self):
- self.props = Properties()
- self.build = FakeBuild(self.props)
-
-
- def test_list_deferred(self):
- r1 = DeferredRenderable()
- r2 = DeferredRenderable()
- d = self.build.render([r1, r2])
- d.addCallback(self.failUnlessEqual,
- ["lispy", "lists"])
- r2.callback("lists")
- r1.callback("lispy")
- return d
-
-
- def test_tuple_deferred(self):
- r1 = DeferredRenderable()
- r2 = DeferredRenderable()
- d = self.build.render((r1, r2))
- d.addCallback(self.failUnlessEqual,
- ("totally", "tupled"))
- r2.callback("tupled")
- r1.callback("totally")
- return d
-
-
- def test_dict(self):
- r1 = DeferredRenderable()
- r2 = DeferredRenderable()
- k1 = DeferredRenderable()
- k2 = DeferredRenderable()
- d = self.build.render({k1: r1, k2: r2})
- d.addCallback(self.failUnlessEqual,
- {"lock": "load", "dict": "lookup"})
- k1.callback("lock")
- r1.callback("load")
- k2.callback("dict")
- r2.callback("lookup")
- return d
-
-class Renderer(unittest.TestCase):
-
- def setUp(self):
- self.props = Properties()
- self.build = FakeBuild(self.props)
-
-
- def test_renderer(self):
- self.props.setProperty("x", "X", "test")
- d = self.build.render(
- renderer(lambda p : 'x%sx' % p.getProperty('x')))
- d.addCallback(self.failUnlessEqual, 'xXx')
- return d
-
- def test_renderer_called(self):
- # it's tempting to try to call the decorated function. Don't do that.
- # It's not a function anymore.
- d = defer.maybeDeferred(lambda :
- self.build.render(renderer(lambda p : 'x')('y')))
- self.failUnlessFailure(d, TypeError)
- return d
-
- def test_renderer_decorator(self):
- self.props.setProperty("x", "X", "test")
- @renderer
- def rend(p):
- return 'x%sx' % p.getProperty('x')
- d = self.build.render(rend)
- d.addCallback(self.failUnlessEqual, 'xXx')
- return d
-
- def test_renderer_deferred(self):
- self.props.setProperty("x", "X", "test")
- d = self.build.render(
- renderer(lambda p : defer.succeed('y%sy' % p.getProperty('x'))))
- d.addCallback(self.failUnlessEqual, 'yXy')
- return d
-
- def test_renderer_fails(self):
- d = self.build.render(
- renderer(lambda p : defer.fail(RuntimeError("oops"))))
- self.failUnlessFailure(d, RuntimeError)
- return d
-
-class Compare(unittest.TestCase):
-
- def test_WithProperties_lambda(self):
- self.failIfEqual(WithProperties("%(key)s", key=lambda p:'val'), WithProperties("%(key)s", key=lambda p:'val'))
- def rend(p):
- return "val"
- self.failUnlessEqual(
- WithProperties("%(key)s", key=rend),
- WithProperties("%(key)s", key=rend))
- self.failIfEqual(
- WithProperties("%(key)s", key=rend),
- WithProperties("%(key)s", otherkey=rend))
-
- def test_WithProperties_positional(self):
- self.failIfEqual(
- WithProperties("%s", 'key'),
- WithProperties("%s", 'otherkey'))
- self.failUnlessEqual(
- WithProperties("%s", 'key'),
- WithProperties("%s", 'key'))
- self.failIfEqual(
- WithProperties("%s", 'key'),
- WithProperties("k%s", 'key'))
-
- def test_Interpolate_constant(self):
- self.failIfEqual(
- Interpolate('some text here'),
- Interpolate('and other text there'))
- self.failUnlessEqual(
- Interpolate('some text here'),
- Interpolate('some text here'))
-
- def test_Interpolate_positional(self):
- self.failIfEqual(
- Interpolate('%s %s', "test", "text"),
- Interpolate('%s %s', "other", "text"))
- self.failUnlessEqual(
- Interpolate('%s %s', "test", "text"),
- Interpolate('%s %s', "test", "text"))
-
- def test_Interpolate_kwarg(self):
- self.failIfEqual(
- Interpolate("%(kw:test)s", test=object(), other=2),
- Interpolate("%(kw:test)s", test=object(), other=2))
- self.failUnlessEqual(
- Interpolate('testing: %(kw:test)s', test="test", other=3),
- Interpolate('testing: %(kw:test)s', test="test", other=3))
-
- def test_renderer(self):
- self.failIfEqual(
- renderer(lambda p:'val'),
- renderer(lambda p:'val'))
- def rend(p):
- return "val"
- self.failUnlessEqual(
- renderer(rend),
- renderer(rend))
-
- def test_Lookup_simple(self):
- self.failIfEqual(
- _Lookup({'test': 5, 'other': 6}, 'other'),
- _Lookup({'test': 5, 'other': 6}, 'test'))
- self.failUnlessEqual(
- _Lookup({'test': 5, 'other': 6}, 'test'),
- _Lookup({'test': 5, 'other': 6}, 'test'))
-
- def test_Lookup_default(self):
- self.failIfEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', default='default'),
- _Lookup({'test': 5, 'other': 6}, 'test'))
- self.failUnlessEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', default='default'),
- _Lookup({'test': 5, 'other': 6}, 'test', default='default'))
-
- def test_Lookup_defaultWhenFalse(self):
- self.failIfEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', defaultWhenFalse=False),
- _Lookup({'test': 5, 'other': 6}, 'test'))
- self.failIfEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', defaultWhenFalse=False),
- _Lookup({'test': 5, 'other': 6}, 'test', defaultWhenFalse=True))
- self.failUnlessEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', defaultWhenFalse=True),
- _Lookup({'test': 5, 'other': 6}, 'test', defaultWhenFalse=True))
- self.failUnlessEqual(
- _Lookup({'test': 5, 'other': 6}, 'test'),
- _Lookup({'test': 5, 'other': 6}, 'test', defaultWhenFalse=True))
-
- def test_Lookup_hasKey(self):
- self.failIfEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', hasKey=None),
- _Lookup({'test': 5, 'other': 6}, 'test'))
- self.failIfEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', hasKey='has-key'),
- _Lookup({'test': 5, 'other': 6}, 'test'))
- self.failIfEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', hasKey='has-key'),
- _Lookup({'test': 5, 'other': 6}, 'test', hasKey='other-key'))
- self.failUnlessEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', hasKey='has-key'),
- _Lookup({'test': 5, 'other': 6}, 'test', hasKey='has-key'))
-
- def test_Lookup_elideNoneAs(self):
- self.failUnlessEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', elideNoneAs=None),
- _Lookup({'test': 5, 'other': 6}, 'test'))
- self.failIfEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', elideNoneAs=''),
- _Lookup({'test': 5, 'other': 6}, 'test'))
- self.failIfEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', elideNoneAs='got None'),
- _Lookup({'test': 5, 'other': 6}, 'test', elideNoneAs=''))
- self.failUnlessEqual(
- _Lookup({'test': 5, 'other': 6}, 'test', elideNoneAs='got None'),
- _Lookup({'test': 5, 'other': 6}, 'test', elideNoneAs='got None'))
-
- def test_Lazy(self):
- self.failIfEqual(
- _Lazy(5),
- _Lazy(6))
- self.failUnlessEqual(
- _Lazy(5),
- _Lazy(5))
-
- def test_SourceStampDict(self):
- self.failIfEqual(
- _SourceStampDict('binary'),
- _SourceStampDict('library'))
- self.failUnlessEqual(
- _SourceStampDict('binary'),
- _SourceStampDict('binary'))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_manager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_manager.py
deleted file mode 100644
index 031f9677..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_manager.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.process.users import manager, manual
-from buildbot import config
-
-class FakeUserManager(manual.UsersBase):
- pass
-
-class TestUserManager(unittest.TestCase):
- def setUp(self):
- self.master = mock.Mock()
- self.umm = manager.UserManagerManager(self.master)
- self.umm.startService()
-
- self.config = config.MasterConfig()
-
- def tearDown(self):
- self.umm.stopService()
-
- @defer.inlineCallbacks
- def test_reconfigService(self):
- # add a user manager
- um1 = FakeUserManager()
- self.config.user_managers = [ um1 ]
-
- yield self.umm.reconfigService(self.config)
-
- self.assertTrue(um1.running)
- self.assertIdentical(um1.master, self.master)
-
- # and back to nothing
- self.config.user_managers = [ ]
- yield self.umm.reconfigService(self.config)
-
- self.assertIdentical(um1.master, None)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_manual.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_manual.py
deleted file mode 100644
index 9b330051..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_manual.py
+++ /dev/null
@@ -1,304 +0,0 @@
-# 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
-
-# this class is known to contain cruft and will be looked at later, so
-# no current implementation utilizes it aside from scripts.runner.
-
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-
-from buildbot.test.fake import fakedb
-from buildbot.process.users import manual
-
-class ManualUsersMixin(object):
- """
- This class fakes out the master/db components to test the manual
- user managers located in process.users.manual.
- """
-
- class FakeMaster(object):
-
- def __init__(self):
- self.db = fakedb.FakeDBConnector(self)
- self.slavePortnum = "tcp:9989"
- self.caches = mock.Mock(name="caches")
- self.caches.get_cache = self.get_cache
-
- def get_cache(self, cache_name, miss_fn):
- c = mock.Mock(name=cache_name)
- c.get = miss_fn
- return c
-
- def setUpManualUsers(self):
- self.master = self.FakeMaster()
-
-class TestUsersBase(unittest.TestCase):
- """
- Not really sure what there is to test, aside from _setUpManualUsers getting
- self.master set.
- """
- pass
-
-class TestCommandlineUserManagerPerspective(unittest.TestCase, ManualUsersMixin):
-
- def setUp(self):
- self.setUpManualUsers()
-
- def call_perspective_commandline(self, *args):
- persp = manual.CommandlineUserManagerPerspective(self.master)
- return persp.perspective_commandline(*args)
-
- def test_perspective_commandline_add(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'x', 'git': 'x'}])
- def check_get(_):
- d = self.master.db.users.getUser(1)
- def real_check(usdict):
- self.assertEqual(usdict, dict(uid=1,
- identifier='x',
- bb_username=None,
- bb_password=None,
- git='x'))
- d.addCallback(real_check)
- return d
- d.addCallback(check_get)
- return d
-
- def test_perspective_commandline_update(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'x', 'svn':'x'}])
- d.addCallback(lambda _ :
- self.call_perspective_commandline(
- 'update', None, None, None,
- [{'identifier':'x', 'svn':'y'}]))
- def check(_):
- d = self.master.db.users.getUser(1)
- def real_check(usdict):
- self.assertEqual(usdict, dict(uid=1,
- identifier='x',
- bb_username=None,
- bb_password=None,
- svn='y'))
- d.addCallback(real_check)
- return d
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_update_bb(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'x',
- 'svn':'x'}])
- d.addCallback(lambda _ :
- self.call_perspective_commandline(
- 'update', 'bb_user',
- 'hashed_bb_pass', None,
- [{'identifier':'x'}]))
- def check(_):
- d = self.master.db.users.getUser(1)
- def real_check(usdict):
- self.assertEqual(usdict, dict(uid=1,
- identifier='x',
- bb_username='bb_user',
- bb_password='hashed_bb_pass',
- svn='x'))
- d.addCallback(real_check)
- return d
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_update_both(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'x',
- 'svn':'x'}])
- d.addCallback(lambda _ :
- self.call_perspective_commandline(
- 'update', 'bb_user',
- 'hashed_bb_pass', None,
- [{'identifier':'x',
- 'svn':'y'}]))
- def check(_):
- d = self.master.db.users.getUser(1)
- def real_check(usdict):
- self.assertEqual(usdict, dict(uid=1,
- identifier='x',
- bb_username='bb_user',
- bb_password='hashed_bb_pass',
- svn='y'))
- d.addCallback(real_check)
- return d
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_remove(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'h@c',
- 'git': 'hi <h@c>'}])
- d.addCallback(lambda _ :
- self.call_perspective_commandline('remove', None,
- None, ['x'], None))
- def check(_):
- d = self.master.db.users.getUser('x')
- def real_check(res):
- self.assertEqual(res, None)
- d.addCallback(real_check)
- return d
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_get(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'x',
- 'svn':'x'}])
- d.addCallback(lambda _ :
- self.call_perspective_commandline('get', None, None,
- ['x'], None))
- def check(_):
- d = self.master.db.users.getUser(1)
- def real_check(res):
- self.assertEqual(res, dict(uid=1,
- identifier='x',
- bb_username=None,
- bb_password=None,
- svn='x'))
- d.addCallback(real_check)
- return d
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_get_multiple_attrs(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier': 'x',
- 'svn': 'x',
- 'git': 'x@c'}])
- d.addCallback(lambda _ :
- self.call_perspective_commandline('get', None, None,
- ['x'], None))
- def check(_):
- d = self.master.db.users.getUser(1)
- def real_check(res):
- self.assertEqual(res, dict(uid=1,
- identifier='x',
- bb_username=None,
- bb_password=None,
- svn='x',
- git='x@c'))
- d.addCallback(real_check)
- return d
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_add_format(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'x', 'svn':'x'}])
- def check(result):
- exp_format = "user(s) added:\nidentifier: x\nuid: 1\n\n"
- self.assertEqual(result, exp_format)
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_update_format(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'x', 'svn':'x'}])
- d.addCallback(lambda _ :
- self.call_perspective_commandline('update', None, None, None,
- [{'identifier':'x',
- 'svn':'y'}]))
- def check(result):
- exp_format = 'user(s) updated:\nidentifier: x\n'
- self.assertEqual(result, exp_format)
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_remove_format(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'h@c',
- 'git': 'hi <h@c>'}])
- d.addCallback(lambda _ : self.call_perspective_commandline('remove',
- None, None,
- ['h@c'],
- None))
- def check(result):
- exp_format = "user(s) removed:\nidentifier: h@c\n"
- self.assertEqual(result, exp_format)
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_get_format(self):
- d = self.call_perspective_commandline('add', None, None, None,
- [{'identifier':'x@y', 'git': 'x <x@y>'}])
- d.addCallback(lambda _ :
- self.call_perspective_commandline('get', None, None,
- ['x@y'], None))
- def check(result):
- exp_format = 'user(s) found:\ngit: x <x@y>\nidentifier: x@y\n' \
- 'bb_username: None\nuid: 1\n\n'
- self.assertEqual(result, exp_format)
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_remove_no_match_format(self):
- d = self.call_perspective_commandline('remove', None, None, ['x'], None)
- def check(result):
- exp_format = "user(s) removed:\n"
- self.assertEqual(result, exp_format)
- d.addCallback(check)
- return d
-
- def test_perspective_commandline_get_no_match_format(self):
- d = self.call_perspective_commandline('get', None, None, ['x'], None)
- def check(result):
- exp_format = "user(s) found:\nno match found\n"
- self.assertEqual(result, exp_format)
- d.addCallback(check)
- return d
-
-class TestCommandlineUserManager(unittest.TestCase, ManualUsersMixin):
-
- def setUp(self):
- self.setUpManualUsers()
- self.manual_component = manual.CommandlineUserManager(username="user",
- passwd="userpw",
- port="9990")
- self.manual_component.master = self.master
-
- def test_no_userpass(self):
- d = defer.maybeDeferred(lambda : manual.CommandlineUserManager())
- return self.assertFailure(d, AssertionError)
-
- def test_no_port(self):
- d = defer.maybeDeferred(lambda : manual.CommandlineUserManager(username="x",
- passwd="y"))
- return self.assertFailure(d, AssertionError)
-
- def test_service(self):
- # patch out the pbmanager's 'register' command both to be sure
- # the registration is correct and to get a copy of the factory
- registration = mock.Mock()
- registration.unregister = lambda : defer.succeed(None)
- self.master.pbmanager = mock.Mock()
- def register(portstr, user, passwd, factory):
- self.assertEqual([portstr, user, passwd],
- ['9990', 'user', 'userpw'])
- self.got_factory = factory
- return registration
- self.master.pbmanager.register = register
-
- self.manual_component.startService()
-
- persp = self.got_factory(mock.Mock(), 'user')
- self.failUnless(isinstance(persp, manual.CommandlineUserManagerPerspective))
-
- return self.manual_component.stopService()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_users.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_users.py
deleted file mode 100644
index 3c3b7bb8..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_process_users_users.py
+++ /dev/null
@@ -1,152 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-
-from buildbot.process.users import users
-from buildbot.test.fake import fakedb
-
-class UsersTests(unittest.TestCase):
-
- def setUp(self):
- self.master = mock.Mock()
- self.master.db = self.db = fakedb.FakeDBConnector(self)
- self.test_sha = users.encrypt("cancer")
-
- def test_createUserObject_no_src(self):
- d = users.createUserObject(self.master, "Tyler Durden", None)
- def check(_):
- self.assertEqual(self.db.users.users, {})
- self.assertEqual(self.db.users.users_info, {})
- d.addCallback(check)
- return d
-
- def test_createUserObject_unrecognized_src(self):
- d = users.createUserObject(self.master, "Tyler Durden", 'blah')
- def check(_):
- self.assertEqual(self.db.users.users, {})
- self.assertEqual(self.db.users.users_info, {})
- d.addCallback(check)
- return d
-
- def test_createUserObject_git(self):
- d = users.createUserObject(self.master,
- "Tyler Durden <tyler@mayhem.net>", 'git')
- def check(_):
- self.assertEqual(self.db.users.users,
- { 1: dict(identifier='Tyler Durden <tyler@mayhem.net>',
- bb_username=None, bb_password=None) })
- self.assertEqual(self.db.users.users_info,
- { 1: [dict(attr_type="git",
- attr_data="Tyler Durden <tyler@mayhem.net>")]})
- d.addCallback(check)
- return d
-
- def test_createUserObject_svn(self):
- d = users.createUserObject(self.master, "tdurden", 'svn')
- def check(_):
- self.assertEqual(self.db.users.users,
- { 1: dict(identifier='tdurden',
- bb_username=None, bb_password=None) })
- self.assertEqual(self.db.users.users_info,
- { 1: [dict(attr_type="svn",
- attr_data="tdurden")]})
- d.addCallback(check)
- return d
-
- def test_createUserObject_hg(self):
- d = users.createUserObject(self.master,
- "Tyler Durden <tyler@mayhem.net>", 'hg')
- def check(_):
- self.assertEqual(self.db.users.users,
- { 1: dict(identifier='Tyler Durden <tyler@mayhem.net>',
- bb_username=None, bb_password=None) })
- self.assertEqual(self.db.users.users_info,
- { 1: [dict(attr_type="hg",
- attr_data="Tyler Durden <tyler@mayhem.net>")]})
- d.addCallback(check)
- return d
-
- def test_createUserObject_cvs(self):
- d = users.createUserObject(self.master, "tdurden", 'cvs')
- def check(_):
- self.assertEqual(self.db.users.users,
- { 1: dict(identifier='tdurden',
- bb_username=None, bb_password=None) })
- self.assertEqual(self.db.users.users_info,
- { 1: [dict(attr_type="cvs",
- attr_data="tdurden")]})
- d.addCallback(check)
- return d
-
- def test_createUserObject_darcs(self):
- d = users.createUserObject(self.master, "tyler@mayhem.net", 'darcs')
- def check(_):
- self.assertEqual(self.db.users.users,
- { 1: dict(identifier='tyler@mayhem.net',
- bb_username=None, bb_password=None) })
- self.assertEqual(self.db.users.users_info,
- { 1: [dict(attr_type="darcs",
- attr_data="tyler@mayhem.net")]})
- d.addCallback(check)
- return d
-
- def test_createUserObject_bzr(self):
- d = users.createUserObject(self.master, "Tyler Durden", 'bzr')
- def check(_):
- self.assertEqual(self.db.users.users,
- { 1: dict(identifier='Tyler Durden',
- bb_username=None, bb_password=None) })
- self.assertEqual(self.db.users.users_info,
- { 1: [dict(attr_type="bzr",
- attr_data="Tyler Durden")]})
- d.addCallback(check)
- return d
-
- def test_getUserContact_found(self):
- self.db.insertTestData([fakedb.User(uid=1, identifier='tdurden'),
- fakedb.UserInfo(uid=1, attr_type='svn',
- attr_data='tdurden'),
- fakedb.UserInfo(uid=1, attr_type='email',
- attr_data='tyler@mayhem.net')])
- d = users.getUserContact(self.master, contact_types=['email'], uid=1)
- def check(contact):
- self.assertEqual(contact, 'tyler@mayhem.net')
- d.addCallback(check)
- return d
-
- def test_getUserContact_key_not_found(self):
- self.db.insertTestData([fakedb.User(uid=1, identifier='tdurden'),
- fakedb.UserInfo(uid=1, attr_type='svn',
- attr_data='tdurden'),
- fakedb.UserInfo(uid=1, attr_type='email',
- attr_data='tyler@mayhem.net')])
- d = users.getUserContact(self.master, contact_types=['blargh'], uid=1)
- def check(contact):
- self.assertEqual(contact, None)
- d.addCallback(check)
- return d
-
- def test_getUserContact_uid_not_found(self):
- d = users.getUserContact(self.master, contact_types=['email'], uid=1)
- def check(contact):
- self.assertEqual(contact, None)
- d.addCallback(check)
- return d
-
- def test_check_passwd(self):
- res = users.check_passwd("cancer", self.test_sha)
- self.assertEqual(res, True)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_revlinks.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_revlinks.py
deleted file mode 100644
index 70c53404..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_revlinks.py
+++ /dev/null
@@ -1,82 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.revlinks import RevlinkMatch, GithubRevlink, SourceforgeGitRevlink, GitwebMatch
-
-class TestGithubRevlink(unittest.TestCase):
- revision = 'b6874701b54e0043a78882b020afc86033133f91'
- url = 'https://github.com/buildbot/buildbot/commit/b6874701b54e0043a78882b020afc86033133f91'
- def testHTTPS(self):
- self.assertEqual(GithubRevlink(self.revision, 'https://github.com/buildbot/buildbot.git'),
- self.url)
-
- def testGIT(self):
- self.assertEqual(GithubRevlink(self.revision, 'git://github.com/buildbot/buildbot.git'),
- self.url)
-
- def testSSH(self):
- self.assertEqual(GithubRevlink(self.revision, 'git@github.com:buildbot/buildbot.git'),
- self.url)
-
- def testSSHuri(self):
- self.assertEqual(GithubRevlink(self.revision, 'ssh://git@github.com/buildbot/buildbot.git'),
- self.url)
-
-class TestSourceforgeGitRevlink(unittest.TestCase):
- revision = 'b99c89a2842d386accea8072ae5bb6e24aa7cf29'
- url = 'http://gemrb.git.sourceforge.net/git/gitweb.cgi?p=gemrb/gemrb;a=commit;h=b99c89a2842d386accea8072ae5bb6e24aa7cf29'
-
- def testGIT(self):
- self.assertEqual(SourceforgeGitRevlink(self.revision, 'git://gemrb.git.sourceforge.net/gitroot/gemrb/gemrb'),
- self.url)
-
- def testSSH(self):
- self.assertEqual(SourceforgeGitRevlink(self.revision, 'somebody@gemrb.git.sourceforge.net:gitroot/gemrb/gemrb'),
- self.url)
-
- def testSSHuri(self):
- self.assertEqual(SourceforgeGitRevlink(self.revision, 'ssh://somebody@gemrb.git.sourceforge.net/gitroot/gemrb/gemrb'),
- self.url)
-
-class TestRevlinkMatch(unittest.TestCase):
- def testNotmuch(self):
- revision = 'f717d2ece1836c863f9cc02abd1ff2539307cd1d'
- matcher = RevlinkMatch(['git://notmuchmail.org/git/(.*)'],
- r'http://git.notmuchmail.org/git/\1/commit/%s')
- self.assertEquals(matcher(revision, 'git://notmuchmail.org/git/notmuch'),
- 'http://git.notmuchmail.org/git/notmuch/commit/f717d2ece1836c863f9cc02abd1ff2539307cd1d')
-
- def testSingleString(self):
- revision = 'rev'
- matcher = RevlinkMatch('test', 'out%s')
- self.assertEquals(matcher(revision, 'test'), 'outrev')
-
- def testSingleUnicode(self):
- revision = 'rev'
- matcher = RevlinkMatch(u'test', 'out%s')
- self.assertEquals(matcher(revision, 'test'), 'outrev')
-
- def testTwoCaptureGroups(self):
- revision = 'rev'
- matcher = RevlinkMatch('([A-Z]*)Z([0-9]*)', r'\2-\1-%s')
- self.assertEquals(matcher(revision, 'ABCZ43'), '43-ABC-rev')
-
-class TestGitwebMatch(unittest.TestCase):
- def testOrgmode(self):
- revision = '490d6ace10e0cfe74bab21c59e4b7bd6aa3c59b8'
- matcher = GitwebMatch('git://orgmode.org/(?P<repo>.*)', 'http://orgmode.org/w/')
- self.assertEquals(matcher(revision, 'git://orgmode.org/org-mode.git'),
- 'http://orgmode.org/w/?p=org-mode.git;a=commit;h=490d6ace10e0cfe74bab21c59e4b7bd6aa3c59b8')
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_base.py
deleted file mode 100644
index 7eaa003d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_base.py
+++ /dev/null
@@ -1,523 +0,0 @@
-# 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 sys
-import mock
-import twisted
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot import config
-from buildbot.schedulers import base
-from buildbot.process import properties
-from buildbot.test.util import scheduler
-from buildbot.test.fake import fakedb
-
-class BaseScheduler(scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 19
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- def makeScheduler(self, name='testsched', builderNames=['a', 'b'],
- properties={}, codebases = {'':{}}):
- sched = self.attachScheduler(
- base.BaseScheduler(name=name, builderNames=builderNames,
- properties=properties, codebases=codebases),
- self.OBJECTID)
-
- return sched
-
- # tests
-
- def test_constructor_builderNames(self):
- self.assertRaises(config.ConfigErrors,
- lambda : self.makeScheduler(builderNames='xxx'))
-
- def test_constructor_builderNames_unicode(self):
- self.makeScheduler(builderNames=[u'a'])
-
- def test_constructor_codebases_valid(self):
- codebases = {"codebase1": {"repository":"", "branch":"", "revision":""}}
- self.makeScheduler(codebases = codebases)
-
- def test_constructor_codebases_invalid(self):
- # scheduler only accepts codebases with at least repository set
- codebases = {"codebase1": {"dictionary":"", "that":"", "fails":""}}
- self.assertRaises(config.ConfigErrors,
- lambda : self.makeScheduler(codebases = codebases))
-
- def test_listBuilderNames(self):
- sched = self.makeScheduler(builderNames=['x', 'y'])
- self.assertEqual(sched.listBuilderNames(), ['x', 'y'])
-
- def test_getPendingBuildTimes(self):
- sched = self.makeScheduler()
- self.assertEqual(sched.getPendingBuildTimes(), [])
-
- def test_addBuildsetForLatest_defaults(self):
- sched = self.makeScheduler(name='testy', builderNames=['x'],
- properties=dict(a='b'))
- d = sched.addBuildsetForLatest(reason='because')
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='because', brids=brids,
- external_idstring=None,
- properties=[ ('a', ('b', 'Scheduler')),
- ('scheduler', ('testy', 'Scheduler')), ],
- sourcestampsetid=100),
- {'':
- dict(branch=None, revision=None, repository='', codebase='',
- project='', sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_startConsumingChanges_fileIsImportant_check(self):
- sched = self.makeScheduler()
- self.assertRaises(AssertionError,
- lambda : sched.startConsumingChanges(fileIsImportant="maybe"))
-
- def do_test_change_consumption(self, kwargs, change, expected_result):
- # (expected_result should be True (important), False (unimportant), or
- # None (ignore the change))
- sched = self.makeScheduler()
- sched.startService()
-
- change_received = [ None ]
- def gotChange(got_change, got_important):
- self.assertEqual(got_change, change)
- change_received[0] = got_important
- return defer.succeed(None)
- sched.gotChange = gotChange
-
- d = sched.startConsumingChanges(**kwargs)
- def test(_):
- # check that it registered a callback
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertNotEqual(callbacks['changes'], None)
-
- # invoke the callback with the change, and check the result
- callbacks['changes'](change)
- self.assertEqual(change_received[0], expected_result)
- d.addCallback(test)
- d.addCallback(lambda _ : sched.stopService())
- return d
-
- def test_change_consumption_defaults(self):
- # all changes are important by default
- return self.do_test_change_consumption(
- dict(),
- self.makeFakeChange(),
- True)
-
- def test_change_consumption_fileIsImportant_True(self):
- return self.do_test_change_consumption(
- dict(fileIsImportant=lambda c : True),
- self.makeFakeChange(),
- True)
-
- def test_change_consumption_fileIsImportant_False(self):
- return self.do_test_change_consumption(
- dict(fileIsImportant=lambda c : False),
- self.makeFakeChange(),
- False)
-
- def test_change_consumption_fileIsImportant_exception(self):
- d = self.do_test_change_consumption(
- dict(fileIsImportant=lambda c : 1/0),
- self.makeFakeChange(),
- None)
- def check_err(_):
- self.assertEqual(1, len(self.flushLoggedErrors(ZeroDivisionError)))
- d.addCallback(check_err)
- return d
- if twisted.version.major <= 9 and sys.version_info[:2] >= (2,7):
- test_change_consumption_fileIsImportant_exception.skip = \
- "flushLoggedErrors does not work correctly on 9.0.0 and earlier with Python-2.7"
-
- def test_change_consumption_change_filter_True(self):
- cf = mock.Mock()
- cf.filter_change = lambda c : True
- return self.do_test_change_consumption(
- dict(change_filter=cf),
- self.makeFakeChange(),
- True)
-
- def test_change_consumption_change_filter_False(self):
- cf = mock.Mock()
- cf.filter_change = lambda c : False
- return self.do_test_change_consumption(
- dict(change_filter=cf),
- self.makeFakeChange(),
- None)
-
- def test_change_consumption_fileIsImportant_False_onlyImportant(self):
- return self.do_test_change_consumption(
- dict(fileIsImportant=lambda c : False, onlyImportant=True),
- self.makeFakeChange(),
- None)
-
- def test_change_consumption_fileIsImportant_True_onlyImportant(self):
- return self.do_test_change_consumption(
- dict(fileIsImportant=lambda c : True, onlyImportant=True),
- self.makeFakeChange(),
- True)
-
- def test_addBuilsetForLatest_args(self):
- sched = self.makeScheduler(name='xyz', builderNames=['y', 'z'])
- d = sched.addBuildsetForLatest(reason='cuz', branch='default',
- project='myp', repository='hgmo',
- external_idstring='try_1234')
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='cuz', brids=brids,
- external_idstring='try_1234',
- properties=[('scheduler', ('xyz', 'Scheduler'))],
- sourcestampsetid=100),
- {'':
- dict(branch='default', revision=None, repository='hgmo',
- codebase='', project='myp', sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForLatest_properties(self):
- props = properties.Properties(xxx="yyy")
- sched = self.makeScheduler(name='xyz', builderNames=['y', 'z'])
- d = sched.addBuildsetForLatest(reason='cuz', branch='default',
- project='myp', repository='hgmo',
- external_idstring='try_1234', properties=props)
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='cuz', brids=brids,
- external_idstring='try_1234',
- properties=[
- ('scheduler', ('xyz', 'Scheduler')),
- ('xxx', ('yyy', 'TEST')),
- ],
- sourcestampsetid=100),
- {'':
- dict(branch='default', revision=None, repository='hgmo',
- codebase='', project='myp', sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForLatest_builderNames(self):
- sched = self.makeScheduler(name='xyz', builderNames=['y', 'z'])
- d = sched.addBuildsetForLatest(reason='cuz', branch='default',
- builderNames=['a', 'b'])
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='cuz', brids=brids,
- external_idstring=None,
- properties=[('scheduler', ('xyz', 'Scheduler'))],
- sourcestampsetid=100),
- {'':
- dict(branch='default', revision=None, repository='',
- codebase='', project='', sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForChanges_one_change(self):
- sched = self.makeScheduler(name='n', builderNames=['b'])
- self.db.insertTestData([
- fakedb.Change(changeid=13, branch='trunk', revision='9283',
- repository='svn://...', codebase='',
- project='world-domination'),
- ])
- d = sched.addBuildsetForChanges(reason='power', changeids=[13])
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='power', brids=brids,
- external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- sourcestampsetid=100),
- {'':
- dict(branch='trunk', repository='svn://...', codebase='',
- changeids=set([13]), project='world-domination',
- revision='9283', sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForChanges_properties(self):
- props = properties.Properties(xxx="yyy")
- sched = self.makeScheduler(name='n', builderNames=['c'])
- self.db.insertTestData([
- fakedb.Change(changeid=14, branch='default', revision='123:abc',
- repository='', project='', codebase=''),
- ])
- d = sched.addBuildsetForChanges(reason='downstream', changeids=[14],
- properties=props)
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='downstream', brids=brids,
- external_idstring=None,
- properties=[
- ('scheduler', ('n', 'Scheduler')),
- ('xxx', ('yyy', 'TEST')),
- ],
- sourcestampsetid=100),
- {'':
- dict(branch='default', revision='123:abc', repository='',
- project='', changeids=set([14]), sourcestampsetid=100,
- codebase='')
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForChanges_one_change_builderNames(self):
- sched = self.makeScheduler(name='n', builderNames=['b'])
- self.db.insertTestData([
- fakedb.Change(changeid=13, branch='trunk', revision='9283',
- codebase='', repository='svn://...',
- project='world-domination'),
- ])
- d = sched.addBuildsetForChanges(reason='power', changeids=[13],
- builderNames=['p'])
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='power', brids=brids,
- external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- sourcestampsetid=100),
- {'':
- dict(branch='trunk', repository='svn://...', codebase='',
- changeids=set([13]), project='world-domination',
- revision='9283', sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForChanges_multiple_changes_no_codebaseGenerator(self):
- # This is a test for backwards compatibility
- # Changes from different repositories come together in one build
- sched = self.makeScheduler(name='n', builderNames=['b', 'c'])
- # No codebaseGenerator means all changes have codebase == ''
- self.db.insertTestData([
- fakedb.Change(changeid=13, branch='trunk', revision='9283',
- repository='svn://A..', project='knitting',
- codebase=''),
- fakedb.Change(changeid=14, branch='devel', revision='9284',
- repository='svn://B..', project='making-tea',
- codebase=''),
- fakedb.Change(changeid=15, branch='trunk', revision='9285',
- repository='svn://C..', project='world-domination',
- codebase=''),
- ])
-
- # note that the changeids are given out of order here; it should still
- # use the most recent
- d = sched.addBuildsetForChanges(reason='power', changeids=[14, 15, 13])
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='power', brids=brids,
- external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- sourcestampsetid=100),
- {'':
- dict(branch='trunk', repository='svn://C..', codebase='',
- changeids=set([13,14,15]), project='world-domination',
- revision='9285', sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForChanges_multiple_changes_single_codebase(self):
- sched = self.makeScheduler(name='n', builderNames=['b', 'c'])
- self.db.insertTestData([
- fakedb.Change(changeid=13, branch='trunk', revision='9283',
- repository='svn://...', project='knitting',
- codebase=''),
- fakedb.Change(changeid=14, branch='devel', revision='9284',
- repository='svn://...', project='making-tea',
- codebase=''),
- fakedb.Change(changeid=15, branch='trunk', revision='9285',
- repository='svn://...', project='world-domination',
- codebase=''),
- ])
-
- # note that the changeids are given out of order here; it should still
- # use the most recent
- d = sched.addBuildsetForChanges(reason='power', changeids=[14, 15, 13])
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='power', brids=brids,
- external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- sourcestampsetid=100),
- {'':
- dict(branch='trunk', repository='svn://...', codebase='',
- changeids=set([13,14,15]), project='world-domination',
- revision='9285', sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForChanges_codebases_set_multiple_changed_codebases(self):
- codebases = { 'cbA':dict(
- repository='svn://A..',
- branch='stable',
- revision='13579'),
- 'cbB':dict(
- repository='svn://B..',
- branch='stable',
- revision='24680'),
- 'cbC':dict(
- repository='svn://C..',
- branch='stable',
- revision='12345'),
- 'cbD':dict(
- repository='svn://D..')}
- # Scheduler gets codebases that can be used to create extra sourcestamps
- # for repositories that have no changes
- sched = self.makeScheduler(name='n', builderNames=['b', 'c'],
- codebases=codebases)
- self.db.insertTestData([
- fakedb.Change(changeid=12, branch='trunk', revision='9282',
- repository='svn://A..', project='playing',
- codebase='cbA'),
- fakedb.Change(changeid=13, branch='trunk', revision='9283',
- repository='svn://A..', project='knitting',
- codebase='cbA'),
- fakedb.Change(changeid=14, branch='develop', revision='9284',
- repository='svn://A..', project='making-tea',
- codebase='cbA'),
- fakedb.Change(changeid=15, branch='trunk', revision='8085',
- repository='svn://B..', project='boxing',
- codebase='cbB'),
- fakedb.Change(changeid=16, branch='develop', revision='8086',
- repository='svn://B..', project='playing soccer',
- codebase='cbB'),
- fakedb.Change(changeid=17, branch='develop', revision='8087',
- repository='svn://B..', project='swimming',
- codebase='cbB'),
- ])
-
- # note that the changeids are given out of order here; it should still
- # use the most recent for each codebase
- d = sched.addBuildsetForChanges(reason='power', changeids=[14, 12, 17, 16, 13, 15])
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='power', brids=brids,
- external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- sourcestampsetid=100),
- {'cbA':
- dict(branch='develop', repository='svn://A..', codebase='cbA',
- changeids=set([12,13,14]), project='making-tea',
- revision='9284', sourcestampsetid=100),
- 'cbB':
- dict(branch='develop', repository='svn://B..', codebase='cbB',
- changeids=set([15,16,17]), project='swimming',
- revision='8087', sourcestampsetid=100),
- 'cbC':
- dict(branch='stable', repository='svn://C..', codebase='cbC',
- project='', revision='12345', sourcestampsetid=100),
- 'cbD':
- dict(branch=None, repository='svn://D..', codebase='cbD',
- project='', revision=None, sourcestampsetid=100),
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForSourceStamp(self):
- sched = self.makeScheduler(name='n', builderNames=['b'])
- d = self.db.insertTestData([
- fakedb.SourceStampSet(id=1091),
- fakedb.SourceStamp(id=91, sourcestampsetid=1091, branch='fixins',
- revision='abc', patchid=None, repository='r',
- project='p'),
- ])
- d.addCallback(lambda _ :
- sched.addBuildsetForSourceStamp(reason='whynot', setid=1091))
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='whynot', brids=brids,
- external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- sourcestampsetid=1091),
- {'':
- dict(branch='fixins', revision='abc', repository='r',
- project='p', codebase='', sourcestampsetid=1091)
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForSourceStamp_properties(self):
- props = properties.Properties(xxx="yyy")
- sched = self.makeScheduler(name='n', builderNames=['b'])
- d = self.db.insertTestData([
- fakedb.SourceStampSet(id=1091),
- fakedb.SourceStamp(id=91, sourcestampsetid=1091, branch='fixins',
- revision='abc', patchid=None, repository='r', codebase='cb',
- project='p'),
- ])
- d.addCallback(lambda _ :
- sched.addBuildsetForSourceStamp(reason='whynot', setid=1091,
- properties=props))
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='whynot', brids=brids,
- external_idstring=None,
- properties=[
- ('scheduler', ('n', 'Scheduler')),
- ('xxx', ('yyy', 'TEST')),
- ],
- sourcestampsetid=1091),
- {'cb':
- dict(branch='fixins', revision='abc', repository='r',
- codebase='cb', project='p', sourcestampsetid=1091)
- })
- d.addCallback(check)
- return d
-
- def test_addBuildsetForSourceStamp_builderNames(self):
- sched = self.makeScheduler(name='n', builderNames=['k'])
- d = self.db.insertTestData([
- fakedb.SourceStampSet(id=1091),
- fakedb.SourceStamp(id=91, sourcestampsetid=1091, branch='fixins',
- revision='abc', patchid=None, repository='r', codebase='cb',
- project='p'),
- ])
- d.addCallback(lambda _ :
- sched.addBuildsetForSourceStamp(reason='whynot', setid = 1091,
- builderNames=['a', 'b']))
- def check((bsid,brids)):
- self.db.buildsets.assertBuildset(bsid,
- dict(reason='whynot', brids=brids,
- external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- sourcestampsetid=1091),
- {'cb':
- dict(branch='fixins', revision='abc', repository='r',
- codebase='cb', project='p', sourcestampsetid=1091)
- })
- d.addCallback(check)
- return d
-
- def test_findNewSchedulerInstance(self):
- sched = self.makeScheduler(name='n', builderNames=['k'])
- new_sched = self.makeScheduler(name='n', builderNames=['l'])
- distractor = self.makeScheduler(name='x', builderNames=['l'])
- config = mock.Mock()
- config.schedulers = dict(dist=distractor, n=new_sched)
- self.assertIdentical(sched.findNewSchedulerInstance(config), new_sched)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_basic.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_basic.py
deleted file mode 100644
index db8e848e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_basic.py
+++ /dev/null
@@ -1,452 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-from twisted.internet import defer, task
-from buildbot import config
-from buildbot.test.fake import fakedb
-from buildbot.schedulers import basic
-from buildbot.test.util import scheduler
-
-class CommonStuffMixin(object):
-
- def makeScheduler(self, klass, **kwargs_override):
- kwargs = dict(name="tsched", treeStableTimer=60,
- builderNames=['tbuild'])
- kwargs.update(kwargs_override)
- sched = self.attachScheduler(klass(**kwargs), self.OBJECTID)
-
- # add a Clock to help checking timing issues
- self.clock = sched._reactor = task.Clock()
-
- # keep track of builds in self.events
- self.events = []
- def addBuildsetForChanges(reason='', external_idstring=None, changeids=[]):
- self.assertEqual(external_idstring, None)
- self.assertEqual(reason, 'scheduler') # basic schedulers all use this
- self.events.append('B%s@%d' % (`changeids`.replace(' ',''),
- self.clock.seconds()))
- return defer.succeed(None)
- sched.addBuildsetForChanges = addBuildsetForChanges
-
- # see self.assertConsumingChanges
- self.consumingChanges = None
- def startConsumingChanges(**kwargs):
- self.consumingChanges = kwargs
- return defer.succeed(None)
- sched.startConsumingChanges = startConsumingChanges
-
- return sched
-
- def assertConsumingChanges(self, **kwargs):
- self.assertEqual(self.consumingChanges, kwargs)
-
-class BaseBasicScheduler(CommonStuffMixin,
- scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 244
-
- # a custom subclass since we're testing the base class. This basically
- # re-implements SingleBranchScheduler, but with more asserts
- class Subclass(basic.BaseBasicScheduler):
- timer_started = False
- def getChangeFilter(self, *args, **kwargs):
- return kwargs.get('change_filter')
-
- def getTimerNameForChange(self, change):
- self.timer_started = True
- return "xxx"
-
- def getChangeClassificationsForTimer(self, objectid, timer_name):
- assert timer_name == "xxx"
- assert objectid == BaseBasicScheduler.OBJECTID
- return self.master.db.schedulers.getChangeClassifications(objectid)
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- # tests
-
- def test_constructor_positional_exception(self):
- self.assertRaises(config.ConfigErrors,
- lambda : self.Subclass("tsched", "master", 60))
-
- def test_startService_no_treeStableTimer(self):
- cf = mock.Mock('cf')
- fII = mock.Mock('fII')
- sched = self.makeScheduler(self.Subclass, treeStableTimer=None, change_filter=cf,
- fileIsImportant=fII)
-
- self.db.schedulers.fakeClassifications(self.OBJECTID, { 20 : True })
-
- d = sched.startService(_returnDeferred=True)
-
- # check that the scheduler has started to consume changes, and the
- # classifications *have* been flushed, since they will not be used
- def check(_):
- self.assertConsumingChanges(fileIsImportant=fII, change_filter=cf,
- onlyImportant=False)
- self.db.schedulers.assertClassifications(self.OBJECTID, {})
- d.addCallback(check)
- d.addCallback(lambda _ : sched.stopService())
- return d
-
- def test_subclass_fileIsImportant(self):
- class Subclass(self.Subclass):
- def fileIsImportant(self, change):
- return False
- sched = self.makeScheduler(Subclass, onlyImportant=True)
- self.failUnlessEqual(Subclass.fileIsImportant.__get__(sched), sched.fileIsImportant)
-
- def test_startService_treeStableTimer(self):
- cf = mock.Mock()
- sched = self.makeScheduler(self.Subclass, treeStableTimer=10, change_filter=cf)
-
- self.db.schedulers.fakeClassifications(self.OBJECTID, { 20 : True })
- self.master.db.insertTestData([
- fakedb.Change(changeid=20),
- fakedb.SchedulerChange(objectid=self.OBJECTID,
- changeid=20, important=1)
- ])
-
- d = sched.startService(_returnDeferred=True)
-
- # check that the scheduler has started to consume changes, and no
- # classifications have been flushed. Furthermore, the existing
- # classification should have been acted on, so the timer should be
- # running
- def check(_):
- self.assertConsumingChanges(fileIsImportant=None, change_filter=cf,
- onlyImportant=False)
- self.db.schedulers.assertClassifications(self.OBJECTID, { 20 : True })
- self.assertTrue(sched.timer_started)
- self.assertEqual(sched.getPendingBuildTimes(), [ 10 ])
- self.clock.advance(10)
- self.assertEqual(sched.getPendingBuildTimes(), [])
- d.addCallback(check)
- d.addCallback(lambda _ : sched.stopService())
- return d
-
- def test_gotChange_no_treeStableTimer_unimportant(self):
- sched = self.makeScheduler(self.Subclass, treeStableTimer=None, branch='master')
-
- sched.startService()
-
- d = sched.gotChange(self.makeFakeChange(branch='master', number=13), False)
- def check(_):
- self.assertEqual(self.events, [])
- d.addCallback(check)
-
- d.addCallback(lambda _ : sched.stopService())
-
- def test_gotChange_no_treeStableTimer_important(self):
- sched = self.makeScheduler(self.Subclass, treeStableTimer=None, branch='master')
-
- sched.startService()
-
- d = sched.gotChange(self.makeFakeChange(branch='master', number=13), True)
- def check(_):
- self.assertEqual(self.events, [ 'B[13]@0' ])
- d.addCallback(check)
-
- d.addCallback(lambda _ : sched.stopService())
-
- def test_gotChange_treeStableTimer_unimportant(self):
- sched = self.makeScheduler(self.Subclass, treeStableTimer=10, branch='master')
-
- sched.startService()
-
- d = sched.gotChange(self.makeFakeChange(branch='master', number=13), False)
- def check(_):
- self.assertEqual(self.events, [])
- d.addCallback(check)
- d.addCallback(lambda _ : self.clock.advance(10))
- d.addCallback(check) # should still be empty
-
- d.addCallback(lambda _ : sched.stopService())
-
- def test_gotChange_treeStableTimer_important(self):
- sched = self.makeScheduler(self.Subclass, treeStableTimer=10, branch='master')
-
- sched.startService()
-
- d = sched.gotChange(self.makeFakeChange(branch='master', number=13), True)
- d.addCallback(lambda _ : self.clock.advance(10))
- def check(_):
- self.assertEqual(self.events, [ 'B[13]@10' ])
- d.addCallback(check)
-
- d.addCallback(lambda _ : sched.stopService())
-
- @defer.inlineCallbacks
- def test_gotChange_treeStableTimer_sequence(self):
- sched = self.makeScheduler(self.Subclass, treeStableTimer=9, branch='master')
- self.master.db.insertTestData([
- fakedb.Change(changeid=1, branch='master', when_timestamp=1110),
- fakedb.ChangeFile(changeid=1, filename='readme.txt'),
- fakedb.Change(changeid=2, branch='master', when_timestamp=2220),
- fakedb.ChangeFile(changeid=2, filename='readme.txt'),
- fakedb.Change(changeid=3, branch='master', when_timestamp=3330),
- fakedb.ChangeFile(changeid=3, filename='readme.txt'),
- fakedb.Change(changeid=4, branch='master', when_timestamp=4440),
- fakedb.ChangeFile(changeid=4, filename='readme.txt'),
- ])
- sched.startService()
-
- self.clock.advance(2220)
-
- # this important change arrives at 2220, so the stable timer will last
- # until 2229
- yield sched.gotChange(
- self.makeFakeChange(branch='master', number=1, when=2220),
- True)
- self.assertEqual(self.events, [])
- self.assertEqual(sched.getPendingBuildTimes(), [2229])
- self.db.schedulers.assertClassifications(self.OBJECTID, { 1 : True })
-
- # but another (unimportant) change arrives before then
- self.clock.advance(6) # to 2226
- self.assertEqual(self.events, [])
-
- yield sched.gotChange(
- self.makeFakeChange(branch='master', number=2, when=2226),
- False)
- self.assertEqual(self.events, [])
- self.assertEqual(sched.getPendingBuildTimes(), [2235])
- self.db.schedulers.assertClassifications(self.OBJECTID, { 1 : True, 2 : False })
-
- self.clock.advance(3) # to 2229
- self.assertEqual(self.events, [])
-
- self.clock.advance(3) # to 2232
- self.assertEqual(self.events, [])
-
- # another important change arrives at 2232
- yield sched.gotChange(
- self.makeFakeChange(branch='master', number=3, when=2232),
- True)
- self.assertEqual(self.events, [])
- self.assertEqual(sched.getPendingBuildTimes(), [2241])
- self.db.schedulers.assertClassifications(self.OBJECTID, { 1 : True, 2 : False, 3 : True })
-
- self.clock.advance(3) # to 2235
- self.assertEqual(self.events, [])
-
- # finally, time to start the build!
- self.clock.advance(6) # to 2241
- self.assertEqual(self.events, [ 'B[1,2,3]@2241' ])
- self.assertEqual(sched.getPendingBuildTimes(), [])
- self.db.schedulers.assertClassifications(self.OBJECTID, { })
-
- yield sched.stopService()
-
-
-class SingleBranchScheduler(CommonStuffMixin,
- scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 245
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- def test_constructor_branch_mandatory(self):
- self.assertRaises(config.ConfigErrors,
- lambda : basic.SingleBranchScheduler(name="tsched", treeStableTimer=60))
-
- def test_constructor_no_branch_but_filter(self):
- # this shouldn't fail
- basic.SingleBranchScheduler(name="tsched", treeStableTimer=60,
- builderNames=['a','b'], change_filter=mock.Mock())
-
- def test_constructor_branches_forbidden(self):
- self.assertRaises(config.ConfigErrors,
- lambda : basic.SingleBranchScheduler(name="tsched", treeStableTimer=60, branches='x'))
-
- def test_gotChange_treeStableTimer_important(self):
- # this looks suspiciously like the same test above, because SingleBranchScheduler
- # is about the same as the test subclass used above
- sched = self.makeScheduler(basic.SingleBranchScheduler,
- treeStableTimer=10, branch='master')
-
- sched.startService()
-
- d = sched.gotChange(self.makeFakeChange(branch='master', number=13), True)
- d.addCallback(lambda _ : self.clock.advance(10))
- def check(_):
- self.assertEqual(self.events, [ 'B[13]@10' ])
- d.addCallback(check)
-
- d.addCallback(lambda _ : sched.stopService())
-
-
-class AnyBranchScheduler(CommonStuffMixin,
- scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 246
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- def test_constructor_branch_forbidden(self):
- self.assertRaises(config.ConfigErrors,
- lambda : basic.SingleBranchScheduler(name="tsched", treeStableTimer=60, branch='x'))
-
- def test_gotChange_treeStableTimer_multiple_branches(self):
- """Two changes with different branches get different treeStableTimers"""
- sched = self.makeScheduler(basic.AnyBranchScheduler,
- treeStableTimer=10, branches=['master', 'devel', 'boring'])
-
- sched.startService()
-
- def mkch(**kwargs):
- ch = self.makeFakeChange(**kwargs)
- self.db.changes.fakeAddChangeInstance(ch)
- return ch
-
- d = defer.succeed(None)
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', number=13), True))
- d.addCallback(lambda _ :
- self.assertEqual(sched.getPendingBuildTimes(), [10]))
- d.addCallback(lambda _ :
- self.clock.advance(1)) # time is now 1
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', number=14), False))
- d.addCallback(lambda _ :
- self.assertEqual(sched.getPendingBuildTimes(), [11]))
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='boring', number=15), False))
- d.addCallback(lambda _ :
- self.clock.pump([1]*4)) # time is now 5
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='devel', number=16), True))
- d.addCallback(lambda _ :
- self.assertEqual(sorted(sched.getPendingBuildTimes()), [11,15]))
- d.addCallback(lambda _ :
- self.clock.pump([1]*10)) # time is now 15
- def check(_):
- self.assertEqual(self.events, [ 'B[13,14]@11', 'B[16]@15' ])
- d.addCallback(check)
-
- d.addCallback(lambda _ : sched.stopService())
-
- def test_gotChange_treeStableTimer_multiple_repositories(self):
- """Two repositories, even with the same branch name, have different treeStableTimers"""
- sched = self.makeScheduler(basic.AnyBranchScheduler,
- treeStableTimer=10, branches=['master'])
-
- sched.startService()
-
- def mkch(**kwargs):
- ch = self.makeFakeChange(**kwargs)
- self.db.changes.fakeAddChangeInstance(ch)
- return ch
-
- d = defer.succeed(None)
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', repository="repo", number=13), True))
- d.addCallback(lambda _ :
- self.clock.advance(1)) # time is now 1
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', repository="repo", number=14), False))
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', repository="other_repo", number=15), False))
- d.addCallback(lambda _ :
- self.clock.pump([1]*4)) # time is now 5
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', repository="other_repo", number=17), True))
- d.addCallback(lambda _ :
- self.clock.pump([1]*10)) # time is now 15
- def check(_):
- self.assertEqual(self.events, [ 'B[13,14]@11', 'B[15,17]@15' ])
- d.addCallback(check)
-
- d.addCallback(lambda _ : sched.stopService())
-
- def test_gotChange_treeStableTimer_multiple_projects(self):
- """Two projects, even with the same branch name, have different treeStableTimers"""
- sched = self.makeScheduler(basic.AnyBranchScheduler,
- treeStableTimer=10, branches=['master'])
-
- sched.startService()
-
- def mkch(**kwargs):
- ch = self.makeFakeChange(**kwargs)
- self.db.changes.fakeAddChangeInstance(ch)
- return ch
-
- d = defer.succeed(None)
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', project="proj", number=13), True))
- d.addCallback(lambda _ :
- self.clock.advance(1)) # time is now 1
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', project="proj", number=14), False))
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', project="other_proj", number=15), False))
- d.addCallback(lambda _ :
- self.clock.pump([1]*4)) # time is now 5
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', project="other_proj", number=17), True))
- d.addCallback(lambda _ :
- self.clock.pump([1]*10)) # time is now 15
- def check(_):
- self.assertEqual(self.events, [ 'B[13,14]@11', 'B[15,17]@15' ])
- d.addCallback(check)
-
- d.addCallback(lambda _ : sched.stopService())
-
- def test_gotChange_treeStableTimer_multiple_codebases(self):
- """Two codebases, even with the same branch name, have different treeStableTimers"""
- sched = self.makeScheduler(basic.AnyBranchScheduler,
- treeStableTimer=10, branches=['master'])
-
- sched.startService()
-
- def mkch(**kwargs):
- ch = self.makeFakeChange(**kwargs)
- self.db.changes.fakeAddChangeInstance(ch)
- return ch
-
- d = defer.succeed(None)
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', codebase="base", number=13), True))
- d.addCallback(lambda _ :
- self.clock.advance(1)) # time is now 1
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', codebase="base", number=14), False))
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', codebase="other_base", number=15), False))
- d.addCallback(lambda _ :
- self.clock.pump([1]*4)) # time is now 5
- d.addCallback(lambda _ :
- sched.gotChange(mkch(branch='master', codebase="other_base", number=17), True))
- d.addCallback(lambda _ :
- self.clock.pump([1]*10)) # time is now 15
- def check(_):
- self.assertEqual(self.events, [ 'B[13,14]@11', 'B[15,17]@15' ])
- d.addCallback(check)
-
- d.addCallback(lambda _ : sched.stopService())
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_dependent.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_dependent.py
deleted file mode 100644
index 0af082a6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_dependent.py
+++ /dev/null
@@ -1,153 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot import config
-from buildbot.schedulers import dependent, base
-from buildbot.status.results import SUCCESS, WARNINGS, FAILURE
-from buildbot.test.util import scheduler
-from buildbot.test.fake import fakedb
-
-class Dependent(scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 33
- UPSTREAM_NAME = 'uppy'
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- def makeScheduler(self, upstream=None):
- # build a fake upstream scheduler
- class Upstream(base.BaseScheduler):
- def __init__(self, name):
- self.name = name
- if not upstream:
- upstream = Upstream(self.UPSTREAM_NAME)
-
- sched = dependent.Dependent(name='n', builderNames=['b'],
- upstream=upstream)
- self.attachScheduler(sched, self.OBJECTID)
- return sched
-
- def assertBuildsetSubscriptions(self, bsids=None):
- self.db.state.assertState(self.OBJECTID,
- upstream_bsids=bsids)
-
- # tests
-
- # NOTE: these tests take advantage of the fact that all of the fake
- # scheduler operations are synchronous, and thus do not return a Deferred.
- # The Deferred from trigger() is completely processed before this test
- # method returns.
-
- def test_constructor_string_arg(self):
- self.assertRaises(config.ConfigErrors,
- lambda : self.makeScheduler(upstream='foo'))
-
- def test_startService(self):
- sched = self.makeScheduler()
- sched.startService()
-
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertNotEqual(callbacks['buildsets'], None)
- self.assertNotEqual(callbacks['buildset_completion'], None)
-
- d = sched.stopService()
- def check(_):
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertEqual(callbacks['buildsets'], None)
- self.assertEqual(callbacks['buildset_completion'], None)
- d.addCallback(check)
- return d
-
- def do_test(self, scheduler_name, expect_subscription,
- result, expect_buildset):
- sched = self.makeScheduler()
- sched.startService()
- callbacks = self.master.getSubscriptionCallbacks()
-
- # pretend we saw a buildset with a matching name
- self.db.insertTestData([
- fakedb.SourceStamp(id=93, sourcestampsetid=1093, revision='555',
- branch='master', project='proj', repository='repo',
- codebase = 'cb'),
- fakedb.Buildset(id=44, sourcestampsetid=1093),
- ])
- callbacks['buildsets'](bsid=44,
- properties=dict(scheduler=(scheduler_name, 'Scheduler')))
-
- # check whether scheduler is subscribed to that buildset
- if expect_subscription:
- self.assertBuildsetSubscriptions([44])
- else:
- self.assertBuildsetSubscriptions([])
-
- # pretend that the buildset is finished
- self.db.buildsets.fakeBuildsetCompletion(bsid=44, result=result)
- callbacks['buildset_completion'](44, result)
-
- # and check whether a buildset was added in response
- if expect_buildset:
- self.db.buildsets.assertBuildsets(2)
- bsids = self.db.buildsets.allBuildsetIds()
- bsids.remove(44)
- self.db.buildsets.assertBuildset(bsids[0],
- dict(external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- reason='downstream', sourcestampsetid = 1093),
- {'cb':
- dict(revision='555', branch='master', project='proj',
- repository='repo', codebase='cb',
- sourcestampsetid = 1093)
- })
- else:
- self.db.buildsets.assertBuildsets(1) # only the one we added above
-
- def test_related_buildset_SUCCESS(self):
- return self.do_test(self.UPSTREAM_NAME, True, SUCCESS, True)
-
- def test_related_buildset_WARNINGS(self):
- return self.do_test(self.UPSTREAM_NAME, True, WARNINGS, True)
-
- def test_related_buildset_FAILURE(self):
- return self.do_test(self.UPSTREAM_NAME, True, FAILURE, False)
-
- def test_unrelated_buildset(self):
- return self.do_test('unrelated', False, SUCCESS, False)
-
- @defer.inlineCallbacks
- def test_getUpstreamBuildsets_missing(self):
- sched = self.makeScheduler()
-
- # insert some state, with more bsids than exist
- self.db.insertTestData([
- fakedb.SourceStampSet(id=99),
- fakedb.Buildset(id=11, sourcestampsetid=99),
- fakedb.Buildset(id=13, sourcestampsetid=99),
- fakedb.Object(id=self.OBJECTID),
- fakedb.ObjectState(objectid=self.OBJECTID,
- name='upstream_bsids', value_json='[11,12,13]'),
- ])
-
- # check return value (missing 12)
- self.assertEqual((yield sched._getUpstreamBuildsets()),
- [(11, 99, False, -1), (13, 99, False, -1)])
-
- # and check that it wrote the correct value back to the state
- self.db.state.assertState(self.OBJECTID, upstream_bsids=[11, 13])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_forcesched.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_forcesched.py
deleted file mode 100644
index 12476224..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_forcesched.py
+++ /dev/null
@@ -1,506 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot import config
-from buildbot.schedulers.forcesched import ForceScheduler, StringParameter
-from buildbot.schedulers.forcesched import IntParameter, FixedParameter
-from buildbot.schedulers.forcesched import BooleanParameter, UserNameParameter
-from buildbot.schedulers.forcesched import ChoiceStringParameter, ValidationError
-from buildbot.schedulers.forcesched import NestedParameter, AnyPropertyParameter
-from buildbot.schedulers.forcesched import CodebaseParameter, BaseParameter
-from buildbot.test.util import scheduler
-from buildbot.test.util.config import ConfigErrorsMixin
-
-class TestForceScheduler(scheduler.SchedulerMixin, ConfigErrorsMixin, unittest.TestCase):
-
- OBJECTID = 19
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- def makeScheduler(self, name='testsched', builderNames=['a', 'b'],
- **kw):
- sched = self.attachScheduler(
- ForceScheduler(name=name, builderNames=builderNames,**kw),
- self.OBJECTID)
- sched.master.config = config.MasterConfig()
-
- self.assertEquals(sched.name, name)
-
- return sched
-
- # tests
-
- def test_compare_branch(self):
- self.assertNotEqual(
- ForceScheduler(name="testched", builderNames=[]),
- ForceScheduler(name="testched", builderNames=[],
- branch=FixedParameter("branch","fishing/pole")))
-
-
- def test_compare_reason(self):
- self.assertNotEqual(
- ForceScheduler(name="testched", builderNames=[],
- reason=FixedParameter("reason","no fish for you!")),
- ForceScheduler(name="testched", builderNames=[],
- reason=FixedParameter("reason","thanks for the fish!")))
-
-
- def test_compare_revision(self):
- self.assertNotEqual(
- ForceScheduler(name="testched", builderNames=[],
- revision=FixedParameter("revision","fish-v1")),
- ForceScheduler(name="testched", builderNames=[],
- revision=FixedParameter("revision","fish-v2")))
-
-
- def test_compare_repository(self):
- self.assertNotEqual(
- ForceScheduler(name="testched", builderNames=[],
- repository=FixedParameter("repository","git://pond.org/fisher.git")),
- ForceScheduler(name="testched", builderNames=[],
- repository=FixedParameter("repository","svn://ocean.com/trawler/")))
-
-
- def test_compare_project(self):
- self.assertNotEqual(
- ForceScheduler(name="testched", builderNames=[],
- project=FixedParameter("project","fisher")),
- ForceScheduler(name="testched", builderNames=[],
- project=FixedParameter("project","trawler")))
-
-
- def test_compare_username(self):
- self.assertNotEqual(
- ForceScheduler(name="testched", builderNames=[]),
- ForceScheduler(name="testched", builderNames=[],
- project=FixedParameter("username","The Fisher King <avallach@atlantis.al>")))
-
-
- def test_compare_properties(self):
- self.assertNotEqual(
- ForceScheduler(name="testched", builderNames=[],
- properties=[]),
- ForceScheduler(name="testched", builderNames=[],
- properties=[FixedParameter("prop","thanks for the fish!")]))
-
- def test_compare_codebases(self):
- self.assertNotEqual(
- ForceScheduler(name="testched", builderNames=[],
- codebases=['bar']),
- ForceScheduler(name="testched", builderNames=[],
- codebases=['foo']))
-
-
- @defer.inlineCallbacks
- def test_basicForce(self):
- sched = self.makeScheduler()
-
- res = yield sched.force('user', builderNames=['a'], branch='a', reason='because',revision='c',
- repository='d', project='p',
- property1_name='p1',property1_value='e',
- property2_name='p2',property2_value='f',
- property3_name='p3',property3_value='g',
- property4_name='p4',property4_value='h'
- )
- bsid,brids = res
-
- # only one builder forced, so there should only be one brid
- self.assertEqual(len(brids), 1)
-
- self.db.buildsets.assertBuildset\
- (bsid,
- dict(reason="A build was forced by 'user': because",
- brids=brids,
- external_idstring=None,
- properties=[ ('owner', ('user', 'Force Build Form')),
- ('p1', ('e', 'Force Build Form')),
- ('p2', ('f', 'Force Build Form')),
- ('p3', ('g', 'Force Build Form')),
- ('p4', ('h', 'Force Build Form')),
- ('reason', ('because', 'Force Build Form')),
- ('scheduler', ('testsched', 'Scheduler')),
- ],
- sourcestampsetid=100),
- {'':
- dict(branch='a', revision='c', repository='d', codebase='',
- project='p', sourcestampsetid=100)
- })
-
- @defer.inlineCallbacks
- def test_force_allBuilders(self):
- sched = self.makeScheduler()
-
- res = yield sched.force('user', branch='a', reason='because',revision='c',
- repository='d', project='p',
- )
- bsid,brids = res
-
- self.assertEqual(len(brids), 2)
-
- self.db.buildsets.assertBuildset\
- (bsid,
- dict(reason="A build was forced by 'user': because",
- brids=brids,
- builders = ['a', 'b'],
- external_idstring=None,
- properties=[ ('owner', ('user', 'Force Build Form')),
- ('reason', ('because', 'Force Build Form')),
- ('scheduler', ('testsched', 'Scheduler')),
- ],
- sourcestampsetid=100),
- {'':
- dict(branch='a', revision='c', repository='d', codebase='',
- project='p', sourcestampsetid=100)
- })
-
- @defer.inlineCallbacks
- def test_force_someBuilders(self):
- sched = self.makeScheduler(builderNames=['a','b','c'])
-
- res = yield sched.force('user', builderNames=['a','b'],
- branch='a', reason='because',revision='c',
- repository='d', project='p',
- )
- bsid,brids = res
-
- self.assertEqual(len(brids), 2)
-
- self.db.buildsets.assertBuildset\
- (bsid,
- dict(reason="A build was forced by 'user': because",
- brids=brids,
- builders = ['a', 'b'],
- external_idstring=None,
- properties=[ ('owner', ('user', 'Force Build Form')),
- ('reason', ('because', 'Force Build Form')),
- ('scheduler', ('testsched', 'Scheduler')),
- ],
- sourcestampsetid=100),
- {'':
- dict(branch='a', revision='c', repository='d', codebase='',
- project='p', sourcestampsetid=100)
- })
-
- def test_bad_codebases(self):
- # cant specify both codebases and branch/revision/project/repository:
- self.assertRaisesConfigError("ForceScheduler: Must either specify 'codebases' or the 'branch/revision/repository/project' parameters:",
- lambda: ForceScheduler(name='foo', builderNames=['bar'],
- codebases=['foo'], branch=StringParameter('name')))
- self.assertRaisesConfigError("ForceScheduler: Must either specify 'codebases' or the 'branch/revision/repository/project' parameters:",
- lambda: ForceScheduler(name='foo', builderNames=['bar'],
- codebases=['foo'], revision=StringParameter('name')))
- self.assertRaisesConfigError("ForceScheduler: Must either specify 'codebases' or the 'branch/revision/repository/project' parameters:",
- lambda: ForceScheduler(name='foo', builderNames=['bar'],
- codebases=['foo'], project=StringParameter('name')))
- self.assertRaisesConfigError("ForceScheduler: Must either specify 'codebases' or the 'branch/revision/repository/project' parameters:",
- lambda: ForceScheduler(name='foo', builderNames=['bar'],
- codebases=['foo'], repository=StringParameter('name')))
-
- # codebases must be a list of either string or BaseParameter types
- self.assertRaisesConfigError("ForceScheduler: 'codebases' must be a list of strings or CodebaseParameter objects:",
- lambda: ForceScheduler(name='foo', builderNames=['bar'],
- codebases=[123],))
- self.assertRaisesConfigError("ForceScheduler: 'codebases' must be a list of strings or CodebaseParameter objects:",
- lambda: ForceScheduler(name='foo', builderNames=['bar'],
- codebases=[IntParameter('foo')],))
-
- # codebases cannot be empty
- self.assertRaisesConfigError("ForceScheduler: 'codebases' cannot be empty; use CodebaseParameter(codebase='', hide=True) if needed:",
- lambda: ForceScheduler(name='foo',
- builderNames=['bar'],
- codebases=[]))
-
- @defer.inlineCallbacks
- def test_good_codebases(self):
- sched = self.makeScheduler(codebases=['foo', CodebaseParameter('bar')])
- res = yield sched.force('user', builderNames=['a'], reason='because',
- foo_branch='a', foo_revision='c', foo_repository='d', foo_project='p',
- bar_branch='a2', bar_revision='c2', bar_repository='d2', bar_project='p2',
- property1_name='p1',property1_value='e',
- property2_name='p2',property2_value='f',
- property3_name='p3',property3_value='g',
- property4_name='p4',property4_value='h'
- )
-
- bsid,brids = res
- self.db.buildsets.assertBuildset\
- (bsid,
- dict(reason="A build was forced by 'user': because",
- brids=brids,
- external_idstring=None,
- properties=[ ('owner', ('user', 'Force Build Form')),
- ('p1', ('e', 'Force Build Form')),
- ('p2', ('f', 'Force Build Form')),
- ('p3', ('g', 'Force Build Form')),
- ('p4', ('h', 'Force Build Form')),
- ('reason', ('because', 'Force Build Form')),
- ('scheduler', ('testsched', 'Scheduler')),
- ],
- sourcestampsetid=100),
- {'foo': dict(codebase='foo', sourcestampsetid=100,
- branch='a', revision='c', repository='d', project='p', ),
- 'bar': dict(codebase='bar', sourcestampsetid=100,
- branch='a2', revision='c2', repository='d2', project='p2', ),
- })
-
- # value = the value to be sent with the parameter (ignored if req is set)
- # expect = the expected result (can be an exception type)
- # klass = the parameter class type
- # req = use this request instead of the auto-generated one based on value
- @defer.inlineCallbacks
- def do_ParameterTest(self,
- expect,
- klass,
- expectKind=None, # None=one prop, Exception=exception, dict=many props
- owner='user',
- value=None, req=None,
- **kwargs):
-
- name = kwargs.setdefault('name', 'p1')
-
- # construct one if needed
- if isinstance(klass, type):
- prop = klass(**kwargs)
- else:
- prop = klass
-
- self.assertEqual(prop.name, name)
- self.assertEqual(prop.label, kwargs.get('label', prop.name))
-
- sched = self.makeScheduler(properties=[prop])
-
- if not req:
- req = {name:value, 'reason':'because'}
- try:
- bsid, brids = yield sched.force(owner, builderNames=['a'], **req)
- except Exception,e:
- if expectKind is not Exception:
- # an exception is not expected
- raise
- if not isinstance(e, expect):
- # the exception is the wrong kind
- raise
- defer.returnValue(None) # success
-
- expect_props = [
- ('owner', ('user', 'Force Build Form')),
- ('reason', ('because', 'Force Build Form')),
- ('scheduler', ('testsched', 'Scheduler')),
- ]
-
- if expectKind is None:
- expect_props.append((name, (expect, 'Force Build Form')))
- elif expectKind is dict:
- for k,v in expect.iteritems():
- expect_props.append((k, (v, 'Force Build Form')))
- else:
- self.fail("expectKind is wrong type!")
-
- self.db.buildsets.assertBuildset\
- (bsid,
- dict(reason="A build was forced by 'user': because",
- brids=brids,
- external_idstring=None,
- properties=sorted(expect_props),
- sourcestampsetid=100),
- {"":
- dict(branch="", revision="", repository="", codebase='',
- project="", sourcestampsetid=100)
- })
-
- def test_StringParameter(self):
- self.do_ParameterTest(value="testedvalue", expect="testedvalue",
- klass=StringParameter)
-
- def test_IntParameter(self):
- self.do_ParameterTest(value="123", expect=123, klass=IntParameter)
-
-
- def test_FixedParameter(self):
- self.do_ParameterTest(value="123", expect="321", klass=FixedParameter,
- default="321")
-
-
- def test_BooleanParameter_True(self):
- req = dict(p1=True,reason='because')
- self.do_ParameterTest(value="123", expect=True, klass=BooleanParameter,
- req=req)
-
-
- def test_BooleanParameter_False(self):
- req = dict(p2=True,reason='because')
- self.do_ParameterTest(value="123", expect=False,
- klass=BooleanParameter, req=req)
-
-
- def test_UserNameParameter(self):
- email = "test <test@buildbot.net>"
- self.do_ParameterTest(value=email, expect=email,
- klass=UserNameParameter(),
- name="username", label="Your name:")
-
-
- def test_UserNameParameterError(self):
- for value in ["test","test@buildbot.net","<test@buildbot.net>"]:
- self.do_ParameterTest(value=value,
- expect=ValidationError,
- expectKind=Exception,
- klass=UserNameParameter(debug=False),
- name="username", label="Your name:")
-
-
- def test_ChoiceParameter(self):
- self.do_ParameterTest(value='t1', expect='t1',
- klass=ChoiceStringParameter, choices=['t1','t2'])
-
-
- def test_ChoiceParameterError(self):
- self.do_ParameterTest(value='t3',
- expect=ValidationError,
- expectKind=Exception,
- klass=ChoiceStringParameter, choices=['t1','t2'],
- debug=False)
-
- def test_ChoiceParameterError_notStrict(self):
- self.do_ParameterTest(value='t1', expect='t1',
- strict=False,
- klass=ChoiceStringParameter, choices=['t1','t2'])
-
-
- def test_ChoiceParameterMultiple(self):
- self.do_ParameterTest(value=['t1','t2'], expect=['t1','t2'],
- klass=ChoiceStringParameter,choices=['t1','t2'], multiple=True)
-
-
- def test_ChoiceParameterMultipleError(self):
- self.do_ParameterTest(value=['t1','t3'],
- expect=ValidationError,
- expectKind=Exception,
- klass=ChoiceStringParameter, choices=['t1','t2'],
- multiple=True, debug=False)
-
-
- def test_NestedParameter(self):
- fields = [
- IntParameter(name="foo")
- ]
- self.do_ParameterTest(req=dict(p1_foo='123', reason="because"),
- expect=dict(foo=123),
- klass=NestedParameter, fields=fields)
-
- def test_NestedNestedParameter(self):
- fields = [
- NestedParameter(name="inner", fields=[
- StringParameter(name='str'),
- AnyPropertyParameter(name='any')
- ]),
- IntParameter(name="foo")
- ]
- self.do_ParameterTest(req=dict(p1_foo='123',
- p1_inner_str="bar",
- p1_inner_any_name="hello",
- p1_inner_any_value="world",
- reason="because"),
- expect=dict(foo=123, inner=dict(str="bar", hello="world")),
- klass=NestedParameter, fields=fields)
-
- def test_NestedParameter_nullname(self):
- # same as above except "p1" and "any" are skipped
- fields = [
- NestedParameter(name="inner", fields=[
- StringParameter(name='str'),
- AnyPropertyParameter(name='')
- ]),
- IntParameter(name="foo"),
- NestedParameter(name='bar', fields=[
- NestedParameter(name='', fields=[AnyPropertyParameter(name='a')]),
- NestedParameter(name='', fields=[AnyPropertyParameter(name='b')])
- ])
- ]
- self.do_ParameterTest(req=dict(foo='123',
- inner_str="bar",
- inner_name="hello",
- inner_value="world",
- reason="because",
- bar_a_name="a",
- bar_a_value="7",
- bar_b_name="b",
- bar_b_value="8"),
- expect=dict(foo=123,
- inner=dict(str="bar", hello="world"),
- bar={'a':'7', 'b':'8'}),
- expectKind=dict,
- klass=NestedParameter, fields=fields, name='')
-
- def test_bad_reason(self):
- self.assertRaisesConfigError("ForceScheduler reason must be a StringParameter",
- lambda: ForceScheduler(name='testsched', builderNames=[],
- codebases=['bar'], reason="foo"))
-
- def test_bad_username(self):
- self.assertRaisesConfigError("ForceScheduler username must be a StringParameter",
- lambda: ForceScheduler(name='testsched', builderNames=[],
- codebases=['bar'], username="foo"))
-
- def test_notstring_name(self):
- self.assertRaisesConfigError("ForceScheduler name must be a unicode string:",
- lambda: ForceScheduler(name=1234, builderNames=[],
- codebases=['bar'], username="foo"))
-
- def test_emptystring_name(self):
- self.assertRaisesConfigError("ForceScheduler name must not be empty:",
- lambda: ForceScheduler(name='', builderNames=[],
- codebases=['bar'], username="foo"))
-
- def test_integer_builderNames(self):
- self.assertRaisesConfigError("ForceScheduler builderNames must be a list of strings:",
- lambda: ForceScheduler(name='testsched', builderNames=1234,
- codebases=['bar'], username="foo"))
-
- def test_listofints_builderNames(self):
- self.assertRaisesConfigError("ForceScheduler builderNames must be a list of strings:",
- lambda: ForceScheduler(name='testsched', builderNames=[1234],
- codebases=['bar'], username="foo"))
-
- def test_listofmixed_builderNames(self):
- self.assertRaisesConfigError("ForceScheduler builderNames must be a list of strings:",
- lambda: ForceScheduler(name='testsched',
- builderNames=['test', 1234],
- codebases=['bar'], username="foo"))
-
- def test_integer_properties(self):
- self.assertRaisesConfigError("ForceScheduler properties must be a list of BaseParameters:",
- lambda: ForceScheduler(name='testsched', builderNames=[],
- codebases=['bar'], username="foo",
- properties=1234))
-
- def test_listofints_properties(self):
- self.assertRaisesConfigError("ForceScheduler properties must be a list of BaseParameters:",
- lambda: ForceScheduler(name='testsched', builderNames=[],
- codebases=['bar'], username="foo",
- properties=[1234, 2345]))
-
- def test_listofmixed_properties(self):
- self.assertRaisesConfigError("ForceScheduler properties must be a list of BaseParameters:",
- lambda: ForceScheduler(name='testsched', builderNames=[],
- codebases=['bar'], username="foo",
- properties=[BaseParameter(name="test",),
- 4567]))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_manager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_manager.py
deleted file mode 100644
index 0c79730b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_manager.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.schedulers import manager, base
-from buildbot import config
-
-class SchedulerManager(unittest.TestCase):
-
- def setUp(self):
- self.next_objectid = 13
- self.objectids = {}
-
- self.master = mock.Mock()
- def getObjectId(sched_name, class_name):
- k = (sched_name, class_name)
- try:
- rv = self.objectids[k]
- except:
- rv = self.objectids[k] = self.next_objectid
- self.next_objectid += 1
- return defer.succeed(rv)
- self.master.db.state.getObjectId = getObjectId
-
- self.new_config = mock.Mock()
-
- self.sm = manager.SchedulerManager(self.master)
- self.sm.startService()
-
- def tearDown(self):
- if self.sm.running:
- return self.sm.stopService()
-
- class Sched(base.BaseScheduler):
-
- # changing sch.attr should make a scheduler look "updated"
- compare_attrs = base.BaseScheduler.compare_attrs + ( 'attr', )
- already_started = False
- reconfig_count = 0
-
- def startService(self):
- assert not self.already_started
- assert self.master is not None
- assert self.objectid is not None
- self.already_started = True
- base.BaseScheduler.startService(self)
-
- def stopService(self):
- d = base.BaseScheduler.stopService(self)
- def still_set(_):
- assert self.master is not None
- assert self.objectid is not None
- d.addCallback(still_set)
- return d
-
- class ReconfigSched(config.ReconfigurableServiceMixin, Sched):
-
- def reconfigService(self, new_config):
- self.reconfig_count += 1
- new_sched = self.findNewSchedulerInstance(new_config)
- self.attr = new_sched.attr
- return config.ReconfigurableServiceMixin.reconfigService(self,
- new_config)
-
- class ReconfigSched2(ReconfigSched):
- pass
-
- def makeSched(self, cls, name, attr='alpha'):
- sch = cls(name=name, builderNames=['x'], properties={})
- sch.attr = attr
- return sch
-
- # tests
-
- @defer.inlineCallbacks
- def test_reconfigService_add_and_change_and_remove(self):
- sch1 = self.makeSched(self.ReconfigSched, 'sch1', attr='alpha')
- self.new_config.schedulers = dict(sch1=sch1)
-
- yield self.sm.reconfigService(self.new_config)
-
- self.assertIdentical(sch1.parent, self.sm)
- self.assertIdentical(sch1.master, self.master)
- self.assertEqual(sch1.reconfig_count, 1)
-
- sch1_new = self.makeSched(self.ReconfigSched, 'sch1', attr='beta')
- sch2 = self.makeSched(self.ReconfigSched, 'sch2', attr='alpha')
- self.new_config.schedulers = dict(sch1=sch1_new, sch2=sch2)
-
- yield self.sm.reconfigService(self.new_config)
-
- # sch1 is still the active scheduler, and has been reconfig'd,
- # and has the correct attribute
- self.assertIdentical(sch1.parent, self.sm)
- self.assertIdentical(sch1.master, self.master)
- self.assertEqual(sch1.attr, 'beta')
- self.assertEqual(sch1.reconfig_count, 2)
- self.assertIdentical(sch1_new.parent, None)
- self.assertIdentical(sch1_new.master, None)
-
- self.assertIdentical(sch2.parent, self.sm)
- self.assertIdentical(sch2.master, self.master)
-
- self.new_config.schedulers = {}
-
- yield self.sm.reconfigService(self.new_config)
-
- self.assertIdentical(sch1.parent, None)
- self.assertIdentical(sch1.master, None)
-
- @defer.inlineCallbacks
- def test_reconfigService_class_name_change(self):
- sch1 = self.makeSched(self.ReconfigSched, 'sch1')
- self.new_config.schedulers = dict(sch1=sch1)
-
- yield self.sm.reconfigService(self.new_config)
-
- self.assertIdentical(sch1.parent, self.sm)
- self.assertIdentical(sch1.master, self.master)
- self.assertEqual(sch1.reconfig_count, 1)
-
- sch1_new = self.makeSched(self.ReconfigSched2, 'sch1')
- self.new_config.schedulers = dict(sch1=sch1_new)
-
- yield self.sm.reconfigService(self.new_config)
-
- # sch1 had its class name change, so sch1_new is now the active
- # instance
- self.assertIdentical(sch1_new.parent, self.sm)
- self.assertIdentical(sch1_new.master, self.master)
-
- @defer.inlineCallbacks
- def test_reconfigService_add_and_change_and_remove_no_reconfig(self):
- sch1 = self.makeSched(self.Sched, 'sch1', attr='alpha')
- self.new_config.schedulers = dict(sch1=sch1)
-
- yield self.sm.reconfigService(self.new_config)
-
- self.assertIdentical(sch1.parent, self.sm)
- self.assertIdentical(sch1.master, self.master)
-
- sch1_new = self.makeSched(self.Sched, 'sch1', attr='beta')
- sch2 = self.makeSched(self.Sched, 'sch2', attr='alpha')
- self.new_config.schedulers = dict(sch1=sch1_new, sch2=sch2)
-
- yield self.sm.reconfigService(self.new_config)
-
- # sch1 is not longer active, and sch1_new is
- self.assertIdentical(sch1.parent, None)
- self.assertIdentical(sch1.master, None)
- self.assertIdentical(sch1_new.parent, self.sm)
- self.assertIdentical(sch1_new.master, self.master)
- self.assertIdentical(sch2.parent, self.sm)
- self.assertIdentical(sch2.master, self.master)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Nightly.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Nightly.py
deleted file mode 100644
index 34d6c3cb..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Nightly.py
+++ /dev/null
@@ -1,208 +0,0 @@
-# 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 time
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer, task
-from twisted.python import log
-from buildbot.schedulers import timed
-from buildbot.test.util import scheduler
-from buildbot.changes import filter
-from buildbot import config
-
-class Nightly(scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 132
-
- # not all timezones are even multiples of 1h from GMT. This variable
- # holds the number of seconds ahead of the hour for the current timezone.
- # This is then added to the clock before each test is run (to get to 0
- # minutes past the hour) and subtracted before the time offset is reported.
- localtime_offset = time.timezone % 3600
-
- def makeScheduler(self, firstBuildDuration=0, **kwargs):
- sched = self.attachScheduler(timed.Nightly(**kwargs),
- self.OBJECTID)
-
- # add a Clock to help checking timing issues
- self.clock = sched._reactor = task.Clock()
- self.clock.advance(self.localtime_offset) # get to 0 min past the hour
-
- # keep track of builds in self.events
- self.events = []
- def addBuildsetForLatest(reason='', external_idstring='',
- branch=None, repository='', project=''):
- self.assertIn('scheduler named', reason)
- isFirst = (self.events == [])
- self.events.append('B(%s)@%d' % (branch,
- # show the offset as seconds past the GMT hour
- self.clock.seconds() - self.localtime_offset))
- if isFirst and firstBuildDuration:
- d = defer.Deferred()
- self.clock.callLater(firstBuildDuration, d.callback, None)
- return d
- else:
- return defer.succeed(None)
- sched.addBuildsetForLatest = addBuildsetForLatest
-
- def addBuildsetForChanges(reason='', external_idstring='', changeids=[]):
- self.events.append('B%s@%d' % (`changeids`.replace(' ',''),
- # show the offset as seconds past the GMT hour
- self.clock.seconds() - self.localtime_offset))
- return defer.succeed(None)
- sched.addBuildsetForChanges = addBuildsetForChanges
-
- # see self.assertConsumingChanges
- self.consumingChanges = None
- def startConsumingChanges(**kwargs):
- self.consumingChanges = kwargs
- return defer.succeed(None)
- sched.startConsumingChanges = startConsumingChanges
-
- return sched
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- def assertConsumingChanges(self, **kwargs):
- self.assertEqual(self.consumingChanges, kwargs)
-
- ## Tests
-
- def test_constructor_change_filter(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- branch=None, change_filter=filter.ChangeFilter(category_re="fo+o"))
- assert sched.change_filter
-
- def test_constructor_no_branch(self):
- self.assertRaises(config.ConfigErrors,
- lambda : self.makeScheduler(name='test', builderNames=['test'],
- change_filter=filter.ChangeFilter(category_re="fo+o")))
-
- ## end-to-end tests: let's see the scheduler in action
-
- def test_iterations_simple(self):
- # note that Nightly works in local time, but the task.Clock() always
- # starts at midnight UTC, so be careful not to use times that are
- # timezone dependent -- stick to minutes-past-the-half-hour, as some
- # timezones are multiples of 30 minutes off from UTC
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ], branch=None,
- minute=[10, 20, 21, 40, 50, 51])
-
- # add a change classification
- self.db.schedulers.fakeClassifications(self.OBJECTID, { 19 : True })
-
- sched.startService()
-
- # check that the classification has been flushed, since this
- # invocation has not requested onlyIfChanged
- self.db.schedulers.assertClassifications(self.OBJECTID, {})
-
- self.clock.advance(0) # let it get set up
- while self.clock.seconds() < self.localtime_offset + 30*60:
- self.clock.advance(60)
- self.assertEqual(self.events, [ 'B(None)@600', 'B(None)@1200', 'B(None)@1260' ])
- self.db.state.assertStateByClass('test', 'Nightly',
- last_build=1260 + self.localtime_offset)
-
- d = sched.stopService()
- return d
-
- def test_iterations_simple_with_branch(self):
- # see timezone warning above
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ],
- branch='master', minute=[5, 35])
-
- sched.startService()
-
- self.clock.advance(0)
- while self.clock.seconds() < self.localtime_offset + 10*60:
- self.clock.advance(60)
- self.assertEqual(self.events, [ 'B(master)@300' ])
- self.db.state.assertStateByClass('test', 'Nightly',
- last_build=300 + self.localtime_offset)
-
- d = sched.stopService()
- return d
-
- def do_test_iterations_onlyIfChanged(self, *changes_at):
- fII = mock.Mock(name='fII')
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ], branch=None,
- minute=[5, 25, 45], onlyIfChanged=True,
- fileIsImportant=fII)
-
- sched.startService()
-
- # check that the scheduler has started to consume changes
- self.assertConsumingChanges(fileIsImportant=fII, change_filter=None,
- onlyImportant=False)
-
- # manually run the clock forward through a half-hour, allowing any
- # excitement to take place
- changes_at = list(changes_at)
- self.clock.advance(0) # let it trigger the first build
- while self.clock.seconds() < self.localtime_offset + 30*60:
- # inject any new changes..
- while (changes_at and
- self.clock.seconds() >=
- self.localtime_offset + changes_at[0][0]):
- when, newchange, important = changes_at.pop(0)
- self.sched.gotChange(newchange, important).addErrback(log.err)
- # and advance the clock by a minute
- self.clock.advance(60)
-
- def test_iterations_onlyIfChanged_no_changes(self):
- self.do_test_iterations_onlyIfChanged()
- self.assertEqual(self.events, [])
- self.db.state.assertStateByClass('test', 'Nightly',
- last_build=1500 + self.localtime_offset)
- return self.sched.stopService()
-
- def test_iterations_onlyIfChanged_unimp_changes(self):
- self.do_test_iterations_onlyIfChanged(
- (60, mock.Mock(), False),
- (600, mock.Mock(), False))
- self.assertEqual(self.events, [])
- self.db.state.assertStateByClass('test', 'Nightly',
- last_build=1500 + self.localtime_offset)
- return self.sched.stopService()
-
- def test_iterations_onlyIfChanged_off_branch_changes(self):
- self.do_test_iterations_onlyIfChanged(
- (60, self.makeFakeChange(branch='testing'), True),
- (1700, self.makeFakeChange(branch='staging'), True))
- self.assertEqual(self.events, [])
- self.db.state.assertStateByClass('test', 'Nightly',
- last_build=1500 + self.localtime_offset)
- return self.sched.stopService()
-
- def test_iterations_onlyIfChanged_mixed_changes(self):
- self.do_test_iterations_onlyIfChanged(
- (120, self.makeFakeChange(number=3, branch=None), False),
- (130, self.makeFakeChange(number=4, branch='offbranch'), True),
- (1200, self.makeFakeChange(number=5, branch=None), True),
- (1201, self.makeFakeChange(number=6, branch=None), False),
- (1202, self.makeFakeChange(number=7, branch='offbranch'), True))
- # note that the changeid list includes the unimportant changes, but not the
- # off-branch changes, and note that no build took place at 300s, as no important
- # changes had yet arrived
- self.assertEqual(self.events, [ 'B[3,5,6]@1500' ])
- self.db.state.assertStateByClass('test', 'Nightly',
- last_build=1500 + self.localtime_offset)
- return self.sched.stopService()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_NightlyBase.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_NightlyBase.py
deleted file mode 100644
index 4d799aed..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_NightlyBase.py
+++ /dev/null
@@ -1,206 +0,0 @@
-# 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 sys
-import time
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.schedulers import timed
-from buildbot.test.util import scheduler
-from buildbot.test.util import config
-
-class NightlyBase(scheduler.SchedulerMixin, unittest.TestCase):
- """detailed getNextBuildTime tests"""
-
- OBJECTID = 133
-
- def makeScheduler(self, firstBuildDuration=0, **kwargs):
- return self.attachScheduler(timed.NightlyBase(**kwargs),
- self.OBJECTID)
-
- @defer.inlineCallbacks
- def do_getNextBuildTime_test(self, sched, *expectations):
- for lastActuated, expected in expectations:
- # convert from tuples to epoch time (in local timezone)
- lastActuated_ep, expected_ep = [
- time.mktime(t + (0,) * (8 - len(t)) + (-1,))
- for t in (lastActuated, expected) ]
- got_ep = yield sched.getNextBuildTime(lastActuated_ep)
- self.assertEqual(got_ep, expected_ep,
- "%s -> %s != %s" % (lastActuated, time.localtime(got_ep),
- expected))
-
- def test_getNextBuildTime_hourly(self):
- sched = self.makeScheduler(name='test', builderNames=['test'])
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 1, 3, 0, 0), (2011, 1, 1, 4, 0, 0)),
- ((2011, 1, 1, 3, 15, 0), (2011, 1, 1, 4, 0, 0)),
- ((2011, 1, 1, 3, 15, 1), (2011, 1, 1, 4, 0, 0)),
- ((2011, 1, 1, 3, 59, 1), (2011, 1, 1, 4, 0, 0)),
- ((2011, 1, 1, 3, 59, 59), (2011, 1, 1, 4, 0, 0)),
- ((2011, 1, 1, 23, 22, 22), (2011, 1, 2, 0, 0, 0)),
- ((2011, 1, 1, 23, 59, 0), (2011, 1, 2, 0, 0, 0)),
- )
-
- def test_getNextBuildTime_minutes_single(self):
- # basically the same as .._hourly
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=4)
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 1, 3, 0, 0), (2011, 1, 1, 3, 4, 0)),
- ((2011, 1, 1, 3, 15, 0), (2011, 1, 1, 4, 4, 0)),
- )
-
- def test_getNextBuildTime_minutes_multiple(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[4, 34])
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 1, 3, 0, 0), (2011, 1, 1, 3, 4, 0)),
- ((2011, 1, 1, 3, 15, 0), (2011, 1, 1, 3, 34, 0)),
- ((2011, 1, 1, 3, 34, 0), (2011, 1, 1, 4, 4, 0)),
- ((2011, 1, 1, 3, 59, 1), (2011, 1, 1, 4, 4, 0)),
- )
-
- def test_getNextBuildTime_minutes_star(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute='*')
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 1, 3, 11, 30), (2011, 1, 1, 3, 12, 0)),
- ((2011, 1, 1, 3, 12, 0), (2011, 1, 1, 3, 13, 0)),
- ((2011, 1, 1, 3, 59, 0), (2011, 1, 1, 4, 0, 0)),
- )
-
- def test_getNextBuildTime_hours_single(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- hour=4)
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 1, 3, 0), (2011, 1, 1, 4, 0)),
- ((2011, 1, 1, 13, 0), (2011, 1, 2, 4, 0)),
- )
-
- def test_getNextBuildTime_hours_multiple(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- hour=[7, 19])
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 1, 3, 0), (2011, 1, 1, 7, 0)),
- ((2011, 1, 1, 7, 1), (2011, 1, 1, 19, 0)),
- ((2011, 1, 1, 18, 59), (2011, 1, 1, 19, 0)),
- ((2011, 1, 1, 19, 59), (2011, 1, 2, 7, 0)),
- )
-
- def test_getNextBuildTime_hours_minutes(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- hour=13, minute=19)
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 1, 3, 11), (2011, 1, 1, 13, 19)),
- ((2011, 1, 1, 13, 19), (2011, 1, 2, 13, 19)),
- ((2011, 1, 1, 23, 59), (2011, 1, 2, 13, 19)),
- )
-
- def test_getNextBuildTime_month_single(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- month=3)
- return self.do_getNextBuildTime_test(sched,
- ((2011, 2, 27, 3, 11), (2011, 3, 1, 0, 0)),
- ((2011, 3, 1, 1, 11), (2011, 3, 1, 2, 0)), # still hourly!
- )
-
- def test_getNextBuildTime_month_multiple(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- month=[4, 6])
- return self.do_getNextBuildTime_test(sched,
- ((2011, 3, 30, 3, 11), (2011, 4, 1, 0, 0)),
- ((2011, 4, 1, 1, 11), (2011, 4, 1, 2, 0)), # still hourly!
- ((2011, 5, 29, 3, 11), (2011, 6, 1, 0, 0)),
- )
-
- def test_getNextBuildTime_month_dayOfMonth(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- month=[3, 6], dayOfMonth=[15])
- return self.do_getNextBuildTime_test(sched,
- ((2011, 2, 12, 3, 11), (2011, 3, 15, 0, 0)),
- ((2011, 3, 12, 3, 11), (2011, 3, 15, 0, 0)),
- )
-
- def test_getNextBuildTime_dayOfMonth_single(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- dayOfMonth=10)
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 9, 3, 0), (2011, 1, 10, 0, 0)),
- ((2011, 1, 10, 3, 0), (2011, 1, 10, 4, 0)), # still hourly!
- ((2011, 1, 30, 3, 0), (2011, 2, 10, 0, 0)),
- ((2011, 12, 30, 11, 0), (2012, 1, 10, 0, 0)),
- )
-
- def test_getNextBuildTime_dayOfMonth_multiple(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- dayOfMonth=[10, 20, 30])
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 9, 22, 0), (2011, 1, 10, 0, 0)),
- ((2011, 1, 19, 22, 0), (2011, 1, 20, 0, 0)),
- ((2011, 1, 29, 22, 0), (2011, 1, 30, 0, 0)),
- ((2011, 2, 29, 22, 0), (2011, 3, 10, 0, 0)), # no Feb 30!
- )
-
- def test_getNextBuildTime_dayOfMonth_hours_minutes(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- dayOfMonth=15, hour=20, minute=30)
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 13, 22, 19), (2011, 1, 15, 20, 30)),
- ((2011, 1, 15, 19, 19), (2011, 1, 15, 20, 30)),
- ((2011, 1, 15, 20, 29), (2011, 1, 15, 20, 30)),
- )
-
- def test_getNextBuildTime_dayOfWeek_single(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- dayOfWeek=1) # Tuesday (2011-1-1 was a Saturday)
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 3, 22, 19), (2011, 1, 4, 0, 0)),
- ((2011, 1, 4, 19, 19), (2011, 1, 4, 20, 0)), # still hourly!
- )
-
- def test_getNextBuildTime_dayOfWeek_multiple_hours(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- dayOfWeek=[1,3], hour=1) # Tuesday, Thursday (2011-1-1 was a Saturday)
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 3, 22, 19), (2011, 1, 4, 1, 0)),
- ((2011, 1, 4, 22, 19), (2011, 1, 6, 1, 0)),
- )
-
- def test_getNextBuildTime_dayOfWeek_dayOfMonth(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- dayOfWeek=[1,4], dayOfMonth=5, hour=1)
- return self.do_getNextBuildTime_test(sched,
- ((2011, 1, 3, 22, 19), (2011, 1, 4, 1, 0)), # Tues
- ((2011, 1, 4, 22, 19), (2011, 1, 5, 1, 0)), # 5th
- ((2011, 1, 5, 22, 19), (2011, 1, 7, 1, 0)), # Thurs
- )
-
-class NightlyCroniterImport(config.ConfigErrorsMixin, unittest.TestCase):
-
- def setUp(self):
- self.savedModules = sys.modules.copy()
-
- def tearDown(self):
- sys.modules.clear()
- sys.modules.update(self.savedModules)
-
- def test_error_without_dateutil(self):
- del sys.modules['buildbot.schedulers.timed']
- del sys.modules['buildbot.util']
- sys.modules["dateutil.relativedelta"] = None
- from buildbot.schedulers.timed import NightlyBase
- self.assertRaisesConfigError("python-dateutil",
- lambda: NightlyBase(name='name', builderNames=[]))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_NightlyTriggerable.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_NightlyTriggerable.py
deleted file mode 100644
index 68b7416e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_NightlyTriggerable.py
+++ /dev/null
@@ -1,309 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from twisted.internet import task
-from buildbot.process import properties
-from buildbot.schedulers import timed
-from buildbot.test.fake import fakedb
-from buildbot.test.util import scheduler
-
-class NightlyTriggerable(scheduler.SchedulerMixin, unittest.TestCase):
-
- SCHEDULERID = 1327
-
- def makeScheduler(self, firstBuildDuration=0, **kwargs):
- sched = self.attachScheduler(timed.NightlyTriggerable(**kwargs),
- self.SCHEDULERID)
-
- # add a Clock to help checking timing issues
- self.clock = sched._reactor = task.Clock()
-
- return sched
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
-
- def test_timer_noBuilds(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5])
-
- sched.startService()
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildsets(0)
-
-
- def test_timer_oneTrigger(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5], codebases={'cb':{'repository':'annoying'}})
-
- sched.startService()
-
- sched.trigger({'cb':
- dict(revision='myrev',
- branch='br', project='p', repository='r'),
- }, set_props=None)
-
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[
- ('scheduler', ('test', 'Scheduler')),
- ],
- reason="The NightlyTriggerable scheduler named 'test' triggered this build",
- sourcestampsetid=100),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev', sourcestampsetid=100)
- })
-
-
- def test_timer_twoTriggers(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5], codebases={'cb':{'repository':'annoying'}})
-
- sched.startService()
-
- sched.trigger({ 'cb':
- dict(revision='myrev1', branch='br', project='p', repository='r')
- } , set_props=None)
- sched.trigger({ 'cb':
- dict(revision='myrev2', branch='br', project='p', repository='r')
- } , set_props=None)
-
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[
- ('scheduler', ('test', 'Scheduler')),
- ],
- reason="The NightlyTriggerable scheduler named 'test' triggered this build",
- sourcestampsetid=100),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev2', sourcestampsetid=100)
- })
-
-
- def test_timer_oneTrigger_then_noBuild(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5], codebases={'cb':{'repository':'annoying'}})
-
- sched.startService()
-
- sched.trigger({ 'cb':
- dict(revision='myrev', branch='br', project='p', repository='r')
- } , set_props=None)
-
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[
- ('scheduler', ('test', 'Scheduler')),
- ],
- reason="The NightlyTriggerable scheduler named 'test' triggered this build",
- sourcestampsetid=100),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev', sourcestampsetid=100)
- })
-
- self.db.buildsets.flushBuildsets()
-
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildsets(0)
-
-
- def test_timer_oneTriggers_then_oneTrigger(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5], codebases={'cb':{'repository':'annoying'}})
-
- sched.startService()
-
- sched.trigger({ 'cb':
- dict(revision='myrev1', branch='br', project='p', repository='r')
- } , set_props=None)
-
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[
- ('scheduler', ('test', 'Scheduler')),
- ],
- reason="The NightlyTriggerable scheduler named 'test' triggered this build",
- sourcestampsetid=100),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev1', sourcestampsetid=100)
- })
- self.db.buildsets.flushBuildsets()
-
- sched.trigger({ 'cb':
- dict(revision='myrev2', branch='br', project='p', repository='r')
- } , set_props=None)
-
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[
- ('scheduler', ('test', 'Scheduler')),
- ],
- reason="The NightlyTriggerable scheduler named 'test' triggered this build",
- sourcestampsetid=101),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev2', sourcestampsetid=101)
- })
-
- def test_savedTrigger(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5], codebases={'cb':{'repository':'annoying'}})
- self.db.insertTestData([
- fakedb.Object(id=self.SCHEDULERID, name='test', class_name='NightlyTriggerable'),
- fakedb.ObjectState(objectid=self.SCHEDULERID, name='lastTrigger',
- value_json='[ {"cb": {"project": "p", "repository": "r", "branch": "br", "revision": "myrev"}} , {} ]'),
- ])
-
- sched.startService()
-
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[
- ('scheduler', ('test', 'Scheduler')),
- ],
- reason="The NightlyTriggerable scheduler named 'test' triggered this build",
- sourcestampsetid=100),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev', sourcestampsetid=100)
- })
-
- def test_saveTrigger(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5], codebases={'cb':{'repository':'annoying'}})
- self.db.insertTestData([
- fakedb.Object(id=self.SCHEDULERID, name='test', class_name='NightlyTriggerable'),
- ])
-
- sched.startService()
-
- d = sched.trigger({'cb':
- dict(revision='myrev',
- branch='br', project='p', repository='r'),
- }, set_props=None)
-
- @d.addCallback
- def cb(_):
- self.db.state.assertState(self.SCHEDULERID, lastTrigger=[{'cb':
- dict(revision='myrev',
- branch='br', project='p', repository='r'),
- }, {}])
-
- return d
-
- def test_saveTrigger_noTrigger(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5], codebases={'cb':{'repository':'annoying'}})
- self.db.insertTestData([
- fakedb.Object(id=self.SCHEDULERID, name='test', class_name='NightlyTriggerable'),
- ])
-
- sched.startService()
-
- d = sched.trigger({'cb':
- dict(revision='myrev',
- branch='br', project='p', repository='r'),
- }, set_props=None)
-
- self.clock.advance(60*60) # Run for 1h
-
- @d.addCallback
- def cb(_):
- self.db.state.assertState(self.SCHEDULERID, lastTrigger=None)
-
- return d
-
- def test_triggerProperties(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5], codebases={'cb':{'repository':'annoying'}})
- self.db.insertTestData([
- fakedb.Object(id=self.SCHEDULERID, name='test', class_name='NightlyTriggerable'),
- ])
-
- sched.startService()
-
- sched.trigger({'cb':
- dict(revision='myrev',
- branch='br', project='p', repository='r'),
- }, properties.Properties(testprop='test'))
-
- self.db.state.assertState(self.SCHEDULERID, lastTrigger=[{'cb':
- dict(revision='myrev',
- branch='br', project='p', repository='r'),
- }, {'testprop': ['test', 'TEST']}])
-
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[
- ('scheduler', ('test', 'Scheduler')),
- ('testprop', ('test', 'TEST')),
- ],
- reason="The NightlyTriggerable scheduler named 'test' triggered this build",
- sourcestampsetid=100),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev', sourcestampsetid=100)
- })
-
- def test_savedProperties(self):
- sched = self.makeScheduler(name='test', builderNames=['test'],
- minute=[5], codebases={'cb':{'repository':'annoying'}})
- self.db.insertTestData([
- fakedb.Object(id=self.SCHEDULERID, name='test', class_name='NightlyTriggerable'),
- fakedb.ObjectState(objectid=self.SCHEDULERID, name='lastTrigger',
- value_json='[ {"cb": {"project": "p", "repository": "r", "branch": "br", "revision": "myrev"}} , {"testprop": ["test", "TEST"]} ]'),
- ])
-
- sched.startService()
-
- self.clock.advance(60*60) # Run for 1h
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[
- ('scheduler', ('test', 'Scheduler')),
- ('testprop', ('test', 'TEST')),
- ],
- reason="The NightlyTriggerable scheduler named 'test' triggered this build",
- sourcestampsetid=100),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev', sourcestampsetid=100)
- })
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Periodic.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Periodic.py
deleted file mode 100644
index 5139a96a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Periodic.py
+++ /dev/null
@@ -1,173 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from twisted.internet import task, defer
-from buildbot.schedulers import timed
-from buildbot import config
-
-class Periodic(unittest.TestCase):
-
- def makeScheduler(self, firstBuildDuration=0, exp_branch=None, **kwargs):
- self.sched = sched = timed.Periodic(**kwargs)
-
- # add a Clock to help checking timing issues
- self.clock = sched._reactor = task.Clock()
-
- # keep track of builds in self.events
- self.events = []
- def addBuildsetForLatest(reason=None, branch=None):
- self.assertIn('Periodic scheduler named', reason)
- self.assertEqual(branch, exp_branch)
- isFirst = (self.events == [])
- self.events.append('B@%d' % self.clock.seconds())
- if isFirst and firstBuildDuration:
- d = defer.Deferred()
- self.clock.callLater(firstBuildDuration, d.callback, None)
- return d
- else:
- return defer.succeed(None)
- sched.addBuildsetForLatest = addBuildsetForLatest
-
- # handle state locally
- self.state = {}
-
- def getState(k, default):
- return defer.succeed(self.state.get(k, default))
- sched.getState = getState
-
- def setState(k, v):
- self.state[k] = v
- return defer.succeed(None)
- sched.setState = setState
-
- return sched
-
- # tests
-
- def test_constructor_invalid(self):
- self.assertRaises(config.ConfigErrors,
- lambda : timed.Periodic(name='test', builderNames=[ 'test' ],
- periodicBuildTimer=-2))
-
- def test_iterations_simple(self):
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ],
- periodicBuildTimer=13)
-
- sched.startService()
- self.clock.advance(0) # let it trigger the first build
- while self.clock.seconds() < 30:
- self.clock.advance(1)
- self.assertEqual(self.events, [ 'B@0', 'B@13', 'B@26' ])
- self.assertEqual(self.state.get('last_build'), 26)
-
- d = sched.stopService()
- return d
-
- def test_iterations_simple_branch(self):
- sched = self.makeScheduler(exp_branch='newfeature',
- name='test', builderNames=[ 'test' ],
- periodicBuildTimer=13, branch='newfeature')
-
- sched.startService()
- self.clock.advance(0) # let it trigger the first build
- while self.clock.seconds() < 30:
- self.clock.advance(1)
- self.assertEqual(self.events, [ 'B@0', 'B@13', 'B@26' ])
- self.assertEqual(self.state.get('last_build'), 26)
-
- d = sched.stopService()
- return d
-
- def test_iterations_long(self):
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ],
- periodicBuildTimer=10,
- firstBuildDuration=15) # takes a while to start a build
-
- sched.startService()
- self.clock.advance(0) # let it trigger the first (longer) build
- while self.clock.seconds() < 40:
- self.clock.advance(1)
- self.assertEqual(self.events, [ 'B@0', 'B@15', 'B@25', 'B@35' ])
- self.assertEqual(self.state.get('last_build'), 35)
-
- d = sched.stopService()
- return d
-
- def test_iterations_stop_while_starting_build(self):
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ],
- periodicBuildTimer=13,
- firstBuildDuration=6) # takes a while to start a build
-
- sched.startService()
- self.clock.advance(0) # let it trigger the first (longer) build
- self.clock.advance(3) # get partway into that build
-
- d = sched.stopService() # begin stopping the service
- d.addCallback(lambda _ : self.events.append('STOP@%d' % self.clock.seconds()))
-
- # run the clock out
- while self.clock.seconds() < 40:
- self.clock.advance(1)
-
- # note that the stopService completes after the first build completes, and no
- # subsequent builds occur
- self.assertEqual(self.events, [ 'B@0', 'STOP@6' ])
- self.assertEqual(self.state.get('last_build'), 0)
-
- return d
-
- def test_iterations_with_initial_state(self):
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ],
- periodicBuildTimer=13)
- self.state['last_build'] = self.clock.seconds() - 7 # so next build should start in 6s
-
- sched.startService()
- self.clock.advance(0) # let it trigger the first build
- while self.clock.seconds() < 30:
- self.clock.advance(1)
- self.assertEqual(self.events, [ 'B@6', 'B@19' ])
- self.assertEqual(self.state.get('last_build'), 19)
-
- d = sched.stopService()
- return d
-
- def test_getNextBuildTime_None(self):
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ],
- periodicBuildTimer=13)
- # given None, build right away
- d = sched.getNextBuildTime(None)
- d.addCallback(lambda t : self.assertEqual(t, 0))
- return d
-
- def test_getNextBuildTime_given(self):
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ],
- periodicBuildTimer=13)
- # given a time, add the periodicBuildTimer to it
- d = sched.getNextBuildTime(20)
- d.addCallback(lambda t : self.assertEqual(t, 33))
- return d
-
- def test_getPendingBuildTimes(self):
- sched = self.makeScheduler(name='test', builderNames=[ 'test' ],
- periodicBuildTimer=13)
- self.state['last_build'] = self.clock.seconds() - 10 # so next build should start in 3s
-
- sched.startService()
- self.clock.advance(0) # let it schedule the first build
- self.assertEqual(sched.getPendingBuildTimes(), [ 3.0 ])
-
- d = sched.stopService()
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Timed.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Timed.py
deleted file mode 100644
index 54ecd70d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_timed_Timed.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from twisted.internet import task, defer
-from buildbot.schedulers import timed
-from buildbot.test.util import scheduler
-
-class Timed(scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 928754
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- class Subclass(timed.Timed):
- def getNextBuildTime(self, lastActuation):
- self.got_lastActuation = lastActuation
- return defer.succeed((lastActuation or 1000) + 60)
- def startBuild(self):
- self.started_build = True
- return defer.succeed(None)
-
- def makeScheduler(self, firstBuildDuration=0, **kwargs):
- sched = self.attachScheduler(self.Subclass(**kwargs), self.OBJECTID)
- self.clock = sched._reactor = task.Clock()
- return sched
-
- # tests
-
- # note that most of the heavy-lifting for testing this class is handled by
- # the subclasses' tests, as that's the more natural place for it
-
- def test_getPendingBuildTimes(self):
- sched = self.makeScheduler(name='test', builderNames=['foo'])
-
- sched.startService()
-
- self.assertEqual(sched.got_lastActuation, None)
- self.assertEqual(sched.getPendingBuildTimes(), [ 1060 ])
-
- self.clock.advance(1065)
- self.assertTrue(sched.started_build)
- self.assertEqual(sched.getPendingBuildTimes(), [ 1120 ])
-
- d = sched.stopService()
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_triggerable.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_triggerable.py
deleted file mode 100644
index eb225b5b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_triggerable.py
+++ /dev/null
@@ -1,211 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.schedulers import triggerable
-from buildbot.process import properties
-from buildbot.test.util import scheduler
-
-class Triggerable(scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 33
-
- def setUp(self):
- self.setUpScheduler()
- self.subscription = None
-
- def tearDown(self):
- self.tearDownScheduler()
-
- def makeScheduler(self, **kwargs):
- sched = self.attachScheduler(
- triggerable.Triggerable(name='n', builderNames=['b'], **kwargs),
- self.OBJECTID)
-
- return sched
-
- # tests
-
- # NOTE: these tests take advantage of the fact that all of the fake
- # scheduler operations are synchronous, and thus do not return a Deferred.
- # The Deferred from trigger() is completely processed before this test
- # method returns.
-
- def test_trigger(self):
- sched = self.makeScheduler(codebases = {'cb':{'repository':'r'}})
- # no subscription should be in place yet
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertEqual(callbacks['buildset_completion'], None)
-
- # trigger the scheduler, exercising properties while we're at it
- set_props = properties.Properties()
- set_props.setProperty('pr', 'op', 'test')
- ss = {'revision':'myrev',
- 'branch':'br',
- 'project':'p',
- 'repository':'r',
- 'codebase':'cb' }
- d = sched.trigger({'cb': ss}, set_props=set_props)
-
- bsid = self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[
- ('pr', ('op', 'test')),
- ('scheduler', ('n', 'Scheduler')),
- ],
- reason='Triggerable(n)',
- sourcestampsetid=100),
- {'cb':
- dict(branch='br', project='p', repository='r',
- codebase='cb', revision='myrev', sourcestampsetid=100)
- })
- # set up a boolean so that we can know when the deferred fires
- self.fired = False
- def fired((result, brids)):
- self.assertEqual(result, 13) # 13 comes from the result below
- self.assertEqual(brids, self.db.buildsets.allBuildRequests(bsid))
- self.fired = True
- d.addCallback(fired)
-
- # check that the scheduler has subscribed to buildset changes, but
- # not fired yet
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertNotEqual(callbacks['buildset_completion'], None)
- self.assertFalse(self.fired)
-
- # pretend a non-matching buildset is complete
- callbacks['buildset_completion'](bsid+27, 3)
-
- # scheduler should not have reacted
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertNotEqual(callbacks['buildset_completion'], None)
- self.assertFalse(self.fired)
-
- # pretend the matching buildset is complete
- callbacks['buildset_completion'](bsid, 13)
-
- # scheduler should have reacted
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertEqual(callbacks['buildset_completion'], None)
- self.assertTrue(self.fired)
-
- def test_trigger_overlapping(self):
- sched = self.makeScheduler(codebases = {'cb':{'repository':'r'}})
-
- # no subscription should be in place yet
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertEqual(callbacks['buildset_completion'], None)
-
- # define sourcestamp
- ss = {'revision':'myrev1',
- 'branch':'br',
- 'project':'p',
- 'repository':'r',
- 'codebase':'cb' }
- # trigger the scheduler the first time
- d = sched.trigger({'cb':ss})
- bsid1 = self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- reason='Triggerable(n)',
- sourcestampsetid=100),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev1', sourcestampsetid=100)})
- d.addCallback(lambda (res, brids) : self.assertEqual(res, 11)
- and self.assertEqual(brids, self.db.buildsets.allBuildRequests(bsid1)))
-
- # define sourcestamp
- ss = {'revision':'myrev2',
- 'branch':'br',
- 'project':'p',
- 'repository':'r',
- 'codebase':'cb' }
- # and the second time
- d = sched.trigger({'cb':ss})
- bsid2 = self.db.buildsets.assertBuildset(bsid1+1, # assumes bsid's are sequential
- dict(external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- reason='Triggerable(n)', sourcestampsetid=101),
- {'cb':
- dict(branch='br', project='p', repository='r', codebase='cb',
- revision='myrev2', sourcestampsetid=101)})
- d.addCallback(lambda (res, brids) : self.assertEqual(res, 22)
- and self.assertEqual(brids, self.db.buildsets.allBuildRequests(bsid2)))
-
- # check that the scheduler has subscribed to buildset changes
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertNotEqual(callbacks['buildset_completion'], None)
-
- # let a few buildsets complete
- callbacks['buildset_completion'](bsid2+27, 3)
- callbacks['buildset_completion'](bsid2, 22)
- callbacks['buildset_completion'](bsid2+7, 3)
- callbacks['buildset_completion'](bsid1, 11)
-
- # both should have triggered with appropriate results, and the
- # subscription should be cancelled
- callbacks = self.master.getSubscriptionCallbacks()
- self.assertEqual(callbacks['buildset_completion'], None)
-
- def test_trigger_with_unknown_sourcestamp(self):
- # Test a scheduler with 2 repositories.
- # Trigger the scheduler with a sourcestamp that is unknown to the scheduler
- # Expected Result:
- # sourcestamp 1 for repository 1 based on configured sourcestamp
- # sourcestamp 2 for repository 2 based on configured sourcestamp
- sched = self.makeScheduler(
- codebases = {'cb':{'repository':'r', 'branch': 'branchX'},
- 'cb2':{'repository':'r2', 'branch': 'branchX'},})
-
- ss = {'repository': 'r3', 'codebase': 'cb3', 'revision': 'fixrev3',
- 'branch': 'default', 'project': 'p' }
- sched.trigger(sourcestamps = {'cb3': ss})
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- reason='Triggerable(n)',
- sourcestampsetid=100),
- {'cb':
- dict(branch='branchX', project='', repository='r', codebase='cb',
- revision=None, sourcestampsetid=100),
- 'cb2':
- dict(branch='branchX', project='', repository='r2', codebase='cb2',
- revision=None, sourcestampsetid=100),})
-
- def test_trigger_without_sourcestamps(self):
- # Test a scheduler with 2 repositories.
- # Trigger the scheduler without a sourcestamp
- # Expected Result:
- # sourcestamp 1 for repository 1 based on configured sourcestamp
- # sourcestamp 2 for repository 2 based on configured sourcestamp
- sched = self.makeScheduler(
- codebases = {'cb':{'repository':'r', 'branch': 'branchX'},
- 'cb2':{'repository':'r2', 'branch': 'branchX'},})
-
- sched.trigger(sourcestamps = None)
-
- self.db.buildsets.assertBuildset('?',
- dict(external_idstring=None,
- properties=[('scheduler', ('n', 'Scheduler'))],
- reason='Triggerable(n)',
- sourcestampsetid=100),
- {'cb':
- dict(branch='branchX', project='', repository='r', codebase='cb',
- revision=None, sourcestampsetid=100),
- 'cb2':
- dict(branch='branchX', project='', repository='r2', codebase='cb2',
- revision=None, sourcestampsetid=100),}) \ No newline at end of file
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_trysched.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_trysched.py
deleted file mode 100644
index 1aaa5b34..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_schedulers_trysched.py
+++ /dev/null
@@ -1,727 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import mock
-import os
-import shutil
-import cStringIO as StringIO
-import sys
-
-import twisted
-from twisted.internet import defer
-from twisted.trial import unittest
-from twisted.protocols import basic
-from buildbot.schedulers import trysched
-from buildbot.test.util import dirs
-from buildbot.test.util import scheduler
-from buildbot.util import json
-
-
-class TryBase(unittest.TestCase):
-
- def test_filterBuilderList_ok(self):
- sched = trysched.TryBase(
- name='tsched', builderNames=['a', 'b', 'c'], properties={})
- self.assertEqual(sched.filterBuilderList(['b', 'c']), ['b', 'c'])
-
- def test_filterBuilderList_bad(self):
- sched = trysched.TryBase(
- name='tsched', builderNames=['a', 'b'], properties={})
- self.assertEqual(sched.filterBuilderList(['b', 'c']), [])
-
- def test_filterBuilderList_empty(self):
- sched = trysched.TryBase(
- name='tsched', builderNames=['a', 'b'], properties={})
- self.assertEqual(sched.filterBuilderList([]), ['a', 'b'])
-
-
-class JobdirService(dirs.DirsMixin, unittest.TestCase):
-
- def setUp(self):
- self.jobdir = 'jobdir'
- self.newdir = os.path.join(self.jobdir, 'new')
- self.curdir = os.path.join(self.jobdir, 'cur')
- self.tmpdir = os.path.join(self.jobdir, 'tmp')
- self.setUpDirs(self.jobdir, self.newdir, self.curdir, self.tmpdir)
-
- def tearDown(self):
- self.tearDownDirs()
-
- def test_messageReceived(self):
- svc = trysched.JobdirService(self.jobdir)
-
- # creat some new data to process
- jobdata = os.path.join(self.newdir, 'jobdata')
- with open(jobdata, "w") as f:
- f.write('JOBDATA')
-
- # stub out svc.parent.handleJobFile and .jobdir
- def handleJobFile(filename, f):
- self.assertEqual(filename, 'jobdata')
- self.assertEqual(f.read(), 'JOBDATA')
- svc.parent = mock.Mock()
- svc.parent.handleJobFile = handleJobFile
- svc.parent.jobdir = self.jobdir
-
- # run it
- svc.messageReceived('jobdata')
-
-
-class Try_Jobdir(scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 23
-
- def setUp(self):
- self.setUpScheduler()
- self.jobdir = None
-
- def tearDown(self):
- self.tearDownScheduler()
- if self.jobdir:
- shutil.rmtree(self.jobdir)
-
- # tests
-
- def do_test_startService(self, jobdir, exp_jobdir):
- # set up jobdir
- self.jobdir = os.path.abspath('jobdir')
- if os.path.exists(self.jobdir):
- shutil.rmtree(self.jobdir)
- os.mkdir(self.jobdir)
-
- # build scheduler
- kwargs = dict(name="tsched", builderNames=['a'], jobdir=self.jobdir)
- sched = self.attachScheduler(
- trysched.Try_Jobdir(**kwargs), self.OBJECTID)
-
- # start it
- sched.startService()
-
- # check that it has set the basedir correctly
- self.assertEqual(sched.watcher.basedir, self.jobdir)
-
- return sched.stopService()
-
- def test_startService_reldir(self):
- return self.do_test_startService(
- 'jobdir',
- os.path.abspath('basedir/jobdir'))
-
- def test_startService_reldir_subdir(self):
- return self.do_test_startService(
- 'jobdir',
- os.path.abspath('basedir/jobdir/cur'))
-
- def test_startService_absdir(self):
- return self.do_test_startService(
- os.path.abspath('jobdir'),
- os.path.abspath('jobdir'))
-
- # parseJob
-
- def test_parseJob_empty(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['a'], jobdir='foo')
- self.assertRaises(
- trysched.BadJobfile, sched.parseJob, StringIO.StringIO(''))
-
- def test_parseJob_longer_than_netstring_MAXLENGTH(self):
- self.patch(basic.NetstringReceiver, 'MAX_LENGTH', 100)
- sched = trysched.Try_Jobdir(name='tsched', builderNames=['a'], jobdir='foo')
- jobstr = self.makeNetstring(
- '1', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'buildera', 'builderc'
- )
- jobstr += 'x' * 200
-
- test_temp_file = StringIO.StringIO(jobstr)
-
- self.assertRaises(trysched.BadJobfile,
- lambda : sched.parseJob(test_temp_file))
-
- def test_parseJob_invalid(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['a'], jobdir='foo')
- self.assertRaises(
- trysched.BadJobfile, sched.parseJob,
- StringIO.StringIO('this is not a netstring'))
-
- def test_parseJob_invalid_version(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['a'], jobdir='foo')
- self.assertRaises(
- trysched.BadJobfile, sched.parseJob, StringIO.StringIO('1:9,'))
-
- def makeNetstring(self, *strings):
- return ''.join(['%d:%s,' % (len(s), s) for s in strings])
-
- def test_parseJob_v1(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '1', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'buildera', 'builderc'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob, {
- 'baserev': '1234',
- 'branch': 'trunk',
- 'builderNames': ['buildera', 'builderc'],
- 'jobid': 'extid',
- 'patch_body': 'this is my diff, -- ++, etc.',
- 'patch_level': 1,
- 'project': '',
- 'who': '',
- 'comment': '',
- 'repository': '',
- 'properties': {},
- })
-
- def test_parseJob_v1_empty_branch_rev(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- # blank branch, rev are turned to None
- '1', 'extid', '', '', '1', 'this is my diff, -- ++, etc.',
- 'buildera', 'builderc'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['branch'], None)
- self.assertEqual(parsedjob['baserev'], None)
-
- def test_parseJob_v1_no_builders(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '1', 'extid', '', '', '1', 'this is my diff, -- ++, etc.'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['builderNames'], [])
-
- def test_parseJob_v1_no_properties(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '1', 'extid', '', '', '1', 'this is my diff, -- ++, etc.'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['properties'], {})
-
- def test_parseJob_v2(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '2', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj',
- 'buildera', 'builderc'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob, {
- 'baserev': '1234',
- 'branch': 'trunk',
- 'builderNames': ['buildera', 'builderc'],
- 'jobid': 'extid',
- 'patch_body': 'this is my diff, -- ++, etc.',
- 'patch_level': 1,
- 'project': 'proj',
- 'who': '',
- 'comment': '',
- 'repository': 'repo',
- 'properties': {},
- })
-
- def test_parseJob_v2_empty_branch_rev(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- # blank branch, rev are turned to None
- '2', 'extid', '', '', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj',
- 'buildera', 'builderc'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['branch'], None)
- self.assertEqual(parsedjob['baserev'], None)
-
- def test_parseJob_v2_no_builders(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '2', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj',
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['builderNames'], [])
-
- def test_parseJob_v2_no_properties(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '2', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj',
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['properties'], {})
-
- def test_parseJob_v3(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '3', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj', 'who',
- 'buildera', 'builderc'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob, {
- 'baserev': '1234',
- 'branch': 'trunk',
- 'builderNames': ['buildera', 'builderc'],
- 'jobid': 'extid',
- 'patch_body': 'this is my diff, -- ++, etc.',
- 'patch_level': 1,
- 'project': 'proj',
- 'who': 'who',
- 'comment': '',
- 'repository': 'repo',
- 'properties': {},
- })
-
- def test_parseJob_v3_empty_branch_rev(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- # blank branch, rev are turned to None
- '3', 'extid', '', '', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj', 'who',
- 'buildera', 'builderc'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['branch'], None)
- self.assertEqual(parsedjob['baserev'], None)
-
- def test_parseJob_v3_no_builders(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '3', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj', 'who'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['builderNames'], [])
-
- def test_parseJob_v3_no_properties(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '3', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj', 'who'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['properties'], {})
-
- def test_parseJob_v4(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '4', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj', 'who', 'comment',
- 'buildera', 'builderc'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob, {
- 'baserev': '1234',
- 'branch': 'trunk',
- 'builderNames': ['buildera', 'builderc'],
- 'jobid': 'extid',
- 'patch_body': 'this is my diff, -- ++, etc.',
- 'patch_level': 1,
- 'project': 'proj',
- 'who': 'who',
- 'comment': 'comment',
- 'repository': 'repo',
- 'properties': {},
- })
-
- def test_parseJob_v4_empty_branch_rev(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- # blank branch, rev are turned to None
- '4', 'extid', '', '', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj', 'who', 'comment',
- 'buildera', 'builderc'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['branch'], None)
- self.assertEqual(parsedjob['baserev'], None)
-
- def test_parseJob_v4_no_builders(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '4', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj', 'who', 'comment'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['builderNames'], [])
-
- def test_parseJob_v4_no_properties(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '4', 'extid', 'trunk', '1234', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj', 'who', 'comment'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['properties'], {})
-
- def test_parseJob_v5(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '5',
- json.dumps({
- 'jobid': 'extid', 'branch': 'trunk', 'baserev': '1234',
- 'patch_level': 1, 'patch_body': 'this is my diff, -- ++, etc.',
- 'repository': 'repo', 'project': 'proj', 'who': 'who',
- 'comment': 'comment', 'builderNames': ['buildera', 'builderc'],
- 'properties': {'foo': 'bar'},
- }))
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob, {
- 'baserev': '1234',
- 'branch': 'trunk',
- 'builderNames': ['buildera', 'builderc'],
- 'jobid': 'extid',
- 'patch_body': 'this is my diff, -- ++, etc.',
- 'patch_level': 1,
- 'project': 'proj',
- 'who': 'who',
- 'comment': 'comment',
- 'repository': 'repo',
- 'properties': {'foo': 'bar'},
- })
-
- def test_parseJob_v5_empty_branch_rev(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- # blank branch, rev are turned to None
- '4', 'extid', '', '', '1', 'this is my diff, -- ++, etc.',
- 'repo', 'proj', 'who', 'comment',
- 'buildera', 'builderc'
- )
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['branch'], None)
- self.assertEqual(parsedjob['baserev'], None)
-
- def test_parseJob_v5_no_builders(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '5',
- json.dumps({
- 'jobid': 'extid', 'branch': 'trunk', 'baserev': '1234',
- 'patch_level': '1', 'diff': 'this is my diff, -- ++, etc.',
- 'repository': 'repo', 'project': 'proj', 'who': 'who',
- 'comment': 'comment', 'builderNames': [],
- 'properties': {'foo': 'bar'},
- }))
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['builderNames'], [])
-
- def test_parseJob_v5_no_properties(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring(
- '5',
- json.dumps({
- 'jobid': 'extid', 'branch': 'trunk', 'baserev': '1234',
- 'patch_level': '1', 'diff': 'this is my diff, -- ++, etc.',
- 'repository': 'repo', 'project': 'proj', 'who': 'who',
- 'comment': 'comment', 'builderNames': ['buildera', 'builderb'],
- 'properties': {},
- }))
- parsedjob = sched.parseJob(StringIO.StringIO(jobstr))
- self.assertEqual(parsedjob['properties'], {})
-
- def test_parseJob_v5_invalid_json(self):
- sched = trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'], jobdir='foo')
- jobstr = self.makeNetstring('5', '{"comment": "com}')
- self.assertRaises(
- trysched.BadJobfile, sched.parseJob, StringIO.StringIO(jobstr))
-
- # handleJobFile
-
- def call_handleJobFile(self, parseJob):
- sched = self.attachScheduler(
- trysched.Try_Jobdir(
- name='tsched', builderNames=['buildera', 'builderb'],
- jobdir='foo'), self.OBJECTID)
- fakefile = mock.Mock()
-
- def parseJob_(f):
- assert f is fakefile
- return parseJob(f)
- sched.parseJob = parseJob_
- return sched.handleJobFile('fakefile', fakefile)
-
- def makeSampleParsedJob(self, **overrides):
- pj = dict(baserev='1234', branch='trunk',
- builderNames=['buildera', 'builderb'],
- jobid='extid', patch_body='this is my diff, -- ++, etc.',
- patch_level=1, project='proj', repository='repo', who='who',
- comment='comment', properties={})
- pj.update(overrides)
- return pj
-
- def test_handleJobFile(self):
- d = self.call_handleJobFile(lambda f: self.makeSampleParsedJob())
-
- def check(_):
- self.db.buildsets.assertBuildset('?',
- dict(reason="'try' job by user who",
- external_idstring='extid',
- properties=[('scheduler', ('tsched', 'Scheduler'))],
- sourcestampsetid=100),
- {'':
- dict(branch='trunk', repository='repo', codebase='',
- project='proj', revision='1234',
- patch_body='this is my diff, -- ++, etc.',
- patch_level=1, patch_subdir='',
- patch_author='who',
- patch_comment='comment',
- sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_handleJobFile_exception(self):
- def parseJob(f):
- raise trysched.BadJobfile
- d = self.call_handleJobFile(parseJob)
-
- def check(bsid):
- self.db.buildsets.assertBuildsets(0)
- self.assertEqual(
- 1, len(self.flushLoggedErrors(trysched.BadJobfile)))
- d.addCallback(check)
- return d
- if twisted.version.major <= 9 and sys.version_info[:2] >= (2, 7):
- test_handleJobFile_exception.skip = (
- "flushLoggedErrors does not work correctly on 9.0.0 "
- "and earlier with Python-2.7")
-
- def test_handleJobFile_bad_builders(self):
- d = self.call_handleJobFile(
- lambda f: self.makeSampleParsedJob(builderNames=['xxx']))
-
- def check(_):
- self.db.buildsets.assertBuildsets(0)
- d.addCallback(check)
- return d
-
- def test_handleJobFile_subset_builders(self):
- d = self.call_handleJobFile(
- lambda f: self.makeSampleParsedJob(builderNames=['buildera']))
-
- def check(_):
- self.db.buildsets.assertBuildset('?',
- dict(reason="'try' job by user who",
- external_idstring='extid',
- properties=[('scheduler', ('tsched', 'Scheduler'))],
- sourcestampsetid=100),
- {'':
- dict(branch='trunk', repository='repo', codebase='',
- project='proj', revision='1234',
- patch_body='this is my diff, -- ++, etc.',
- patch_level=1, patch_subdir='',
- patch_author='who',
- patch_comment='comment',
- sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_handleJobFile_with_try_properties(self):
- d = self.call_handleJobFile(
- lambda f: self.makeSampleParsedJob(properties={'foo': 'bar'}))
-
- def check(_):
- self.db.buildsets.assertBuildset('?',
- dict(reason="'try' job by user who",
- external_idstring='extid',
- properties=[
- ('foo', ('bar', 'try build')),
- ('scheduler', ('tsched', 'Scheduler')),
- ],
- sourcestampsetid=100),
- {'':
- dict(branch='trunk', repository='repo', codebase='',
- project='proj', revision='1234',
- patch_body='this is my diff, -- ++, etc.',
- patch_level=1, patch_subdir='',
- patch_author='who',
- patch_comment='comment',
- sourcestampsetid=100)
- })
- d.addCallback(check)
- return d
-
- def test_handleJobFile_with_invalid_try_properties(self):
- d = self.call_handleJobFile(
- lambda f: self.makeSampleParsedJob(properties=['foo', 'bar']))
- return self.assertFailure(d, AttributeError)
-
-
-class Try_Userpass_Perspective(scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 26
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- def makeScheduler(self, **kwargs):
- sched = self.attachScheduler(trysched.Try_Userpass(**kwargs),
- self.OBJECTID)
- # Try will return a remote version of master.status, so give it
- # something to return
- sched.master.status = mock.Mock()
- return sched
-
- def call_perspective_try(self, *args, **kwargs):
- sched = self.makeScheduler(name='tsched', builderNames=['a', 'b'],
- port='xxx', userpass=[('a', 'b')], properties=dict(frm='schd'))
- persp = trysched.Try_Userpass_Perspective(sched, 'a')
- return persp.perspective_try(*args, **kwargs)
-
- def test_perspective_try(self):
- d = self.call_perspective_try(
- 'default', 'abcdef', (1, '-- ++'), 'repo', 'proj', ['a'],
- properties={'pr': 'op'})
-
- def check(_):
- self.db.buildsets.assertBuildset('?',
- dict(reason="'try' job",
- external_idstring=None,
- properties=[
- ('frm', ('schd', 'Scheduler')),
- ('pr', ('op', 'try build')),
- ('scheduler', ('tsched', 'Scheduler')),
- ],
- sourcestampsetid=100,
- ),
- {'':
- dict(branch='default', repository='repo', codebase='',
- project='proj', revision='abcdef',
- sourcestampsetid=100,
- patch_body='-- ++', patch_level=1, patch_subdir='',
- patch_author="", patch_comment="")
- })
- d.addCallback(check)
- return d
-
- def test_perspective_try_who(self):
- d = self.call_perspective_try(
- 'default', 'abcdef', (1, '-- ++'), 'repo', 'proj', ['a'],
- who='who', comment='comment', properties={'pr': 'op'})
-
- def check(_):
- self.db.buildsets.assertBuildset('?',
- dict(reason="'try' job by user who (comment)",
- external_idstring=None,
- properties=[
- ('frm', ('schd', 'Scheduler')),
- ('pr', ('op', 'try build')),
- ('scheduler', ('tsched', 'Scheduler')),
- ],
- sourcestampsetid=100,
- ),
- {'':
- dict(branch='default', repository='repo', codebase='',
- project='proj', revision='abcdef',
- sourcestampsetid=100,
- patch_body='-- ++', patch_level=1, patch_subdir='',
- patch_author='who', patch_comment="comment")
- })
- d.addCallback(check)
- return d
-
- def test_perspective_try_bad_builders(self):
- d = self.call_perspective_try(
- 'default', 'abcdef', (1, '-- ++'), 'repo', 'proj', ['xxx'],
- properties={'pr': 'op'})
-
- def check(_):
- self.db.buildsets.assertBuildsets(0)
- d.addCallback(check)
- return d
-
- def test_getAvailableBuilderNames(self):
- sched = self.makeScheduler(name='tsched', builderNames=['a', 'b'],
- port='xxx', userpass=[('a', 'b')])
- persp = trysched.Try_Userpass_Perspective(sched, 'a')
- d = defer.maybeDeferred(
- lambda: persp.perspective_getAvailableBuilderNames())
-
- def check(buildernames):
- self.assertEqual(buildernames, ['a', 'b'])
- d.addCallback(check)
- return d
-
-
-class Try_Userpass(scheduler.SchedulerMixin, unittest.TestCase):
-
- OBJECTID = 25
-
- def setUp(self):
- self.setUpScheduler()
-
- def tearDown(self):
- self.tearDownScheduler()
-
- def makeScheduler(self, **kwargs):
- sched = self.attachScheduler(trysched.Try_Userpass(**kwargs),
- self.OBJECTID)
- return sched
-
- def test_service(self):
- sched = self.makeScheduler(name='tsched', builderNames=['a'],
- port='tcp:9999', userpass=[('fred', 'derf')])
- # patch out the pbmanager's 'register' command both to be sure
- # the registration is correct and to get a copy of the factory
- registration = mock.Mock()
- registration.unregister = lambda: defer.succeed(None)
- sched.master.pbmanager = mock.Mock()
-
- def register(portstr, user, passwd, factory):
- self.assertEqual([portstr, user, passwd],
- ['tcp:9999', 'fred', 'derf'])
- self.got_factory = factory
- return registration
- sched.master.pbmanager.register = register
- # start it
- sched.startService()
- # make a fake connection by invoking the factory, and check that we
- # get the correct perspective
- persp = self.got_factory(mock.Mock(), 'fred')
- self.failUnless(isinstance(persp, trysched.Try_Userpass_Perspective))
- return sched.stopService()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_base.py
deleted file mode 100644
index 7d7d22de..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_base.py
+++ /dev/null
@@ -1,268 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os
-import string
-import cStringIO
-import textwrap
-from twisted.trial import unittest
-from buildbot.scripts import base
-from buildbot.test.util import dirs, misc
-from twisted.python import usage, runtime
-
-class TestIBD(dirs.DirsMixin, misc.StdoutAssertionsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpDirs('test')
- self.stdout = cStringIO.StringIO()
- self.setUpStdoutAssertions()
-
- def test_isBuildmasterDir_no_dir(self):
- self.assertFalse(base.isBuildmasterDir(os.path.abspath('test/nosuch')))
- self.assertInStdout('error reading')
- self.assertInStdout('invalid buildmaster directory')
-
- def test_isBuildmasterDir_no_file(self):
- self.assertFalse(base.isBuildmasterDir(os.path.abspath('test')))
- self.assertInStdout('error reading')
- self.assertInStdout('invalid buildmaster directory')
-
- def test_isBuildmasterDir_no_Application(self):
- with open(os.path.join('test', 'buildbot.tac'), 'w') as f:
- f.write("foo\nx = Application('buildslave')\nbar")
- self.assertFalse(base.isBuildmasterDir(os.path.abspath('test')))
- self.assertInStdout('unexpected content')
- self.assertInStdout('invalid buildmaster directory')
-
- def test_isBuildmasterDir_matches(self):
- with open(os.path.join('test', 'buildbot.tac'), 'w') as f:
- f.write("foo\nx = Application('buildmaster')\nbar")
- self.assertTrue(base.isBuildmasterDir(os.path.abspath('test')))
- self.assertWasQuiet()
-
-class TestTacFallback(dirs.DirsMixin, unittest.TestCase):
- """
- Tests for L{base.getConfigFileFromTac}.
- """
-
- def setUp(self):
- """
- Create a base directory.
- """
- self.basedir = os.path.abspath('basedir')
- return self.setUpDirs('basedir')
-
- def _createBuildbotTac(self, contents=None):
- """
- Create a C{buildbot.tac} that points to a given C{configfile}
- and create that file.
-
- @param configfile: Config file to point at and create.
- @type configfile: L{str}
- """
- if contents is None:
- contents = '#dummy'
- tacfile = os.path.join(self.basedir, "buildbot.tac")
- with open(tacfile, "wt") as f:
- f.write(contents)
- return tacfile
-
-
- def test_getConfigFileFromTac(self):
- """
- When L{getConfigFileFromTac} is passed a C{basedir}
- containing a C{buildbot.tac}, it reads the location
- of the config file from there.
- """
- self._createBuildbotTac("configfile='other.cfg'")
- foundConfigFile = base.getConfigFileFromTac(
- basedir=self.basedir)
- self.assertEqual(foundConfigFile, "other.cfg")
-
- def test_getConfigFileFromTac_fallback(self):
- """
- When L{getConfigFileFromTac} is passed a C{basedir}
- which doesn't contain a C{buildbot.tac},
- it returns C{master.cfg}
- """
- foundConfigFile = base.getConfigFileFromTac(
- basedir=self.basedir)
- self.assertEqual(foundConfigFile, 'master.cfg')
-
-
- def test_getConfigFileFromTac_tacWithoutConfigFile(self):
- """
- When L{getConfigFileFromTac} is passed a C{basedir}
- containing a C{buildbot.tac}, but C{buildbot.tac} doesn't
- define C{configfile}, L{getConfigFileFromTac} returns C{master.cfg}
- """
- self._createBuildbotTac()
- foundConfigFile = base.getConfigFileFromTac(
- basedir=self.basedir)
- self.assertEqual(foundConfigFile, 'master.cfg')
-
-
- def test_getConfigFileFromTac_usingFile(self):
- """
- Wehn L{getConfigFileFromTac} is passed a C{basedir}
- containing a C{buildbot.tac} which references C{__file__},
- that reference points to C{buildbot.tac}.
- """
- self._createBuildbotTac(textwrap.dedent("""
- from twisted.python.util import sibpath
- configfile = sibpath(__file__, "relative.cfg")
- """))
- foundConfigFile = base.getConfigFileFromTac(basedir=self.basedir)
- self.assertEqual(foundConfigFile, os.path.join(self.basedir, "relative.cfg"))
-
-
-
-class TestSubcommandOptions(unittest.TestCase):
-
- def fakeOptionsFile(self, **kwargs):
- self.patch(base.SubcommandOptions, 'loadOptionsFile',
- lambda self : kwargs.copy())
-
- def parse(self, cls, *args):
- self.opts = cls()
- self.opts.parseOptions(args)
- return self.opts
-
- class Bare(base.SubcommandOptions):
- optFlags = [ [ 'foo', 'f', 'Foo!' ] ]
-
- def test_bare_subclass(self):
- self.fakeOptionsFile()
- opts = self.parse(self.Bare, '-f')
- self.assertTrue(opts['foo'])
-
- class ParamsAndOptions(base.SubcommandOptions):
- optParameters = [ [ 'volume', 'v', '5', 'How Loud?' ] ]
- buildbotOptions = [ [ 'volcfg', 'volume' ] ]
-
- def test_buildbotOptions(self):
- self.fakeOptionsFile()
- opts = self.parse(self.ParamsAndOptions)
- self.assertEqual(opts['volume'], '5')
-
- def test_buildbotOptions_options(self):
- self.fakeOptionsFile(volcfg='3')
- opts = self.parse(self.ParamsAndOptions)
- self.assertEqual(opts['volume'], '3')
-
- def test_buildbotOptions_override(self):
- self.fakeOptionsFile(volcfg='3')
- opts = self.parse(self.ParamsAndOptions, '--volume', '7')
- self.assertEqual(opts['volume'], '7')
-
- class RequiredOptions(base.SubcommandOptions):
- optParameters = [ [ 'volume', 'v', None, 'How Loud?' ] ]
- requiredOptions = [ 'volume' ]
-
- def test_requiredOptions(self):
- self.fakeOptionsFile()
- self.assertRaises(usage.UsageError,
- lambda : self.parse(self.RequiredOptions))
-
-class TestLoadOptionsFile(dirs.DirsMixin, misc.StdoutAssertionsMixin,
- unittest.TestCase):
-
- def setUp(self):
- self.setUpDirs('test', 'home')
- self.opts = base.SubcommandOptions()
- self.dir = os.path.abspath('test')
- self.home = os.path.abspath('home')
- self.setUpStdoutAssertions()
-
- def tearDown(self):
- self.tearDownDirs()
-
- def do_loadOptionsFile(self, _here, exp):
- # only patch these os.path functions briefly, to
- # avoid breaking other parts of the test system
- patches = []
-
- if runtime.platformType == 'win32':
- from win32com.shell import shell
- patches.append(self.patch(shell, 'SHGetFolderPath',
- lambda *args : self.home))
- else:
- def expanduser(p):
- return p.replace('~/', self.home + '/')
- patches.append(self.patch(os.path, 'expanduser', expanduser))
-
- old_dirname = os.path.dirname
- def dirname(p):
- # bottom out at self.dir, rather than /
- if p == self.dir:
- return p
- return old_dirname(p)
- patches.append(self.patch(os.path, 'dirname', dirname))
-
- try:
- self.assertEqual(self.opts.loadOptionsFile(_here=_here), exp)
- finally:
- for p in patches:
- p.restore()
-
- def writeOptionsFile(self, dir, content, bbdir='.buildbot'):
- os.makedirs(os.path.join(dir, bbdir))
- with open(os.path.join(dir, bbdir, 'options'), 'w') as f:
- f.write(content)
-
- def test_loadOptionsFile_subdirs_not_found(self):
- subdir = os.path.join(self.dir, 'a', 'b')
- os.makedirs(subdir)
- self.do_loadOptionsFile(_here=subdir, exp={})
-
- def test_loadOptionsFile_subdirs_at_root(self):
- subdir = os.path.join(self.dir, 'a', 'b')
- os.makedirs(subdir)
- self.writeOptionsFile(self.dir, 'abc="def"')
- self.writeOptionsFile(self.home, 'abc=123') # not seen
- self.do_loadOptionsFile(_here=subdir, exp={'abc':'def'})
-
- def test_loadOptionsFile_subdirs_at_tip(self):
- subdir = os.path.join(self.dir, 'a', 'b')
- os.makedirs(subdir)
- self.writeOptionsFile(os.path.join(self.dir, 'a', 'b'), 'abc="def"')
- self.writeOptionsFile(self.dir, 'abc=123') # not seen
- self.do_loadOptionsFile(_here=subdir, exp={'abc':'def'})
-
- def test_loadOptionsFile_subdirs_at_homedir(self):
- subdir = os.path.join(self.dir, 'a', 'b')
- os.makedirs(subdir)
- # on windows, the subdir of the home (well, appdata) dir
- # is 'buildbot', not '.buildbot'
- self.writeOptionsFile(self.home, 'abc=123',
- 'buildbot' if runtime.platformType == 'win32' else '.buildbot')
- self.do_loadOptionsFile(_here=subdir, exp={'abc':123})
-
- def test_loadOptionsFile_syntax_error(self):
- self.writeOptionsFile(self.dir, 'abc=abc')
- self.assertRaises(NameError, lambda :
- self.do_loadOptionsFile(_here=self.dir, exp={}))
- self.assertInStdout('error while reading')
-
- def test_loadOptionsFile_toomany(self):
- subdir = os.path.join(self.dir, *tuple(string.lowercase))
- os.makedirs(subdir)
- self.do_loadOptionsFile(_here=subdir, exp={})
- self.assertInStdout('infinite glories')
-
- # NOTE: testing the ownership check requires patching os.stat, which causes
- # other problems since it is so heavily used.
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_checkconfig.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_checkconfig.py
deleted file mode 100644
index c6bf3bde..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_checkconfig.py
+++ /dev/null
@@ -1,169 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import mock
-import re
-import sys
-import os
-import textwrap
-import cStringIO
-from twisted.trial import unittest
-from buildbot.test.util import dirs, compat
-from buildbot.scripts import base, checkconfig
-
-class TestConfigLoader(dirs.DirsMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpDirs('configdir')
-
- def tearDown(self):
- return self.tearDownDirs()
-
- # tests
-
- def do_test_load(self, config='', other_files={},
- stdout_re=None, stderr_re=None):
- configFile = os.path.join('configdir', 'master.cfg')
- with open(configFile, "w") as f:
- f.write(config)
- for filename, contents in other_files.iteritems():
- if type(filename) == type(()):
- fn = os.path.join('configdir', *filename)
- dn = os.path.dirname(fn)
- if not os.path.isdir(dn):
- os.makedirs(dn)
- else:
- fn = os.path.join('configdir', filename)
- with open(fn, "w") as f:
- f.write(contents)
-
- old_stdout, old_stderr = sys.stdout, sys.stderr
- stdout = sys.stdout = cStringIO.StringIO()
- stderr = sys.stderr = cStringIO.StringIO()
- try:
- checkconfig._loadConfig(
- basedir='configdir', configFile="master.cfg", quiet=False)
- finally:
- sys.stdout, sys.stderr = old_stdout, old_stderr
- if stdout_re:
- stdout = stdout.getvalue()
- self.failUnless(stdout_re.search(stdout), stdout)
- if stderr_re:
- stderr = stderr.getvalue()
- self.failUnless(stderr_re.search(stderr), stderr)
-
- def test_success(self):
- len_sys_path = len(sys.path)
- config = textwrap.dedent("""\
- c = BuildmasterConfig = {}
- c['multiMaster'] = True
- c['schedulers'] = []
- from buildbot.config import BuilderConfig
- from buildbot.process.factory import BuildFactory
- c['builders'] = [
- BuilderConfig('testbuilder', factory=BuildFactory(),
- slavename='sl'),
- ]
- from buildbot.buildslave import BuildSlave
- c['slaves'] = [
- BuildSlave('sl', 'pass'),
- ]
- c['slavePortnum'] = 9989
- """)
- self.do_test_load(config=config,
- stdout_re=re.compile('Config file is good!'))
-
- # (regression) check that sys.path hasn't changed
- self.assertEqual(len(sys.path), len_sys_path)
-
- @compat.usesFlushLoggedErrors
- def test_failure_ImportError(self):
- config = textwrap.dedent("""\
- import test_scripts_checkconfig_does_not_exist
- """)
- self.do_test_load(config=config,
- stderr_re=re.compile(
- 'No module named test_scripts_checkconfig_does_not_exist'))
- self.flushLoggedErrors()
-
- @compat.usesFlushLoggedErrors
- def test_failure_no_slaves(self):
- config = textwrap.dedent("""\
- BuildmasterConfig={}
- """)
- self.do_test_load(config=config,
- stderr_re=re.compile('no slaves'))
- self.flushLoggedErrors()
-
- def test_success_imports(self):
- config = textwrap.dedent("""\
- from othermodule import port
- c = BuildmasterConfig = {}
- c['schedulers'] = []
- c['builders'] = []
- c['slaves'] = []
- c['slavePortnum'] = port
- """)
- other_files = { 'othermodule.py' : 'port = 9989' }
- self.do_test_load(config=config, other_files=other_files)
-
- def test_success_import_package(self):
- config = textwrap.dedent("""\
- from otherpackage.othermodule import port
- c = BuildmasterConfig = {}
- c['schedulers'] = []
- c['builders'] = []
- c['slaves'] = []
- c['slavePortnum'] = port
- """)
- other_files = {
- ('otherpackage', '__init__.py') : '',
- ('otherpackage', 'othermodule.py') : 'port = 9989',
- }
- self.do_test_load(config=config, other_files=other_files)
-
-
-class TestCheckconfig(unittest.TestCase):
-
- def setUp(self):
- self.loadConfig = mock.Mock(spec=checkconfig._loadConfig, return_value=3)
- self.patch(checkconfig, '_loadConfig', self.loadConfig)
-
- def test_checkconfig_given_dir(self):
- self.assertEqual(checkconfig.checkconfig(dict(configFile='.')), 3)
- self.loadConfig.assert_called_with(basedir='.', configFile='master.cfg', quiet=None)
-
- def test_checkconfig_given_file(self):
- config = dict(configFile='master.cfg')
- self.assertEqual(checkconfig.checkconfig(config), 3)
- self.loadConfig.assert_called_with(basedir=os.getcwd(), configFile='master.cfg', quiet=None)
-
- def test_checkconfig_quiet(self):
- config = dict(configFile='master.cfg', quiet=True)
- self.assertEqual(checkconfig.checkconfig(config), 3)
- self.loadConfig.assert_called_with(basedir=os.getcwd(), configFile='master.cfg', quiet=True)
-
- def test_checkconfig_syntaxError_quiet(self):
- """
- When C{base.getConfigFileFromTac} raises L{SyntaxError},
- C{checkconfig.checkconfig} return an error.
- """
- mockGetConfig = mock.Mock(spec=base.getConfigFileFromTac,
- side_effect=SyntaxError)
- self.patch(checkconfig, 'getConfigFileFromTac', mockGetConfig)
- config = dict(configFile='.', quiet=True)
- self.assertEqual(checkconfig.checkconfig(config), 1)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_create_master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_create_master.py
deleted file mode 100644
index 081a2747..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_create_master.py
+++ /dev/null
@@ -1,214 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.scripts import create_master
-from buildbot.db import connector, model
-from buildbot.test.util import dirs, misc
-
-def mkconfig(**kwargs):
- config = dict(force=False, relocatable=False, config='master.cfg',
- db='sqlite:///state.sqlite', basedir=os.path.abspath('basedir'),
- quiet=False, **{'no-logrotate':False, 'log-size':'10000000',
- 'log-count':'10'})
- config.update(kwargs)
- return config
-
-class TestCreateMaster(misc.StdoutAssertionsMixin, unittest.TestCase):
-
- def setUp(self):
- # createMaster is decorated with @in_reactor, so strip that decoration
- # since the master is already running
- self.patch(create_master, 'createMaster',
- create_master.createMaster._orig)
- self.setUpStdoutAssertions()
-
- # tests
-
- def do_test_createMaster(self, config):
- # mock out everything that createMaster calls, then check that
- # they are called, in order
- functions = [ 'makeBasedir', 'makeTAC', 'makeSampleConfig',
- 'makePublicHtml', 'makeTemplatesDir', 'createDB' ]
- repls = {}
- calls = []
- for fn in functions:
- repl = repls[fn] = mock.Mock(name=fn)
- repl.side_effect = lambda config, fn=fn : calls.append(fn)
- self.patch(create_master, fn, repl)
- repls['createDB'].side_effect = (lambda config :
- calls.append(fn) or defer.succeed(None))
- d = create_master.createMaster(config)
- @d.addCallback
- def check(rc):
- self.assertEqual(rc, 0)
- self.assertEqual(calls, functions)
- for repl in repls.values():
- repl.assert_called_with(config)
- return d
-
- def test_createMaster_quiet(self):
- d = self.do_test_createMaster(mkconfig(quiet=True))
- @d.addCallback
- def check(_):
- self.assertWasQuiet()
- return d
-
- def test_createMaster_loud(self):
- d = self.do_test_createMaster(mkconfig(quiet=False))
- @d.addCallback
- def check(_):
- self.assertInStdout('buildmaster configured in')
- return d
-
-class TestCreateMasterFunctions(dirs.DirsMixin, misc.StdoutAssertionsMixin,
- unittest.TestCase):
-
- def setUp(self):
- self.setUpDirs('test')
- self.basedir = os.path.abspath(os.path.join('test', 'basedir'))
- self.setUpStdoutAssertions()
-
- def tearDown(self):
- self.tearDownDirs()
-
- def assertInTacFile(self, str):
- self.assertIn(str,
- open(os.path.join('test', 'buildbot.tac'), 'rt').read())
-
- def assertNotInTacFile(self, str):
- self.assertNotIn(str,
- open(os.path.join('test', 'buildbot.tac'), 'rt').read())
-
- def assertDBSetup(self, basedir=None, db_url='sqlite:///state.sqlite',
- verbose=True):
- # mock out the database setup
- self.db = mock.Mock()
- self.db.setup.side_effect = lambda *a, **k : defer.succeed(None)
- self.DBConnector = mock.Mock()
- self.DBConnector.return_value = self.db
- self.patch(connector, 'DBConnector', self.DBConnector)
-
- basedir = basedir or self.basedir
- self.assertEqual(
- dict(basedir=self.DBConnector.call_args[0][1],
- db_url=self.DBConnector.call_args[0][0].mkconfig.db['db_url'],
- verbose=self.db.setup.call_args[1]['verbose'],
- check_version=self.db.setup.call_args[1]['check_version'],
- ),
- dict(basedir=self.basedir,
- db_url=db_url,
- verbose=True,
- check_version=False))
-
- # tests
-
- def test_makeBasedir(self):
- self.assertFalse(os.path.exists(self.basedir))
- create_master.makeBasedir(mkconfig(basedir=self.basedir))
- self.assertTrue(os.path.exists(self.basedir))
- self.assertInStdout('mkdir %s' % (self.basedir,))
-
- def test_makeBasedir_quiet(self):
- self.assertFalse(os.path.exists(self.basedir))
- create_master.makeBasedir(mkconfig(basedir=self.basedir, quiet=True))
- self.assertTrue(os.path.exists(self.basedir))
- self.assertWasQuiet()
-
- def test_makeBasedir_existing(self):
- os.mkdir(self.basedir)
- create_master.makeBasedir(mkconfig(basedir=self.basedir))
- self.assertInStdout('updating existing installation')
-
- def test_makeTAC(self):
- create_master.makeTAC(mkconfig(basedir='test'))
- self.assertInTacFile("Application('buildmaster')")
- self.assertWasQuiet()
-
- def test_makeTAC_relocatable(self):
- create_master.makeTAC(mkconfig(basedir='test', relocatable=True))
- self.assertInTacFile("basedir = '.'") # repr() prefers ''
- self.assertWasQuiet()
-
- def test_makeTAC_no_logrotate(self):
- create_master.makeTAC(mkconfig(basedir='test', **{'no-logrotate':True}))
- self.assertNotInTacFile("import Log")
- self.assertWasQuiet()
-
- def test_makeTAC_existing_incorrect(self):
- with open(os.path.join('test', 'buildbot.tac'), 'wt') as f:
- f.write('WRONG')
- create_master.makeTAC(mkconfig(basedir='test'))
- self.assertInTacFile("WRONG")
- self.assertTrue(os.path.exists(
- os.path.join('test', 'buildbot.tac.new')))
- self.assertInStdout('not touching existing buildbot.tac')
-
- def test_makeTAC_existing_incorrect_quiet(self):
- with open(os.path.join('test', 'buildbot.tac'), 'wt') as f:
- f.write('WRONG')
- create_master.makeTAC(mkconfig(basedir='test', quiet=True))
- self.assertInTacFile("WRONG")
- self.assertWasQuiet()
-
- def test_makeTAC_existing_correct(self):
- create_master.makeTAC(mkconfig(basedir='test', quiet=True))
- create_master.makeTAC(mkconfig(basedir='test'))
- self.assertFalse(os.path.exists(
- os.path.join('test', 'buildbot.tac.new')))
- self.assertInStdout('and is correct')
-
- def test_makeSampleConfig(self):
- create_master.makeSampleConfig(mkconfig(basedir='test'))
- self.assertTrue(os.path.exists(
- os.path.join('test', 'master.cfg.sample')))
- self.assertInStdout('creating ')
-
- def test_makeSampleConfig_db(self):
- create_master.makeSampleConfig(mkconfig(basedir='test', db='XXYYZZ',
- quiet=True))
- with open(os.path.join('test', 'master.cfg.sample'), 'rt') as f:
- self.assertIn("XXYYZZ", f.read())
- self.assertWasQuiet()
-
- def test_makePublicHtml(self):
- create_master.makePublicHtml(mkconfig(basedir='test', quiet=True))
- self.assertTrue(os.path.exists(
- os.path.join('test', 'public_html', 'robots.txt')))
- self.assertWasQuiet()
-
- def test_makeTemplatesDir(self):
- create_master.makeTemplatesDir(mkconfig(basedir='test', quiet=True))
- self.assertTrue(os.path.exists(
- os.path.join('test', 'templates', 'README.txt')))
- self.assertWasQuiet()
-
- @defer.inlineCallbacks
- def test_createDB(self):
- setup = mock.Mock(side_effect=lambda **kwargs : defer.succeed(None))
- self.patch(connector.DBConnector, 'setup', setup)
- upgrade = mock.Mock(side_effect=lambda **kwargs : defer.succeed(None))
- self.patch(model.Model, 'upgrade', upgrade)
- yield create_master.createDB(
- mkconfig(basedir='test', quiet=True),
- _noMonkey=True)
- setup.asset_called_with(check_version=False, verbose=False)
- upgrade.assert_called()
- self.assertWasQuiet()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_restart.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_restart.py
deleted file mode 100644
index 656d2005..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_restart.py
+++ /dev/null
@@ -1,70 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os
-from twisted.trial import unittest
-from buildbot.scripts import restart, stop, start
-from buildbot.test.util import dirs, misc
-
-def mkconfig(**kwargs):
- config = dict(quiet=False, basedir=os.path.abspath('basedir'))
- config.update(kwargs)
- return config
-
-class TestStop(misc.StdoutAssertionsMixin, dirs.DirsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpDirs('basedir')
- with open(os.path.join('basedir', 'buildbot.tac'), 'wt') as f:
- f.write("Application('buildmaster')")
- self.setUpStdoutAssertions()
-
- def tearDown(self):
- self.tearDownDirs()
-
- # tests
-
- def test_restart_not_basedir(self):
- self.assertEqual(restart.restart(mkconfig(basedir='doesntexist')), 1)
- self.assertInStdout('invalid buildmaster directory')
-
- def test_restart_stop_fails(self):
- self.patch(stop, 'stop', lambda config, wait : 1)
- self.assertEqual(restart.restart(mkconfig()), 1)
-
- def test_restart_stop_succeeds_start_fails(self):
- self.patch(stop, 'stop', lambda config, wait : 0)
- self.patch(start, 'start', lambda config : 1)
- self.assertEqual(restart.restart(mkconfig()), 1)
-
- def test_restart_succeeds(self):
- self.patch(stop, 'stop', lambda config, wait : 0)
- self.patch(start, 'start', lambda config : 0)
- self.assertEqual(restart.restart(mkconfig()), 0)
- self.assertInStdout('now restarting')
-
- def test_restart_succeeds_quiet(self):
- self.patch(stop, 'stop', lambda config, wait : 0)
- self.patch(start, 'start', lambda config : 0)
- self.assertEqual(restart.restart(mkconfig(quiet=True)), 0)
- self.assertWasQuiet()
-
- def test_restart_clean(self):
- self.patch(stop, 'stop', lambda config, wait : 0)
- self.patch(start, 'start', lambda config : 0)
- self.assertEqual(restart.restart(mkconfig(quiet=True, clean=True)), 0)
- self.assertWasQuiet()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_runner.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_runner.py
deleted file mode 100644
index 0da2c7d0..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_runner.py
+++ /dev/null
@@ -1,971 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os
-import sys
-import getpass
-import mock
-import cStringIO
-from twisted.trial import unittest
-from twisted.python import usage, runtime, log
-from buildbot.scripts import base, runner
-from buildbot.test.util import misc
-
-class OptionsMixin(object):
-
- def setUpOptions(self):
- self.options_file = {}
- self.patch(base.SubcommandOptions, 'loadOptionsFile',
- lambda other_self : self.options_file)
-
- def assertOptions(self, opts, exp):
- got = dict([(k, opts[k]) for k in exp])
- if got != exp:
- msg = []
- for k in exp:
- if opts[k] != exp[k]:
- msg.append(" %s: expected %r, got %r" %
- (k, exp[k], opts[k]))
- self.fail("did not get expected options\n" + ("\n".join(msg)))
-
-
-class TestUpgradeMasterOptions(OptionsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpOptions()
-
- def parse(self, *args):
- self.opts = runner.UpgradeMasterOptions()
- self.opts.parseOptions(args)
- return self.opts
-
- def test_synopsis(self):
- opts = runner.UpgradeMasterOptions()
- self.assertIn('buildbot upgrade-master', opts.getSynopsis())
-
- def test_defaults(self):
- opts = self.parse()
- exp = dict(quiet=False, replace=False)
- self.assertOptions(opts, exp)
-
- def test_short(self):
- opts = self.parse('-q', '-r')
- exp = dict(quiet=True, replace=True)
- self.assertOptions(opts, exp)
-
- def test_long(self):
- opts = self.parse('--quiet', '--replace')
- exp = dict(quiet=True, replace=True)
- self.assertOptions(opts, exp)
-
-
-class TestCreateMasterOptions(OptionsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpOptions()
-
- def parse(self, *args):
- self.opts = runner.CreateMasterOptions()
- self.opts.parseOptions(args)
- return self.opts
-
- def defaults_and(self, **kwargs):
- defaults = dict(force=False, relocatable=False, config='master.cfg',
- db='sqlite:///state.sqlite', basedir=os.getcwd(), quiet=False,
- **{'no-logrotate':False, 'log-size':'10000000',
- 'log-count':'10'})
- unk_keys = set(kwargs.keys()) - set(defaults.keys())
- assert not unk_keys, "invalid keys %s" % (unk_keys,)
- opts = defaults.copy()
- opts.update(kwargs)
- return opts
-
- def test_synopsis(self):
- opts = runner.CreateMasterOptions()
- self.assertIn('buildbot create-master', opts.getSynopsis())
-
- def test_defaults(self):
- opts = self.parse()
- exp = self.defaults_and()
- self.assertOptions(opts, exp)
-
- def test_db_quiet(self):
- opts = self.parse('-q')
- exp = self.defaults_and(quiet=True)
- self.assertOptions(opts, exp)
-
- def test_db_quiet_long(self):
- opts = self.parse('--quiet')
- exp = self.defaults_and(quiet=True)
- self.assertOptions(opts, exp)
-
- def test_force(self):
- opts = self.parse('-f')
- exp = self.defaults_and(force=True)
- self.assertOptions(opts, exp)
-
- def test_force_long(self):
- opts = self.parse('--force')
- exp = self.defaults_and(force=True)
- self.assertOptions(opts, exp)
-
- def test_relocatable(self):
- opts = self.parse('-r')
- exp = self.defaults_and(relocatable=True)
- self.assertOptions(opts, exp)
-
- def test_relocatable_long(self):
- opts = self.parse('--relocatable')
- exp = self.defaults_and(relocatable=True)
- self.assertOptions(opts, exp)
-
- def test_no_logrotate(self):
- opts = self.parse('-n')
- exp = self.defaults_and(**{'no-logrotate' : True})
- self.assertOptions(opts, exp)
-
- def test_no_logrotate_long(self):
- opts = self.parse('--no-logrotate')
- exp = self.defaults_and(**{'no-logrotate' : True})
- self.assertOptions(opts, exp)
-
- def test_config(self):
- opts = self.parse('-cxyz')
- exp = self.defaults_and(config='xyz')
- self.assertOptions(opts, exp)
-
- def test_config_long(self):
- opts = self.parse('--config=xyz')
- exp = self.defaults_and(config='xyz')
- self.assertOptions(opts, exp)
-
- def test_log_size(self):
- opts = self.parse('-s124')
- exp = self.defaults_and(**{'log-size':'124'})
- self.assertOptions(opts, exp)
-
- def test_log_size_long(self):
- opts = self.parse('--log-size=124')
- exp = self.defaults_and(**{'log-size':'124'})
- self.assertOptions(opts, exp)
-
- def test_log_size_noninteger(self):
- self.assertRaises(usage.UsageError,
- lambda :self.parse('--log-size=1M'))
-
- def test_log_count(self):
- opts = self.parse('-l124')
- exp = self.defaults_and(**{'log-count':'124'})
- self.assertOptions(opts, exp)
-
- def test_log_count_long(self):
- opts = self.parse('--log-count=124')
- exp = self.defaults_and(**{'log-count':'124'})
- self.assertOptions(opts, exp)
-
- def test_log_count_noninteger(self):
- self.assertRaises(usage.UsageError,
- lambda :self.parse('--log-count=M'))
-
- def test_db_long(self):
- opts = self.parse('--db=foo://bar')
- exp = self.defaults_and(db='foo://bar')
- self.assertOptions(opts, exp)
-
- def test_db_basedir(self):
- path = r'c:\foo\bar' if runtime.platformType == "win32" else '/foo/bar'
- opts = self.parse('-f', path)
- exp = self.defaults_and(force=True, basedir=path)
- self.assertOptions(opts, exp)
-
-
-class BaseTestSimpleOptions(OptionsMixin):
- # tests for options with just --quiet and a usage message
-
- commandName = None
- optionsClass = None
-
- def setUp(self):
- self.setUpOptions()
-
- def parse(self, *args):
- self.opts = self.optionsClass()
- self.opts.parseOptions(args)
- return self.opts
-
- def test_synopsis(self):
- opts = self.optionsClass()
- self.assertIn('buildbot %s' % self.commandName, opts.getSynopsis())
-
- def test_defaults(self):
- opts = self.parse()
- exp = dict(quiet=False)
- self.assertOptions(opts, exp)
-
- def test_quiet(self):
- opts = self.parse('--quiet')
- exp = dict(quiet=True)
- self.assertOptions(opts, exp)
-
-
-class TestStopOptions(BaseTestSimpleOptions, unittest.TestCase):
- commandName = 'stop'
- optionsClass = runner.StopOptions
-
-
-class TestResetartOptions(BaseTestSimpleOptions, unittest.TestCase):
- commandName = 'restart'
- optionsClass = runner.RestartOptions
-
- def test_nodaemon(self):
- opts = self.parse('--nodaemon')
- exp = dict(nodaemon=True)
- self.assertOptions(opts, exp)
-
-
-class TestStartOptions(BaseTestSimpleOptions, unittest.TestCase):
- commandName = 'start'
- optionsClass = runner.StartOptions
-
- def test_nodaemon(self):
- opts = self.parse('--nodaemon')
- exp = dict(nodaemon=True)
- self.assertOptions(opts, exp)
-
-
-class TestReconfigOptions(BaseTestSimpleOptions, unittest.TestCase):
- commandName = 'reconfig'
- optionsClass = runner.ReconfigOptions
-
-
-class TestDebugClientOptions(OptionsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpOptions()
-
- def parse(self, *args):
- self.opts = runner.DebugClientOptions()
- self.opts.parseOptions(args)
- return self.opts
-
- def test_synopsis(self):
- opts = runner.DebugClientOptions()
- self.assertIn('buildbot debugclient', opts.getSynopsis())
-
- def test_defaults(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse())
-
- def test_args_missing_passwd(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse('-m', 'mm'))
-
- def test_options_long(self):
- opts = self.parse('--master', 'mm:9989', '--passwd', 'pp')
- exp = dict(master='mm:9989', passwd='pp')
- self.assertOptions(opts, exp)
-
- def test_positional_master_passwd(self):
- opts = self.parse('foo:9989', 'pass')
- exp = dict(master='foo:9989', passwd='pass')
- self.assertOptions(opts, exp)
-
- def test_positional_master(self):
- opts = self.parse('-p', 'pass', 'foo:9989')
- exp = dict(master='foo:9989', passwd='pass')
- self.assertOptions(opts, exp)
-
- def test_args_master_passwd(self):
- opts = self.parse('foo:9989', 'pass')
- exp = dict(master='foo:9989', passwd='pass')
- self.assertOptions(opts, exp)
-
- def test_missing_both(self):
- self.assertRaises(usage.UsageError,
- lambda :self.parse())
-
- def test_missing_passwd(self):
- self.assertRaises(usage.UsageError,
- lambda :self.parse('master'))
-
- def test_missing_master(self):
- self.assertRaises(usage.UsageError,
- lambda :self.parse('-p', 'pass'))
-
- def test_invalid_master(self):
- self.assertRaises(usage.UsageError, self.parse,
- "-m", "foo", "-p", "pass")
-
- def test_options_extra_positional(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse('mm', 'pp', '??'))
-
- def test_options_master(self):
- self.options_file['master'] = 'opt:9989'
- opts = self.parse('-p', 'pass')
- exp = dict(master='opt:9989', passwd='pass')
- self.assertOptions(opts, exp)
-
- def test_options_debugMaster(self):
- self.options_file['master'] = 'not seen'
- self.options_file['debugMaster'] = 'opt:9989'
- opts = self.parse('-p', 'pass')
- exp = dict(master='opt:9989', passwd='pass')
- self.assertOptions(opts, exp)
-
-
-class TestBaseStatusClientOptions(OptionsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpOptions()
-
- def parse(self, *args):
- self.opts = runner.BaseStatusClientOptions()
- self.opts.parseOptions(args)
- return self.opts
-
- def test_defaults(self):
- opts = self.parse('--master', 'm:20')
- exp = dict(master='m:20', username='statusClient', passwd='clientpw')
- self.assertOptions(opts, exp)
-
- def test_short(self):
- opts = self.parse('-m', 'm:20', '-u', 'u', '-p', 'p')
- exp = dict(master='m:20', username='u', passwd='p')
- self.assertOptions(opts, exp)
-
- def test_long(self):
- opts = self.parse('--master', 'm:20',
- '--username', 'u', '--passwd', 'p')
- exp = dict(master='m:20', username='u', passwd='p')
- self.assertOptions(opts, exp)
-
- def test_positional_master(self):
- opts = self.parse('--username', 'u', '--passwd', 'p', 'm:20')
- exp = dict(master='m:20', username='u', passwd='p')
- self.assertOptions(opts, exp)
-
- def test_positional_extra(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse('--username', 'u', '--passwd', 'p', 'm', '2'))
-
- def test_missing_master(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse('--username', 'u', '--passwd', 'p'))
-
- def test_invalid_master(self):
- self.assertRaises(usage.UsageError, self.parse, "-m foo")
-
- def test_options_masterstatus(self):
- self.options_file['master'] = 'not_seen:2'
- self.options_file['masterstatus'] = 'opt:3'
- opts = self.parse('-p', 'pass', '-u', 'user')
- exp = dict(master='opt:3', username='user', passwd='pass')
- self.assertOptions(opts, exp)
-
-
-class TestStatusLogOptions(unittest.TestCase):
-
- def test_synopsis(self):
- opts = runner.StatusLogOptions()
- self.assertIn('buildbot statuslog', opts.getSynopsis())
-
-
-class TestStatusGuiOptions(unittest.TestCase):
-
- def test_synopsis(self):
- opts = runner.StatusGuiOptions()
- self.assertIn('buildbot statusgui', opts.getSynopsis())
-
-
-class TestTryOptions(OptionsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpOptions()
-
- def parse(self, *args):
- self.opts = runner.TryOptions()
- self.opts.parseOptions(args)
- return self.opts
-
- def defaults_and(self, **kwargs):
- defaults = dict(connect=None, host=None, jobdir=None, username=None,
- master=None, passwd=None, who=None, comment=None, diff=None,
- patchlevel=0, baserev=None, vc=None, branch=None,
- repository=None, topfile=None, topdir=None, wait=False,
- dryrun=False, quiet=False, builders=[], properties={},
- buildbotbin='buildbot')
- # dashes make python syntax hard..
- defaults['get-builder-names'] = False
- if 'get_builder_names' in kwargs:
- kwargs['get-builder-names'] = kwargs['get_builder_names']
- del kwargs['get_builder_names']
- assert set(kwargs.keys()) <= set(defaults.keys()), "invalid keys"
- opts = defaults.copy()
- opts.update(kwargs)
- return opts
-
- def test_synopsis(self):
- opts = runner.TryOptions()
- self.assertIn('buildbot try', opts.getSynopsis())
-
- def test_defaults(self):
- opts = self.parse()
- exp = self.defaults_and()
- self.assertOptions(opts, exp)
-
- def test_properties(self):
- opts = self.parse('--properties=a=b')
- exp = self.defaults_and(properties=dict(a='b'))
- self.assertOptions(opts, exp)
-
- def test_properties_multiple_opts(self):
- opts = self.parse('--properties=X=1', '--properties=Y=2')
- exp = self.defaults_and(properties=dict(X='1', Y='2'))
- self.assertOptions(opts, exp)
-
- def test_properties_equals(self):
- opts = self.parse('--properties=X=2+2=4')
- exp = self.defaults_and(properties=dict(X='2+2=4'))
- self.assertOptions(opts, exp)
-
- def test_properties_commas(self):
- opts = self.parse('--properties=a=b,c=d')
- exp = self.defaults_and(properties=dict(a='b', c='d'))
- self.assertOptions(opts, exp)
-
- def test_property(self):
- opts = self.parse('--property=a=b')
- exp = self.defaults_and(properties=dict(a='b'))
- self.assertOptions(opts, exp)
-
- def test_property_multiple_opts(self):
- opts = self.parse('--property=X=1', '--property=Y=2')
- exp = self.defaults_and(properties=dict(X='1', Y='2'))
- self.assertOptions(opts, exp)
-
- def test_property_equals(self):
- opts = self.parse('--property=X=2+2=4')
- exp = self.defaults_and(properties=dict(X='2+2=4'))
- self.assertOptions(opts, exp)
-
- def test_property_commas(self):
- opts = self.parse('--property=a=b,c=d')
- exp = self.defaults_and(properties=dict(a='b,c=d'))
- self.assertOptions(opts, exp)
-
- def test_property_and_properties(self):
- opts = self.parse('--property=X=1', '--properties=Y=2')
- exp = self.defaults_and(properties=dict(X='1', Y='2'))
- self.assertOptions(opts, exp)
-
- def test_properties_builders_multiple(self):
- opts = self.parse('--builder=aa', '--builder=bb')
- exp = self.defaults_and(builders=['aa', 'bb'])
- self.assertOptions(opts, exp)
-
- def test_options_short(self):
- opts = self.parse(
- *'-n -q -c pb -u me -m mr:7 -w you -C comm -p 2 -b bb'.split())
- exp = self.defaults_and(dryrun=True, quiet=True, connect='pb',
- username='me', master='mr:7', who='you', comment='comm',
- patchlevel=2, builders=['bb'])
- self.assertOptions(opts, exp)
-
- def test_options_long(self):
- opts = self.parse(
- *"""--wait --dryrun --get-builder-names --quiet --connect=pb
- --host=h --jobdir=j --username=u --master=m:1234 --passwd=p
- --who=w --comment=comm --diff=d --patchlevel=7 --baserev=br
- --vc=cvs --branch=br --repository=rep --builder=bl
- --properties=a=b --topfile=Makefile --topdir=.
- --buildbotbin=.virtualenvs/buildbot/bin/buildbot""".split())
- exp = self.defaults_and(wait=True, dryrun=True, get_builder_names=True,
- quiet=True, connect='pb', host='h', jobdir='j', username='u',
- master='m:1234', passwd='p', who='w', comment='comm', diff='d',
- patchlevel=7, baserev='br', vc='cvs', branch='br',
- repository='rep', builders=['bl'], properties=dict(a='b'),
- topfile='Makefile', topdir='.',
- buildbotbin='.virtualenvs/buildbot/bin/buildbot')
- self.assertOptions(opts, exp)
-
- def test_patchlevel_inval(self):
- self.assertRaises(ValueError, lambda:
- self.parse('-p', 'a'))
-
- def test_config_builders(self):
- self.options_file['try_builders'] = ['a', 'b']
- opts = self.parse()
- self.assertOptions(opts, dict(builders=['a', 'b']))
-
- def test_config_builders_override(self):
- self.options_file['try_builders'] = ['a', 'b']
- opts = self.parse('-b', 'd') # overrides a, b
- self.assertOptions(opts, dict(builders=['d']))
-
- def test_config_old_names(self):
- self.options_file['try_masterstatus'] = 'ms'
- self.options_file['try_dir'] = 'td'
- self.options_file['try_password'] = 'pw'
- opts = self.parse()
- self.assertOptions(opts, dict(master='ms', jobdir='td', passwd='pw'))
-
- def test_config_masterstatus(self):
- self.options_file['masterstatus'] = 'ms'
- opts = self.parse()
- self.assertOptions(opts, dict(master='ms'))
-
- def test_config_masterstatus_override(self):
- self.options_file['masterstatus'] = 'ms'
- opts = self.parse('-m', 'mm')
- self.assertOptions(opts, dict(master='mm'))
-
- def test_config_options(self):
- self.options_file.update(dict(try_connect='pb', try_vc='cvs',
- try_branch='br', try_repository='rep', try_topdir='.',
- try_topfile='Makefile', try_host='h', try_username='u',
- try_jobdir='j', try_password='p', try_master='m:8', try_who='w',
- try_comment='comm', try_quiet='y', try_wait='y',
- try_buildbotbin='.virtualenvs/buildbot/bin/buildbot'))
- opts = self.parse()
- exp = self.defaults_and(wait=True, quiet=True, connect='pb', host='h',
- jobdir='j', username='u', master='m:8', passwd='p', who='w',
- comment='comm', vc='cvs', branch='br', repository='rep',
- topfile='Makefile', topdir='.',
- buildbotbin='.virtualenvs/buildbot/bin/buildbot')
- self.assertOptions(opts, exp)
-
- def test_pb_withNoMaster(self):
- """
- When 'builbot try' is asked to connect via pb, but no master is
- specified, a usage error is raised.
- """
- self.assertRaises(usage.UsageError, self.parse, '--connect=pb')
-
- def test_pb_withInvalidMaster(self):
- """
- When 'buildbot try' is asked to conncect via pb, but an invalid
- master is specified, a usage error is raised.
- """
- self.assertRaises(usage.UsageError, self.parse,
- '--connect=pb', '--master=foo')
-
-class TestSendChangeOptions(OptionsMixin, unittest.TestCase):
-
- master_and_who = ['-m', 'm:1', '-W', 'w']
-
- def setUp(self):
- self.setUpOptions()
- self.getpass_response = 'typed-password'
- self.patch(getpass, 'getpass', lambda prompt : self.getpass_response)
-
- def parse(self, *args):
- self.opts = runner.SendChangeOptions()
- self.opts.parseOptions(args)
- return self.opts
-
- def test_synopsis(self):
- opts = runner.SendChangeOptions()
- self.assertIn('buildbot sendchange', opts.getSynopsis())
-
- def test_defaults(self):
- opts = self.parse('-m', 'm:1', '-W', 'me')
- exp = dict(master='m:1', auth=('change', 'changepw'), who='me',
- vc=None, repository='', project='', branch=None, category=None,
- revision=None, revision_file=None, property=None,
- comments='', logfile=None, when=None, revlink='',
- encoding='utf8', files=())
- self.assertOptions(opts, exp)
-
- def test_files(self):
- opts = self.parse(*self.master_and_who + ['a', 'b', 'c'])
- self.assertEqual(opts['files'], ('a', 'b', 'c'))
-
- def test_properties(self):
- opts = self.parse('--property', 'x:y', '--property', 'a:b',
- *self.master_and_who)
- self.assertEqual(opts['properties'], dict(x="y", a="b"))
-
- def test_properties_with_colon(self):
- opts = self.parse('--property', 'x:http://foo', *self.master_and_who)
- self.assertEquals(opts['properties'], dict(x='http://foo'))
-
- def test_config_file(self):
- self.options_file['master'] = 'MMM:123'
- self.options_file['who'] = 'WWW'
- self.options_file['branch'] = 'BBB'
- self.options_file['category'] = 'CCC'
- self.options_file['vc'] = 'svn'
- opts = self.parse()
- exp = dict(master='MMM:123', who='WWW',
- branch='BBB', category='CCC', vc='svn')
- self.assertOptions(opts, exp)
-
- def test_short_args(self):
- opts = self.parse(*('-m m:1 -a a:b -W W -R r -P p -b b -s git ' +
- '-C c -r r -p pn:pv -c c -F f -w 123 -l l -e e').split())
- exp = dict(master='m:1', auth=('a','b'), who='W', repository='r',
- project='p', branch='b', category='c', revision='r', vc='git',
- properties=dict(pn='pv'), comments='c', logfile='f',
- when=123.0, revlink='l', encoding='e')
- self.assertOptions(opts, exp)
-
- def test_long_args(self):
- opts = self.parse(*('--master m:1 --auth a:b --who w --repository r ' +
- '--project p --branch b --category c --revision r --vc git ' +
- '--property pn:pv --comments c --logfile f ' +
- '--when 123 --revlink l --encoding e').split())
- exp = dict(master='m:1', auth=('a', 'b'), who='w', repository='r',
- project='p', branch='b', category='c', revision='r', vc='git',
- properties=dict(pn='pv'), comments='c', logfile='f',
- when=123.0, revlink='l', encoding='e')
- self.assertOptions(opts, exp)
-
- def test_revision_file(self):
- with open('revfile', 'wt') as f:
- f.write('my-rev')
- self.addCleanup(lambda : os.unlink('revfile'))
- opts = self.parse('--revision_file', 'revfile', *self.master_and_who)
- self.assertOptions(opts, dict(revision='my-rev'))
-
- def test_invalid_when(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse('--when=foo', *self.master_and_who))
-
- def test_comments_overrides_logfile(self):
- opts = self.parse('--logfile', 'logs', '--comments', 'foo',
- *self.master_and_who)
- self.assertOptions(opts, dict(comments='foo'))
-
- def test_logfile(self):
- with open('comments', 'wt') as f:
- f.write('hi')
- self.addCleanup(lambda : os.unlink('comments'))
- opts = self.parse('--logfile', 'comments', *self.master_and_who)
- self.assertOptions(opts, dict(comments='hi'))
-
- def test_logfile_stdin(self):
- stdin = mock.Mock()
- stdin.read = lambda : 'hi'
- self.patch(sys, 'stdin', stdin)
- opts = self.parse('--logfile', '-', *self.master_and_who)
- self.assertOptions(opts, dict(comments='hi'))
-
- def test_auth_getpass(self):
- opts = self.parse('--auth=dustin', *self.master_and_who)
- self.assertOptions(opts, dict(auth=('dustin', 'typed-password')))
-
- def test_invalid_vcs(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse('--vc=foo', *self.master_and_who))
-
- def test_invalid_master(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- "--who=test", "-m foo")
-
-
-class TestTryServerOptions(OptionsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpOptions()
-
- def parse(self, *args):
- self.opts = runner.TryServerOptions()
- self.opts.parseOptions(args)
- return self.opts
-
- def test_synopsis(self):
- opts = runner.TryServerOptions()
- self.assertIn('buildbot tryserver', opts.getSynopsis())
-
- def test_defaults(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse())
-
- def test_with_jobdir(self):
- opts = self.parse('--jobdir', 'xyz')
- exp = dict(jobdir='xyz')
- self.assertOptions(opts, exp)
-
-
-class TestCheckConfigOptions(OptionsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpOptions()
-
- def parse(self, *args):
- self.opts = runner.CheckConfigOptions()
- self.opts.parseOptions(args)
- return self.opts
-
- def test_synopsis(self):
- opts = runner.CheckConfigOptions()
- self.assertIn('buildbot checkconfig', opts.getSynopsis())
-
- def test_defaults(self):
- opts = self.parse()
- exp = dict(quiet=False, configFile='master.cfg')
- self.assertOptions(opts, exp)
-
- def test_configfile(self):
- opts = self.parse('foo.cfg')
- exp = dict(quiet=False, configFile='foo.cfg')
- self.assertOptions(opts, exp)
-
- def test_quiet(self):
- opts = self.parse('-q')
- exp = dict(quiet=True, configFile='master.cfg')
- self.assertOptions(opts, exp)
-
-
-class TestUserOptions(OptionsMixin, unittest.TestCase):
-
- # mandatory arguments
- extra_args = [ '--master', 'a:1',
- '--username', 'u', '--passwd', 'p' ]
-
- def setUp(self):
- self.setUpOptions()
-
- def parse(self, *args):
- self.opts = runner.UserOptions()
- self.opts.parseOptions(args)
- return self.opts
-
- def test_defaults(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse())
-
- def test_synopsis(self):
- opts = runner.UserOptions()
- self.assertIn('buildbot user', opts.getSynopsis())
-
- def test_master(self):
- opts = self.parse("--master", "abcd:1234",
- '--op=get', '--ids=x', '--username=u', '--passwd=p')
- self.assertOptions(opts, dict(master="abcd:1234"))
-
- def test_ids(self):
- opts = self.parse("--ids", "id1,id2,id3",
- '--op', 'get', *self.extra_args)
- self.assertEqual(opts['ids'], ['id1', 'id2', 'id3'])
-
- def test_info(self):
- opts = self.parse("--info", "git=Tyler Durden <tyler@mayhem.net>",
- '--op', 'add', *self.extra_args)
- self.assertEqual(opts['info'],
- [dict(git='Tyler Durden <tyler@mayhem.net>')])
-
- def test_info_only_id(self):
- opts = self.parse("--info", "tdurden",
- '--op', 'update', *self.extra_args)
- self.assertEqual(opts['info'], [dict(identifier='tdurden')])
-
- def test_info_with_id(self):
- opts = self.parse("--info", "tdurden:svn=marla",
- '--op', 'update', *self.extra_args)
- self.assertEqual(opts['info'], [dict(identifier='tdurden', svn='marla')])
-
- def test_info_multiple(self):
- opts = self.parse("--info", "git=Tyler Durden <tyler@mayhem.net>",
- "--info", "git=Narrator <narrator@mayhem.net>",
- '--op', 'add', *self.extra_args)
- self.assertEqual(opts['info'],
- [dict(git='Tyler Durden <tyler@mayhem.net>'),
- dict(git='Narrator <narrator@mayhem.net>')])
-
- def test_config_user_params(self):
- self.options_file['user_master'] = 'mm:99'
- self.options_file['user_username'] = 'un'
- self.options_file['user_passwd'] = 'pw'
- opts = self.parse('--op', 'get', '--ids', 'x')
- self.assertOptions(opts, dict(master='mm:99', username='un', passwd='pw'))
-
- def test_config_master(self):
- self.options_file['master'] = 'mm:99'
- opts = self.parse('--op', 'get', '--ids', 'x',
- '--username=u', '--passwd=p')
- self.assertOptions(opts, dict(master='mm:99'))
-
- def test_config_master_override(self):
- self.options_file['master'] = 'not seen'
- self.options_file['user_master'] = 'mm:99'
- opts = self.parse('--op', 'get', '--ids', 'x',
- '--username=u', '--passwd=p')
- self.assertOptions(opts, dict(master='mm:99'))
-
- def test_invalid_info(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse("--info", "foo=bar",
- '--op', 'add', *self.extra_args))
-
- def test_no_master(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse('-op=foo'))
-
- def test_invalid_master(self):
- self.assertRaises(usage.UsageError, self.parse,'-m', 'foo')
-
- def test_no_operation(self):
- self.assertRaises(usage.UsageError, self.parse, '-m', 'a:1')
-
- def test_bad_operation(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '-m', 'a:1', '--op=mayhem')
-
- def test_no_username(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '-m', 'a:1', '--op=add')
-
- def test_no_password(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=add', '-m', 'a:1', '-u', 'tdurden')
-
- def test_invalid_bb_username(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=add', '--bb_username=tdurden',
- *self.extra_args)
-
- def test_invalid_bb_password(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=add', '--bb_password=marla',
- *self.extra_args)
-
- def test_update_no_bb_username(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=update', '--bb_password=marla',
- *self.extra_args)
-
- def test_update_no_bb_password(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=update', '--bb_username=tdurden',
- *self.extra_args)
-
- def test_no_ids_info(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=add', *self.extra_args)
-
- def test_ids_with_add(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=add', '--ids=id1', *self.extra_args)
-
- def test_ids_with_update(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=update', '--ids=id1', *self.extra_args)
-
- def test_no_ids_found_update(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- "--op=update", "--info=svn=x", *self.extra_args)
-
- def test_id_with_add(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- "--op=add", "--info=id:x", *self.extra_args)
-
- def test_info_with_remove(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=remove', '--info=x=v', *self.extra_args)
-
-
- def test_info_with_get(self):
- self.assertRaises(usage.UsageError,
- self.parse,
- '--op=get', '--info=x=v', *self.extra_args)
-
-
-class TestOptions(OptionsMixin, misc.StdoutAssertionsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpOptions()
- self.setUpStdoutAssertions()
-
- def parse(self, *args):
- self.opts = runner.Options()
- self.opts.parseOptions(args)
- return self.opts
-
- def test_defaults(self):
- self.assertRaises(usage.UsageError,
- lambda : self.parse())
-
- def test_version(self):
- try:
- self.parse('--version')
- except SystemExit, e:
- self.assertEqual(e.args[0], 0)
- self.assertInStdout('Buildbot version:')
-
- def test_verbose(self):
- self.patch(log, 'startLogging', mock.Mock())
- self.assertRaises(usage.UsageError, self.parse, "--verbose")
- log.startLogging.assert_called_once_with(sys.stderr)
-
-
-class TestRun(unittest.TestCase):
-
- class MySubCommand(usage.Options):
- subcommandFunction = 'buildbot.test.unit.test_scripts_runner.subcommandFunction'
- optFlags = [
- [ 'loud', 'l', 'be noisy' ]
- ]
- def postOptions(self):
- if self['loud']:
- raise usage.UsageError('THIS IS ME BEING LOUD')
-
- def setUp(self):
- # patch our subcommand in
- self.patch(runner.Options, 'subCommands',
- [ [ 'my', None, self.MySubCommand, 'my, my' ] ])
-
- # and patch in the callback for it
- global subcommandFunction
- subcommandFunction = mock.Mock(name='subcommandFunction',
- return_value=3)
-
- def test_run_good(self):
- self.patch(sys, 'argv', [ 'buildbot', 'my' ])
- try:
- runner.run()
- except SystemExit, e:
- self.assertEqual(e.args[0], 3)
- else:
- self.fail("didn't exit")
-
- def test_run_bad(self):
- self.patch(sys, 'argv', [ 'buildbot', 'my', '-l' ])
- stdout = cStringIO.StringIO()
- self.patch(sys, 'stdout', stdout)
- try:
- runner.run()
- except SystemExit, e:
- self.assertEqual(e.args[0], 1)
- else:
- self.fail("didn't exit")
- self.assertIn('THIS IS ME', stdout.getvalue())
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_sendchange.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_sendchange.py
deleted file mode 100644
index daeaab88..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_sendchange.py
+++ /dev/null
@@ -1,119 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from twisted.internet import reactor, defer
-from buildbot.scripts import sendchange
-from buildbot.clients import sendchange as sendchange_client
-from buildbot.test.util import misc
-
-class TestSendChange(misc.StdoutAssertionsMixin, unittest.TestCase):
-
- class FakeSender:
- def __init__(self, testcase, master, auth, encoding=None):
- self.master = master
- self.auth = auth
- self.encoding = encoding
- self.testcase = testcase
-
- def send(self, branch, revision, comments, files, **kwargs):
- kwargs['branch'] = branch
- kwargs['revision'] = revision
- kwargs['comments'] = comments
- kwargs['files'] = files
- self.send_kwargs = kwargs
- d = defer.Deferred()
- if self.testcase.fail:
- reactor.callLater(0, d.errback, RuntimeError("oh noes"))
- else:
- reactor.callLater(0, d.callback, None)
- return d
-
- def setUp(self):
- self.fail = False # set to true to get Sender.send to fail
- def Sender_constr(*args, **kwargs):
- self.sender = self.FakeSender(self, *args, **kwargs)
- return self.sender
- self.patch(sendchange_client, 'Sender', Sender_constr)
-
- # undo the effects of @in_reactor
- self.patch(sendchange, 'sendchange', sendchange.sendchange._orig)
-
- self.setUpStdoutAssertions()
-
- def test_sendchange_config(self):
- d = sendchange.sendchange(dict(encoding='utf16', who='me',
- auth=['a', 'b'], master='m', branch='br', category='cat',
- revision='rr', properties={'a':'b'}, repository='rep',
- project='prj', vc='git', revlink='rl', when=1234.0,
- comments='comm', files=('a', 'b'), codebase='cb'))
- def check(rc):
- self.assertEqual((self.sender.master, self.sender.auth,
- self.sender.encoding, self.sender.send_kwargs,
- self.getStdout(), rc),
- ('m', ['a','b'], 'utf16', {
- 'branch': 'br',
- 'category': 'cat',
- 'codebase': 'cb',
- 'comments': 'comm',
- 'files': ('a', 'b'),
- 'project': 'prj',
- 'properties': {'a':'b'},
- 'repository': 'rep',
- 'revision': 'rr',
- 'revlink': 'rl',
- 'when': 1234.0,
- 'who': 'me',
- 'vc': 'git'},
- 'change sent successfully', 0))
- d.addCallback(check)
- return d
-
- def test_sendchange_config_no_codebase(self):
- d = sendchange.sendchange(dict(encoding='utf16', who='me',
- auth=['a', 'b'], master='m', branch='br', category='cat',
- revision='rr', properties={'a':'b'}, repository='rep',
- project='prj', vc='git', revlink='rl', when=1234.0,
- comments='comm', files=('a', 'b')))
- def check(rc):
- self.assertEqual((self.sender.master, self.sender.auth,
- self.sender.encoding, self.sender.send_kwargs,
- self.getStdout(), rc),
- ('m', ['a','b'], 'utf16', {
- 'branch': 'br',
- 'category': 'cat',
- 'codebase': None,
- 'comments': 'comm',
- 'files': ('a', 'b'),
- 'project': 'prj',
- 'properties': {'a':'b'},
- 'repository': 'rep',
- 'revision': 'rr',
- 'revlink': 'rl',
- 'when': 1234.0,
- 'who': 'me',
- 'vc': 'git'},
- 'change sent successfully', 0))
- d.addCallback(check)
- return d
-
- def test_sendchange_fail(self):
- self.fail = True
- d = sendchange.sendchange({})
- def check(rc):
- self.assertEqual((self.getStdout().split('\n')[0], rc),
- ('change not sent:', 1))
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_start.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_start.py
deleted file mode 100644
index ddf04d9a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_start.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os, sys
-import twisted
-from twisted.python import versions
-from twisted.internet.utils import getProcessOutputAndValue
-from twisted.trial import unittest
-from buildbot.scripts import start
-from buildbot.test.util import dirs, misc, compat
-
-def mkconfig(**kwargs):
- config = {
- 'quiet': False,
- 'basedir': os.path.abspath('basedir'),
- 'nodaemon': False,
- }
- config.update(kwargs)
- return config
-
-fake_master_tac = """\
-from twisted.application import service
-from twisted.python import log
-from twisted.internet import reactor
-application = service.Application('highscore')
-class App(service.Service):
- def startService(self):
- service.Service.startService(self)
- log.msg("BuildMaster is running") # heh heh heh
- reactor.callLater(0, reactor.stop)
-app = App()
-app.setServiceParent(application)
-# isBuildmasterDir wants to see this -> Application('buildmaster')
-"""
-
-class TestStart(misc.StdoutAssertionsMixin, dirs.DirsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpDirs('basedir')
- with open(os.path.join('basedir', 'buildbot.tac'), 'wt') as f:
- f.write(fake_master_tac)
- self.setUpStdoutAssertions()
-
- def tearDown(self):
- self.tearDownDirs()
-
- # tests
-
- def test_start_not_basedir(self):
- self.assertEqual(start.start(mkconfig(basedir='doesntexist')), 1)
- self.assertInStdout('invalid buildmaster directory')
-
- def runStart(self, **config):
- args=[
- '-c',
- 'from buildbot.scripts.start import start; start(%r)' % (mkconfig(**config),),
- ]
- env = os.environ.copy()
- env['PYTHONPATH'] = os.pathsep.join(sys.path)
- return getProcessOutputAndValue(sys.executable, args=args, env=env)
-
- def test_start_no_daemon(self):
- d = self.runStart(nodaemon=True)
- @d.addCallback
- def cb(res):
- self.assertEquals(res, ('', '', 0))
- print res
- return d
-
- def test_start_quiet(self):
- d = self.runStart(quiet=True)
- @d.addCallback
- def cb(res):
- self.assertEquals(res, ('', '', 0))
- print res
- return d
-
- @compat.skipUnlessPlatformIs('posix')
- def test_start(self):
- d = self.runStart()
- @d.addCallback
- def cb((out, err, rc)):
- self.assertEqual((rc, err), (0, ''))
- self.assertSubstring('BuildMaster is running', out)
- return d
-
- if twisted.version <= versions.Version('twisted', 9, 0, 0):
- test_start.skip = test_start_quiet.skip = "Skipping due to suprious PotentialZombieWarning."
-
- # the remainder of this script does obscene things:
- # - forks
- # - shells out to tail
- # - starts and stops the reactor
- # so testing it will be *far* more pain than is worthwhile
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_statuslog.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_statuslog.py
deleted file mode 100644
index fd067afd..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_statuslog.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-from buildbot.clients import text
-from buildbot.scripts import statuslog
-
-class TestStatusLog(unittest.TestCase):
-
- def test_statuslog(self):
- TextClient = mock.Mock()
- self.patch(text, 'TextClient', TextClient)
- inst = TextClient.return_value = mock.Mock(name='TextClient-instance')
-
- rc = statuslog.statuslog(dict(master='mm', passwd='pp', username='uu'))
-
- TextClient.assert_called_with('mm', passwd='pp', username='uu')
- inst.run.assert_called_with()
- self.assertEqual(rc, 0)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_stop.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_stop.py
deleted file mode 100644
index 07ac05b7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_stop.py
+++ /dev/null
@@ -1,126 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os
-import time
-import signal
-from twisted.trial import unittest
-from buildbot.scripts import stop
-from buildbot.test.util import dirs, misc, compat
-
-def mkconfig(**kwargs):
- config = dict(quiet=False, clean=False, basedir=os.path.abspath('basedir'))
- config.update(kwargs)
- return config
-
-class TestStop(misc.StdoutAssertionsMixin, dirs.DirsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpDirs('basedir')
- self.setUpStdoutAssertions()
-
- def tearDown(self):
- self.tearDownDirs()
-
- # tests
-
- def do_test_stop(self, config, kill_sequence, is_running=True, **kwargs):
- with open(os.path.join('basedir', 'buildbot.tac'), 'wt') as f:
- f.write("Application('buildmaster')")
- if is_running:
- with open("basedir/twistd.pid", 'wt') as f:
- f.write('1234')
- def sleep(t):
- what, exp_t = kill_sequence.pop(0)
- self.assertEqual((what, exp_t), ('sleep', t))
- self.patch(time, 'sleep', sleep)
- def kill(pid, signal):
- exp_sig, result = kill_sequence.pop(0)
- self.assertEqual((pid,signal), (1234,exp_sig))
- if isinstance(result, Exception):
- raise result
- else:
- return result
- self.patch(os, 'kill', kill)
- rv = stop.stop(config, **kwargs)
- self.assertEqual(kill_sequence, [])
- return rv
-
- @compat.skipUnlessPlatformIs('posix')
- def test_stop_not_running(self):
- rv = self.do_test_stop(mkconfig(), [], is_running=False)
- self.assertInStdout('not running')
- self.assertEqual(rv, 0)
-
- @compat.skipUnlessPlatformIs('posix')
- def test_stop_dead_but_pidfile_remains(self):
- rv = self.do_test_stop(mkconfig(),
- [ (signal.SIGTERM, OSError(3, 'No such process')) ])
- self.assertEqual(rv, 0)
- self.assertFalse(os.path.exists(os.path.join('basedir', 'twistd.pid')))
- self.assertInStdout('not running')
-
- @compat.skipUnlessPlatformIs('posix')
- def test_stop_dead_but_pidfile_remains_quiet(self):
- rv = self.do_test_stop(mkconfig(quiet=True),
- [ (signal.SIGTERM, OSError(3, 'No such process')) ],)
- self.assertEqual(rv, 0)
- self.assertFalse(os.path.exists(os.path.join('basedir', 'twistd.pid')))
- self.assertWasQuiet()
-
- @compat.skipUnlessPlatformIs('posix')
- def test_stop_dead_but_pidfile_remains_wait(self):
- rv = self.do_test_stop(mkconfig(),
- [ (signal.SIGTERM, OSError(3, 'No such process')) ],
- wait=True)
- self.assertEqual(rv, 0)
- self.assertFalse(os.path.exists(os.path.join('basedir', 'twistd.pid')))
-
- @compat.skipUnlessPlatformIs('posix')
- def test_stop_slow_death_wait(self):
- rv = self.do_test_stop(mkconfig(), [
- (signal.SIGTERM, None),
- ('sleep', 0.1),
- (0, None), # polling..
- ('sleep', 1),
- (0, None),
- ('sleep', 1),
- (0, None),
- ('sleep', 1),
- (0, OSError(3, 'No such process')),
- ],
- wait=True)
- self.assertInStdout('is dead')
- self.assertEqual(rv, 0)
-
- @compat.skipUnlessPlatformIs('posix')
- def test_stop_slow_death_wait_timeout(self):
- rv = self.do_test_stop(mkconfig(), [
- (signal.SIGTERM, None),
- ('sleep', 0.1), ] +
- [ (0, None),
- ('sleep', 1), ] * 10,
- wait=True)
- self.assertInStdout('never saw process')
- self.assertEqual(rv, 1)
-
- @compat.skipUnlessPlatformIs('posix')
- def test_stop_clean(self):
- rv = self.do_test_stop(mkconfig(clean=True), [
- (signal.SIGUSR1, None), ], wait=False)
- self.assertInStdout('sent SIGUSR1 to process')
- self.assertEqual(rv, 0)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_trycmd.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_trycmd.py
deleted file mode 100644
index 88b32aba..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_trycmd.py
+++ /dev/null
@@ -1,33 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-from buildbot.clients import tryclient
-from buildbot.scripts import trycmd
-
-class TestStatusLog(unittest.TestCase):
-
- def test_trycmd(self):
- Try = mock.Mock()
- self.patch(tryclient, 'Try', Try)
- inst = Try.return_value = mock.Mock(name='Try-instance')
-
- rc = trycmd.trycmd(dict(cfg=1))
-
- Try.assert_called_with(dict(cfg=1))
- inst.run.assert_called_with()
- self.assertEqual(rc, 0)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_tryserver.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_tryserver.py
deleted file mode 100644
index 42ff72da..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_tryserver.py
+++ /dev/null
@@ -1,46 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os
-import sys
-from cStringIO import StringIO
-from twisted.trial import unittest
-from buildbot.scripts import tryserver
-from buildbot.test.util import dirs
-
-class TestStatusLog(dirs.DirsMixin, unittest.TestCase):
-
- def setUp(self):
- self.newdir = os.path.join('jobdir', 'new')
- self.tmpdir = os.path.join('jobdir', 'tmp')
- self.setUpDirs("jobdir", self.newdir, self.tmpdir)
-
- def test_trycmd(self):
- config = dict(jobdir='jobdir')
- inputfile = StringIO('this is my try job')
- self.patch(sys, 'stdin', inputfile)
-
- rc = tryserver.tryserver(config)
-
- self.assertEqual(rc, 0)
-
- newfiles = os.listdir(self.newdir)
- tmpfiles = os.listdir(self.tmpdir)
- self.assertEqual((len(newfiles), len(tmpfiles)),
- (1, 0))
- with open(os.path.join(self.newdir, newfiles[0]), 'rt') as f:
- self.assertEqual(f.read(), 'this is my try job')
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_upgrade_master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_upgrade_master.py
deleted file mode 100644
index 1023d005..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_upgrade_master.py
+++ /dev/null
@@ -1,258 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.scripts import upgrade_master
-from buildbot import config as config_module
-from buildbot.db import connector, model
-from buildbot.test.util import dirs, misc, compat
-
-def mkconfig(**kwargs):
- config = dict(quiet=False, replace=False, basedir='test')
- config.update(kwargs)
- return config
-
-class TestUpgradeMaster(dirs.DirsMixin, misc.StdoutAssertionsMixin,
- unittest.TestCase):
-
- def setUp(self):
- # createMaster is decorated with @in_reactor, so strip that decoration
- # since the master is already running
- self.patch(upgrade_master, 'upgradeMaster',
- upgrade_master.upgradeMaster._orig)
- self.setUpDirs('test')
- self.setUpStdoutAssertions()
-
- def patchFunctions(self, basedirOk=True, configOk=True):
- self.calls = []
-
- def checkBasedir(config):
- self.calls.append('checkBasedir')
- return basedirOk
- self.patch(upgrade_master, 'checkBasedir', checkBasedir)
-
- def loadConfig(config, configFileName='master.cfg'):
- self.calls.append('loadConfig')
- return config_module.MasterConfig() if configOk else False
- self.patch(upgrade_master, 'loadConfig', loadConfig)
-
- def upgradeFiles(config):
- self.calls.append('upgradeFiles')
- self.patch(upgrade_master, 'upgradeFiles', upgradeFiles)
-
- def upgradeDatabase(config, master_cfg):
- self.assertIsInstance(master_cfg, config_module.MasterConfig)
- self.calls.append('upgradeDatabase')
- self.patch(upgrade_master, 'upgradeDatabase', upgradeDatabase)
-
- # tests
-
- def test_upgradeMaster_success(self):
- self.patchFunctions()
- d = upgrade_master.upgradeMaster(mkconfig(), _noMonkey=True)
- @d.addCallback
- def check(rv):
- self.assertEqual(rv, 0)
- self.assertInStdout('upgrade complete')
- return d
-
- def test_upgradeMaster_quiet(self):
- self.patchFunctions()
- d = upgrade_master.upgradeMaster(mkconfig(quiet=True), _noMonkey=True)
- @d.addCallback
- def check(rv):
- self.assertEqual(rv, 0)
- self.assertWasQuiet()
- return d
-
- def test_upgradeMaster_bad_basedir(self):
- self.patchFunctions(basedirOk=False)
- d = upgrade_master.upgradeMaster(mkconfig(), _noMonkey=True)
- @d.addCallback
- def check(rv):
- self.assertEqual(rv, 1)
- return d
-
- def test_upgradeMaster_bad_config(self):
- self.patchFunctions(configOk=False)
- d = upgrade_master.upgradeMaster(mkconfig(), _noMonkey=True)
- @d.addCallback
- def check(rv):
- self.assertEqual(rv, 1)
- return d
-
-class TestUpgradeMasterFunctions(dirs.DirsMixin, misc.StdoutAssertionsMixin,
- unittest.TestCase):
-
- def setUp(self):
- self.setUpDirs('test')
- self.basedir = os.path.abspath(os.path.join('test', 'basedir'))
- self.setUpStdoutAssertions()
-
- def tearDown(self):
- self.tearDownDirs()
-
- def activeBasedir(self):
- with open(os.path.join('test', 'buildbot.tac'), 'wt') as f:
- f.write("Application('buildmaster')")
-
- def writeFile(self, path, contents):
- with open(path, 'wt') as f:
- f.write(contents)
-
- def readFile(self, path):
- with open(path, 'rt') as f:
- return f.read()
-
- # tests
-
- def test_checkBasedir(self):
- self.activeBasedir()
- rv = upgrade_master.checkBasedir(mkconfig())
- self.assertTrue(rv)
- self.assertInStdout('checking basedir')
-
- def test_checkBasedir_quiet(self):
- self.activeBasedir()
- rv = upgrade_master.checkBasedir(mkconfig(quiet=True))
- self.assertTrue(rv)
- self.assertWasQuiet()
-
- def test_checkBasedir_no_dir(self):
- rv = upgrade_master.checkBasedir(mkconfig(basedir='doesntexist'))
- self.assertFalse(rv)
- self.assertInStdout('invalid buildmaster directory')
-
- @compat.skipUnlessPlatformIs('posix')
- def test_checkBasedir_active_pidfile(self):
- self.activeBasedir()
- open(os.path.join('test', 'twistd.pid'), 'w').close()
- rv = upgrade_master.checkBasedir(mkconfig())
- self.assertFalse(rv)
- self.assertInStdout('still running')
-
- def test_loadConfig(self):
- @classmethod
- def loadConfig(cls, basedir, filename):
- return config_module.MasterConfig()
- self.patch(config_module.MasterConfig, 'loadConfig', loadConfig)
- cfg = upgrade_master.loadConfig(mkconfig())
- self.assertIsInstance(cfg, config_module.MasterConfig)
- self.assertInStdout('checking')
-
- def test_loadConfig_ConfigErrors(self):
- @classmethod
- def loadConfig(cls, basedir, filename):
- raise config_module.ConfigErrors(['oh noes'])
- self.patch(config_module.MasterConfig, 'loadConfig', loadConfig)
- cfg = upgrade_master.loadConfig(mkconfig())
- self.assertIdentical(cfg, None)
- self.assertInStdout('oh noes')
-
- def test_loadConfig_exception(self):
- @classmethod
- def loadConfig(cls, basedir, filename):
- raise RuntimeError()
- self.patch(config_module.MasterConfig, 'loadConfig', loadConfig)
- cfg = upgrade_master.loadConfig(mkconfig())
- self.assertIdentical(cfg, None)
- self.assertInStdout('RuntimeError')
-
- def test_installFile(self):
- self.writeFile('test/srcfile', 'source data')
- upgrade_master.installFile(mkconfig(), 'test/destfile', 'test/srcfile')
- self.assertEqual(self.readFile('test/destfile'), 'source data')
- self.assertInStdout('creating test/destfile')
-
- def test_installFile_existing_differing(self):
- self.writeFile('test/srcfile', 'source data')
- self.writeFile('test/destfile', 'dest data')
- upgrade_master.installFile(mkconfig(), 'test/destfile', 'test/srcfile')
- self.assertEqual(self.readFile('test/destfile'), 'dest data')
- self.assertEqual(self.readFile('test/destfile.new'), 'source data')
- self.assertInStdout('writing new contents to')
-
- def test_installFile_existing_differing_overwrite(self):
- self.writeFile('test/srcfile', 'source data')
- self.writeFile('test/destfile', 'dest data')
- upgrade_master.installFile(mkconfig(), 'test/destfile', 'test/srcfile',
- overwrite=True)
- self.assertEqual(self.readFile('test/destfile'), 'source data')
- self.assertFalse(os.path.exists('test/destfile.new'))
- self.assertInStdout('overwriting')
-
- def test_installFile_existing_same(self):
- self.writeFile('test/srcfile', 'source data')
- self.writeFile('test/destfile', 'source data')
- upgrade_master.installFile(mkconfig(), 'test/destfile', 'test/srcfile')
- self.assertEqual(self.readFile('test/destfile'), 'source data')
- self.assertFalse(os.path.exists('test/destfile.new'))
- self.assertWasQuiet()
-
- def test_installFile_quiet(self):
- self.writeFile('test/srcfile', 'source data')
- upgrade_master.installFile(mkconfig(quiet=True), 'test/destfile',
- 'test/srcfile')
- self.assertWasQuiet()
-
- def test_upgradeFiles(self):
- upgrade_master.upgradeFiles(mkconfig())
- for f in [
- 'test/public_html',
- 'test/public_html/bg_gradient.jpg',
- 'test/public_html/default.css',
- 'test/public_html/robots.txt',
- 'test/public_html/favicon.ico',
- 'test/templates',
- 'test/master.cfg.sample',
- ]:
- self.assertTrue(os.path.exists(f), "%s not found" % f)
- self.assertInStdout('upgrading basedir')
-
- def test_upgradeFiles_rename_index_html(self):
- os.mkdir('test/public_html')
- self.writeFile('test/public_html/index.html', 'INDEX')
- upgrade_master.upgradeFiles(mkconfig())
- self.assertFalse(os.path.exists("test/public_html/index.html"))
- self.assertEqual(self.readFile("test/templates/root.html"), 'INDEX')
- self.assertInStdout('Moving ')
-
- def test_upgradeFiles_index_html_collision(self):
- os.mkdir('test/public_html')
- self.writeFile('test/public_html/index.html', 'INDEX')
- os.mkdir('test/templates')
- self.writeFile('test/templates/root.html', 'ROOT')
- upgrade_master.upgradeFiles(mkconfig())
- self.assertTrue(os.path.exists("test/public_html/index.html"))
- self.assertEqual(self.readFile("test/templates/root.html"), 'ROOT')
- self.assertInStdout('Decide')
-
- @defer.inlineCallbacks
- def test_upgradeDatabase(self):
- setup = mock.Mock(side_effect=lambda **kwargs : defer.succeed(None))
- self.patch(connector.DBConnector, 'setup', setup)
- upgrade = mock.Mock(side_effect=lambda **kwargs : defer.succeed(None))
- self.patch(model.Model, 'upgrade', upgrade)
- yield upgrade_master.upgradeDatabase(
- mkconfig(basedir='test', quiet=True),
- config_module.MasterConfig())
- setup.asset_called_with(check_version=False, verbose=False)
- upgrade.assert_called()
- self.assertWasQuiet()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_user.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_user.py
deleted file mode 100644
index 2291c50e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_scripts_user.py
+++ /dev/null
@@ -1,100 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from twisted.internet import defer, reactor
-from buildbot.scripts import user
-from buildbot.clients import usersclient
-from buildbot.process.users import users
-
-class TestUsersClient(unittest.TestCase):
-
- class FakeUsersClient(object):
- def __init__(self, master, username="user", passwd="userpw", port=0):
- self.master = master
- self.port = port
- self.username = username
- self.passwd = passwd
- self.fail = False
-
- def send(self, op, bb_username, bb_password, ids, info):
- self.op = op
- self.bb_username = bb_username
- self.bb_password = bb_password
- self.ids = ids
- self.info = info
- d = defer.Deferred()
- if self.fail:
- reactor.callLater(0, d.errback, RuntimeError("oh noes"))
- else:
- reactor.callLater(0, d.callback, None)
- return d
-
- def setUp(self):
- def fake_UsersClient(*args):
- self.usersclient = self.FakeUsersClient(*args)
- return self.usersclient
- self.patch(usersclient, 'UsersClient', fake_UsersClient)
-
- # un-do the effects of @in_reactor
- self.patch(user, 'user', user.user._orig)
-
- def test_usersclient_send_ids(self):
- d = user.user(dict(master='a:9990', username="x",
- passwd="y", op='get', bb_username=None,
- bb_password=None, ids=['me', 'you'],
- info=None))
- def check(_):
- c = self.usersclient
- self.assertEqual((c.master, c.port, c.username, c.passwd, c.op,
- c.ids, c.info),
- ('a', 9990, "x", "y", 'get', ['me', 'you'], None))
- d.addCallback(check)
- return d
-
- def test_usersclient_send_update_info(self):
- def _fake_encrypt(passwd):
- assert passwd == 'day'
- return 'ENCRY'
- self.patch(users, 'encrypt', _fake_encrypt)
-
- d = user.user(dict(master='a:9990', username="x",
- passwd="y", op='update', bb_username='bud',
- bb_password='day', ids=None,
- info=[{'identifier':'x', 'svn':'x'}]))
- def check(_):
- c = self.usersclient
- self.assertEqual((c.master, c.port, c.username, c.passwd, c.op,
- c.bb_username, c.bb_password, c.ids, c.info),
- ('a', 9990, "x", "y", 'update', 'bud', 'ENCRY',
- None, [{'identifier':'x', 'svn':'x'}]))
- d.addCallback(check)
- return d
-
- def test_usersclient_send_add_info(self):
- d = user.user(dict(master='a:9990', username="x",
- passwd="y", op='add', bb_username=None,
- bb_password=None, ids=None,
- info=[{'git':'x <h@c>', 'irc':'aaa'}]))
- def check(_):
- c = self.usersclient
- self.assertEqual((c.master, c.port, c.username, c.passwd, c.op,
- c.bb_username, c.bb_password, c.ids, c.info),
- ('a', 9990, "x", "y", 'add', None, None, None,
- [{'identifier':'aaa',
- 'git': 'x <h@c>',
- 'irc': 'aaa'}]))
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_sourcestamp.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_sourcestamp.py
deleted file mode 100644
index 3af7d505..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_sourcestamp.py
+++ /dev/null
@@ -1,195 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-from buildbot.changes import changes
-from buildbot.test.fake import fakedb, fakemaster
-from buildbot import sourcestamp
-
-class TestBuilderBuildCreation(unittest.TestCase):
-
- def test_fromSsdict_changes(self):
- master = fakemaster.make_master()
- master.db = fakedb.FakeDBConnector(self)
- master.db.insertTestData([
- fakedb.Change(changeid=13, branch='trunk', revision='9283',
- repository='svn://...', codebase='cb',
- project='world-domination'),
- fakedb.Change(changeid=14, branch='trunk', revision='9284',
- repository='svn://...', codebase='cb',
- project='world-domination'),
- fakedb.Change(changeid=15, branch='trunk', revision='9284',
- repository='svn://...', codebase='cb',
- project='world-domination'),
- fakedb.Change(changeid=16, branch='trunk', revision='9284',
- repository='svn://...', codebase='cb',
- project='world-domination'),
- fakedb.SourceStamp(id=234, branch='trunk', revision='9284',
- repository='svn://...', codebase='cb',
- project='world-domination'),
- fakedb.SourceStampChange(sourcestampid=234, changeid=14),
- fakedb.SourceStampChange(sourcestampid=234, changeid=13),
- fakedb.SourceStampChange(sourcestampid=234, changeid=15),
- fakedb.SourceStampChange(sourcestampid=234, changeid=16),
- ])
- # use getSourceStamp to minimize the risk from changes to the format of
- # the ssdict
- d = master.db.sourcestamps.getSourceStamp(234)
- d.addCallback(lambda ssdict :
- sourcestamp.SourceStamp.fromSsdict(master, ssdict))
- def check(ss):
- self.assertEqual(ss.ssid, 234)
- self.assertEqual(ss.branch, 'trunk')
- self.assertEqual(ss.revision, '9284')
- self.assertEqual(ss.patch, None)
- self.assertEqual(ss.patch_info, None)
- self.assertEqual([ ch.number for ch in ss.changes],
- [13, 14, 15, 16])
- self.assertEqual(ss.project, 'world-domination')
- self.assertEqual(ss.repository, 'svn://...')
- self.assertEqual(ss.codebase, 'cb')
- d.addCallback(check)
- return d
-
- def test_fromSsdict_patch(self):
- master = fakemaster.make_master()
- master.db = fakedb.FakeDBConnector(self)
- master.db.insertTestData([
- fakedb.Patch(id=99, subdir='/foo', patchlevel=3,
- patch_base64='LS0gKys=',
- patch_author='Professor Chaos',
- patch_comment='comment'),
- fakedb.SourceStamp(id=234, sourcestampsetid=234, branch='trunk', revision='9284',
- repository='svn://...', codebase='cb', project='world-domination',
- patchid=99),
- ])
- # use getSourceStamp to minimize the risk from changes to the format of
- # the ssdict
- d = master.db.sourcestamps.getSourceStamp(234)
- d.addCallback(lambda ssdict :
- sourcestamp.SourceStamp.fromSsdict(master, ssdict))
- def check(ss):
- self.assertEqual(ss.ssid, 234)
- self.assertEqual(ss.branch, 'trunk')
- self.assertEqual(ss.revision, '9284')
- self.assertEqual(ss.patch, (3, '-- ++', '/foo'))
- self.assertEqual(ss.patch_info, ('Professor Chaos', 'comment'))
- self.assertEqual(ss.changes, ())
- self.assertEqual(ss.project, 'world-domination')
- self.assertEqual(ss.repository, 'svn://...')
- self.assertEqual(ss.codebase, 'cb')
- d.addCallback(check)
- return d
-
- def test_fromSsdict_simple(self):
- master = fakemaster.make_master()
- master.db = fakedb.FakeDBConnector(self)
- master.db.insertTestData([
- fakedb.SourceStamp(id=234, sourcestampsetid=234, branch='trunk', revision='9284',
- repository='svn://...', codebase = 'cb', project='world-domination'),
- ])
- # use getSourceStamp to minimize the risk from changes to the format of
- # the ssdict
- d = master.db.sourcestamps.getSourceStamp(234)
- d.addCallback(lambda ssdict :
- sourcestamp.SourceStamp.fromSsdict(master, ssdict))
- def check(ss):
- self.assertEqual(ss.ssid, 234)
- self.assertEqual(ss.branch, 'trunk')
- self.assertEqual(ss.revision, '9284')
- self.assertEqual(ss.patch, None)
- self.assertEqual(ss.patch_info, None)
- self.assertEqual(ss.changes, ())
- self.assertEqual(ss.project, 'world-domination')
- self.assertEqual(ss.repository, 'svn://...')
- self.assertEqual(ss.codebase, 'cb')
- d.addCallback(check)
- return d
-
- def test_getAbsoluteSourceStamp_from_relative(self):
- ss = sourcestamp.SourceStamp(branch='dev', revision=None,
- project='p', repository='r', codebase='cb')
- abs_ss = ss.getAbsoluteSourceStamp('abcdef')
- self.assertEqual(abs_ss.branch, 'dev')
- self.assertEqual(abs_ss.revision, 'abcdef')
- self.assertEqual(abs_ss.project, 'p')
- self.assertEqual(abs_ss.repository, 'r')
- self.assertEqual(abs_ss.codebase, 'cb')
-
- def test_getAbsoluteSourceStamp_from_absolute(self):
- ss = sourcestamp.SourceStamp(branch='dev', revision='xyz',
- project='p', repository='r', codebase='cb')
- abs_ss = ss.getAbsoluteSourceStamp('abcdef')
- self.assertEqual(abs_ss.branch, 'dev')
- # revision gets overridden
- self.assertEqual(abs_ss.revision, 'abcdef')
- self.assertEqual(abs_ss.project, 'p')
- self.assertEqual(abs_ss.repository, 'r')
- self.assertEqual(abs_ss.codebase, 'cb')
-
- def test_getAbsoluteSourceStamp_from_absolute_with_changes(self):
- c1 = mock.Mock()
- c1.branch = 'dev'
- c1.revision = 'xyz'
- c1.project = 'p'
- c1.repository = 'r'
- c1.codebase = 'cb'
- ss = sourcestamp.SourceStamp(branch='dev', revision='xyz',
- project='p', repository='r', codebase='cb', changes=[c1])
- abs_ss = ss.getAbsoluteSourceStamp('abcdef')
- self.assertEqual(abs_ss.branch, 'dev')
- # revision changes, even though changes say different - this is
- # useful for CVS, for example
- self.assertEqual(abs_ss.revision, 'abcdef')
- self.assertEqual(abs_ss.project, 'p')
- self.assertEqual(abs_ss.repository, 'r')
- self.assertEqual(abs_ss.codebase, 'cb')
-
- def test_canBeMergedWith_where_sourcestamp_do_not_both_have_changes(self):
- c1 = mock.Mock()
- c1.codebase = 'cb'
- ss1 = sourcestamp.SourceStamp(branch='dev', revision='xyz',
- project='p', repository='r', codebase='cb', changes=[c1])
- ss2 = sourcestamp.SourceStamp(branch='dev', revision='xyz',
- project='p', repository='r', codebase='cb', changes=[])
- self.assertFalse(ss1.canBeMergedWith(ss2))
-
- def test_canBeMergedWith_where_sourcestamp_have_different_codebases(self):
- ss1 = sourcestamp.SourceStamp(branch='dev', revision='xyz',
- project='p', repository='r', codebase='cbA', changes=[])
- ss2 = sourcestamp.SourceStamp(branch='dev', revision='xyz',
- project='p', repository='r', codebase='cbB', changes=[])
- self.assertFalse(ss1.canBeMergedWith(ss2))
-
- def test_canBeMergedWith_with_self_patched_sourcestamps(self):
- ss = sourcestamp.SourceStamp(branch='dev', revision='xyz',
- project='p', repository='r', codebase='cbA', changes=[],
- patch=(1, ''))
- self.assertTrue(ss.canBeMergedWith(ss))
-
- def test_constructor_most_recent_change(self):
- chgs = [
- changes.Change('author', [], 'comments', branch='branch',
- revision='2'),
- changes.Change('author', [], 'comments', branch='branch',
- revision='3'),
- changes.Change('author', [], 'comments', branch='branch',
- revision='1'),
- ]
- for ch in chgs: # mock the DB changeid (aka build number) to match rev
- ch.number = int(ch.revision)
- ss = sourcestamp.SourceStamp(changes=chgs)
- self.assertEquals(ss.revision, '3')
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_build.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_build.py
deleted file mode 100644
index 2917f855..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_build.py
+++ /dev/null
@@ -1,135 +0,0 @@
-# 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
-
-from zope.interface import implements
-import mock
-from twisted.trial import unittest
-from buildbot.status import build
-from buildbot import interfaces
-from buildbot.test.fake import fakemaster
-from buildbot import util
-
-class FakeBuilderStatus:
- implements(interfaces.IBuilderStatus)
-
-class FakeSource(util.ComparableMixin):
- compare_attrs = ('codebase', 'revision')
- def __init__(self, codebase, revision):
- self.codebase = codebase
- self.revision = revision
-
- def clone(self):
- return FakeSource(self.codebase, self.revision)
-
- def getAbsoluteSourceStamp(self, revision):
- return FakeSource(self.codebase, revision)
-
- def __repr__(self):
- # note: this won't work for VC systems with huge 'revision' strings
- text = []
- if self.codebase:
- text.append("(%s)" % self.codebase)
- if self.revision is None:
- return text + [ "latest" ]
- text.append(str(self.revision))
- return "FakeSource(%s)" % (', '.join(text),)
-
-class TestBuildProperties(unittest.TestCase):
- """
- Test that a BuildStatus has the necessary L{IProperties} methods and that
- they delegate to its C{properties} attribute properly - so really just a
- test of the L{IProperties} adapter.
- """
-
- BUILD_NUMBER = 33
-
- def setUp(self):
- self.builder_status = FakeBuilderStatus()
- self.master = fakemaster.make_master()
- self.build_status = build.BuildStatus(self.builder_status, self.master,
- self.BUILD_NUMBER)
- self.build_status.properties = mock.Mock()
-
- def test_getProperty(self):
- self.build_status.getProperty('x')
- self.build_status.properties.getProperty.assert_called_with('x', None)
-
- def test_getProperty_default(self):
- self.build_status.getProperty('x', 'nox')
- self.build_status.properties.getProperty.assert_called_with('x', 'nox')
-
- def test_setProperty(self):
- self.build_status.setProperty('n', 'v', 's')
- self.build_status.properties.setProperty.assert_called_with('n', 'v',
- 's', runtime=True)
-
- def test_hasProperty(self):
- self.build_status.properties.hasProperty.return_value = True
- self.assertTrue(self.build_status.hasProperty('p'))
- self.build_status.properties.hasProperty.assert_called_with('p')
-
- def test_render(self):
- self.build_status.render("xyz")
- self.build_status.properties.render.assert_called_with("xyz")
-
-class TestBuildGetSourcestamps(unittest.TestCase):
- """
- Test that a BuildStatus has the necessary L{IProperties} methods and that
- they delegate to its C{properties} attribute properly - so really just a
- test of the L{IProperties} adapter.
- """
- BUILD_NUMBER = 33
-
- def setUp(self):
- self.builder_status = FakeBuilderStatus()
- self.master = fakemaster.make_master()
- self.build_status = build.BuildStatus(self.builder_status, self.master,
- self.BUILD_NUMBER)
-
- def test_getSourceStamps_no_codebases(self):
- got_revisions = {'': '1111111'}
- self.build_status.sources = [FakeSource('', '0000000')]
- self.build_status.setProperty('got_revision', got_revisions)
- sourcestamps = [ss for ss in self.build_status.getSourceStamps(absolute=False)]
- self.assertEqual(sourcestamps, [FakeSource('', '0000000')])
-
- def test_getSourceStamps_no_codebases_absolute(self):
- got_revisions = {'': '1111111'}
- self.build_status.sources = [FakeSource('', '0000000')]
- self.build_status.setProperty('got_revision', got_revisions)
- sourcestamps = [ss for ss in self.build_status.getSourceStamps(absolute=True)]
- self.assertEqual(sourcestamps, [FakeSource('', '1111111')])
-
- def test_getSourceStamps_with_codebases_absolute(self):
- got_revisions = {'lib1': '1111111', 'lib2': 'aaaaaaa'}
- self.build_status.sources = [FakeSource('lib1', '0000000'),
- FakeSource('lib2', '0000000')]
- self.build_status.setProperty('got_revision', got_revisions)
- sourcestamps = [ss for ss in self.build_status.getSourceStamps(absolute=True)]
- expected_sourcestamps = [FakeSource('lib1', '1111111'),
- FakeSource('lib2', 'aaaaaaa')]
- self.assertEqual(sourcestamps, expected_sourcestamps)
-
- def test_getSourceStamps_with_codebases_less_gotrevisions_absolute(self):
- got_revisions = {'lib1': '1111111', 'lib2': 'aaaaaaa'}
- self.build_status.sources = [FakeSource('lib1', '0000000'),
- FakeSource('lib2', '0000000'),
- FakeSource('lib3', '0000000')]
- self.build_status.setProperty('got_revision', got_revisions)
- sourcestamps = [ss for ss in self.build_status.getSourceStamps(absolute=True)]
- expected_sourcestamps = [FakeSource('lib1', '1111111'),
- FakeSource('lib2', 'aaaaaaa'),
- FakeSource('lib3', '0000000')]
- self.assertEqual(sourcestamps, expected_sourcestamps)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_builder_cache.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_builder_cache.py
deleted file mode 100644
index 4e7a36f7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_builder_cache.py
+++ /dev/null
@@ -1,73 +0,0 @@
-# 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 os
-from mock import Mock
-from twisted.trial import unittest
-from buildbot.status import builder, master
-from buildbot.test.fake import fakemaster
-
-class TestBuildStatus(unittest.TestCase):
-
- # that buildstep.BuildStepStatus is never instantiated here should tell you
- # that these classes are not well isolated!
-
- def setupBuilder(self, buildername, category=None, description=None):
- m = fakemaster.make_master()
- b = builder.BuilderStatus(buildername=buildername, category=category,
- master=m, description=description)
- # Awkwardly, Status sets this member variable.
- b.basedir = os.path.abspath(self.mktemp())
- os.mkdir(b.basedir)
- # Otherwise, builder.nextBuildNumber is not defined.
- b.determineNextBuildNumber()
- # Must initialize these fields before pickling.
- b.currentBigState = 'idle'
- b.status = 'idle'
- return b
-
- def setupStatus(self, b):
- m = Mock()
- m.buildbotURL = 'http://buildbot:8010/'
- m.basedir = '/basedir'
- s = master.Status(m)
- b.status = s
- return s
-
- def testBuildCache(self):
- b = self.setupBuilder('builder_1')
- builds = []
- for i in xrange(5):
- build = b.newBuild()
- build.setProperty('propkey', 'propval%d' % i, 'test')
- builds.append(build)
- build.buildStarted(build)
- build.buildFinished()
- for build in builds:
- build2 = b.getBuild(build.number)
- self.assertTrue(build2)
- self.assertEqual(build2.number, build.number)
- self.assertEqual(build2.getProperty('propkey'),
- 'propval%d' % build.number)
- # Do another round, to make sure we're hitting the cache
- hits = b.buildCache.hits
- for build in builds:
- build2 = b.getBuild(build.number)
- self.assertTrue(build2)
- self.assertEqual(build2.number, build.number)
- self.assertEqual(build2.getProperty('propkey'),
- 'propval%d' % build.number)
- self.assertEqual(b.buildCache.hits, hits+1)
- hits = hits + 1
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_buildstep.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_buildstep.py
deleted file mode 100644
index 44e2d504..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_buildstep.py
+++ /dev/null
@@ -1,67 +0,0 @@
-# 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 os
-from twisted.trial import unittest
-from buildbot.status import builder, master
-from buildbot.test.fake import fakemaster
-
-class TestBuildStepStatus(unittest.TestCase):
-
- # that buildstep.BuildStepStatus is never instantiated here should tell you
- # that these classes are not well isolated!
-
- def setupBuilder(self, buildername, category=None, description=None):
- self.master = fakemaster.make_master()
- self.master.basedir = '/basedir'
-
- b = builder.BuilderStatus(buildername, self.master, category, description)
- b.master = self.master
- # Ackwardly, Status sets this member variable.
- b.basedir = os.path.abspath(self.mktemp())
- os.mkdir(b.basedir)
- # Otherwise, builder.nextBuildNumber is not defined.
- b.determineNextBuildNumber()
- return b
-
- def setupStatus(self, b):
- s = master.Status(self.master)
- b.status = s
- return s
-
- def testBuildStepNumbers(self):
- b = self.setupBuilder('builder_1')
- bs = b.newBuild()
- self.assertEquals(0, bs.getNumber())
- bss1 = bs.addStepWithName('step_1')
- self.assertEquals('step_1', bss1.getName())
- bss2 = bs.addStepWithName('step_2')
- self.assertEquals(0, bss1.asDict()['step_number'])
- self.assertEquals('step_2', bss2.getName())
- self.assertEquals(1, bss2.asDict()['step_number'])
- self.assertEquals([bss1, bss2], bs.getSteps())
-
- def testLogDict(self):
- b = self.setupBuilder('builder_1')
- self.setupStatus(b)
- bs = b.newBuild()
- bss1 = bs.addStepWithName('step_1')
- bss1.stepStarted()
- bss1.addLog('log_1')
- self.assertEquals(
- bss1.asDict()['logs'],
- [['log_1', ('http://localhost:8080/builders/builder_1/'
- 'builds/0/steps/step_1/logs/log_1')]]
- )
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_client.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_client.py
deleted file mode 100644
index 75e93fb4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_client.py
+++ /dev/null
@@ -1,47 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-from buildbot.status import master, client
-from buildbot.test.fake import fakedb
-
-class TestStatusClientPerspective(unittest.TestCase):
-
- def makeStatusClientPersp(self):
- m = mock.Mock(name='master')
- self.db = m.db = fakedb.FakeDBConnector(self)
- m.basedir = r'C:\BASEDIR'
- s = master.Status(m)
- persp = client.StatusClientPerspective(s)
- return persp
-
- def test_getBuildSets(self):
- persp = self.makeStatusClientPersp()
- self.db.insertTestData([
- fakedb.SourceStampSet(id=234),
- fakedb.Buildset(id=91, sourcestampsetid=234, complete=0,
- complete_at=298297875, results=-1, submitted_at=266761875,
- external_idstring='extid', reason='rsn1'),
- ])
-
- d = persp.perspective_getBuildSets()
- def check(bslist):
- self.assertEqual(len(bslist), 1)
- self.assertEqual(bslist[0][1], 91)
- self.failUnlessIsInstance(bslist[0][0], client.RemoteBuildSet)
- d.addCallback(check)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_logfile.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_logfile.py
deleted file mode 100644
index a2f7153f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_logfile.py
+++ /dev/null
@@ -1,336 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os
-import cStringIO, cPickle
-import mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.status import logfile
-from buildbot.test.util import dirs
-from buildbot import config
-
-class TestLogFileProducer(unittest.TestCase):
- def make_static_logfile(self, contents):
- "make a fake logfile with the given contents"
- lf = mock.Mock()
- lf.getFile = lambda : cStringIO.StringIO(contents)
- lf.waitUntilFinished = lambda : defer.succeed(None) # already finished
- lf.runEntries = []
- return lf
-
- def test_getChunks_static_helloworld(self):
- lf = self.make_static_logfile("13:0hello world!,")
- lfp = logfile.LogFileProducer(lf, mock.Mock())
- chunks = list(lfp.getChunks())
- self.assertEqual(chunks, [ (0, 'hello world!') ])
-
- def test_getChunks_static_multichannel(self):
- lf = self.make_static_logfile("2:0a,3:1xx,2:0c,")
- lfp = logfile.LogFileProducer(lf, mock.Mock())
- chunks = list(lfp.getChunks())
- self.assertEqual(chunks, [ (0, 'a'), (1, 'xx'), (0, 'c') ])
-
- # Remainder of LogFileProduer has a wacky interface that's not
- # well-defined, so it's not tested yet
-
-class TestLogFile(unittest.TestCase, dirs.DirsMixin):
-
- def setUp(self):
- step = self.build_step_status = mock.Mock(name='build_step_status')
- self.basedir = step.build.builder.basedir = os.path.abspath('basedir')
- self.setUpDirs(self.basedir)
- self.logfile = logfile.LogFile(step, 'testlf', '123-stdio')
- self.master = self.logfile.master = mock.Mock()
- self.config = self.logfile.master.config = config.MasterConfig()
-
- def tearDown(self):
- if self.logfile.openfile:
- try:
- self.logfile.openfile.close()
- except:
- pass # oh well, we tried
- self.tearDownDirs()
-
- def pickle_and_restore(self):
- pkl = cPickle.dumps(self.logfile)
- self.logfile = cPickle.loads(pkl)
- step = self.build_step_status
- self.logfile.step = step
- self.logfile.master = self.master
- step.build.builder.basedir = self.basedir
-
- def delete_logfile(self):
- if self.logfile.openfile:
- try:
- self.logfile.openfile.close()
- except:
- pass # oh well, we tried
- os.unlink(os.path.join('basedir', '123-stdio'))
-
- # tests
-
- def test_getFilename(self):
- self.assertEqual(self.logfile.getFilename(),
- os.path.abspath(os.path.join('basedir', '123-stdio')))
-
- def test_hasContents_yes(self):
- self.assertTrue(self.logfile.hasContents())
-
- def test_hasContents_no(self):
- self.delete_logfile()
- self.assertFalse(self.logfile.hasContents())
-
- def test_hasContents_gz(self):
- self.delete_logfile()
- with open(os.path.join(self.basedir, '123-stdio.gz'), "w") as f:
- f.write("hi")
- self.assertTrue(self.logfile.hasContents())
-
- def test_hasContents_gz_pickled(self):
- self.delete_logfile()
- with open(os.path.join(self.basedir, '123-stdio.gz'), "w") as f:
- f.write("hi")
- self.pickle_and_restore()
- self.assertTrue(self.logfile.hasContents())
-
- def test_hasContents_bz2(self):
- self.delete_logfile()
- with open(os.path.join(self.basedir, '123-stdio.bz2'), "w") as f:
- f.write("hi")
- self.assertTrue(self.logfile.hasContents())
-
- def test_getName(self):
- self.assertEqual(self.logfile.getName(), 'testlf')
-
- def test_getStep(self):
- self.assertEqual(self.logfile.getStep(), self.build_step_status)
-
- def test_isFinished_no(self):
- self.assertFalse(self.logfile.isFinished())
-
- def test_isFinished_yes(self):
- self.logfile.finish()
- self.assertTrue(self.logfile.isFinished())
-
- def test_waitUntilFinished(self):
- state = []
- d = self.logfile.waitUntilFinished()
- d.addCallback(lambda _ : state.append('called'))
- self.assertEqual(state, []) # not called yet
- self.logfile.finish()
- self.assertEqual(state, ['called'])
-
- def test_getFile(self):
- # test getFile at a number of points in the life-cycle
- self.logfile.addEntry(0, 'hello, world')
- self.logfile._merge()
-
- # while still open for writing
- fp = self.logfile.getFile()
- fp.seek(0, 0)
- self.assertEqual(fp.read(), '13:0hello, world,')
-
- self.logfile.finish()
-
- # fp is still open after finish()
- fp.seek(0, 0)
- self.assertEqual(fp.read(), '13:0hello, world,')
-
- # but a fresh getFile call works, too
- fp = self.logfile.getFile()
- fp.seek(0, 0)
- self.assertEqual(fp.read(), '13:0hello, world,')
-
- self.pickle_and_restore()
-
- # even after it is pickled
- fp = self.logfile.getFile()
- fp.seek(0, 0)
- self.assertEqual(fp.read(), '13:0hello, world,')
-
- # ..and compressed
- self.config.logCompressionMethod = 'bz2'
- d = self.logfile.compressLog()
- def check(_):
- self.assertTrue(
- os.path.exists(os.path.join(self.basedir, '123-stdio.bz2')))
- fp = self.logfile.getFile()
- fp.seek(0, 0)
- self.assertEqual(fp.read(), '13:0hello, world,')
- d.addCallback(check)
- return d
-
- def do_test_addEntry(self, entries, expected):
- for chan, txt in entries:
- self.logfile.addEntry(chan, txt)
- self.logfile.finish()
- fp = self.logfile.getFile()
- fp.seek(0, 0)
- self.assertEqual(fp.read(), expected)
-
- def test_addEntry_single(self):
- return self.do_test_addEntry([(0, 'hello, world')],
- '13:0hello, world,')
-
- def test_addEntry_run(self):
- # test that addEntry is calling merge() correctly
- return self.do_test_addEntry([ (0, c) for c in 'hello, world' ],
- '13:0hello, world,')
-
- def test_addEntry_multichan(self):
- return self.do_test_addEntry([(1, 'x'), (2, 'y'), (1, 'z')],
- '2:1x,2:2y,2:1z,')
-
- def test_addEntry_length(self):
- self.do_test_addEntry([(1, 'x'), (2, 'y')],
- '2:1x,2:2y,')
- self.assertEqual(self.logfile.length, 2)
-
- def test_addEntry_unicode(self):
- return self.do_test_addEntry([(1, u'\N{SNOWMAN}')],
- '4:1\xe2\x98\x83,') # utf-8 encoded
-
- def test_addEntry_logMaxSize(self):
- self.config.logMaxSize = 10 # not evenly divisible by chunk size
- return self.do_test_addEntry([(0, 'abcdef')] * 10 ,
- '11:0abcdefabcd,'
- '64:2\nOutput exceeded 10 bytes, remaining output has been '
- 'truncated\n,')
-
- def test_addEntry_logMaxSize_ignores_header(self):
- self.config.logMaxSize = 10
- return self.do_test_addEntry([(logfile.HEADER, 'abcdef')] * 10 ,
- '61:2' + 'abcdef'*10 + ',')
-
- def test_addEntry_logMaxSize_divisor(self):
- self.config.logMaxSize = 12 # evenly divisible by chunk size
- return self.do_test_addEntry([(0, 'abcdef')] * 10 ,
- '13:0abcdefabcdef,'
- '64:2\nOutput exceeded 12 bytes, remaining output has been '
- 'truncated\n,')
-
- def test_addEntry_logMaxTailSize(self):
- self.config.logMaxSize = 10
- self.config.logMaxTailSize = 14
- return self.do_test_addEntry([(0, 'abcdef')] * 10 ,
- '11:0abcdefabcd,'
- '64:2\nOutput exceeded 10 bytes, remaining output has been '
- 'truncated\n,'
- # NOTE: this gets too few bytes; this is OK for now, and
- # easier than subdividing chunks in the tail tracking
- '31:2\nFinal 12 bytes follow below:\n,'
- '13:0abcdefabcdef,')
-
- def test_addEntry_logMaxTailSize_divisor(self):
- self.config.logMaxSize = 10
- self.config.logMaxTailSize = 12
- return self.do_test_addEntry([(0, 'abcdef')] * 10 ,
- '11:0abcdefabcd,'
- '64:2\nOutput exceeded 10 bytes, remaining output has been '
- 'truncated\n,'
- '31:2\nFinal 12 bytes follow below:\n,'
- '13:0abcdefabcdef,')
-
- # TODO: test that head and tail don't discriminate between stderr and stdout
-
- def test_addEntry_chunkSize(self):
- self.logfile.chunkSize = 11
- return self.do_test_addEntry([(0, 'abcdef')] * 10 ,
- # note that this doesn't re-chunk everything; just shrinks
- # chunks that will exceed the maximum size
- '12:0abcdefabcde,2:0f,' * 5)
-
- def test_addEntry_big_channel(self):
- # channels larger than one digit are not allowed
- self.assertRaises(AssertionError,
- lambda : self.do_test_addEntry([(9999, 'x')], ''))
-
- def test_addEntry_finished(self):
- self.logfile.finish()
- self.assertRaises(AssertionError,
- lambda : self.do_test_addEntry([(0, 'x')], ''))
-
- def test_addEntry_merge_exception(self):
- def fail():
- raise RuntimeError("FAIL")
- self.patch(self.logfile, '_merge', fail)
- self.assertRaises(RuntimeError,
- lambda : self.do_test_addEntry([(0, 'x')], ''))
-
- def test_addEntry_watchers(self):
- watcher = mock.Mock(name='watcher')
- self.logfile.watchers.append(watcher)
- self.do_test_addEntry([(0, 'x')], '2:0x,')
- watcher.logChunk.assert_called_with(self.build_step_status.build,
- self.build_step_status, self.logfile, 0, 'x')
-
- def test_addEntry_watchers_logMaxSize(self):
- watcher = mock.Mock(name='watcher')
- self.logfile.watchers.append(watcher)
- self.config.logMaxSize = 10
- self.do_test_addEntry([(0, 'x')] * 15,
- '11:0xxxxxxxxxx,'
- '64:2\nOutput exceeded 10 bytes, remaining output has been '
- 'truncated\n,')
- logChunk_chunks = [ tuple(args[0][3:])
- for args in watcher.logChunk.call_args_list ]
- self.assertEqual(logChunk_chunks, [(0, 'x')] * 15)
-
- def test_addStdout(self):
- addEntry = mock.Mock()
- self.patch(self.logfile, 'addEntry', addEntry)
- self.logfile.addStdout('oot')
- addEntry.assert_called_with(0, 'oot')
-
- def test_addStderr(self):
- addEntry = mock.Mock()
- self.patch(self.logfile, 'addEntry', addEntry)
- self.logfile.addStderr('eer')
- addEntry.assert_called_with(1, 'eer')
-
- def test_addHeader(self):
- addEntry = mock.Mock()
- self.patch(self.logfile, 'addEntry', addEntry)
- self.logfile.addHeader('hed')
- addEntry.assert_called_with(2, 'hed')
-
- def do_test_compressLog(self, ext, expect_comp=True):
- self.logfile.openfile.write('xyz' * 1000)
- self.logfile.finish()
- d = self.logfile.compressLog()
- def check(_):
- st = os.stat(self.logfile.getFilename() + ext)
- if expect_comp:
- self.assertTrue(0 < st.st_size < 3000)
- else:
- self.assertTrue(st.st_size == 3000)
- d.addCallback(check)
- return d
-
- def test_compressLog_gz(self):
- self.config.logCompressionMethod = 'gz'
- return self.do_test_compressLog('.gz')
-
- def test_compressLog_bz2(self):
- self.config.logCompressionMethod = 'bz2'
- return self.do_test_compressLog('.bz2')
-
- def test_compressLog_none(self):
- self.config.logCompressionMethod = None
- return self.do_test_compressLog('', expect_comp=False)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_mail.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_mail.py
deleted file mode 100644
index 3ca64247..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_mail.py
+++ /dev/null
@@ -1,816 +0,0 @@
-# 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 sys
-from mock import Mock
-from buildbot import config
-from twisted.trial import unittest
-from buildbot.status.results import SUCCESS, FAILURE, WARNINGS, EXCEPTION
-from buildbot.status.mail import MailNotifier
-from twisted.internet import defer
-from buildbot.test.fake import fakedb
-from buildbot.test.fake.fakebuild import FakeBuildStatus
-from buildbot.process import properties
-
-py_27 = sys.version_info[0] > 2 or (sys.version_info[0] == 2
- and sys.version_info[1] >= 7)
-
-class FakeLog(object):
- def __init__(self, text):
- self.text = text
-
- def getName(self):
- return 'log-name'
-
- def getStep(self):
- class FakeStep(object):
- def getName(self):
- return 'step-name'
- return FakeStep()
-
- def getText(self):
- return self.text
-
-class FakeSource:
- def __init__(self, branch = None, revision = None, repository = None,
- codebase = None, project = None):
- self.changes = []
- self.branch = branch
- self.revision = revision
- self.repository = repository
- self.codebase = codebase
- self.project = project
- self.patch_info = None
- self.patch = None
-
-class TestMailNotifier(unittest.TestCase):
-
- def do_test_createEmail_cte(self, funnyChars, expEncoding):
- builds = [ FakeBuildStatus(name='build') ]
- msgdict = create_msgdict(funnyChars)
- mn = MailNotifier('from@example.org')
- d = mn.createEmail(msgdict, u'builder-name', u'project-name',
- SUCCESS, builds)
- @d.addCallback
- def callback(m):
- cte_lines = [ l for l in m.as_string().split("\n")
- if l.startswith('Content-Transfer-Encoding:') ]
- self.assertEqual(cte_lines,
- [ 'Content-Transfer-Encoding: %s' % expEncoding ],
- `m.as_string()`)
- return d
-
- def test_createEmail_message_content_transfer_encoding_7bit(self):
- return self.do_test_createEmail_cte(u"old fashioned ascii",
- '7bit' if py_27 else 'base64')
-
- def test_createEmail_message_content_transfer_encoding_8bit(self):
- return self.do_test_createEmail_cte(u"\U0001F4A7",
- '8bit' if py_27 else 'base64')
-
- def test_createEmail_message_without_patch_and_log_contains_unicode(self):
- builds = [ FakeBuildStatus(name="build") ]
- msgdict = create_msgdict()
- mn = MailNotifier('from@example.org')
- d = mn.createEmail(msgdict, u'builder-n\u00E5me', u'project-n\u00E5me',
- SUCCESS, builds)
- @d.addCallback
- def callback(m):
- try:
- m.as_string()
- except UnicodeEncodeError:
- self.fail('Failed to call as_string() on email message.')
- return d
-
- def test_createEmail_extraHeaders_one_build(self):
- builds = [ FakeBuildStatus(name="build") ]
- builds[0].properties = properties.Properties()
- builds[0].setProperty('hhh','vvv')
- msgdict = create_msgdict()
- mn = MailNotifier('from@example.org', extraHeaders=dict(hhh='vvv'))
- # add some Unicode to detect encoding problems
- d = mn.createEmail(msgdict, u'builder-n\u00E5me', u'project-n\u00E5me',
- SUCCESS, builds)
- @d.addCallback
- def callback(m):
- txt = m.as_string()
- self.assertIn('hhh: vvv', txt)
- return d
-
- def test_createEmail_extraHeaders_two_builds(self):
- builds = [ FakeBuildStatus(name="build1"),
- FakeBuildStatus(name="build2") ]
- msgdict = create_msgdict()
- mn = MailNotifier('from@example.org', extraHeaders=dict(hhh='vvv'))
- d = mn.createEmail(msgdict, u'builder-n\u00E5me', u'project-n\u00E5me',
- SUCCESS, builds)
- @d.addCallback
- def callback(m):
- txt = m.as_string()
- # note that the headers are *not* rendered
- self.assertIn('hhh: vvv', txt)
- return d
-
- def test_createEmail_message_with_patch_and_log_containing_unicode(self):
- builds = [ FakeBuildStatus(name="build") ]
- msgdict = create_msgdict()
- patches = [ ['', u'\u00E5\u00E4\u00F6', ''] ]
- msg = u'Unicode log with non-ascii (\u00E5\u00E4\u00F6).'
- # add msg twice: as unicode and already encoded
- logs = [ FakeLog(msg), FakeLog(msg.encode('utf-8')) ]
- mn = MailNotifier('from@example.org', addLogs=True)
- d = mn.createEmail(msgdict, u'builder-n\u00E5me',
- u'project-n\u00E5me', SUCCESS,
- builds, patches, logs)
- @d.addCallback
- def callback(m):
- try:
- m.as_string()
- except UnicodeEncodeError:
- self.fail('Failed to call as_string() on email message.')
- return d
-
- def test_createEmail_message_with_nonascii_patch(self):
- builds = [ FakeBuildStatus(name="build") ]
- msgdict = create_msgdict()
- patches = [ ['', '\x99\xaa', ''] ]
- logs = [ FakeLog('simple log') ]
- mn = MailNotifier('from@example.org', addLogs=True)
- d = mn.createEmail(msgdict, u'builder', u'pr', SUCCESS,
- builds, patches, logs)
- @d.addCallback
- def callback(m):
- txt = m.as_string()
- self.assertIn('application/octet-stream', txt)
- return d
-
- def test_init_enforces_categories_and_builders_are_mutually_exclusive(self):
- self.assertRaises(config.ConfigErrors,
- MailNotifier, 'from@example.org',
- categories=['fast','slow'], builders=['a','b'])
-
- def test_builderAdded_ignores_unspecified_categories(self):
- mn = MailNotifier('from@example.org', categories=['fast'])
-
- builder = Mock()
- builder.category = 'slow'
-
- self.assertEqual(None, mn.builderAdded('dummyBuilder', builder))
- self.assert_(builder not in mn.watched)
-
- def test_builderAdded_subscribes_to_all_builders_by_default(self):
- mn = MailNotifier('from@example.org')
-
- builder = Mock()
- builder.category = 'slow'
- builder2 = Mock()
- builder2.category = None
-
- self.assertEqual(mn, mn.builderAdded('dummyBuilder', builder))
- self.assertEqual(mn, mn.builderAdded('dummyBuilder2', builder2))
- self.assertTrue(builder in mn.watched)
- self.assertTrue(builder2 in mn.watched)
-
- def test_buildFinished_ignores_unspecified_builders(self):
- mn = MailNotifier('from@example.org', builders=['a','b'])
-
- build = FakeBuildStatus()
- build.builder = Mock()
-
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build, SUCCESS))
-
- def test_buildsetFinished_sends_email(self):
- fakeBuildMessage = Mock()
- mn = MailNotifier('from@example.org',
- buildSetSummary=True,
- mode=("failing", "passing", "warnings"),
- builders=["Builder1", "Builder2"])
-
- mn.buildMessage = fakeBuildMessage
-
- builder1 = Mock()
- builder1.getBuild = lambda number: build1
- builder1.name = "Builder1"
-
- build1 = FakeBuildStatus()
- build1.results = FAILURE
- build1.finished = True
- build1.reason = "testReason"
- build1.getBuilder.return_value = builder1
-
- builder2 = Mock()
- builder2.getBuild = lambda number: build2
- builder2.name = "Builder2"
-
- build2 = FakeBuildStatus()
- build2.results = FAILURE
- build2.finished = True
- build2.reason = "testReason"
- build2.getBuilder.return_value = builder1
-
- def fakeGetBuilder(buildername):
- return {"Builder1": builder1, "Builder2": builder2}[buildername]
-
-
- self.db = fakedb.FakeDBConnector(self)
- self.db.insertTestData([fakedb.SourceStampSet(id=127),
- fakedb.Buildset(id=99, sourcestampsetid=127,
- results=SUCCESS,
- reason="testReason"),
- fakedb.BuildRequest(id=11, buildsetid=99,
- buildername='Builder1'),
- fakedb.Build(number=0, brid=11),
- fakedb.BuildRequest(id=12, buildsetid=99,
- buildername='Builder2'),
- fakedb.Build(number=0, brid=12),
- ])
- mn.master = self # FIXME: Should be FakeMaster
-
- self.status = Mock()
- mn.master_status = Mock()
- mn.master_status.getBuilder = fakeGetBuilder
- mn.buildMessageDict = Mock()
- mn.buildMessageDict.return_value = {"body":"body", "type":"text",
- "subject":"subject"}
-
- mn.buildsetFinished(99, FAILURE)
- fakeBuildMessage.assert_called_with("Buildset Complete: testReason",
- [build1, build2], SUCCESS)
-
- def test_buildsetFinished_doesnt_send_email(self):
- fakeBuildMessage = Mock()
- mn = MailNotifier('from@example.org',
- buildSetSummary=True,
- mode=("failing", "warnings"),
- builders=["Builder"])
- mn.buildMessage = fakeBuildMessage
-
-
- def fakeGetBuild(number):
- return build
-
- def fakeGetBuilder(buildername):
- if buildername == builder.name:
- return builder
- return None
-
- def fakeGetBuildRequests(self, bsid):
- return defer.succeed([{"buildername":"Builder", "brid":1}])
-
- builder = Mock()
- builder.getBuild = fakeGetBuild
- builder.name = "Builder"
-
- build = FakeBuildStatus()
- build.results = SUCCESS
- build.finished = True
- build.reason = "testReason"
- build.getBuilder.return_value = builder
-
- self.db = fakedb.FakeDBConnector(self)
- self.db.insertTestData([fakedb.SourceStampSet(id=127),
- fakedb.Buildset(id=99, sourcestampsetid=127,
- results=SUCCESS,
- reason="testReason"),
- fakedb.BuildRequest(id=11, buildsetid=99,
- buildername='Builder'),
- fakedb.Build(number=0, brid=11),
- ])
- mn.master = self
-
- self.status = Mock()
- mn.master_status = Mock()
- mn.master_status.getBuilder = fakeGetBuilder
- mn.buildMessageDict = Mock()
- mn.buildMessageDict.return_value = {"body":"body", "type":"text",
- "subject":"subject"}
-
- mn.buildsetFinished(99, FAILURE)
- self.assertFalse(fakeBuildMessage.called)
-
- def test_getCustomMesgData_multiple_sourcestamps(self):
- self.passedAttrs = {}
- def fakeCustomMessage(attrs):
- self.passedAttrs = attrs
- return ("", "")
-
- mn = MailNotifier('from@example.org',
- buildSetSummary=True,
- mode=("failing", "passing", "warnings"),
- builders=["Builder"])
-
-
- def fakeBuildMessage(name, builds, results):
- for build in builds:
- mn.buildMessageDict(name=build.getBuilder().name,
- build=build, results=build.results)
-
- mn.buildMessage = fakeBuildMessage
- mn.customMesg = fakeCustomMessage
-
- def fakeGetBuild(number):
- return build
-
- def fakeGetBuilder(buildername):
- if buildername == builder.name:
- return builder
- return None
-
- def fakeGetBuildRequests(self, bsid):
- return defer.succeed([{"buildername":"Builder", "brid":1}])
-
- self.db = fakedb.FakeDBConnector(self)
- self.db.insertTestData([fakedb.SourceStampSet(id=127),
- fakedb.Buildset(id=99, sourcestampsetid=127,
- results=SUCCESS,
- reason="testReason"),
- fakedb.BuildRequest(id=11, buildsetid=99,
- buildername='Builder'),
- fakedb.Build(number=0, brid=11),
- ])
- mn.master = self
-
- builder = Mock()
- builder.getBuild = fakeGetBuild
- builder.name = "Builder"
-
- build = FakeBuildStatus()
- build.results = FAILURE
- build.finished = True
- build.reason = "testReason"
- build.getLogs.return_value = []
- build.getBuilder.return_value = builder
-
- self.status = Mock()
- mn.master_status = Mock()
- mn.master_status.getBuilder = fakeGetBuilder
-
- ss1 = FakeSource(revision='111222', codebase='testlib1')
- ss2 = FakeSource(revision='222333', codebase='testlib2')
- build.getSourceStamps.return_value = [ss1, ss2]
-
- mn.buildsetFinished(99, FAILURE)
-
- self.assertTrue('revision' in self.passedAttrs, "No revision entry found in attrs")
- self.assertTrue(isinstance(self.passedAttrs['revision'], dict))
- self.assertEqual(self.passedAttrs['revision']['testlib1'], '111222')
- self.assertEqual(self.passedAttrs['revision']['testlib2'], '222333')
-
- def test_getCustomMesgData_single_sourcestamp(self):
- self.passedAttrs = {}
- def fakeCustomMessage(attrs):
- self.passedAttrs = attrs
- return ("", "")
-
- mn = MailNotifier('from@example.org',
- buildSetSummary=True,
- mode=("failing", "passing", "warnings"),
- builders=["Builder"])
-
-
- def fakeBuildMessage(name, builds, results):
- for build in builds:
- mn.buildMessageDict(name=build.getBuilder().name,
- build=build, results=build.results)
-
- mn.buildMessage = fakeBuildMessage
- mn.customMesg = fakeCustomMessage
-
- def fakeGetBuild(number):
- return build
-
- def fakeGetBuilder(buildername):
- if buildername == builder.name:
- return builder
- return None
-
- def fakeGetBuildRequests(self, bsid):
- return defer.succeed([{"buildername":"Builder", "brid":1}])
-
- self.db = fakedb.FakeDBConnector(self)
- self.db.insertTestData([fakedb.SourceStampSet(id=127),
- fakedb.Buildset(id=99, sourcestampsetid=127,
- results=SUCCESS,
- reason="testReason"),
- fakedb.BuildRequest(id=11, buildsetid=99,
- buildername='Builder'),
- fakedb.Build(number=0, brid=11),
- ])
- mn.master = self
-
- builder = Mock()
- builder.getBuild = fakeGetBuild
- builder.name = "Builder"
-
- build = FakeBuildStatus()
- build.results = FAILURE
- build.finished = True
- build.reason = "testReason"
- build.getLogs.return_value = []
- build.getBuilder.return_value = builder
-
- self.status = Mock()
- mn.master_status = Mock()
- mn.master_status.getBuilder = fakeGetBuilder
-
- ss1 = FakeSource(revision='111222', codebase='testlib1')
- build.getSourceStamps.return_value = [ss1]
-
- mn.buildsetFinished(99, FAILURE)
-
- self.assertTrue('builderName' in self.passedAttrs, "No builderName entry found in attrs")
- self.assertEqual(self.passedAttrs['builderName'], 'Builder')
- self.assertTrue('revision' in self.passedAttrs, "No revision entry found in attrs")
- self.assertTrue(isinstance(self.passedAttrs['revision'], str))
- self.assertEqual(self.passedAttrs['revision'], '111222')
-
- def test_buildFinished_ignores_unspecified_categories(self):
- mn = MailNotifier('from@example.org', categories=['fast'])
-
-
- build = FakeBuildStatus(name="build")
- build.builder = Mock()
- build.builder.category = 'slow'
-
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build, SUCCESS))
-
- def run_simple_test_sends_email_for_mode(self, mode, result):
- mock_method = Mock()
- self.patch(MailNotifier, "buildMessage", mock_method)
- mn = MailNotifier('from@example.org', mode=mode)
-
- build = FakeBuildStatus(name="build")
- mn.buildFinished('dummyBuilder', build, result)
-
- mock_method.assert_called_with('dummyBuilder', [build], result)
-
- def run_simple_test_ignores_email_for_mode(self, mode, result):
- mock_method = Mock()
- self.patch(MailNotifier, "buildMessage", mock_method)
- mn = MailNotifier('from@example.org', mode=mode)
-
- build = FakeBuildStatus(name="build")
- mn.buildFinished('dummyBuilder', build, result)
-
- self.assertFalse(mock_method.called)
-
- def test_buildFinished_mode_all_for_success(self):
- self.run_simple_test_sends_email_for_mode("all", SUCCESS)
- def test_buildFinished_mode_all_for_failure(self):
- self.run_simple_test_sends_email_for_mode("all", FAILURE)
- def test_buildFinished_mode_all_for_warnings(self):
- self.run_simple_test_sends_email_for_mode("all", WARNINGS)
- def test_buildFinished_mode_all_for_exception(self):
- self.run_simple_test_sends_email_for_mode("all", EXCEPTION)
-
- def test_buildFinished_mode_failing_for_success(self):
- self.run_simple_test_ignores_email_for_mode("failing", SUCCESS)
- def test_buildFinished_mode_failing_for_failure(self):
- self.run_simple_test_sends_email_for_mode("failing", FAILURE)
- def test_buildFinished_mode_failing_for_warnings(self):
- self.run_simple_test_ignores_email_for_mode("failing", WARNINGS)
- def test_buildFinished_mode_failing_for_exception(self):
- self.run_simple_test_ignores_email_for_mode("failing", EXCEPTION)
-
- def test_buildFinished_mode_exception_for_success(self):
- self.run_simple_test_ignores_email_for_mode("exception", SUCCESS)
- def test_buildFinished_mode_exception_for_failure(self):
- self.run_simple_test_ignores_email_for_mode("exception", FAILURE)
- def test_buildFinished_mode_exception_for_warnings(self):
- self.run_simple_test_ignores_email_for_mode("exception", WARNINGS)
- def test_buildFinished_mode_exception_for_exception(self):
- self.run_simple_test_sends_email_for_mode("exception", EXCEPTION)
-
- def test_buildFinished_mode_warnings_for_success(self):
- self.run_simple_test_ignores_email_for_mode("warnings", SUCCESS)
- def test_buildFinished_mode_warnings_for_failure(self):
- self.run_simple_test_sends_email_for_mode("warnings", FAILURE)
- def test_buildFinished_mode_warnings_for_warnings(self):
- self.run_simple_test_sends_email_for_mode("warnings", WARNINGS)
- def test_buildFinished_mode_warnings_for_exception(self):
- self.run_simple_test_ignores_email_for_mode("warnings", EXCEPTION)
-
- def test_buildFinished_mode_passing_for_success(self):
- self.run_simple_test_sends_email_for_mode("passing", SUCCESS)
- def test_buildFinished_mode_passing_for_failure(self):
- self.run_simple_test_ignores_email_for_mode("passing", FAILURE)
- def test_buildFinished_mode_passing_for_warnings(self):
- self.run_simple_test_ignores_email_for_mode("passing", WARNINGS)
- def test_buildFinished_mode_passing_for_exception(self):
- self.run_simple_test_ignores_email_for_mode("passing", EXCEPTION)
-
- def test_buildFinished_mode_failing_ignores_successful_build(self):
- mn = MailNotifier('from@example.org', mode=("failing",))
-
- build = FakeBuildStatus(name="build")
-
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build, SUCCESS))
-
- def test_buildFinished_mode_passing_ignores_failed_build(self):
- mn = MailNotifier('from@example.org', mode=("passing",))
-
- build = FakeBuildStatus(name="build")
-
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build, FAILURE))
-
- def test_buildFinished_mode_problem_ignores_successful_build(self):
- mn = MailNotifier('from@example.org', mode=("problem",))
-
- build = FakeBuildStatus(name="build")
-
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build, SUCCESS))
-
- def test_buildFinished_mode_problem_ignores_two_failed_builds_in_sequence(self):
- mn = MailNotifier('from@example.org', mode=("problem",))
-
- build = FakeBuildStatus(name="build")
- old_build = FakeBuildStatus(name="old_build")
- build.getPreviousBuild.return_value = old_build
- old_build.getResults.return_value = FAILURE
-
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build, FAILURE))
-
- def test_buildFinished_mode_change_ignores_first_build(self):
- mn = MailNotifier('from@example.org', mode=("change",))
-
- build = FakeBuildStatus(name="build")
- build.getPreviousBuild.return_value = None
-
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build, FAILURE))
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build, SUCCESS))
-
-
- def test_buildFinished_mode_change_ignores_same_result_in_sequence(self):
- mn = MailNotifier('from@example.org', mode=("change",))
-
- build = FakeBuildStatus(name="build")
- old_build = FakeBuildStatus(name="old_build")
- build.getPreviousBuild.return_value = old_build
- old_build.getResults.return_value = FAILURE
-
- build2 = FakeBuildStatus(name="build2")
- old_build2 = FakeBuildStatus(name="old_build2")
- build2.getPreviousBuild.return_value = old_build2
- old_build2.getResults.return_value = SUCCESS
-
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build, FAILURE))
- self.assertEqual(None, mn.buildFinished('dummyBuilder', build2, SUCCESS))
-
- def test_buildMessage_addLogs(self):
- mn = MailNotifier('from@example.org', mode=("change",), addLogs=True)
-
- mn.buildMessageDict = Mock()
- mn.buildMessageDict.return_value = {"body":"body", "type":"text",
- "subject":"subject"}
-
- mn.createEmail = Mock("createEmail")
-
- mn._gotRecipients = Mock("_gotReceipients")
- mn._gotRecipients.return_value = None
-
- mn.master_status = Mock()
- mn.master_status.getTitle.return_value = 'TITLE'
-
- bldr = Mock(name="builder")
- builds = [ FakeBuildStatus(name='build1'),
- FakeBuildStatus(name='build2') ]
- logs = [ FakeLog('log1'), FakeLog('log2') ]
- for b, l in zip(builds, logs):
- b.builder = bldr
- b.results = 0
- ss = Mock(name='ss')
- b.getSourceStamps.return_value = [ss]
- ss.patch = None
- ss.changes = []
- b.getLogs.return_value = [ l ]
- d = mn.buildMessage("mybldr", builds, 0)
- def check(_):
- mn.createEmail.assert_called_with(
- dict(body='body\n\nbody\n\n', type='text', subject='subject'),
- 'mybldr', 'TITLE', 0, builds, [], logs)
- d.addCallback(check)
- return d
-
- def do_test_sendToInterestedUsers(self, lookup=None, extraRecipients=[],
- sendToInterestedUsers=True,
- exp_called_with=None, exp_TO=None,
- exp_CC=None):
- from email.Message import Message
- m = Message()
-
- mn = MailNotifier(fromaddr='from@example.org',
- lookup=lookup,
- sendToInterestedUsers=sendToInterestedUsers,
- extraRecipients=extraRecipients)
- mn.sendMessage = Mock()
-
- def fakeGetBuild(number):
- return build
- def fakeGetBuilder(buildername):
- if buildername == builder.name:
- return builder
- return None
- def fakeGetBuildRequests(self, bsid):
- return defer.succeed([{"buildername":"Builder", "brid":1}])
-
- builder = Mock()
- builder.getBuild = fakeGetBuild
- builder.name = "Builder"
-
- build = FakeBuildStatus(name="build")
- build.result = FAILURE
- build.finished = True
- build.reason = "testReason"
- build.builder = builder
-
- def fakeCreateEmail(msgdict, builderName, title, results, builds=None,
- patches=None, logs=None):
- # only concerned with m['To'] and m['CC'], which are added in
- # _got_recipients later
- return defer.succeed(m)
- mn.createEmail = fakeCreateEmail
-
- self.db = fakedb.FakeDBConnector(self)
- self.db.insertTestData([fakedb.SourceStampSet(id=1099),
- fakedb.Buildset(id=99, sourcestampsetid=1099,
- results=SUCCESS,
- reason="testReason"),
- fakedb.BuildRequest(id=11, buildsetid=99,
- buildername='Builder'),
- fakedb.Build(number=0, brid=11),
- fakedb.Change(changeid=9123),
- fakedb.ChangeUser(changeid=9123, uid=1),
- fakedb.User(uid=1, identifier="tdurden"),
- fakedb.UserInfo(uid=1, attr_type='svn',
- attr_data="tdurden"),
- fakedb.UserInfo(uid=1, attr_type='email',
- attr_data="tyler@mayhem.net")
- ])
-
- # fake sourcestamp with relevant user bits
- ss = Mock(name="sourcestamp")
- fake_change = Mock(name="change")
- fake_change.number = 9123
- ss.changes = [fake_change]
- ss.patch, ss.addPatch = None, None
-
- def fakeGetSSlist():
- return [ss]
- build.getSourceStamps = fakeGetSSlist
-
- def _getInterestedUsers():
- # 'narrator' in this case is the owner, which tests the lookup
- return ["narrator"]
- build.getInterestedUsers = _getInterestedUsers
-
- def _getResponsibleUsers():
- return ["Big Bob <bob@mayhem.net>"]
- build.getResponsibleUsers = _getResponsibleUsers
-
- mn.master = self # FIXME: Should be FakeMaster
- self.status = mn.master_status = mn.buildMessageDict = Mock()
- mn.master_status.getBuilder = fakeGetBuilder
- mn.buildMessageDict.return_value = {"body": "body", "type": "text"}
-
- mn.buildMessage(builder.name, [build], build.result)
- mn.sendMessage.assert_called_with(m, exp_called_with)
- self.assertEqual(m['To'], exp_TO)
- self.assertEqual(m['CC'], exp_CC)
-
- def test_sendToInterestedUsers_lookup(self):
- self.do_test_sendToInterestedUsers(
- lookup="example.org",
- exp_called_with=['Big Bob <bob@mayhem.net>',
- 'narrator@example.org'],
- exp_TO="Big Bob <bob@mayhem.net>, " \
- "narrator@example.org")
-
- def test_buildMessage_sendToInterestedUsers_no_lookup(self):
- self.do_test_sendToInterestedUsers(
- exp_called_with=['tyler@mayhem.net'],
- exp_TO="tyler@mayhem.net")
-
- def test_buildMessage_sendToInterestedUsers_extraRecipients(self):
- self.do_test_sendToInterestedUsers(
- extraRecipients=["marla@mayhem.net"],
- exp_called_with=['tyler@mayhem.net',
- 'marla@mayhem.net'],
- exp_TO="tyler@mayhem.net",
- exp_CC="marla@mayhem.net")
- def test_sendToInterestedUsers_False(self):
- self.do_test_sendToInterestedUsers(
- extraRecipients=["marla@mayhem.net"],
- sendToInterestedUsers=False,
- exp_called_with=['marla@mayhem.net'],
- exp_TO="marla@mayhem.net")
-
- def test_sendToInterestedUsers_two_builds(self):
- from email.Message import Message
- m = Message()
-
- mn = MailNotifier(fromaddr="from@example.org", lookup=None)
- mn.sendMessage = Mock()
-
- def fakeGetBuilder(buildername):
- if buildername == builder.name:
- return builder
- return None
- def fakeGetBuildRequests(self, bsid):
- return defer.succeed([{"buildername":"Builder", "brid":1}])
-
- builder = Mock()
- builder.name = "Builder"
-
- build1 = FakeBuildStatus(name="build")
- build1.result = FAILURE
- build1.finished = True
- build1.reason = "testReason"
- build1.builder = builder
-
- build2 = FakeBuildStatus(name="build")
- build2.result = FAILURE
- build2.finished = True
- build2.reason = "testReason"
- build2.builder = builder
-
- def fakeCreateEmail(msgdict, builderName, title, results, builds=None,
- patches=None, logs=None):
- # only concerned with m['To'] and m['CC'], which are added in
- # _got_recipients later
- return defer.succeed(m)
- mn.createEmail = fakeCreateEmail
-
- self.db = fakedb.FakeDBConnector(self)
- self.db.insertTestData([fakedb.SourceStampSet(id=1099),
- fakedb.Buildset(id=99, sourcestampsetid=1099,
- results=SUCCESS,
- reason="testReason"),
- fakedb.BuildRequest(id=11, buildsetid=99,
- buildername='Builder'),
- fakedb.Build(number=0, brid=11),
- fakedb.Build(number=1, brid=11),
- fakedb.Change(changeid=9123),
- fakedb.Change(changeid=9124),
- fakedb.ChangeUser(changeid=9123, uid=1),
- fakedb.ChangeUser(changeid=9124, uid=2),
- fakedb.User(uid=1, identifier="tdurden"),
- fakedb.User(uid=2, identifier="user2"),
- fakedb.UserInfo(uid=1, attr_type='email',
- attr_data="tyler@mayhem.net"),
- fakedb.UserInfo(uid=2, attr_type='email',
- attr_data="user2@example.net")
- ])
-
- def _getInterestedUsers():
- # 'narrator' in this case is the owner, which tests the lookup
- return ["narrator"]
- build1.getInterestedUsers = _getInterestedUsers
- build2.getInterestedUsers = _getInterestedUsers
-
- def _getResponsibleUsers():
- return ["Big Bob <bob@mayhem.net>"]
- build1.getResponsibleUsers = _getResponsibleUsers
- build2.getResponsibleUsers = _getResponsibleUsers
-
- # fake sourcestamp with relevant user bits
- ss1 = Mock(name="sourcestamp")
- fake_change1 = Mock(name="change")
- fake_change1.number = 9123
- ss1.changes = [fake_change1]
- ss1.patch, ss1.addPatch = None, None
-
- ss2 = Mock(name="sourcestamp")
- fake_change2 = Mock(name="change")
- fake_change2.number = 9124
- ss2.changes = [fake_change2]
- ss2.patch, ss1.addPatch = None, None
-
- def fakeGetSSlist(ss):
- return lambda: [ss]
- build1.getSourceStamps = fakeGetSSlist(ss1)
- build2.getSourceStamps = fakeGetSSlist(ss2)
-
- mn.master = self # FIXME: Should be FakeMaster
- self.status = mn.master_status = mn.buildMessageDict = Mock()
- mn.master_status.getBuilder = fakeGetBuilder
- mn.buildMessageDict.return_value = {"body": "body", "type": "text"}
-
- mn.buildMessage(builder.name, [build1, build2], build1.result)
- self.assertEqual(m['To'], "tyler@mayhem.net, user2@example.net")
-
-def create_msgdict(funny_chars=u'\u00E5\u00E4\u00F6'):
- unibody = u'Unicode body with non-ascii (%s).' % funny_chars
- msg_dict = dict(body=unibody, type='plain')
- return msg_dict
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_master.py
deleted file mode 100644
index 04ae5136..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_master.py
+++ /dev/null
@@ -1,95 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.status import master, base
-from buildbot.test.fake import fakedb
-
-class FakeStatusReceiver(base.StatusReceiver):
- pass
-
-class TestStatus(unittest.TestCase):
-
- def makeStatus(self):
- m = mock.Mock(name='master')
- self.db = m.db = fakedb.FakeDBConnector(self)
- m.basedir = r'C:\BASEDIR'
- s = master.Status(m)
- return s
-
- def test_getBuildSets(self):
- s = self.makeStatus()
- self.db.insertTestData([
- fakedb.Buildset(id=91, sourcestampsetid=234, complete=0,
- complete_at=298297875, results=-1, submitted_at=266761875,
- external_idstring='extid', reason='rsn1'),
- fakedb.Buildset(id=92, sourcestampsetid=234, complete=1,
- complete_at=298297876, results=7, submitted_at=266761876,
- external_idstring='extid', reason='rsn2'),
- ])
-
- d = s.getBuildSets()
- def check(bslist):
- self.assertEqual([ bs.id for bs in bslist ], [ 91 ])
- d.addCallback(check)
- return d
-
- @defer.inlineCallbacks
- def test_reconfigService(self):
- m = mock.Mock(name='master')
- status = master.Status(m)
- status.startService()
-
- config = mock.Mock()
-
- # add a status reciever
- sr0 = FakeStatusReceiver()
- config.status = [ sr0 ]
-
- yield status.reconfigService(config)
-
- self.assertTrue(sr0.running)
- self.assertIdentical(sr0.master, m)
-
- # add a status reciever
- sr1 = FakeStatusReceiver()
- sr2 = FakeStatusReceiver()
- config.status = [ sr1, sr2 ]
-
- yield status.reconfigService(config)
-
- self.assertFalse(sr0.running)
- self.assertIdentical(sr0.master, None)
- self.assertTrue(sr1.running)
- self.assertIdentical(sr1.master, m)
- self.assertTrue(sr2.running)
- self.assertIdentical(sr2.master, m)
-
- # reconfig with those two (a regression check)
- sr1 = FakeStatusReceiver()
- sr2 = FakeStatusReceiver()
- config.status = [ sr1, sr2 ]
-
- yield status.reconfigService(config)
-
- # and back to nothing
- config.status = [ ]
- yield status.reconfigService(config)
-
- self.assertIdentical(sr0.master, None)
- self.assertIdentical(sr1.master, None)
- self.assertIdentical(sr2.master, None)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_persistent_queue.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_persistent_queue.py
deleted file mode 100644
index 3bf65e5d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_persistent_queue.py
+++ /dev/null
@@ -1,147 +0,0 @@
-# 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 os
-from twisted.trial import unittest
-from buildbot.test.util import dirs
-
-from buildbot.status.persistent_queue import MemoryQueue, DiskQueue, \
- IQueue, PersistentQueue, WriteFile
-
-class test_Queues(dirs.DirsMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpDirs('fake_dir')
-
- def tearDown(self):
- self.assertEqual([], os.listdir('fake_dir'))
- self.tearDownDirs()
-
- def testQueued(self):
- # Verify behavior when starting up with queued items on disk.
- WriteFile(os.path.join('fake_dir', '3'), 'foo3')
- WriteFile(os.path.join('fake_dir', '5'), 'foo5')
- WriteFile(os.path.join('fake_dir', '8'), 'foo8')
- queue = PersistentQueue(MemoryQueue(3),
- DiskQueue('fake_dir', 5, pickleFn=str, unpickleFn=str))
- self.assertEqual(['foo3', 'foo5', 'foo8'], queue.items())
- self.assertEqual(3, queue.nbItems())
- self.assertEqual(['foo3', 'foo5', 'foo8'], queue.popChunk())
-
- def _test_helper(self, q):
- self.assertTrue(IQueue.providedBy(q))
- self.assertEqual(8, q.maxItems())
- self.assertEqual(0, q.nbItems())
- self.assertEqual([], q.items())
-
- for i in range(4):
- self.assertEqual(None, q.pushItem(i), str(i))
- self.assertEqual(i + 1, q.nbItems(), str(i))
- self.assertEqual([0, 1, 2, 3], q.items())
- self.assertEqual(4, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([0, 1, 2], q.primaryQueue.items())
- self.assertEqual([3], q.secondaryQueue.items())
-
- self.assertEqual(None, q.save())
- self.assertEqual([0, 1, 2, 3], q.items())
- self.assertEqual(4, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([], q.primaryQueue.items())
- self.assertEqual([0, 1, 2, 3], q.secondaryQueue.items())
-
- for i in range(4):
- self.assertEqual(None, q.pushItem(i + 4), str(i + 4))
- self.assertEqual(i + 5, q.nbItems(), str(i + 4))
- self.assertEqual([0, 1, 2, 3, 4, 5, 6, 7], q.items())
- self.assertEqual(8, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([0, 1, 2], q.primaryQueue.items())
- self.assertEqual([3, 4, 5, 6, 7], q.secondaryQueue.items())
-
- self.assertEqual(0, q.pushItem(8))
- self.assertEqual(8, q.nbItems())
- self.assertEqual([1, 2, 3, 4, 5, 6, 7, 8], q.items())
- if isinstance(q, PersistentQueue):
- self.assertEqual([1, 2, 3], q.primaryQueue.items())
- self.assertEqual([4, 5, 6, 7, 8], q.secondaryQueue.items())
-
- self.assertEqual([1, 2], q.popChunk(2))
- self.assertEqual([3, 4, 5, 6, 7, 8], q.items())
- self.assertEqual(6, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([3], q.primaryQueue.items())
- self.assertEqual([4, 5, 6, 7, 8], q.secondaryQueue.items())
-
- self.assertEqual([3], q.popChunk(1))
- self.assertEqual([4, 5, 6, 7, 8], q.items())
- self.assertEqual(5, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([], q.primaryQueue.items())
- self.assertEqual([4, 5, 6, 7, 8], q.secondaryQueue.items())
-
- self.assertEqual(None, q.save())
- self.assertEqual(5, q.nbItems())
- self.assertEqual([4, 5, 6, 7, 8], q.items())
- if isinstance(q, PersistentQueue):
- self.assertEqual([], q.primaryQueue.items())
- self.assertEqual([4, 5, 6, 7, 8], q.secondaryQueue.items())
-
- self.assertEqual(None, q.insertBackChunk([2, 3]))
- self.assertEqual([2, 3, 4, 5, 6, 7, 8], q.items())
- self.assertEqual(7, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([2, 3], q.primaryQueue.items())
- self.assertEqual([4, 5, 6, 7, 8], q.secondaryQueue.items())
-
- self.assertEqual([0], q.insertBackChunk([0, 1]))
- self.assertEqual([1, 2, 3, 4, 5, 6, 7, 8], q.items())
- self.assertEqual(8, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([1, 2, 3], q.primaryQueue.items())
- self.assertEqual([4, 5, 6, 7, 8], q.secondaryQueue.items())
-
- self.assertEqual([10, 11], q.insertBackChunk([10, 11]))
- self.assertEqual([1, 2, 3, 4, 5, 6, 7, 8], q.items())
- self.assertEqual(8, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([1, 2, 3], q.primaryQueue.items())
- self.assertEqual([4, 5, 6, 7, 8], q.secondaryQueue.items())
-
- self.assertEqual([1, 2, 3, 4, 5, 6, 7, 8], q.popChunk(8))
- self.assertEqual([], q.items())
- self.assertEqual(0, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([], q.primaryQueue.items())
- self.assertEqual([], q.secondaryQueue.items())
-
- self.assertEqual([], q.popChunk())
- self.assertEqual(0, q.nbItems())
- if isinstance(q, PersistentQueue):
- self.assertEqual([], q.primaryQueue.items())
- self.assertEqual([], q.secondaryQueue.items())
-
- def testMemoryQueue(self):
- self._test_helper(MemoryQueue(maxItems=8))
-
- def testDiskQueue(self):
- self._test_helper(DiskQueue('fake_dir', maxItems=8))
-
- def testPersistentQueue(self):
- self._test_helper(PersistentQueue(MemoryQueue(3),
- DiskQueue('fake_dir', 5)))
-
-# vim: set ts=4 sts=4 sw=4 et:
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_progress.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_progress.py
deleted file mode 100644
index b1abc8b9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_progress.py
+++ /dev/null
@@ -1,43 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.status import progress
-
-class TestExpectations(unittest.TestCase):
-
- def test_addNewStep(self):
- """
- http://trac.buildbot.net/ticket/2252
- """
- buildProgress = progress.BuildProgress([])
- expectations = progress.Expectations(buildProgress)
- stepProgress = progress.StepProgress("step", ["metric"])
- newProgress = progress.BuildProgress([stepProgress])
- stepProgress.start()
- stepProgress.finish()
- stepProgress.setProgress("metric", 42)
- expectations.update(newProgress)
-
-
- def test_removeOldStep(self):
- """
- http://trac.buildbot.net/ticket/2281
- """
- stepProgress = progress.StepProgress("step", ["metric"])
- oldProgress = progress.BuildProgress([stepProgress])
- expectations = progress.Expectations(oldProgress)
- buildProgress = progress.BuildProgress([])
- buildProgress.setExpectationsFrom(expectations)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_auth_HTPasswdAprAuth.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_auth_HTPasswdAprAuth.py
deleted file mode 100644
index 27a0d24f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_auth_HTPasswdAprAuth.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# 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
-"""
-Test Passwords
-desbuildmaster:yifux5rkzvI5w
-desbuildslave:W8SPURMnCs7Tc
-desbuildbot:IzclhyfHAq6Oc
-md5buildmaster:$apr1$pSepI8Wp$eJZcfhnpENrRlUn28wak50
-md5buildslave:$apr1$dtX6FDei$vFB5BlnR9bjQisy7v3ZaC0
-md5buildbot:$apr1$UcfsHmrF$i9fYa4OsPI3AK8UBbN3ju1
-shabuildmaster:{SHA}vpAKSO3uPt6z8KL6cqf5W5Sredk=
-shabuildslave:{SHA}sNA10GbdONwGJ+a8VGRNtEyWd9I=
-shabuildbot:{SHA}TwEDa5Q31ZhI4GLmIbE1VrrAkpk=
-"""
-
-
-from twisted.trial import unittest
-
-from buildbot.status.web.auth import HTPasswdAprAuth
-from buildbot.test.util import compat
-
-class TestHTPasswdAprAuth(unittest.TestCase):
-
- htpasswd = HTPasswdAprAuth(__file__)
-
- @compat.skipUnlessPlatformIs('posix') # crypt module
- def test_authenticate_des(self):
- for key in ('buildmaster','buildslave','buildbot'):
- if self.htpasswd.authenticate('des'+key, key) == False:
- self.fail("authenticate failed for '%s'" % ('des'+key))
-
- def test_authenticate_md5(self):
- if not self.htpasswd.apr:
- raise unittest.SkipTest("libaprutil-1 not found")
- for key in ('buildmaster','buildslave','buildbot'):
- if self.htpasswd.authenticate('md5'+key, key) == False:
- self.fail("authenticate failed for '%s'" % ('md5'+key))
-
- def test_authenticate_sha(self):
- if not self.htpasswd.apr:
- raise unittest.SkipTest("libaprutil-1 not found")
- for key in ('buildmaster','buildslave','buildbot'):
- if self.htpasswd.authenticate('sha'+key, key) == False:
- self.fail("authenticate failed for '%s'" % ('sha'+key))
-
- def test_authenticate_unknown(self):
- if self.htpasswd.authenticate('foo', 'bar') == True:
- self.fail("authenticate succeed for 'foo:bar'")
-
- @compat.skipUnlessPlatformIs('posix') # crypt module
- def test_authenticate_wopassword(self):
- for algo in ('des','md5','sha'):
- if self.htpasswd.authenticate(algo+'buildmaster', '') == True:
- self.fail("authenticate succeed for %s w/o password"
- % (algo+'buildmaster'))
-
- @compat.skipUnlessPlatformIs('posix') # crypt module
- def test_authenticate_wrongpassword(self):
- for algo in ('des','md5','sha'):
- if self.htpasswd.authenticate(algo+'buildmaster', algo) == True:
- self.fail("authenticate succeed for %s w/ wrong password"
- % (algo+'buildmaster'))
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_auth_HTPasswdAuth.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_auth_HTPasswdAuth.py
deleted file mode 100644
index d27dc193..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_auth_HTPasswdAuth.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# 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
-"""
-Test Passwords
-desbuildmaster:yifux5rkzvI5w
-desbuildslave:W8SPURMnCs7Tc
-desbuildbot:IzclhyfHAq6Oc
-"""
-
-
-from twisted.trial import unittest
-
-from buildbot.status.web.auth import HTPasswdAuth
-from buildbot.test.util import compat
-
-class TestHTPasswdAuth(unittest.TestCase):
-
- htpasswd = HTPasswdAuth(__file__)
-
- @compat.skipUnlessPlatformIs('posix') # crypt module
- def test_authenticate_des(self):
- for key in ('buildmaster','buildslave','buildbot'):
- if self.htpasswd.authenticate('des'+key, key) == False:
- self.fail("authenticate failed for '%s'" % ('des'+key))
-
- def test_authenticate_unknown(self):
- if self.htpasswd.authenticate('foo', 'bar') == True:
- self.fail("authenticate succeed for 'foo:bar'")
-
- @compat.skipUnlessPlatformIs('posix') # crypt module
- def test_authenticate_wopassword(self):
- for algo in ('des','md5','sha'):
- if self.htpasswd.authenticate(algo+'buildmaster', '') == True:
- self.fail("authenticate succeed for %s w/o password"
- % (algo+'buildmaster'))
-
- @compat.skipUnlessPlatformIs('posix') # crypt module
- def test_authenticate_wrongpassword(self):
- for algo in ('des','md5','sha'):
- if self.htpasswd.authenticate(algo+'buildmaster', algo) == True:
- self.fail("authenticate succeed for %s w/ wrong password"
- % (algo+'buildmaster'))
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_authz_Authz.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_authz_Authz.py
deleted file mode 100644
index a38201a2..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_authz_Authz.py
+++ /dev/null
@@ -1,227 +0,0 @@
-# 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
-
-from zope.interface import implements
-from twisted.trial import unittest
-from twisted.internet import defer
-
-from buildbot.status.web.authz import Authz
-from buildbot.status.web.auth import IAuth, AuthBase
-
-class StubRequest(object):
- # all we need from a request is username/password
- def __init__(self, username=None, passwd=None):
- self.args = {
- 'username' : [ username ],
- 'passwd' : [ passwd ],
- }
- self.received_cookies = {}
- self.send_cookies = []
- def getUser(self):
- return ''
-
- def getPassword(self):
- return None
- def addCookie(self, key, cookie, expires, path):
- self.send_cookies.append((key, cookie, expires, path))
-
-class StubHttpAuthRequest(object):
- # all we need from a request is username/password
- def __init__(self, username, passwd):
- self.args = {}
- self.username = username
- self.passwd = passwd
-
- def getUser(self):
- return self.username
-
- def getPassword(self):
- return self.passwd
-
-class StubAuth(AuthBase):
- implements(IAuth)
- def __init__(self, user):
- self.user = user
-
- def authenticate(self, user, pw):
- return user == self.user
-class TestAuthz(unittest.TestCase):
-
- def test_actionAllowed_Defaults(self):
- "by default, nothing is allowed"
- z = Authz()
- self.failedActions = []
- self.dl = []
- for a in Authz.knownActions:
- md = z.actionAllowed(a, StubRequest('foo', 'bar'))
- def check(res):
- if res:
- self.failedActions.append(a)
- return
- md.addCallback(check)
- self.dl.append(md)
- d = defer.DeferredList(self.dl)
- def check_failed(_):
- if self.failedActions:
- raise unittest.FailTest("action(s) %s do not default to False"
- % (self.failedActions,))
- d.addCallback(check_failed)
- return d
-
- def test_actionAllowed_Positive(self):
- "'True' should always permit access"
- z = Authz(forceBuild=True)
- d = z.actionAllowed('forceBuild', StubRequest('foo', 'bar'))
- def check(res):
- self.assertEqual(res, True)
- d.addCallback(check)
- return d
-
- def test_actionAllowed_AuthPositive(self):
- z = Authz(auth=StubAuth('jrobinson'),
- stopBuild='auth')
- d = z.actionAllowed('stopBuild', StubRequest('jrobinson', 'bar'))
- def check(res):
- self.assertEqual(res, True)
- d.addCallback(check)
- return d
-
- def test_actionAllowed_AuthNegative(self):
- z = Authz(auth=StubAuth('jrobinson'),
- stopBuild='auth')
- d = z.actionAllowed('stopBuild', StubRequest('apeterson', 'bar'))
- def check(res):
- self.assertEqual(res, False)
- d.addCallback(check)
- return d
-
- def test_actionAllowed_AuthCallable(self):
- myargs = []
- def myAuthzFn(*args):
- myargs.extend(args)
- z = Authz(auth=StubAuth('uu'),
- stopBuild=myAuthzFn)
- d = z.actionAllowed('stopBuild', StubRequest('uu', 'shh'), 'arg', 'arg2')
- def check(res):
- self.assertEqual(myargs, ['uu', 'arg', 'arg2'])
- d.addCallback(check)
- return d
-
- def test_actionAllowed_AuthCallableTrue(self):
- def myAuthzFn(*args):
- return True
- z = Authz(auth=StubAuth('uu'),
- stopBuild=myAuthzFn)
- d = z.actionAllowed('stopBuild', StubRequest('uu', 'shh'))
- def check(res):
- self.assertEqual(res, True)
- d.addCallback(check)
- return d
-
- def test_actionAllowed_AuthCallableFalse(self):
- def myAuthzFn(*args):
- return False
- z = Authz(auth=StubAuth('uu'),
- stopBuild=myAuthzFn)
- d = z.actionAllowed('stopBuild', StubRequest('uu', 'shh'))
- def check(res):
- self.assertEqual(res, False)
- d.addCallback(check)
- return d
-
- def test_advertiseAction_False(self):
- z = Authz(forceBuild = False)
- assert not z.advertiseAction('forceBuild',StubRequest())
-
- def test_advertiseAction_True(self):
- z = Authz(forceAllBuilds = True)
- assert z.advertiseAction('forceAllBuilds',StubRequest())
-
- def test_advertiseAction_auth(self):
- z = Authz(stopBuild = 'auth')
- assert not z.advertiseAction('stopBuild',StubRequest())
-
- def test_advertiseAction_auth_authenticated(self):
- z = Authz(auth=StubAuth('uu'),stopBuild = 'auth')
- r = StubRequest('uu','aa')
- d = z.login(r)
- def check(c):
- assert z.advertiseAction('stopBuild',r)
- d.addCallback(check)
-
- def test_advertiseAction_callable(self):
- z = Authz(auth=StubAuth('uu'), stopAllBuilds = lambda u : False)
- r = StubRequest('uu','aa')
- d = z.login(r)
- @d.addCallback
- def check(c):
- assert z.advertiseAction('stopAllBuilds',r)
- return d
-
- def test_authenticated_False(self):
- z = Authz(forceBuild = False)
- assert not z.authenticated(StubRequest())
-
- def test_authenticated_True(self):
- z = Authz(auth=StubAuth('uu'), forceBuild = True)
- r = StubRequest('uu','aa')
- d = z.login(r)
- @d.addCallback
- def check(c):
- assert z.authenticated(r)
- return d
-
- def test_authenticated_http_False(self):
- z = Authz(useHttpHeader = True)
- assert not z.authenticated(StubRequest())
-
- def test_authenticated_http_True(self):
- z = Authz(useHttpHeader = True)
- assert z.authenticated(StubHttpAuthRequest('foo', 'bar'))
-
- def test_constructor_invalidAction(self):
- self.assertRaises(ValueError, Authz, someRandomAction=3)
-
- def test_getUsername_http(self):
- z = Authz(useHttpHeader = True)
- assert z.getUsername(StubHttpAuthRequest('foo', 'bar')) == 'foo'
-
- def test_getPassword_http(self):
- z = Authz(useHttpHeader = True)
- assert z.getPassword(StubHttpAuthRequest('foo', 'bar')) == 'bar'
-
- def test_getUsername_http_missing(self):
- z = Authz(useHttpHeader = True)
- assert z.getUsername(StubRequest('foo', 'bar')) == ''
-
- def test_getPassword_http_missing(self):
- z = Authz(useHttpHeader = True)
- assert z.getPassword(StubRequest('foo', 'bar')) == None
-
- def test_getUsername_request(self):
- z = Authz()
- assert z.getUsername(StubRequest('foo', 'bar')) == 'foo'
-
- def test_getPassword_request(self):
- z = Authz()
- assert z.getPassword(StubRequest('foo', 'bar')) == 'bar'
-
- def test_advertiseAction_invalidAction(self):
- z = Authz()
- self.assertRaises(KeyError, z.advertiseAction, 'someRandomAction', StubRequest('snow', 'foo'))
-
- def test_actionAllowed_invalidAction(self):
- z = Authz()
- self.assertRaises(KeyError, z.actionAllowed, 'someRandomAction', StubRequest('snow', 'foo'))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_base.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_base.py
deleted file mode 100644
index a7d007c0..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_base.py
+++ /dev/null
@@ -1,98 +0,0 @@
-# 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 mock
-from buildbot.status.web import base
-from twisted.internet import defer
-from twisted.trial import unittest
-
-from buildbot.test.fake.web import FakeRequest
-
-class ActionResource(unittest.TestCase):
-
- def test_ActionResource_success(self):
-
- class MyActionResource(base.ActionResource):
- def performAction(self, request):
- self.got_request = request
- return defer.succeed('http://buildbot.net')
-
- rsrc = MyActionResource()
- request = FakeRequest()
- rsrc.render(request)
- d = request.deferred
-
- def check(_):
- self.assertIdentical(rsrc.got_request, request)
- self.assertTrue(request.finished)
- self.assertIn('buildbot.net', request.written)
- self.assertEqual(request.redirected_to, 'http://buildbot.net')
- d.addCallback(check)
- return d
-
- def test_ActionResource_exception(self):
-
- class MyActionResource(base.ActionResource):
- def performAction(self, request):
- return defer.fail(RuntimeError('sacrebleu'))
-
- rsrc = MyActionResource()
- request = FakeRequest()
- rsrc.render(request)
- d = request.deferred
-
- def check(f):
- f.trap(RuntimeError)
- # pass - all good!
- d.addErrback(check)
- return d
-
-class Functions(unittest.TestCase):
-
- def do_test_getRequestCharset(self, hdr, exp):
- req = mock.Mock()
- req.getHeader.return_value = hdr
-
- self.assertEqual(base.getRequestCharset(req), exp)
-
- def fakeRequest(self, prepath):
- r = mock.Mock()
- r.prepath = prepath
- return r
-
- def test_getRequestCharset_empty(self):
- return self.do_test_getRequestCharset(None, 'utf-8')
-
- def test_getRequestCharset_specified(self):
- return self.do_test_getRequestCharset(
- 'application/x-www-form-urlencoded ; charset=ISO-8859-1',
- 'ISO-8859-1')
-
- def test_getRequestCharset_other_params(self):
- return self.do_test_getRequestCharset(
- 'application/x-www-form-urlencoded ; charset=UTF-16 ; foo=bar',
- 'UTF-16')
-
- def test_path_to_root_from_root(self):
- self.assertEqual(base.path_to_root(self.fakeRequest([])),
- './')
-
- def test_path_to_root_from_one_level(self):
- self.assertEqual(base.path_to_root(self.fakeRequest(['waterfall'])),
- './')
-
- def test_path_to_root_from_two_level(self):
- self.assertEqual(base.path_to_root(self.fakeRequest(['a', 'b'])),
- '../')
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hook.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hook.py
deleted file mode 100644
index 692ee4b4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hook.py
+++ /dev/null
@@ -1,168 +0,0 @@
-# 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
-
-from buildbot.status.web import change_hook
-from buildbot.util import json
-from buildbot.test.util import compat
-from buildbot.test.fake.web import FakeRequest
-
-from twisted.trial import unittest
-
-class TestChangeHookUnconfigured(unittest.TestCase):
- def setUp(self):
- self.request = FakeRequest()
- self.changeHook = change_hook.ChangeHookResource()
-
- # A bad URI should cause an exception inside check_hook.
- # After writing the test, it became apparent this can't happen.
- # I'll leave the test anyway
- def testDialectReMatchFail(self):
- self.request.uri = "/garbage/garbage"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check(ret):
- expected = "URI doesn't match change_hook regex: /garbage/garbage"
- self.assertEqual(self.request.written, expected)
- self.request.setResponseCode.assert_called_with(400, expected)
- d.addCallback(check)
- return d
-
- def testUnkownDialect(self):
- self.request.uri = "/change_hook/garbage"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check(ret):
- expected = "The dialect specified, 'garbage', wasn't whitelisted in change_hook"
- self.assertEqual(self.request.written, expected)
- self.request.setResponseCode.assert_called_with(400, expected)
- d.addCallback(check)
- return d
-
- def testDefaultDialect(self):
- self.request.uri = "/change_hook/"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check(ret):
- expected = "The dialect specified, 'base', wasn't whitelisted in change_hook"
- self.assertEqual(self.request.written, expected)
- self.request.setResponseCode.assert_called_with(400, expected)
- d.addCallback(check)
- return d
-
-class TestChangeHookConfigured(unittest.TestCase):
- def setUp(self):
- self.request = FakeRequest()
- self.changeHook = change_hook.ChangeHookResource(dialects={'base' : True})
-
- def testDefaultDialectGetNullChange(self):
- self.request.uri = "/change_hook/"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check_changes(r):
- self.assertEquals(len(self.request.addedChanges), 1)
- change = self.request.addedChanges[0]
- self.assertEquals(change["category"], None)
- self.assertEquals(len(change["files"]), 0)
- self.assertEquals(change["repository"], None)
- self.assertEquals(change["when"], None)
- self.assertEquals(change["author"], None)
- self.assertEquals(change["revision"], None)
- self.assertEquals(change["comments"], None)
- self.assertEquals(change["project"], None)
- self.assertEquals(change["branch"], None)
- self.assertEquals(change["revlink"], None)
- self.assertEquals(len(change["properties"]), 0)
- self.assertEquals(change["revision"], None)
- d.addCallback(check_changes)
- return d
-
- # Test 'base' hook with attributes. We should get a json string representing
- # a Change object as a dictionary. All values show be set.
- def testDefaultDialectWithChange(self):
- self.request.uri = "/change_hook/"
- self.request.method = "GET"
- self.request.args = { "category" : ["mycat"],
- "files" : [json.dumps(['file1', 'file2'])],
- "repository" : ["myrepo"],
- "when" : ["1234"],
- "author" : ["Santa Claus"],
- "number" : ["2"],
- "comments" : ["a comment"],
- "project" : ["a project"],
- "at" : ["sometime"],
- "branch" : ["a branch"],
- "revlink" : ["a revlink"],
- "properties" : [json.dumps( { "prop1" : "val1", "prop2" : "val2" })],
- "revision" : ["99"] }
- d = self.request.test_render(self.changeHook)
- def check_changes(r):
- self.assertEquals(len(self.request.addedChanges), 1)
- change = self.request.addedChanges[0]
- self.assertEquals(change["category"], "mycat")
- self.assertEquals(change["repository"], "myrepo")
- self.assertEquals(change["when"], 1234)
- self.assertEquals(change["author"], "Santa Claus")
- self.assertEquals(change["src"], None)
- self.assertEquals(change["revision"], "99")
- self.assertEquals(change["comments"], "a comment")
- self.assertEquals(change["project"], "a project")
- self.assertEquals(change["branch"], "a branch")
- self.assertEquals(change["revlink"], "a revlink")
- self.assertEquals(change['properties'], dict(prop1='val1', prop2='val2'))
- self.assertEquals(change['files'], ['file1', 'file2'])
- d.addCallback(check_changes)
- return d
-
- @compat.usesFlushLoggedErrors
- def testDefaultWithNoChange(self):
- self.request = FakeRequest()
- self.request.uri = "/change_hook/"
- self.request.method = "GET"
- def namedModuleMock(name):
- if name == 'buildbot.status.web.hooks.base':
- class mock_hook_module(object):
- def getChanges(self, request, options):
- raise AssertionError
- return mock_hook_module()
- self.patch(change_hook, "namedModule", namedModuleMock)
-
- d = self.request.test_render(self.changeHook)
- def check_changes(r):
- expected = "Error processing changes."
- self.assertEquals(len(self.request.addedChanges), 0)
- self.assertEqual(self.request.written, expected)
- self.request.setResponseCode.assert_called_with(500, expected)
- self.assertEqual(len(self.flushLoggedErrors(AssertionError)), 1)
-
- d.addCallback(check_changes)
- return d
-
-class TestChangeHookConfiguredBogus(unittest.TestCase):
- def setUp(self):
- self.request = FakeRequest()
- self.changeHook = change_hook.ChangeHookResource(dialects={'garbage' : True})
-
- @compat.usesFlushLoggedErrors
- def testBogusDialect(self):
- self.request.uri = "/change_hook/garbage"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check(ret):
- expected = "Error processing changes."
- self.assertEqual(self.request.written, expected)
- self.request.setResponseCode.assert_called_with(500, expected)
- self.assertEqual(len(self.flushLoggedErrors()), 1)
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_github.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_github.py
deleted file mode 100644
index dabc5118..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_github.py
+++ /dev/null
@@ -1,205 +0,0 @@
-# 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 buildbot.status.web.change_hook as change_hook
-from buildbot.test.fake.web import FakeRequest
-from buildbot.test.util import compat
-
-from twisted.trial import unittest
-
-# Sample GITHUB commit payload from http://help.github.com/post-receive-hooks/
-# Added "modfied" and "removed", and change email
-
-gitJsonPayload = """
-{
- "before": "5aef35982fb2d34e9d9d4502f6ede1072793222d",
- "repository": {
- "url": "http://github.com/defunkt/github",
- "name": "github",
- "description": "You're lookin' at it.",
- "watchers": 5,
- "forks": 2,
- "private": 1,
- "owner": {
- "email": "fred@flinstone.org",
- "name": "defunkt"
- }
- },
- "commits": [
- {
- "id": "41a212ee83ca127e3c8cf465891ab7216a705f59",
- "url": "http://github.com/defunkt/github/commit/41a212ee83ca127e3c8cf465891ab7216a705f59",
- "author": {
- "email": "fred@flinstone.org",
- "name": "Fred Flinstone"
- },
- "message": "okay i give in",
- "timestamp": "2008-02-15T14:57:17-08:00",
- "added": ["filepath.rb"]
- },
- {
- "id": "de8251ff97ee194a289832576287d6f8ad74e3d0",
- "url": "http://github.com/defunkt/github/commit/de8251ff97ee194a289832576287d6f8ad74e3d0",
- "author": {
- "email": "fred@flinstone.org",
- "name": "Fred Flinstone"
- },
- "message": "update pricing a tad",
- "timestamp": "2008-02-15T14:36:34-08:00",
- "modified": ["modfile"],
- "removed": ["removedFile"]
- }
- ],
- "after": "de8251ff97ee194a289832576287d6f8ad74e3d0",
- "ref": "refs/heads/master"
-}
-"""
-
-gitJsonPayloadNonBranch = """
-{
- "before": "5aef35982fb2d34e9d9d4502f6ede1072793222d",
- "repository": {
- "url": "http://github.com/defunkt/github",
- "name": "github",
- "description": "You're lookin' at it.",
- "watchers": 5,
- "forks": 2,
- "private": 1,
- "owner": {
- "email": "fred@flinstone.org",
- "name": "defunkt"
- }
- },
- "commits": [
- {
- "id": "41a212ee83ca127e3c8cf465891ab7216a705f59",
- "url": "http://github.com/defunkt/github/commit/41a212ee83ca127e3c8cf465891ab7216a705f59",
- "author": {
- "email": "fred@flinstone.org",
- "name": "Fred Flinstone"
- },
- "message": "okay i give in",
- "timestamp": "2008-02-15T14:57:17-08:00",
- "added": ["filepath.rb"]
- }
- ],
- "after": "de8251ff97ee194a289832576287d6f8ad74e3d0",
- "ref": "refs/garbage/master"
-}
-"""
-
-gitJsonPayloadEmpty = """
-{
- "before": "5aef35982fb2d34e9d9d4502f6ede1072793222d",
- "repository": {
- "url": "http://github.com/defunkt/github",
- "name": "github",
- "description": "You're lookin' at it.",
- "watchers": 5,
- "forks": 2,
- "private": 1,
- "owner": {
- "email": "fred@flinstone.org",
- "name": "defunkt"
- }
- },
- "commits": [
- ],
- "after": "de8251ff97ee194a289832576287d6f8ad74e3d0",
- "ref": "refs/heads/master"
-}
-"""
-class TestChangeHookConfiguredWithGitChange(unittest.TestCase):
- def setUp(self):
- self.changeHook = change_hook.ChangeHookResource(dialects={'github' : True})
-
- # Test 'base' hook with attributes. We should get a json string representing
- # a Change object as a dictionary. All values show be set.
- def testGitWithChange(self):
- changeDict={"payload" : [gitJsonPayload]}
- self.request = FakeRequest(changeDict)
- self.request.uri = "/change_hook/github"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check_changes(r):
- self.assertEquals(len(self.request.addedChanges), 2)
- change = self.request.addedChanges[0]
-
- self.assertEquals(change['files'], ['filepath.rb'])
- self.assertEquals(change["repository"], "http://github.com/defunkt/github")
- self.assertEquals(change["when"], 1203116237)
- self.assertEquals(change["who"], "Fred Flinstone <fred@flinstone.org>")
- self.assertEquals(change["revision"], '41a212ee83ca127e3c8cf465891ab7216a705f59')
- self.assertEquals(change["comments"], "okay i give in")
- self.assertEquals(change["branch"], "master")
- self.assertEquals(change["revlink"], "http://github.com/defunkt/github/commit/41a212ee83ca127e3c8cf465891ab7216a705f59")
-
- change = self.request.addedChanges[1]
- self.assertEquals(change['files'], [ 'modfile', 'removedFile' ])
- self.assertEquals(change["repository"], "http://github.com/defunkt/github")
- self.assertEquals(change["when"], 1203114994)
- self.assertEquals(change["who"], "Fred Flinstone <fred@flinstone.org>")
- self.assertEquals(change["src"], "git")
- self.assertEquals(change["revision"], 'de8251ff97ee194a289832576287d6f8ad74e3d0')
- self.assertEquals(change["comments"], "update pricing a tad")
- self.assertEquals(change["branch"], "master")
- self.assertEquals(change["revlink"], "http://github.com/defunkt/github/commit/de8251ff97ee194a289832576287d6f8ad74e3d0")
-
- d.addCallback(check_changes)
- return d
-
- @compat.usesFlushLoggedErrors
- def testGitWithNoJson(self):
- self.request = FakeRequest()
- self.request.uri = "/change_hook/github"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check_changes(r):
- expected = "Error processing changes."
- self.assertEquals(len(self.request.addedChanges), 0)
- self.assertEqual(self.request.written, expected)
- self.request.setResponseCode.assert_called_with(500, expected)
- self.assertEqual(len(self.flushLoggedErrors()), 1)
-
- d.addCallback(check_changes)
- return d
-
- def testGitWithNoChanges(self):
- changeDict={"payload" : [gitJsonPayloadEmpty]}
- self.request = FakeRequest(changeDict)
- self.request.uri = "/change_hook/github"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check_changes(r):
- expected = "no changes found"
- self.assertEquals(len(self.request.addedChanges), 0)
- self.assertEqual(self.request.written, expected)
-
- d.addCallback(check_changes)
- return d
-
- def testGitWithNonBranchChanges(self):
- changeDict={"payload" : [gitJsonPayloadNonBranch]}
- self.request = FakeRequest(changeDict)
- self.request.uri = "/change_hook/github"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check_changes(r):
- expected = "no changes found"
- self.assertEquals(len(self.request.addedChanges), 0)
- self.assertEqual(self.request.written, expected)
-
- d.addCallback(check_changes)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_googlecode.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_googlecode.py
deleted file mode 100644
index 2eb30674..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_googlecode.py
+++ /dev/null
@@ -1,90 +0,0 @@
-# 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 2011 Louis Opter <kalessin@kalessin.fr>
-#
-# Written from the github change hook unit test
-
-import StringIO
-
-import buildbot.status.web.change_hook as change_hook
-from buildbot.test.fake.web import FakeRequest
-
-from twisted.trial import unittest
-
-# Sample Google Code commit payload extracted from a Google Code test project
-# {
-# "repository_path": "https://code.google.com/p/webhook-test/",
-# "project_name": "webhook-test",
-# "revision_count": 1,
-# "revisions": [
-# {
-# "added": [],
-# "parents": ["6574485e26a09a0e743e0745374056891d6a836a"],
-# "author": "Louis Opter \\u003Clouis@lse.epitech.net\\u003E",
-# "url": "http://webhook-test.googlecode.com/hg-history/68e5df283a8e751cdbf95516b20357b2c46f93d4/",
-# "timestamp": 1324082130,
-# "message": "Print a message",
-# "path_count": 1,
-# "removed": [],
-# "modified": ["/CMakeLists.txt"],
-# "revision": "68e5df283a8e751cdbf95516b20357b2c46f93d4"
-# }
-# ]
-# }
-googleCodeJsonBody = '{"repository_path":"https://code.google.com/p/webhook-test/","project_name":"webhook-test","revisions":[{"added":[],"parents":["6574485e26a09a0e743e0745374056891d6a836a"],"author":"Louis Opter \u003Clouis@lse.epitech.net\u003E","url":"http://webhook-test.googlecode.com/hg-history/68e5df283a8e751cdbf95516b20357b2c46f93d4/","timestamp":1324082130,"message":"Print a message","path_count":1,"removed":[],"modified":["/CMakeLists.txt"],"revision":"68e5df283a8e751cdbf95516b20357b2c46f93d4"}],"revision_count":1}'
-
-class TestChangeHookConfiguredWithGoogleCodeChange(unittest.TestCase):
- def setUp(self):
- self.request = FakeRequest()
- # Google Code simply transmit the payload as an UTF-8 JSON body
- self.request.content = StringIO.StringIO(googleCodeJsonBody)
- self.request.received_headers = {
- 'Google-Code-Project-Hosting-Hook-Hmac': '85910bf93ba5c266402d9328b0c7a856',
- 'Content-Length': '509',
- 'Accept-Encoding': 'gzip',
- 'User-Agent': 'Google Code Project Hosting (+http://code.google.com/p/support/wiki/PostCommitWebHooks)',
- 'Host': 'buildbot6-lopter.dotcloud.com:19457',
- 'Content-Type': 'application/json; charset=UTF-8'
- }
-
- self.changeHook = change_hook.ChangeHookResource(dialects={
- 'googlecode': {
- 'secret_key': 'FSP3p-Ghdn4T0oqX',
- 'branch': 'test'
- }
- })
-
- # Test 'base' hook with attributes. We should get a json string representing
- # a Change object as a dictionary. All values show be set.
- def testGoogleCodeWithHgChange(self):
- self.request.uri = "/change_hook/googlecode"
- self.request.method = "GET"
- d = self.request.test_render(self.changeHook)
- def check_changes(r):
- # Only one changeset has been submitted.
- self.assertEquals(len(self.request.addedChanges), 1)
-
- # First changeset.
- change = self.request.addedChanges[0]
- self.assertEquals(change['files'], ['/CMakeLists.txt'])
- self.assertEquals(change["repository"], "https://code.google.com/p/webhook-test/")
- self.assertEquals(change["when"], 1324082130)
- self.assertEquals(change["author"], "Louis Opter <louis@lse.epitech.net>")
- self.assertEquals(change["revision"], '68e5df283a8e751cdbf95516b20357b2c46f93d4')
- self.assertEquals(change["comments"], "Print a message")
- self.assertEquals(change["branch"], "test")
- self.assertEquals(change["revlink"], "http://webhook-test.googlecode.com/hg-history/68e5df283a8e751cdbf95516b20357b2c46f93d4/")
-
- d.addCallback(check_changes)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_poller.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_poller.py
deleted file mode 100644
index fca1b66e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_change_hooks_poller.py
+++ /dev/null
@@ -1,107 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.changes import base
-import buildbot.status.web.change_hook as change_hook
-from buildbot.test.fake.web import FakeRequest
-from buildbot.changes.manager import ChangeManager
-
-
-class TestPollingChangeHook(unittest.TestCase):
- class Subclass(base.PollingChangeSource):
- pollInterval = None
- called = False
-
- def poll(self):
- self.called = True
-
- def setUpRequest(self, args, options=True):
- self.changeHook = change_hook.ChangeHookResource(dialects={'poller' : options})
-
- self.request = FakeRequest(args=args)
- self.request.uri = "/change_hook/poller"
- self.request.method = "GET"
-
- master = self.request.site.buildbot_service.master
- master.change_svc = ChangeManager(master)
-
- self.changesrc = self.Subclass("example", None)
- self.changesrc.setServiceParent(master.change_svc)
-
- self.disabledChangesrc = self.Subclass("disabled", None)
- self.disabledChangesrc.setServiceParent(master.change_svc)
-
- anotherchangesrc = base.ChangeSource()
- anotherchangesrc.setName("notapoller")
- anotherchangesrc.setServiceParent(master.change_svc)
-
- return self.request.test_render(self.changeHook)
-
- @defer.inlineCallbacks
- def test_no_args(self):
- yield self.setUpRequest({})
- self.assertEqual(self.request.written, "no changes found")
- self.assertEqual(self.changesrc.called, True)
- self.assertEqual(self.disabledChangesrc.called, True)
-
- @defer.inlineCallbacks
- def test_no_poller(self):
- yield self.setUpRequest({"poller": ["nosuchpoller"]})
- expected = "Could not find pollers: nosuchpoller"
- self.assertEqual(self.request.written, expected)
- self.request.setResponseCode.assert_called_with(400, expected)
- self.assertEqual(self.changesrc.called, False)
- self.assertEqual(self.disabledChangesrc.called, False)
-
- @defer.inlineCallbacks
- def test_invalid_poller(self):
- yield self.setUpRequest({"poller": ["notapoller"]})
- expected = "Could not find pollers: notapoller"
- self.assertEqual(self.request.written, expected)
- self.request.setResponseCode.assert_called_with(400, expected)
- self.assertEqual(self.changesrc.called, False)
- self.assertEqual(self.disabledChangesrc.called, False)
-
- @defer.inlineCallbacks
- def test_trigger_poll(self):
- yield self.setUpRequest({"poller": ["example"]})
- self.assertEqual(self.request.written, "no changes found")
- self.assertEqual(self.changesrc.called, True)
- self.assertEqual(self.disabledChangesrc.called, False)
-
- @defer.inlineCallbacks
- def test_allowlist_deny(self):
- yield self.setUpRequest({"poller": ["disabled"]}, options={"allowed": ["example"]})
- expected = "Could not find pollers: disabled"
- self.assertEqual(self.request.written, expected)
- self.request.setResponseCode.assert_called_with(400, expected)
- self.assertEqual(self.changesrc.called, False)
- self.assertEqual(self.disabledChangesrc.called, False)
-
- @defer.inlineCallbacks
- def test_allowlist_allow(self):
- yield self.setUpRequest({"poller": ["example"]}, options={"allowed": ["example"]})
- self.assertEqual(self.request.written, "no changes found")
- self.assertEqual(self.changesrc.called, True)
- self.assertEqual(self.disabledChangesrc.called, False)
-
- @defer.inlineCallbacks
- def test_allowlist_all(self):
- yield self.setUpRequest({}, options={"allowed": ["example"]})
- self.assertEqual(self.request.written, "no changes found")
- self.assertEqual(self.changesrc.called, True)
- self.assertEqual(self.disabledChangesrc.called, False)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_links.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_links.py
deleted file mode 100644
index 4abe1573..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_web_links.py
+++ /dev/null
@@ -1,239 +0,0 @@
-# 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 buildbot.status.web.base as wb
-import jinja2, re
-
-from twisted.trial import unittest
-
-class RevisionLinks(unittest.TestCase):
- """
- Test webstatus revision link filters
- """
-
- def setUp(self):
- pass
-
- def _test(self, env, should_have_links=True):
- for name in ['shortrev', 'revlink']:
- f = env.filters[name]
- for r in [None, 'repo', 'repo2', 'sub/repo']:
- self.assertNotSubstring('<a', f(None, r), 'repo: %s' % r)
- if should_have_links:
- self.assertSubstring('<a', f(1234, r), 'repo: %s' % r)
- self.assertSubstring('<a', f('deadbeef1234', r), 'repo: %s' % r)
- else:
- self.assertNotSubstring('<a', f(1234, r), 'repo: %s' % r)
- self.assertNotSubstring('<a', f('deadbeef1234', r), 'repo: %s' % r)
-
- def test_default(self):
- env = wb.createJinjaEnv()
- self._test(env, False)
-
- def test_format(self):
- env = wb.createJinjaEnv('http://myserver.net/repo/%s')
- self._test(env)
-
- def test_dict(self):
- env = wb.createJinjaEnv({None: 'http://default.net/repo/%s',
- 'repo': 'http://myserver.net/repo/%s',
- 'repo2': 'http://myserver2.net/repo/%s',
- 'sub/repo': 'http://otherserver.com/%s'})
- self._test(env)
-
- def test_callable(self):
- def my_revlink(rev, repo):
- import urllib
- if not rev:
- return None
- if not repo:
- repo = 'main'
- rev = urllib.quote(rev)
- repo = urllib.quote(repo)
- return 'http://myserver.net/repos/%s/rev/%s' % (repo, rev)
-
- env = wb.createJinjaEnv(my_revlink)
- self._test(env)
-
-
- def test_template(self):
- template_str = '''{{ rev|revlink('repo') }} - {{ rev|shortrev('repo') }}'''
- env = wb.createJinjaEnv(revlink='http://myserver.net/repo/%s')
- template = env.from_string(template_str)
-
- rev = '1234567890' * 4 # reasonably long
- html = template.render(rev=rev)
- self.assertSubstring('http://myserver.net/repo/%s' % rev, html)
- self.assertSubstring('...', html) # did it get shortened?
- self.assertEquals(html.count('<a'), 3) # one in revlink, two in shortrev
-
-
-class ChangeCommentLinks(unittest.TestCase):
- """
- Tests webstatus changecomment link filter
- """
-
- def setUp(self):
- pass
-
- def _test(self, env):
- f = env.filters['changecomment']
- for p in [None, 'project1', 'project2']:
- self.assertNotSubstring('<a', f('', p))
- self.assertNotSubstring('<a', f('There is no ticket...', p))
- self.assertSubstring('<a', f('There is a ticket #123', p))
- self.assertEquals(f('There are two tickets #123 and #456', p).count("<a"), 2)
-
-
- def test_default(self):
- env = wb.createJinjaEnv()
- f = env.filters['changecomment']
- self.assertNotSubstring('<a', f(None, ''))
- self.assertNotSubstring('<a', f(None, 'There is no ticket #123'))
- self.assertNotSubstring('<a', f('project', ''))
- self.assertNotSubstring('<a', f('project', 'There is no ticket #123'))
-
- def test_tuple2(self):
- env = wb.createJinjaEnv(
- changecommentlink=(r'#(\d+)', r'http://buildbot.net/trac/ticket/\1'))
- self._test(env)
-
- def test_tuple3(self):
- env = wb.createJinjaEnv(
- changecommentlink=(r'#(\d+)', r'http://buildbot.net/trac/ticket/\1',
- r'Ticket #\1'))
- self._test(env)
-
- def test_dict_2tuple(self):
- env = wb.createJinjaEnv(
- changecommentlink={
- None: (r'#(\d+)', r'http://server/trac/ticket/\1'),
- 'project1': (r'#(\d+)', r'http://server/trac/p1/ticket/\1'),
- 'project2': (r'#(\d+)', r'http://server/trac/p2/ticket/\1')
- })
- self._test(env)
-
- f = env.filters['changecomment']
- self.assertNotSubstring('<a', f('fixed #123', 'nonexistingproject'))
-
-
- def test_dict_3tuple(self):
- env = wb.createJinjaEnv(
- changecommentlink={
- None: (r'#(\d+)', r'http://server/trac/ticket/\1', r'Ticket #\1'),
- 'project1': (r'#(\d+)', r'http://server/trac/p1/ticket/\1', r'Ticket #\1'),
- 'project2': (r'#(\d+)', r'http://server/bugzilla/p2/ticket/\1', r'Bug #\1')
- })
- self._test(env)
-
- f = env.filters['changecomment']
- self.assertNotSubstring('<a', f('fixed #123', 'nonexistingproject'))
-
- def test_callable(self):
- r1 = re.compile(r'#(\d+)')
- r2 = re.compile(r'bug ([a-eA-E0-9]+)')
-
- r1_sub = jinja2.Markup(r'<a href="\1" title="Ticket #\1">\g<0></a>')
- r2_sub = jinja2.Markup(r'<a href="\1" title="Bug \1"><img src="\bug.png">\g<0></a>')
-
- def my_changelink(changehtml, project):
- if project == 'nonexistingproject':
- return changehtml
-
- html1 = r1.sub(r1_sub, changehtml)
- html2 = r2.sub(r2_sub, html1)
- return html2
-
- env = wb.createJinjaEnv(changecommentlink=my_changelink)
- self._test(env)
-
- f = env.filters['changecomment']
- self.assertNotSubstring('<a', f('fixed #123', 'nonexistingproject'))
-
-
-class DictLinkfilter(unittest.TestCase):
- '''test the dictlink filter used for top-level links to
- projects and repostiories'''
-
- def test_default(self):
- f = wb.dictlinkfilter(None)
-
- self.assertNotSubstring('<a', f(None))
- self.assertNotSubstring('<a', f('repo'))
- self.assertNotSubstring('<a', f('repo2'))
-
- def test_simple(self):
- f = wb.dictlinkfilter({'repo': 'http://myrepo.net'})
-
- self.assertNotSubstring('<a', f(None))
- self.assertSubstring('<a', f('repo'))
- self.assertNotSubstring('<a', f('repo2'))
- self.assertEquals(f('bah'), 'bah') # passthrough
-
- def test_callable(self):
- def my_dictlink(value):
- if len(value) == 0:
- return 'http://thevoid.net'
- if len(value) == 1:
- return 'http://highlander.net'
- if value == 'hiddenproject':
- return None
- else:
- return 'http://legion.net'
-
- f = wb.dictlinkfilter(my_dictlink)
- self.assertSubstring('thevoid', f(''))
- self.assertSubstring('highlander', f('X'))
- self.assertSubstring('legion', f('many'))
- self.assertSubstring('<a', f('many'))
- self.assertNotSubstring('<a', f('hiddenproject'))
-
-
- def test_jinjaenv(self):
- env = wb.createJinjaEnv(repositories={'a': 'http://a.net'},
- projects={'b': 'http://b.net'})
-
- self.assertSubstring('<a href="http://a.net">', env.filters['repolink']('a'))
- self.assertSubstring('<a href="http://b.net">', env.filters['projectlink']('b'))
-
-
-class EmailFilter(unittest.TestCase):
- ''' test that the email filter actually obfuscates email addresses'''
-
- def test_emailfilter(self):
- self.assertNotSubstring('me@the.net', wb.emailfilter('me@the.net'))
- self.assertSubstring('me', wb.emailfilter('me@the.net'))
- self.assertSubstring('@', wb.emailfilter('me@the.net'))
- self.assertSubstring('the.net', wb.emailfilter('me@the.net'))
-
-
-
-class UserFilter(unittest.TestCase):
- '''test commit user names filtering, should be safe from complete
- email addresses and split user/email into separate HTML instances'''
-
- def test_emailfilter(self):
- self.assertNotSubstring('me@the.net', wb.userfilter('me@the.net'))
- self.assertNotSubstring('me@the.net', wb.userfilter('Me <me@the.net>'))
-
- def test_emailfilter_split(self):
- self.assertNotSubstring('Me <me', wb.userfilter('Me <me@the.net>'))
- self.assertSubstring('me', wb.userfilter('Me <me@the.net>'))
- self.assertSubstring('the.net', wb.userfilter('Me <me@the.net>'))
- self.assertSubstring('John Doe', wb.userfilter('John Doe <me@the.net>'))
-
-
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_words.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_words.py
deleted file mode 100644
index d1300ac5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_status_words.py
+++ /dev/null
@@ -1,617 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-from twisted.application import internet
-from twisted.internet import task, reactor
-from buildbot.status import words
-from buildbot.test.util import compat, config
-
-class TestIrcContactChannel(unittest.TestCase):
-
- def setUp(self):
- self.bot = mock.Mock(name='IRCStatusBot-instance')
- self.bot.nickname = 'nick'
- self.bot.notify_events = { 'success' : 1, 'failure' : 1 }
-
- # fake out subscription/unsubscription
- self.subscribed = False
- def subscribe(contact):
- self.subscribed = True
- self.bot.status.subscribe = subscribe
- def unsubscribe(contact):
- self.subscribed = False
- self.bot.status.unsubscribe = unsubscribe
-
- # fake out clean shutdown
- self.bot.master = mock.Mock(name='IRCStatusBot-instance.master')
- self.bot.master.botmaster = mock.Mock(name='IRCStatusBot-instance.master.botmaster')
- self.bot.master.botmaster.shuttingDown = False
- def cleanShutdown():
- self.bot.master.botmaster.shuttingDown = True
- self.bot.master.botmaster.cleanShutdown = cleanShutdown
- def cancelCleanShutdown():
- self.bot.master.botmaster.shuttingDown = False
- self.bot.master.botmaster.cancelCleanShutdown = cancelCleanShutdown
-
- self.contact = words.IRCContact(self.bot, '#buildbot')
-
- def patch_send(self):
- self.sent = []
- def send(msg):
- self.sent.append(msg)
- self.contact.send = send
-
- def patch_act(self):
- self.actions = []
- def act(msg):
- self.actions.append(msg)
- self.contact.act = act
-
- def do_test_command(self, command, args='', who='me', clock_ticks=None,
- exp_usage=True, exp_UsageError=False, allowShutdown=False,
- shuttingDown=False):
- cmd = getattr(self.contact, 'command_' + command.upper())
-
- if exp_usage:
- self.assertTrue(hasattr(cmd, 'usage'))
-
- clock = task.Clock()
- self.patch(reactor, 'callLater', clock.callLater)
- self.patch_send()
- self.patch_act()
- self.bot.factory.allowShutdown = allowShutdown
- self.bot.master.botmaster.shuttingDown = shuttingDown
-
- if exp_UsageError:
- try:
- cmd(args, who)
- except words.UsageError:
- return
- else:
- self.fail("no UsageError")
- else:
- cmd(args, who)
- if clock_ticks:
- clock.pump(clock_ticks)
-
- # tests
-
- def test_doSilly(self):
- clock = task.Clock()
- self.patch(reactor, 'callLater', clock.callLater)
- self.patch_send()
- silly_prompt, silly_response = self.contact.silly.items()[0]
-
- self.contact.doSilly(silly_prompt)
- clock.pump([0.5] * 20)
-
- self.assertEqual(self.sent, silly_response)
-
- # TODO: remaining commands
- # (all depend on status, which interface will change soon)
-
- def test_command_mute(self):
- self.do_test_command('mute')
- self.assertTrue(self.contact.muted)
-
- def test_command_unmute(self):
- self.contact.muted = True
- self.do_test_command('unmute')
- self.assertFalse(self.contact.muted)
-
- def test_command_unmute_not_muted(self):
- self.do_test_command('unmute')
- self.assertFalse(self.contact.muted)
- self.assertIn("hadn't told me to be quiet", self.sent[0])
-
- def test_command_help_noargs(self):
- self.do_test_command('help')
- self.assertIn('help on what', self.sent[0])
-
- def test_command_help_arg(self):
- self.contact.command_FOO = lambda : None
- self.contact.command_FOO.usage = 'foo - bar'
- self.do_test_command('help', args='foo')
- self.assertIn('Usage: foo - bar', self.sent[0])
-
- def test_command_help_no_usage(self):
- self.contact.command_FOO = lambda : None
- self.do_test_command('help', args='foo')
- self.assertIn('No usage info for', self.sent[0])
-
- def test_command_help_dict_command(self):
- self.contact.command_FOO = lambda : None
- self.contact.command_FOO.usage = {
- None : 'foo - bar'
- }
- self.do_test_command('help', args='foo')
- self.assertIn('Usage: foo - bar', self.sent[0])
-
- def test_command_help_dict_command_no_usage(self):
- self.contact.command_FOO = lambda : None
- self.contact.command_FOO.usage = {}
- self.do_test_command('help', args='foo')
- self.assertIn("No usage info for 'foo'", self.sent[0])
-
- def test_command_help_dict_command_arg(self):
- self.contact.command_FOO = lambda : None
- self.contact.command_FOO.usage = {
- 'this' : 'foo this - bar'
- }
- self.do_test_command('help', args='foo this')
- self.assertIn('Usage: foo this - bar', self.sent[0])
-
- def test_command_help_dict_command_arg_no_usage(self):
- self.contact.command_FOO = lambda : None
- self.contact.command_FOO.usage = {
- # nothing for arg 'this'
- ('this', 'first') : 'foo this first - bar'
- }
- self.do_test_command('help', args='foo this')
- self.assertIn("No usage info for 'foo' 'this'", self.sent[0])
-
- def test_command_help_dict_command_arg_subarg(self):
- self.contact.command_FOO = lambda : None
- self.contact.command_FOO.usage = {
- ('this', 'first') : 'foo this first - bar'
- }
- self.do_test_command('help', args='foo this first')
- self.assertIn('Usage: foo this first - bar', self.sent[0])
-
- def test_command_help_dict_command_arg_subarg_no_usage(self):
- self.contact.command_FOO = lambda : None
- self.contact.command_FOO.usage = {
- None : 'foo - bar',
- 'this' : 'foo this - bar',
- ('this', 'first') : 'foo this first - bar'
- # nothing for subarg 'missing'
- }
- self.do_test_command('help', args='foo this missing')
- self.assertIn("No usage info for 'foo' 'this' 'missing'", self.sent[0])
-
- def test_command_help_nosuch(self):
- self.do_test_command('help', args='foo', exp_UsageError=True)
-
- def test_command_shutdown(self):
- self.do_test_command('shutdown', exp_UsageError=True)
- self.assertEqual(self.bot.factory.allowShutdown, False)
- self.assertEqual(self.bot.master.botmaster.shuttingDown, False)
-
- def test_command_shutdown_dissalowed(self):
- self.do_test_command('shutdown', args='check', exp_UsageError=True)
- self.assertEqual(self.bot.factory.allowShutdown, False)
- self.assertEqual(self.bot.master.botmaster.shuttingDown, False)
-
- def test_command_shutdown_check_running(self):
- self.do_test_command('shutdown', args='check', allowShutdown=True, shuttingDown=False)
- self.assertEqual(self.bot.factory.allowShutdown, True)
- self.assertEqual(self.bot.master.botmaster.shuttingDown, False)
- self.assertIn('buildbot is running', self.sent[0])
-
- def test_command_shutdown_check_shutting_down(self):
- self.do_test_command('shutdown', args='check', allowShutdown=True, shuttingDown=True)
- self.assertEqual(self.bot.factory.allowShutdown, True)
- self.assertEqual(self.bot.master.botmaster.shuttingDown, True)
- self.assertIn('buildbot is shutting down', self.sent[0])
-
- def test_command_shutdown_start(self):
- self.do_test_command('shutdown', args='start', allowShutdown=True, shuttingDown=False)
- self.assertEqual(self.bot.factory.allowShutdown, True)
- self.assertEqual(self.bot.master.botmaster.shuttingDown, True)
-
- def test_command_shutdown_stop(self):
- self.do_test_command('shutdown', args='stop', allowShutdown=True, shuttingDown=True)
- self.assertEqual(self.bot.factory.allowShutdown, True)
- self.assertEqual(self.bot.master.botmaster.shuttingDown, False)
-
- def test_command_shutdown_now(self):
- stop = mock.Mock()
- self.patch(reactor, 'stop', stop)
- self.do_test_command('shutdown', args='now', allowShutdown=True)
- self.assertEqual(self.bot.factory.allowShutdown, True)
- self.assertEqual(self.bot.master.botmaster.shuttingDown, False)
- stop.assert_called_with()
-
- def test_command_source(self):
- self.do_test_command('source')
- self.assertIn('My source', self.sent[0])
-
- def test_command_commands(self):
- self.do_test_command('commands')
- self.assertIn('buildbot commands', self.sent[0])
-
- def test_command_destroy(self):
- self.do_test_command('destroy', exp_usage=False)
- self.assertEqual(self.actions, [ 'readies phasers' ])
-
- def test_command_dance(self):
- self.do_test_command('dance', clock_ticks=[1.0]*10, exp_usage=False)
- self.assertTrue(self.sent) # doesn't matter what it sent
-
- def test_send(self):
- events = []
- def msgOrNotice(dest, msg):
- events.append((dest, msg))
- self.contact.bot.msgOrNotice = msgOrNotice
-
- self.contact.send("unmuted")
- self.contact.send(u"unmuted, unicode \N{SNOWMAN}")
- self.contact.muted = True
- self.contact.send("muted")
-
- self.assertEqual(events, [
- ('#buildbot', 'unmuted'),
- ('#buildbot', 'unmuted, unicode ?'),
- ])
-
- def test_act(self):
- events = []
- def describe(dest, msg):
- events.append((dest, msg))
- self.contact.bot.describe = describe
-
- self.contact.act("unmuted")
- self.contact.act(u"unmuted, unicode \N{SNOWMAN}")
- self.contact.muted = True
- self.contact.act("muted")
-
- self.assertEqual(events, [
- ('#buildbot', 'unmuted'),
- ('#buildbot', 'unmuted, unicode ?'),
- ])
-
- def test_handleMessage_silly(self):
- silly_prompt = self.contact.silly.keys()[0]
- self.contact.doSilly = mock.Mock()
- d = self.contact.handleMessage(silly_prompt, 'me')
- @d.addCallback
- def cb(_):
- self.contact.doSilly.assert_called_with(silly_prompt)
- return d
-
- def test_handleMessage_short_command(self):
- self.contact.command_TESTY = mock.Mock()
- d = self.contact.handleMessage('testy', 'me')
- @d.addCallback
- def cb(_):
- self.contact.command_TESTY.assert_called_with('', 'me')
- return d
-
- def test_handleMessage_long_command(self):
- self.contact.command_TESTY = mock.Mock()
- d = self.contact.handleMessage('testy westy boo', 'me')
- @d.addCallback
- def cb(_):
- self.contact.command_TESTY.assert_called_with('westy boo', 'me')
- return d
-
- def test_handleMessage_excited(self):
- self.patch_send()
- d = self.contact.handleMessage('hi!', 'me')
- @d.addCallback
- def cb(_):
- self.assertEqual(len(self.sent), 1) # who cares what it says..
- return d
-
- @compat.usesFlushLoggedErrors
- def test_handleMessage_exception(self):
- self.patch_send()
- def command_TESTY(msg, who):
- raise RuntimeError("FAIL")
- self.contact.command_TESTY = command_TESTY
- d = self.contact.handleMessage('testy boom', 'me')
- @d.addCallback
- def cb(_):
- self.assertEqual(self.sent,
- [ "Something bad happened (see logs)" ])
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
- return d
-
- def test_handleMessage_UsageError(self):
- self.patch_send()
- def command_TESTY(msg, who):
- raise words.UsageError("oh noes")
- self.contact.command_TESTY = command_TESTY
- d = self.contact.handleMessage('testy boom', 'me')
- @d.addCallback
- def cb(_):
- self.assertEqual(self.sent, [ "oh noes" ])
- return d
-
- def test_handleAction_ignored(self):
- self.patch_act()
- self.contact.handleAction('waves hi', 'me')
- self.assertEqual(self.actions, [])
-
- def test_handleAction_kick(self):
- self.patch_act()
- self.contact.handleAction('kicks nick', 'me')
- self.assertEqual(self.actions, ['kicks back'])
-
- def test_handleAction_stpuid(self):
- self.patch_act()
- self.contact.handleAction('stupids nick', 'me')
- self.assertEqual(self.actions, ['stupids me too'])
-
- def test_unclosed_quote(self):
- self.do_test_command('list', args='args\'', exp_UsageError=True)
- self.do_test_command('status', args='args\'', exp_UsageError=True)
- self.do_test_command('notify', args='args\'', exp_UsageError=True)
- self.do_test_command('watch', args='args\'', exp_UsageError=True)
- self.do_test_command('force', args='args\'', exp_UsageError=True)
- self.do_test_command('stop', args='args\'', exp_UsageError=True)
- self.do_test_command('last', args='args\'', exp_UsageError=True)
- self.do_test_command('help', args='args\'', exp_UsageError=True)
-
-
-class FakeContact(object):
-
- def __init__(self, bot, name):
- self.bot = bot
- self.name = name
- self.messages = []
- self.actions = []
-
- def handleMessage(self, message, user):
- self.messages.append((message, user))
-
- def handleAction(self, data, user):
- self.actions.append((data, user))
-
-
-class TestIrcStatusBot(unittest.TestCase):
-
- def setUp(self):
- self.status = mock.Mock(name='status')
-
- def makeBot(self, *args, **kwargs):
- if not args:
- args = ('nick', 'pass', ['#ch'], [], self.status, [], {})
- return words.IrcStatusBot(*args, **kwargs)
-
- def test_msgOrNotice(self):
- b = self.makeBot(noticeOnChannel=False)
- b.notice = lambda d, m : evts.append(('n', d, m))
- b.msg = lambda d, m : evts.append(('m', d, m))
-
- evts = []
- b.msgOrNotice('nick', 'hi')
- self.assertEqual(evts, [('m', 'nick', 'hi')])
-
- evts = []
- b.msgOrNotice('#chan', 'hi')
- self.assertEqual(evts, [('m', '#chan', 'hi')])
-
- b.noticeOnChannel = True
-
- evts = []
- b.msgOrNotice('#chan', 'hi')
- self.assertEqual(evts, [('n', '#chan', 'hi')])
-
- def test_getContact(self):
- b = self.makeBot()
-
- c1 = b.getContact('c1')
- c2 = b.getContact('c2')
- c1b = b.getContact('c1')
-
- self.assertIdentical(c1, c1b)
- self.assertIsInstance(c2, words.IRCContact)
-
- def test_getContact_case_insensitive(self):
- b = self.makeBot()
-
- c1 = b.getContact('c1')
- c1b = b.getContact('C1')
-
- self.assertIdentical(c1, c1b)
-
- def test_privmsg_user(self):
- b = self.makeBot()
- b.contactClass = FakeContact
- b.privmsg('jimmy!~foo@bar', 'nick', 'hello')
-
- c = b.getContact('jimmy')
- self.assertEqual(c.messages, [('hello', 'jimmy')])
-
- def test_privmsg_user_uppercase(self):
- b = self.makeBot('NICK', 'pass', ['#ch'], [], self.status, [], {})
- b.contactClass = FakeContact
- b.privmsg('jimmy!~foo@bar', 'NICK', 'hello')
-
- c = b.getContact('jimmy')
- self.assertEqual(c.messages, [('hello', 'jimmy')])
-
- def test_privmsg_channel_unrelated(self):
- b = self.makeBot()
- b.contactClass = FakeContact
- b.privmsg('jimmy!~foo@bar', '#ch', 'hello')
-
- c = b.getContact('#ch')
- self.assertEqual(c.messages, [])
-
- def test_privmsg_channel_related(self):
- b = self.makeBot()
- b.contactClass = FakeContact
- b.privmsg('jimmy!~foo@bar', '#ch', 'nick: hello')
-
- c = b.getContact('#ch')
- self.assertEqual(c.messages, [(' hello', 'jimmy')])
-
- def test_action_unrelated(self):
- b = self.makeBot()
- b.contactClass = FakeContact
- b.action('jimmy!~foo@bar', '#ch', 'waves')
-
- c = b.getContact('#ch')
- self.assertEqual(c.actions, [])
-
- def test_action_unrelated_buildbot(self):
- b = self.makeBot()
- b.contactClass = FakeContact
- b.action('jimmy!~foo@bar', '#ch', 'waves at buildbot')# b.nickname is not 'buildbot'
-
- c = b.getContact('#ch')
- self.assertEqual(c.actions, [])
-
- def test_action_related(self):
- b = self.makeBot()
- b.contactClass = FakeContact
- b.action('jimmy!~foo@bar', '#ch', 'waves at nick')
-
- c = b.getContact('#ch')
- self.assertEqual(c.actions, [('waves at nick', 'jimmy')])
-
- def test_signedOn(self):
- b = self.makeBot('nick', 'pass',
- ['#ch1', dict(channel='#ch2', password='sekrits')],
- ['jimmy', 'bobby'], self.status, [], {})
- evts = []
- def msg(d, m):
- evts.append(('m', d, m))
- b.msg = msg
- def join(channel, key):
- evts.append(('k', channel, key))
- b.join = join
- b.contactClass = FakeContact
-
- b.signedOn()
-
- self.assertEqual(sorted(evts), [
- ('k', '#ch1', None),
- ('k', '#ch2', 'sekrits'),
- ('m', 'Nickserv', 'IDENTIFY pass'),
- ])
- self.assertEqual(sorted(b.contacts.keys()),
- # channels don't get added until joined() is called
- sorted(['jimmy', 'bobby']))
-
- def test_joined(self):
- b = self.makeBot()
- b.joined('#ch1')
- b.joined('#ch2')
- self.assertEqual(sorted(b.contacts.keys()),
- sorted(['#ch1', '#ch2']))
-
- def test_other(self):
- # these methods just log, but let's get them covered anyway
- b = self.makeBot()
- b.left('#ch1')
- b.kickedFrom('#ch1', 'dustin', 'go away!')
-
-
-class TestIrcStatusFactory(unittest.TestCase):
-
- def makeFactory(self, *args, **kwargs):
- if not args:
- args = ('nick', 'pass', ['ch'], [], [], {})
- return words.IrcStatusFactory(*args, **kwargs)
-
- def test_shutdown(self):
- # this is kinda lame, but the factory would be better tested
- # in an integration-test environment
- f = self.makeFactory()
- self.assertFalse(f.shuttingDown)
- f.shutdown()
- self.assertTrue(f.shuttingDown)
-
-
-class TestIRC(config.ConfigErrorsMixin, unittest.TestCase):
-
- def makeIRC(self, **kwargs):
- kwargs.setdefault('host', 'localhost')
- kwargs.setdefault('nick', 'russo')
- kwargs.setdefault('channels', ['#buildbot'])
- self.factory = None
- def TCPClient(host, port, factory):
- client = mock.Mock(name='tcp-client')
- client.host = host
- client.port = port
- client.factory = factory
- # keep for later
- self.factory = factory
- self.client = client
- return client
- self.patch(internet, 'TCPClient', TCPClient)
- return words.IRC(**kwargs)
-
- def test_constr(self):
- irc = self.makeIRC(host='foo', port=123)
- self.client.setServiceParent.assert_called_with(irc)
- self.assertEqual(self.client.host, 'foo')
- self.assertEqual(self.client.port, 123)
- self.assertIsInstance(self.client.factory, words.IrcStatusFactory)
-
- def test_constr_args(self):
- # test that the args to IRC(..) make it all the way down to
- # the IrcStatusBot class
- self.makeIRC(
- host='host',
- nick='nick',
- channels=['channels'],
- pm_to_nicks=['pm', 'to', 'nicks'],
- port=1234,
- allowForce=True,
- categories=['categories'],
- password='pass',
- notify_events={ 'successToFailure': 1, },
- noticeOnChannel=True,
- showBlameList=False,
- useRevisions=True,
- useSSL=False,
- lostDelay=10,
- failedDelay=20,
- useColors=False)
-
- # patch it up
- factory = self.factory
- proto_obj = mock.Mock(name='proto_obj')
- factory.protocol = mock.Mock(name='protocol', return_value=proto_obj)
- factory.status = 'STATUS'
-
- # run it
- p = factory.buildProtocol('address')
- self.assertIdentical(p, proto_obj)
- factory.protocol.assert_called_with(
- 'nick', 'pass', ['channels'], ['pm', 'to', 'nicks'],
- factory.status, ['categories'], { 'successToFailure': 1 },
- noticeOnChannel=True,
- useColors=False,
- useRevisions=True,
- showBlameList=False)
-
- def test_allowForce_notBool(self):
- """
- When L{IRCClient} is called with C{allowForce} not a boolean,
- a config error is reported.
- """
- self.assertRaisesConfigError("allowForce must be boolean, not",
- lambda: self.makeIRC(allowForce=object()))
-
- def test_allowShutdown_notBool(self):
- """
- When L{IRCClient} is called with C{allowShutdown} not a boolean,
- a config error is reported.
- """
- self.assertRaisesConfigError("allowShutdown must be boolean, not",
- lambda: self.makeIRC(allowShutdown=object()))
-
- def test_service(self):
- irc = self.makeIRC()
- # just put it through its paces
- irc.startService()
- return irc.stopService()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_master.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_master.py
deleted file mode 100644
index 5b5ce6b8..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_master.py
+++ /dev/null
@@ -1,229 +0,0 @@
-# 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 os
-import sys
-from twisted.python import failure, runtime
-from twisted.internet import error, reactor
-from twisted.trial import unittest
-from buildbot.test.util import steps
-from buildbot.status.results import SUCCESS, FAILURE, EXCEPTION
-from buildbot.steps import master
-from buildbot.process.properties import WithProperties
-from buildbot.process.properties import Interpolate
-import pprint
-
-class TestMasterShellCommand(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- if runtime.platformType == 'win32':
- self.comspec = os.environ.get('COMPSPEC')
- os.environ['COMSPEC'] = r'C:\WINDOWS\system32\cmd.exe'
- return self.setUpBuildStep()
-
- def tearDown(self):
- if runtime.platformType == 'win32':
- if self.comspec:
- os.environ['COMSPEC'] = self.comspec
- else:
- del os.environ['COMSPEC']
- return self.tearDownBuildStep()
-
- def patchSpawnProcess(self, exp_cmd, exp_argv, exp_path, exp_usePTY,
- exp_env, outputs):
- def spawnProcess(pp, cmd, argv, path, usePTY, env):
- self.assertEqual([cmd, argv, path, usePTY, env],
- [exp_cmd, exp_argv, exp_path, exp_usePTY, exp_env])
- for output in outputs:
- if output[0] == 'out':
- pp.outReceived(output[1])
- elif output[0] == 'err':
- pp.errReceived(output[1])
- elif output[0] == 'rc':
- if output[1] != 0:
- so = error.ProcessTerminated(exitCode=output[1])
- else:
- so = error.ProcessDone(None)
- pp.processEnded(failure.Failure(so))
- self.patch(reactor, 'spawnProcess', spawnProcess)
-
- def test_real_cmd(self):
- cmd = [ sys.executable, '-c', 'print "hello"' ]
- self.setupStep(
- master.MasterShellCommand(command=cmd))
- if runtime.platformType == 'win32':
- self.expectLogfile('stdio', "hello\r\n")
- else:
- self.expectLogfile('stdio', "hello\n")
- self.expectOutcome(result=SUCCESS, status_text=["Ran"])
- return self.runStep()
-
- def test_real_cmd_interrupted(self):
- cmd = [ sys.executable, '-c', 'while True: pass' ]
- self.setupStep(
- master.MasterShellCommand(command=cmd))
- self.expectLogfile('stdio', "")
- if runtime.platformType == 'win32':
- # windows doesn't have signals, so we don't get 'killed'
- self.expectOutcome(result=EXCEPTION,
- status_text=["failed (1)", "interrupted"])
- else:
- self.expectOutcome(result=EXCEPTION,
- status_text=["killed (9)", "interrupted"])
- d = self.runStep()
- self.step.interrupt("KILL")
- return d
-
- def test_real_cmd_fails(self):
- cmd = [ sys.executable, '-c', 'import sys; sys.exit(1)' ]
- self.setupStep(
- master.MasterShellCommand(command=cmd))
- self.expectLogfile('stdio', "")
- self.expectOutcome(result=FAILURE, status_text=["failed (1)"])
- return self.runStep()
-
- def test_constr_args(self):
- self.setupStep(
- master.MasterShellCommand(description='x', descriptionDone='y',
- env={'a':'b'}, path=['/usr/bin'], usePTY=True,
- command='true'))
-
- self.assertEqual(self.step.describe(), ['x'])
-
- if runtime.platformType == 'win32':
- exp_argv = [ r'C:\WINDOWS\system32\cmd.exe', '/c', 'true' ]
- else:
- exp_argv = [ '/bin/sh', '-c', 'true' ]
- self.patchSpawnProcess(
- exp_cmd=exp_argv[0], exp_argv=exp_argv,
- exp_path=['/usr/bin'], exp_usePTY=True, exp_env={'a':'b'},
- outputs=[
- ('out', 'hello!\n'),
- ('err', 'world\n'),
- ('rc', 0),
- ])
- self.expectOutcome(result=SUCCESS, status_text=['y'])
- return self.runStep()
-
- def test_env_subst(self):
- cmd = [ sys.executable, '-c', 'import os; print os.environ["HELLO"]' ]
- os.environ['WORLD'] = 'hello'
- self.setupStep(
- master.MasterShellCommand(command=cmd,
- env={'HELLO': '${WORLD}'}))
- if runtime.platformType == 'win32':
- self.expectLogfile('stdio', "hello\r\n")
- else:
- self.expectLogfile('stdio', "hello\n")
- self.expectOutcome(result=SUCCESS, status_text=["Ran"])
- def _restore_env(res):
- del os.environ['WORLD']
- return res
- d = self.runStep()
- d.addBoth(_restore_env)
- return d
-
- def test_env_list_subst(self):
- cmd = [ sys.executable, '-c', 'import os; print os.environ["HELLO"]' ]
- os.environ['WORLD'] = 'hello'
- os.environ['LIST'] = 'world'
- self.setupStep(
- master.MasterShellCommand(command=cmd,
- env={'HELLO': ['${WORLD}', '${LIST}']}))
- if runtime.platformType == 'win32':
- self.expectLogfile('stdio', "hello;world\r\n")
- else:
- self.expectLogfile('stdio', "hello:world\n")
- self.expectOutcome(result=SUCCESS, status_text=["Ran"])
- def _restore_env(res):
- del os.environ['WORLD']
- del os.environ['LIST']
- return res
- d = self.runStep()
- d.addBoth(_restore_env)
- return d
-
- def test_prop_rendering(self):
- cmd = [ sys.executable, '-c', WithProperties(
- 'import os; print "%s"; print os.environ[\"BUILD\"]',
- 'project') ]
- self.setupStep(
- master.MasterShellCommand(command=cmd,
- env={'BUILD': WithProperties('%s', "project")}))
- self.properties.setProperty("project", "BUILDBOT-TEST", "TEST")
- if runtime.platformType == 'win32':
- self.expectLogfile('stdio', "BUILDBOT-TEST\r\nBUILDBOT-TEST\r\n")
- else:
- self.expectLogfile('stdio', "BUILDBOT-TEST\nBUILDBOT-TEST\n")
- self.expectOutcome(result=SUCCESS, status_text=["Ran"])
- return self.runStep()
-
- def test_constr_args_descriptionSuffix(self):
- self.setupStep(
- master.MasterShellCommand(description='x', descriptionDone='y',
- descriptionSuffix='z',
- env={'a':'b'}, path=['/usr/bin'], usePTY=True,
- command='true'))
-
- # call twice to make sure the suffix doesn't get double added
- self.assertEqual(self.step.describe(), ['x', 'z'])
- self.assertEqual(self.step.describe(), ['x', 'z'])
-
- if runtime.platformType == 'win32':
- exp_argv = [ r'C:\WINDOWS\system32\cmd.exe', '/c', 'true' ]
- else:
- exp_argv = [ '/bin/sh', '-c', 'true' ]
- self.patchSpawnProcess(
- exp_cmd=exp_argv[0], exp_argv=exp_argv,
- exp_path=['/usr/bin'], exp_usePTY=True, exp_env={'a':'b'},
- outputs=[
- ('out', 'hello!\n'),
- ('err', 'world\n'),
- ('rc', 0),
- ])
- self.expectOutcome(result=SUCCESS, status_text=['y', 'z'])
- return self.runStep()
-
-class TestSetProperty(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_simple(self):
- self.setupStep(master.SetProperty(property="testProperty", value=Interpolate("sch=%(prop:scheduler)s, slave=%(prop:slavename)s")))
- self.properties.setProperty('scheduler', 'force', source='SetProperty', runtime=True)
- self.properties.setProperty('slavename', 'testSlave', source='SetPropery', runtime=True)
- self.expectOutcome(result=SUCCESS, status_text=["SetProperty"])
- self.expectProperty('testProperty', 'sch=force, slave=testSlave', source='SetProperty')
- return self.runStep()
-
-class TestLogRenderable(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_simple(self):
- self.setupStep(master.LogRenderable(content=Interpolate('sch=%(prop:scheduler)s, slave=%(prop:slavename)s')))
- self.properties.setProperty('scheduler', 'force', source='TestSetProperty', runtime=True)
- self.properties.setProperty('slavename', 'testSlave', source='TestSetProperty', runtime=True)
- self.expectOutcome(result=SUCCESS, status_text=['LogRenderable'])
- self.expectLogfile('Output', pprint.pformat('sch=force, slave=testSlave'))
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_maxq.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_maxq.py
deleted file mode 100644
index 07f3edef..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_maxq.py
+++ /dev/null
@@ -1,71 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.test.util import steps
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.test.fake.remotecommand import ExpectShell
-from buildbot.steps import maxq
-from buildbot import config
-
-class TestShellCommandExecution(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_testdir_required(self):
- self.assertRaises(config.ConfigErrors, lambda : maxq.MaxQ())
-
- def test_success(self):
- self.setupStep(
- maxq.MaxQ(testdir='x'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="run_maxq.py x")
- + ExpectShell.log('stdio', stdout='no failures\n')
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=['maxq', 'tests'])
- return self.runStep()
-
- def test_nonzero_rc_no_failures(self):
- self.setupStep(
- maxq.MaxQ(testdir='x'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="run_maxq.py x")
- + ExpectShell.log('stdio', stdout='no failures\n')
- + 2
- )
- self.expectOutcome(result=FAILURE,
- status_text=['1', 'maxq', 'failures'])
- return self.runStep()
-
- def test_failures(self):
- self.setupStep(
- maxq.MaxQ(testdir='x'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="run_maxq.py x")
- + ExpectShell.log('stdio', stdout='\nTEST FAILURE: foo\n' * 10)
- + 2
- )
- self.expectOutcome(result=FAILURE,
- status_text=['10', 'maxq', 'failures'])
- return self.runStep()
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_deb_lintian.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_deb_lintian.py
deleted file mode 100644
index cec98927..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_deb_lintian.py
+++ /dev/null
@@ -1,55 +0,0 @@
-# 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
-
-from buildbot.status.results import SUCCESS
-from buildbot.steps.package.deb import lintian
-from buildbot.test.fake.remotecommand import ExpectShell
-from buildbot.test.util import steps
-from twisted.trial import unittest
-from buildbot import config
-
-class TestDebLintian(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_no_fileloc(self):
- self.assertRaises(config.ConfigErrors, lambda :
- lintian.DebLintian())
-
- def test_success(self):
- self.setupStep(lintian.DebLintian('foo_0.23_i386.changes'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['lintian', '-v', 'foo_0.23_i386.changes'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['Lintian'])
- return self.runStep()
-
- def test_success_suppressTags(self):
- self.setupStep(lintian.DebLintian('foo_0.23_i386.changes',
- suppressTags=['bad-distribution-in-changes-file']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['lintian', '-v', 'foo_0.23_i386.changes',
- '--suppress-tags', 'bad-distribution-in-changes-file'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['Lintian'])
- return self.runStep()
-
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_deb_pbuilder.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_deb_pbuilder.py
deleted file mode 100644
index 975b431e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_deb_pbuilder.py
+++ /dev/null
@@ -1,372 +0,0 @@
-# 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 stat
-import time
-
-from twisted.trial import unittest
-from buildbot.steps.package.deb import pbuilder
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.test.util import steps
-from buildbot.test.fake.remotecommand import ExpectShell, Expect
-from buildbot import config
-
-class TestDebPbuilder(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_new(self):
- self.setupStep(pbuilder.DebPbuilder())
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.tgz'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--create',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz',
- '--distribution', 'stable',
- '--mirror', 'http://cdn.debian.net/debian/'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_update(self):
- self.setupStep(pbuilder.DebPbuilder())
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.tgz'})
- + Expect.update('stat', [stat.S_IFREG, 99, 99, 1, 0, 0, 99, 0, 0, 0])
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--update',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz',])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_buildonly(self):
- self.setupStep(pbuilder.DebPbuilder())
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.tgz'})
- + Expect.update('stat', [stat.S_IFREG, 99, 99, 1, 0, 0, 99, 0, int(time.time()), 0])
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_architecture(self):
- self.setupStep(pbuilder.DebPbuilder(architecture='amd64'))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-amd64-buildbot.tgz'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--create',
- '--basetgz', '/var/cache/pbuilder/stable-amd64-buildbot.tgz',
- '--distribution', 'stable',
- '--mirror', 'http://cdn.debian.net/debian/',
- '--architecture', 'amd64'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder',
- '--architecture', 'amd64', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/stable-amd64-buildbot.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_distribution(self):
- self.setupStep(pbuilder.DebPbuilder(distribution='woody'))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/woody-local-buildbot.tgz'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--create',
- '--basetgz', '/var/cache/pbuilder/woody-local-buildbot.tgz',
- '--distribution', 'woody',
- '--mirror', 'http://cdn.debian.net/debian/'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/woody-local-buildbot.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_basetgz(self):
- self.setupStep(pbuilder.DebPbuilder(basetgz='/buildbot/%(distribution)s-%(architecture)s.tgz'))
- self.expectCommands(
- Expect('stat', {'file': '/buildbot/stable-local.tgz'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--create',
- '--basetgz', '/buildbot/stable-local.tgz',
- '--distribution', 'stable',
- '--mirror', 'http://cdn.debian.net/debian/'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/buildbot/stable-local.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_mirror(self):
- self.setupStep(pbuilder.DebPbuilder(mirror='http://apt:9999/debian'))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.tgz'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--create',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz',
- '--distribution', 'stable',
- '--mirror', 'http://apt:9999/debian'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_extrapackages(self):
- self.setupStep(pbuilder.DebPbuilder(extrapackages=['buildbot']))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.tgz'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--create',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz',
- '--distribution', 'stable',
- '--mirror', 'http://cdn.debian.net/debian/',
- '--extrapackages', 'buildbot'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz',
- '--extrapackages', 'buildbot'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_keyring(self):
- self.setupStep(pbuilder.DebPbuilder(keyring='/builbot/buildbot.gpg'))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.tgz'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--create',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz',
- '--distribution', 'stable',
- '--mirror', 'http://cdn.debian.net/debian/',
- '--debootstrapopts', '--keyring=/builbot/buildbot.gpg'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_components(self):
- self.setupStep(pbuilder.DebPbuilder(components='main universe'))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.tgz'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--create',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz',
- '--distribution', 'stable',
- '--mirror', 'http://cdn.debian.net/debian/',
- '--components', 'main universe'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/stable-local-buildbot.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
-class TestDebCowbuilder(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_new(self):
- self.setupStep(pbuilder.DebCowbuilder())
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.cow/'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/cowbuilder', '--create',
- '--basepath', '/var/cache/pbuilder/stable-local-buildbot.cow/',
- '--distribution', 'stable',
- '--mirror', 'http://cdn.debian.net/debian/'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/cowbuilder', '--', '--buildresult', '.',
- '--basepath', '/var/cache/pbuilder/stable-local-buildbot.cow/'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_update(self):
- self.setupStep(pbuilder.DebCowbuilder())
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.cow/'})
- + Expect.update('stat', [stat.S_IFDIR, 99, 99, 1, 0, 0, 99, 0, 0, 0])
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/cowbuilder', '--update',
- '--basepath', '/var/cache/pbuilder/stable-local-buildbot.cow/',])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/cowbuilder', '--', '--buildresult', '.',
- '--basepath', '/var/cache/pbuilder/stable-local-buildbot.cow/'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_buildonly(self):
- self.setupStep(pbuilder.DebCowbuilder())
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.cow/'})
- + Expect.update('stat', [stat.S_IFDIR, 99, 99, 1, 0, 0, 99, 0, int(time.time()), 0])
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/cowbuilder', '--', '--buildresult', '.',
- '--basepath', '/var/cache/pbuilder/stable-local-buildbot.cow/'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
- def test_update_reg(self):
- self.setupStep(pbuilder.DebCowbuilder(basetgz='/var/cache/pbuilder/stable-local-buildbot.cow'))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.cow'})
- + Expect.update('stat', [stat.S_IFREG, 99, 99, 1, 0, 0, 99, 0, 0, 0])
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/cowbuilder', '--update',
- '--basepath', '/var/cache/pbuilder/stable-local-buildbot.cow'])
- + 1)
- self.expectOutcome(result=FAILURE, status_text=['PBuilder update.'])
- return self.runStep()
-
- def test_buildonly_reg(self):
- self.setupStep(pbuilder.DebCowbuilder(basetgz='/var/cache/pbuilder/stable-local-buildbot.cow'))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/stable-local-buildbot.cow'})
- + Expect.update('stat', [stat.S_IFREG, 99, 99, 1, 0, 0, 99, 0, int(time.time()), 0])
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/cowbuilder', '--', '--buildresult', '.',
- '--basepath', '/var/cache/pbuilder/stable-local-buildbot.cow'])
- + 1)
- self.expectOutcome(result=FAILURE, status_text=['pdebuild', 'failed'])
- return self.runStep()
-
-class TestUbuPbuilder(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_no_distribution(self):
- self.assertRaises(config.ConfigErrors, lambda :
- pbuilder.UbuPbuilder())
-
- def test_new(self):
- self.setupStep(pbuilder.UbuPbuilder(distribution='oneiric'))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/oneiric-local-buildbot.tgz'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/pbuilder', '--create',
- '--basetgz', '/var/cache/pbuilder/oneiric-local-buildbot.tgz',
- '--distribution', 'oneiric',
- '--mirror', 'http://archive.ubuntu.com/ubuntu/',
- '--components', 'main universe'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/pbuilder', '--', '--buildresult', '.',
- '--basetgz', '/var/cache/pbuilder/oneiric-local-buildbot.tgz'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
-
-class TestUbuCowbuilder(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_no_distribution(self):
- self.assertRaises(config.ConfigErrors, lambda :
- pbuilder.UbuCowbuilder())
-
- def test_new(self):
- self.setupStep(pbuilder.UbuCowbuilder(distribution='oneiric'))
- self.expectCommands(
- Expect('stat', {'file': '/var/cache/pbuilder/oneiric-local-buildbot.cow/'})
- + 1,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sudo', '/usr/sbin/cowbuilder', '--create',
- '--basepath', '/var/cache/pbuilder/oneiric-local-buildbot.cow/',
- '--distribution', 'oneiric',
- '--mirror', 'http://archive.ubuntu.com/ubuntu/',
- '--components', 'main universe'])
- +0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['pdebuild', '--buildresult', '.',
- '--pbuilder', '/usr/sbin/cowbuilder', '--', '--buildresult', '.',
- '--basepath', '/var/cache/pbuilder/oneiric-local-buildbot.cow/'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['pdebuild'])
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_mock.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_mock.py
deleted file mode 100644
index df0e937b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_mock.py
+++ /dev/null
@@ -1,128 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.steps.package.rpm import mock
-from buildbot.status.results import SUCCESS
-from buildbot.test.util import steps
-from buildbot.test.fake.remotecommand import ExpectShell, Expect
-from buildbot import config
-
-class TestMock(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_no_root(self):
- self.assertRaises(config.ConfigErrors, lambda :
- mock.Mock())
-
- def test_class_attrs(self):
- step = self.setupStep(mock.Mock(root='TESTROOT'))
- self.assertEqual(step.command, ['mock', '--root', 'TESTROOT'])
-
- def test_success(self):
- self.setupStep(mock.Mock(root='TESTROOT'))
- self.expectCommands(
- Expect('rmdir', {'dir': ['build/build.log', 'build/root.log',
- 'build/state.log']})
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['mock', '--root', 'TESTROOT'],
- logfiles={'build.log': 'build.log',
- 'root.log': 'root.log',
- 'state.log': 'state.log'})
- +0)
- self.expectOutcome(result=SUCCESS, status_text=["'mock", '--root', "...'"])
- return self.runStep()
-
- def test_resultdir_success(self):
- self.setupStep(mock.Mock(root='TESTROOT', resultdir='RESULT'))
- self.expectCommands(
- Expect('rmdir', {'dir': ['build/RESULT/build.log',
- 'build/RESULT/root.log',
- 'build/RESULT/state.log']})
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['mock', '--root', 'TESTROOT',
- '--resultdir', 'RESULT'],
- logfiles={'build.log': 'RESULT/build.log',
- 'root.log': 'RESULT/root.log',
- 'state.log': 'RESULT/state.log'})
- +0)
- self.expectOutcome(result=SUCCESS, status_text=["'mock", '--root', "...'"])
- return self.runStep()
-
-
-
-class TestMockBuildSRPM(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_no_spec(self):
- self.assertRaises(config.ConfigErrors, lambda :
- mock.MockBuildSRPM(root='TESTROOT'))
-
- def test_success(self):
- self.setupStep(mock.MockBuildSRPM(root='TESTROOT', spec="foo.spec"))
- self.expectCommands(
- Expect('rmdir', {'dir': ['build/build.log', 'build/root.log',
- 'build/state.log']})
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['mock', '--root', 'TESTROOT',
- '--buildsrpm', '--spec', 'foo.spec',
- '--sources', '.'],
- logfiles={'build.log': 'build.log',
- 'root.log': 'root.log',
- 'state.log': 'state.log'},)
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['mock buildsrpm'])
- return self.runStep()
-
-class TestMockRebuild(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_no_srpm(self):
- self.assertRaises(config.ConfigErrors, lambda :
- mock.MockRebuild(root='TESTROOT'))
-
- def test_success(self):
- self.setupStep(mock.MockRebuild(root='TESTROOT', srpm="foo.src.rpm"))
- self.expectCommands(
- Expect('rmdir', {'dir': ['build/build.log', 'build/root.log',
- 'build/state.log']})
- + 0,
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['mock', '--root', 'TESTROOT',
- '--rebuild', 'foo.src.rpm'],
- logfiles={'build.log': 'build.log',
- 'root.log': 'root.log',
- 'state.log': 'state.log'},)
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['mock rebuild srpm'])
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_rpmbuild.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_rpmbuild.py
deleted file mode 100644
index 97dee1e5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_rpmbuild.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# 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
-
-from buildbot.status.results import SUCCESS
-from buildbot.steps.package.rpm import rpmbuild
-from buildbot.test.fake.remotecommand import ExpectShell
-from buildbot.test.util import steps
-from twisted.trial import unittest
-from buildbot import config
-
-class RpmBuild(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_no_specfile(self):
- self.assertRaises(config.ConfigErrors, lambda :
- rpmbuild.RpmBuild())
-
- def test_success(self):
- self.setupStep(rpmbuild.RpmBuild(specfile="foo.spec", dist=".el6"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command='rpmbuild --define "_topdir '
- '`pwd`" --define "_builddir `pwd`" --define "_rpmdir '
- '`pwd`" --define "_sourcedir `pwd`" --define "_specdir '
- '`pwd`" --define "_srcrpmdir `pwd`" --define "dist .el6" '
- '-ba foo.spec',
- usePTY='slave-config')
- + ExpectShell.log('stdio',
- stdout='lalala')
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['RPMBUILD'])
- return self.runStep()
-
- def test_autoRelease(self):
- self.setupStep(rpmbuild.RpmBuild(specfile="foo.spec", dist=".el6",
- autoRelease=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command='rpmbuild --define "_topdir '
- '`pwd`" --define "_builddir `pwd`" --define "_rpmdir `pwd`" '
- '--define "_sourcedir `pwd`" --define "_specdir `pwd`" '
- '--define "_srcrpmdir `pwd`" --define "dist .el6" '
- '--define "_release 0" -ba foo.spec',
- usePTY='slave-config')
- + ExpectShell.log('stdio',
- stdout='Your code has been rated at 10/10')
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['RPMBUILD'])
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_rpmlint.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_rpmlint.py
deleted file mode 100644
index cb36e31c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_package_rpm_rpmlint.py
+++ /dev/null
@@ -1,56 +0,0 @@
-# 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
-
-from buildbot.status.results import SUCCESS
-from buildbot.steps.package.rpm import rpmlint
-from buildbot.test.fake.remotecommand import ExpectShell
-from buildbot.test.util import steps
-from twisted.trial import unittest
-
-class TestRpmLint(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_success(self):
- self.setupStep(rpmlint.RpmLint())
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['rpmlint', '-i', '.'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['Finished checking RPM/SPEC issues'])
- return self.runStep()
-
- def test_fileloc_success(self):
- self.setupStep(rpmlint.RpmLint(fileloc='RESULT'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['rpmlint', '-i', 'RESULT'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['Finished checking RPM/SPEC issues'])
- return self.runStep()
-
- def test_config_success(self):
- self.setupStep(rpmlint.RpmLint(config='foo.cfg'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['rpmlint', '-i', '-f', 'foo.cfg', '.'])
- +0)
- self.expectOutcome(result=SUCCESS, status_text=['Finished checking RPM/SPEC issues'])
- return self.runStep()
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_python.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_python.py
deleted file mode 100644
index 4bc31cbc..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_python.py
+++ /dev/null
@@ -1,445 +0,0 @@
-# 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
-
-from buildbot.status.results import FAILURE, SUCCESS, WARNINGS
-from buildbot.steps import python
-from buildbot.test.fake.remotecommand import ExpectShell
-from buildbot.test.util import steps
-from twisted.trial import unittest
-from buildbot import config
-
-log_output_success = '''\
-Making output directory...
-Running Sphinx v1.0.7
-loading pickled environment... not yet created
-No builder selected, using default: html
-building [html]: targets for 24 source files that are out of date
-updating environment: 24 added, 0 changed, 0 removed
-reading sources... [ 4%] index
-reading sources... [ 8%] manual/cfg-builders
-...
-copying static files... done
-dumping search index... done
-dumping object inventory... done
-build succeeded.
-'''
-
-log_output_nochange = '''\
-Running Sphinx v1.0.7
-loading pickled environment... done
-No builder selected, using default: html
-building [html]: targets for 0 source files that are out of date
-updating environment: 0 added, 0 changed, 0 removed
-looking for now-outdated files... none found
-no targets are out of date.
-'''
-
-log_output_warnings = '''\
-Running Sphinx v1.0.7
-loading pickled environment... done
-building [html]: targets for 1 source files that are out of date
-updating environment: 0 added, 1 changed, 0 removed
-reading sources... [100%] file
-
-file.rst:18: (WARNING/2) Literal block expected; none found.
-
-looking for now-outdated files... none found
-pickling environment... done
-checking consistency... done
-preparing documents... done
-writing output... [ 50%] index
-writing output... [100%] file
-
-index.rst:: WARNING: toctree contains reference to document 'preamble' that \
-doesn't have a title: no link will be generated
-writing additional files... search
-copying static files... done
-dumping search index... done
-dumping object inventory... done
-build succeeded, 2 warnings.'''
-
-warnings = '''\
-file.rst:18: (WARNING/2) Literal block expected; none found.
-index.rst:: WARNING: toctree contains reference to document 'preamble' that \
-doesn't have a title: no link will be generated\
-'''
-
-
-class PyLint(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_success(self):
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log('stdio',
- stdout='Your code has been rated at 10/10')
- + python.PyLint.RC_OK)
- self.expectOutcome(result=SUCCESS, status_text=['pylint'])
- return self.runStep()
-
- def test_error(self):
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout=('W: 11: Bad indentation. Found 6 spaces, expected 4\n'
- 'E: 12: Undefined variable \'foo\'\n'))
- + (python.PyLint.RC_WARNING|python.PyLint.RC_ERROR))
- self.expectOutcome(result=FAILURE,
- status_text=['pylint', 'error=1', 'warning=1',
- 'failed'])
- self.expectProperty('pylint-warning', 1)
- self.expectProperty('pylint-error', 1)
- return self.runStep()
-
- def test_failure(self):
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout=('W: 11: Bad indentation. Found 6 spaces, expected 4\n'
- 'F: 13: something really strange happened\n'))
- + (python.PyLint.RC_WARNING|python.PyLint.RC_FATAL))
- self.expectOutcome(result=FAILURE,
- status_text=['pylint', 'fatal=1', 'warning=1',
- 'failed'])
- self.expectProperty('pylint-warning', 1)
- self.expectProperty('pylint-fatal', 1)
- return self.runStep()
-
- def test_failure_zero_returncode(self):
- # Make sure that errors result in a failed step when pylint's
- # return code is 0, e.g. when run through a wrapper script.
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout=('W: 11: Bad indentation. Found 6 spaces, expected 4\n'
- 'E: 12: Undefined variable \'foo\'\n'))
- + 0)
- self.expectOutcome(result=FAILURE,
- status_text=['pylint', 'error=1', 'warning=1',
- 'failed'])
- self.expectProperty('pylint-warning', 1)
- self.expectProperty('pylint-error', 1)
- return self.runStep()
-
- def test_regex_text(self):
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout=('W: 11: Bad indentation. Found 6 spaces, expected 4\n'
- 'C: 1:foo123: Missing docstring\n'))
- + (python.PyLint.RC_WARNING|python.PyLint.RC_CONVENTION))
- self.expectOutcome(result=WARNINGS,
- status_text=['pylint', 'convention=1', 'warning=1',
- 'warnings'])
- self.expectProperty('pylint-warning', 1)
- self.expectProperty('pylint-convention', 1)
- self.expectProperty('pylint-total', 2)
- return self.runStep()
-
- def test_regex_text_0_24(self):
- # pylint >= 0.24.0 prints out column offsets when using text format
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout=('W: 11,0: Bad indentation. Found 6 spaces, expected 4\n'
- 'C: 3,10:foo123: Missing docstring\n'))
- + (python.PyLint.RC_WARNING|python.PyLint.RC_CONVENTION))
- self.expectOutcome(result=WARNINGS,
- status_text=['pylint', 'convention=1', 'warning=1',
- 'warnings'])
- self.expectProperty('pylint-warning', 1)
- self.expectProperty('pylint-convention', 1)
- self.expectProperty('pylint-total', 2)
- return self.runStep()
-
- def test_regex_text_ids(self):
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout=('W0311: 11: Bad indentation.\n'
- 'C0111: 1:funcName: Missing docstring\n'))
- + (python.PyLint.RC_WARNING|python.PyLint.RC_CONVENTION))
- self.expectOutcome(result=WARNINGS,
- status_text=['pylint', 'convention=1', 'warning=1',
- 'warnings'])
- self.expectProperty('pylint-warning', 1)
- self.expectProperty('pylint-convention', 1)
- self.expectProperty('pylint-total', 2)
- return self.runStep()
-
- def test_regex_text_ids_0_24(self):
- # pylint >= 0.24.0 prints out column offsets when using text format
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout=('W0311: 11,0: Bad indentation.\n'
- 'C0111: 3,10:foo123: Missing docstring\n'))
- + (python.PyLint.RC_WARNING|python.PyLint.RC_CONVENTION))
- self.expectOutcome(result=WARNINGS,
- status_text=['pylint', 'convention=1', 'warning=1',
- 'warnings'])
- self.expectProperty('pylint-warning', 1)
- self.expectProperty('pylint-convention', 1)
- self.expectProperty('pylint-total', 2)
- return self.runStep()
-
- def test_regex_parseable_ids(self):
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout=('test.py:9: [W0311] Bad indentation.\n'
- 'test.py:3: [C0111, foo123] Missing docstring\n'))
- + (python.PyLint.RC_WARNING|python.PyLint.RC_CONVENTION))
- self.expectOutcome(result=WARNINGS,
- status_text=['pylint', 'convention=1', 'warning=1',
- 'warnings'])
- self.expectProperty('pylint-warning', 1)
- self.expectProperty('pylint-convention', 1)
- self.expectProperty('pylint-total', 2)
- return self.runStep()
-
- def test_regex_parseable(self):
- self.setupStep(python.PyLint(command=['pylint']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['pylint'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout=('test.py:9: [W] Bad indentation.\n'
- 'test.py:3: [C, foo123] Missing docstring\n'))
- + (python.PyLint.RC_WARNING|python.PyLint.RC_CONVENTION))
- self.expectOutcome(result=WARNINGS,
- status_text=['pylint', 'convention=1', 'warning=1',
- 'warnings'])
- self.expectProperty('pylint-warning', 1)
- self.expectProperty('pylint-convention', 1)
- self.expectProperty('pylint-total', 2)
- return self.runStep()
-
-class PyFlakes(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_success(self):
- self.setupStep(python.PyFlakes())
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['make', 'pyflakes'],
- usePTY='slave-config')
- + 0)
- self.expectOutcome(result=SUCCESS, status_text=['pyflakes'])
- return self.runStep()
-
- def test_unused(self):
- self.setupStep(python.PyFlakes())
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['make', 'pyflakes'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout="foo.py:1: 'bar' imported but unused\n")
- + 1)
- self.expectOutcome(result=WARNINGS,
- status_text=['pyflakes', 'unused=1', 'warnings'])
- self.expectProperty('pyflakes-unused', 1)
- self.expectProperty('pyflakes-total', 1)
- return self.runStep()
-
- def test_undefined(self):
- self.setupStep(python.PyFlakes())
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['make', 'pyflakes'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout="foo.py:1: undefined name 'bar'\n")
- + 1)
- self.expectOutcome(result=FAILURE,
- status_text=['pyflakes', 'undefined=1', 'failed'])
- self.expectProperty('pyflakes-undefined', 1)
- self.expectProperty('pyflakes-total', 1)
- return self.runStep()
-
- def test_redefs(self):
- self.setupStep(python.PyFlakes())
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['make', 'pyflakes'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout="foo.py:2: redefinition of unused 'foo' from line 1\n")
- + 1)
- self.expectOutcome(result=WARNINGS,
- status_text=['pyflakes', 'redefs=1', 'warnings'])
- self.expectProperty('pyflakes-redefs', 1)
- self.expectProperty('pyflakes-total', 1)
- return self.runStep()
-
- def test_importstar(self):
- self.setupStep(python.PyFlakes())
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['make', 'pyflakes'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout="foo.py:1: 'from module import *' used; unable to detect undefined names\n")
- + 1)
- self.expectOutcome(result=WARNINGS,
- status_text=['pyflakes', 'import*=1', 'warnings'])
- self.expectProperty('pyflakes-import*', 1)
- self.expectProperty('pyflakes-total', 1)
- return self.runStep()
-
- def test_misc(self):
- self.setupStep(python.PyFlakes())
- self.expectCommands(
- ExpectShell(workdir='wkdir', command=['make', 'pyflakes'],
- usePTY='slave-config')
- + ExpectShell.log(
- 'stdio',
- stdout="foo.py:2: redefinition of function 'bar' from line 1\n")
- + 1)
- self.expectOutcome(result=WARNINGS,
- status_text=['pyflakes', 'misc=1', 'warnings'])
- self.expectProperty('pyflakes-misc', 1)
- self.expectProperty('pyflakes-total', 1)
- return self.runStep()
-
-
-class TestSphinx(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_builddir_required(self):
- self.assertRaises(config.ConfigErrors, lambda :
- python.Sphinx())
-
- def test_bad_mode(self):
- self.assertRaises(config.ConfigErrors, lambda: python.Sphinx(
- sphinx_builddir="_build", mode="don't care"))
-
- def test_success(self):
- self.setupStep(python.Sphinx(sphinx_builddir="_build"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sphinx-build', '.', '_build'])
- + ExpectShell.log('stdio',
- stdout=log_output_success)
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=["sphinx", "0 warnings"])
- return self.runStep()
-
- def test_failure(self):
- self.setupStep(python.Sphinx(sphinx_builddir="_build"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sphinx-build', '.', '_build'])
- + ExpectShell.log('stdio',
- stdout='oh noes!')
- + 1
- )
- self.expectOutcome(result=FAILURE, status_text=["sphinx", "0 warnings", "failed"])
- return self.runStep()
-
- def test_nochange(self):
- self.setupStep(python.Sphinx(sphinx_builddir="_build"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sphinx-build', '.', '_build'])
- + ExpectShell.log('stdio',
- stdout=log_output_nochange)
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["sphinx", "0 warnings"])
- return self.runStep()
-
- def test_warnings(self):
- self.setupStep(python.Sphinx(sphinx_builddir="_build"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['sphinx-build', '.', '_build'])
- + ExpectShell.log('stdio',
- stdout=log_output_warnings)
- + 0
- )
- self.expectOutcome(result=WARNINGS,
- status_text=["sphinx", "2 warnings", "warnings"])
- self.expectLogfile("warnings", warnings)
- d = self.runStep()
- def check(_):
- self.assertEqual(self.step_statistics, { 'warnings' : 2 })
- d.addCallback(check)
- return d
-
- def test_constr_args(self):
- self.setupStep(python.Sphinx(sphinx_sourcedir='src',
- sphinx_builddir="bld",
- sphinx_builder='css',
- sphinx="/path/to/sphinx-build",
- tags=['a', 'b'],
- defines=dict(empty=None, t=True, f=False, s="str"),
- mode='full'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['/path/to/sphinx-build', '-b', 'css',
- '-t', 'a', '-t', 'b', '-D', 'empty',
- '-D', 'f=0', '-D', 's=str', '-D', 't=1',
- '-E', 'src', 'bld'])
- + ExpectShell.log('stdio',
- stdout=log_output_success)
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=["sphinx", "0 warnings"])
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_python_twisted.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_python_twisted.py
deleted file mode 100644
index daefb43b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_python_twisted.py
+++ /dev/null
@@ -1,194 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.steps import python_twisted
-from buildbot.status.results import SUCCESS
-from buildbot.test.util import steps
-from buildbot.test.fake.remotecommand import ExpectShell
-from buildbot.process.properties import Property
-
-
-
-class Trial(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_run_env(self):
- self.setupStep(
- python_twisted.Trial(workdir='build',
- tests = 'testname',
- testpath = None,
- env = {'PYTHONPATH': 'somepath'}))
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '--reporter=bwverbose', 'testname'],
- usePTY="slave-config",
- logfiles={'test.log': '_trial_temp/test.log'},
- env=dict(PYTHONPATH='somepath'))
- + ExpectShell.log('stdio', stdout="Ran 0 tests\n")
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=['no tests', 'run'])
- return self.runStep()
-
- def test_run_env_supplement(self):
- self.setupStep(
- python_twisted.Trial(workdir='build',
- tests = 'testname',
- testpath = 'path1',
- env = {'PYTHONPATH': ['path2','path3']}))
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '--reporter=bwverbose', 'testname'],
- usePTY="slave-config",
- logfiles={'test.log': '_trial_temp/test.log'},
- env=dict(PYTHONPATH=['path1', 'path2', 'path3']))
- + ExpectShell.log('stdio', stdout="Ran 0 tests\n")
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=['no tests', 'run'])
- return self.runStep()
-
- def test_run_env_nodupe(self):
- self.setupStep(
- python_twisted.Trial(workdir='build',
- tests = 'testname',
- testpath = 'path2',
- env = {'PYTHONPATH': ['path1','path2']}))
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '--reporter=bwverbose', 'testname'],
- usePTY="slave-config",
- logfiles={'test.log': '_trial_temp/test.log'},
- env=dict(PYTHONPATH=['path1','path2']))
- + ExpectShell.log('stdio', stdout="Ran 0 tests\n")
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=['no tests', 'run'])
- return self.runStep()
-
- def test_run_singular(self):
- self.setupStep(
- python_twisted.Trial(workdir='build',
- tests = 'testname',
- testpath=None))
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '--reporter=bwverbose', 'testname'],
- usePTY="slave-config",
- logfiles={'test.log': '_trial_temp/test.log'})
- + ExpectShell.log('stdio', stdout="Ran 1 tests\n")
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=['1 test', 'passed'])
- return self.runStep()
-
- def test_run_plural(self):
- self.setupStep(
- python_twisted.Trial(workdir='build',
- tests = 'testname',
- testpath=None))
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '--reporter=bwverbose', 'testname'],
- usePTY="slave-config",
- logfiles={'test.log': '_trial_temp/test.log'})
- + ExpectShell.log('stdio', stdout="Ran 2 tests\n")
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=['2 tests', 'passed'])
- return self.runStep()
-
- def testProperties(self):
- self.setupStep(python_twisted.Trial(workdir='build',
- tests = Property('test_list'),
- testpath=None))
- self.properties.setProperty('test_list',['testname'], 'Test')
-
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '--reporter=bwverbose', 'testname'],
- usePTY="slave-config",
- logfiles={'test.log': '_trial_temp/test.log'})
- + ExpectShell.log('stdio', stdout="Ran 2 tests\n")
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=['2 tests', 'passed'])
- return self.runStep()
-
- def test_run_jobs(self):
- """
- The C{jobs} kwarg should correspond to trial's -j option (
- included since Twisted 12.3.0), and make corresponding changes to
- logfiles.
- """
- self.setupStep(python_twisted.Trial(workdir='build',
- tests = 'testname',
- testpath = None,
- jobs=2))
-
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '--reporter=bwverbose', '--jobs=2',
- 'testname'],
- usePTY="slave-config",
- logfiles={
- 'test.0.log': '_trial_temp/0/test.log',
- 'err.0.log': '_trial_temp/0/err.log',
- 'out.0.log': '_trial_temp/0/out.log',
- 'test.1.log': '_trial_temp/1/test.log',
- 'err.1.log': '_trial_temp/1/err.log',
- 'out.1.log': '_trial_temp/1/out.log',
- })
- + ExpectShell.log('stdio', stdout="Ran 1 tests\n")
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=['1 test', 'passed'])
- return self.runStep()
-
- def test_run_jobsProperties(self):
- """
- C{jobs} should accept Properties
- """
- self.setupStep(python_twisted.Trial(workdir='build',
- tests = 'testname',
- jobs=Property('jobs_count'),
- testpath=None))
- self.properties.setProperty('jobs_count', '2', 'Test')
-
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '--reporter=bwverbose', '--jobs=2',
- 'testname'],
- usePTY="slave-config",
- logfiles={
- 'test.0.log': '_trial_temp/0/test.log',
- 'err.0.log': '_trial_temp/0/err.log',
- 'out.0.log': '_trial_temp/0/out.log',
- 'test.1.log': '_trial_temp/1/test.log',
- 'err.1.log': '_trial_temp/1/err.log',
- 'out.1.log': '_trial_temp/1/out.log',
- })
- + ExpectShell.log('stdio', stdout="Ran 1 tests\n")
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=['1 test', 'passed'])
- return self.runStep()
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_shell.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_shell.py
deleted file mode 100644
index 9f914600..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_shell.py
+++ /dev/null
@@ -1,836 +0,0 @@
-# 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 re
-import textwrap
-from twisted.trial import unittest
-from buildbot.steps import shell
-from buildbot.status.results import SKIPPED, SUCCESS, WARNINGS, FAILURE
-from buildbot.status.results import EXCEPTION
-from buildbot.test.util import steps, compat
-from buildbot.test.util import config as configmixin
-from buildbot.test.fake.remotecommand import ExpectShell, Expect
-from buildbot.test.fake.remotecommand import ExpectRemoteRef
-from buildbot import config
-from buildbot.process import properties
-
-class TestShellCommandExecution(steps.BuildStepMixin, unittest.TestCase, configmixin.ConfigErrorsMixin):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_doStepIf_False(self):
- self.setupStep(
- shell.ShellCommand(command="echo hello", doStepIf=False))
- self.expectOutcome(result=SKIPPED,
- status_text=["'echo", "hello'", "skipped"])
- return self.runStep()
-
- def test_constructor_args_strings(self):
- step = shell.ShellCommand(workdir='build', command="echo hello",
- usePTY=False, description="echoing",
- descriptionDone="echoed")
- self.assertEqual(step.description, ['echoing'])
- self.assertEqual(step.descriptionDone, ['echoed'])
-
- def test_constructor_args_lists(self):
- step = shell.ShellCommand(workdir='build', command="echo hello",
- usePTY=False, description=["echoing"],
- descriptionDone=["echoed"])
- self.assertEqual(step.description, ['echoing'])
- self.assertEqual(step.descriptionDone, ['echoed'])
-
- def test_constructor_args_kwargs(self):
- # this is an ugly way to define an API, but for now check that
- # the RemoteCommand arguments are properly passed on
- step = shell.ShellCommand(workdir='build', command="echo hello",
- want_stdout=0, logEnviron=False)
- self.assertEqual(step.remote_kwargs, dict(want_stdout=0,
- logEnviron=False, workdir='build',
- usePTY='slave-config'))
-
- def test_constructor_args_validity(self):
- # this checks that an exception is raised for invalid arguments
- self.assertRaisesConfigError(
- "Invalid argument(s) passed to RemoteShellCommand: ",
- lambda: shell.ShellCommand('build', "echo Hello World",
- wrongArg1=1, wrongArg2='two'))
-
- def test_describe_no_command(self):
- step = shell.ShellCommand(workdir='build')
- self.assertEqual((step.describe(), step.describe(done=True)),
- (['???'],)*2)
-
- def test_describe_from_empty_command(self):
- # this is more of a regression test for a potential failure, really
- step = shell.ShellCommand(workdir='build', command=' ')
- self.assertEqual((step.describe(), step.describe(done=True)),
- (['???'],)*2)
-
- def test_describe_from_short_command(self):
- step = shell.ShellCommand(workdir='build', command="true")
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'true'"],)*2)
-
- def test_describe_from_short_command_list(self):
- step = shell.ShellCommand(workdir='build', command=["true"])
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'true'"],)*2)
-
- def test_describe_from_med_command(self):
- step = shell.ShellCommand(command="echo hello")
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'echo", "hello'"],)*2)
-
- def test_describe_from_med_command_list(self):
- step = shell.ShellCommand(command=["echo", "hello"])
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'echo", "hello'"],)*2)
-
- def test_describe_from_long_command(self):
- step = shell.ShellCommand(command="this is a long command")
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'this", "is", "...'"],)*2)
-
- def test_describe_from_long_command_list(self):
- step = shell.ShellCommand(command="this is a long command".split())
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'this", "is", "...'"],)*2)
-
- def test_describe_from_nested_command_list(self):
- step = shell.ShellCommand(command=["this", ["is", "a"], "nested"])
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'this", "is", "...'"],)*2)
-
- def test_describe_from_nested_command_tuples(self):
- step = shell.ShellCommand(command=["this", ("is", "a"), "nested"])
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'this", "is", "...'"],)*2)
-
- def test_describe_from_nested_command_list_empty(self):
- step = shell.ShellCommand(command=["this", [], ["is", "a"], "nested"])
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'this", "is", "...'"],)*2)
-
- def test_describe_from_nested_command_list_deep(self):
- step = shell.ShellCommand(command=[["this", [[["is", ["a"]]]]]])
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'this", "is", "...'"],)*2)
-
- def test_describe_custom(self):
- step = shell.ShellCommand(command="echo hello",
- description=["echoing"], descriptionDone=["echoed"])
- self.assertEqual((step.describe(), step.describe(done=True)),
- (['echoing'], ['echoed']))
-
- def test_describe_with_suffix(self):
- step = shell.ShellCommand(command="echo hello", descriptionSuffix="suffix")
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'echo", "hello'", 'suffix'],)*2)
-
- def test_describe_custom_with_suffix(self):
- step = shell.ShellCommand(command="echo hello",
- description=["echoing"], descriptionDone=["echoed"],
- descriptionSuffix="suffix")
- self.assertEqual((step.describe(), step.describe(done=True)),
- (['echoing', 'suffix'], ['echoed', 'suffix']))
-
- def test_describe_no_command_with_suffix(self):
- step = shell.ShellCommand(workdir='build', descriptionSuffix="suffix")
- self.assertEqual((step.describe(), step.describe(done=True)),
- (['???', 'suffix'],)*2)
-
- def test_describe_unrendered_WithProperties(self):
- step = shell.ShellCommand(command=properties.WithProperties(''))
- self.assertEqual((step.describe(), step.describe(done=True)),
- (['???'],)*2)
-
- def test_describe_unrendered_WithProperties_list(self):
- step = shell.ShellCommand(
- command=[ 'x', properties.WithProperties(''), 'y' ])
- self.assertEqual((step.describe(), step.describe(done=True)),
- (["'x", "y'"],)*2)
-
- @compat.usesFlushLoggedErrors
- def test_describe_fail(self):
- step = shell.ShellCommand(command=object())
- self.assertEqual((step.describe(), step.describe(done=True)),
- (['???'],)*2)
- # (describe is called twice, so two exceptions)
- self.assertEqual(len(self.flushLoggedErrors(TypeError)), 2)
-
- def test_run_simple(self):
- self.setupStep(
- shell.ShellCommand(workdir='build', command="echo hello"))
- self.expectCommands(
- ExpectShell(workdir='build', command='echo hello',
- usePTY="slave-config")
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=["'echo", "hello'"])
- return self.runStep()
-
- def test_run_list(self):
- self.setupStep(
- shell.ShellCommand(workdir='build',
- command=['trial', '-b', '-B', 'buildbot.test']))
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '-b', '-B', 'buildbot.test'],
- usePTY="slave-config")
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["'trial", "-b", "...'"])
- return self.runStep()
-
- def test_run_nested_command(self):
- self.setupStep(
- shell.ShellCommand(workdir='build',
- command=['trial', ['-b', '-B'], 'buildbot.test']))
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '-b', '-B', 'buildbot.test'],
- usePTY="slave-config")
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["'trial", "-b", "...'"])
- return self.runStep()
-
- def test_run_nested_deeply_command(self):
- self.setupStep(
- shell.ShellCommand(workdir='build',
- command=[['trial', ['-b', ['-B']]], 'buildbot.test']))
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '-b', '-B', 'buildbot.test'],
- usePTY="slave-config")
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["'trial", "-b", "...'"])
- return self.runStep()
-
- def test_run_nested_empty_command(self):
- self.setupStep(
- shell.ShellCommand(workdir='build',
- command=['trial', [], '-b', [], 'buildbot.test']))
- self.expectCommands(
- ExpectShell(workdir='build',
- command=['trial', '-b', 'buildbot.test'],
- usePTY="slave-config")
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["'trial", "-b", "...'"])
- return self.runStep()
-
- def test_run_env(self):
- self.setupStep(
- shell.ShellCommand(workdir='build', command="echo hello"),
- slave_env=dict(DEF='HERE'))
- self.expectCommands(
- ExpectShell(workdir='build', command='echo hello',
- usePTY="slave-config",
- env=dict(DEF='HERE'))
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=["'echo", "hello'"])
- return self.runStep()
-
- def test_run_env_override(self):
- self.setupStep(
- shell.ShellCommand(workdir='build', env={'ABC':'123'},
- command="echo hello"),
- slave_env=dict(ABC='XXX', DEF='HERE'))
- self.expectCommands(
- ExpectShell(workdir='build', command='echo hello',
- usePTY="slave-config",
- env=dict(ABC='123', DEF='HERE'))
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=["'echo", "hello'"])
- return self.runStep()
-
- def test_run_usePTY(self):
- self.setupStep(
- shell.ShellCommand(workdir='build', command="echo hello",
- usePTY=False))
- self.expectCommands(
- ExpectShell(workdir='build', command='echo hello',
- usePTY=False)
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=["'echo", "hello'"])
- return self.runStep()
-
- def test_run_usePTY_old_slave(self):
- self.setupStep(
- shell.ShellCommand(workdir='build', command="echo hello",
- usePTY=True),
- slave_version=dict(shell='1.1'))
- self.expectCommands(
- ExpectShell(workdir='build', command='echo hello')
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=["'echo", "hello'"])
- return self.runStep()
-
- def test_run_decodeRC(self, rc=1, results=WARNINGS, extra_text = ["warnings"]):
- self.setupStep(
- shell.ShellCommand(workdir='build', command="echo hello",
- decodeRC={1:WARNINGS}))
- self.expectCommands(
- ExpectShell(workdir='build', command='echo hello',
- usePTY="slave-config")
- + rc
- )
- self.expectOutcome(result=results, status_text=["'echo", "hello'"]+extra_text)
- return self.runStep()
-
- def test_run_decodeRC_defaults(self):
- return self.test_run_decodeRC(2, FAILURE,extra_text=["failed"])
-
- def test_run_decodeRC_defaults_0_is_failure(self):
- return self.test_run_decodeRC(0, FAILURE,extra_text=["failed"])
-
-
-
-class TreeSize(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_run_success(self):
- self.setupStep(shell.TreeSize())
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['du', '-s', '-k', '.'])
- + ExpectShell.log('stdio', stdout='9292 .\n')
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["treesize", "9292 KiB"])
- self.expectProperty('tree-size-KiB', 9292)
- return self.runStep()
-
- def test_run_misparsed(self):
- self.setupStep(shell.TreeSize())
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['du', '-s', '-k', '.'])
- + ExpectShell.log('stdio', stdio='abcdef\n')
- + 0
- )
- self.expectOutcome(result=WARNINGS,
- status_text=["treesize", "unknown"])
- return self.runStep()
-
- def test_run_failed(self):
- self.setupStep(shell.TreeSize())
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['du', '-s', '-k', '.'])
- + ExpectShell.log('stdio', stderr='abcdef\n')
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["treesize", "unknown"])
- return self.runStep()
-
-class SetPropertyFromCommand(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_constructor_conflict(self):
- self.assertRaises(config.ConfigErrors, lambda :
- shell.SetPropertyFromCommand(property='foo', extract_fn=lambda : None))
-
- def test_run_property(self):
- self.setupStep(shell.SetPropertyFromCommand(property="res", command="cmd"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="cmd")
- + ExpectShell.log('stdio', stdout='\n\nabcdef\n')
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["property 'res' set"])
- self.expectProperty("res", "abcdef") # note: stripped
- self.expectLogfile('property changes', r"res: 'abcdef'")
- return self.runStep()
-
- def test_run_property_no_strip(self):
- self.setupStep(shell.SetPropertyFromCommand(property="res", command="cmd",
- strip=False))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="cmd")
- + ExpectShell.log('stdio', stdout='\n\nabcdef\n')
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["property 'res' set"])
- self.expectProperty("res", "\n\nabcdef\n")
- self.expectLogfile('property changes', r"res: '\n\nabcdef\n'")
- return self.runStep()
-
- def test_run_failure(self):
- self.setupStep(shell.SetPropertyFromCommand(property="res", command="blarg"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="blarg")
- + ExpectShell.log('stdio', stderr='cannot blarg: File not found')
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["'blarg'", "failed"])
- self.expectNoProperty("res")
- return self.runStep()
-
- def test_run_extract_fn(self):
- def extract_fn(rc, stdout, stderr):
- self.assertEqual((rc, stdout, stderr), (0, 'startend', 'STARTEND'))
- return dict(a=1, b=2)
- self.setupStep(shell.SetPropertyFromCommand(extract_fn=extract_fn, command="cmd"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="cmd")
- + ExpectShell.log('stdio', stdout='start', stderr='START')
- + ExpectShell.log('stdio', stdout='end')
- + ExpectShell.log('stdio', stderr='END')
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["2 properties set"])
- self.expectLogfile('property changes', 'a: 1\nb: 2')
- self.expectProperty("a", 1)
- self.expectProperty("b", 2)
- return self.runStep()
-
- def test_run_extract_fn_cmdfail(self):
- def extract_fn(rc, stdout, stderr):
- self.assertEqual((rc, stdout, stderr), (3, '', ''))
- return dict(a=1, b=2)
- self.setupStep(shell.SetPropertyFromCommand(extract_fn=extract_fn, command="cmd"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="cmd")
- + 3
- )
- # note that extract_fn *is* called anyway
- self.expectOutcome(result=FAILURE,
- status_text=["2 properties set"])
- self.expectLogfile('property changes', 'a: 1\nb: 2')
- return self.runStep()
-
- def test_run_extract_fn_cmdfail_empty(self):
- def extract_fn(rc, stdout, stderr):
- self.assertEqual((rc, stdout, stderr), (3, '', ''))
- return dict()
- self.setupStep(shell.SetPropertyFromCommand(extract_fn=extract_fn, command="cmd"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="cmd")
- + 3
- )
- # note that extract_fn *is* called anyway, but returns no properties
- self.expectOutcome(result=FAILURE,
- status_text=["'cmd'", "failed"])
- return self.runStep()
-
- @compat.usesFlushLoggedErrors
- def test_run_extract_fn_exception(self):
- def extract_fn(rc, stdout, stderr):
- raise RuntimeError("oh noes")
- self.setupStep(shell.SetPropertyFromCommand(extract_fn=extract_fn, command="cmd"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="cmd")
- + 0
- )
- # note that extract_fn *is* called anyway, but returns no properties
- self.expectOutcome(result=EXCEPTION,
- status_text=["setproperty", "exception"])
- d = self.runStep()
- d.addCallback(lambda _ :
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1))
- return d
-
-class SetPropertyDeprecation(unittest.TestCase):
- """
- Tests for L{shell.SetProperty}
- """
-
- def test_deprecated(self):
- """
- Accessing L{shell.SetProperty} reports a deprecation error.
- """
- shell.SetProperty
- warnings = self.flushWarnings([self.test_deprecated])
- self.assertEqual(len(warnings), 1)
- self.assertIdentical(warnings[0]['category'], DeprecationWarning)
- self.assertEqual(warnings[0]['message'],
- "buildbot.steps.shell.SetProperty was deprecated in Buildbot 0.8.8: "
- "It has been renamed to SetPropertyFromCommand"
- )
-
-
-class Configure(unittest.TestCase):
-
- def test_class_attrs(self):
- # nothing too exciting here, but at least make sure the class is present
- step = shell.Configure()
- self.assertEqual(step.command, ['./configure'])
-
-class WarningCountingShellCommand(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_no_warnings(self):
- self.setupStep(shell.WarningCountingShellCommand(workdir='w',
- command=['make']))
- self.expectCommands(
- ExpectShell(workdir='w', usePTY='slave-config',
- command=["make"])
- + ExpectShell.log('stdio', stdout='blarg success!')
- + 0
- )
- self.expectOutcome(result=SUCCESS, status_text=["'make'"])
- self.expectProperty("warnings-count", 0)
- return self.runStep()
-
- def test_default_pattern(self):
- self.setupStep(shell.WarningCountingShellCommand(command=['make']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=["make"])
- + ExpectShell.log('stdio',
- stdout='normal: foo\nwarning: blarg!\nalso normal')
- + 0
- )
- self.expectOutcome(result=WARNINGS, status_text=["'make'", "warnings"])
- self.expectProperty("warnings-count", 1)
- self.expectLogfile("warnings (1)", "warning: blarg!\n")
- return self.runStep()
-
- def test_custom_pattern(self):
- self.setupStep(shell.WarningCountingShellCommand(command=['make'],
- warningPattern=r"scary:.*"))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=["make"])
- + ExpectShell.log('stdio',
- stdout='scary: foo\nwarning: bar\nscary: bar')
- + 0
- )
- self.expectOutcome(result=WARNINGS, status_text=["'make'", "warnings"])
- self.expectProperty("warnings-count", 2)
- self.expectLogfile("warnings (2)", "scary: foo\nscary: bar\n")
- return self.runStep()
-
- def test_maxWarnCount(self):
- self.setupStep(shell.WarningCountingShellCommand(command=['make'],
- maxWarnCount=9))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=["make"])
- + ExpectShell.log('stdio', stdout='warning: noo!\n' * 10)
- + 0
- )
- self.expectOutcome(result=FAILURE, status_text=["'make'", "failed"])
- self.expectProperty("warnings-count", 10)
- return self.runStep()
-
- def test_fail_with_warnings(self):
- self.setupStep(shell.WarningCountingShellCommand(command=['make']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=["make"])
- + ExpectShell.log('stdio', stdout='warning: I might fail')
- + 3
- )
- self.expectOutcome(result=FAILURE, status_text=["'make'", "failed"])
- self.expectProperty("warnings-count", 1)
- self.expectLogfile("warnings (1)", "warning: I might fail\n")
- return self.runStep()
-
- def do_test_suppressions(self, step, supps_file='', stdout='',
- exp_warning_count=0, exp_warning_log='',
- exp_exception=False):
- self.setupStep(step)
-
- # Invoke the expected callbacks for the suppression file upload. Note
- # that this assumes all of the remote_* are synchronous, but can be
- # easily adapted to suit if that changes (using inlineCallbacks)
- def upload_behavior(command):
- writer = command.args['writer']
- writer.remote_write(supps_file)
- writer.remote_close()
-
- self.expectCommands(
- # step will first get the remote suppressions file
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='supps', workdir='wkdir',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(upload_behavior),
-
- # and then run the command
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=["make"])
- + ExpectShell.log('stdio', stdout=stdout)
- + 0
- )
- if exp_exception:
- self.expectOutcome(result=EXCEPTION,
- status_text=["shell", "exception"])
- else:
- if exp_warning_count != 0:
- self.expectOutcome(result=WARNINGS,
- status_text=["'make'", "warnings"])
- self.expectLogfile("warnings (%d)" % exp_warning_count,
- exp_warning_log)
- else:
- self.expectOutcome(result=SUCCESS,
- status_text=["'make'"])
- self.expectProperty("warnings-count", exp_warning_count)
- return self.runStep()
-
- def test_suppressions(self):
- step = shell.WarningCountingShellCommand(command=['make'],
- suppressionFile='supps')
- supps_file = textwrap.dedent("""\
- # example suppressions file
-
- amar.c : .*unused variable.*
- holding.c : .*invalid access to non-static.*
- """).strip()
- stdout = textwrap.dedent("""\
- /bin/sh ../libtool --tag=CC --silent --mode=link gcc blah
- /bin/sh ../libtool --tag=CC --silent --mode=link gcc blah
- amar.c: In function 'write_record':
- amar.c:164: warning: unused variable 'x'
- amar.c:164: warning: this should show up
- /bin/sh ../libtool --tag=CC --silent --mode=link gcc blah
- /bin/sh ../libtool --tag=CC --silent --mode=link gcc blah
- holding.c: In function 'holding_thing':
- holding.c:984: warning: invalid access to non-static 'y'
- """)
- exp_warning_log = textwrap.dedent("""\
- amar.c:164: warning: this should show up
- """)
- return self.do_test_suppressions(step, supps_file, stdout, 1,
- exp_warning_log)
-
- def test_suppressions_directories(self):
- def warningExtractor(step, line, match):
- return line.split(':', 2)
- step = shell.WarningCountingShellCommand(command=['make'],
- suppressionFile='supps',
- warningExtractor=warningExtractor)
- supps_file = textwrap.dedent("""\
- # these should be suppressed:
- amar-src/amar.c : XXX
- .*/server-src/.* : AAA
- # these should not, as the dirs do not match:
- amar.c : YYY
- server-src.* : BBB
- """).strip()
- # note that this uses the unicode smart-quotes that gcc loves so much
- stdout = textwrap.dedent(u"""\
- make: Entering directory \u2019amar-src\u2019
- amar.c:164: warning: XXX
- amar.c:165: warning: YYY
- make: Leaving directory 'amar-src'
- make: Entering directory "subdir"
- make: Entering directory 'server-src'
- make: Entering directory `one-more-dir`
- holding.c:999: warning: BBB
- holding.c:1000: warning: AAA
- """)
- exp_warning_log = textwrap.dedent("""\
- amar.c:165: warning: YYY
- holding.c:999: warning: BBB
- """)
- return self.do_test_suppressions(step, supps_file, stdout, 2,
- exp_warning_log)
-
- def test_suppressions_directories_custom(self):
- def warningExtractor(step, line, match):
- return line.split(':', 2)
- step = shell.WarningCountingShellCommand(command=['make'],
- suppressionFile='supps',
- warningExtractor=warningExtractor,
- directoryEnterPattern="^IN: (.*)",
- directoryLeavePattern="^OUT:")
- supps_file = "dir1/dir2/abc.c : .*"
- stdout = textwrap.dedent(u"""\
- IN: dir1
- IN: decoy
- OUT: decoy
- IN: dir2
- abc.c:123: warning: hello
- """)
- return self.do_test_suppressions(step, supps_file, stdout, 0, '')
-
- def test_suppressions_linenos(self):
- def warningExtractor(step, line, match):
- return line.split(':', 2)
- step = shell.WarningCountingShellCommand(command=['make'],
- suppressionFile='supps',
- warningExtractor=warningExtractor)
- supps_file = "abc.c:.*:100-199\ndef.c:.*:22"
- stdout = textwrap.dedent(u"""\
- abc.c:99: warning: seen 1
- abc.c:150: warning: unseen
- def.c:22: warning: unseen
- abc.c:200: warning: seen 2
- """)
- exp_warning_log = textwrap.dedent(u"""\
- abc.c:99: warning: seen 1
- abc.c:200: warning: seen 2
- """)
- return self.do_test_suppressions(step, supps_file, stdout, 2,
- exp_warning_log)
-
- @compat.usesFlushLoggedErrors
- def test_suppressions_warningExtractor_exc(self):
- def warningExtractor(step, line, match):
- raise RuntimeError("oh noes")
- step = shell.WarningCountingShellCommand(command=['make'],
- suppressionFile='supps',
- warningExtractor=warningExtractor)
- supps_file = 'x:y' # need at least one supp to trigger warningExtractor
- stdout = "abc.c:99: warning: seen 1"
- d = self.do_test_suppressions(step, supps_file, stdout,
- exp_exception=True)
- d.addCallback(lambda _ :
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1))
- return d
-
- def test_suppressions_addSuppression(self):
- # call addSuppression "manually" from a subclass
- class MyWCSC(shell.WarningCountingShellCommand):
- def start(self):
- self.addSuppression([('.*', '.*unseen.*', None, None)])
- return shell.WarningCountingShellCommand.start(self)
-
- def warningExtractor(step, line, match):
- return line.split(':', 2)
- step = MyWCSC(command=['make'], suppressionFile='supps',
- warningExtractor=warningExtractor)
- stdout = textwrap.dedent(u"""\
- abc.c:99: warning: seen 1
- abc.c:150: warning: unseen
- abc.c:200: warning: seen 2
- """)
- exp_warning_log = textwrap.dedent(u"""\
- abc.c:99: warning: seen 1
- abc.c:200: warning: seen 2
- """)
- return self.do_test_suppressions(step, '', stdout, 2,
- exp_warning_log)
-
- def test_warnExtractFromRegexpGroups(self):
- step = shell.WarningCountingShellCommand(command=['make'])
- we = shell.WarningCountingShellCommand.warnExtractFromRegexpGroups
- line, pat, exp_file, exp_lineNo, exp_text = \
- ('foo:123:text', '(.*):(.*):(.*)', 'foo', 123, 'text')
- self.assertEqual(we(step, line, re.match(pat, line)),
- (exp_file, exp_lineNo, exp_text))
-
-class Compile(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_class_args(self):
- # since this step is just a pre-configured WarningCountingShellCommand,
- # there' not much to test!
- step = self.setupStep(shell.Compile())
- self.assertEqual(step.name, "compile")
- self.assertTrue(step.haltOnFailure)
- self.assertTrue(step.flunkOnFailure)
- self.assertEqual(step.description, ["compiling"])
- self.assertEqual(step.descriptionDone, ["compile"])
- self.assertEqual(step.command, ["make", "all"])
-
-class Test(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- self.setUpBuildStep()
-
- def tearDown(self):
- self.tearDownBuildStep()
-
- def test_setTestResults(self):
- step = self.setupStep(shell.Test())
- step.setTestResults(total=10, failed=3, passed=5, warnings=3)
- self.assertEqual(self.step_statistics, {
- 'tests-total' : 10,
- 'tests-failed' : 3,
- 'tests-passed' : 5,
- 'tests-warnings' : 3,
- })
- # ensure that they're additive
- step.setTestResults(total=1, failed=2, passed=3, warnings=4)
- self.assertEqual(self.step_statistics, {
- 'tests-total' : 11,
- 'tests-failed' : 5,
- 'tests-passed' : 8,
- 'tests-warnings' : 7,
- })
-
- def test_describe_not_done(self):
- step = self.setupStep(shell.Test())
- self.assertEqual(step.describe(), ['testing'])
-
- def test_describe_done(self):
- step = self.setupStep(shell.Test())
- self.step_statistics['tests-total'] = 93
- self.step_statistics['tests-failed'] = 10
- self.step_statistics['tests-passed'] = 20
- self.step_statistics['tests-warnings'] = 30
- self.assertEqual(step.describe(done=True), [ 'test', '93 tests',
- '20 passed', '30 warnings', '10 failed'])
-
- def test_describe_done_no_total(self):
- step = self.setupStep(shell.Test())
- self.step_statistics['tests-total'] = 0
- self.step_statistics['tests-failed'] = 10
- self.step_statistics['tests-passed'] = 20
- self.step_statistics['tests-warnings'] = 30
- # describe calculates 60 = 10+20+30
- self.assertEqual(step.describe(done=True), [ 'test', '60 tests',
- '20 passed', '30 warnings', '10 failed'])
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_slave.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_slave.py
deleted file mode 100644
index 8052dca7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_slave.py
+++ /dev/null
@@ -1,381 +0,0 @@
-# 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 stat
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.steps import slave
-from buildbot.status.results import SUCCESS, FAILURE, EXCEPTION
-from buildbot.process import properties, buildstep
-from buildbot.test.fake.remotecommand import Expect
-from buildbot.test.util import steps, compat
-from buildbot.interfaces import BuildSlaveTooOldError
-
-class TestSetPropertiesFromEnv(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_simple(self):
- self.setupStep(slave.SetPropertiesFromEnv(
- variables=["one", "two", "three", "five", "six"],
- source="me"))
- self.buildslave.slave_environ = { "one": "1", "two": None, "six": "6", "FIVE" : "555" }
- self.properties.setProperty("four", 4, "them")
- self.properties.setProperty("five", 5, "them")
- self.properties.setProperty("six", 99, "them")
- self.expectOutcome(result=SUCCESS,
- status_text=["Set"])
- self.expectProperty('one', "1", source='me')
- self.expectNoProperty('two')
- self.expectNoProperty('three')
- self.expectProperty('four', 4, source='them')
- self.expectProperty('five', 5, source='them')
- self.expectProperty('six', '6', source='me')
- self.expectLogfile("properties",
- "one = '1'\nsix = '6'")
- return self.runStep()
-
- def test_case_folding(self):
- self.setupStep(slave.SetPropertiesFromEnv(
- variables=["eNv"], source="me"))
- self.buildslave.slave_environ = { "ENV": 'EE' }
- self.buildslave.slave_system = 'win32'
- self.expectOutcome(result=SUCCESS,
- status_text=["Set"])
- self.expectProperty('eNv', 'EE', source='me')
- self.expectLogfile("properties",
- "eNv = 'EE'")
- return self.runStep()
-
-
-class TestFileExists(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_found(self):
- self.setupStep(slave.FileExists(file="x"))
- self.expectCommands(
- Expect('stat', { 'file' : 'x' })
- + Expect.update('stat', [stat.S_IFREG, 99, 99])
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["File found."])
- return self.runStep()
-
- def test_not_found(self):
- self.setupStep(slave.FileExists(file="x"))
- self.expectCommands(
- Expect('stat', { 'file' : 'x' })
- + Expect.update('stat', [0, 99, 99])
- + 0
- )
- self.expectOutcome(result=FAILURE,
- status_text=["Not a file."])
- return self.runStep()
-
- def test_failure(self):
- self.setupStep(slave.FileExists(file="x"))
- self.expectCommands(
- Expect('stat', { 'file' : 'x' })
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["File not found."])
- return self.runStep()
-
- def test_render(self):
- self.setupStep(slave.FileExists(file=properties.Property("x")))
- self.properties.setProperty('x', 'XXX', 'here')
- self.expectCommands(
- Expect('stat', { 'file' : 'XXX' })
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["File not found."])
- return self.runStep()
-
- @compat.usesFlushLoggedErrors
- def test_old_version(self):
- self.setupStep(slave.FileExists(file="x"),
- slave_version=dict())
- self.expectOutcome(result=EXCEPTION,
- status_text=["FileExists", "exception"])
- d = self.runStep()
- def check(_):
- self.assertEqual(
- len(self.flushLoggedErrors(BuildSlaveTooOldError)), 1)
- d.addCallback(check)
- return d
-
-
-class TestCopyDirectory(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_success(self):
- self.setupStep(slave.CopyDirectory(src="s", dest="d"))
- self.expectCommands(
- Expect('cpdir', { 'fromdir' : 's', 'todir' : 'd' })
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["Copied", "s", "to", "d"])
- return self.runStep()
-
- def test_timeout(self):
- self.setupStep(slave.CopyDirectory(src="s", dest="d", timeout=300))
- self.expectCommands(
- Expect('cpdir', { 'fromdir' : 's', 'todir' : 'd', 'timeout': 300 })
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["Copied", "s", "to", "d"])
- return self.runStep()
-
- def test_maxTime(self):
- self.setupStep(slave.CopyDirectory(src="s", dest="d", maxTime=10))
- self.expectCommands(
- Expect('cpdir', { 'fromdir' : 's', 'todir' : 'd', 'maxTime': 10 })
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["Copied", "s", "to", "d"])
- return self.runStep()
-
- def test_failure(self):
- self.setupStep(slave.CopyDirectory(src="s", dest="d"))
- self.expectCommands(
- Expect('cpdir', { 'fromdir' : 's', 'todir' : 'd' })
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["Copying", "s", "to", "d", "failed."])
- return self.runStep()
-
- def test_render(self):
- self.setupStep(slave.CopyDirectory(src=properties.Property("x"), dest=properties.Property("y")))
- self.properties.setProperty('x', 'XXX', 'here')
- self.properties.setProperty('y', 'YYY', 'here')
- self.expectCommands(
- Expect('cpdir', { 'fromdir' : 'XXX', 'todir' : 'YYY' })
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["Copied", "XXX", "to", "YYY"])
- return self.runStep()
-
-class TestRemoveDirectory(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_success(self):
- self.setupStep(slave.RemoveDirectory(dir="d"))
- self.expectCommands(
- Expect('rmdir', { 'dir' : 'd' })
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["Deleted"])
- return self.runStep()
-
- def test_failure(self):
- self.setupStep(slave.RemoveDirectory(dir="d"))
- self.expectCommands(
- Expect('rmdir', { 'dir' : 'd' })
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["Delete failed."])
- return self.runStep()
-
- def test_render(self):
- self.setupStep(slave.RemoveDirectory(dir=properties.Property("x")))
- self.properties.setProperty('x', 'XXX', 'here')
- self.expectCommands(
- Expect('rmdir', { 'dir' : 'XXX' })
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["Deleted"])
- return self.runStep()
-
-class TestMakeDirectory(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_success(self):
- self.setupStep(slave.MakeDirectory(dir="d"))
- self.expectCommands(
- Expect('mkdir', { 'dir' : 'd' })
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["Created"])
- return self.runStep()
-
- def test_failure(self):
- self.setupStep(slave.MakeDirectory(dir="d"))
- self.expectCommands(
- Expect('mkdir', { 'dir' : 'd' })
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["Create failed."])
- return self.runStep()
-
- def test_render(self):
- self.setupStep(slave.MakeDirectory(dir=properties.Property("x")))
- self.properties.setProperty('x', 'XXX', 'here')
- self.expectCommands(
- Expect('mkdir', { 'dir' : 'XXX' })
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["Created"])
- return self.runStep()
-
-class CompositeUser(buildstep.LoggingBuildStep, slave.CompositeStepMixin):
- def __init__(self, payload):
- self.payload = payload
- self.logEnviron=False
- buildstep.LoggingBuildStep.__init__(self)
- def start(self):
- self.addLogForRemoteCommands('stdio')
- d = self.payload(self)
- d.addCallback(self.commandComplete)
- d.addErrback(self.failed)
- def commandComplete(self,res):
- self.finished(FAILURE if res else SUCCESS)
-
-class TestCompositeStepMixin(steps.BuildStepMixin, unittest.TestCase):
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_runRemoteCommand(self):
- cmd_args = ('foo', {'bar': False})
- def testFunc(x):
- x.runRemoteCommand(*cmd_args)
- self.setupStep(CompositeUser(testFunc))
- self.expectCommands(Expect(*cmd_args)+0)
- self.expectOutcome(result=SUCCESS,
- status_text=["generic"])
-
- def test_runRemoteCommandFail(self):
- cmd_args = ('foo', {'bar': False})
- @defer.inlineCallbacks
- def testFunc(x):
- yield x.runRemoteCommand(*cmd_args)
- self.setupStep(CompositeUser(testFunc))
- self.expectCommands(Expect(*cmd_args)+1)
- self.expectOutcome(result=FAILURE,
- status_text=["generic"])
- return self.runStep()
-
- def test_runRemoteCommandFailNoAbandon(self):
- cmd_args = ('foo', {'bar': False})
- @defer.inlineCallbacks
- def testFunc(x):
- res = yield x.runRemoteCommand(*cmd_args,
- **dict(abandonOnFailure=False))
- x.step_status.setText([str(res)])
- self.setupStep(CompositeUser(testFunc))
- self.expectCommands(Expect(*cmd_args)+1)
- self.expectOutcome(result=SUCCESS,
- status_text=["True"])
- return self.runStep()
-
- def test_mkdir(self):
- self.setupStep(CompositeUser(lambda x:x.runMkdir("d")))
- self.expectCommands(
- Expect('mkdir', { 'dir' : 'd' , 'logEnviron': False})
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["generic"])
- return self.runStep()
-
- def test_rmdir(self):
- self.setupStep(CompositeUser(lambda x:x.runRmdir("d")))
- self.expectCommands(
- Expect('rmdir', { 'dir' : 'd' , 'logEnviron': False})
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["generic"])
- return self.runStep()
-
- def test_mkdir_fail(self):
- self.setupStep(CompositeUser(lambda x:x.runMkdir("d")))
- self.expectCommands(
- Expect('mkdir', { 'dir' : 'd' , 'logEnviron': False})
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["generic"])
- return self.runStep()
-
- def test_abandonOnFailure(self):
- @defer.inlineCallbacks
- def testFunc(x):
- yield x.runMkdir("d")
- yield x.runMkdir("d")
- self.setupStep(CompositeUser(testFunc))
- self.expectCommands(
- Expect('mkdir', { 'dir' : 'd' , 'logEnviron': False})
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["generic"])
- return self.runStep()
-
- def test_notAbandonOnFailure(self):
- @defer.inlineCallbacks
- def testFunc(x):
- yield x.runMkdir("d", abandonOnFailure=False)
- yield x.runMkdir("d", abandonOnFailure=False)
- self.setupStep(CompositeUser(testFunc))
- self.expectCommands(
- Expect('mkdir', { 'dir' : 'd' , 'logEnviron': False})
- + 1,
- Expect('mkdir', { 'dir' : 'd' , 'logEnviron': False})
- + 1
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["generic"])
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_base_Source.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_base_Source.py
deleted file mode 100644
index 3260e479..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_base_Source.py
+++ /dev/null
@@ -1,137 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-
-from buildbot.steps.source import Source
-from buildbot.test.util import steps, sourcesteps
-
-class TestSource(sourcesteps.SourceStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_start_alwaysUseLatest_True(self):
- step = self.setupStep(Source(alwaysUseLatest=True),
- {
- 'branch': 'other-branch',
- 'revision': 'revision',
- },
- patch = 'patch'
- )
- step.branch = 'branch'
- step.startVC = mock.Mock()
-
- step.startStep(mock.Mock())
-
- self.assertEqual(step.startVC.call_args, (('branch', None, None), {}))
-
- def test_start_alwaysUseLatest_False(self):
- step = self.setupStep(Source(),
- {
- 'branch': 'other-branch',
- 'revision': 'revision',
- },
- patch = 'patch'
- )
- step.branch = 'branch'
- step.startVC = mock.Mock()
-
- step.startStep(mock.Mock())
-
- self.assertEqual(step.startVC.call_args, (('other-branch', 'revision', 'patch'), {}))
-
- def test_start_alwaysUseLatest_False_no_branch(self):
- step = self.setupStep(Source())
- step.branch = 'branch'
- step.startVC = mock.Mock()
-
- step.startStep(mock.Mock())
-
- self.assertEqual(step.startVC.call_args, (('branch', None, None), {}))
-
- def test_start_no_codebase(self):
- step = self.setupStep(Source())
- step.branch = 'branch'
- step.startVC = mock.Mock()
- step.build.getSourceStamp = mock.Mock()
- step.build.getSourceStamp.return_value = None
-
- self.assertEqual(step.describe(), ['updating'])
- self.assertEqual(step.name, Source.name)
-
- step.startStep(mock.Mock())
- self.assertEqual(step.build.getSourceStamp.call_args[0], ('',))
-
- self.assertEqual(step.description, ['updating'])
-
- def test_start_with_codebase(self):
- step = self.setupStep(Source(codebase='codebase'))
- step.branch = 'branch'
- step.startVC = mock.Mock()
- step.build.getSourceStamp = mock.Mock()
- step.build.getSourceStamp.return_value = None
-
- self.assertEqual(step.describe(), ['updating', 'codebase'])
- self.assertEqual(step.name, Source.name + " codebase")
-
- step.startStep(mock.Mock())
- self.assertEqual(step.build.getSourceStamp.call_args[0], ('codebase',))
-
- self.assertEqual(step.describe(True), ['update', 'codebase'])
-
- def test_start_with_codebase_and_descriptionSuffix(self):
- step = self.setupStep(Source(codebase='my-code',
- descriptionSuffix='suffix'))
- step.branch = 'branch'
- step.startVC = mock.Mock()
- step.build.getSourceStamp = mock.Mock()
- step.build.getSourceStamp.return_value = None
-
- self.assertEqual(step.describe(), ['updating', 'suffix'])
- self.assertEqual(step.name, Source.name + " my-code")
-
- step.startStep(mock.Mock())
- self.assertEqual(step.build.getSourceStamp.call_args[0], ('my-code',))
-
- self.assertEqual(step.describe(True), ['update', 'suffix'])
-
-
-class TestSourceDescription(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_constructor_args_strings(self):
- step = Source(workdir='build',
- description='svn update (running)',
- descriptionDone='svn update')
- self.assertEqual(step.description, ['svn update (running)'])
- self.assertEqual(step.descriptionDone, ['svn update'])
-
- def test_constructor_args_lists(self):
- step = Source(workdir='build',
- description=['svn', 'update', '(running)'],
- descriptionDone=['svn', 'update'])
- self.assertEqual(step.description, ['svn', 'update', '(running)'])
- self.assertEqual(step.descriptionDone, ['svn', 'update'])
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_bzr.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_bzr.py
deleted file mode 100644
index e1e84dbb..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_bzr.py
+++ /dev/null
@@ -1,482 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from twisted.python.reflect import namedModule
-from buildbot.steps.source import bzr
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.test.util import sourcesteps
-from buildbot.test.fake.remotecommand import ExpectShell, Expect
-import os.path
-
-class TestBzr(sourcesteps.SourceStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpSourceStep()
-
- def tearDown(self):
- return self.tearDownSourceStep()
-
- def test_mode_full(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='fresh'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'clean-tree', '--force'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'update'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
- def test_mode_full_win32path(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='fresh'))
- self.build.path_module = namedModule('ntpath')
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file=r'wkdir\.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'clean-tree', '--force'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'update'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_timeout(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='fresh', timeout=1))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['bzr', 'clean-tree', '--force'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['bzr', 'update'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
- def test_mode_full_revision(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='fresh'),
- args=dict(revision='3730'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'clean-tree', '--force'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'update', '-r', '3730'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
- def test_mode_full_clean(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'clean-tree', '--ignored', '--force'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'update'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
- def test_mode_full_clean_revision(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='clean'),
- args=dict(revision='2345'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'clean-tree', '--ignored', '--force'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'update', '-r', '2345'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
- def test_mode_full_fresh(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='fresh'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'clean-tree', '--force'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'update'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
- def test_mode_full_clobber(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='clobber'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'checkout',
- 'http://bzr.squid-cache.org/bzr/squid3/trunk', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
-
- def test_mode_full_clobber_revision(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='clobber'),
- args=dict(revision='3730'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'checkout',
- 'http://bzr.squid-cache.org/bzr/squid3/trunk',
- '.', '-r', '3730'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
-
- def test_mode_full_clobber_baseurl(self):
- self.setupStep(
- bzr.Bzr(baseURL='http://bzr.squid-cache.org/bzr/squid3',
- defaultBranch='trunk', mode='full', method='clobber'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'checkout',
- os.path.join('http://bzr.squid-cache.org/bzr/squid3', 'trunk'), '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
-
- def test_mode_full_clobber_baseurl_nodefault(self):
- self.setupStep(
- bzr.Bzr(baseURL='http://bzr.squid-cache.org/bzr/squid3',
- defaultBranch='trunk', mode='full', method='clobber'),
- args=dict(branch='branches/SQUID_3_0'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'checkout',
- os.path.join('http://bzr.squid-cache.org/bzr/squid3', 'branches/SQUID_3_0'), '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
-
- def test_mode_full_copy(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='full', method='copy'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('rmdir', dict(dir='build',
- logEnviron=True))
- + 0,
- Expect('stat', dict(file='source/.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='source',
- command=['bzr', 'update'])
- + 0,
- Expect('cpdir', {'fromdir': 'source',
- 'logEnviron': True,
- 'todir': 'build'})
- + 0,
- ExpectShell(workdir='source',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
- def test_mode_incremental(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='incremental'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'update'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
- def test_mode_incremental_revision(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='incremental'),
- args=dict(revision='9384'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'update', '-r', '9384'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'Bzr')
- return self.runStep()
-
- def test_mode_incremental_no_existing_repo(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='incremental'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'checkout',
- 'http://bzr.squid-cache.org/bzr/squid3/trunk', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='100\n')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100\n', 'Bzr')
- return self.runStep()
-
- def test_bad_revparse(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='incremental'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'checkout',
- 'http://bzr.squid-cache.org/bzr/squid3/trunk', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'version-info', '--custom', "--template='{revno}"])
- + ExpectShell.log('stdio',
- stdout='oiasdfj010laksjfd')
- + 0,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_bad_checkout(self):
- self.setupStep(
- bzr.Bzr(repourl='http://bzr.squid-cache.org/bzr/squid3/trunk',
- mode='incremental'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['bzr', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.bzr',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['bzr', 'checkout',
- 'http://bzr.squid-cache.org/bzr/squid3/trunk', '.'])
- + ExpectShell.log('stdio',
- stderr='failed\n')
- + 128,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_cvs.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_cvs.py
deleted file mode 100644
index 7f39cdb5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_cvs.py
+++ /dev/null
@@ -1,765 +0,0 @@
-# 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 time
-from twisted.trial import unittest
-from buildbot.steps import shell
-from buildbot.steps.source import cvs
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.test.util import sourcesteps
-from buildbot.test.fake.remotecommand import ExpectShell, Expect, ExpectRemoteRef
-
-def uploadString(cvsroot):
- def behavior(command):
- writer = command.args['writer']
- writer.remote_write(cvsroot + "\n")
- writer.remote_close()
- return behavior
-
-class TestCVS(sourcesteps.SourceStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpSourceStep()
-
- def tearDown(self):
- return self.tearDownSourceStep()
-
- def setupStep(self, step, *args, **kwargs):
- sourcesteps.SourceStepMixin.setupStep(self, step, *args, **kwargs)
-
- # make parseGotRevision return something consistent, patching the class
- # instead of the object since a new object is constructed by runTest.
- def parseGotRevision(self, res):
- self.updateSourceProperty('got_revision',
- '2012-09-09 12:00:39 +0000')
- return res
- self.patch(cvs.CVS, 'parseGotRevision', parseGotRevision)
-
- def test_parseGotRevision(self):
- def gmtime():
- return time.struct_time((2012, 9, 9, 12, 9, 33, 6, 253, 0))
- self.patch(time, 'gmtime', gmtime)
-
- step = cvs.CVS(cvsroot="x", cvsmodule="m", mode='full', method='clean')
- props = []
- def updateSourceProperty(prop, name):
- props.append((prop, name))
- step.updateSourceProperty = updateSourceProperty
-
- self.assertEqual(step.parseGotRevision(10), 10) # passes res along
- self.assertEqual(props,
- [('got_revision', '2012-09-09 12:09:33 +0000')])
-
- def test_mode_full_clean(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='clean',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvsdiscard'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_full_clean_timeout(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='clean',
- login=True, timeout=1))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['cvsdiscard'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['cvs', '-z3', 'update', '-dP'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_full_clean_branch(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='clean',
- branch='branch', login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvsdiscard'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP', '-r', 'branch'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_full_clean_branch_sourcestamp(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='clean',
- login=True), args={'branch':'my_branch'})
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvsdiscard'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP', '-r', 'my_branch'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_full_fresh(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='fresh',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvsdiscard', '--ignore'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_full_clobber(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='clobber',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='',
- command=['cvs',
- '-d',
- ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot',
- '-z3', 'checkout', '-d', 'wkdir', 'mozilla/browser/'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_full_copy(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='copy',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='source/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='source/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='source',
- command=['cvs', '-z3', 'update', '-dP'])
- + 0,
- Expect('cpdir', {'fromdir': 'source', 'todir': 'build',
- 'logEnviron': True})
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
-
- def test_mode_full_copy_wrong_repo(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='copy',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='source/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('the-end-of-the-universe'))
- + 0,
- Expect('rmdir', dict(dir='source',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='',
- command=['cvs',
- '-d',
- ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot',
- '-z3', 'checkout', '-d', 'source', 'mozilla/browser/'])
- + 0,
- Expect('cpdir', {'fromdir': 'source', 'todir': 'build',
- 'logEnviron': True})
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_incremental(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_incremental_password_windows(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:dustin:secrets@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- # on Windows, this file does not contain the password, per
- # http://trac.buildbot.net/ticket/2355
- + Expect.behavior(uploadString(':pserver:dustin@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_branch(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- branch='my_branch', login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP', '-r', 'my_branch'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_incremental_special_case(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- branch='HEAD', login=True),
- args=dict(revision='2012-08-16 16:05:16 +0000'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP',
- # note, no -r HEAD here - that's the special case
- '-D', '2012-08-16 16:05:16 +0000'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_branch_sourcestamp(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=True), args={'branch':'my_branch'})
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP', '-r', 'my_branch'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
-
- def test_mode_incremental_not_loggedin(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=False))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-d',
- ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot',
- 'login'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
-
- def test_mode_incremental_no_existing_repo(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + 1,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='',
- command=['cvs',
- '-d',
- ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot',
- '-z3', 'checkout', '-d', 'wkdir', 'mozilla/browser/'])
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
-
- def test_mode_incremental_wrong_repo(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('the-end-of-the-universe'))
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='',
- command=['cvs',
- '-d',
- ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot',
- '-z3', 'checkout', '-d', 'wkdir', 'mozilla/browser/'])
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
-
- def test_mode_incremental_wrong_module(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('the-end-of-the-universe'))
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='',
- command=['cvs',
- '-d',
- ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot',
- '-z3', 'checkout', '-d', 'wkdir', 'mozilla/browser/'])
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
-
- def test_mode_full_clean_no_existing_repo(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='clean',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + 1,
- ExpectShell(workdir='',
- command=['cvs',
- '-d',
- ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot',
- '-z3', 'checkout', '-d', 'wkdir', 'mozilla/browser/'])
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_full_clean_wrong_repo(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='clean',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('the-end-of-the-universe'))
- + 0,
- ExpectShell(workdir='',
- command=['cvs',
- '-d',
- ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot',
- '-z3', 'checkout', '-d', 'wkdir', 'mozilla/browser/'])
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_full_no_method(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvsdiscard', '--ignore'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP'])
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_incremental_with_options(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=True, global_options=['-q'], extra_options=['-l']))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + 1,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='',
- command=['cvs', '-q', '-d',
- ':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot',
- '-z3', 'checkout', '-d', 'wkdir', '-l', 'mozilla/browser/'])
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_mode_incremental_with_env_logEnviron(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=True, env={'abc': '123'}, logEnviron=False))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'],
- env={'abc': '123'},
- logEnviron=False)
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvs', '-z3', 'update', '-dP'],
- env={'abc': '123'},
- logEnviron=False)
- + 0,
- )
-
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '2012-09-09 12:00:39 +0000', 'CVS')
- return self.runStep()
-
- def test_command_fails(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='incremental',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 128,
- )
-
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_cvsdiscard_fails(self):
- self.setupStep(
- cvs.CVS(cvsroot=":pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot",
- cvsmodule="mozilla/browser/", mode='full', method='fresh',
- login=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['cvs', '--version'])
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Root', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString(':pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot'))
- + 0,
- Expect('uploadFile', dict(blocksize=32768, maxsize=None,
- slavesrc='Repository', workdir='wkdir/CVS',
- writer=ExpectRemoteRef(shell.StringFileWriter)))
- + Expect.behavior(uploadString('mozilla/browser/'))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['cvsdiscard', '--ignore'])
- + ExpectShell.log('stdio',
- stderr='FAIL!\n')
- + 1,
- )
-
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_git.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_git.py
deleted file mode 100644
index 4f60813d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_git.py
+++ /dev/null
@@ -1,1457 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from twisted.python.reflect import namedModule
-from buildbot.steps.source import git
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.test.util import config, sourcesteps
-from buildbot.test.fake.remotecommand import ExpectShell, Expect
-
-class TestGit(sourcesteps.SourceStepMixin, config.ConfigErrorsMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpSourceStep()
-
- def tearDown(self):
- return self.tearDownSourceStep()
-
- def test_mode_full_clean(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_clean_win32path(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clean'))
- self.build.path_module = namedModule('ntpath')
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file=r'wkdir\.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_clean_timeout(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- timeout=1,
- mode='full', method='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['git', 'clean', '-f', '-d'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_clean_patch(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clean'),
- patch=(1, 'patch'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'apply', '--index', '-p', '1'],
- initialStdin='patch')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_clean_patch_fail(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clean'),
- patch=(1, 'patch'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'apply', '--index', '-p', '1'],
- initialStdin='patch')
- + 1,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- self.expectNoProperty('got_revision')
- return self.runStep()
-
- def test_mode_full_clean_branch(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clean', branch='test-branch'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'test-branch'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'branch', '-M', 'test-branch'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_clean_parsefail(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + ExpectShell.log('stdio',
- stderr="fatal: Could not parse object "
- "'b08076bc71c7813038f2cefedff9c5b678d225a8'.\n")
- + 128,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- self.expectNoProperty('got_revision')
- return self.runStep()
-
- def test_mode_full_clean_no_existing_repo(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
-
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_clean_no_existing_repo_branch(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clean', branch='test-branch'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
-
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- '--branch', 'test-branch',
- 'http://github.com/buildbot/buildbot.git', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_clobber(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clobber', progress=True))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git',
- '.', '--progress'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_clobber_branch(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clobber', progress=True, branch='test-branch'))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- '--branch', 'test-branch',
- 'http://github.com/buildbot/buildbot.git',
- '.', '--progress'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_incremental(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
-
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_incremental_branch(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental', branch='test-branch'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'test-branch'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'branch', '-M', 'test-branch'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
-
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_fresh(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='fresh'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d', '-x'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_incremental_given_revision(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental'), dict(
- revision='abcdef01',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'cat-file', '-e', 'abcdef01'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'abcdef01', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_fresh_submodule(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='fresh', submodules=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d', '-x'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'submodule', 'update', '--recursive'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'submodule', 'foreach', 'git', 'clean',
- '-f', '-d', '-x'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_clobber_shallow(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clobber', shallow=True))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone', '--depth', '1',
- 'http://github.com/buildbot/buildbot.git',
- '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_clobber_no_shallow(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clobber'))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git',
- '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_incremental_retryFetch(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental', retryFetch=True))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_incremental_retryFetch_branch(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental', retryFetch=True, branch='test-branch'))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'test-branch'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'test-branch'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'branch', '-M', 'test-branch'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_incremental_clobberOnFailure(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental', clobberOnFailure=True))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 1,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git',
- '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_incremental_clobberOnFailure_branch(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental', clobberOnFailure=True, branch = 'test-branch'))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'test-branch'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 1,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- '--branch', 'test-branch',
- 'http://github.com/buildbot/buildbot.git',
- '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_copy(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='copy'))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200)),
- Expect('stat', dict(file='source/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='source',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='source',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- Expect('cpdir', {'fromdir': 'source', 'todir': 'build',
- 'logEnviron': True, 'timeout': 1200})
- + 0,
- ExpectShell(workdir='build',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_copy_shallow(self):
- self.assertRaisesConfigError("shallow only possible with mode 'full' and method 'clobber'", lambda :
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='copy', shallow=True))
-
- def test_mode_incremental_no_existing_repo(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
-
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_clobber_given_revision(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clobber', progress=True), dict(
- revision='abcdef01',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git',
- '.', '--progress'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'abcdef01', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_revparse_failure(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clobber', progress=True), dict(
- revision='abcdef01',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git',
- '.', '--progress'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'abcdef01', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ada95a1d') # too short
- + 0,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- self.expectNoProperty('got_revision')
- return self.runStep()
-
- def test_mode_full_clobber_submodule(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clobber', submodules=True))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'submodule', 'update',
- '--init', '--recursive'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_repourl(self):
- self.assertRaisesConfigError("must provide repourl", lambda :
- git.Git(mode="full"))
-
- def test_mode_full_fresh_revision(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='fresh', progress=True), dict(
- revision='abcdef01',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git',
- '.', '--progress'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'abcdef01', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_fresh_clobberOnFailure(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='fresh', clobberOnFailure=True))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git', '.'])
- + 1,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git',
- '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_no_method(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d', '-x'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_with_env(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', env={'abc': '123'}))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'],
- env={'abc': '123'})
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d', '-x'],
- env={'abc': '123'})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'],
- env={'abc': '123'})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'],
- env={'abc': '123'})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'],
- env={'abc': '123'})
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_mode_full_logEnviron(self):
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', logEnviron=False))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['git', '--version'],
- logEnviron=False)
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=False))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clean', '-f', '-d', '-x'],
- logEnviron=False)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'],
- logEnviron=False)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'],
- logEnviron=False)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'],
- logEnviron=False)
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- return self.runStep()
-
- def test_getDescription(self):
- # clone of: test_mode_incremental
- # only difference is to set the getDescription property
-
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental',
- getDescription=True))
- self.expectCommands(
- ## copied from test_mode_incremental:
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
-
- ## plus this to test describe:
- ExpectShell(workdir='wkdir',
- command=['git', 'describe', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='Tag-1234')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- self.expectProperty('commit-description', 'Tag-1234', 'Git')
- return self.runStep()
-
- def test_getDescription_failed(self):
- # clone of: test_mode_incremental
- # only difference is to set the getDescription property
-
- # this tests when 'git describe' fails; for example, there are no
- # tags in the repository
-
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='incremental',
- getDescription=True))
- self.expectCommands(
- ## copied from test_mode_incremental:
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'fetch', '-t',
- 'http://github.com/buildbot/buildbot.git',
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'reset', '--hard', 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
-
- ## plus this to test describe:
- ExpectShell(workdir='wkdir',
- command=['git', 'describe', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='')
- + 128, # error, but it's suppressed
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- self.expectNoProperty('commit-description')
- return self.runStep()
-
- def setup_getDescription_test(self, setup_args, output_args, codebase=None):
- # clone of: test_mode_full_clobber
- # only difference is to set the getDescription property
-
- kwargs = {}
- if codebase is not None:
- kwargs.update(codebase=codebase)
-
- self.setupStep(
- git.Git(repourl='http://github.com/buildbot/buildbot.git',
- mode='full', method='clobber', progress=True,
- getDescription=setup_args,
- **kwargs))
-
- self.expectCommands(
- ## copied from test_mode_full_clobber:
- ExpectShell(workdir='wkdir',
- command=['git', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True,
- timeout=1200))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'clone',
- 'http://github.com/buildbot/buildbot.git',
- '.', '--progress'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['git', 'rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
-
- ## plus this to test describe:
- ExpectShell(workdir='wkdir',
- command=['git', 'describe'] +
- output_args +
- ['HEAD'])
- + ExpectShell.log('stdio',
- stdout='Tag-1234')
- + 0,
- )
-
- if codebase:
- self.expectOutcome(result=SUCCESS, status_text=["update", codebase])
- self.expectProperty('got_revision', {codebase:'f6ad368298bd941e934a41f3babc827b2aa95a1d'}, 'Git')
- self.expectProperty('commit-description', {codebase:'Tag-1234'}, 'Git')
- else:
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'f6ad368298bd941e934a41f3babc827b2aa95a1d', 'Git')
- self.expectProperty('commit-description', 'Tag-1234', 'Git')
-
- def test_getDescription_empty_dict(self):
- self.setup_getDescription_test(
- setup_args = {},
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_empty_dict_with_codebase(self):
- self.setup_getDescription_test(
- setup_args = {},
- output_args = [],
- codebase = 'baz'
- )
- return self.runStep()
-
- def test_getDescription_match(self):
- self.setup_getDescription_test(
- setup_args = { 'match': 'stuff-*' },
- output_args = ['--match', 'stuff-*']
- )
- return self.runStep()
- def test_getDescription_match_false(self):
- self.setup_getDescription_test(
- setup_args = { 'match': None },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_tags(self):
- self.setup_getDescription_test(
- setup_args = { 'tags': True },
- output_args = ['--tags']
- )
- return self.runStep()
- def test_getDescription_tags_false(self):
- self.setup_getDescription_test(
- setup_args = { 'tags': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_all(self):
- self.setup_getDescription_test(
- setup_args = { 'all': True },
- output_args = ['--all']
- )
- return self.runStep()
- def test_getDescription_all_false(self):
- self.setup_getDescription_test(
- setup_args = { 'all': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_abbrev(self):
- self.setup_getDescription_test(
- setup_args = { 'abbrev': 7 },
- output_args = ['--abbrev=7']
- )
- return self.runStep()
- def test_getDescription_abbrev_zero(self):
- self.setup_getDescription_test(
- setup_args = { 'abbrev': 0 },
- output_args = ['--abbrev=0']
- )
- return self.runStep()
- def test_getDescription_abbrev_false(self):
- self.setup_getDescription_test(
- setup_args = { 'abbrev': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_dirty(self):
- self.setup_getDescription_test(
- setup_args = { 'dirty': True },
- output_args = ['--dirty']
- )
- return self.runStep()
- def test_getDescription_dirty_empty_str(self):
- self.setup_getDescription_test(
- setup_args = { 'dirty': '' },
- output_args = ['--dirty']
- )
- return self.runStep()
- def test_getDescription_dirty_str(self):
- self.setup_getDescription_test(
- setup_args = { 'dirty': 'foo' },
- output_args = ['--dirty=foo']
- )
- return self.runStep()
- def test_getDescription_dirty_false(self):
- self.setup_getDescription_test(
- setup_args = { 'dirty': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_contains(self):
- self.setup_getDescription_test(
- setup_args = { 'contains': True },
- output_args = ['--contains']
- )
- return self.runStep()
- def test_getDescription_contains_false(self):
- self.setup_getDescription_test(
- setup_args = { 'contains': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_candidates(self):
- self.setup_getDescription_test(
- setup_args = { 'candidates': 7 },
- output_args = ['--candidates=7']
- )
- return self.runStep()
- def test_getDescription_candidates_zero(self):
- self.setup_getDescription_test(
- setup_args = { 'candidates': 0 },
- output_args = ['--candidates=0']
- )
- return self.runStep()
- def test_getDescription_candidates_false(self):
- self.setup_getDescription_test(
- setup_args = { 'candidates': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_exact_match(self):
- self.setup_getDescription_test(
- setup_args = { 'exact-match': True },
- output_args = ['--exact-match']
- )
- return self.runStep()
- def test_getDescription_exact_match_false(self):
- self.setup_getDescription_test(
- setup_args = { 'exact-match': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_debug(self):
- self.setup_getDescription_test(
- setup_args = { 'debug': True },
- output_args = ['--debug']
- )
- return self.runStep()
- def test_getDescription_debug_false(self):
- self.setup_getDescription_test(
- setup_args = { 'debug': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_long(self):
- self.setup_getDescription_test(
- setup_args = { 'long': True },
- output_args = ['--long']
- )
- def test_getDescription_long_false(self):
- self.setup_getDescription_test(
- setup_args = { 'long': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_always(self):
- self.setup_getDescription_test(
- setup_args = { 'always': True },
- output_args = ['--always']
- )
- def test_getDescription_always_false(self):
- self.setup_getDescription_test(
- setup_args = { 'always': False },
- output_args = []
- )
- return self.runStep()
-
- def test_getDescription_lotsa_stuff(self):
- self.setup_getDescription_test(
- setup_args = { 'match': 'stuff-*',
- 'abbrev': 6,
- 'exact-match': True},
- output_args = ['--exact-match',
- '--match', 'stuff-*',
- '--abbrev=6'],
- codebase='baz'
- )
- return self.runStep()
-
- def test_config_option(self):
- name = 'url.http://github.com.insteadOf'
- value = 'blahblah'
- self.setupStep(
- git.Git(repourl='%s/buildbot/buildbot.git' % (value,),
- mode='full', method='clean',
- config={name: value}))
- prefix = ['git', '-c', '%s=%s' % (name, value)]
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=prefix + ['--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.git',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=prefix + ['clean', '-f', '-d'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=prefix + ['fetch', '-t',
- '%s/buildbot/buildbot.git' % (value,),
- 'HEAD'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=prefix + ['reset', '--hard',
- 'FETCH_HEAD', '--'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=prefix + ['rev-parse', 'HEAD'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_mercurial.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_mercurial.py
deleted file mode 100644
index e8543d97..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_mercurial.py
+++ /dev/null
@@ -1,863 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from twisted.python.reflect import namedModule
-from buildbot.steps.source import mercurial
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.test.util import sourcesteps
-from buildbot.test.fake.remotecommand import ExpectShell, Expect
-from buildbot import config
-
-class TestMercurial(sourcesteps.SourceStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpSourceStep()
-
- def tearDown(self):
- return self.tearDownSourceStep()
-
- def patch_slaveVersionIsOlderThan(self, result):
- self.patch(mercurial.Mercurial, 'slaveVersionIsOlderThan', lambda x, y, z: result)
-
- def test_no_repourl(self):
- self.assertRaises(config.ConfigErrors, lambda :
- mercurial.Mercurial(mode="full"))
-
- def test_incorrect_mode(self):
- self.assertRaises(config.ConfigErrors, lambda :
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='invalid'))
-
- def test_incorrect_method(self):
- self.assertRaises(config.ConfigErrors, lambda :
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- method='invalid'))
-
- def test_incorrect_branchType(self):
- self.assertRaises(config.ConfigErrors, lambda :
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- branchType='invalid'))
-
- def test_mode_full_clean(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='clean', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--config',
- 'extensions.purge=', 'purge'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio',
- stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_clean_win32path(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='clean', branchType='inrepo'))
- self.build.path_module = namedModule('ntpath')
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file=r'wkdir\.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--config',
- 'extensions.purge=', 'purge'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio',
- stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_clean_timeout(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- timeout=1,
- mode='full', method='clean', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['hg', '--verbose', '--config',
- 'extensions.purge=', 'purge'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio',
- stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_clean_patch(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='clean', branchType='inrepo'),
- patch=(1, 'patch'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--config',
- 'extensions.purge=', 'purge'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio',
- stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'import',
- '--no-commit', '-p', '1', '-'],
- initialStdin='patch')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_clean_patch_fail(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='clean', branchType='inrepo'),
- patch=(1, 'patch'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--config',
- 'extensions.purge=', 'purge'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio',
- stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'import',
- '--no-commit', '-p', '1', '-'],
- initialStdin='patch')
- + 1,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_mode_full_clean_no_existing_repo(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='clean', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'clone',
- 'http://hg.mozilla.org', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_clobber(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='clobber', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'clone', '--noupdate',
- 'http://hg.mozilla.org', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_fresh(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='fresh', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--config',
- 'extensions.purge=', 'purge', '--all'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio',
- stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_fresh_no_existing_repo(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='fresh', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'clone',
- 'http://hg.mozilla.org', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_no_existing_repo_dirname(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='incremental', branchType='dirname'),
- )
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 1, # does not exist
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'clone',
- 'http://hg.mozilla.org', '.', '--noupdate'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update', '--clean'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
-
- def test_mode_incremental_branch_change_dirname(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org/',
- mode='incremental', branchType='dirname', defaultBranch='devel'),
- dict(branch='stable')
- )
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org/stable'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'clone', '--noupdate',
- 'http://hg.mozilla.org/stable', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_no_existing_repo_inrepo(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='incremental', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 1, # does not exist
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'clone',
- 'http://hg.mozilla.org', '.', '--noupdate'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio', stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update', '--clean',
- '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_existing_repo(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='incremental', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0, # directory exists
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio', stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update', '--clean',
- '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_existing_repo_added_files(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='incremental', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0, # directory exists
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio', stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + ExpectShell.log('stdio', stdout='foo\nbar/baz\n')
- + 1,
- Expect('rmdir', dict(dir=['wkdir/foo','wkdir/bar/baz'],
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update', '--clean',
- '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_existing_repo_added_files_old_rmdir(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='incremental', branchType='inrepo'))
- self.patch_slaveVersionIsOlderThan(True)
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0, # directory exists
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio', stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + ExpectShell.log('stdio', stdout='foo\nbar/baz\n')
- + 1,
- Expect('rmdir', dict(dir='wkdir/foo',
- logEnviron=True))
- + 0,
- Expect('rmdir', dict(dir='wkdir/bar/baz',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update', '--clean',
- '--rev', 'default'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_given_revision(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='incremental', branchType='inrepo'), dict(
- revision='abcdef01',
- ))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio', stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update', '--clean',
- '--rev', 'abcdef01'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_branch_change(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='incremental', branchType='inrepo'), dict(
- branch='stable',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio', stdout='default')
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'clone', '--noupdate',
- 'http://hg.mozilla.org', '.'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'stable'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_branch_change_no_clobberOnBranchChange(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='incremental', branchType='inrepo',
- clobberOnBranchChange=False), dict(
- branch='stable',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'])
- + ExpectShell.log('stdio', stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'])
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'stable'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'])
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_clean_env(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='clean', branchType='inrepo',
- env={'abc': '123'}))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'], env={'abc': '123'})
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--config',
- 'extensions.purge=', 'purge'], env={'abc': '123'})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'], env={'abc': '123'})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'],
- env={'abc': '123'})
- + ExpectShell.log('stdio',
- stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'],
- env={'abc': '123'})
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update', '--clean',
- '--rev', 'default'], env={'abc': '123'})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'], env={'abc': '123'})
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_full_clean_logEnviron(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='clean',
- branchType='inrepo',
- logEnviron=False))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'],
- logEnviron=False)
- + 0,
- Expect('stat', dict(file='wkdir/.hg',
- logEnviron=False))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--config',
- 'extensions.purge=', 'purge'],
- logEnviron=False)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'pull',
- 'http://hg.mozilla.org'],
- logEnviron=False)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'identify', '--branch'],
- logEnviron=False)
- + ExpectShell.log('stdio',
- stdout='default')
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'locate', 'set:added()'],
- logEnviron=False)
- + 1,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'update',
- '--clean', '--rev', 'default'],
- logEnviron=False)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', 'parents',
- '--template', '{node}\\n'],
- logEnviron=False)
- + ExpectShell.log('stdio', stdout='\n')
- + ExpectShell.log('stdio',
- stdout='f6ad368298bd941e934a41f3babc827b2aa95a1d')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_command_fails(self):
- self.setupStep(
- mercurial.Mercurial(repourl='http://hg.mozilla.org',
- mode='full', method='fresh', branchType='inrepo'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['hg', '--verbose', '--version'])
- + 1,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource.py
deleted file mode 100644
index 300ae091..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource.py
+++ /dev/null
@@ -1,74 +0,0 @@
-# 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 mock
-from twisted.trial import unittest
-
-from buildbot.steps.source import oldsource
-
-class SlaveSource(unittest.TestCase):
-
- def doCommandCompleteTest(self,
- cmdHasGotRevision=True,
- cmdGotRevision='rev',
- initialPropertyValue=None,
- expectedPropertyValue=None,
- expectSetProperty=True):
-
- # set up a step with getProperty and setProperty
- step = oldsource.SlaveSource(codebase='foo')
- def getProperty(prop, default=None):
- self.assert_(prop == 'got_revision')
- if initialPropertyValue is None:
- return default
- return initialPropertyValue
- step.getProperty = getProperty
-
- def setProperty(prop, value, source):
- raise RuntimeError("should not be calling setProperty directly")
- step.setProperty = setProperty
-
- def updateSourceProperty(prop, value):
- self.failUnlessEqual((prop, value),
- ('got_revision', expectedPropertyValue))
- self.propSet = True
- step.updateSourceProperty = updateSourceProperty
-
- # fake RemoteCommand, optionally with a got_revision update
- cmd = mock.Mock()
- cmd.updates = dict()
- if cmdHasGotRevision:
- cmd.updates['got_revision'] = [ cmdGotRevision ]
-
- # run the method and ensure it set something; the set asserts the
- # value is correct
- self.propSet = False
- step.commandComplete(cmd)
- self.assertEqual(self.propSet, expectSetProperty)
-
- def test_commandComplete_got_revision(self):
- self.doCommandCompleteTest(
- expectedPropertyValue='rev')
-
- def test_commandComplete_no_got_revision(self):
- self.doCommandCompleteTest(
- cmdHasGotRevision=False,
- expectSetProperty=False)
-
- def test_commandComplete_None_got_revision(self):
- self.doCommandCompleteTest(
- cmdGotRevision=None,
- expectSetProperty=False)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource_ComputeRepositoryURL.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource_ComputeRepositoryURL.py
deleted file mode 100644
index 65c8739d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource_ComputeRepositoryURL.py
+++ /dev/null
@@ -1,106 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-
-from twisted.internet import defer
-
-from buildbot.interfaces import IRenderable
-from buildbot.process.properties import Properties, WithProperties
-from buildbot.steps.source.oldsource import _ComputeRepositoryURL
-
-
-class SourceStamp(object):
- repository = "test"
-
-class Build(object):
- s = SourceStamp()
- props = Properties(foo = "bar")
- def getSourceStamp(self, codebase):
- assert codebase == ''
- return self.s
- def getProperties(self):
- return self.props
- def render(self, value):
- self.props.build = self
- return defer.maybeDeferred(IRenderable(value).getRenderingFor, self.props)
-
-class FakeStep(object):
- codebase = ''
-
-class RepoURL(unittest.TestCase):
- def setUp(self):
- self.build = Build()
-
- def test_backward_compatibility(self):
- url = _ComputeRepositoryURL(FakeStep(), "repourl")
- d = self.build.render(url)
- @d.addCallback
- def callback(res):
- self.assertEquals(res, "repourl")
- return d
-
- def test_format_string(self):
- url = _ComputeRepositoryURL(FakeStep(), "http://server/%s")
- d = self.build.render(url)
- @d.addCallback
- def callback(res):
- self.assertEquals(res, "http://server/test")
- return d
-
- def test_dict(self):
- dict = {}
- dict['test'] = "ssh://server/testrepository"
- url = _ComputeRepositoryURL(FakeStep(), dict)
- d = self.build.render(url)
- @d.addCallback
- def callback(res):
- self.assertEquals(res, "ssh://server/testrepository")
- return d
-
- def test_callable(self):
- func = lambda x: x[::-1]
- url = _ComputeRepositoryURL(FakeStep(), func)
- d = self.build.render(url)
- @d.addCallback
- def callback(res):
- self.assertEquals(res, "tset")
- return d
-
- def test_backward_compatibility_render(self):
- url = _ComputeRepositoryURL(FakeStep(), WithProperties("repourl%(foo)s"))
- d = self.build.render(url)
- @d.addCallback
- def callback(res):
- self.assertEquals(res, "repourlbar")
- return d
-
- def test_dict_render(self):
- d = dict(test=WithProperties("repourl%(foo)s"))
- url = _ComputeRepositoryURL(FakeStep(), d)
- d = self.build.render(url)
- @d.addCallback
- def callback(res):
- self.assertEquals(res, "repourlbar")
- return d
-
- def test_callable_render(self):
- func = lambda x: WithProperties(x+"%(foo)s")
- url = _ComputeRepositoryURL(FakeStep(), func)
- d = self.build.render(url)
- @d.addCallback
- def callback(res):
- self.assertEquals(res, "testbar")
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource_Repo.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource_Repo.py
deleted file mode 100644
index bb8c8a26..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_oldsource_Repo.py
+++ /dev/null
@@ -1,31 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-
-from buildbot.steps.source import Repo
-
-class RepoURL(unittest.TestCase):
-
- def test_parse1(self):
- r = Repo()
- self.assertEqual(r.parseDownloadProperty("repo download test/bla 564/12"),["test/bla 564/12"])
- def test_parse2(self):
- r = Repo()
- self.assertEqual(r.parseDownloadProperty("repo download test/bla 564/12 repo download test/bla 564/2"),["test/bla 564/12","test/bla 564/2"])
- def test_parse3(self):
- r = Repo()
- self.assertEqual(r.parseDownloadProperty("repo download test/bla 564/12 repo download test/bla 564/2 test/foo 5/1"),["test/bla 564/12","test/bla 564/2","test/foo 5/1"])
- self.assertEqual(r.parseDownloadProperty("repo download test/bla 564/12"),["test/bla 564/12"])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_p4.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_p4.py
deleted file mode 100644
index b822f01f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_p4.py
+++ /dev/null
@@ -1,423 +0,0 @@
-# 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
-# Portions Copyright 2013 Bad Dog Consulting
-
-
-from twisted.trial import unittest
-from buildbot.steps.source.p4 import P4
-from buildbot.status.results import SUCCESS
-from buildbot.test.util import sourcesteps
-from buildbot.test.util.properties import ConstantRenderable
-from buildbot.test.fake.remotecommand import ExpectShell, Expect
-from buildbot import config
-import textwrap
-
-
-class TestP4(sourcesteps.SourceStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpSourceStep()
-
- def tearDown(self):
- return self.tearDownSourceStep()
-
- def setupStep(self, step, args={}, patch=None, **kwargs):
- step = sourcesteps.SourceStepMixin.setupStep(self, step, args={}, patch=None, **kwargs)
- self.build.getSourceStamp().revision = args.get('revision', None)
-
- # builddir propety used to create absolute path required in perforce client spec.
- self.properties.setProperty('builddir', '/home/user/workspace', 'P4')
-
- def test_no_empty_step_config(self):
- self.assertRaises(config.ConfigErrors, lambda: P4())
-
- def test_no_multiple_type_step_config(self):
- self.assertRaises(config.ConfigErrors, lambda:
- P4(p4viewspec=('//depot/trunk', ''),
- p4base='//depot', p4branch='trunk',
- p4extra_views=['src', 'doc']))
-
- def test_no_p4viewspec_is_string_step_config(self):
- self.assertRaises(config.ConfigErrors, lambda:
- P4(p4viewspec='a_bad_idea'))
-
- def test_no_p4base_has_trailing_slash_step_config(self):
- self.assertRaises(config.ConfigErrors, lambda:
- P4(p4base='//depot/'))
-
- def test_no_p4branch_has_trailing_slash_step_config(self):
- self.assertRaises(config.ConfigErrors, lambda:
- P4(p4base='//depot', p4branch='blah/'))
-
- def test_no_p4branch_with_no_p4base_step_config(self):
- self.assertRaises(config.ConfigErrors, lambda:
- P4(p4branch='blah'))
-
- def test_no_p4extra_views_with_no_p4base_step_config(self):
- self.assertRaises(config.ConfigErrors, lambda:
- P4(p4extra_views='blah'))
-
- def test_incorrect_mode(self):
- self.assertRaises(config.ConfigErrors, lambda:
- P4(p4base='//depot',
- mode='invalid'))
-
- def test_mode_incremental_p4base_with_revision(self):
- self.setupStep(P4(p4port='localhost:12000', mode='incremental',
- p4base='//depot', p4branch='trunk',
- p4user='user', p4client='p4_client1', p4passwd='pass'),
- dict(revision='100',))
-
- client_spec = textwrap.dedent('''\
- Client: p4_client1
-
- Owner: user
-
- Description:
- \tCreated by user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/trunk/... //p4_client1/...
- ''');
-
- self.expectCommands(
- ExpectShell(workdir='wkdir', # defaults to this, only changes if it has a copy mode.
- command=['p4', '-V']) # expected remote command
- + 0, # expected exit status
-
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', 'user',
- '-P', 'pass', '-c', 'p4_client1',
- 'client', '-i'],
- initialStdin=client_spec)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', 'user',
- '-P', 'pass', '-c', 'p4_client1',
- 'sync', '//depot...@100'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', 'user',
- '-P', 'pass', '-c', 'p4_client1',
- 'changes', '-m1', '#have'])
- + ExpectShell.log('stdio',
- stdout="Change 100 on 2013/03/21 by user@machine \'duh\'")
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'P4')
- return self.runStep()
-
- def _incremental(self, client_stdin=''):
- self.expectCommands(
- ExpectShell(workdir='wkdir', # defaults to this, only changes if it has a copy mode.
- command=['p4', '-V']) # expected remote command
- + 0, # expected exit status
-
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', 'user',
- '-P', 'pass', '-c', 'p4_client1',
- 'client', '-i'],
- initialStdin=client_stdin,)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', 'user',
- '-P', 'pass', '-c', 'p4_client1',
- 'sync'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', 'user',
- '-P', 'pass', '-c', 'p4_client1',
- 'changes', '-m1', '#have'])
- + ExpectShell.log('stdio',
- stdout="Change 100 on 2013/03/21 by user@machine \'duh\'")
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'P4')
- return self.runStep()
-
- def test_mode_incremental_p4base(self):
- self.setupStep(P4(p4port='localhost:12000', mode='incremental',
- p4base='//depot', p4branch='trunk',
- p4user='user', p4client='p4_client1', p4passwd='pass'))
-
- client_spec = textwrap.dedent('''\
- Client: p4_client1
-
- Owner: user
-
- Description:
- \tCreated by user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/trunk/... //p4_client1/...
- ''')
- self._incremental(client_stdin=client_spec)
-
- def test_mode_incremental_p4base_with_p4extra_views(self):
- self.setupStep(P4(p4port='localhost:12000', mode='incremental',
- p4base='//depot', p4branch='trunk',
- p4extra_views=[('-//depot/trunk/test', 'test'),
- ('-//depot/trunk/doc', 'doc')],
- p4user='user', p4client='p4_client1', p4passwd='pass'))
- client_spec = textwrap.dedent('''\
- Client: p4_client1
-
- Owner: user
-
- Description:
- \tCreated by user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/trunk/... //p4_client1/...
- \t-//depot/trunk/test/... //p4_client1/test/...
- \t-//depot/trunk/doc/... //p4_client1/doc/...
- ''')
- self._incremental(client_stdin=client_spec)
-
- def test_mode_incremental_p4viewspec(self):
- self.setupStep(P4(p4port='localhost:12000', mode='incremental',
- p4viewspec=[('//depot/trunk/', '')],
- p4user='user', p4client='p4_client1', p4passwd='pass'))
- client_spec = textwrap.dedent('''\
- Client: p4_client1
-
- Owner: user
-
- Description:
- \tCreated by user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/trunk/... //p4_client1/...
- ''')
- self._incremental(client_stdin=client_spec)
-
- def _full(self, client_stdin='', p4client='p4_client1', p4user='user'):
- self.expectCommands(
- ExpectShell(workdir='wkdir', # defaults to this, only changes if it has a copy mode.
- command=['p4', '-V']) # expected remote command
- + 0, # expected exit status
-
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', p4user,
- '-P', 'pass', '-c', p4client, 'client',
- '-i'],
- initialStdin=client_stdin)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', p4user,
- '-P', 'pass', '-c', p4client, 'sync',
- '#none'])
- + 0,
-
- Expect('rmdir', {'dir': 'wkdir', 'logEnviron': True})
- + 0,
-
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', p4user,
- '-P', 'pass', '-c', p4client, 'sync'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['p4', '-p', 'localhost:12000', '-u', p4user,
- '-P', 'pass', '-c', p4client, 'changes',
- '-m1', '#have'])
- + ExpectShell.log('stdio',
- stdout="Change 100 on 2013/03/21 by user@machine \'duh\'")
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'P4')
- return self.runStep()
-
- def test_mode_full_p4base(self):
- self.setupStep(
- P4(p4port='localhost:12000',
- mode='full', p4base='//depot', p4branch='trunk',
- p4user='user', p4client='p4_client1', p4passwd='pass'))
-
- client_stdin = textwrap.dedent('''\
- Client: p4_client1
-
- Owner: user
-
- Description:
- \tCreated by user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/trunk/... //p4_client1/...\n''')
- self._full(client_stdin=client_stdin)
-
- def test_mode_full_p4viewspec(self):
- self.setupStep(
- P4(p4port='localhost:12000',
- mode='full', p4viewspec=[('//depot/main/', '')],
- p4user='user', p4client='p4_client1', p4passwd='pass'))
- client_stdin = textwrap.dedent('''\
- Client: p4_client1
-
- Owner: user
-
- Description:
- \tCreated by user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/main/... //p4_client1/...\n''')
-
- self._full(client_stdin=client_stdin)
-
- def test_mode_full_renderable_p4base(self):
- # Note that the config check skips checking p4base if it's a renderable
- self.setupStep(
- P4(p4port='localhost:12000',
- mode='full', p4base=ConstantRenderable('//depot'),
- p4branch='release/1.0', p4user='user', p4client='p4_client2',
- p4passwd='pass'))
-
- client_stdin = textwrap.dedent('''\
- Client: p4_client2
-
- Owner: user
-
- Description:
- \tCreated by user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/release/1.0/... //p4_client2/...\n''')
-
- self._full(client_stdin=client_stdin, p4client='p4_client2')
-
- def test_mode_full_renderable_p4client(self):
- # Note that the config check skips checking p4base if it's a renderable
- self.setupStep(
- P4(p4port='localhost:12000',
- mode='full', p4base='//depot', p4branch='trunk',
- p4user='user', p4client=ConstantRenderable('p4_client_render'),
- p4passwd='pass'))
-
- client_stdin = textwrap.dedent('''\
- Client: p4_client_render
-
- Owner: user
-
- Description:
- \tCreated by user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/trunk/... //p4_client_render/...\n''')
-
- self._full(client_stdin=client_stdin, p4client='p4_client_render')
-
- def test_mode_full_renderable_p4branch(self):
- # Note that the config check skips checking p4base if it's a renderable
- self.setupStep(
- P4(p4port='localhost:12000',
- mode='full', p4base='//depot',
- p4branch=ConstantRenderable('render_branch'),
- p4user='user', p4client='p4_client1', p4passwd='pass'))
-
- client_stdin = textwrap.dedent('''\
- Client: p4_client1
-
- Owner: user
-
- Description:
- \tCreated by user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/render_branch/... //p4_client1/...\n''')
-
- self._full(client_stdin=client_stdin)
-
- def test_mode_full_renderable_p4viewspec(self):
- self.setupStep(
- P4(p4port='localhost:12000',
- mode='full',
- p4viewspec=[(ConstantRenderable('//depot/render_trunk/'), '')],
- p4user='different_user', p4client='p4_client1',
- p4passwd='pass'))
-
- client_stdin = textwrap.dedent('''\
- Client: p4_client1
-
- Owner: different_user
-
- Description:
- \tCreated by different_user
-
- Root:\t/home/user/workspace/wkdir
-
- Options:\tallwrite rmdir
-
- LineEnd:\tlocal
-
- View:
- \t//depot/render_trunk/... //p4_client1/...\n''')
-
- self._full(client_stdin=client_stdin, p4user='different_user')
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_repo.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_repo.py
deleted file mode 100644
index 0baaa0ed..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_repo.py
+++ /dev/null
@@ -1,613 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.steps.source import repo
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.test.util import sourcesteps
-from buildbot.test.fake.remotecommand import ExpectShell, Expect
-from buildbot.process.properties import Properties
-from .test_changes_gerritchangesource import TestGerritChangeSource
-from buildbot.changes.changes import Change
-import os
-
-
-class RepoURL(unittest.TestCase):
- # testcases taken from old_source/Repo test
-
- def oneTest(self, props, expected):
- p = Properties()
- p.update(props, "test")
- r = repo.RepoDownloadsFromProperties(props.keys())
- self.assertEqual(r.getRenderingFor(p), expected)
-
- def test_parse1(self):
- self.oneTest(
- {'a': "repo download test/bla 564/12"}, ["test/bla 564/12"])
-
- def test_parse2(self):
- self.oneTest(
- {'a':
- "repo download test/bla 564/12 repo download test/bla 564/2"},
- ["test/bla 564/12", "test/bla 564/2"])
- self.oneTest({'a': "repo download test/bla 564/12", 'b': "repo download test/bla 564/2"}, [
- "test/bla 564/12", "test/bla 564/2"])
-
- def test_parse3(self):
- self.oneTest({'a': "repo download test/bla 564/12 repo download test/bla 564/2 test/foo 5/1"}, [
- "test/bla 564/12", "test/bla 564/2", "test/foo 5/1"])
- self.oneTest(
- {'a': "repo download test/bla 564/12"}, ["test/bla 564/12"])
-
-
-class TestRepo(sourcesteps.SourceStepMixin, unittest.TestCase):
-
- def setUp(self):
- self.shouldRetry = False
- self.logEnviron = True
- return self.setUpSourceStep()
-
- def tearDown(self):
- return self.tearDownSourceStep()
-
- def shouldLogEnviron(self):
- r = self.logEnviron
- self.logEnviron = False
- return r
-
- def ExpectShell(self, **kw):
- if 'workdir' not in kw:
- kw['workdir'] = 'wkdir'
- if 'logEnviron' not in kw:
- kw['logEnviron'] = self.shouldLogEnviron()
- return ExpectShell(**kw)
-
- def mySetupStep(self, **kwargs):
- if "repoDownloads" not in kwargs:
- kwargs.update(
- dict(repoDownloads=repo.RepoDownloadsFromProperties(["repo_download", "repo_download2"])))
- self.setupStep(
- repo.Repo(manifestURL='git://myrepo.com/manifest.git',
- manifestBranch="mb",
- manifestFile="mf",
- **kwargs))
- self.build.allChanges = lambda x=None: []
-
- def myRunStep(self, result=SUCCESS, status_text=["update"]):
- self.expectOutcome(result=result, status_text=status_text)
- d = self.runStep()
-
- def printlogs(res):
- text = self.step.stdio_log.getTextWithHeaders()
- if "Failure instance" in text and not self.shouldRetry:
- print text
- return res
- d.addBoth(printlogs)
- return d
-
- def expectClobber(self):
- # stat return 1 so we clobber
- self.expectCommands(
- Expect('stat', dict(file=os.path.join('wkdir', '.repo'),
- logEnviron=self.logEnviron))
- + 1,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=self.logEnviron))
- + 0,
- Expect('mkdir', dict(dir='wkdir',
- logEnviron=self.logEnviron))
- + 0,
- )
-
- def expectnoClobber(self):
- # stat return 0, so nothing
- self.expectCommands(
- Expect('stat', dict(file=os.path.join('wkdir', '.repo'),
- logEnviron=self.logEnviron))
- + 0,
- )
-
- def expectRepoSync(self, which_fail=-1, breakatfail=False, syncoptions=["-c"], override_commands=[]):
- commands = [
- self.ExpectShell(
- command=[
- 'bash', '-c', self.step._getCleanupCommand()]),
- self.ExpectShell(
- command=['repo', 'init', '-u', 'git://myrepo.com/manifest.git',
- '-b', 'mb', '-m', 'mf'])
- ] + override_commands + [
- self.ExpectShell(command=['repo', 'sync'] + syncoptions),
- self.ExpectShell(
- command=['repo', 'manifest', '-r', '-o', 'manifest-original.xml'])
- ]
- for i in xrange(len(commands)):
- self.expectCommands(commands[i] + (which_fail == i and 1 or 0))
- if which_fail == i and breakatfail:
- break
-
- def test_basic(self):
- """basic first time repo sync"""
- self.mySetupStep(repoDownloads=None)
- self.expectClobber()
- self.expectRepoSync()
- return self.myRunStep(status_text=["update"])
-
- def test_update(self):
- """basic second time repo sync"""
- self.mySetupStep()
- self.expectnoClobber()
- self.expectRepoSync()
- return self.myRunStep(status_text=["update"])
-
- def test_jobs(self):
- """basic first time repo sync with jobs"""
- self.mySetupStep(jobs=2)
- self.expectClobber()
- self.expectRepoSync(syncoptions=["-j2", "-c"])
- return self.myRunStep(status_text=["update"])
-
- def test_sync_all_branches(self):
- """basic first time repo sync with all branches"""
- self.mySetupStep(syncAllBranches=True)
- self.expectClobber()
- self.expectRepoSync(syncoptions=[])
- return self.myRunStep(status_text=["update"])
-
- def test_manifest_override(self):
- """repo sync with manifest_override_url property set
- download via wget
- """
- self.mySetupStep(manifestOverrideUrl=
- "http://u.rl/test.manifest",
- syncAllBranches=True)
- self.expectClobber()
- override_commands = [
- Expect(
- 'stat', dict(file=os.path.join('wkdir', 'http://u.rl/test.manifest'),
- logEnviron=False)),
- self.ExpectShell(logEnviron=False, command=['wget',
- 'http://u.rl/test.manifest',
- '-O', 'manifest_override.xml']),
- self.ExpectShell(
- logEnviron=False, workdir=os.path.join('wkdir', '.repo'),
- command=['ln', '-sf', '../manifest_override.xml',
- 'manifest.xml'])
- ]
- self.expectRepoSync(which_fail=2, syncoptions=[],
- override_commands=override_commands)
- return self.myRunStep(status_text=["update"])
-
- def test_manifest_override_local(self):
- """repo sync with manifest_override_url property set
- copied from local FS
- """
- self.mySetupStep(manifestOverrideUrl=
- "test.manifest",
- syncAllBranches=True)
- self.expectClobber()
- override_commands = [
- Expect('stat', dict(file=os.path.join('wkdir', 'test.manifest'),
- logEnviron=False)),
- self.ExpectShell(logEnviron=False,
- command=[
- 'cp', '-f', 'test.manifest', 'manifest_override.xml']),
- self.ExpectShell(logEnviron=False,
- workdir=os.path.join('wkdir', '.repo'),
- command=['ln', '-sf', '../manifest_override.xml',
- 'manifest.xml'])
- ]
- self.expectRepoSync(
- syncoptions=[], override_commands=override_commands)
- return self.myRunStep(status_text=["update"])
-
- def test_tarball(self):
- """repo sync using the tarball cache
- """
- self.mySetupStep(tarball="/tarball.tar")
- self.expectClobber()
- self.expectCommands(
- self.ExpectShell(command=['tar', '-xvf', '/tarball.tar']) + 0)
- self.expectRepoSync()
- self.expectCommands(self.ExpectShell(command=['stat', '-c%Y', '/tarball.tar'])
- + Expect.log('stdio', stdout=str(10000))
- + 0)
- self.expectCommands(self.ExpectShell(command=['stat', '-c%Y', '.'])
- + Expect.log(
- 'stdio', stdout=str(10000 + 7 * 24 * 3600))
- + 0)
- return self.myRunStep(status_text=["update"])
-
- def test_create_tarball(self):
- """repo sync create the tarball if its not here
- """
- self.mySetupStep(tarball="/tarball.tgz")
- self.expectClobber()
- self.expectCommands(
- self.ExpectShell(
- command=['tar', '-z', '-xvf', '/tarball.tgz']) + 1,
- self.ExpectShell(command=['rm', '-f', '/tarball.tgz']) + 1,
- Expect('rmdir', dict(dir=os.path.join('wkdir', '.repo'),
- logEnviron=False))
- + 1)
- self.expectRepoSync()
- self.expectCommands(self.ExpectShell(command=['stat', '-c%Y', '/tarball.tgz'])
- + Expect.log('stdio', stderr="file not found!")
- + 1,
- self.ExpectShell(command=['tar', '-z',
- '-cvf', '/tarball.tgz', '.repo'])
- + 0)
- return self.myRunStep(status_text=["update"])
-
- def do_test_update_tarball(self, suffix, option):
- """repo sync update the tarball cache at the end (tarball older than a week)
- """
- self.mySetupStep(tarball="/tarball." + suffix)
- self.expectClobber()
- self.expectCommands(
- self.ExpectShell(command=['tar'] + option + ['-xvf', '/tarball.' + suffix]) + 0)
- self.expectRepoSync()
- self.expectCommands(self.ExpectShell(command=['stat', '-c%Y', '/tarball.' + suffix])
- + Expect.log('stdio', stdout=str(10000))
- + 0,
- self.ExpectShell(command=['stat', '-c%Y', '.'])
- + Expect.log(
- 'stdio', stdout=str(10001 + 7 * 24 * 3600))
- + 0,
- self.ExpectShell(command=['tar'] + option +
- ['-cvf', '/tarball.' + suffix, '.repo'])
- + 0)
- return self.myRunStep(status_text=["update"])
-
- def test_update_tarball(self):
- self.do_test_update_tarball("tar", [])
-
- def test_update_tarball_gz(self):
- """tarball compression variants"""
- self.do_test_update_tarball("tar.gz", ["-z"])
-
- def test_update_tarball_tgz(self):
- self.do_test_update_tarball("tgz", ["-z"])
-
- def test_update_tarball_bzip(self):
- self.do_test_update_tarball("tar.bz2", ["-j"])
-
- def test_update_tarball_lzma(self):
- self.do_test_update_tarball("tar.lzma", ["--lzma"])
-
- def test_update_tarball_lzop(self):
- self.do_test_update_tarball("tar.lzop", ["--lzop"])
-
- def test_update_tarball_fail1(self, suffix="tar", option=[]):
- """tarball extract fail -> remove the tarball + remove .repo dir
- """
- self.mySetupStep(tarball="/tarball." + suffix)
- self.expectClobber()
- self.expectCommands(
- self.ExpectShell(
- command=[
- 'tar'] + option + ['-xvf', '/tarball.' + suffix]) + 1,
- self.ExpectShell(
- command=['rm', '-f', '/tarball.tar']) + 0,
- Expect(
- 'rmdir', dict(dir=os.path.join('wkdir', '.repo'),
- logEnviron=False))
- + 0)
- self.expectRepoSync()
- self.expectCommands(self.ExpectShell(command=['stat', '-c%Y', '/tarball.' + suffix])
- + Expect.log('stdio', stdout=str(10000))
- + 0,
- self.ExpectShell(command=['stat', '-c%Y', '.'])
- + Expect.log(
- 'stdio', stdout=str(10001 + 7 * 24 * 3600))
- + 0,
- self.ExpectShell(command=['tar'] + option +
- ['-cvf', '/tarball.' + suffix, '.repo'])
- + 0)
- return self.myRunStep(status_text=["update"])
-
- def test_update_tarball_fail2(self, suffix="tar", option=[]):
- """tarball update fail -> remove the tarball + continue repo download
- """
- self.mySetupStep(tarball="/tarball." + suffix)
- self.build.setProperty("repo_download",
- "repo download test/bla 564/12", "test")
- self.expectClobber()
- self.expectCommands(
- self.ExpectShell(command=['tar'] + option + ['-xvf', '/tarball.' + suffix]) + 0)
- self.expectRepoSync()
- self.expectCommands(self.ExpectShell(command=['stat', '-c%Y', '/tarball.' + suffix])
- + Expect.log('stdio', stdout=str(10000))
- + 0,
- self.ExpectShell(command=['stat', '-c%Y', '.'])
- + Expect.log(
- 'stdio', stdout=str(10001 + 7 * 24 * 3600))
- + 0,
- self.ExpectShell(command=['tar'] + option +
- ['-cvf', '/tarball.' + suffix, '.repo'])
- + 1,
- self.ExpectShell(
- command=['rm', '-f', '/tarball.tar']) + 0,
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 0)
- return self.myRunStep(status_text=["update"])
-
- def test_repo_downloads(self):
- """basic repo download, and check that repo_downloaded is updated"""
- self.mySetupStep()
- self.build.setProperty("repo_download",
- "repo download test/bla 564/12", "test")
- self.expectnoClobber()
- self.expectRepoSync()
- self.expectCommands(
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 0
- + Expect.log(
- 'stdio', stderr="test/bla refs/changes/64/564/12 -> FETCH_HEAD\n")
- + Expect.log('stdio', stderr="HEAD is now at 0123456789abcdef...\n"))
- self.expectProperty(
- "repo_downloaded", "564/12 0123456789abcdef ", "Source")
- return self.myRunStep(status_text=["update"])
-
- def test_repo_downloads2(self):
- """2 repo downloads"""
- self.mySetupStep()
- self.build.setProperty("repo_download",
- "repo download test/bla 564/12", "test")
- self.build.setProperty("repo_download2",
- "repo download test/bla2 565/12", "test")
- self.expectnoClobber()
- self.expectRepoSync()
- self.expectCommands(
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 0,
- self.ExpectShell(
- command=['repo', 'download', 'test/bla2', '565/12'])
- + 0)
- return self.myRunStep(status_text=["update"])
-
- def test_repo_download_manifest(self):
- """2 repo downloads, with one manifest patch"""
- self.mySetupStep()
- self.build.setProperty("repo_download",
- "repo download test/bla 564/12", "test")
- self.build.setProperty("repo_download2",
- "repo download manifest 565/12", "test")
- self.expectnoClobber()
- self.expectCommands(
- self.ExpectShell(
- command=['bash', '-c', self.step._getCleanupCommand()])
- + 0,
- self.ExpectShell(
- command=['repo', 'init', '-u', 'git://myrepo.com/manifest.git',
- '-b', 'mb', '-m', 'mf'])
- + 0,
- self.ExpectShell(
- workdir=os.path.join('wkdir', '.repo', 'manifests'),
- command=[
- 'git', 'fetch', 'git://myrepo.com/manifest.git',
- 'refs/changes/65/565/12'])
- + 0,
- self.ExpectShell(
- workdir=os.path.join('wkdir', '.repo', 'manifests'),
- command=['git', 'cherry-pick', 'FETCH_HEAD'])
- + 0,
- self.ExpectShell(command=['repo', 'sync', '-c'])
- + 0,
- self.ExpectShell(
- command=['repo', 'manifest', '-r', '-o', 'manifest-original.xml'])
- + 0)
- self.expectCommands(
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 0)
- return self.myRunStep(status_text=["update"])
-
- def test_repo_downloads_mirror_sync(self):
- """repo downloads, with mirror synchronization issues"""
- self.mySetupStep()
- self.step.mirror_sync_sleep = 0.001 # we dont really want the test to wait...
- self.build.setProperty("repo_download",
- "repo download test/bla 564/12", "test")
- self.expectnoClobber()
- self.expectRepoSync()
- self.expectCommands(
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 1 +
- Expect.log(
- "stdio", stderr="fatal: Couldn't find remote ref \n"),
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 1 +
- Expect.log(
- "stdio", stderr="fatal: Couldn't find remote ref \n"),
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 0)
- return self.myRunStep(status_text=["update"])
-
- def test_repo_downloads_change_missing(self):
- """repo downloads, with no actual mirror synchronization issues (still retries 2 times)"""
- self.mySetupStep()
- self.step.mirror_sync_sleep = 0.001 # we dont really want the test to wait...
- self.step.mirror_sync_retry = 1 # on retry once
- self.build.setProperty("repo_download",
- "repo download test/bla 564/12", "test")
- self.expectnoClobber()
- self.expectRepoSync()
- self.expectCommands(
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 1 +
- Expect.log(
- "stdio", stderr="fatal: Couldn't find remote ref \n"),
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 1 +
- Expect.log(
- "stdio", stderr="fatal: Couldn't find remote ref \n"),
- )
- return self.myRunStep(result=FAILURE, status_text=["repo: change test/bla 564/12 does not exist"])
-
- def test_repo_downloads_fail1(self):
- """repo downloads, cherry-pick returns 1"""
- self.mySetupStep()
- self.build.setProperty("repo_download",
- "repo download test/bla 564/12", "test")
- self.expectnoClobber()
- self.expectRepoSync()
- self.expectCommands(
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 1 + Expect.log("stdio", stderr="patch \n"),
- self.ExpectShell(
- command=['repo', 'forall', '-c', 'git', 'diff', 'HEAD'])
- + 0
- )
- return self.myRunStep(result=FAILURE, status_text=["download failed: test/bla 564/12"])
-
- def test_repo_downloads_fail2(self):
- """repo downloads, cherry-pick returns 0 but error in stderr"""
- self.mySetupStep()
- self.build.setProperty("repo_download",
- "repo download test/bla 564/12", "test")
- self.expectnoClobber()
- self.expectRepoSync()
- self.expectCommands(
- self.ExpectShell(
- command=['repo', 'download', 'test/bla', '564/12'])
- + 0 +
- Expect.log("stdio", stderr="Automatic cherry-pick failed \n"),
- self.ExpectShell(
- command=['repo', 'forall', '-c', 'git', 'diff', 'HEAD'])
- + 0
- )
- return self.myRunStep(result=FAILURE, status_text=["download failed: test/bla 564/12"])
-
- def test_repo_downloads_from_change_source(self):
- """basic repo download from change source, and check that repo_downloaded is updated"""
- self.mySetupStep(repoDownloads=repo.RepoDownloadsFromChangeSource())
- chdict = TestGerritChangeSource.expected_change
- change = Change(None, None, None, properties=chdict['properties'])
- self.build.allChanges = lambda x=None: [change]
- self.expectnoClobber()
- self.expectRepoSync()
- self.expectCommands(
- self.ExpectShell(command=['repo', 'download', 'pr', '4321/12'])
- + 0
- + Expect.log(
- 'stdio', stderr="test/bla refs/changes/64/564/12 -> FETCH_HEAD\n")
- + Expect.log('stdio', stderr="HEAD is now at 0123456789abcdef...\n"))
- self.expectProperty(
- "repo_downloaded", "564/12 0123456789abcdef ", "Source")
- return self.myRunStep(status_text=["update"])
-
- def test_repo_downloads_from_change_source_codebase(self):
- """basic repo download from change source, and check that repo_downloaded is updated"""
- self.mySetupStep(repoDownloads=repo.RepoDownloadsFromChangeSource("mycodebase"))
- chdict = TestGerritChangeSource.expected_change
- change = Change(None, None, None, properties=chdict['properties'])
- # getSourceStamp is faked by SourceStepMixin
- ss = self.build.getSourceStamp("")
- ss.changes = [change]
- self.expectnoClobber()
- self.expectRepoSync()
- self.expectCommands(
- self.ExpectShell(command=['repo', 'download', 'pr', '4321/12'])
- + 0
- + Expect.log(
- 'stdio', stderr="test/bla refs/changes/64/564/12 -> FETCH_HEAD\n")
- + Expect.log('stdio', stderr="HEAD is now at 0123456789abcdef...\n"))
- self.expectProperty(
- "repo_downloaded", "564/12 0123456789abcdef ", "Source")
- return self.myRunStep(status_text=["update"])
-
- def test_update_fail1(self):
- """ fail at cleanup: ignored"""
- self.mySetupStep()
- self.expectnoClobber()
- self.expectRepoSync(which_fail=0, breakatfail=False)
- return self.myRunStep(status_text=["update"])
-
- def test_update_fail2(self):
- """fail at repo init: clobber"""
- self.mySetupStep()
- self.expectnoClobber()
- self.expectRepoSync(which_fail=1, breakatfail=True)
- self.expectClobber()
- self.expectRepoSync()
- self.shouldRetry = True
- return self.myRunStep(status_text=["update"])
-
- def test_update_fail3(self):
- """ fail at repo sync: clobber"""
- self.mySetupStep()
- self.expectnoClobber()
- self.expectRepoSync(which_fail=2, breakatfail=True)
- self.expectClobber()
- self.expectRepoSync()
- self.shouldRetry = True
- return self.myRunStep(status_text=["update"])
-
- def test_update_fail4(self):
- """fail at repo manifest: clobber"""
- self.mySetupStep()
- self.expectnoClobber()
- self.expectRepoSync(which_fail=3, breakatfail=True)
- self.expectClobber()
- self.expectRepoSync()
- self.shouldRetry = True
- return self.myRunStep(status_text=["update"])
-
- def test_update_doublefail(self):
- """fail at repo manifest: clobber but still fail"""
- self.mySetupStep()
- self.expectnoClobber()
- self.expectRepoSync(which_fail=3, breakatfail=True)
- self.expectClobber()
- self.expectRepoSync(which_fail=3, breakatfail=True)
- self.shouldRetry = True
- return self.myRunStep(result=FAILURE, status_text=["repo failed at: repo manifest"])
-
- def test_update_doublefail2(self):
- """fail at repo sync: clobber but still fail"""
- self.mySetupStep()
- self.expectnoClobber()
- self.expectRepoSync(which_fail=2, breakatfail=True)
- self.expectClobber()
- self.expectRepoSync(which_fail=2, breakatfail=True)
- self.shouldRetry = True
- return self.myRunStep(result=FAILURE, status_text=["repo failed at: repo sync"])
-
- def test_update_doublefail3(self):
- """fail at repo init: clobber but still fail"""
- self.mySetupStep()
- self.expectnoClobber()
- self.expectRepoSync(which_fail=1, breakatfail=True)
- self.expectClobber()
- self.expectRepoSync(which_fail=1, breakatfail=True)
- self.shouldRetry = True
- return self.myRunStep(result=FAILURE, status_text=["repo failed at: repo init"])
-
- def test_basic_fail(self):
- """fail at repo init: no need to re-clobber but still fail"""
- self.mySetupStep()
- self.expectClobber()
- self.expectRepoSync(which_fail=1, breakatfail=True)
- self.shouldRetry = True
- return self.myRunStep(result=FAILURE, status_text=["repo failed at: repo init"])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_svn.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_svn.py
deleted file mode 100644
index b1c4e2ce..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_source_svn.py
+++ /dev/null
@@ -1,1477 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from twisted.python.reflect import namedModule
-from buildbot.steps.source import svn
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.test.util import sourcesteps
-from buildbot.process import buildstep
-from buildbot.test.fake.remotecommand import ExpectShell, Expect
-from buildbot.test.util.properties import ConstantRenderable
-from buildbot import config
-
-class TestSVN(sourcesteps.SourceStepMixin, unittest.TestCase):
-
- svn_st_xml = """<?xml version="1.0"?>
- <status>
- <target path=".">
- <entry path="svn_external_path">
- <wc-status props="none" item="external">
- </wc-status>
- </entry>
- <entry path="svn_external_path/unversioned_file1">
- <wc-status props="none" item="unversioned">
- </wc-status>
- </entry>
- <entry path="svn_external_path/unversioned_file2">
- <wc-status props="none" item="unversioned">
- </wc-status>
- </entry>
- </target>
- </status>
- """
- svn_st_xml_corrupt = """<?xml version="1.0"?>
- <target path=".">
- <entry path="svn_external_path">
- <wc-status props="none" item="external">
- </wc-status>
- </entry>
- <entry path="svn_external_path/unversioned_file">
- <wc-status props="none" item="unversioned">
- </wc-status>
- </entry>
- </target>
- </status>
- """
- svn_st_xml_empty = """<?xml version="1.0"?>
- <status>
- <target path=".">
- </target>
- </status>"""
- svn_info_stdout_xml = """<?xml version="1.0"?>
- <info>
- <entry
- kind="dir"
- path="."
- revision="100">
- <url>http://svn.red-bean.com/repos/test</url>
- <repository>
- <root>http://svn.red-bean.com/repos/test</root>
- <uuid>5e7d134a-54fb-0310-bd04-b611643e5c25</uuid>
- </repository>
- <wc-info>
- <schedule>normal</schedule>
- <depth>infinity</depth>
- </wc-info>
- <commit
- revision="90">
- <author>sally</author>
- <date>2003-01-15T23:35:12.847647Z</date>
- </commit>
- </entry>
- </info>"""
- svn_info_stdout_xml_nonintegerrevision = """<?xml version="1.0"?>
- <info>
- <entry
- kind="dir"
- path="."
- revision="a10">
- <url>http://svn.red-bean.com/repos/test</url>
- <repository>
- <root>http://svn.red-bean.com/repos/test</root>
- <uuid>5e7d134a-54fb-0310-bd04-b611643e5c25</uuid>
- </repository>
- <wc-info>
- <schedule>normal</schedule>
- <depth>infinity</depth>
- </wc-info>
- <commit
- revision="a10">
- <author>sally</author>
- <date>2003-01-15T23:35:12.847647Z</date>
- </commit>
- </entry>
- </info>"""
-
- def setUp(self):
- return self.setUpSourceStep()
-
- def tearDown(self):
- return self.tearDownSourceStep()
-
- def patch_slaveVersionIsOlderThan(self, result):
- self.patch(svn.SVN, 'slaveVersionIsOlderThan', lambda x, y, z: result)
-
- def test_no_repourl(self):
- self.assertRaises(config.ConfigErrors, lambda :
- svn.SVN())
-
- def test_incorrect_mode(self):
- self.assertRaises(config.ConfigErrors, lambda :
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='invalid'))
-
- def test_incorrect_method(self):
- self.assertRaises(config.ConfigErrors, lambda :
- svn.SVN(repourl='http://svn.local/app/trunk',
- method='invalid'))
-
- def test_corrupt_xml(self):
- self.setupStep(svn.SVN(repourl='http://svn.local/app/trunk'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_st_xml_corrupt)
- + 0,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_revision_noninteger(self):
- svnTestStep = svn.SVN(repourl='http://svn.local/app/trunk')
- self.setupStep(svnTestStep)
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml_nonintegerrevision)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', 'a10', 'SVN')
- d = self.runStep()
- def _checkType():
- revision = self.step.getProperty('got_revision')
- self.assertRaises(ValueError, lambda: int(revision))
- d.addCallback(lambda _: _checkType())
- return d
-
- def test_revision_missing(self):
- """Fail if 'revision' tag isnt there"""
- svn_info_stdout = self.svn_info_stdout_xml.replace('entry', 'Blah')
-
- svnTestStep = svn.SVN(repourl='http://svn.local/app/trunk')
- self.setupStep(svnTestStep)
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=svn_info_stdout)
- + 0,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_mode_incremental(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental',username='user',
- password='pass', extra_args=['--random']))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_incremental_timeout(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental',username='user',
- timeout=1,
- password='pass', extra_args=['--random']))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + 0,
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_incremental_repourl_renderable(self):
- self.setupStep(
- svn.SVN(repourl=ConstantRenderable('http://svn.local/trunk'),
- mode='incremental'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_incremental_repourl_not_updatable(self):
- self.setupStep(
- svn.SVN(repourl=ConstantRenderable('http://svn.local/trunk/app'),
- mode='incremental',))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 1,
- Expect('rmdir', {'dir': 'wkdir', 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'checkout', 'http://svn.local/trunk/app',
- '.', '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_incremental_repourl_not_updatable_svninfo_mismatch(self):
- self.setupStep(
- svn.SVN(repourl=ConstantRenderable('http://svn.local/trunk/app'),
- mode='incremental'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache'])
- + ExpectShell.log('stdio', # expecting ../trunk/app
- stdout="""<?xml version="1.0"?><url>http://svn.local/branch/foo/app</url>""")
- + 0,
- Expect('rmdir', {'dir': 'wkdir', 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'checkout', 'http://svn.local/trunk/app',
- '.', '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_incremental_given_revision(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental'), dict(
- revision='100',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--revision', '100',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_incremental_win32path(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental',username='user',
- password='pass', extra_args=['--random']))
- self.build.path_module = namedModule("ntpath")
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file=r'wkdir\.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- return self.runStep()
-
- def test_mode_incremental_preferLastChangedRev(self):
- """Give the last-changed rev if 'preferLastChangedRev' is set"""
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental',username='user',
- preferLastChangedRev=True,
- password='pass', extra_args=['--random']))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '90', 'SVN')
- return self.runStep()
-
- def test_mode_incremental_preferLastChangedRev_butMissing(self):
- """If 'preferLastChangedRev' is set, but missing, fall back
- to the regular revision value."""
- svn_info_stdout = self.svn_info_stdout_xml.replace('commit', 'Blah')
-
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental',username='user',
- preferLastChangedRev=True,
- password='pass', extra_args=['--random']))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=svn_info_stdout)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_clobber(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='clobber'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', {'dir': 'wkdir',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'checkout',
- 'http://svn.local/app/trunk', '.',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_clobber_given_revision(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='clobber'),dict(
- revision='100',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', {'dir': 'wkdir',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'checkout',
- 'http://svn.local/app/trunk', '.',
- '--revision', '100',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_fresh(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='fresh', depth='infinite'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--depth', 'infinite' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn',
- 'status', '--xml', '--no-ignore',
- '--non-interactive', '--no-auth-cache',
- '--depth', 'infinite'])
- + ExpectShell.log('stdio',
- stdout=self.svn_st_xml_empty)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update',
- '--non-interactive', '--no-auth-cache', '--depth', 'infinite'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio', stdout=self.svn_info_stdout_xml)
- + ExpectShell.log('stdio', stdout='\n')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_fresh_given_revision(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='fresh', depth='infinite'),dict(
- revision='100',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--depth', 'infinite' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn',
- 'status', '--xml', '--no-ignore',
- '--non-interactive', '--no-auth-cache',
- '--depth', 'infinite'])
- + ExpectShell.log('stdio',
- stdout=self.svn_st_xml_empty)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--revision', '100',
- '--non-interactive', '--no-auth-cache', '--depth', 'infinite'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio', stdout=self.svn_info_stdout_xml)
- + ExpectShell.log('stdio', stdout='\n')
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_fresh_keep_on_purge(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full',
- keep_on_purge=['svn_external_path/unversioned_file1']))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn',
- 'status', '--xml', '--no-ignore',
- '--non-interactive', '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout=self.svn_st_xml)
- + 0,
- Expect('rmdir', {'dir':
- ['wkdir/svn_external_path/unversioned_file2'],
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio', stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_clean(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn',
- 'status', '--xml',
- '--non-interactive', '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout=self.svn_st_xml_empty)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio', stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_clean_given_revision(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='clean'),dict(
- revision='100',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn',
- 'status', '--xml',
- '--non-interactive', '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout=self.svn_st_xml_empty)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--revision', '100',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio', stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_not_updatable(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 1,
- Expect('rmdir', {'dir': 'wkdir', 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'checkout', 'http://svn.local/app/trunk',
- '.', '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio', stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_not_updatable_given_revision(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='clean'),dict(
- revision='100',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 1,
- Expect('rmdir', {'dir': 'wkdir', 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'checkout', 'http://svn.local/app/trunk',
- '.', '--revision', '100',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio', stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_clean_old_rmdir(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='clean'))
- self.patch_slaveVersionIsOlderThan(True)
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn',
- 'status', '--xml',
- '--non-interactive', '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout=self.svn_st_xml)
- + 0,
- Expect('rmdir', {'dir':
- 'wkdir/svn_external_path/unversioned_file1',
- 'logEnviron': True})
- + 0,
- Expect('rmdir', {'dir':
- 'wkdir/svn_external_path/unversioned_file2',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio', stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_clean_new_rmdir(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='clean'))
-
- self.patch_slaveVersionIsOlderThan(False)
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn',
- 'status', '--xml',
- '--non-interactive', '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout=self.svn_st_xml)
- + 0,
- Expect('rmdir', {'dir':
- ['wkdir/svn_external_path/unversioned_file1',
- 'wkdir/svn_external_path/unversioned_file2'],
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio', stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_copy(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='copy'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- Expect('stat', dict(file='source/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache'])
- + 0,
- Expect('cpdir', {'fromdir': 'source',
- 'todir': 'wkdir',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_copy_given_revision(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='copy'),dict(
- revision='100',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- Expect('stat', dict(file='source/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'update', '--revision', '100',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- Expect('cpdir', {'fromdir': 'source',
- 'todir': 'wkdir',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_export(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='export'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- Expect('stat', dict(file='source/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='',
- command=['svn', 'export', 'source', 'wkdir'])
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_export_timeout(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- timeout=1,
- mode='full', method='export'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- timeout=1,
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- Expect('stat', dict(file='source/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='source',
- timeout=1,
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='source',
- timeout=1,
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='',
- timeout=1,
- command=['svn', 'export', 'source', 'wkdir'])
- + 0,
- ExpectShell(workdir='source',
- timeout=1,
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_full_export_given_revision(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='export'),dict(
- revision='100',
- ))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- Expect('stat', dict(file='source/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'update', '--revision', '100',
- '--non-interactive', '--no-auth-cache'])
- + 0,
- ExpectShell(workdir='',
- command=['svn', 'export', '--revision', '100',
- 'source', 'wkdir'])
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_incremental_with_env(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental',username='user',
- password='pass', extra_args=['--random'],
- env={'abc': '123'}))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'],
- env={'abc': '123'})
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'],
- env={'abc': '123'})
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'],
- env={'abc': '123'})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'],
- env={'abc': '123'})
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_mode_incremental_logEnviron(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental',username='user',
- password='pass', extra_args=['--random'],
- logEnviron=False))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'],
- logEnviron=False)
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=False))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'],
- logEnviron=False)
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'],
- logEnviron=False)
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'],
- logEnviron=False)
- + ExpectShell.log('stdio',
- stdout=self.svn_info_stdout_xml)
- + 0,
- )
- self.expectOutcome(result=SUCCESS, status_text=["update"])
- self.expectProperty('got_revision', '100', 'SVN')
- return self.runStep()
-
- def test_command_fails(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental',username='user',
- password='pass', extra_args=['--random']))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + 1,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_bogus_svnversion(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='incremental',username='user',
- password='pass', extra_args=['--random']))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', dict(file='wkdir/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + ExpectShell.log('stdio', stdout="""<?xml version="1.0"?><entry kind="dir" path="/a/b/c" revision="1"><url>http://svn.local/app/trunk</url></entry>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache', '--username', 'user',
- '--password', 'pass', '--random'])
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml'])
- + ExpectShell.log('stdio',
- stdout='1x0y0')
- + 0,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_rmdir_fails_clobber(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='clobber'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', {'dir': 'wkdir',
- 'logEnviron': True})
- + 1,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_rmdir_fails_copy(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='copy'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 1,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_cpdir_fails_copy(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full', method='copy'))
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('rmdir', dict(dir='wkdir',
- logEnviron=True))
- + 0,
- Expect('stat', dict(file='source/.svn',
- logEnviron=True))
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='source',
- command=['svn', 'update', '--non-interactive',
- '--no-auth-cache'])
- + 0,
- Expect('cpdir', {'fromdir': 'source',
- 'todir': 'wkdir',
- 'logEnviron': True})
- + 1,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
- def test_rmdir_fails_purge(self):
- self.setupStep(
- svn.SVN(repourl='http://svn.local/app/trunk',
- mode='full',
- keep_on_purge=['svn_external_path/unversioned_file1']))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir',
- command=['svn', '--version'])
- + 0,
- Expect('stat', {'file': 'wkdir/.svn',
- 'logEnviron': True})
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn', 'info', '--xml',
- '--non-interactive',
- '--no-auth-cache' ])
- + ExpectShell.log('stdio',
- stdout="""<?xml version="1.0"?><url>http://svn.local/app/trunk</url>""")
- + 0,
- ExpectShell(workdir='wkdir',
- command=['svn',
- 'status', '--xml', '--no-ignore',
- '--non-interactive', '--no-auth-cache'])
- + ExpectShell.log('stdio',
- stdout=self.svn_st_xml)
- + 0,
- Expect('rmdir', {'dir':
- ['wkdir/svn_external_path/unversioned_file2'],
- 'logEnviron': True})
- + 1,
- )
- self.expectOutcome(result=FAILURE, status_text=["updating"])
- return self.runStep()
-
-class TestGetUnversionedFiles(unittest.TestCase):
- def test_getUnversionedFiles_does_not_list_externals(self):
- svn_st_xml = """<?xml version="1.0"?>
- <status>
- <target path=".">
- <entry path="svn_external_path">
- <wc-status props="none" item="external">
- </wc-status>
- </entry>
- <entry path="svn_external_path/unversioned_file">
- <wc-status props="none" item="unversioned">
- </wc-status>
- </entry>
- </target>
- </status>
- """
- unversioned_files = list(svn.SVN.getUnversionedFiles(svn_st_xml, []))
- self.assertEquals(["svn_external_path/unversioned_file"], unversioned_files)
-
- def test_getUnversionedFiles_does_not_list_missing(self):
- svn_st_xml = """<?xml version="1.0"?>
- <status>
- <target path=".">
- <entry path="missing_file">
- <wc-status props="none" item="missing"></wc-status>
- </entry>
- </target>
- </status>
- """
- unversioned_files = list(svn.SVN.getUnversionedFiles(svn_st_xml, []))
- self.assertEquals([], unversioned_files)
-
- def test_getUnversionedFiles_corrupted_xml(self):
- svn_st_xml_corrupt = """<?xml version="1.0"?>
- <target path=".">
- <entry path="svn_external_path">
- <wc-status props="none" item="external">
- </wc-status>
- </entry>
- <entry path="svn_external_path/unversioned_file">
- <wc-status props="none" item="unversioned">
- </wc-status>
- </entry>
- </target>
- </status>
- """
- self.assertRaises(buildstep.BuildStepFailed,
- lambda : list(svn.SVN.getUnversionedFiles(svn_st_xml_corrupt, [])))
-
- def test_getUnversionedFiles_no_path(self):
- svn_st_xml = """<?xml version="1.0"?>
- <status>
- <target path=".">
- <entry path="svn_external_path">
- <wc-status props="none" item="external">
- </wc-status>
- </entry>
- <entry>
- <wc-status props="none" item="unversioned">
- </wc-status>
- </entry>
- </target>
- </status>
- """
- unversioned_files = list(svn.SVN.getUnversionedFiles(svn_st_xml, []))
- self.assertEquals([], unversioned_files)
-
- def test_getUnversionedFiles_no_item(self):
- svn_st_xml = """<?xml version="1.0"?>
- <status>
- <target path=".">
- <entry path="svn_external_path">
- <wc-status props="none" item="external">
- </wc-status>
- </entry>
- <entry path="svn_external_path/unversioned_file">
- <wc-status props="none">
- </wc-status>
- </entry>
- </target>
- </status>
- """
- unversioned_files = list(svn.SVN.getUnversionedFiles(svn_st_xml, []))
- self.assertEquals(["svn_external_path/unversioned_file"], unversioned_files)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_subunit.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_subunit.py
deleted file mode 100644
index a639b071..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_subunit.py
+++ /dev/null
@@ -1,86 +0,0 @@
-# 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 mock
-import StringIO
-from zope.interface import implements
-from twisted.trial import unittest
-from buildbot import interfaces
-from buildbot.steps import subunit
-from buildbot.process import subunitlogobserver
-from buildbot.status.results import SUCCESS, FAILURE
-from buildbot.test.fake.remotecommand import ExpectShell
-from buildbot.test.util import steps
-
-class StubLogObserver(mock.Mock):
- implements(interfaces.ILogObserver)
-
-class TestSetPropertiesFromEnv(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- self.logobserver = StubLogObserver()
- self.logobserver.failures = []
- self.logobserver.errors = []
- self.logobserver.skips = []
- self.logobserver.testsRun = 0
- self.logobserver.warningio = StringIO.StringIO()
- self.patch(subunitlogobserver, 'SubunitLogObserver',
- lambda : self.logobserver)
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_empty(self):
- self.setupStep(subunit.SubunitShellCommand(command='test'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="test")
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["shell", "no tests", "run"])
- return self.runStep()
-
- def test_empty_error(self):
- self.setupStep(subunit.SubunitShellCommand(command='test',
- failureOnNoTests=True))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="test")
- + 0
- )
- self.expectOutcome(result=FAILURE,
- status_text=["shell", "no tests", "run"])
- return self.runStep()
-
- def test_warnings(self):
- self.setupStep(subunit.SubunitShellCommand(command='test'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command="test")
- + 0
- )
- self.logobserver.warnings.append('not quite up to snuff (list)')
- self.logobserver.warningio.write('not quite up to snuff (io)\n')
- self.logobserver.testsRun = 3
- self.expectOutcome(result=SUCCESS, # N.B. not WARNINGS
- status_text=["shell", "3 tests", "passed"])
- # note that the warnings list is ignored..
- self.expectLogfile('warnings', 'not quite up to snuff (io)\n')
- return self.runStep()
-
- # TODO: test text2 generation?
- # TODO: tests are represented as objects?!
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_transfer.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_transfer.py
deleted file mode 100644
index cfdcefb9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_transfer.py
+++ /dev/null
@@ -1,267 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import tempfile, os
-import shutil
-import tarfile
-from twisted.trial import unittest
-
-from mock import Mock
-
-from buildbot.process.properties import Properties
-from buildbot.util import json
-from buildbot.steps import transfer
-from buildbot.status.results import SUCCESS
-from buildbot import config
-from buildbot.test.util import steps
-from buildbot.test.fake.remotecommand import Expect, ExpectRemoteRef
-
-class TestFileUpload(unittest.TestCase):
- def setUp(self):
- fd, self.destfile = tempfile.mkstemp()
- os.close(fd)
- os.unlink(self.destfile)
-
- def tearDown(self):
- if os.path.exists(self.destfile):
- os.unlink(self.destfile)
-
- def test_constructor_mode_type(self):
- self.assertRaises(config.ConfigErrors, lambda :
- transfer.FileUpload(slavesrc=__file__, masterdest='xyz', mode='g+rwx'))
-
- def testBasic(self):
- s = transfer.FileUpload(slavesrc=__file__, masterdest=self.destfile)
- s.build = Mock()
- s.build.getProperties.return_value = Properties()
- s.build.getSlaveCommandVersion.return_value = 1
-
- s.step_status = Mock()
- s.buildslave = Mock()
- s.remote = Mock()
-
- s.start()
-
- for c in s.remote.method_calls:
- name, command, args = c
- commandName = command[3]
- kwargs = command[-1]
- if commandName == 'uploadFile':
- self.assertEquals(kwargs['slavesrc'], __file__)
- writer = kwargs['writer']
- with open(__file__, "rb") as f:
- writer.remote_write(f.read())
- self.assert_(not os.path.exists(self.destfile))
- writer.remote_close()
- break
- else:
- self.assert_(False, "No uploadFile command found")
-
- with open(self.destfile, "rb") as dest:
- with open(__file__, "rb") as expect:
- self.assertEquals(dest.read(), expect.read())
-
- def testTimestamp(self):
- s = transfer.FileUpload(slavesrc=__file__, masterdest=self.destfile, keepstamp=True)
- s.build = Mock()
- s.build.getProperties.return_value = Properties()
- s.build.getSlaveCommandVersion.return_value = "2.13"
-
- s.step_status = Mock()
- s.buildslave = Mock()
- s.remote = Mock()
- s.start()
- timestamp = ( os.path.getatime(__file__),
- os.path.getmtime(__file__) )
-
- for c in s.remote.method_calls:
- name, command, args = c
- commandName = command[3]
- kwargs = command[-1]
- if commandName == 'uploadFile':
- self.assertEquals(kwargs['slavesrc'], __file__)
- writer = kwargs['writer']
- with open(__file__, "rb") as f:
- writer.remote_write(f.read())
- self.assert_(not os.path.exists(self.destfile))
- writer.remote_close()
- writer.remote_utime(timestamp)
- break
- else:
- self.assert_(False, "No uploadFile command found")
-
- desttimestamp = ( os.path.getatime(self.destfile),
- os.path.getmtime(self.destfile) )
-
- timestamp = map(int, timestamp)
- desttimestamp = map(int, desttimestamp)
-
- self.assertEquals(timestamp[0],desttimestamp[0])
- self.assertEquals(timestamp[1],desttimestamp[1])
-
- def testURL(self):
- s = transfer.FileUpload(slavesrc=__file__, masterdest=self.destfile, url="http://server/file")
- s.build = Mock()
- s.build.getProperties.return_value = Properties()
- s.build.getSlaveCommandVersion.return_value = "2.13"
-
- s.step_status = Mock()
- s.step_status.addURL = Mock()
- s.buildslave = Mock()
- s.remote = Mock()
- s.start()
-
- for c in s.remote.method_calls:
- name, command, args = c
- commandName = command[3]
- kwargs = command[-1]
- if commandName == 'uploadFile':
- self.assertEquals(kwargs['slavesrc'], __file__)
- writer = kwargs['writer']
- with open(__file__, "rb") as f:
- writer.remote_write(f.read())
- self.assert_(not os.path.exists(self.destfile))
- writer.remote_close()
- break
- else:
- self.assert_(False, "No uploadFile command found")
-
- s.step_status.addURL.assert_called_once_with(
- os.path.basename(self.destfile), "http://server/file")
-
-class TestDirectoryUpload(steps.BuildStepMixin, unittest.TestCase):
- def setUp(self):
- self.destdir = os.path.abspath('destdir')
- if os.path.exists(self.destdir):
- shutil.rmtree(self.destdir)
-
- return self.setUpBuildStep()
-
- def tearDown(self):
- if os.path.exists(self.destdir):
- shutil.rmtree(self.destdir)
-
- return self.tearDownBuildStep()
-
- def testBasic(self):
- self.setupStep(
- transfer.DirectoryUpload(slavesrc="srcdir", masterdest=self.destdir))
-
- def upload_behavior(command):
- from cStringIO import StringIO
- f = StringIO()
- archive = tarfile.TarFile(fileobj=f, name='fake.tar', mode='w')
- archive.addfile(tarfile.TarInfo("test"), StringIO("Hello World!"))
- writer = command.args['writer']
- writer.remote_write(f.getvalue())
- writer.remote_unpack()
-
- self.expectCommands(
- Expect('uploadDirectory', dict(
- slavesrc="srcdir", workdir='wkdir',
- blocksize=16384, compress=None, maxsize=None,
- writer=ExpectRemoteRef(transfer._DirectoryWriter)))
- + Expect.behavior(upload_behavior)
- + 0)
-
- self.expectOutcome(result=SUCCESS, status_text=["uploading", "srcdir"])
- d = self.runStep()
- return d
-
-class TestStringDownload(unittest.TestCase):
- def testBasic(self):
- s = transfer.StringDownload("Hello World", "hello.txt")
- s.build = Mock()
- s.build.getProperties.return_value = Properties()
- s.build.getSlaveCommandVersion.return_value = 1
-
- s.step_status = Mock()
- s.buildslave = Mock()
- s.remote = Mock()
-
- s.start()
-
- for c in s.remote.method_calls:
- name, command, args = c
- commandName = command[3]
- kwargs = command[-1]
- if commandName == 'downloadFile':
- self.assertEquals(kwargs['slavedest'], 'hello.txt')
- reader = kwargs['reader']
- data = reader.remote_read(100)
- self.assertEquals(data, "Hello World")
- break
- else:
- self.assert_(False, "No downloadFile command found")
-
-class TestJSONStringDownload(unittest.TestCase):
- def testBasic(self):
- msg = dict(message="Hello World")
- s = transfer.JSONStringDownload(msg, "hello.json")
- s.build = Mock()
- s.build.getProperties.return_value = Properties()
- s.build.getSlaveCommandVersion.return_value = 1
-
- s.step_status = Mock()
- s.buildslave = Mock()
- s.remote = Mock()
-
- s.start()
-
- for c in s.remote.method_calls:
- name, command, args = c
- commandName = command[3]
- kwargs = command[-1]
- if commandName == 'downloadFile':
- self.assertEquals(kwargs['slavedest'], 'hello.json')
- reader = kwargs['reader']
- data = reader.remote_read(100)
- self.assertEquals(data, json.dumps(msg))
- break
- else:
- self.assert_(False, "No downloadFile command found")
-
-class TestJSONPropertiesDownload(unittest.TestCase):
- def testBasic(self):
- s = transfer.JSONPropertiesDownload("props.json")
- s.build = Mock()
- props = Properties()
- props.setProperty('key1', 'value1', 'test')
- s.build.getProperties.return_value = props
- s.build.getSlaveCommandVersion.return_value = 1
- ss = Mock()
- ss.asDict.return_value = dict(revision="12345")
- s.build.getSourceStamp.return_value = ss
-
- s.step_status = Mock()
- s.buildslave = Mock()
- s.remote = Mock()
-
- s.start()
-
- for c in s.remote.method_calls:
- name, command, args = c
- commandName = command[3]
- kwargs = command[-1]
- if commandName == 'downloadFile':
- self.assertEquals(kwargs['slavedest'], 'props.json')
- reader = kwargs['reader']
- data = reader.remote_read(100)
- self.assertEquals(data, json.dumps(dict(sourcestamp=ss.asDict(), properties={'key1': 'value1'})))
- break
- else:
- self.assert_(False, "No downloadFile command found")
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_trigger.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_trigger.py
deleted file mode 100644
index 245985a5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_trigger.py
+++ /dev/null
@@ -1,502 +0,0 @@
-# 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
-
-from zope.interface import implements
-
-from twisted.trial import unittest
-from twisted.python import failure
-from twisted.internet import defer, reactor
-from buildbot import config, interfaces
-from buildbot.process import properties
-from buildbot.status import master
-from buildbot.status.results import SUCCESS, FAILURE, EXCEPTION
-from buildbot.steps import trigger
-from buildbot.test.util import steps, compat
-from buildbot.test.fake import fakemaster, fakedb
-
-class FakeTriggerable(object):
- implements(interfaces.ITriggerableScheduler)
-
- triggered_with = None
- result = SUCCESS
- brids = {}
- exception = False
-
- def __init__(self, name):
- self.name = name
-
- def trigger(self, sourcestamps = None, set_props=None):
- self.triggered_with = (sourcestamps, set_props.properties)
- d = defer.Deferred()
- if self.exception:
- reactor.callLater(0, d.errback, RuntimeError('oh noes'))
- else:
- reactor.callLater(0, d.callback, (self.result, self.brids))
- return d
-
-
-class FakeSourceStamp(object):
-
- def __init__(self, **kwargs):
- self.__dict__.update(kwargs)
-
- def asDict(self, includePatch = True):
- return self.__dict__.copy()
-
-# Magic numbers that relate brid to other build settings
-BRID_TO_BSID = lambda brid: brid+2000
-BRID_TO_BID = lambda brid: brid+3000
-BRID_TO_BUILD_NUMBER = lambda brid: brid+4000
-
-class TestTrigger(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def setupStep(self, step, sourcestampsInBuild=None, gotRevisionsInBuild=None, *args, **kwargs):
- sourcestamps = sourcestampsInBuild or []
- got_revisions = gotRevisionsInBuild or {}
-
- steps.BuildStepMixin.setupStep(self, step, *args, **kwargs)
-
- # This step reaches deeply into a number of parts of Buildbot. That
- # should be fixed!
-
- # set up a buildmaster that knows about two fake schedulers, a and b
- m = fakemaster.make_master()
- self.build.builder.botmaster = m.botmaster
- m.db = fakedb.FakeDBConnector(self)
- m.status = master.Status(m)
- m.config.buildbotURL = "baseurl/"
-
- self.scheduler_a = a = FakeTriggerable(name='a')
- self.scheduler_b = b = FakeTriggerable(name='b')
- def allSchedulers():
- return [ a, b ]
- m.allSchedulers = allSchedulers
-
- a.brids = {'A': 11}
- b.brids = {'B': 22}
-
- make_fake_br = lambda brid, name: fakedb.BuildRequest(id=brid,
- buildsetid=BRID_TO_BSID(brid),
- buildername=name)
- make_fake_build = lambda brid: fakedb.Build(brid=brid,
- id=BRID_TO_BID(brid),
- number=BRID_TO_BUILD_NUMBER(brid))
-
- m.db.insertTestData([
- make_fake_br(11, "A"),
- make_fake_br(22, "B"),
- make_fake_build(11),
- make_fake_build(22),
- ])
-
- def getAllSourceStamps():
- return sourcestamps
- self.build.getAllSourceStamps = getAllSourceStamps
- def getAllGotRevisions():
- return got_revisions
- self.build.build_status.getAllGotRevisions = getAllGotRevisions
-
- self.exp_add_sourcestamp = None
- self.exp_a_trigger = None
- self.exp_b_trigger = None
- self.exp_added_urls = []
-
- def runStep(self, expect_waitForFinish=False):
- d = steps.BuildStepMixin.runStep(self)
-
- if expect_waitForFinish:
- # the build doesn't finish until after a callLater, so this has the
- # effect of checking whether the deferred has been fired already;
- # it should not have been!
- early = []
- d.addCallback(early.append)
- self.assertEqual(early, [])
-
- def check(_):
- self.assertEqual(self.scheduler_a.triggered_with,
- self.exp_a_trigger)
- self.assertEqual(self.scheduler_b.triggered_with,
- self.exp_b_trigger)
- self.assertEqual(self.step_status.addURL.call_args_list,
- self.exp_added_urls)
-
- if self.exp_add_sourcestamp:
- self.assertEqual(self.addSourceStamp_kwargs,
- self.exp_add_sourcestamp)
- d.addCallback(check)
-
- # pause runStep's completion until after any other callLater's are done
- def wait(_):
- d = defer.Deferred()
- reactor.callLater(0, d.callback, None)
- return d
- d.addCallback(wait)
-
- return d
-
- def expectTriggeredWith(self, a=None, b=None):
- self.exp_a_trigger = a
- self.exp_b_trigger = b
-
- def expectAddedSourceStamp(self, **kwargs):
- self.exp_add_sourcestamp = kwargs
-
- def expectTriggeredLinks(self, *args):
- def get_args(sch, name):
- label = lambda name, num: "%s #%d" % (name, num)
- url = lambda name, num: "baseurl/builders/%s/builds/%d" % (name, num )
-
- num = BRID_TO_BUILD_NUMBER(sch.brids[name])
-
- #returns the *args and **kwargs that will be called on addURL...
- # which is just addURL('label', 'url')
- return ( (label(name,num), url(name,num)) , {} )
-
- if 'a' in args:
- self.exp_added_urls.append(get_args(self.scheduler_a, 'A'))
- if 'b' in args:
- self.exp_added_urls.append(get_args(self.scheduler_b, 'B'))
-
-
- # tests
-
- def test_no_schedulerNames(self):
- self.assertRaises(config.ConfigErrors, lambda :
- trigger.Trigger())
-
- def test_sourceStamp_and_updateSourceStamp(self):
- self.assertRaises(config.ConfigErrors, lambda :
- trigger.Trigger(schedulerNames=['c'],
- sourceStamp=dict(x=1), updateSourceStamp=True))
-
- def test_sourceStamps_and_updateSourceStamp(self):
- self.assertRaises(config.ConfigErrors, lambda :
- trigger.Trigger(schedulerNames=['c'],
- sourceStamps=[dict(x=1), dict(x=2)],
- updateSourceStamp=True))
-
- def test_updateSourceStamp_and_alwaysUseLatest(self):
- self.assertRaises(config.ConfigErrors, lambda :
- trigger.Trigger(schedulerNames=['c'],
- updateSourceStamp=True, alwaysUseLatest=True))
-
- def test_sourceStamp_and_alwaysUseLatest(self):
- self.assertRaises(config.ConfigErrors, lambda :
- trigger.Trigger(schedulerNames=['c'],
- sourceStamp=dict(x=1), alwaysUseLatest=True))
-
- def test_sourceStamps_and_alwaysUseLatest(self):
- self.assertRaises(config.ConfigErrors, lambda :
- trigger.Trigger(schedulerNames=['c'],
- sourceStamps=[dict(x=1), dict(x=2)],
- alwaysUseLatest=True))
-
- def test_simple(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'], sourceStamps = {}))
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({}, {}))
- return self.runStep()
-
- def test_simple_failure(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a']))
- self.scheduler_a.result = FAILURE
- # not waitForFinish, so trigger step succeeds even though the build
- # didn't fail
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({}, {}))
- return self.runStep()
-
- @compat.usesFlushLoggedErrors
- def test_simple_exception(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a']))
- self.scheduler_a.exception = True
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=( {}, {}))
- d = self.runStep()
- def flush(_):
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
- d.addCallback(flush)
- return d
-
- def test_bogus_scheduler(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a', 'x']))
- self.expectOutcome(result=FAILURE, status_text=['not valid scheduler:', 'x'])
- self.expectTriggeredWith(a=None) # a is not triggered!
- return self.runStep()
-
- def test_updateSourceStamp(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- updateSourceStamp=True),
- sourcestampsInBuild = [FakeSourceStamp(codebase='',
- repository='x',
- revision=11111)
- ],
- gotRevisionsInBuild = {'': 23456},
- )
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({'':{'codebase':'',
- 'repository': 'x',
- 'revision': 23456}
- }, {}))
- return self.runStep()
-
- def test_updateSourceStamp_no_got_revision(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- updateSourceStamp=True),
- sourcestampsInBuild = [FakeSourceStamp(codebase='',
- repository='x',
- revision=11111)
- ])
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({'':{'codebase':'',
- 'repository': 'x',
- 'revision': 11111} # uses old revision
- }, {}))
- return self.runStep()
-
- def test_not_updateSourceStamp(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- updateSourceStamp=False),
- sourcestampsInBuild = [FakeSourceStamp(codebase='',
- repository='x',
- revision=11111)
- ],
- gotRevisionsInBuild = {'': 23456},
- )
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({'':{'codebase':'',
- 'repository': 'x',
- 'revision': 11111}
- }, {}))
- return self.runStep()
-
- def test_updateSourceStamp_multiple_repositories(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- updateSourceStamp=True),
- sourcestampsInBuild = [
- FakeSourceStamp(codebase='cb1',
- revision='12345'),
- FakeSourceStamp(codebase='cb2',
- revision='12345')
- ],
- gotRevisionsInBuild = {'cb1': 23456, 'cb2': 34567},
- )
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({'cb1': {'codebase':'cb1',
- 'revision':23456},
- 'cb2': {'codebase':'cb2',
- 'revision':34567}
- }, {}))
- return self.runStep()
-
- def test_updateSourceStamp_prop_false(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- updateSourceStamp=properties.Property('usess')),
- sourcestampsInBuild = [FakeSourceStamp(codebase='',
- repository='x',
- revision=11111)
- ],
- gotRevisionsInBuild = {'': 23456},
- )
- self.properties.setProperty('usess', False, 'me')
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- # didn't use got_revision
- self.expectTriggeredWith(a=({'': { 'codebase':'',
- 'repository': 'x',
- 'revision': 11111
- }}, {}))
- return self.runStep()
-
- def test_updateSourceStamp_prop_true(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- updateSourceStamp=properties.Property('usess')),
- sourcestampsInBuild = [FakeSourceStamp(codebase='',
- repository='x',
- revision=11111)
- ],
- gotRevisionsInBuild = {'': 23456},
- )
- self.properties.setProperty('usess', True, 'me')
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- # didn't use got_revision
- self.expectTriggeredWith(a=({'': { 'codebase':'',
- 'repository': 'x',
- 'revision': 23456
- }}, {}))
- return self.runStep()
-
- def test_alwaysUseLatest(self):
- self.setupStep(trigger.Trigger(schedulerNames=['b'],
- alwaysUseLatest=True),
- sourcestampsInBuild = [FakeSourceStamp(codebase='',
- repository='x',
- revision=11111)
- ])
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'b'])
- # Do not pass setid
- self.expectTriggeredWith(b=({}, {}))
- return self.runStep()
-
- def test_alwaysUseLatest_prop_false(self):
- self.setupStep(trigger.Trigger(schedulerNames=['b'],
- alwaysUseLatest=properties.Property('aul')),
- sourcestampsInBuild = [FakeSourceStamp(codebase='',
- repository='x',
- revision=11111)
- ])
- self.properties.setProperty('aul', False, 'me')
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'b'])
- # didn't use latest
- self.expectTriggeredWith(b=({'': { 'codebase':'',
- 'repository': 'x',
- 'revision': 11111}
- }, {}))
- return self.runStep()
-
- def test_alwaysUseLatest_prop_true(self):
- self.setupStep(trigger.Trigger(schedulerNames=['b'],
- alwaysUseLatest=properties.Property('aul')),
- sourcestampsInBuild = [FakeSourceStamp(codebase='',
- repository='x',
- revision=11111)
- ])
- self.properties.setProperty('aul', True, 'me')
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'b'])
- # didn't use latest
- self.expectTriggeredWith(b=({}, {}))
- return self.runStep()
-
- def test_sourceStamp(self):
- ss = dict(revision=9876, branch='dev')
- self.setupStep(trigger.Trigger(schedulerNames=['b'],
- sourceStamp=ss))
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'b'])
- self.expectTriggeredWith(b=({'': ss}, {}))
- return self.runStep()
-
- def test_set_of_sourceStamps(self):
- ss1 = dict(codebase='cb1', repository='r1', revision=9876, branch='dev')
- ss2 = dict(codebase='cb2',repository='r2', revision=5432, branch='dev')
- self.setupStep(trigger.Trigger(schedulerNames=['b'],
- sourceStamps=[ss1,ss2]))
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'b'])
- self.expectTriggeredWith(b=({'cb1':ss1, 'cb2':ss2}, {}))
- return self.runStep()
-
- def test_set_of_sourceStamps_override_build(self):
- ss1 = dict(codebase='cb1', repository='r1', revision=9876, branch='dev')
- ss2 = dict(codebase='cb2',repository='r2', revision=5432, branch='dev')
- ss3 = FakeSourceStamp(codebase='cb3', repository='r3', revision=1234, branch='dev')
- ss4 = FakeSourceStamp(codebase='cb4',repository='r4', revision=2345, branch='dev')
- self.setupStep(trigger.Trigger(schedulerNames=['b'],
- sourceStamps=[ss1,ss2]), sourcestampsInBuild=[ss3, ss4])
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'b'])
- self.expectTriggeredWith(b=({'cb1':ss1, 'cb2':ss2}, {}))
- return self.runStep()
-
-
- def test_sourceStamp_prop(self):
- self.setupStep(trigger.Trigger(schedulerNames=['b'],
- sourceStamp=dict(revision=properties.Property('rev'),
- branch='dev')))
- self.properties.setProperty('rev', 602, 'me')
- expected_ss = dict(revision=602, branch='dev')
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'b'])
- self.expectTriggeredWith(b=({'': expected_ss}, {}))
- return self.runStep()
-
- def test_waitForFinish(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a', 'b'],
- waitForFinish=True))
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a', 'b'])
- self.expectTriggeredWith(
- a=({}, {}),
- b=({}, {}))
- self.expectTriggeredLinks('a','b')
- return self.runStep(expect_waitForFinish=True)
-
- def test_waitForFinish_failure(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- waitForFinish=True))
- self.scheduler_a.result = FAILURE
- self.expectOutcome(result=FAILURE, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({}, {}))
- self.expectTriggeredLinks('a')
- return self.runStep(expect_waitForFinish=True)
-
- @compat.usesFlushLoggedErrors
- def test_waitForFinish_exception(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a', 'b'],
- waitForFinish=True))
- self.scheduler_b.exception = True
- self.expectOutcome(result=EXCEPTION,
- status_text=['triggered', 'a', 'b'])
- self.expectTriggeredWith(
- a=({}, {}),
- b=({}, {}))
- self.expectTriggeredLinks('a') # b doesn't return a brid
- d = self.runStep(expect_waitForFinish=True)
- def flush(_):
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
- d.addCallback(flush)
- return d
-
- def test_set_properties(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- set_properties=dict(x=1, y=2)))
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({},
- dict(x=(1, 'Trigger'), y=(2, 'Trigger'))))
- return self.runStep()
-
- def test_set_properties_prop(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- set_properties=dict(x=properties.Property('X'), y=2)))
- self.properties.setProperty('X', 'xxx', 'here')
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({},
- dict(x=('xxx', 'Trigger'), y=(2, 'Trigger'))))
- return self.runStep()
-
- def test_copy_properties(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- copy_properties=['a', 'b']))
- self.properties.setProperty('a', 'A', 'AA')
- self.properties.setProperty('b', 'B', 'BB')
- self.properties.setProperty('c', 'C', 'CC')
- self.expectOutcome(result=SUCCESS, status_text=['triggered', 'a'])
- self.expectTriggeredWith(a=({},
- dict(a=('A', 'Trigger'),
- b=('B', 'Trigger'))))
- return self.runStep()
-
- def test_interrupt(self):
- self.setupStep(trigger.Trigger(schedulerNames=['a'],
- waitForFinish=True))
- self.expectOutcome(result=EXCEPTION, status_text=['interrupted'])
- self.expectTriggeredWith(a=({}, {}))
- d = self.runStep(expect_waitForFinish=True)
-
- # interrupt before the callLater representing the Triggerable
- # schedulers completes
- self.step.interrupt(failure.Failure(RuntimeError('oh noes')))
-
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_vstudio.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_vstudio.py
deleted file mode 100644
index d2cfcb63..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_steps_vstudio.py
+++ /dev/null
@@ -1,824 +0,0 @@
-# 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
-
-from buildbot.status.results import SUCCESS, FAILURE, WARNINGS
-from buildbot.steps import vstudio
-from buildbot.test.fake.remotecommand import ExpectShell
-from buildbot.test.util import steps
-from twisted.trial import unittest
-from buildbot.process.properties import Property
-
-from mock import Mock
-
-real_log = r"""
-1>------ Build started: Project: lib1, Configuration: debug Win32 ------
-1>Compiling...
-1>SystemLog.cpp
-1>c:\absolute\path\to\systemlog.cpp(7) : warning C4100: 'op' : unreferenced formal parameter
-1>c:\absolute\path\to\systemlog.cpp(12) : warning C4100: 'statusword' : unreferenced formal parameter
-1>c:\absolute\path\to\systemlog.cpp(12) : warning C4100: 'op' : unreferenced formal parameter
-1>c:\absolute\path\to\systemlog.cpp(17) : warning C4100: 'retryCounter' : unreferenced formal parameter
-1>c:\absolute\path\to\systemlog.cpp(17) : warning C4100: 'op' : unreferenced formal parameter
-1>c:\absolute\path\to\systemlog.cpp(22) : warning C4100: 'op' : unreferenced formal parameter
-1>Creating library...
-1>Build log was saved at "file://c:\another\absolute\path\to\debug\BuildLog.htm"
-1>lib1 - 0 error(s), 6 warning(s)
-2>------ Build started: Project: product, Configuration: debug Win32 ------
-2>Linking...
-2>LINK : fatal error LNK1168: cannot open ../../debug/directory/dllname.dll for writing
-2>Build log was saved at "file://c:\another\similar\path\to\debug\BuildLog.htm"
-2>product - 1 error(s), 0 warning(s)
-========== Build: 1 succeeded, 1 failed, 6 up-to-date, 0 skipped ==========
-"""
-
-class TestAddEnvPath(unittest.TestCase):
-
- def do_test(self, initial_env, name, value, expected_env):
- vstudio.addEnvPath(initial_env, name, value)
- self.assertEqual(initial_env, expected_env)
-
- def test_new(self):
- self.do_test({}, 'PATH', r'C:\NOTHING',
- { 'PATH' : r'C:\NOTHING;' })
-
- def test_new_semi(self):
- self.do_test({}, 'PATH', r'C:\NOTHING;',
- { 'PATH' : r'C:\NOTHING;' })
-
- def test_existing(self):
- self.do_test({'PATH' : '/bin' }, 'PATH', r'C:\NOTHING',
- { 'PATH' : r'/bin;C:\NOTHING;' })
-
- def test_existing_semi(self):
- self.do_test({'PATH' : '/bin;' }, 'PATH', r'C:\NOTHING',
- { 'PATH' : r'/bin;C:\NOTHING;' })
-
- def test_existing_both_semi(self):
- self.do_test({'PATH' : '/bin;' }, 'PATH', r'C:\NOTHING;',
- { 'PATH' : r'/bin;C:\NOTHING;' })
-
-
-class MSLogLineObserver(unittest.TestCase):
-
- def setUp(self):
- self.warnings = []
- lw = Mock()
- lw.addStdout = lambda l : self.warnings.append(l.rstrip())
-
- self.errors = []
- self.errors_stderr = []
- le = Mock()
- le.addStdout = lambda l : self.errors.append(('o', l.rstrip()))
- le.addStderr = lambda l : self.errors.append(('e', l.rstrip()))
-
- self.llo = vstudio.MSLogLineObserver(lw, le)
-
- self.progress = {}
- self.llo.step = Mock()
- self.llo.step.setProgress = \
- lambda n,prog : self.progress.__setitem__(n, prog)
-
- def receiveLines(self, *lines):
- for line in lines:
- self.llo.outLineReceived(line)
-
- def assertResult(self, nbFiles=0, nbProjects=0, nbWarnings=0, nbErrors=0,
- errors=[], warnings=[], progress={}):
- self.assertEqual(
- dict(nbFiles=self.llo.nbFiles, nbProjects=self.llo.nbProjects,
- nbWarnings=self.llo.nbWarnings,
- nbErrors=self.llo.nbErrors, errors=self.errors,
- warnings=self.warnings, progress=self.progress),
- dict(nbFiles=nbFiles, nbProjects=nbProjects, nbWarnings=nbWarnings,
- nbErrors=nbErrors, errors=errors,
- warnings=warnings, progress=progress))
-
- def test_outLineReceived_empty(self):
- self.llo.outLineReceived('abcd\r\n')
- self.assertResult()
-
- def test_outLineReceived_projects(self):
- lines = [
- "123>----- some project 1 -----",
- "123>----- some project 2 -----",
- ]
- self.receiveLines(*lines)
- self.assertResult(nbProjects=2, progress=dict(projects=2),
- errors=[ ('o', l) for l in lines ],
- warnings=lines)
-
- def test_outLineReceived_files(self):
- lines = [
- "123>SomeClass.cpp",
- "123>SomeStuff.c",
- "123>SomeStuff.h", # .h files not recognized
- ]
- self.receiveLines(*lines)
- self.assertResult(nbFiles=2, progress=dict(files=2))
-
- def test_outLineReceived_warnings(self):
- lines = [
- "abc: warning ABC123: xyz!",
- "def : warning DEF456: wxy!",
- ]
- self.receiveLines(*lines)
- self.assertResult(nbWarnings=2, progress=dict(warnings=2),
- warnings=lines)
-
- def test_outLineReceived_errors(self):
- lines = [
- "error ABC123: foo",
- " error DEF456 : bar",
- " error : bar",
- " error: bar", # NOTE: not matched
- ]
- self.receiveLines(*lines)
- self.assertResult(nbErrors=3, # note: no progress
- errors=[
- ('e', "error ABC123: foo"),
- ('e', " error DEF456 : bar"),
- ('e', " error : bar"),
- ])
-
- def test_outLineReceived_real(self):
- # based on a real logfile donated by Ben Allard
- lines = real_log.split("\n")
- self.receiveLines(*lines)
- errors = [
- ('o', '1>------ Build started: Project: lib1, Configuration: debug Win32 ------'),
- ('o', '2>------ Build started: Project: product, Configuration: debug Win32 ------'),
- ('e', '2>LINK : fatal error LNK1168: cannot open ../../debug/directory/dllname.dll for writing')
- ]
- warnings = [
- '1>------ Build started: Project: lib1, Configuration: debug Win32 ------',
- "1>c:\\absolute\\path\\to\\systemlog.cpp(7) : warning C4100: 'op' : unreferenced formal parameter",
- "1>c:\\absolute\\path\\to\\systemlog.cpp(12) : warning C4100: 'statusword' : unreferenced formal parameter",
- "1>c:\\absolute\\path\\to\\systemlog.cpp(12) : warning C4100: 'op' : unreferenced formal parameter",
- "1>c:\\absolute\\path\\to\\systemlog.cpp(17) : warning C4100: 'retryCounter' : unreferenced formal parameter",
- "1>c:\\absolute\\path\\to\\systemlog.cpp(17) : warning C4100: 'op' : unreferenced formal parameter",
- "1>c:\\absolute\\path\\to\\systemlog.cpp(22) : warning C4100: 'op' : unreferenced formal parameter",
- '2>------ Build started: Project: product, Configuration: debug Win32 ------',
- ]
- self.assertResult(nbFiles=1, nbErrors=1, nbProjects=2, nbWarnings=6,
- progress={'files': 1, 'projects': 2, 'warnings': 6},
- errors=errors, warnings=warnings)
-
-class VCx(vstudio.VisualStudio):
-
- def start(self):
- command = ["command", "here"]
- self.setCommand(command)
- return vstudio.VisualStudio.start(self)
-
-class VisualStudio(steps.BuildStepMixin, unittest.TestCase):
- """
- Test L{VisualStudio} with a simple subclass, L{VCx}.
- """
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_default_config(self):
- vs = vstudio.VisualStudio()
- self.assertEqual(vs.config, 'release')
-
- def test_simple(self):
- self.setupStep(VCx())
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['command', 'here'])
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_installdir(self):
- self.setupStep(VCx(installdir=r'C:\I'))
- self.step.exp_installdir = r'C:\I'
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['command', 'here'])
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- d = self.runStep()
- def check_installdir(_):
- self.assertEqual(self.step.installdir, r'C:\I')
- d.addCallback(check_installdir)
- return d
-
- def test_evaluateCommand_failure(self):
- self.setupStep(VCx())
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['command', 'here'])
- + 1
- )
- self.expectOutcome(result=FAILURE,
- status_text=["compile", "0 projects", "0 files", "failed"])
- return self.runStep()
-
- def test_evaluateCommand_errors(self):
- self.setupStep(VCx())
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['command', 'here'])
- + ExpectShell.log('stdio',
- stdout='error ABC123: foo\r\n')
- + 0
- )
- self.expectOutcome(result=FAILURE,
- status_text=["compile", "0 projects", "0 files",
- "1 errors", "failed"])
- return self.runStep()
-
- def test_evaluateCommand_warnings(self):
- self.setupStep(VCx())
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['command', 'here'])
- + ExpectShell.log('stdio',
- stdout='foo: warning ABC123: foo\r\n')
- + 0
- )
- self.expectOutcome(result=WARNINGS,
- status_text=["compile", "0 projects", "0 files",
- "1 warnings", "warnings"])
- return self.runStep()
-
- def test_env_setup(self):
- self.setupStep(VCx(
- INCLUDE=[ r'c:\INC1', r'c:\INC2' ],
- LIB=[ r'c:\LIB1', r'C:\LIB2' ],
- PATH=[ r'c:\P1', r'C:\P2' ]))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['command', 'here'],
- env=dict(
- INCLUDE=r'c:\INC1;c:\INC2;',
- LIB=r'c:\LIB1;C:\LIB2;',
- PATH=r'c:\P1;C:\P2;'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_env_setup_existing(self):
- self.setupStep(VCx(
- INCLUDE=[ r'c:\INC1', r'c:\INC2' ],
- LIB=[ r'c:\LIB1', r'C:\LIB2' ],
- PATH=[ r'c:\P1', r'C:\P2' ]))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['command', 'here'],
- env=dict(
- INCLUDE=r'c:\INC1;c:\INC2;',
- LIB=r'c:\LIB1;C:\LIB2;',
- PATH=r'c:\P1;C:\P2;'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_rendering(self):
- self.setupStep(VCx(
- projectfile=Property('a'),
- config=Property('b'),
- project=Property('c')))
- self.properties.setProperty('a', 'aa', 'Test')
- self.properties.setProperty('b', 'bb', 'Test')
- self.properties.setProperty('c', 'cc', 'Test')
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['command', 'here'])
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- d = self.runStep()
- def check_props(_):
- self.assertEqual(
- [ self.step.projectfile, self.step.config, self.step.project ],
- [ 'aa', 'bb', 'cc' ])
- d.addCallback(check_props)
- return d
-
-
-class TestVC6(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def getExpectedEnv(self, installdir, l=None, p=None, i=None):
- include = [
- installdir + r'\VC98\INCLUDE;',
- installdir + r'\VC98\ATL\INCLUDE;',
- installdir + r'\VC98\MFC\INCLUDE;',
- ]
- lib = [
- installdir + r'\VC98\LIB;',
- installdir + r'\VC98\MFC\LIB;',
- ]
- path = [
- installdir + r'\Common\msdev98\BIN;',
- installdir + r'\VC98\BIN;',
- installdir + r'\Common\TOOLS\WINNT;',
- installdir + r'\Common\TOOLS;',
- ]
- if p:
- path.insert(0, '%s;' % p)
- if i:
- include.insert(0, '%s;' % i)
- if l:
- lib.insert(0, '%s;' % l)
- return dict(
- INCLUDE = ''.join(include),
- LIB = ''.join(lib),
- PATH = ''.join(path),
- )
-
- def test_args(self):
- self.setupStep(vstudio.VC6(projectfile='pf', config='cfg',
- project='pj'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['msdev', 'pf', '/MAKE',
- 'pj - cfg', '/REBUILD'],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_clean(self):
- self.setupStep(vstudio.VC6(projectfile='pf', config='cfg',
- project='pj', mode='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['msdev', 'pf', '/MAKE',
- 'pj - cfg', '/CLEAN'],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_noproj_build(self):
- self.setupStep(vstudio.VC6(projectfile='pf', config='cfg',
- mode='build'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['msdev', 'pf', '/MAKE',
- 'ALL - cfg', '/BUILD'],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_env_prepend(self):
- self.setupStep(vstudio.VC6(projectfile='pf', config='cfg',
- project='pj', PATH=['p'], INCLUDE=['i'],
- LIB=['l']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['msdev', 'pf', '/MAKE',
- 'pj - cfg', '/REBUILD',
- '/USEENV'], # note extra param
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio',
- l='l', p='p', i='i'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
-
-class TestVC7(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def getExpectedEnv(self, installdir, l=None, p=None, i=None):
- include = [
- installdir + r'\VC7\INCLUDE;',
- installdir + r'\VC7\ATLMFC\INCLUDE;',
- installdir + r'\VC7\PlatformSDK\include;',
- installdir + r'\SDK\v1.1\include;',
- ]
- lib = [
- installdir + r'\VC7\LIB;',
- installdir + r'\VC7\ATLMFC\LIB;',
- installdir + r'\VC7\PlatformSDK\lib;',
- installdir + r'\SDK\v1.1\lib;',
- ]
- path = [
- installdir + r'\Common7\IDE;',
- installdir + r'\VC7\BIN;',
- installdir + r'\Common7\Tools;',
- installdir + r'\Common7\Tools\bin;',
- ]
- if p:
- path.insert(0, '%s;' % p)
- if i:
- include.insert(0, '%s;' % i)
- if l:
- lib.insert(0, '%s;' % l)
- return dict(
- INCLUDE = ''.join(include),
- LIB = ''.join(lib),
- PATH = ''.join(path),
- )
-
- def test_args(self):
- self.setupStep(vstudio.VC7(projectfile='pf', config='cfg',
- project='pj'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Rebuild', 'cfg',
- '/Project', 'pj'],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio .NET 2003'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_clean(self):
- self.setupStep(vstudio.VC7(projectfile='pf', config='cfg',
- project='pj', mode='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Clean', 'cfg',
- '/Project', 'pj'],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio .NET 2003'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_noproj_build(self):
- self.setupStep(vstudio.VC7(projectfile='pf', config='cfg',
- mode='build'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Build', 'cfg'],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio .NET 2003'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_env_prepend(self):
- self.setupStep(vstudio.VC7(projectfile='pf', config='cfg',
- project='pj', PATH=['p'], INCLUDE=['i'],
- LIB=['l']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Rebuild', 'cfg',
- '/UseEnv', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio .NET 2003',
- l='l', p='p', i='i'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
-
-class VC8ExpectedEnvMixin(object):
- # used for VC8 and VC9Express
- def getExpectedEnv(self, installdir, x64=False, l=None, i=None, p=None):
- include = [
- installdir + r'\VC\INCLUDE;',
- installdir + r'\VC\ATLMFC\include;',
- installdir + r'\VC\PlatformSDK\include;',
- ]
- lib = [
- installdir + r'\VC\LIB;',
- installdir + r'\VC\ATLMFC\LIB;',
- installdir + r'\VC\PlatformSDK\lib;',
- installdir + r'\SDK\v2.0\lib;',
- ]
- path = [
- installdir + r'\Common7\IDE;',
- installdir + r'\VC\BIN;',
- installdir + r'\Common7\Tools;',
- installdir + r'\Common7\Tools\bin;',
- installdir + r'\VC\PlatformSDK\bin;',
- installdir + r'\SDK\v2.0\bin;',
- installdir + r'\VC\VCPackages;',
- r'${PATH};',
- ]
- if x64:
- path.insert(1, installdir + r'\VC\BIN\x86_amd64;')
- lib = [ lb[:-1] + r'\amd64;' for lb in lib ]
- if l:
- lib.insert(0, '%s;' % l)
- if p:
- path.insert(0, '%s;' % p)
- if i:
- include.insert(0, '%s;' % i)
- return dict(
- INCLUDE = ''.join(include),
- LIB = ''.join(lib),
- PATH = ''.join(path),
- )
-
-class TestVC8(VC8ExpectedEnvMixin, steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_args(self):
- self.setupStep(vstudio.VC8(projectfile='pf', config='cfg',
- project='pj', arch='arch'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Rebuild',
- 'cfg', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio 8'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_args_x64(self):
- self.setupStep(vstudio.VC8(projectfile='pf', config='cfg',
- project='pj', arch='x64'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Rebuild',
- 'cfg', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio 8',
- x64=True))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_clean(self):
- self.setupStep(vstudio.VC8(projectfile='pf', config='cfg',
- project='pj', mode='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Clean',
- 'cfg', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio 8'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_rendering(self):
- self.setupStep(vstudio.VC8(projectfile='pf', config='cfg',
- arch=Property('a')))
- self.properties.setProperty('a', 'x64', 'Test')
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Rebuild', 'cfg'],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio 8',
- x64=True)) # property has expected effect
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- d = self.runStep()
- def check_props(_):
- self.assertEqual(self.step.arch, 'x64')
- d.addCallback(check_props)
- return d
-
-
-class TestVCExpress9(VC8ExpectedEnvMixin, steps.BuildStepMixin,
- unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_args(self):
- self.setupStep(vstudio.VCExpress9(projectfile='pf', config='cfg',
- project='pj'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['vcexpress', 'pf', '/Rebuild',
- 'cfg', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- # note: still uses version 8 (?!)
- r'C:\Program Files\Microsoft Visual Studio 8'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_clean(self):
- self.setupStep(vstudio.VCExpress9(projectfile='pf', config='cfg',
- project='pj', mode='clean'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['vcexpress', 'pf', '/Clean',
- 'cfg', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- # note: still uses version 8 (?!)
- r'C:\Program Files\Microsoft Visual Studio 8'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
- def test_mode_build_env(self):
- self.setupStep(vstudio.VCExpress9(projectfile='pf', config='cfg',
- project='pj', mode='build', INCLUDE=['i']))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['vcexpress', 'pf', '/Build',
- 'cfg', '/UseEnv', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio 8',
- i='i'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
-
-class TestVC9(VC8ExpectedEnvMixin, steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_installdir(self):
- self.setupStep(vstudio.VC9(projectfile='pf', config='cfg',
- project='pj'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Rebuild',
- 'cfg', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio 9.0'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
-
-class TestVC10(VC8ExpectedEnvMixin, steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_installdir(self):
- self.setupStep(vstudio.VC10(projectfile='pf', config='cfg',
- project='pj'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Rebuild',
- 'cfg', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio 10.0'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
-
-class TestVC11(VC8ExpectedEnvMixin, steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_installdir(self):
- self.setupStep(vstudio.VC11(projectfile='pf', config='cfg',
- project='pj'))
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['devenv.com', 'pf', '/Rebuild',
- 'cfg', '/Project', 'pj' ],
- env=self.getExpectedEnv(
- r'C:\Program Files\Microsoft Visual Studio 11.0'))
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["compile", "0 projects", "0 files"])
- return self.runStep()
-
-
-class TestMsBuild(steps.BuildStepMixin, unittest.TestCase):
-
- def setUp(self):
- return self.setUpBuildStep()
-
- def tearDown(self):
- return self.tearDownBuildStep()
-
- def test_build_project(self):
- self.setupStep(vstudio.MsBuild(projectfile='pf', config='cfg', platform='Win32', project='pj'))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['%VCENV_BAT%', 'x86', '&&',
- 'msbuild', 'pf', '/p:Configuration=cfg', '/p:Platform=Win32',
- '/t:pj'],
- env={'VCENV_BAT': '"${VS110COMNTOOLS}..\\..\\VC\\vcvarsall.bat"'})
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["built", "pj for", 'cfg|Win32'])
- return self.runStep()
-
- def test_build_solution(self):
- self.setupStep(vstudio.MsBuild(projectfile='pf', config='cfg', platform='x64'))
-
- self.expectCommands(
- ExpectShell(workdir='wkdir', usePTY='slave-config',
- command=['%VCENV_BAT%', 'x86', '&&',
- 'msbuild', 'pf', '/p:Configuration=cfg', '/p:Platform=x64'],
- env={'VCENV_BAT': '"${VS110COMNTOOLS}..\\..\\VC\\vcvarsall.bat"'})
- + 0
- )
- self.expectOutcome(result=SUCCESS,
- status_text=["built", "solution for", 'cfg|x64'])
- return self.runStep()
-
-
-class Aliases(unittest.TestCase):
-
- def test_vs2003(self):
- self.assertIdentical(vstudio.VS2003, vstudio.VC7)
-
- def test_vs2005(self):
- self.assertIdentical(vstudio.VS2005, vstudio.VC8)
-
- def test_vs2008(self):
- self.assertIdentical(vstudio.VS2008, vstudio.VC9)
-
- def test_vs2010(self):
- self.assertIdentical(vstudio.VS2010, vstudio.VC10)
-
- def test_vs2012(self):
- self.assertIdentical(vstudio.VS2012, vstudio.VC11)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_test_util_gpo.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_test_util_gpo.py
deleted file mode 100644
index 3b6a90f9..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_test_util_gpo.py
+++ /dev/null
@@ -1,323 +0,0 @@
-# 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 sys
-import twisted
-from twisted.trial import reporter, unittest
-from twisted.internet import utils
-from buildbot.test.util.gpo import GetProcessOutputMixin, Expect
-
-class TestGPOMixin(unittest.TestCase):
-
- # these tests use self.patch, but the SkipTest exception gets eaten, so
- # explicitly skip things here.
- if twisted.version.major <= 9 and sys.version_info[:2] == (2,7):
- skip = "unittest.TestCase.patch is not available"
-
- def runTestMethod(self, method):
- class TestCase(GetProcessOutputMixin, unittest.TestCase):
- def setUp(self):
- self.setUpGetProcessOutput()
- def runTest(self):
- return method(self)
- self.testcase = TestCase()
- result = reporter.TestResult()
- self.testcase.run(result) # This blocks
- return result
-
- def assertTestFailure(self, result, expectedFailure):
- self.assertEqual(result.errors, [])
- self.assertEqual(len(result.failures), 1)
- self.failUnless(result.failures[0][1].check(unittest.FailTest))
- if expectedFailure:
- self.assertSubstring(expectedFailure, result.failures[0][1].getErrorMessage())
-
- def assertSuccessful(self, result):
- if not result.wasSuccessful():
- output = 'expected success'
- if result.failures:
- output += ('\ntest failed: %s' %
- result.failures[0][1].getErrorMessage())
- if result.errors:
- output += ('\nerrors: %s' %
- map(lambda x: x[1].value, result.errors))
- raise self.failureException(output)
-
- self.failUnless(result.wasSuccessful())
-
- def test_patch(self):
- original_getProcessOutput = utils.getProcessOutput
- original_getProcessOutputAndValue = utils.getProcessOutputAndValue
- def method(testcase):
- testcase.expectCommands()
- self.assertEqual(utils.getProcessOutput,
- testcase.patched_getProcessOutput)
- self.assertEqual(utils.getProcessOutputAndValue,
- testcase.patched_getProcessOutputAndValue)
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
- self.assertEqual(utils.getProcessOutput,
- original_getProcessOutput)
- self.assertEqual(utils.getProcessOutputAndValue,
- original_getProcessOutputAndValue)
-
- def test_methodChaining(self):
- expect = Expect('command')
- self.assertEqual(expect, expect.exit(0))
- self.assertEqual(expect, expect.stdout("output"))
- self.assertEqual(expect, expect.stderr("error"))
-
- def test_gpo_oneCommand(self):
- def method(testcase):
- testcase.expectCommands(Expect("command"))
- d = utils.getProcessOutput("command", ())
- d.addCallback(self.assertEqual, '')
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpo_expectTwo_runOne(self):
- def method(testcase):
- testcase.expectCommands(Expect("command"))
- testcase.expectCommands(Expect("command2"))
- d = utils.getProcessOutput("command", ())
- d.addCallback(self.assertEqual, '')
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "assert all expected commands were run")
-
- def test_gpo_wrongCommand(self):
- def method(testcase):
- testcase.expectCommands(Expect("command2"))
- d = utils.getProcessOutput("command", ())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpo_wrongArgs(self):
- def method(testcase):
- testcase.expectCommands(Expect("command", "arg"))
- d = utils.getProcessOutput("command", ("otherarg",))
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpo_missingPath(self):
- def method(testcase):
- testcase.expectCommands(Expect("command", "arg").path("/home"))
- d = utils.getProcessOutput("command", ("otherarg",))
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpo_wrongPath(self):
- def method(testcase):
- testcase.expectCommands(Expect("command", "arg").path("/home"))
- d = utils.getProcessOutput("command", ("otherarg",), path="/work")
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpo_notCurrentPath(self):
- def method(testcase):
- testcase.expectCommands(Expect("command", "arg"))
- d = utils.getProcessOutput("command", ("otherarg",), path="/work")
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpo_errorOutput(self):
- def method(testcase):
- testcase.expectCommands(Expect("command").stderr("some test"))
- d = testcase.assertFailure(utils.getProcessOutput("command", ()), [IOError])
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "got stderr: 'some test'")
-
- def test_gpo_errorOutput_errtoo(self):
- def method(testcase):
- testcase.expectCommands(Expect("command").stderr("some test"))
- d = utils.getProcessOutput("command", (), errortoo=True)
- d.addCallback(testcase.assertEqual, "some test")
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpo_exitIgnored(self):
- def method(testcase):
- testcase.expectCommands(Expect("command").exit(1))
- d = utils.getProcessOutput("command", ())
- d.addCallback(self.assertEqual, '')
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpo_output(self):
- def method(testcase):
- testcase.expectCommands(Expect("command").stdout("stdout"))
- d = utils.getProcessOutput("command", ())
- d.addCallback(testcase.assertEqual, "stdout")
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpo_outputAndError(self):
- def method(testcase):
- testcase.expectCommands(Expect("command").stdout("stdout").stderr("stderr"))
- d = utils.getProcessOutput("command", (), errortoo=True)
- @d.addCallback
- def cb(res):
- testcase.assertSubstring("stdout", res)
- testcase.assertSubstring("stderr", res)
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpo_environ_success(self):
- def method(testcase):
- testcase.expectCommands(Expect("command"))
- testcase.addGetProcessOutputExpectEnv({'key': 'value'})
- d = utils.getProcessOutput("command", (), env={'key': 'value'})
- d.addCallback(self.assertEqual, '')
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpo_environ_wrongValue(self):
- def method(testcase):
- testcase.expectCommands(Expect("command"))
- testcase.addGetProcessOutputExpectEnv({'key': 'value'})
- d = utils.getProcessOutput("command", (), env={'key': 'wrongvalue'})
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "Expected environment to have key = 'value'")
-
- def test_gpo_environ_missing(self):
- def method(testcase):
- testcase.expectCommands(Expect("command"))
- testcase.addGetProcessOutputExpectEnv({'key': 'value'})
- d = utils.getProcessOutput("command", ())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "Expected environment to have key = 'value'")
-
- def test_gpoav_oneCommand(self):
- def method(testcase):
- testcase.expectCommands(Expect("command"))
- d = utils.getProcessOutputAndValue("command", ())
- d.addCallback(self.assertEqual, ('','',0))
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpoav_expectTwo_runOne(self):
- def method(testcase):
- testcase.expectCommands(Expect("command"))
- testcase.expectCommands(Expect("command2"))
- d = utils.getProcessOutputAndValue("command", ())
- d.addCallback(self.assertEqual, ('','',0))
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "assert all expected commands were run")
-
- def test_gpoav_wrongCommand(self):
- def method(testcase):
- testcase.expectCommands(Expect("command2"))
- d = utils.getProcessOutputAndValue("command", ())
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpoav_wrongArgs(self):
- def method(testcase):
- testcase.expectCommands(Expect("command", "arg"))
- d = utils.getProcessOutputAndValue("command", ("otherarg",))
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpoav_missingPath(self):
- def method(testcase):
- testcase.expectCommands(Expect("command", "arg").path("/home"))
- d = utils.getProcessOutputAndValue("command", ("otherarg",))
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpoav_wrongPath(self):
- def method(testcase):
- testcase.expectCommands(Expect("command", "arg").path("/home"))
- d = utils.getProcessOutputAndValue("command", ("otherarg",), path="/work")
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpoav_notCurrentPath(self):
- def method(testcase):
- testcase.expectCommands(Expect("command", "arg"))
- d = utils.getProcessOutputAndValue("command", ("otherarg",), path="/work")
- d.addCallback(lambda _: testcase.assertAllCommandsRan())
- return d
- result = self.runTestMethod(method)
- self.assertTestFailure(result, "unexpected command run")
-
- def test_gpoav_errorOutput(self):
- def method(testcase):
- testcase.expectCommands(Expect("command").stderr("some test"))
- d = utils.getProcessOutputAndValue("command", ())
- d.addCallback(self.assertEqual, ('','some test',0))
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpoav_exit(self):
- def method(testcase):
- testcase.expectCommands(Expect("command").exit(1))
- d = utils.getProcessOutputAndValue("command", ())
- d.addCallback(self.assertEqual, ('','',1))
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpoav_output(self):
- def method(testcase):
- testcase.expectCommands(Expect("command").stdout("stdout"))
- d = utils.getProcessOutputAndValue("command", ())
- d.addCallback(testcase.assertEqual, ("stdout",'',0))
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
-
- def test_gpoav_outputAndError(self):
- def method(testcase):
- testcase.expectCommands(Expect("command").stdout("stdout").stderr("stderr"))
- d = utils.getProcessOutputAndValue("command", ())
- d.addCallback(testcase.assertEqual, ("stdout",'stderr',0))
- return d
- result = self.runTestMethod(method)
- self.assertSuccessful(result)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util.py
deleted file mode 100644
index 8411e92c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util.py
+++ /dev/null
@@ -1,194 +0,0 @@
-# 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 datetime
-
-from twisted.trial import unittest
-
-from buildbot import util
-
-class formatInterval(unittest.TestCase):
-
- def test_zero(self):
- self.assertEqual(util.formatInterval(0), "0 secs")
-
- def test_seconds_singular(self):
- self.assertEqual(util.formatInterval(1), "1 secs")
-
- def test_seconds(self):
- self.assertEqual(util.formatInterval(7), "7 secs")
-
- def test_minutes_one(self):
- self.assertEqual(util.formatInterval(60), "60 secs")
-
- def test_minutes_over_one(self):
- self.assertEqual(util.formatInterval(61), "1 mins, 1 secs")
-
- def test_minutes(self):
- self.assertEqual(util.formatInterval(300), "5 mins, 0 secs")
-
- def test_hours_one(self):
- self.assertEqual(util.formatInterval(3600), "60 mins, 0 secs")
-
- def test_hours_over_one_sec(self):
- self.assertEqual(util.formatInterval(3601), "1 hrs, 1 secs")
-
- def test_hours_over_one_min(self):
- self.assertEqual(util.formatInterval(3660), "1 hrs, 60 secs")
-
- def test_hours(self):
- self.assertEqual(util.formatInterval(7200), "2 hrs, 0 secs")
-
- def test_mixed(self):
- self.assertEqual(util.formatInterval(7392), "2 hrs, 3 mins, 12 secs")
-
-class safeTranslate(unittest.TestCase):
-
- def test_str_good(self):
- self.assertEqual(util.safeTranslate(str("full")), str("full"))
-
- def test_str_bad(self):
- self.assertEqual(util.safeTranslate(str("speed=slow;quality=high")),
- str("speed_slow_quality_high"))
-
- def test_str_pathological(self):
- # if you needed proof this wasn't for use with sensitive data
- self.assertEqual(util.safeTranslate(str("p\ath\x01ogy")),
- str("p\ath\x01ogy")) # bad chars still here!
-
- def test_unicode_good(self):
- self.assertEqual(util.safeTranslate(u"full"), str("full"))
-
- def test_unicode_bad(self):
- self.assertEqual(util.safeTranslate(unicode("speed=slow;quality=high")),
- str("speed_slow_quality_high"))
-
- def test_unicode_pathological(self):
- self.assertEqual(util.safeTranslate(u"\u0109"),
- str("\xc4\x89")) # yuck!
-
-class naturalSort(unittest.TestCase):
-
- def test_alpha(self):
- self.assertEqual(
- util.naturalSort(['x', 'aa', 'ab']),
- ['aa', 'ab', 'x'])
-
- def test_numeric(self):
- self.assertEqual(
- util.naturalSort(['1', '10', '11', '2', '20']),
- ['1', '2', '10', '11', '20'])
-
- def test_alphanum(self):
- l1 = 'aa10ab aa1ab aa10aa f a aa3 aa30 aa3a aa30a'.split()
- l2 = 'a aa1ab aa3 aa3a aa10aa aa10ab aa30 aa30a f'.split()
- self.assertEqual(util.naturalSort(l1), l2)
-
-class none_or_str(unittest.TestCase):
-
- def test_none(self):
- self.assertEqual(util.none_or_str(None), None)
-
- def test_str(self):
- self.assertEqual(util.none_or_str("hi"), "hi")
-
- def test_int(self):
- self.assertEqual(util.none_or_str(199), "199")
-
-class TimeFunctions(unittest.TestCase):
-
- def test_UTC(self):
- self.assertEqual(util.UTC.utcoffset(datetime.datetime.now()),
- datetime.timedelta(0))
- self.assertEqual(util.UTC.dst(datetime.datetime.now()),
- datetime.timedelta(0))
- self.assertEqual(util.UTC.tzname(), "UTC")
-
- def test_epoch2datetime(self):
- self.assertEqual(util.epoch2datetime(0),
- datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=util.UTC))
- self.assertEqual(util.epoch2datetime(1300000000),
- datetime.datetime(2011, 3, 13, 7, 6, 40, tzinfo=util.UTC))
-
- def test_datetime2epoch(self):
- dt = datetime.datetime(1970, 1, 1, 0, 0, 0, tzinfo=util.UTC)
- self.assertEqual(util.datetime2epoch(dt), 0)
- dt = datetime.datetime(2011, 3, 13, 7, 6, 40, tzinfo=util.UTC)
- self.assertEqual(util.datetime2epoch(dt), 1300000000)
-
-class DiffSets(unittest.TestCase):
-
- def test_empty(self):
- removed, added = util.diffSets(set([]), set([]))
- self.assertEqual((removed, added), (set([]), set([])))
-
- def test_no_lists(self):
- removed, added = util.diffSets([1, 2], [2, 3])
- self.assertEqual((removed, added), (set([1]), set([3])))
-
- def test_no_overlap(self):
- removed, added = util.diffSets(set([1, 2]), set([3, 4]))
- self.assertEqual((removed, added), (set([1, 2]), set([3, 4])))
-
- def test_no_change(self):
- removed, added = util.diffSets(set([1, 2]), set([1, 2]))
- self.assertEqual((removed, added), (set([]), set([])))
-
- def test_added(self):
- removed, added = util.diffSets(set([1, 2]), set([1, 2, 3]))
- self.assertEqual((removed, added), (set([]), set([3])))
-
- def test_removed(self):
- removed, added = util.diffSets(set([1, 2]), set([1]))
- self.assertEqual((removed, added), (set([2]), set([])))
-
-class MakeList(unittest.TestCase):
-
- def test_empty_string(self):
- self.assertEqual(util.makeList(''), [ '' ])
-
- def test_None(self):
- self.assertEqual(util.makeList(None), [ ])
-
- def test_string(self):
- self.assertEqual(util.makeList('hello'), [ 'hello' ])
-
- def test_unicode(self):
- self.assertEqual(util.makeList(u'\N{SNOWMAN}'), [ u'\N{SNOWMAN}' ])
-
- def test_list(self):
- self.assertEqual(util.makeList(['a','b']), [ 'a', 'b' ])
-
- def test_tuple(self):
- self.assertEqual(util.makeList(('a','b')), [ 'a', 'b' ])
-
- def test_copy(self):
- input = ['a', 'b']
- output = util.makeList(input)
- input.append('c')
- self.assertEqual(output, [ 'a', 'b' ])
-
-class Flatten(unittest.TestCase):
-
- def test_simple(self):
- self.assertEqual(util.flatten([1, 2, 3]), [1, 2, 3])
-
- def test_deep(self):
- self.assertEqual(util.flatten([ [ 1, 2 ], 3, [ [ 4 ] ] ]),
- [1, 2, 3, 4])
-
- def test_tuples(self):
- self.assertEqual(util.flatten([ ( 1, 2 ), 3 ]), [ (1, 2), 3 ])
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_ComparableMixin.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_ComparableMixin.py
deleted file mode 100644
index a7c34de0..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_ComparableMixin.py
+++ /dev/null
@@ -1,72 +0,0 @@
-# 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
-
-
-from twisted.trial import unittest
-
-from buildbot import util
-
-
-class ComparableMixin(unittest.TestCase):
- class Foo(util.ComparableMixin):
- compare_attrs = ["a", "b"]
- def __init__(self, a, b, c):
- self.a, self.b, self.c = a,b,c
-
- class Bar(Foo, util.ComparableMixin):
- compare_attrs = ["b", "c"]
-
- def setUp(self):
- self.f123 = self.Foo(1, 2, 3)
- self.f124 = self.Foo(1, 2, 4)
- self.f134 = self.Foo(1, 3, 4)
- self.b123 = self.Bar(1, 2, 3)
- self.b223 = self.Bar(2, 2, 3)
- self.b213 = self.Bar(2, 1, 3)
-
- def test_equality_identity(self):
- self.assertEqual(self.f123, self.f123)
-
- def test_equality_same(self):
- another_f123 = self.Foo(1, 2, 3)
- self.assertEqual(self.f123, another_f123)
-
- def test_equality_unimportantDifferences(self):
- self.assertEqual(self.f123, self.f124)
-
- def test_equality_unimportantDifferences_subclass(self):
- # verify that the parent class's compare_attrs doesn't
- # affect the subclass
- self.assertEqual(self.b123, self.b223)
-
- def test_inequality_importantDifferences(self):
- self.assertNotEqual(self.f123, self.f134)
-
- def test_inequality_importantDifferences_subclass(self):
- self.assertNotEqual(self.b123, self.b213)
-
- def test_inequality_differentClasses(self):
- self.assertNotEqual(self.f123, self.b123)
-
- def test_inequality_sameClass_differentCompareAttrs(self):
- another_f123 = self.Foo(1, 2, 3)
- another_f123.compare_attrs = ["b", "a"]
- self.assertNotEqual(self.f123, another_f123)
-
- def test_lt_importantDifferences(self):
- assert self.f123 < self.f134
-
- def test_lt_differentClasses(self):
- assert self.b123 < self.f123
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_bbcollections.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_bbcollections.py
deleted file mode 100644
index de3ede52..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_bbcollections.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.util import bbcollections
-
-class KeyedSets(unittest.TestCase):
-
- def setUp(self):
- self.ks = bbcollections.KeyedSets()
-
- def test_getitem_default(self):
- self.assertEqual(self.ks['x'], set())
- # remaining tests effectively cover __getitem__
-
- def test_add(self):
- self.ks.add('y', 2)
- self.assertEqual(self.ks['y'], set([2]))
-
- def test_add_twice(self):
- self.ks.add('z', 2)
- self.ks.add('z', 4)
- self.assertEqual(self.ks['z'], set([2, 4]))
-
- def test_discard_noError(self):
- self.ks.add('full', 12)
- self.ks.discard('empty', 13) # should not fail
- self.ks.discard('full', 13) # nor this
- self.assertEqual(self.ks['full'], set([12]))
-
- def test_discard_existing(self):
- self.ks.add('yarn', 'red')
- self.ks.discard('yarn', 'red')
- self.assertEqual(self.ks['yarn'], set([]))
-
- def test_contains_true(self):
- self.ks.add('yarn', 'red')
- self.assertTrue('yarn' in self.ks)
-
- def test_contains_false(self):
- self.assertFalse('yarn' in self.ks)
-
- def test_contains_setNamesNotContents(self):
- self.ks.add('yarn', 'red')
- self.assertFalse('red' in self.ks)
-
- def test_pop_exists(self):
- self.ks.add('names', 'pop')
- self.ks.add('names', 'coke')
- self.ks.add('names', 'soda')
- popped = self.ks.pop('names')
- remaining = self.ks['names']
- self.assertEqual((popped, remaining),
- (set(['pop', 'coke', 'soda']), set()))
-
- def test_pop_missing(self):
- self.assertEqual(self.ks.pop('flavors'), set())
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_eventual.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_eventual.py
deleted file mode 100644
index fa37ec29..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_eventual.py
+++ /dev/null
@@ -1,108 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from twisted.internet import defer
-from twisted.python import log
-
-from buildbot.util import eventual
-
-class Eventually(unittest.TestCase):
-
- def setUp(self):
- # reset the queue to its base state
- eventual._theSimpleQueue = eventual._SimpleCallQueue()
- self.old_log_err = log.err
- self.results = []
-
- def tearDown(self):
- log.err = self.old_log_err
- return eventual.flushEventualQueue()
-
- # utility callback
- def cb(self, *args, **kwargs):
- r = args
- if kwargs: r = r + (kwargs,)
- self.results.append(r)
-
- # flush the queue and assert results
- def assertResults(self, exp):
- d = eventual.flushEventualQueue()
- def cb(_):
- self.assertEqual(self.results, exp)
- d.addCallback(cb)
- return d
-
- ## tests
-
- def test_eventually_calls(self):
- eventual.eventually(self.cb)
- return self.assertResults([()])
-
- def test_eventually_args(self):
- eventual.eventually(self.cb, 1, 2, a='a')
- return self.assertResults([(1, 2, dict(a='a'))])
-
- def test_eventually_err(self):
- # monkey-patch log.err; this is restored by tearDown
- log.err = lambda : self.results.append("err")
- def cb_fails():
- raise RuntimeError("should not cause test failure")
- eventual.eventually(cb_fails)
- return self.assertResults(['err'])
-
- def test_eventually_butNotNow(self):
- eventual.eventually(self.cb, 1)
- self.failIf(self.results != [])
- return self.assertResults([(1,)])
-
- def test_eventually_order(self):
- eventual.eventually(self.cb, 1)
- eventual.eventually(self.cb, 2)
- eventual.eventually(self.cb, 3)
- return self.assertResults([(1,), (2,), (3,)])
-
- def test_flush_waitForChainedEventuallies(self):
- def chain(n):
- self.results.append(n)
- if n <= 0: return
- eventual.eventually(chain, n-1)
- chain(3)
- # (the flush this tests is implicit in assertResults)
- return self.assertResults([3, 2, 1, 0])
-
- def test_flush_waitForTreeEventuallies(self):
- # a more complex set of eventualities
- def tree(n):
- self.results.append(n)
- if n <= 0: return
- eventual.eventually(tree, n-1)
- eventual.eventually(tree, n-1)
- tree(2)
- # (the flush this tests is implicit in assertResults)
- return self.assertResults([2, 1, 1, 0, 0, 0, 0])
-
- def test_flush_duringTurn(self):
- testd = defer.Deferred()
- def cb():
- d = eventual.flushEventualQueue()
- d.addCallback(testd.callback)
- eventual.eventually(cb)
- return testd
-
- def test_fireEventually_call(self):
- d = eventual.fireEventually(13)
- d.addCallback(self.cb)
- return self.assertResults([(13,)])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_lru.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_lru.py
deleted file mode 100644
index d67e90d8..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_lru.py
+++ /dev/null
@@ -1,576 +0,0 @@
-# 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 string
-import random
-import gc
-from twisted.trial import unittest
-from twisted.internet import defer, reactor
-from twisted.python import failure
-from buildbot.util import lru
-
-# construct weakref-able objects for particular keys
-def short(k):
- return set([k.upper() * 3])
-def long(k):
- return set([k.upper() * 6])
-
-class LRUCacheTest(unittest.TestCase):
-
- def setUp(self):
- lru.inv_failed = False
- self.lru = lru.LRUCache(short, 3)
-
- def tearDown(self):
- self.assertFalse(lru.inv_failed, "invariant failed; see logs")
-
- def check_result(self, r, exp, exp_hits=None, exp_misses=None,
- exp_refhits=None):
- self.assertEqual(r, exp)
- if exp_hits is not None:
- self.assertEqual(self.lru.hits, exp_hits)
- if exp_misses is not None:
- self.assertEqual(self.lru.misses, exp_misses)
- if exp_refhits is not None:
- self.assertEqual(self.lru.refhits, exp_refhits)
-
- def test_single_key(self):
- # just get an item
- val = self.lru.get('a')
- self.check_result(val, short('a'), 0, 1)
-
- # second time, it should be cached..
- self.lru.miss_fn = long
- val = self.lru.get('a')
- self.check_result(val, short('a'), 1, 1)
-
- def test_simple_lru_expulsion(self):
- val = self.lru.get('a')
- self.check_result(val, short('a'), 0, 1)
- val = self.lru.get('b')
- self.check_result(val, short('b'), 0, 2)
- val = self.lru.get('c')
- self.check_result(val, short('c'), 0, 3)
- val = self.lru.get('d')
- self.check_result(val, short('d'), 0, 4)
- del(val)
- gc.collect()
-
- # now try 'a' again - it should be a miss
- self.lru.miss_fn = long
- val = self.lru.get('a')
- self.check_result(val, long('a'), 0, 5)
-
- # ..and that expelled B, but C is still in the cache
- val = self.lru.get('c')
- self.check_result(val, short('c'), 1, 5)
-
- def test_simple_lru_expulsion_maxsize_1(self):
- self.lru = lru.LRUCache(short, 1)
- val = self.lru.get('a')
- self.check_result(val, short('a'), 0, 1)
- val = self.lru.get('a')
- self.check_result(val, short('a'), 1, 1)
- val = self.lru.get('b')
- self.check_result(val, short('b'), 1, 2)
- del(val)
- gc.collect()
-
- # now try 'a' again - it should be a miss
- self.lru.miss_fn = long
- val = self.lru.get('a')
- self.check_result(val, long('a'), 1, 3)
- del(val)
- gc.collect()
-
- # ..and that expelled B
- val = self.lru.get('b')
- self.check_result(val, long('b'), 1, 4)
-
- def test_simple_lru_expulsion_maxsize_1_null_result(self):
- # a regression test for #2011
- def miss_fn(k):
- if k == 'b':
- return None
- else:
- return short(k)
- self.lru = lru.LRUCache(miss_fn, 1)
- val = self.lru.get('a')
- self.check_result(val, short('a'), 0, 1)
- val = self.lru.get('b')
- self.check_result(val, None, 0, 2)
- del(val)
-
- # 'a' was not expelled since 'b' was None
- self.lru.miss_fn = long
- val = self.lru.get('a')
- self.check_result(val, short('a'), 1, 2)
-
- def test_queue_collapsing(self):
- # just to check that we're practicing with the right queue size (so
- # QUEUE_SIZE_FACTOR is 10)
- self.assertEqual(self.lru.max_queue, 30)
-
- for c in 'a' + 'x' * 27 + 'ab':
- res = self.lru.get(c)
- self.check_result(res, short('b'), 27, 3)
-
- # at this point, we should have 'x', 'a', and 'b' in the cache, and
- # 'axx..xxab' in the queue.
- self.assertEqual(len(self.lru.queue), 30)
-
- # This 'get' operation for an existing key should cause compaction
- res = self.lru.get('b')
- self.check_result(res, short('b'), 28, 3)
-
- self.assertEqual(len(self.lru.queue), 3)
-
- # expect a cached short('a')
- self.lru.miss_fn = long
- res = self.lru.get('a')
- self.check_result(res, short('a'), 29, 3)
-
- def test_all_misses(self):
- for i, c in enumerate(string.lowercase + string.uppercase):
- res = self.lru.get(c)
- self.check_result(res, short(c), 0, i+1)
-
- def test_get_exception(self):
- def fail_miss_fn(k):
- raise RuntimeError("oh noes")
- self.lru.miss_fn = fail_miss_fn
-
- got_exc = False
- try:
- self.lru.get('abc')
- except RuntimeError:
- got_exc = True
-
- self.assertEqual(got_exc, True)
-
- def test_all_hits(self):
- res = self.lru.get('a')
- self.check_result(res, short('a'), 0, 1)
-
- self.lru.miss_fn = long
- for i in xrange(100):
- res = self.lru.get('a')
- self.check_result(res, short('a'), i+1, 1)
-
- def test_weakrefs(self):
- res_a = self.lru.get('a')
- self.check_result(res_a, short('a'))
- # note that res_a keeps a reference to this value
-
- res_b = self.lru.get('b')
- self.check_result(res_b, short('b'))
- del res_b # discard reference to b
-
- # blow out the cache and the queue
- self.lru.miss_fn = long
- for c in (string.lowercase[2:] * 5):
- self.lru.get(c)
-
- # and fetch a again, expecting the cached value
- res = self.lru.get('a')
- self.check_result(res, res_a, exp_refhits=1)
-
- # but 'b' should give us a new value
- res = self.lru.get('b')
- self.check_result(res, long('b'), exp_refhits=1)
-
- def test_fuzz(self):
- chars = list(string.lowercase * 40)
- random.shuffle(chars)
- for i, c in enumerate(chars):
- res = self.lru.get(c)
- self.check_result(res, short(c))
-
- def test_set_max_size(self):
- # load up the cache with three items
- for c in 'abc':
- res = self.lru.get(c)
- self.check_result(res, short(c))
- del(res)
-
- # reset the size to 1
- self.lru.set_max_size(1)
- gc.collect()
-
- # and then expect that 'b' is no longer in the cache
- self.lru.miss_fn = long
- res = self.lru.get('b')
- self.check_result(res, long('b'))
-
- def test_miss_fn_kwargs(self):
- def keep_kwargs_miss_fn(k, **kwargs):
- return set(kwargs.keys())
- self.lru.miss_fn = keep_kwargs_miss_fn
-
- val = self.lru.get('a', a=1, b=2)
- self.check_result(val, set(['a', 'b']), 0, 1)
-
- def test_miss_fn_returns_none(self):
- calls = []
- def none_miss_fn(k):
- calls.append(k)
- return None
- self.lru.miss_fn = none_miss_fn
-
- for i in range(2):
- self.assertEqual(self.lru.get('a'), None)
-
- # check that the miss_fn was called twice
- self.assertEqual(calls, ['a', 'a'])
-
- def test_put(self):
- self.assertEqual(self.lru.get('p'), short('p'))
- self.lru.put('p', set(['P2P2']))
- self.assertEqual(self.lru.get('p'), set(['P2P2']))
-
- def test_put_nonexistent_key(self):
- self.assertEqual(self.lru.get('p'), short('p'))
- self.lru.put('q', set(['new-q']))
- self.assertEqual(self.lru.get('p'), set(['PPP']))
- self.assertEqual(self.lru.get('q'), set(['QQQ'])) # not updated
-
-
-class AsyncLRUCacheTest(unittest.TestCase):
-
- def setUp(self):
- lru.inv_failed = False
- self.lru = lru.AsyncLRUCache(self.short_miss_fn, 3)
-
- def tearDown(self):
- self.assertFalse(lru.inv_failed, "invariant failed; see logs")
-
- def short_miss_fn(self, key):
- return defer.succeed(short(key))
-
- def long_miss_fn(self, key):
- return defer.succeed(long(key))
-
- def failure_miss_fn(self, key):
- return defer.succeed(None)
-
- def check_result(self, r, exp, exp_hits=None, exp_misses=None,
- exp_refhits=None):
- self.assertEqual(r, exp)
- if exp_hits is not None:
- self.assertEqual(self.lru.hits, exp_hits)
- if exp_misses is not None:
- self.assertEqual(self.lru.misses, exp_misses)
- if exp_refhits is not None:
- self.assertEqual(self.lru.refhits, exp_refhits)
-
- # tests
-
- def test_single_key(self):
- # just get an item
- d = self.lru.get('a')
- d.addCallback(self.check_result, short('a'), 0, 1)
-
- # second time, it should be cached..
- self.lru.miss_fn = self.long_miss_fn
- d.addCallback(lambda _ :
- self.lru.get('a'))
- d.addCallback(self.check_result, short('a'), 1, 1)
- return d
-
- def test_simple_lru_expulsion(self):
- d = defer.succeed(None)
-
- d.addCallback(lambda _ :
- self.lru.get('a'))
- d.addCallback(self.check_result, short('a'), 0, 1)
- d.addCallback(lambda _ :
- self.lru.get('b'))
- d.addCallback(self.check_result, short('b'), 0, 2)
- d.addCallback(lambda _ :
- self.lru.get('c'))
- d.addCallback(self.check_result, short('c'), 0, 3)
- d.addCallback(lambda _ :
- self.lru.get('d'))
- d.addCallback(self.check_result, short('d'), 0, 4)
-
- gc.collect()
-
- # now try 'a' again - it should be a miss
- self.lru.miss_fn = self.long_miss_fn
- d.addCallback(lambda _ :
- self.lru.get('a'))
- d.addCallback(self.check_result, long('a'), 0, 5)
-
- # ..and that expelled B, but C is still in the cache
- d.addCallback(lambda _ :
- self.lru.get('c'))
- d.addCallback(self.check_result, short('c'), 1, 5)
- return d
-
- def test_simple_lru_expulsion_maxsize_1(self):
- self.lru = lru.AsyncLRUCache(self.short_miss_fn, 1)
- d = defer.succeed(None)
-
- d.addCallback(lambda _ :
- self.lru.get('a'))
- d.addCallback(self.check_result, short('a'), 0, 1)
- d.addCallback(lambda _ :
- self.lru.get('a'))
- d.addCallback(self.check_result, short('a'), 1, 1)
- d.addCallback(lambda _ :
- self.lru.get('b'))
- d.addCallback(self.check_result, short('b'), 1, 2)
-
- gc.collect()
-
- # now try 'a' again - it should be a miss
- self.lru.miss_fn = self.long_miss_fn
- d.addCallback(lambda _ :
- self.lru.get('a'))
- d.addCallback(self.check_result, long('a'), 1, 3)
-
- gc.collect()
-
- # ..and that expelled B
- d.addCallback(lambda _ :
- self.lru.get('b'))
- d.addCallback(self.check_result, long('b'), 1, 4)
- return d
-
- def test_simple_lru_expulsion_maxsize_1_null_result(self):
- # a regression test for #2011
- def miss_fn(k):
- if k == 'b':
- return defer.succeed(None)
- else:
- return defer.succeed(short(k))
- self.lru = lru.AsyncLRUCache(miss_fn, 1)
- d = defer.succeed(None)
-
- d.addCallback(lambda _ :
- self.lru.get('a'))
- d.addCallback(self.check_result, short('a'), 0, 1)
- d.addCallback(lambda _ :
- self.lru.get('b'))
- d.addCallback(self.check_result, None, 0, 2)
-
- # 'a' was not expelled since 'b' was None
- self.lru.miss_fn = self.long_miss_fn
- d.addCallback(lambda _ :
- self.lru.get('a'))
- d.addCallback(self.check_result, short('a'), 1, 2)
-
- return d
-
- @defer.inlineCallbacks
- def test_queue_collapsing(self):
- # just to check that we're practicing with the right queue size (so
- # QUEUE_SIZE_FACTOR is 10)
- self.assertEqual(self.lru.max_queue, 30)
-
- for c in 'a' + 'x' * 27 + 'ab':
- res = yield self.lru.get(c)
- self.check_result(res, short('b'), 27, 3)
-
- # at this point, we should have 'x', 'a', and 'b' in the cache, and
- # 'axx..xxab' in the queue.
- self.assertEqual(len(self.lru.queue), 30)
-
- # This 'get' operation for an existing key should cause compaction
- res = yield self.lru.get('b')
- self.check_result(res, short('b'), 28, 3)
-
- self.assertEqual(len(self.lru.queue), 3)
-
- # expect a cached short('a')
- self.lru.miss_fn = self.long_miss_fn
- res = yield self.lru.get('a')
- self.check_result(res, short('a'), 29, 3)
-
- @defer.inlineCallbacks
- def test_all_misses(self):
- for i, c in enumerate(string.lowercase + string.uppercase):
- res = yield self.lru.get(c)
- self.check_result(res, short(c), 0, i+1)
-
- @defer.inlineCallbacks
- def test_get_exception(self):
- def fail_miss_fn(k):
- return defer.fail(RuntimeError("oh noes"))
- self.lru.miss_fn = fail_miss_fn
-
- got_exc = False
- try:
- yield self.lru.get('abc')
- except RuntimeError:
- got_exc = True
-
- self.assertEqual(got_exc, True)
-
- @defer.inlineCallbacks
- def test_all_hits(self):
- res = yield self.lru.get('a')
- self.check_result(res, short('a'), 0, 1)
-
- self.lru.miss_fn = self.long_miss_fn
- for i in xrange(100):
- res = yield self.lru.get('a')
- self.check_result(res, short('a'), i+1, 1)
-
- @defer.inlineCallbacks
- def test_weakrefs(self):
- res_a = yield self.lru.get('a')
- self.check_result(res_a, short('a'))
- # note that res_a keeps a reference to this value
-
- res_b = yield self.lru.get('b')
- self.check_result(res_b, short('b'))
- del res_b # discard reference to b
-
- # blow out the cache and the queue
- self.lru.miss_fn = self.long_miss_fn
- for c in (string.lowercase[2:] * 5):
- yield self.lru.get(c)
-
- # and fetch a again, expecting the cached value
- res = yield self.lru.get('a')
- self.check_result(res, res_a, exp_refhits=1)
-
- # but 'b' should give us a new value
- res = yield self.lru.get('b')
- self.check_result(res, long('b'), exp_refhits=1)
-
- @defer.inlineCallbacks
- def test_fuzz(self):
- chars = list(string.lowercase * 40)
- random.shuffle(chars)
- for i, c in enumerate(chars):
- res = yield self.lru.get(c)
- self.check_result(res, short(c))
-
- def test_massively_parallel(self):
- chars = list(string.lowercase * 5)
-
- misses = [ 0 ]
- def slow_short_miss_fn(key):
- d = defer.Deferred()
- misses[0] += 1
- reactor.callLater(0, lambda : d.callback(short(key)))
- return d
- self.lru.miss_fn = slow_short_miss_fn
-
- def check(c, d):
- d.addCallback(self.check_result, short(c))
- return d
- d = defer.gatherResults([
- check(c, self.lru.get(c))
- for c in chars ])
- def post_check(_):
- self.assertEqual(misses[0], 26)
- self.assertEqual(self.lru.misses, 26)
- self.assertEqual(self.lru.hits, 4*26)
- d.addCallback(post_check)
- return d
-
- def test_slow_fetch(self):
- def slower_miss_fn(k):
- d = defer.Deferred()
- reactor.callLater(0.05, lambda : d.callback(short(k)))
- return d
- self.lru.miss_fn = slower_miss_fn
-
- def do_get(test_d, k):
- d = self.lru.get(k)
- d.addCallback(self.check_result, short(k))
- d.addCallbacks(test_d.callback, test_d.errback)
-
- ds = []
- for i in range(8):
- d = defer.Deferred()
- reactor.callLater(0.02*i, do_get, d, 'x')
- ds.append(d)
-
- d = defer.gatherResults(ds)
- def check(_):
- self.assertEqual((self.lru.hits, self.lru.misses), (7, 1))
- d.addCallback(check)
- return d
-
- def test_slow_failure(self):
- def slow_fail_miss_fn(k):
- d = defer.Deferred()
- reactor.callLater(0.05,
- lambda : d.errback(failure.Failure(RuntimeError("oh noes"))))
- return d
- self.lru.miss_fn = slow_fail_miss_fn
-
- def do_get(test_d, k):
- d = self.lru.get(k)
- self.assertFailure(d, RuntimeError)
- d.addCallbacks(test_d.callback, test_d.errback)
-
- ds = []
- for i in range(8):
- d = defer.Deferred()
- reactor.callLater(0.02*i, do_get, d, 'x')
- ds.append(d)
-
- d = defer.gatherResults(ds)
- return d
-
- @defer.inlineCallbacks
- def test_set_max_size(self):
- # load up the cache with three items
- for c in 'abc':
- res = yield self.lru.get(c)
- self.check_result(res, short(c))
-
- # reset the size to 1
- self.lru.set_max_size(1)
- gc.collect()
-
- # and then expect that 'b' is no longer in the cache
- self.lru.miss_fn = self.long_miss_fn
- res = yield self.lru.get('b')
- self.check_result(res, long('b'))
-
- def test_miss_fn_kwargs(self):
- def keep_kwargs_miss_fn(k, **kwargs):
- return defer.succeed(set(kwargs.keys()))
- self.lru.miss_fn = keep_kwargs_miss_fn
-
- d = self.lru.get('a', a=1, b=2)
- d.addCallback(self.check_result, set(['a', 'b']), 0, 1)
- return d
-
- @defer.inlineCallbacks
- def test_miss_fn_returns_none(self):
- calls = []
- def none_miss_fn(k):
- calls.append(k)
- return defer.succeed(None)
- self.lru.miss_fn = none_miss_fn
-
- for i in range(2):
- self.assertEqual((yield self.lru.get('a')), None)
-
- # check that the miss_fn was called twice
- self.assertEqual(calls, ['a', 'a'])
-
- @defer.inlineCallbacks
- def test_put(self):
- self.assertEqual((yield self.lru.get('p')), short('p'))
- self.lru.put('p', set(['P2P2']))
- self.assertEqual((yield self.lru.get('p')), set(['P2P2']))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_maildir.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_maildir.py
deleted file mode 100644
index 419ae448..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_maildir.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.util import maildir
-from buildbot.test.util import dirs
-
-class TestMaildirService(dirs.DirsMixin, unittest.TestCase):
- def setUp(self):
- self.maildir = os.path.abspath("maildir")
- self.newdir = os.path.join(self.maildir, "new")
- self.curdir = os.path.join(self.maildir, "cur")
- self.tmpdir = os.path.join(self.maildir, "tmp")
- self.setUpDirs(self.maildir, self.newdir, self.curdir, self.tmpdir)
-
- self.svc = None
-
- def tearDown(self):
- if self.svc and self.svc.running:
- self.svc.stopService()
- self.tearDownDirs()
-
- # tests
-
- @defer.inlineCallbacks
- def test_start_stop_repeatedly(self):
- self.svc = maildir.MaildirService(self.maildir)
- self.svc.startService()
- yield self.svc.stopService()
- self.svc.startService()
- yield self.svc.stopService()
- self.assertEqual(len(list(self.svc)), 0)
-
-
- def test_messageReceived(self):
- self.svc = maildir.MaildirService(self.maildir)
-
- # add a fake messageReceived method
- messagesReceived = []
- def messageReceived(filename):
- messagesReceived.append(filename)
- return defer.succeed(None)
- self.svc.messageReceived = messageReceived
- d = defer.maybeDeferred(self.svc.startService)
- def check_empty(_):
- self.assertEqual(messagesReceived, [])
- d.addCallback(check_empty)
- def add_msg(_):
- tmpfile = os.path.join(self.tmpdir, "newmsg")
- newfile = os.path.join(self.newdir, "newmsg")
- open(tmpfile, "w").close()
- os.rename(tmpfile, newfile)
- d.addCallback(add_msg)
- def trigger(_):
- # TODO: can we wait for a dnotify somehow, if enabled?
- return self.svc.poll()
- d.addCallback(trigger)
- def check_nonempty(_):
- self.assertEqual(messagesReceived, [ 'newmsg' ])
- d.addCallback(check_nonempty)
- return d
-
- def test_moveToCurDir(self):
- self.svc = maildir.MaildirService(self.maildir)
- tmpfile = os.path.join(self.tmpdir, "newmsg")
- newfile = os.path.join(self.newdir, "newmsg")
- open(tmpfile, "w").close()
- os.rename(tmpfile, newfile)
- self.svc.moveToCurDir("newmsg")
- self.assertEqual([ os.path.exists(os.path.join(d, "newmsg"))
- for d in (self.newdir, self.curdir, self.tmpdir) ],
- [ False, True, False ])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_misc.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_misc.py
deleted file mode 100644
index 78f38144..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_misc.py
+++ /dev/null
@@ -1,130 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.util import misc
-from buildbot import util
-from twisted.python import failure
-from twisted.internet import defer, reactor
-from buildbot.test.util import compat
-from buildbot.util.eventual import eventually
-
-class deferredLocked(unittest.TestCase):
- def test_name(self):
- self.assertEqual(util.deferredLocked, misc.deferredLocked)
-
- def test_fn(self):
- l = defer.DeferredLock()
- @util.deferredLocked(l)
- def check_locked(arg1, arg2):
- self.assertEqual([l.locked, arg1, arg2], [True, 1, 2])
- return defer.succeed(None)
- d = check_locked(1, 2)
- def check_unlocked(_):
- self.assertFalse(l.locked)
- d.addCallback(check_unlocked)
- return d
-
- def test_fn_fails(self):
- l = defer.DeferredLock()
- @util.deferredLocked(l)
- def do_fail():
- return defer.fail(RuntimeError("oh noes"))
- d = do_fail()
- def check_unlocked(_):
- self.assertFalse(l.locked)
- d.addCallbacks(lambda _ : self.fail("didn't errback"),
- lambda _ : self.assertFalse(l.locked))
- return d
-
- def test_fn_exception(self):
- l = defer.DeferredLock()
- @util.deferredLocked(l)
- def do_fail():
- raise RuntimeError("oh noes")
- d = do_fail()
- def check_unlocked(_):
- self.assertFalse(l.locked)
- d.addCallbacks(lambda _ : self.fail("didn't errback"),
- lambda _ : self.assertFalse(l.locked))
- return d
-
- def test_method(self):
- testcase = self
- class C:
- @util.deferredLocked('aLock')
- def check_locked(self, arg1, arg2):
- testcase.assertEqual([self.aLock.locked, arg1, arg2], [True, 1, 2])
- return defer.succeed(None)
- obj = C()
- obj.aLock = defer.DeferredLock()
- d = obj.check_locked(1, 2)
- def check_unlocked(_):
- self.assertFalse(obj.aLock.locked)
- d.addCallback(check_unlocked)
- return d
-
-class SerializedInvocation(unittest.TestCase):
-
- def waitForQuiet(self, si):
- d = defer.Deferred()
- si._quiet = lambda : d.callback(None)
- return d
-
- # tests
-
- def test_name(self):
- self.assertEqual(util.SerializedInvocation, misc.SerializedInvocation)
-
- def testCallFolding(self):
- events = []
- def testfn():
- d = defer.Deferred()
- def done():
- events.append('TM')
- d.callback(None)
- eventually(done)
- return d
- si = misc.SerializedInvocation(testfn)
-
- # run three times - the first starts testfn, the second
- # requires a second run, and the third is folded.
- d1 = si()
- d2 = si()
- d3 = si()
-
- dq = self.waitForQuiet(si)
- d = defer.gatherResults([d1, d2, d3, dq])
- def check(_):
- self.assertEqual(events, [ 'TM', 'TM' ])
- d.addCallback(check)
- return d
-
- @compat.usesFlushLoggedErrors
- def testException(self):
- def testfn():
- d = defer.Deferred()
- reactor.callLater(0, d.errback,
- failure.Failure(RuntimeError("oh noes")))
- return d
- si = misc.SerializedInvocation(testfn)
-
- d = si()
-
- def check(_):
- self.assertEqual(len(self.flushLoggedErrors(RuntimeError)), 1)
- d.addCallback(check)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_netstrings.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_netstrings.py
deleted file mode 100644
index 87173e5d..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_netstrings.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# 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
-
-from twisted.protocols import basic
-from twisted.trial import unittest
-from buildbot.util import netstrings
-
-class NetstringParser(unittest.TestCase):
-
- def test_valid_netstrings(self):
- p = netstrings.NetstringParser()
- p.feed("5:hello,5:world,")
- self.assertEqual(p.strings, ['hello', 'world'])
-
- def test_valid_netstrings_byte_by_byte(self):
- # (this is really testing twisted's support, but oh well)
- p = netstrings.NetstringParser()
- [ p.feed(c) for c in "5:hello,5:world," ]
- self.assertEqual(p.strings, ['hello', 'world'])
-
- def test_invalid_netstring(self):
- p = netstrings.NetstringParser()
- self.assertRaises(basic.NetstringParseError,
- lambda : p.feed("5-hello!"))
-
- def test_incomplete_netstring(self):
- p = netstrings.NetstringParser()
- p.feed("11:hello world,6:foob")
- # note that the incomplete 'foobar' does not appear here
- self.assertEqual(p.strings, ['hello world'])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_sautils.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_sautils.py
deleted file mode 100644
index 6c77e49a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_sautils.py
+++ /dev/null
@@ -1,22 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.util import sautils
-
-class SAVersion(unittest.TestCase):
-
- def test_sa_version(self):
- self.failUnless(sautils.sa_version() > (0,5,0))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_state.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_state.py
deleted file mode 100644
index 8e7adca2..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_state.py
+++ /dev/null
@@ -1,77 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-from buildbot.util import state
-from buildbot.test.fake.fakemaster import make_master
-
-class FakeObject(state.StateMixin):
- name = "fake-name"
-
- def __init__(self, master):
- self.master = master
-
-class TestStateMixin(unittest.TestCase):
-
- OBJECTID = 19
-
- def setUp(self):
- self.master = make_master(wantDb=True, testcase=self)
- self.object = FakeObject(self.master)
-
- def test_getState(self):
- self.master.db.state.fakeState('fake-name', 'FakeObject',
- fav_color=['red','purple'])
- d = self.object.getState('fav_color')
- def check(res):
- self.assertEqual(res, ['red', 'purple'])
- d.addCallback(check)
- return d
-
- def test_getState_default(self):
- d = self.object.getState('fav_color', 'black')
- def check(res):
- self.assertEqual(res, 'black')
- d.addCallback(check)
- return d
-
- def test_getState_KeyError(self):
- self.master.db.state.fakeState('fake-name', 'FakeObject',
- fav_color=['red','purple'])
- d = self.object.getState('fav_book')
- def cb(_):
- self.fail("should not succeed")
- def check_exc(f):
- f.trap(KeyError)
- pass
- d.addCallbacks(cb, check_exc)
- return d
-
- def test_setState(self):
- d = self.object.setState('y', 14)
- def check(_):
- self.master.db.state.assertStateByClass('fake-name', 'FakeObject',
- y=14)
- d.addCallback(check)
- return d
-
- def test_setState_existing(self):
- self.master.db.state.fakeState('fake-name', 'FakeObject', x=13)
- d = self.object.setState('x', 14)
- def check(_):
- self.master.db.state.assertStateByClass('fake-name', 'FakeObject',
- x=14)
- d.addCallback(check)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_subscriptions.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_subscriptions.py
deleted file mode 100644
index 0defb18a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/unit/test_util_subscriptions.py
+++ /dev/null
@@ -1,64 +0,0 @@
-# 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
-
-from twisted.trial import unittest
-
-from buildbot.util import subscription
-from buildbot.test.util import compat
-
-class subscriptions(unittest.TestCase):
-
- def setUp(self):
- self.subpt = subscription.SubscriptionPoint('test_sub')
-
- def test_str(self):
- self.assertIn('test_sub', str(self.subpt))
-
- def test_subscribe_unsubscribe(self):
- state = []
- def cb(*args, **kwargs):
- state.append((args, kwargs))
-
- # subscribe
- sub = self.subpt.subscribe(cb)
- self.assertTrue(isinstance(sub, subscription.Subscription))
- self.assertEqual(state, [])
-
- # deliver
- self.subpt.deliver(1, 2, a=3, b=4)
- self.assertEqual(state, [((1,2), dict(a=3, b=4))])
- state.pop()
-
- # unsubscribe
- sub.unsubscribe()
-
- # don't receive events anymore
- self.subpt.deliver(3, 4)
- self.assertEqual(state, [])
-
- @compat.usesFlushLoggedErrors
- def test_exception(self):
- def cb(*args, **kwargs):
- raise RuntimeError('mah bucket!')
-
- # subscribe
- self.subpt.subscribe(cb)
- try:
- self.subpt.deliver()
- except RuntimeError:
- self.fail("should not have seen exception here!")
- # log.err will cause Trial to complain about this error anyway, unless
- # we clean it up
- self.assertEqual(1, len(self.flushLoggedErrors(RuntimeError)))
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/__init__.py
deleted file mode 100644
index e69de29b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/__init__.py
+++ /dev/null
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/change_import.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/change_import.py
deleted file mode 100644
index e461dda6..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/change_import.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# 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
-
-from __future__ import with_statement
-
-import os
-import shutil
-import cPickle
-from buildbot.test.util import db
-
-from buildbot.changes.changes import Change, OldChangeMaster
-
-class ChangeImportMixin(db.RealDatabaseMixin):
- """
- We have a number of tests that examine the results of importing particular
- flavors of Change objects. This class uses some pickling to make this easy
- to test.
-
- This is a subclass of RealDatabaseMixin, so do not inherit from that class
- separately!
-
- >>> self.make_pickle(self.make_change(who=u'jimmy'), self.make_change(who='johnny'))
- """
- def make_pickle(self, *changes, **kwargs):
- recode_fn = kwargs.pop('recode_fn', None)
- cm = OldChangeMaster()
- cm.changes = changes
- if recode_fn:
- recode_fn(cm)
- with open(self.changes_pickle, "wb") as f:
- cPickle.dump(cm, f)
-
- def make_change(self, **kwargs):
- return Change(**kwargs)
-
- def setUpChangeImport(self):
- self.basedir = os.path.abspath("basedir")
- if os.path.exists(self.basedir):
- shutil.rmtree(self.basedir)
- os.makedirs(self.basedir)
- self.changes_pickle = os.path.join(self.basedir, "changes.pck")
- return self.setUpRealDatabase()
-
- def tearDownChangeImport(self):
- d = self.tearDownRealDatabase()
- def rmtree(_):
- if os.path.exists(self.basedir):
- shutil.rmtree(self.basedir)
- d.addCallback(rmtree)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/changesource.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/changesource.py
deleted file mode 100644
index 172f1584..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/changesource.py
+++ /dev/null
@@ -1,75 +0,0 @@
-# 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 mock
-from twisted.internet import defer
-from twisted.trial import unittest
-from buildbot.test.fake.fakemaster import make_master
-
-class ChangeSourceMixin(object):
- """
- This class is used for testing change sources, and handles a few things:
-
- - starting and stopping a ChangeSource service
- - a fake C{self.master.addChange}, which adds its args
- to the list C{self.changes_added}
- """
-
- changesource = None
- started = False
-
- def setUpChangeSource(self):
- "Set up the mixin - returns a deferred."
- self.changes_added = []
- def addChange(**kwargs):
- # check for 8-bit strings
- for k,v in kwargs.items():
- if type(v) == type(""):
- try:
- v.decode('ascii')
- except UnicodeDecodeError:
- raise unittest.FailTest(
- "non-ascii string for key '%s': %r" % (k,v))
- self.changes_added.append(kwargs)
- return defer.succeed(mock.Mock())
- self.master = make_master(testcase=self, wantDb=True)
- self.master.addChange = addChange
- return defer.succeed(None)
-
- def tearDownChangeSource(self):
- "Tear down the mixin - returns a deferred."
- if not self.started:
- return defer.succeed(None)
- if self.changesource.running:
- return defer.maybeDeferred(self.changesource.stopService)
- return defer.succeed(None)
-
- def attachChangeSource(self, cs):
- "Set up a change source for testing; sets its .master attribute"
- self.changesource = cs
- self.changesource.master = self.master
-
- def startChangeSource(self):
- "start the change source as a service"
- self.started = True
- self.changesource.startService()
-
- def stopChangeSource(self):
- "stop the change source again; returns a deferred"
- d = self.changesource.stopService()
- def mark_stopped(_):
- self.started = False
- d.addCallback(mark_stopped)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/compat.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/compat.py
deleted file mode 100644
index cf6305dd..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/compat.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# 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 sys
-import twisted
-from twisted.python import versions, runtime
-
-def usesFlushLoggedErrors(test):
- "Decorate a test method that uses flushLoggedErrors with this decorator"
- if (sys.version_info[:2] == (2,7)
- and twisted.version <= versions.Version('twisted', 9, 0, 0)):
- test.skip = \
- "flushLoggedErrors is broken on Python==2.7 and Twisted<=9.0.0"
- return test
-
-def usesFlushWarnings(test):
- "Decorate a test method that uses flushWarnings with this decorator"
- if (sys.version_info[:2] == (2,7)
- and twisted.version <= versions.Version('twisted', 9, 0, 0)):
- test.skip = \
- "flushWarnings is broken on Python==2.7 and Twisted<=9.0.0"
- return test
-
-def skipUnlessPlatformIs(platform):
- def closure(test):
- if runtime.platformType != platform:
- test.skip = "not a %s platform" % platform
- return test
- return closure
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/config.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/config.py
deleted file mode 100644
index 3747977e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/config.py
+++ /dev/null
@@ -1,41 +0,0 @@
-# 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
-
-from buildbot import config
-
-class ConfigErrorsMixin(object):
-
- def assertConfigError(self, errors, substr_or_re):
- if len(errors.errors) > 1:
- self.fail("too many errors: %s" % (errors.errors,))
- elif len(errors.errors) < 1:
- self.fail("expected error did not occur")
- elif isinstance(substr_or_re, str):
- if substr_or_re not in errors.errors[0]:
- self.fail("non-matching error: %s" % (errors.errors,))
- else:
- if not substr_or_re.search(errors.errors[0]):
- self.fail("non-matching error: %s" % (errors.errors,))
-
- def assertRaisesConfigError(self, substr_or_re, fn):
- try:
- fn()
- except config.ConfigErrors, e:
- self.assertConfigError(e, substr_or_re)
- else:
- self.fail("ConfigErrors not raised")
-
- def assertNoConfigErrors(self, errors):
- self.assertEqual(errors.errors, [])
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/connector_component.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/connector_component.py
deleted file mode 100644
index 159e824c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/connector_component.py
+++ /dev/null
@@ -1,54 +0,0 @@
-# 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
-
-from buildbot.db import model
-from buildbot.test.util import db
-from buildbot.test.fake import fakemaster
-
-class FakeDBConnector(object):
- pass
-
-class ConnectorComponentMixin(db.RealDatabaseMixin):
- """
- Implements a mock DBConnector object, replete with a thread pool and a DB
- model. This includes a RealDatabaseMixin, so subclasses should not
- instantiate that class directly. The connector appears at C{self.db}, and
- the component should be attached to it as an attribute.
-
- @ivar db: fake database connector
- @ivar db.pool: DB thread pool
- @ivar db.model: DB model
- """
- def setUpConnectorComponent(self, table_names=[], basedir='basedir'):
- """Set up C{self.db}, using the given db_url and basedir."""
- d = self.setUpRealDatabase(table_names=table_names, basedir=basedir)
- def finish_setup(_):
- self.db = FakeDBConnector()
- self.db.pool = self.db_pool
- self.db.model = model.Model(self.db)
- self.db.master = fakemaster.make_master()
- d.addCallback(finish_setup)
- return d
-
- def tearDownConnectorComponent(self):
- d = self.tearDownRealDatabase()
- def finish_cleanup(_):
- self.db_pool.shutdown()
- # break some reference loops, just for fun
- del self.db.pool
- del self.db.model
- del self.db
- d.addCallback(finish_cleanup)
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/db.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/db.py
deleted file mode 100644
index 67f2ce0c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/db.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# 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 os
-import sqlalchemy as sa
-from sqlalchemy.schema import MetaData
-from twisted.python import log
-from twisted.trial import unittest
-from twisted.internet import defer
-from buildbot.db import model, pool, enginestrategy
-
-def skip_for_dialect(dialect):
- """Decorator to skip a test for a particular SQLAlchemy dialect."""
- def dec(fn):
- def wrap(self, *args, **kwargs):
- if self.db_engine.dialect.name == dialect:
- raise unittest.SkipTest(
- "Not supported on dialect '%s'" % dialect)
- return fn(self, *args, **kwargs)
- return wrap
- return dec
-
-class RealDatabaseMixin(object):
- """
- A class that sets up a real database for testing. This sets self.db_url to
- the URL for the database. By default, it specifies an in-memory SQLite
- database, but if the BUILDBOT_TEST_DB_URL environment variable is set, it
- will use the specified database, being careful to clean out *all* tables in
- the database before and after the tests are run - so each test starts with
- a clean database.
-
- @ivar db_pool: a (real) DBThreadPool instance that can be used as desired
-
- @ivar db_url: the DB URL used to run these tests
-
- @ivar db_engine: the engine created for the test database
- """
-
- # Note that this class uses the production database model. A
- # re-implementation would be virtually identical and just require extra
- # work to keep synchronized.
-
- # Similarly, this class uses the production DB thread pool. This achieves
- # a few things:
- # - affords more thorough tests for the pool
- # - avoids repetitive implementation
- # - cooperates better at runtime with thread-sensitive DBAPI's
-
- def __thd_clean_database(self, conn):
- # drop the known tables, although sometimes this misses dependencies
- try:
- model.Model.metadata.drop_all(bind=conn, checkfirst=True)
- except sa.exc.ProgrammingError:
- pass
-
- # see if we can find any other tables to drop
- meta = MetaData(bind=conn)
- meta.reflect()
- meta.drop_all()
-
- def __thd_create_tables(self, conn, table_names):
- all_table_names = set(table_names)
- ordered_tables = [ t for t in model.Model.metadata.sorted_tables
- if t.name in all_table_names ]
-
- for tbl in ordered_tables:
- tbl.create(bind=conn, checkfirst=True)
-
- def setUpRealDatabase(self, table_names=[], basedir='basedir',
- want_pool=True, sqlite_memory=True):
- """
-
- Set up a database. Ordinarily sets up an engine and a pool and takes
- care of cleaning out any existing tables in the database. If
- C{want_pool} is false, then no pool will be created, and the database
- will not be cleaned.
-
- @param table_names: list of names of tables to instantiate
- @param basedir: (optional) basedir for the engine
- @param want_pool: (optional) false to not create C{self.db_pool}
- @param sqlite_memory: (optional) False to avoid using an in-memory db
- @returns: Deferred
- """
- self.__want_pool = want_pool
-
- default = 'sqlite://'
- if not sqlite_memory:
- default = "sqlite:///tmp.sqlite"
- if not os.path.exists(basedir):
- os.makedirs(basedir)
-
- self.db_url = os.environ.get('BUILDBOT_TEST_DB_URL', default)
-
- self.db_engine = enginestrategy.create_engine(self.db_url,
- basedir=basedir)
- # if the caller does not want a pool, we're done.
- if not want_pool:
- return defer.succeed(None)
-
- self.db_pool = pool.DBThreadPool(self.db_engine)
-
- log.msg("cleaning database %s" % self.db_url)
- d = self.db_pool.do(self.__thd_clean_database)
- d.addCallback(lambda _ :
- self.db_pool.do(self.__thd_create_tables, table_names))
- return d
-
- def tearDownRealDatabase(self):
- if self.__want_pool:
- return self.db_pool.do(self.__thd_clean_database)
- else:
- return defer.succeed(None)
-
- def insertTestData(self, rows):
- """Insert test data into the database for use during the test.
-
- @param rows: be a sequence of L{fakedb.Row} instances. These will be
- sorted by table dependencies, so order does not matter.
-
- @returns: Deferred
- """
- # sort the tables by dependency
- all_table_names = set([ row.table for row in rows ])
- ordered_tables = [ t for t in model.Model.metadata.sorted_tables
- if t.name in all_table_names ]
- def thd(conn):
- # insert into tables -- in order
- for tbl in ordered_tables:
- for row in [ r for r in rows if r.table == tbl.name ]:
- tbl = model.Model.metadata.tables[row.table]
- try:
- tbl.insert(bind=conn).execute(row.values)
- except:
- log.msg("while inserting %s - %s" % (row, row.values))
- raise
- return self.db_pool.do(thd)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/dirs.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/dirs.py
deleted file mode 100644
index 22b5dd55..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/dirs.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# 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 os
-import shutil
-from twisted.internet import defer
-
-class DirsMixin(object):
-
- _dirs = None
-
- def setUpDirs(self, *dirs):
- """Make sure C{dirs} exist and are empty, and set them up to be deleted
- in tearDown."""
- self._dirs = map(os.path.abspath, dirs)
- for dir in self._dirs:
- if os.path.exists(dir):
- shutil.rmtree(dir)
- os.makedirs(dir)
- # return a deferred to make chaining easier
- return defer.succeed(None)
-
- def tearDownDirs(self):
- for dir in self._dirs:
- if os.path.exists(dir):
- shutil.rmtree(dir)
- # return a deferred to make chaining easier
- return defer.succeed(None)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/gpo.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/gpo.py
deleted file mode 100644
index 05bb5849..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/gpo.py
+++ /dev/null
@@ -1,116 +0,0 @@
-# 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
-
-from twisted.internet import defer, utils
-
-class Expect(object):
- _stdout = ""
- _stderr = ""
- _exit = 0
- _path = None
-
- def __init__(self, bin, *args):
- self._bin = bin
- self._args = args
-
- def stdout(self, stdout):
- self._stdout = stdout
- return self
-
- def stderr(self, stderr):
- self._stderr = stderr
- return self
-
- def exit(self, exit):
- self._exit = exit
- return self
-
- def path(self, path):
- self._path = path
- return self
-
- def check(self, test, bin, path, args):
- test.assertEqual(
- dict(bin=bin, path=path, args=tuple(args)),
- dict(bin=self._bin, path=self._path, args=self._args),
- "unexpected command run")
- return (self._stdout, self._stderr, self._exit)
-
- def __repr__(self):
- return "<gpo.Expect(bin=%s, args=%s)>" % (self._bin, self._args)
-
-
-class GetProcessOutputMixin:
-
- def setUpGetProcessOutput(self):
- self._gpo_patched = False
- self._expected_commands = []
- self._gpo_expect_env = {}
-
- def assertAllCommandsRan(self):
- self.assertEqual(self._expected_commands, [],
- "assert all expected commands were run")
-
- def _check_env(self, env):
- env = env or {}
- for var, value in self._gpo_expect_env.items():
- self.assertEqual(env.get(var), value,
- 'Expected environment to have %s = %r' % (var, value))
-
- def patched_getProcessOutput(self, bin, args, env=None,
- errortoo=False, path=None):
- d = self.patched_getProcessOutputAndValue(bin, args, env=env,
- path=path)
- @d.addCallback
- def cb(res):
- stdout, stderr, exit = res
- if errortoo:
- return defer.succeed(stdout + stderr)
- else:
- if stderr:
- return defer.fail(IOError("got stderr: %r" % (stderr,)))
- else:
- return defer.succeed(stdout)
- return d
-
- def patched_getProcessOutputAndValue(self, bin, args, env=None,
- path=None):
- self._check_env(env)
-
- if not self._expected_commands:
- self.fail("got command %s %s when no further commands were expected"
- % (bin, args))
-
- expect = self._expected_commands.pop(0)
- return defer.succeed(expect.check(self, bin, path, args))
-
- def _patch_gpo(self):
- if not self._gpo_patched:
- self.patch(utils, "getProcessOutput",
- self.patched_getProcessOutput)
- self.patch(utils, "getProcessOutputAndValue",
- self.patched_getProcessOutputAndValue)
- self._gpo_patched = True
-
- def addGetProcessOutputExpectEnv(self, d):
- self._gpo_expect_env.update(d)
-
- def expectCommands(self, *exp):
- """
- Add to the expected commands, along with their results. Each
- argument should be an instance of L{Expect}.
- """
- self._patch_gpo()
- self._expected_commands.extend(exp)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/interfaces.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/interfaces.py
deleted file mode 100644
index 44756ffe..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/interfaces.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# 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 inspect
-
-class InterfaceTests(object):
-
- # assertions
-
- def assertArgSpecMatches(self, actual):
- def wrap(template):
- actual_argspec = inspect.getargspec(actual)
- template_argspec = inspect.getargspec(template)
- if actual_argspec != template_argspec:
- msg = "Expected: %s; got: %s" % (
- inspect.formatargspec(*template_argspec),
- inspect.formatargspec(*actual_argspec))
- self.fail(msg)
- return template # just in case it's useful
- return wrap
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/logging.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/logging.py
deleted file mode 100644
index f482fd37..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/logging.py
+++ /dev/null
@@ -1,32 +0,0 @@
-# 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 re
-from twisted.python import log
-
-class LoggingMixin(object):
-
- def setUpLogging(self):
- self._logEvents = []
- log.addObserver(self._logEvents.append)
- self.addCleanup(log.removeObserver, self._logEvents.append)
-
- def assertLogged(self, regexp):
- r = re.compile(regexp)
- for event in self._logEvents:
- msg = log.textFromEventDict(event)
- if msg is not None and r.search(msg):
- return
- self.fail("%r not matched in log output" % regexp)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/migration.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/migration.py
deleted file mode 100644
index 42cef870..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/migration.py
+++ /dev/null
@@ -1,80 +0,0 @@
-# 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 os
-from twisted.python import log
-from twisted.internet import defer
-import sqlalchemy as sa
-import migrate
-import migrate.versioning.api
-from buildbot.db import connector
-from buildbot.test.util import db, dirs, querylog
-from buildbot.test.fake import fakemaster
-
-
-# test_upgrade vs. migration tests
-#
-# test_upgrade is an integration test -- it tests the whole upgrade process,
-# including the code in model.py. Migrate tests are unit tests, and test a
-# single db upgrade script.
-
-class MigrateTestMixin(db.RealDatabaseMixin, dirs.DirsMixin):
-
- def setUpMigrateTest(self):
- self.basedir = os.path.abspath("basedir")
- self.setUpDirs('basedir')
-
- d = self.setUpRealDatabase()
- def make_dbc(_):
- master = fakemaster.make_master()
- self.db = connector.DBConnector(master, self.basedir)
- self.db.pool = self.db_pool
- d.addCallback(make_dbc)
- return d
-
- def tearDownMigrateTest(self):
- self.tearDownDirs()
- return self.tearDownRealDatabase()
-
- def do_test_migration(self, base_version, target_version,
- setup_thd_cb, verify_thd_cb):
- d = defer.succeed(None)
- def setup_thd(conn):
- metadata = sa.MetaData()
- table = sa.Table('migrate_version', metadata,
- sa.Column('repository_id', sa.String(250),
- primary_key=True),
- sa.Column('repository_path', sa.Text),
- sa.Column('version', sa.Integer))
- table.create(bind=conn)
- conn.execute(table.insert(),
- repository_id='Buildbot',
- repository_path=self.db.model.repo_path,
- version=base_version)
- setup_thd_cb(conn)
- d.addCallback(lambda _ : self.db.pool.do(setup_thd))
-
- def upgrade_thd(engine):
- querylog.log_from_engine(engine)
- schema = migrate.versioning.schema.ControlledSchema(engine,
- self.db.model.repo_path)
- changeset = schema.changeset(target_version)
- for version, change in changeset:
- log.msg('upgrading to schema version %d' % (version+1))
- schema.runchange(version, change, 1)
- d.addCallback(lambda _ : self.db.pool.do_with_engine(upgrade_thd))
-
- d.addCallback(lambda _ : self.db.pool.do(verify_thd_cb))
- return d
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/misc.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/misc.py
deleted file mode 100644
index aeb0f63a..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/misc.py
+++ /dev/null
@@ -1,51 +0,0 @@
-# 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 os
-import sys
-import cStringIO
-
-class PatcherMixin(object):
- """
- Mix this in to get a few special-cased patching methods
- """
-
- def patch_os_uname(self, replacement):
- # twisted's 'patch' doesn't handle the case where an attribute
- # doesn't exist..
- if hasattr(os, 'uname'):
- self.patch(os, 'uname', replacement)
- else:
- def cleanup():
- del os.uname
- self.addCleanup(cleanup)
- os.uname = replacement
-
-class StdoutAssertionsMixin(object):
- """
- Mix this in to be able to assert on stdout during the test
- """
- def setUpStdoutAssertions(self):
- self.stdout = cStringIO.StringIO()
- self.patch(sys, 'stdout', self.stdout)
-
- def assertWasQuiet(self):
- self.assertEqual(self.stdout.getvalue(), '')
-
- def assertInStdout(self, exp):
- self.assertIn(exp, self.stdout.getvalue())
-
- def getStdout(self):
- return self.stdout.getvalue().strip()
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/pbmanager.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/pbmanager.py
deleted file mode 100644
index ac215744..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/pbmanager.py
+++ /dev/null
@@ -1,50 +0,0 @@
-# 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 mock
-from twisted.internet import defer
-
-class PBManagerMixin:
- def setUpPBChangeSource(self):
- "Set up a fake self.pbmanager."
- self.registrations = []
- self.unregistrations = []
- pbm = self.pbmanager = mock.Mock()
- pbm.register = self._fake_register
-
- def _fake_register(self, portstr, username, password, factory):
- reg = mock.Mock()
- def unregister():
- self.unregistrations.append((portstr, username, password))
- return defer.succeed(None)
- reg.unregister = unregister
- self.registrations.append((portstr, username, password))
- return reg
-
- def assertNotRegistered(self):
- self.assertEqual(self.registrations, [])
-
- def assertRegistered(self, portstr, username, password):
- for ps, un, pw in self.registrations:
- if ps == portstr and username == un and pw == password:
- return
- self.fail("not registered: %r not in %s" %
- ((portstr, username, password), self.registrations))
-
- def assertUnregistered(self, portstr, username, password):
- for ps, un, pw in self.unregistrations:
- if ps == portstr and username == un and pw == password:
- return
- self.fail("still registered")
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/properties.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/properties.py
deleted file mode 100644
index 36b958f1..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/properties.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# 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
-
-from zope.interface import implements
-from buildbot.interfaces import IRenderable
-
-class ConstantRenderable(object):
- implements(IRenderable)
- def __init__(self, value):
- self.value = value
- def getRenderingFor(self, props):
- return self.value
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/querylog.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/querylog.py
deleted file mode 100644
index 359657a4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/querylog.py
+++ /dev/null
@@ -1,35 +0,0 @@
-# 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
-
-from __future__ import absolute_import
-import logging
-from twisted.python import log
-
-# this class bridges Python's `logging` module into Twisted's log system.
-# SqlAlchemy query logging uses `logging`, so this provides a way to enter
-# queries into the Twisted log file.
-
-class PythonToTwistedHandler(logging.Handler):
-
- def emit(self, record):
- log.msg(record.getMessage())
-
-def log_from_engine(engine):
- # add the handler *before* enabling logging, so that no "default" logger
- # is added automatically, but only do so once. This is important since
- # logging's loggers are singletons
- if not engine.logger.handlers:
- engine.logger.addHandler(PythonToTwistedHandler())
- engine.echo = True
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/scheduler.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/scheduler.py
deleted file mode 100644
index 680bc48f..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/scheduler.py
+++ /dev/null
@@ -1,142 +0,0 @@
-# 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 os
-import mock
-from buildbot.test.fake import fakedb
-
-class FakeMaster(object):
-
- def __init__(self, basedir, db):
- self.basedir = basedir
- self.db = db
- self.changes_subscr_cb = None
- self.bset_subscr_cb = None
- self.bset_completion_subscr_cb = None
- self.caches = mock.Mock(name="caches")
- self.caches.get_cache = self.get_cache
-
- def addBuildset(self, **kwargs):
- return self.db.buildsets.addBuildset(**kwargs)
-
- # subscriptions
- # note that only one subscription of each type is supported
-
- def _makeSubscription(self, attr_to_clear):
- sub = mock.Mock()
- def unsub():
- setattr(self, attr_to_clear, None)
- sub.unsubscribe = unsub
- return sub
-
- def subscribeToChanges(self, callback):
- assert not self.changes_subscr_cb
- self.changes_subscr_cb = callback
- return self._makeSubscription('changes_subscr_cb')
-
- def subscribeToBuildsets(self, callback):
- assert not self.bset_subscr_cb
- self.bset_subscr_cb = callback
- return self._makeSubscription('bset_subscr_cb')
-
- def subscribeToBuildsetCompletions(self, callback):
- assert not self.bset_completion_subscr_cb
- self.bset_completion_subscr_cb = callback
- return self._makeSubscription('bset_completion_subscr_cb')
-
- # caches
-
- def get_cache(self, cache_name, miss_fn):
- c = mock.Mock(name=cache_name)
- c.get = miss_fn
- return c
-
- # useful assertions
-
- def getSubscriptionCallbacks(self):
- """get the subscription callbacks set on the master, in a dictionary
- with keys @{buildsets}, @{buildset_completion}, and C{changes}."""
- return dict(buildsets=self.bset_subscr_cb,
- buildset_completion=self.bset_completion_subscr_cb,
- changes=self.changes_subscr_cb)
-
-
-class SchedulerMixin(object):
- """
- This class fakes out enough of a master and the various relevant database
- connectors to test schedulers. All of the database methods have identical
- signatures to the real database connectors, but for ease of testing always
- return an already-fired Deferred, meaning that there is no need to wait for
- events to complete.
-
- This class is tightly coupled with the various L{buildbot.test.fake.fakedb}
- module. All instance variables are only available after C{attachScheduler}
- has been called.
-
- @ivar sched: scheduler instance
- @ivar master: the fake master
- @ivar db: the fake db (same as C{self.master.db}, but shorter)
- """
-
- def setUpScheduler(self):
- pass
-
- def tearDownScheduler(self):
- pass
-
- def attachScheduler(self, scheduler, objectid):
- """Set up a scheduler with a fake master and db; sets self.sched, and
- sets the master's basedir to the absolute path of 'basedir' in the test
- directory.
-
- @returns: scheduler
- """
- scheduler.objectid = objectid
-
- # set up a fake master
- db = self.db = fakedb.FakeDBConnector(self)
- self.master = FakeMaster(os.path.abspath('basedir'), db)
- scheduler.master = self.master
-
- db.insertTestData([
- fakedb.Object(id=objectid, name=scheduler.name,
- class_name='SomeScheduler'),
- ])
-
- self.sched = scheduler
- return scheduler
-
- class FakeChange:
- who = ''
- files = []
- comments = ''
- isdir=0
- links=None
- revision=None
- when=None
- branch=None
- category=None
- revlink=''
- properties={}
- repository=''
- project=''
- codebase=''
-
- def makeFakeChange(self, **kwargs):
- """Utility method to make a fake Change object with the given
- attributes"""
- ch = self.FakeChange()
- ch.__dict__.update(kwargs)
- return ch
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/sourcesteps.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/sourcesteps.py
deleted file mode 100644
index df1b931b..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/sourcesteps.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# 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 mock
-from buildbot.test.util import steps
-
-import os
-
-class SourceStepMixin(steps.BuildStepMixin):
- """
- Support for testing source steps. Aside from the capabilities of
- L{BuildStepMixin}, this adds:
-
- - fake sourcestamps
-
- The following instance variables are available after C{setupSourceStep}, in
- addition to those made available by L{BuildStepMixin}:
-
- @ivar sourcestamp: fake SourceStamp for the build
- """
-
- def setUpSourceStep(self):
- return steps.BuildStepMixin.setUpBuildStep(self)
-
- def tearDownSourceStep(self):
- return steps.BuildStepMixin.tearDownBuildStep(self)
-
- # utilities
-
- def setupStep(self, step, args={}, patch=None, **kwargs):
- """
- Set up C{step} for testing. This calls L{BuildStepMixin}'s C{setupStep}
- and then does setup specific to a Source step.
- """
- step = steps.BuildStepMixin.setupStep(self, step, **kwargs)
-
- ss = self.sourcestamp = mock.Mock(name="sourcestamp")
- ss.ssid = 9123
- ss.branch = args.get('branch', None)
- ss.revision = args.get('revision', None)
- ss.project = ''
- ss.repository = ''
- ss.patch = patch
- ss.patch_info = None
- ss.changes = []
- self.build.path_module = os.path
- self.build.getSourceStamp = lambda x=None: ss
- return step
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/steps.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/steps.py
deleted file mode 100644
index 3c70d92e..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/test/util/steps.py
+++ /dev/null
@@ -1,256 +0,0 @@
-# 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 mock
-from buildbot import interfaces
-from buildbot.process import buildstep
-from buildbot.test.fake import remotecommand, fakebuild, slave
-
-
-class BuildStepMixin(object):
- """
- Support for testing build steps. This class adds two capabilities:
-
- - patch out RemoteCommand with fake versions that check expected
- commands and produce the appropriate results
-
- - surround a step with the mock objects that it needs to execute
-
- The following instance variables are available after C{setupStep}:
-
- @ivar step: the step under test
- @ivar build: the fake build containing the step
- @ivar progress: mock progress object
- @ivar buildslave: mock buildslave object
- @ivar step_status: mock StepStatus object
- @ivar properties: build properties (L{Properties} instance)
- """
-
- def setUpBuildStep(self):
- # make an (admittedly global) reference to this test case so that
- # the fakes can call back to us
- remotecommand.FakeRemoteCommand.testcase = self
- self.patch(buildstep, 'RemoteCommand',
- remotecommand.FakeRemoteCommand)
- self.patch(buildstep, 'RemoteShellCommand',
- remotecommand.FakeRemoteShellCommand)
- self.expected_remote_commands = []
-
- def tearDownBuildStep(self):
- # delete the reference added in setUp
- del remotecommand.FakeRemoteCommand.testcase
-
- # utilities
-
- def setupStep(self, step, slave_version={'*':"99.99"}, slave_env={}):
- """
- Set up C{step} for testing. This begins by using C{step} as a factory
- to create a I{new} step instance, thereby testing that the the factory
- arguments are handled correctly. It then creates a comfortable
- environment for the slave to run in, repleate with a fake build and a
- fake slave.
-
- As a convenience, it calls the step's setDefaultWorkdir method with
- C{'wkdir'}.
-
- @param slave_version: slave version to present, as a dictionary mapping
- command name to version. A command name of '*' will apply for all
- commands.
-
- @param slave_env: environment from the slave at slave startup
- """
- factory = interfaces.IBuildStepFactory(step)
- step = self.step = factory.buildStep()
-
- # step.build
-
- b = self.build = fakebuild.FakeBuild()
- def getSlaveVersion(cmd, oldversion):
- if cmd in slave_version:
- return slave_version[cmd]
- if '*' in slave_version:
- return slave_version['*']
- return oldversion
- b.getSlaveCommandVersion = getSlaveVersion
- b.slaveEnvironment = slave_env.copy()
- step.setBuild(b)
-
- # watch for properties being set
- self.properties = interfaces.IProperties(b)
-
- # step.progress
-
- step.progress = mock.Mock(name="progress")
-
- # step.buildslave
-
- self.buildslave = step.buildslave = slave.FakeSlave()
-
- # step.step_status
-
- ss = self.step_status = mock.Mock(name="step_status")
-
- ss.status_text = None
- ss.logs = {}
-
- def ss_setText(strings):
- ss.status_text = strings
- ss.setText = ss_setText
-
- ss.getLogs = lambda : ss.logs.values()
-
- self.step_statistics = {}
- ss.setStatistic = self.step_statistics.__setitem__
- ss.getStatistic = self.step_statistics.get
- ss.hasStatistic = self.step_statistics.__contains__
-
- self.step.setStepStatus(ss)
-
- # step overrides
-
- def addLog(name):
- l = remotecommand.FakeLogFile(name, step)
- ss.logs[name] = l
- return l
- step.addLog = addLog
-
- def addHTMLLog(name, html):
- l = remotecommand.FakeLogFile(name, step)
- l.addStdout(html)
- ss.logs[name] = l
- return l
- step.addHTMLLog = addHTMLLog
-
- def addCompleteLog(name, text):
- l = remotecommand.FakeLogFile(name, step)
- l.addStdout(text)
- ss.logs[name] = l
- return l
- step.addCompleteLog = addCompleteLog
-
- step.logobservers = self.logobservers = {}
- def addLogObserver(logname, observer):
- self.logobservers.setdefault(logname, []).append(observer)
- observer.step = step
- step.addLogObserver = addLogObserver
-
- # set defaults
-
- step.setDefaultWorkdir('wkdir')
-
- # expectations
-
- self.exp_outcome = None
- self.exp_properties = {}
- self.exp_missing_properties = []
- self.exp_logfiles = {}
- self.exp_hidden = False
-
- return step
-
- def expectCommands(self, *exp):
- """
- Add to the expected remote commands, along with their results. Each
- argument should be an instance of L{Expect}.
- """
- self.expected_remote_commands.extend(exp)
-
- def expectOutcome(self, result, status_text):
- """
- Expect the given result (from L{buildbot.status.results}) and status
- text (a list).
- """
- self.exp_outcome = dict(result=result, status_text=status_text)
-
- def expectProperty(self, property, value, source=None):
- """
- Expect the given property to be set when the step is complete.
- """
- self.exp_properties[property] = (value, source)
-
- def expectNoProperty(self, property):
- """
- Expect the given property is *not* set when the step is complete
- """
- self.exp_missing_properties.append(property)
-
- def expectLogfile(self, logfile, contents):
- """
- Expect a logfile with the given contents
- """
- self.exp_logfiles[logfile] = contents
-
- def expectHidden(self, hidden):
- """
- Set whether the step is expected to be hidden.
- """
- self.exp_hidden = hidden
-
- def runStep(self):
- """
- Run the step set up with L{setupStep}, and check the results.
-
- @returns: Deferred
- """
- self.remote = mock.Mock(name="SlaveBuilder(remote)")
- # TODO: self.step.setupProgress()
- d = self.step.startStep(self.remote)
- def check(result):
- self.assertEqual(self.expected_remote_commands, [],
- "assert all expected commands were run")
- got_outcome = dict(result=result,
- status_text=self.step_status.status_text)
- self.assertEqual(got_outcome, self.exp_outcome, "expected step outcome")
- for pn, (pv, ps) in self.exp_properties.iteritems():
- self.assertTrue(self.properties.hasProperty(pn),
- "missing property '%s'" % pn)
- self.assertEqual(self.properties.getProperty(pn), pv, "property '%s'" % pn)
- if ps is not None:
- self.assertEqual(self.properties.getPropertySource(pn), ps, "property '%s' source" % pn)
- for pn in self.exp_missing_properties:
- self.assertFalse(self.properties.hasProperty(pn), "unexpected property '%s'" % pn)
- for log, contents in self.exp_logfiles.iteritems():
- self.assertEqual(self.step_status.logs[log].stdout, contents, "log '%s' contents" % log)
- self.step_status.setHidden.assert_called_once_with(self.exp_hidden)
- d.addCallback(check)
- return d
-
- # callbacks from the running step
-
- def _remotecommand_run(self, command, step, remote):
- self.assertEqual(step, self.step)
- self.assertEqual(remote, self.remote)
- got = (command.remote_command, command.args)
-
- if not self.expected_remote_commands:
- self.fail("got command %r when no further commands were expected"
- % (got,))
-
- exp = self.expected_remote_commands.pop(0)
-
- # handle any incomparable args
- for arg in exp.incomparable_args:
- self.failUnless(arg in got[1],
- "incomparable arg '%s' not received" % (arg,))
- del got[1][arg]
-
- # first check any ExpectedRemoteReference instances
- self.assertEqual((exp.remote_command, exp.args), got)
-
- # let the Expect object show any behaviors that are required
- d = exp.runBehaviors(command)
- d.addCallback(lambda _: command)
- return d
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/__init__.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/__init__.py
deleted file mode 100644
index 281c345c..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/__init__.py
+++ /dev/null
@@ -1,204 +0,0 @@
-# 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 time, re, string
-import datetime
-import calendar
-from buildbot.util.misc import deferredLocked, SerializedInvocation
-
-def naturalSort(l):
- l = l[:]
- def try_int(s):
- try:
- return int(s)
- except ValueError:
- return s
- def key_func(item):
- return [try_int(s) for s in re.split('(\d+)', item)]
- # prepend integer keys to each element, sort them, then strip the keys
- keyed_l = [ (key_func(i), i) for i in l ]
- keyed_l.sort()
- l = [ i[1] for i in keyed_l ]
- return l
-
-def flatten(l):
- if l and type(l[0]) == list:
- rv = []
- for e in l:
- if type(e) == list:
- rv.extend(flatten(e))
- else:
- rv.append(e)
- return rv
- else:
- return l
-
-def now(_reactor=None):
- if _reactor and hasattr(_reactor, "seconds"):
- return _reactor.seconds()
- else:
- return time.time()
-
-def formatInterval(eta):
- eta_parts = []
- if eta > 3600:
- eta_parts.append("%d hrs" % (eta / 3600))
- eta %= 3600
- if eta > 60:
- eta_parts.append("%d mins" % (eta / 60))
- eta %= 60
- eta_parts.append("%d secs" % eta)
- return ", ".join(eta_parts)
-
-class ComparableMixin:
-
- compare_attrs = []
-
- class _None:
- pass
-
- def __hash__(self):
- alist = [self.__class__] + \
- [getattr(self, name, self._None) for name in self.compare_attrs]
- return hash(tuple(map(str, alist)))
-
- def __cmp__(self, them):
- result = cmp(type(self), type(them))
- if result:
- return result
-
- result = cmp(self.__class__.__name__, them.__class__.__name__)
- if result:
- return result
-
- result = cmp(self.compare_attrs, them.compare_attrs)
- if result:
- return result
-
- self_list = [getattr(self, name, self._None)
- for name in self.compare_attrs]
- them_list = [getattr(them, name, self._None)
- for name in self.compare_attrs]
- return cmp(self_list, them_list)
-
-def diffSets(old, new):
- if not isinstance(old, set):
- old = set(old)
- if not isinstance(new, set):
- new = set(new)
- return old - new, new - old
-
-# Remove potentially harmful characters from builder name if it is to be
-# used as the build dir.
-badchars_map = string.maketrans("\t !#$%&'()*+,./:;<=>?@[\\]^{|}~",
- "______________________________")
-def safeTranslate(str):
- if isinstance(str, unicode):
- str = str.encode('utf8')
- return str.translate(badchars_map)
-
-def none_or_str(x):
- if x is not None and not isinstance(x, str):
- return str(x)
- return x
-
-# place a working json module at 'buildbot.util.json'. Code is adapted from
-# Paul Wise <pabs@debian.org>:
-# http://lists.debian.org/debian-python/2010/02/msg00016.html
-# json doesn't exist as a standard module until python2.6
-# However python2.6's json module is much slower than simplejson, so we prefer
-# to use simplejson if available.
-try:
- import simplejson as json
- assert json
-except ImportError:
- import json # python 2.6 or 2.7
-try:
- _tmp = json.loads
-except AttributeError:
- import warnings
- import sys
- warnings.warn("Use simplejson, not the old json module.")
- sys.modules.pop('json') # get rid of the bad json module
- import simplejson as json
-
-# changes and schedulers consider None to be a legitimate name for a branch,
-# which makes default function keyword arguments hard to handle. This value
-# is always false.
-class NotABranch:
- def __nonzero__(self):
- return False
-NotABranch = NotABranch()
-
-# time-handling methods
-
-class UTC(datetime.tzinfo):
- """Simple definition of UTC timezone"""
- def utcoffset(self, dt):
- return datetime.timedelta(0)
-
- def dst(self, dt):
- return datetime.timedelta(0)
-
- def tzname(self):
- return "UTC"
-UTC = UTC()
-
-def epoch2datetime(epoch):
- """Convert a UNIX epoch time to a datetime object, in the UTC timezone"""
- if epoch is not None:
- return datetime.datetime.fromtimestamp(epoch, tz=UTC)
-
-def datetime2epoch(dt):
- """Convert a non-naive datetime object to a UNIX epoch timestamp"""
- if dt is not None:
- return calendar.timegm(dt.utctimetuple())
-
-def makeList(input):
- if isinstance(input, basestring):
- return [ input ]
- elif input is None:
- return [ ]
- else:
- return list(input)
-
-def in_reactor(f):
- """decorate a function by running it with maybeDeferred in a reactor"""
- def wrap(*args, **kwargs):
- from twisted.internet import reactor, defer
- result = [ ]
- def async():
- d = defer.maybeDeferred(f, *args, **kwargs)
- def eb(f):
- f.printTraceback()
- d.addErrback(eb)
- def do_stop(r):
- result.append(r)
- reactor.stop()
- d.addBoth(do_stop)
- reactor.callWhenRunning(async)
- reactor.run()
- return result[0]
- wrap.__doc__ = f.__doc__
- wrap.__name__ = f.__name__
- wrap._orig = f # for tests
- return wrap
-
-__all__ = [
- 'naturalSort', 'now', 'formatInterval', 'ComparableMixin', 'json',
- 'safeTranslate', 'LRUCache', 'none_or_str',
- 'NotABranch', 'deferredLocked', 'SerializedInvocation', 'UTC',
- 'diffLists', 'makeList', 'in_reactor' ]
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/bbcollections.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/bbcollections.py
deleted file mode 100644
index 96e0eb27..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/bbcollections.py
+++ /dev/null
@@ -1,40 +0,0 @@
-# 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
-
-# this is here for compatibility
-from collections import defaultdict
-assert defaultdict
-
-class KeyedSets:
- def __init__(self):
- self.d = dict()
- def add(self, key, value):
- if key not in self.d:
- self.d[key] = set()
- self.d[key].add(value)
- def discard(self, key, value):
- if key in self.d:
- self.d[key].discard(value)
- if not self.d[key]:
- del self.d[key]
- def __contains__(self, key):
- return key in self.d
- def __getitem__(self, key):
- return self.d.get(key, set())
- def pop(self, key):
- if key in self.d:
- return self.d.pop(key)
- return set()
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/croniter.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/croniter.py
deleted file mode 100644
index 21ffca58..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/croniter.py
+++ /dev/null
@@ -1,311 +0,0 @@
-# Copied from croniter
-# https://github.com/taichino/croniter
-# Licensed under MIT license
-# Pyflakes warnings corrected
-
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-
-import re
-from time import time, mktime
-from datetime import datetime
-from dateutil.relativedelta import relativedelta
-
-search_re = re.compile(r'^([^-]+)-([^-/]+)(/(.*))?$')
-only_int_re = re.compile(r'^\d+$')
-any_int_re = re.compile(r'^\d+')
-star_or_int_re = re.compile(r'^(\d+|\*)$')
-
-__all__ = ('croniter',)
-
-
-class croniter(object):
- RANGES = (
- (0, 59),
- (0, 23),
- (1, 31),
- (1, 12),
- (0, 6),
- (0, 59)
- )
- DAYS = (
- 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
- )
-
- ALPHACONV = (
- { },
- { },
- { },
- { 'jan':1, 'feb':2, 'mar':3, 'apr':4, 'may':5, 'jun':6,
- 'jul':7, 'aug':8, 'sep':9, 'oct':10, 'nov':11, 'dec':12 },
- { 'sun':0, 'mon':1, 'tue':2, 'wed':3, 'thu':4, 'fri':5, 'sat':0 },
- { }
- )
-
- LOWMAP = (
- {},
- {},
- {0: 1},
- {0: 1},
- {7: 0},
- {},
- )
-
- bad_length = 'Exactly 5 or 6 columns has to be specified for iterator' \
- 'expression.'
-
- def __init__(self, expr_format, start_time=time()):
- if isinstance(start_time, datetime):
- start_time = mktime(start_time.timetuple())
-
- self.cur = start_time
- self.exprs = expr_format.split()
-
- if len(self.exprs) != 5 and len(self.exprs) != 6:
- raise ValueError(self.bad_length)
-
- expanded = []
-
- for i, expr in enumerate(self.exprs):
- e_list = expr.split(',')
- res = []
-
- while len(e_list) > 0:
- e = e_list.pop()
- t = re.sub(r'^\*(/.+)$', r'%d-%d\1' % (self.RANGES[i][0],
- self.RANGES[i][1]),
- str(e))
- m = search_re.search(t)
-
- if m:
- (low, high, step) = m.group(1), m.group(2), m.group(4) or 1
-
- if not any_int_re.search(low):
- low = self.ALPHACONV[i][low.lower()]
-
- if not any_int_re.search(high):
- high = self.ALPHACONV[i][high.lower()]
-
- if (not low or not high or int(low) > int(high)
- or not only_int_re.search(str(step))):
- raise ValueError("[%s] is not acceptable" %expr_format)
-
- for j in xrange(int(low), int(high)+1):
- if j % int(step) == 0:
- e_list.append(j)
- else:
- if not star_or_int_re.search(t):
- t = self.ALPHACONV[i][t.lower()]
-
- try:
- t = int(t)
- except:
- pass
-
- if t in self.LOWMAP[i]:
- t = self.LOWMAP[i][t]
-
- if t != '*' and (int(t) < self.RANGES[i][0] or
- int(t) > self.RANGES[i][1]):
- raise ValueError("[%s] is not acceptable, out of range" % expr_format)
-
- res.append(t)
-
- res.sort()
- expanded.append(['*'] if (len(res) == 1 and res[0] == '*') else res)
- self.expanded = expanded
-
- def get_next(self, ret_type=float):
- return self._get_next(ret_type, is_prev=False)
-
- def get_prev(self, ret_type=float):
- return self._get_next(ret_type, is_prev=True)
-
- def _get_next(self, ret_type=float, is_prev=False):
- expanded = self.expanded[:]
-
- if ret_type not in (float, datetime):
- raise TypeError("Invalid ret_type, only 'float' or 'datetime' " \
- "is acceptable.")
-
- if expanded[2][0] != '*' and expanded[4][0] != '*':
- bak = expanded[4]
- expanded[4] = ['*']
- t1 = self._calc(self.cur, expanded, is_prev)
- expanded[4] = bak
- expanded[2] = ['*']
-
- t2 = self._calc(self.cur, expanded, is_prev)
- if not is_prev:
- result = t1 if t1 < t2 else t2
- else:
- result = t1 if t1 > t2 else t2
- else:
- result = self._calc(self.cur, expanded, is_prev)
- self.cur = result
-
- if ret_type == datetime:
- result = datetime.fromtimestamp(result)
- return result
-
- def _calc(self, now, expanded, is_prev):
- if is_prev:
- nearest_diff_method = self._get_prev_nearest_diff
- sign = -1
- else:
- nearest_diff_method = self._get_next_nearest_diff
- sign = 1
-
- offset = len(expanded) == 6 and 1 or 60
- dst = now = datetime.fromtimestamp(now + sign * offset)
-
- day, month, year = dst.day, dst.month, dst.year
- current_year = now.year
- DAYS = self.DAYS
-
- def proc_month(d):
- if expanded[3][0] != '*':
- diff_month = nearest_diff_method(d.month, expanded[3], 12)
- days = DAYS[month - 1]
- if month == 2 and self.is_leap(year) == True:
- days += 1
-
- reset_day = days if is_prev else 1
-
- if diff_month != None and diff_month != 0:
- if is_prev:
- d += relativedelta(months=diff_month)
- else:
- d += relativedelta(months=diff_month, day=reset_day,
- hour=0, minute=0, second=0)
- return True, d
- return False, d
-
- def proc_day_of_month(d):
- if expanded[2][0] != '*':
- days = DAYS[month - 1]
- if month == 2 and self.is_leap(year) == True:
- days += 1
-
- diff_day = nearest_diff_method(d.day, expanded[2], days)
-
- if diff_day != None and diff_day != 0:
- if is_prev:
- d += relativedelta(days=diff_day)
- else:
- d += relativedelta(days=diff_day, hour=0, minute=0, second=0)
- return True, d
- return False, d
-
- def proc_day_of_week(d):
- if expanded[4][0] != '*':
- diff_day_of_week = nearest_diff_method(d.isoweekday() % 7, expanded[4], 7)
- if diff_day_of_week != None and diff_day_of_week != 0:
- if is_prev:
- d += relativedelta(days=diff_day_of_week)
- else:
- d += relativedelta(days=diff_day_of_week, hour=0, minute=0, second=0)
- return True, d
- return False, d
-
- def proc_hour(d):
- if expanded[1][0] != '*':
- diff_hour = nearest_diff_method(d.hour, expanded[1], 24)
- if diff_hour != None and diff_hour != 0:
- if is_prev:
- d += relativedelta(hours = diff_hour)
- else:
- d += relativedelta(hours = diff_hour, minute=0, second=0)
- return True, d
- return False, d
-
- def proc_minute(d):
- if expanded[0][0] != '*':
- diff_min = nearest_diff_method(d.minute, expanded[0], 60)
- if diff_min != None and diff_min != 0:
- if is_prev:
- d += relativedelta(minutes = diff_min)
- else:
- d += relativedelta(minutes = diff_min, second=0)
- return True, d
- return False, d
-
- def proc_second(d):
- if len(expanded) == 6:
- if expanded[5][0] != '*':
- diff_sec = nearest_diff_method(d.second, expanded[5], 60)
- if diff_sec != None and diff_sec != 0:
- d += relativedelta(seconds = diff_sec)
- return True, d
- else:
- d += relativedelta(second = 0)
- return False, d
-
- if is_prev:
- procs = [proc_second,
- proc_minute,
- proc_hour,
- proc_day_of_week,
- proc_day_of_month,
- proc_month]
- else:
- procs = [proc_month,
- proc_day_of_month,
- proc_day_of_week,
- proc_hour,
- proc_minute,
- proc_second]
-
- while abs(year - current_year) <= 1:
- next = False
- for proc in procs:
- (changed, dst) = proc(dst)
- if changed:
- next = True
- break
- if next:
- continue
- return mktime(dst.timetuple())
-
- raise "failed to find prev date"
-
- def _get_next_nearest(self, x, to_check):
- small = [item for item in to_check if item < x]
- large = [item for item in to_check if item >= x]
- large.extend(small)
- return large[0]
-
- def _get_prev_nearest(self, x, to_check):
- small = [item for item in to_check if item <= x]
- large = [item for item in to_check if item > x]
- small.reverse()
- large.reverse()
- small.extend(large)
- return small[0]
-
- def _get_next_nearest_diff(self, x, to_check, range_val):
- for i, d in enumerate(to_check):
- if d >= x:
- return d - x
- return to_check[0] - x + range_val
-
- def _get_prev_nearest_diff(self, x, to_check, range_val):
- candidates = to_check[:]
- candidates.reverse()
- for d in candidates:
- if d <= x:
- return d - x
- return (candidates[0]) - x - range_val
-
- def is_leap(self, year):
- if year % 400 == 0 or (year % 4 == 0 and year % 100 != 0):
- return True
- else:
- return False
-
-if __name__ == '__main__':
-
- base = datetime(2010, 1, 25)
- itr = croniter('0 0 1 * *', base)
- n1 = itr.get_next(datetime)
- print n1
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/eventual.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/eventual.py
deleted file mode 100644
index 15fba6cf..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/eventual.py
+++ /dev/null
@@ -1,85 +0,0 @@
-# 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
-
-
-# copied from foolscap
-
-from twisted.internet import reactor, defer
-from twisted.python import log
-
-class _SimpleCallQueue(object):
-
- _reactor = reactor
-
- def __init__(self):
- self._events = []
- self._flushObservers = []
- self._timer = None
- self._in_turn = False
-
- def append(self, cb, args, kwargs):
- self._events.append((cb, args, kwargs))
- if not self._timer:
- self._timer = self._reactor.callLater(0, self._turn)
-
- def _turn(self):
- self._timer = None
- self._in_turn = True
- # flush all the messages that are currently in the queue. If anything
- # gets added to the queue while we're doing this, those events will
- # be put off until the next turn.
- events, self._events = self._events, []
- for cb, args, kwargs in events:
- try:
- cb(*args, **kwargs)
- except:
- log.err()
- self._in_turn = False
- if self._events and not self._timer:
- self._timer = self._reactor.callLater(0, self._turn)
- if not self._events:
- observers, self._flushObservers = self._flushObservers, []
- for o in observers:
- o.callback(None)
-
- def flush(self):
- if not self._events and not self._in_turn:
- return defer.succeed(None)
- d = defer.Deferred()
- self._flushObservers.append(d)
- return d
-
-
-_theSimpleQueue = _SimpleCallQueue()
-
-def eventually(cb, *args, **kwargs):
- _theSimpleQueue.append(cb, args, kwargs)
-
-
-def fireEventually(value=None):
- d = defer.Deferred()
- eventually(d.callback, value)
- return d
-
-def flushEventualQueue(_ignored=None):
- return _theSimpleQueue.flush()
-
-def _setReactor(r=None):
- # This sets the reactor used to schedule future events to r. If r is None
- # (the default), the reactor is reset to its default value.
- # This should only be used for unit tests.
- if r is None:
- r = reactor
- _theSimpleQueue._reactor = r
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/lru.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/lru.py
deleted file mode 100644
index d7ae14b7..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/lru.py
+++ /dev/null
@@ -1,232 +0,0 @@
-# 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
-
-from weakref import WeakValueDictionary
-from itertools import ifilterfalse
-from twisted.python import log
-from twisted.internet import defer
-from collections import deque
-from collections import defaultdict
-
-
-class LRUCache(object):
- """
- A least-recently-used cache, with a fixed maximum size.
-
- See buildbot manual for more information.
- """
-
- __slots__ = ('max_size max_queue miss_fn queue cache weakrefs '
- 'refcount hits refhits misses'.split())
- sentinel = object()
- QUEUE_SIZE_FACTOR = 10
-
- def __init__(self, miss_fn, max_size=50):
- self.max_size = max_size
- self.max_queue = max_size * self.QUEUE_SIZE_FACTOR
- self.queue = deque()
- self.cache = {}
- self.weakrefs = WeakValueDictionary()
- self.hits = self.misses = self.refhits = 0
- self.refcount = defaultdict(lambda : 0)
- self.miss_fn = miss_fn
-
- def put(self, key, value):
- if key in self.cache:
- self.cache[key] = value
- self.weakrefs[key] = value
- elif key in self.weakrefs:
- self.weakrefs[key] = value
-
- def get(self, key, **miss_fn_kwargs):
- try:
- return self._get_hit(key)
- except KeyError:
- pass
-
- self.misses += 1
-
- result = self.miss_fn(key, **miss_fn_kwargs)
- if result is not None:
- self.cache[key] = result
- self.weakrefs[key] = result
- self._ref_key(key)
- self._purge()
-
- return result
-
- def keys(self):
- return self.cache.keys()
-
- def set_max_size(self, max_size):
- if self.max_size == max_size:
- return
-
- self.max_size = max_size
- self.max_queue = max_size * self.QUEUE_SIZE_FACTOR
- self._purge()
-
- def inv(self):
- global inv_failed
-
- # the keys of the queue and cache should be identical
- cache_keys = set(self.cache.keys())
- queue_keys = set(self.queue)
- if queue_keys - cache_keys:
- log.msg("INV: uncached keys in queue:", queue_keys - cache_keys)
- inv_failed = True
- if cache_keys - queue_keys:
- log.msg("INV: unqueued keys in cache:", cache_keys - queue_keys)
- inv_failed = True
-
- # refcount should always represent the number of times each key appears
- # in the queue
- exp_refcount = dict()
- for k in self.queue:
- exp_refcount[k] = exp_refcount.get(k, 0) + 1
- if exp_refcount != self.refcount:
- log.msg("INV: refcounts differ:")
- log.msg(" expected:", sorted(exp_refcount.items()))
- log.msg(" got:", sorted(self.refcount.items()))
- inv_failed = True
-
- def _ref_key(self, key):
- """Record a reference to the argument key."""
- queue = self.queue
- refcount = self.refcount
-
- queue.append(key)
- refcount[key] = refcount[key] + 1
-
- # periodically compact the queue by eliminating duplicate keys
- # while preserving order of most recent access. Note that this
- # is only required when the cache does not exceed its maximum
- # size
- if len(queue) > self.max_queue:
- refcount.clear()
- queue_appendleft = queue.appendleft
- queue_appendleft(self.sentinel)
- for k in ifilterfalse(refcount.__contains__,
- iter(queue.pop, self.sentinel)):
- queue_appendleft(k)
- refcount[k] = 1
-
- def _get_hit(self, key):
- """Try to do a value lookup from the existing cache entries."""
- try:
- result = self.cache[key]
- self.hits += 1
- self._ref_key(key)
- return result
- except KeyError:
- pass
-
- result = self.weakrefs[key]
- self.refhits += 1
- self.cache[key] = result
- self._ref_key(key)
- return result
-
- def _purge(self):
- """
- Trim the cache down to max_size by evicting the
- least-recently-used entries.
- """
- if len(self.cache) <= self.max_size:
- return
-
- cache = self.cache
- refcount = self.refcount
- queue = self.queue
- max_size = self.max_size
-
- # purge least recently used entries, using refcount to count entries
- # that appear multiple times in the queue
- while len(cache) > max_size:
- refc = 1
- while refc:
- k = queue.popleft()
- refc = refcount[k] = refcount[k] - 1
- del cache[k]
- del refcount[k]
-
-
-class AsyncLRUCache(LRUCache):
- """
- An LRU cache with asynchronous locking to ensure that in the common case of
- multiple concurrent requests for the same key, only one fetch is performed.
- """
-
- __slots__ = ['concurrent']
-
- def __init__(self, miss_fn, max_size=50):
- LRUCache.__init__(self, miss_fn, max_size=max_size)
- self.concurrent = {}
-
- def get(self, key, **miss_fn_kwargs):
- try:
- result = self._get_hit(key)
- return defer.succeed(result)
- except KeyError:
- pass
-
- concurrent = self.concurrent
- conc = concurrent.get(key)
- if conc:
- self.hits += 1
- d = defer.Deferred()
- conc.append(d)
- return d
-
- # if we're here, we've missed and need to fetch
- self.misses += 1
-
- # create a list of waiting deferreds for this key
- d = defer.Deferred()
- assert key not in concurrent
- concurrent[key] = [ d ]
-
- miss_d = self.miss_fn(key, **miss_fn_kwargs)
-
- def handle_result(result):
- if result is not None:
- self.cache[key] = result
- self.weakrefs[key] = result
-
- # reference the key once, possibly standing in for multiple
- # concurrent accesses
- self._ref_key(key)
-
- self._purge()
-
- # and fire all of the waiting Deferreds
- dlist = concurrent.pop(key)
- for d in dlist:
- d.callback(result)
-
- def handle_failure(f):
- # errback all of the waiting Deferreds
- dlist = concurrent.pop(key)
- for d in dlist:
- d.errback(f)
-
- miss_d.addCallbacks(handle_result, handle_failure)
- miss_d.addErrback(log.err)
-
- return d
-
-
-# for tests
-inv_failed = False
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/maildir.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/maildir.py
deleted file mode 100644
index 66e895b3..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/maildir.py
+++ /dev/null
@@ -1,142 +0,0 @@
-# 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
-
-
-# This is a class which watches a maildir for new messages. It uses the
-# linux dirwatcher API (if available) to look for new files. The
-# .messageReceived method is invoked with the filename of the new message,
-# relative to the top of the maildir (so it will look like "new/blahblah").
-
-import os
-from twisted.python import log, runtime
-from twisted.application import service, internet
-from twisted.internet import reactor, defer
-dnotify = None
-try:
- import dnotify
-except:
- log.msg("unable to import dnotify, so Maildir will use polling instead")
-
-class NoSuchMaildir(Exception):
- pass
-
-class MaildirService(service.MultiService):
- pollinterval = 10 # only used if we don't have DNotify
-
- def __init__(self, basedir=None):
- service.MultiService.__init__(self)
- if basedir:
- self.setBasedir(basedir)
- self.files = []
- self.dnotify = None
- self.timerService = None
-
- def setBasedir(self, basedir):
- # some users of MaildirService (scheduler.Try_Jobdir, in particular)
- # don't know their basedir until setServiceParent, since it is
- # relative to the buildmaster's basedir. So let them set it late. We
- # don't actually need it until our own startService.
- self.basedir = basedir
- self.newdir = os.path.join(self.basedir, "new")
- self.curdir = os.path.join(self.basedir, "cur")
-
- def startService(self):
- service.MultiService.startService(self)
- if not os.path.isdir(self.newdir) or not os.path.isdir(self.curdir):
- raise NoSuchMaildir("invalid maildir '%s'" % self.basedir)
- try:
- if dnotify:
- # we must hold an fd open on the directory, so we can get
- # notified when it changes.
- self.dnotify = dnotify.DNotify(self.newdir,
- self.dnotify_callback,
- [dnotify.DNotify.DN_CREATE])
- except (IOError, OverflowError):
- # IOError is probably linux<2.4.19, which doesn't support
- # dnotify. OverflowError will occur on some 64-bit machines
- # because of a python bug
- log.msg("DNotify failed, falling back to polling")
- if not self.dnotify:
- self.timerService = internet.TimerService(self.pollinterval, self.poll)
- self.timerService.setServiceParent(self)
- self.poll()
-
-
- def dnotify_callback(self):
- log.msg("dnotify noticed something, now polling")
-
- # give it a moment. I found that qmail had problems when the message
- # was removed from the maildir instantly. It shouldn't, that's what
- # maildirs are made for. I wasn't able to eyeball any reason for the
- # problem, and safecat didn't behave the same way, but qmail reports
- # "Temporary_error_on_maildir_delivery" (qmail-local.c:165,
- # maildir_child() process exited with rc not in 0,2,3,4). Not sure
- # why, and I'd have to hack qmail to investigate further, so it's
- # easier to just wait a second before yanking the message out of new/
-
- reactor.callLater(0.1, self.poll)
-
-
- def stopService(self):
- if self.dnotify:
- self.dnotify.remove()
- self.dnotify = None
- if self.timerService is not None:
- self.timerService.disownServiceParent()
- self.timerService = None
- return service.MultiService.stopService(self)
-
- @defer.inlineCallbacks
- def poll(self):
- try:
- assert self.basedir
- # see what's new
- for f in self.files:
- if not os.path.isfile(os.path.join(self.newdir, f)):
- self.files.remove(f)
- newfiles = []
- for f in os.listdir(self.newdir):
- if not f in self.files:
- newfiles.append(f)
- self.files.extend(newfiles)
- for n in newfiles:
- try:
- yield self.messageReceived(n)
- except:
- log.err(None, "while reading '%s' from maildir '%s':" % (n, self.basedir))
- except Exception:
- log.err(None, "while polling maildir '%s':" % (self.basedir,))
-
- def moveToCurDir(self, filename):
- if runtime.platformType == "posix":
- # open the file before moving it, because I'm afraid that once
- # it's in cur/, someone might delete it at any moment
- path = os.path.join(self.newdir, filename)
- f = open(path, "r")
- os.rename(os.path.join(self.newdir, filename),
- os.path.join(self.curdir, filename))
- elif runtime.platformType == "win32":
- # do this backwards under windows, because you can't move a file
- # that somebody is holding open. This was causing a Permission
- # Denied error on bear's win32-twisted1.3 buildslave.
- os.rename(os.path.join(self.newdir, filename),
- os.path.join(self.curdir, filename))
- path = os.path.join(self.curdir, filename)
- f = open(path, "r")
-
- return f
-
- def messageReceived(self, filename):
- raise NotImplementedError
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/misc.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/misc.py
deleted file mode 100644
index b869a5d5..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/misc.py
+++ /dev/null
@@ -1,69 +0,0 @@
-# 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
-
-"""
-Miscellaneous utilities; these should be imported from C{buildbot.util}, not
-directly from this module.
-"""
-
-from twisted.python import log
-from twisted.internet import defer
-
-def deferredLocked(lock_or_attr):
- def decorator(fn):
- def wrapper(*args, **kwargs):
- lock = lock_or_attr
- if isinstance(lock, basestring):
- lock = getattr(args[0], lock)
- return lock.run(fn, *args, **kwargs)
- return wrapper
- return decorator
-
-class SerializedInvocation(object):
- def __init__(self, method):
- self.method = method
- self.running = False
- self.pending_deferreds = []
-
- def __call__(self):
- d = defer.Deferred()
- self.pending_deferreds.append(d)
- if not self.running:
- self.start()
- return d
-
- def start(self):
- self.running = True
- invocation_deferreds = self.pending_deferreds
- self.pending_deferreds = []
- d = self.method()
- d.addErrback(log.err, 'in invocation of %r' % (self.method,))
-
- def notify_callers(_):
- for d in invocation_deferreds:
- d.callback(None)
- d.addCallback(notify_callers)
-
- def next(_):
- self.running = False
- if self.pending_deferreds:
- self.start()
- else:
- self._quiet()
- d.addBoth(next)
-
- def _quiet(self): # hook for tests
- pass
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/netstrings.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/netstrings.py
deleted file mode 100644
index 47ff0623..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/netstrings.py
+++ /dev/null
@@ -1,60 +0,0 @@
-# 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
-
-from twisted.protocols import basic
-from zope.interface import implements
-from twisted.internet.interfaces import IAddress, ITransport
-
-class NullAddress(object):
- "an address for NullTransport"
- implements(IAddress)
-
-class NullTransport(object):
- "a do-nothing transport to make NetstringReceiver happy"
- implements(ITransport)
- def write(self, data): raise NotImplementedError
- def writeSequence(self, data): raise NotImplementedError
- def loseConnection(self): pass
- def getPeer(self):
- return NullAddress
- def getHost(self):
- return NullAddress
-
-class NetstringParser(basic.NetstringReceiver):
- """
- Adapts the Twisted netstring support (which assumes it is on a socket) to
- work on simple strings, too. Call the C{feed} method with arbitrary blocks
- of data, and override the C{stringReceived} method to get called for each
- embedded netstring. The default implementation collects the netstrings in
- the list C{self.strings}.
- """
-
- def __init__(self):
- # most of the complexity here is stubbing out the transport code so
- # that Twisted-10.2.0 and higher believes that this is a valid protocol
- self.makeConnection(NullTransport())
- self.strings = []
-
- def feed(self, data):
- """
- """
- self.dataReceived(data)
- # dataReceived handles errors unusually quietly!
- if self.brokenPeer:
- raise basic.NetstringParseError
-
- def stringReceived(self, string):
- self.strings.append(string)
-
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/sautils.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/sautils.py
deleted file mode 100644
index d05cc3da..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/sautils.py
+++ /dev/null
@@ -1,42 +0,0 @@
-# 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
-from sqlalchemy.ext import compiler
-from sqlalchemy.sql.expression import Executable, ClauseElement
-
-# from http://www.sqlalchemy.org/docs/core/compiler.html#compiling-sub-elements-of-a-custom-expression-construct
-
-class InsertFromSelect(Executable, ClauseElement):
- def __init__(self, table, select):
- self.table = table
- self.select = select
-
-@compiler.compiles(InsertFromSelect)
-def _visit_insert_from_select(element, compiler, **kw):
- return "INSERT INTO %s %s" % (
- compiler.process(element.table, asfrom=True),
- compiler.process(element.select)
- )
-
-def sa_version():
- if hasattr(sa, '__version__'):
- def tryint(s):
- try:
- return int(s)
- except:
- return -1
- return tuple(map(tryint, sa.__version__.split('.')))
- return (0,0,0) # "it's old"
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/state.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/state.py
deleted file mode 100644
index 509f6527..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/state.py
+++ /dev/null
@@ -1,26 +0,0 @@
-from twisted.internet import defer
-
-class StateMixin(object):
- ## state management
-
- _objectid = None
-
- @defer.inlineCallbacks
- def getState(self, *args, **kwargs):
- # get the objectid, if not known
- if self._objectid is None:
- self._objectid = yield self.master.db.state.getObjectId(self.name,
- self.__class__.__name__)
-
- rv = yield self.master.db.state.getState(self._objectid, *args,
- **kwargs)
- defer.returnValue(rv)
-
- @defer.inlineCallbacks
- def setState(self, key, value):
- # get the objectid, if not known
- if self._objectid is None:
- self._objectid = yield self.master.db.state.getObjectId(self.name,
- self.__class__.__name__)
-
- yield self.master.db.state.setState(self._objectid, key, value)
diff --git a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/subscription.py b/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/subscription.py
deleted file mode 100644
index 85ed7de4..00000000
--- a/lib/python2.7/site-packages/buildbot-0.8.8-py2.7.egg/buildbot/util/subscription.py
+++ /dev/null
@@ -1,48 +0,0 @@
-# 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
-
-from twisted.python import failure, log
-
-class SubscriptionPoint(object):
- def __init__(self, name):
- self.name = name
- self.subscriptions = set()
-
- def __str__(self):
- return "<SubscriptionPoint '%s'>" % self.name
-
- def subscribe(self, callback):
- sub = Subscription(self, callback)
- self.subscriptions.add(sub)
- return sub
-
- def deliver(self, *args, **kwargs):
- for sub in list(self.subscriptions):
- try:
- sub.callback(*args, **kwargs)
- except:
- log.err(failure.Failure(),
- 'while invoking callback %s to %s' % (sub.callback, self))
-
- def _unsubscribe(self, subscription):
- self.subscriptions.remove(subscription)
-
-class Subscription(object):
- def __init__(self, subpt, callback):
- self.subpt = subpt
- self.callback = callback
-
- def unsubscribe(self):
- self.subpt._unsubscribe(self)