diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 93d5ff0a963c38c90710ba658a40031da9a6d926..3e161ee9bede69e9d7f09aec4a65bbdaa7dc0647 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -10040,6 +10040,7 @@ class LUTestJobqueue(NoHooksLU):
     self.LogInfo("Executing")
 
     if self.op.log_messages:
+      self._Notify(False, constants.JQT_STARTMSG, len(self.op.log_messages))
       for idx, msg in enumerate(self.op.log_messages):
         self.LogInfo("Sending log message %s", idx + 1)
         feedback_fn(constants.JQT_MSGPREFIX + msg)
diff --git a/lib/constants.py b/lib/constants.py
index e13df8edcc678a383884dbdb790d934b40883043..ce4c6f1b18b95b5bd109ec00a4ba0efd13e64642 100644
--- a/lib/constants.py
+++ b/lib/constants.py
@@ -843,10 +843,12 @@ JQT_MSGPREFIX = "TESTMSG="
 JQT_EXPANDNAMES = "expandnames"
 JQT_EXEC = "exec"
 JQT_LOGMSG = "logmsg"
+JQT_STARTMSG = "startmsg"
 JQT_ALL = frozenset([
   JQT_EXPANDNAMES,
   JQT_EXEC,
   JQT_LOGMSG,
+  JQT_STARTMSG,
   ])
 
 # max dynamic devices
diff --git a/scripts/gnt-debug b/scripts/gnt-debug
index f945cd257c5b01a8eaa21940780979f36941cad3..944ccdc0f8bf19924037f48afaa7df9ada52c8cc 100755
--- a/scripts/gnt-debug
+++ b/scripts/gnt-debug
@@ -164,14 +164,16 @@ class _JobQueueTestReporter(cli.StdioJobPollReportCb):
 
     """
     cli.StdioJobPollReportCb.__init__(self)
-    self._testmsgs = []
+    self._expected_msgcount = 0
+    self._all_testmsgs = []
+    self._testmsgs = None
     self._job_id = None
 
   def GetTestMessages(self):
     """Returns all test log messages received so far.
 
     """
-    return self._testmsgs
+    return self._all_testmsgs
 
   def GetJobId(self):
     """Returns the job ID.
@@ -195,7 +197,12 @@ class _JobQueueTestReporter(cli.StdioJobPollReportCb):
 
     elif (log_type == constants.ELOG_MESSAGE and
           log_msg.startswith(constants.JQT_MSGPREFIX)):
-      self._testmsgs.append(log_msg[len(constants.JQT_MSGPREFIX):])
+      if self._testmsgs is None:
+        raise errors.OpExecError("Received test message without a preceding"
+                                 " start message")
+      testmsg = log_msg[len(constants.JQT_MSGPREFIX):]
+      self._testmsgs.append(testmsg)
+      self._all_testmsgs.append(testmsg)
       return
 
     return cli.StdioJobPollReportCb.ReportLogMessage(self, job_id, serial,
@@ -236,7 +243,10 @@ class _JobQueueTestReporter(cli.StdioJobPollReportCb):
                                    " not '%s' as expected" %
                                    (status, constants.JOB_STATUS_RUNNING))
 
-      if test == constants.JQT_LOGMSG:
+      if test == constants.JQT_STARTMSG:
+        logging.debug("Expecting %s test messages", arg)
+        self._testmsgs = []
+      elif test == constants.JQT_LOGMSG:
         if len(self._testmsgs) != arg:
           raise errors.OpExecError("Received %s test messages when %s are"
                                    " expected" % (len(self._testmsgs), arg))
@@ -249,47 +259,120 @@ def TestJobqueue(opts, _):
   """Runs a few tests on the job queue.
 
   """
-  test_messages = [
-    "Hello World",
-    "A",
-    "",
-    "B"
-    "Foo|bar|baz",
-    utils.TimestampForFilename(),
-    ]
-
-  for fail in [False, True]:
-    if fail:
-      ToStdout("Testing job failure")
+  (TM_SUCCESS,
+   TM_MULTISUCCESS,
+   TM_FAIL,
+   TM_PARTFAIL) = range(4)
+  TM_ALL = frozenset([TM_SUCCESS, TM_MULTISUCCESS, TM_FAIL, TM_PARTFAIL])
+
+  for mode in TM_ALL:
+    test_messages = [
+      "Testing mode %s" % mode,
+      "Hello World",
+      "A",
+      "",
+      "B"
+      "Foo|bar|baz",
+      utils.TimestampForFilename(),
+      ]
+
+    fail = mode in (TM_FAIL, TM_PARTFAIL)
+
+    if mode == TM_PARTFAIL:
+      ToStdout("Testing partial job failure")
+      ops = [
+        opcodes.OpTestJobqueue(notify_waitlock=True, notify_exec=True,
+                               log_messages=test_messages, fail=False),
+        opcodes.OpTestJobqueue(notify_waitlock=True, notify_exec=True,
+                               log_messages=test_messages, fail=False),
+        opcodes.OpTestJobqueue(notify_waitlock=True, notify_exec=True,
+                               log_messages=test_messages, fail=True),
+        opcodes.OpTestJobqueue(notify_waitlock=True, notify_exec=True,
+                               log_messages=test_messages, fail=False),
+        ]
+      expect_messages = 3 * [test_messages]
+      expect_opstatus = [
+        constants.OP_STATUS_SUCCESS,
+        constants.OP_STATUS_SUCCESS,
+        constants.OP_STATUS_ERROR,
+        constants.OP_STATUS_ERROR,
+        ]
+      expect_resultlen = 2
+    elif mode == TM_MULTISUCCESS:
+      ToStdout("Testing multiple successful opcodes")
+      ops = [
+        opcodes.OpTestJobqueue(notify_waitlock=True, notify_exec=True,
+                               log_messages=test_messages, fail=False),
+        opcodes.OpTestJobqueue(notify_waitlock=True, notify_exec=True,
+                               log_messages=test_messages, fail=False),
+        ]
+      expect_messages = 2 * [test_messages]
+      expect_opstatus = [
+        constants.OP_STATUS_SUCCESS,
+        constants.OP_STATUS_SUCCESS,
+        ]
+      expect_resultlen = 2
     else:
-      ToStdout("Testing job success")
-
-    op = opcodes.OpTestJobqueue(notify_waitlock=True,
-                                notify_exec=True,
-                                log_messages=test_messages,
-                                fail=fail)
+      if mode == TM_SUCCESS:
+        ToStdout("Testing job success")
+        expect_opstatus = [constants.OP_STATUS_SUCCESS]
+      elif mode == TM_FAIL:
+        ToStdout("Testing job failure")
+        expect_opstatus = [constants.OP_STATUS_ERROR]
+      else:
+        raise errors.ProgrammerError("Unknown test mode %s" % mode)
+
+      ops = [
+        opcodes.OpTestJobqueue(notify_waitlock=True,
+                               notify_exec=True,
+                               log_messages=test_messages,
+                               fail=fail)
+        ]
+      expect_messages = [test_messages]
+      expect_resultlen = 1
+
+    cl = cli.GetClient()
+    cli.SetGenericOpcodeOpts(ops, opts)
+
+    # Send job to master daemon
+    job_id = cli.SendJob(ops, cl=cl)
 
     reporter = _JobQueueTestReporter()
+    results = None
+
     try:
-      SubmitOpCode(op, reporter=reporter, opts=opts)
-    except errors.OpExecError:
+      results = cli.PollJob(job_id, cl=cl, reporter=reporter)
+    except errors.OpExecError, err:
       if not fail:
         raise
-      # Ignore error
+      ToStdout("Ignoring error: %s", err)
     else:
       if fail:
         raise errors.OpExecError("Job didn't fail when it should")
 
+    # Check length of result
+    if fail:
+      if results is not None:
+        raise errors.OpExecError("Received result from failed job")
+    elif len(results) != expect_resultlen:
+      raise errors.OpExecError("Received %s results (%s), expected %s" %
+                               (len(results), results, expect_resultlen))
+
     # Check received log messages
-    if reporter.GetTestMessages() != test_messages:
+    all_messages = [i for j in expect_messages for i in j]
+    if reporter.GetTestMessages() != all_messages:
       raise errors.OpExecError("Received test messages don't match input"
                                " (input %r, received %r)" %
-                               (test_messages, reporter.GetTestMessages()))
+                               (all_messages, reporter.GetTestMessages()))
 
     # Check final status
-    job_id = reporter.GetJobId()
+    reported_job_id = reporter.GetJobId()
+    if reported_job_id != job_id:
+      raise errors.OpExecError("Reported job ID %s doesn't match"
+                               "submission job ID %s" %
+                               (reported_job_id, job_id))
 
-    jobdetails = cli.GetClient().QueryJobs([job_id], ["status"])[0]
+    jobdetails = cli.GetClient().QueryJobs([job_id], ["status", "opstatus"])[0]
     if not jobdetails:
       raise errors.OpExecError("Can't find job %s" % job_id)
 
@@ -298,10 +381,19 @@ def TestJobqueue(opts, _):
     else:
       exp_status = constants.JOB_STATUS_SUCCESS
 
-    final_status = jobdetails[0]
+    (final_status, final_opstatus) = jobdetails
     if final_status != exp_status:
       raise errors.OpExecError("Final job status is %s, not %s as expected" %
                                (final_status, exp_status))
+    if len(final_opstatus) != len(ops):
+      raise errors.OpExecError("Did not receive status for all opcodes (got %s,"
+                               " expected %s)" %
+                               (len(final_opstatus), len(ops)))
+    if final_opstatus != expect_opstatus:
+      raise errors.OpExecError("Opcode status is %s, expected %s" %
+                               (final_opstatus, expect_opstatus))
+
+  ToStdout("Job queue test successful")
 
   return 0