This patch does the following:
1) Changes the ContainerScheduler.scheduleContainer() logic
if the container is guaranteed, we first put it into the guaranteed container queue, then do a pass-through guaranteed queue followed by opportunistic queue to start as many containers as possible. Finally, if the container remains in the guaranteed queue, we know we need to kill some opportunistic container
if the container is opportunistic, we first do a pass through pass-through guaranteed queue followed by opportunistic queue to start as many containers as possible. Then we try to enqueue the opportunistic container, which may fail if the maxOppQueue length is reached. Lastly, we may be able to start it if there happen to be some resources remaining. This way, we slightly change the semantic of maxOppQueueLength in cases where oversubscription is enabled. We enqueue an opportunistic container when neither there is unallocated resource nor can it be started due to oversubscription.
2) When maxOppQUeueLength is set to 0 or a negative value, containers are no longer unconditionally started.
3) Adds a new unit test in TestContainerSchedulerQueuing to test the case where the OppQueue length limit is reached with too many opportunistic container requests.
4) Add a new method resourceAvailableToStartContainer() which we could extend to include oversubscription logic.