session manager can crash attempting to remove a phantom dependency

Bug #1444126 reported by Zygmunt Krynicki
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
PlainBox (Toolkit)
Fix Released
Medium
Zygmunt Krynicki

Bug Description

This bug is a continuation of bug 1443895

What, I think, the traceback below is telling me is that the following situation is causing plainbox to crash:

JobA:
 requires JobB

session = SessionState([jobA])
session.update_desired_job_list([JobA])
# This will see that JobB is not know and thus try to fix the issue by removing it. The problem is that JobB doesn't exist and it is JobA that should be removed.

 Traceback (most recent call last):
  File "/home/u/thunderbolt-testing/plainbox/plainbox/impl/depmgr.py", line 275, in _visit
    next_job = self._job_map[job_id]
KeyError: '2013.com.canonical.plainbox::manifest'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/u/thunderbolt-testing/plainbox/plainbox/impl/session/state.py", line 850, in update_desired_job_list
    self._job_list, self._desired_job_list)
  File "/home/u/thunderbolt-testing/plainbox/plainbox/impl/depmgr.py", line 214, in resolve_dependencies
    return cls(job_list)._solve(visit_list)
  File "/home/u/thunderbolt-testing/plainbox/plainbox/impl/depmgr.py", line 247, in _solve
    self._visit(job)
  File "/home/u/thunderbolt-testing/plainbox/plainbox/impl/depmgr.py", line 284, in _visit
    self._visit(next_job, trail)
  File "/home/u/thunderbolt-testing/plainbox/plainbox/impl/depmgr.py", line 277, in _visit
    raise DependencyMissingError(job, job_id, dep_type)
plainbox.impl.depmgr.DependencyMissingError: missing dependency: '2013.com.canonical.plainbox::manifest' (resource)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/u/thunderbolt-testing/plainbox/plainbox/impl/clitools.py", line 560, in dispatch_and_catch_exceptions
    return self.dispatch_command(ns)
  File "/home/u/thunderbolt-testing/plainbox/plainbox/impl/clitools.py", line 556, in dispatch_command
    return ns.command.invoked(ns)
  File "/home/u/thunderbolt-testing/checkbox-ng/checkbox_ng/commands/launcher.py", line 90, in invoked
    self.provider_loader, lambda: self.config, ns, launcher
  File "/home/u/thunderbolt-testing/checkbox-ng/checkbox_ng/commands/newcli.py", line 150, in run
    return self.do_normal_sequence()
  File "/home/u/thunderbolt-testing/checkbox-ng/checkbox_ng/commands/newcli.py", line 198, in do_normal_sequence
    self.interactively_pick_jobs_to_run()
  File "/home/u/thunderbolt-testing/checkbox-ng/checkbox_ng/commands/newcli.py", line 316, in interactively_pick_jobs_to_run
    self.manager.state.job_list, self._qualifier_list))
  File "/home/u/thunderbolt-testing/plainbox/plainbox/impl/commands/inv_run.py", line 908, in _update_desired_job_list
    problem_list = self.state.update_desired_job_list(desired_job_list)
  File "/home/u/thunderbolt-testing/plainbox/plainbox/impl/session/state.py", line 854, in update_desired_job_list
    self._desired_job_list.remove(exc.affected_job)
ValueError: list.remove(x): x not in list

Related branches

Zygmunt Krynicki (zyga)
Changed in plainbox:
status: New → Confirmed
importance: Undecided → Medium
assignee: nobody → Zygmunt Krynicki (zyga)
Zygmunt Krynicki (zyga)
Changed in plainbox:
status: Confirmed → In Progress
milestone: none → 0.21
Revision history for this message
Zygmunt Krynicki (zyga) wrote :

Ah, the code there is correct. It seems the error is only happening when two errors affect the same job so we remove it and then die trying to remove it again.

Revision history for this message
Zygmunt Krynicki (zyga) wrote :

I cannot guess what triggers this. Back to pdb.

Revision history for this message
Zygmunt Krynicki (zyga) wrote :

Exceptions (in state.py:854) happen in this order:

<DependencyMissingError job:<JobDefinition id:'2013.com.canonical.certification::audio/playback_thunderbolt' plugin:'user-interact-verify'> missing_job_id:'2013.com.canonical.certification::manifest' dep_type:'resource'>
<DependencyMissingError job:<JobDefinition id:'2013.com.canonical.certification::thunderbolt/insert' plugin:'user-interact'> missing_job_id:'2013.com.canonical.plainbox::manifest' dep_type:'resource'>
<DependencyMissingError job:<JobDefinition id:'2013.com.canonical.certification::thunderbolt/storage-test' plugin:'shell'> missing_job_id:'2013.com.canonical.plainbox::manifest' dep_type:'resource'>
<DependencyMissingError job:<JobDefinition id:'2013.com.canonical.certification::thunderbolt/remove' plugin:'user-interact'> missing_job_id:'2013.com.canonical.certification::thuderbolt/storage-test' dep_type:'direct'>
<DependencyMissingError job:<JobDefinition id:'2013.com.canonical.certification::monitor/thunderbolt' plugin:'manual'> missing_job_id:'2013.com.canonical.plainbox::manifest' dep_type:'resource'>
<DependencyMissingError job:<JobDefinition id:'2013.com.canonical.certification::thunderbolt/daisy-chain' plugin:'user-interact-verify'> missing_job_id:'2013.com.canonical.plainbox::manifest' dep_type:'resource'>

So there we have it, I get it now. Test case reproducing this looks like this:

+ def test_dont_remove_missing_jobs(self):
+ """ http://pad.lv/1444126 """
+ A = make_job("A", requires="R")
+ B = make_job("B", depends="A")
+ Z = make_job("Z") # unrelated but required
+ state = SessionState([A, B, Z])
+ problems = state.update_desired_job_list([A, B, Z])
+ self.assertEqual(problems, [
+ DependencyMissingError(A, 'R', 'resource'),
+ DependencyMissingError(B, 'A', 'direct'),
+ ])
+ self.assertEqual(state.desired_job_list, [Z])
+ self.assertEqual(state.run_list, [Z])
+

Zygmunt Krynicki (zyga)
Changed in plainbox:
status: In Progress → Fix Committed
Changed in plainbox:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.