This test ensures that destroy can be called while in the launch loop. The composing containerizer still calls the underlying containerizer's destroy (because it's not sure if the containerizer can handle the type of container being launched). If the launch is not supported by the 1st containerizer, the composing containerizer should stop the launch.
| 65 | // launched). If the launch is not supported by the 1st containerizer, |
| 66 | // the composing containerizer should stop the launch. |
| 67 | TEST_F(ComposingContainerizerTest, DestroyDuringUnsupportedLaunchLoop) |
| 68 | { |
| 69 | vector<Containerizer*> containerizers; |
| 70 | |
| 71 | MockContainerizer* mockContainerizer1 = new MockContainerizer(); |
| 72 | MockContainerizer* mockContainerizer2 = new MockContainerizer(); |
| 73 | |
| 74 | containerizers.push_back(mockContainerizer1); |
| 75 | containerizers.push_back(mockContainerizer2); |
| 76 | |
| 77 | ComposingContainerizer containerizer(containerizers); |
| 78 | ContainerID containerId; |
| 79 | containerId.set_value("container"); |
| 80 | TaskInfo taskInfo; |
| 81 | ExecutorInfo executorInfo; |
| 82 | map<string, string> environment; |
| 83 | |
| 84 | Promise<Containerizer::LaunchResult> launchPromise; |
| 85 | |
| 86 | EXPECT_CALL(*mockContainerizer1, launch(_, _, _, _)) |
| 87 | .WillOnce(Return(launchPromise.future())); |
| 88 | |
| 89 | Future<Nothing> destroy; |
| 90 | Promise<Option<ContainerTermination>> destroyPromise; |
| 91 | EXPECT_CALL(*mockContainerizer1, destroy(_)) |
| 92 | .WillOnce(DoAll(FutureSatisfy(&destroy), |
| 93 | Return(destroyPromise.future()))); |
| 94 | |
| 95 | Future<Containerizer::LaunchResult> launched = containerizer.launch( |
| 96 | containerId, |
| 97 | createContainerConfig(taskInfo, executorInfo, "dir", "user"), |
| 98 | environment, |
| 99 | None()); |
| 100 | |
| 101 | EXPECT_TRUE(launched.isPending()); |
| 102 | |
| 103 | Future<Option<ContainerTermination>> destroyed = |
| 104 | containerizer.destroy(containerId); |
| 105 | |
| 106 | EXPECT_CALL(*mockContainerizer2, launch(_, _, _, _)) |
| 107 | .Times(0); |
| 108 | |
| 109 | // We make sure the destroy is being called on the first containerizer. |
| 110 | // The second containerizer shouldn't be called as well since the |
| 111 | // container is already destroyed. |
| 112 | AWAIT_READY(destroy); |
| 113 | |
| 114 | launchPromise.set(Containerizer::LaunchResult::NOT_SUPPORTED); |
| 115 | destroyPromise.set(Option<ContainerTermination>::none()); |
| 116 | |
| 117 | // `launched` should be a failure and `destroyed` should be `None` |
| 118 | // because there was no container in `RUNNING` or `LAUNCHING` state |
| 119 | // at the moment `destroy()` was called. |
| 120 | AWAIT_FAILED(launched); |
| 121 | |
| 122 | AWAIT_READY(destroyed); |
| 123 | EXPECT_NONE(destroyed.get()); |
| 124 | } |
nothing calls this directly
no test coverage detected