Repository: buildbot/buildbot

Issue:
AssertionError when calling try client with --dryrun 
When calling `buildbot try --connect=pb --username=<redacted> --passwd=<redacted> --master=<redacted> --vc=git --wait -n` 
this error occured:
```
using 'pb' connect method
job created
Job:
        Repository: <redacted>
        Project: 
        Branch: b'master'
        Revision: <redacted>
        Builders: None
<redacted>

job has been delivered
Unhandled Error
Traceback (most recent call last):
  File "<redacted>/buildbot/.venv/lib/python3.7/site-packages/twisted/internet/_baseprocess.py", line 64, in maybeCallProcessEnded
    proto.processEnded(Failure(reason))
  File "<redacted>/buildbot/.venv/lib/python3.7/site-packages/twisted/internet/utils.py", line 174, in processEnded
    self.deferred.callback((out, err, code))
  File "<redacted>/buildbot/.venv/lib/python3.7/site-packages/twisted/internet/defer.py", line 460, in callback
    self._startRunCallbacks(result)
  File "<redacted>/buildbot/.venv/lib/python3.7/site-packages/twisted/internet/defer.py", line 568, in _startRunCallbacks
    self._runCallbacks()
--- <exception caught here> ---
  File "<redacted>/buildbot/.venv/lib/python3.7/site-packages/twisted/internet/defer.py", line 654, in _runCallbacks
    current.result = callback(current.result, *args, **kw)
  File "<redacted>/buildbot/master/buildbot/clients/tryclient.py", line 926, in trapSystemExit
    why.trap(SystemExit)
  File "<redacted>/buildbot/.venv/lib/python3.7/site-packages/twisted/python/failure.py", line 460, in trap
    self.raiseException()
  File "<redacted>/buildbot/.venv/lib/python3.7/site-packages/twisted/python/failure.py", line 488, in raiseException
    raise self.value.with_traceback(self.tb)
  File "<redacted>/buildbot/.venv/lib/python3.7/site-packages/twisted/internet/defer.py", line 654, in _runCallbacks
    current.result = callback(current.result, *args, **kw)
  File "<redacted>/buildbot/master/buildbot/clients/tryclient.py", line 914, in <lambda>
    d.addCallback(lambda res: self.getStatus())
  File "<redacted>/buildbot/master/buildbot/clients/tryclient.py", line 720, in getStatus
    assert self.buildsetStatus
builtins.AssertionError: 
```


Discussion:

Resolving patch:
diff --git a/master/buildbot/clients/tryclient.py b/master/buildbot/clients/tryclient.py
--- a/master/buildbot/clients/tryclient.py
+++ b/master/buildbot/clients/tryclient.py
@@ -531,6 +531,13 @@ def processEnded(self, status_object):
         self.d.callback((sig, rc))
 
 
+class FakeBuildSetStatus:
+    def callRemote(self, name):
+        if name == "getBuildRequests":
+            return defer.succeed([])
+        raise NotImplementedError()
+
+
 class Try(pb.Referenceable):
     buildsetStatus = None
     quiet = False
@@ -623,6 +630,7 @@ def fakeDeliverJob(self):
                ss.revision,
                self.builderNames,
                ss.patch[1]))
+        self.buildsetStatus = FakeBuildSetStatus()
         d = defer.Deferred()
         d.callback(True)
         return d
@@ -719,6 +727,8 @@ def getStatus(self):
             self.running = defer.Deferred()
             assert self.buildsetStatus
             self._getStatus_1()
+            if bool(self.config.get("dryrun")):
+                self.statusDone()
             return self.running
         return None
 
@@ -914,7 +924,8 @@ def run(self, _inTests=False):
             d.addCallback(lambda res: self.getStatus())
         d.addErrback(self.trapSystemExit)
         d.addErrback(log.err)
-        d.addCallback(self.cleanup)
+        if not bool(self.config.get("dryrun")):
+            d.addCallback(self.cleanup)
         if _inTests:
             return d
         d.addCallback(lambda res: reactor.stop())


Test patch:
diff --git a/master/buildbot/test/integration/test_try_client.py b/master/buildbot/test/integration/test_try_client.py
--- a/master/buildbot/test/integration/test_try_client.py
+++ b/master/buildbot/test/integration/test_try_client.py
@@ -160,6 +160,34 @@ def test_userpass_wait(self):
         buildsets = yield self.master.db.buildsets.getBuildsets()
         self.assertEqual(len(buildsets), 1)
 
+    @defer.inlineCallbacks
+    def test_userpass_wait_dryrun(self):
+        yield self.startMaster(
+            trysched.Try_Userpass('try', ['a'], 0, [('u', b'p')]))
+        yield self.runClient({
+            'connect': 'pb',
+            'master': '127.0.0.1:{}'.format(self.serverPort),
+            'username': 'u',
+            'passwd': b'p',
+            'wait': True,
+            'dryrun': True,
+        })
+        self.assertEqual(self.output, [
+            "using 'pb' connect method",
+            'job created',
+            'Job:\n'
+            '\tRepository: \n'
+            '\tProject: \n'
+            '\tBranch: br\n'
+            '\tRevision: rr\n'
+            '\tBuilders: None\n'
+            '++--',
+            'job has been delivered',
+            'All Builds Complete',
+        ])
+        buildsets = yield self.master.db.buildsets.getBuildsets()
+        self.assertEqual(len(buildsets), 0)
+
     @defer.inlineCallbacks
     def test_userpass_list_builders(self):
         yield self.startMaster(
diff --git a/master/buildbot/test/integration/test_try_client_e2e.py b/master/buildbot/test/integration/test_try_client_e2e.py
--- a/master/buildbot/test/integration/test_try_client_e2e.py
+++ b/master/buildbot/test/integration/test_try_client_e2e.py
@@ -32,7 +32,7 @@ def test_shell(self):
 
         def trigger_callback():
             def thd():
-                os.system("buildbot try --connect=pb --master=127.0.0.1:8031 -b testy "
+                os.system("buildbot try --connect=pb --master=127.0.0.1:8030 -b testy "
                           "--property=foo:bar --username=alice --passwd=pw1 --vc=none")
             reactor.callInThread(thd)
 
@@ -51,7 +51,7 @@ def masterConfig():
     c['schedulers'] = [
         schedulers.Try_Userpass(name="try",
                                 builderNames=["testy"],
-                                port=8031,
+                                port=8030,
                                 userpass=[("alice", "pw1")])
     ]
     f = BuildFactory()