Prevent task loops using a key instead of equality

Previously task loops were prevented by using contains() on a task which
is not immutable. This is problematic because currently equality as
provided by the Container class is broken as it does not consider
inherited fields, and because using equality of all fields itself has
issues (it considers task visibiliy fields which should not be
considered differentiators) and may not reflect the true policy that we
want for looping. Instead, switch to using immutable keys to compare
tasks.

Using immutable keys fixes one case where tasks were being flagged
incorrectly as looping when they were not, and also gives tasks
something that can be put into Sets and Maps safely in the future. Add a
test to show that tasks with the same name but returned from different
tasksfactories, which do not inherently create loops and would
previously be flagged as invalid when ancestors of each other, are now
allowed in the same task path.

Change-Id: I6a2b59619469080d9213f266c41ef2c338d05b07
3 files changed