PageRenderTime 35ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/hadoop-mapreduce-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-nodemanager/src/test/java/org/apache/hadoop/yarn/server/nodemanager/containermanager/container/TestContainer.java

https://github.com/rbodkin/hadoop-common
Java | 341 lines | 270 code | 35 blank | 36 comment | 17 complexity | 88cc37db4bcc315cadf7c60d90e33b38 MD5 | raw file
  1. /**
  2. * Licensed to the Apache Software Foundation (ASF) under one
  3. * or more contributor license agreements. See the NOTICE file
  4. * distributed with this work for additional information
  5. * regarding copyright ownership. The ASF licenses this file
  6. * to you under the Apache License, Version 2.0 (the
  7. * "License"); you may not use this file except in compliance
  8. * with the License. You may obtain a copy of the License at
  9. *
  10. * http://www.apache.org/licenses/LICENSE-2.0
  11. *
  12. * Unless required by applicable law or agreed to in writing, software
  13. * distributed under the License is distributed on an "AS IS" BASIS,
  14. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15. * See the License for the specific language governing permissions and
  16. * limitations under the License.
  17. */
  18. package org.apache.hadoop.yarn.server.nodemanager.containermanager.container;
  19. import org.apache.hadoop.yarn.event.Dispatcher;
  20. import org.apache.hadoop.yarn.server.nodemanager.metrics.NodeManagerMetrics;
  21. import java.net.URISyntaxException;
  22. import java.nio.ByteBuffer;
  23. import java.util.Collections;
  24. import java.util.EnumSet;
  25. import java.util.HashMap;
  26. import java.util.HashSet;
  27. import java.util.Map;
  28. import java.util.Random;
  29. import java.util.Map.Entry;
  30. import java.util.AbstractMap.SimpleEntry;
  31. import org.apache.hadoop.fs.Path;
  32. import org.apache.hadoop.yarn.api.records.ApplicationId;
  33. import org.apache.hadoop.yarn.api.records.ContainerId;
  34. import org.apache.hadoop.yarn.api.records.ContainerLaunchContext;
  35. import org.apache.hadoop.yarn.api.records.LocalResource;
  36. import org.apache.hadoop.yarn.api.records.LocalResourceType;
  37. import org.apache.hadoop.yarn.api.records.LocalResourceVisibility;
  38. import org.apache.hadoop.yarn.api.records.URL;
  39. import org.apache.hadoop.yarn.event.DrainDispatcher;
  40. import org.apache.hadoop.yarn.event.EventHandler;
  41. import org.apache.hadoop.yarn.server.nodemanager.NodeManager;
  42. import org.apache.hadoop.yarn.server.nodemanager.containermanager.AuxServicesEvent;
  43. import org.apache.hadoop.yarn.server.nodemanager.containermanager.AuxServicesEventType;
  44. import org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainersLauncherEvent;
  45. import org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainersLauncherEventType;
  46. import org.apache.hadoop.yarn.server.nodemanager.containermanager.localizer.LocalResourceRequest;
  47. import org.apache.hadoop.yarn.server.nodemanager.containermanager.localizer.event.LocalizationEvent;
  48. import org.apache.hadoop.yarn.server.nodemanager.containermanager.localizer.event.LocalizationEventType;
  49. import org.apache.hadoop.yarn.server.nodemanager.containermanager.localizer.event.ContainerLocalizationRequestEvent;
  50. import org.junit.Test;
  51. import static org.junit.Assert.*;
  52. import org.mockito.ArgumentMatcher;
  53. import static org.mockito.Mockito.*;
  54. public class TestContainer {
  55. final NodeManagerMetrics metrics = NodeManagerMetrics.create();
  56. /**
  57. * Verify correct container request events sent to localizer.
  58. */
  59. @Test
  60. @SuppressWarnings("unchecked") // mocked generic
  61. public void testLocalizationRequest() throws Exception {
  62. DrainDispatcher dispatcher = new DrainDispatcher();
  63. dispatcher.init(null);
  64. try {
  65. dispatcher.start();
  66. EventHandler<LocalizationEvent> localizerBus = mock(EventHandler.class);
  67. dispatcher.register(LocalizationEventType.class, localizerBus);
  68. // null serviceData; no registered AuxServicesEventType handler
  69. ContainerLaunchContext ctxt = mock(ContainerLaunchContext.class);
  70. ContainerId cId = getMockContainerId(7, 314159265358979L, 4344);
  71. when(ctxt.getUser()).thenReturn("yak");
  72. when(ctxt.getContainerId()).thenReturn(cId);
  73. Random r = new Random();
  74. long seed = r.nextLong();
  75. r.setSeed(seed);
  76. System.out.println("testLocalizationRequest seed: " + seed);
  77. final Map<String,LocalResource> localResources = createLocalResources(r);
  78. when(ctxt.getAllLocalResources()).thenReturn(localResources);
  79. final Container c = newContainer(dispatcher, ctxt);
  80. assertEquals(ContainerState.NEW, c.getContainerState());
  81. // Verify request for public/private resources to localizer
  82. c.handle(new ContainerEvent(cId, ContainerEventType.INIT_CONTAINER));
  83. dispatcher.await();
  84. ContainerReqMatcher matchesPublicReq =
  85. new ContainerReqMatcher(localResources,
  86. EnumSet.of(LocalResourceVisibility.PUBLIC));
  87. ContainerReqMatcher matchesPrivateReq =
  88. new ContainerReqMatcher(localResources,
  89. EnumSet.of(LocalResourceVisibility.PRIVATE));
  90. ContainerReqMatcher matchesAppReq =
  91. new ContainerReqMatcher(localResources,
  92. EnumSet.of(LocalResourceVisibility.APPLICATION));
  93. verify(localizerBus).handle(argThat(matchesPublicReq));
  94. verify(localizerBus).handle(argThat(matchesPrivateReq));
  95. verify(localizerBus).handle(argThat(matchesAppReq));
  96. assertEquals(ContainerState.LOCALIZING, c.getContainerState());
  97. } finally {
  98. dispatcher.stop();
  99. }
  100. }
  101. /**
  102. * Verify container launch when all resources already cached.
  103. */
  104. @Test
  105. @SuppressWarnings("unchecked") // mocked generic
  106. public void testLocalizationLaunch() throws Exception {
  107. DrainDispatcher dispatcher = new DrainDispatcher();
  108. dispatcher.init(null);
  109. try {
  110. dispatcher.start();
  111. EventHandler<LocalizationEvent> localizerBus = mock(EventHandler.class);
  112. dispatcher.register(LocalizationEventType.class, localizerBus);
  113. EventHandler<ContainersLauncherEvent> launcherBus =
  114. mock(EventHandler.class);
  115. dispatcher.register(ContainersLauncherEventType.class, launcherBus);
  116. // null serviceData; no registered AuxServicesEventType handler
  117. ContainerLaunchContext ctxt = mock(ContainerLaunchContext.class);
  118. ContainerId cId = getMockContainerId(8, 314159265358979L, 4344);
  119. when(ctxt.getUser()).thenReturn("yak");
  120. when(ctxt.getContainerId()).thenReturn(cId);
  121. Random r = new Random();
  122. long seed = r.nextLong();
  123. r.setSeed(seed);
  124. System.out.println("testLocalizationLaunch seed: " + seed);
  125. final Map<String,LocalResource> localResources = createLocalResources(r);
  126. when(ctxt.getAllLocalResources()).thenReturn(localResources);
  127. final Container c = newContainer(dispatcher, ctxt);
  128. assertEquals(ContainerState.NEW, c.getContainerState());
  129. c.handle(new ContainerEvent(cId, ContainerEventType.INIT_CONTAINER));
  130. dispatcher.await();
  131. // Container prepared for localization events
  132. Path cache = new Path("file:///cache");
  133. Map<Path,String> localPaths = new HashMap<Path,String>();
  134. for (Entry<String,LocalResource> rsrc : localResources.entrySet()) {
  135. assertEquals(ContainerState.LOCALIZING, c.getContainerState());
  136. LocalResourceRequest req = new LocalResourceRequest(rsrc.getValue());
  137. Path p = new Path(cache, rsrc.getKey());
  138. localPaths.put(p, rsrc.getKey());
  139. // rsrc copied to p
  140. c.handle(new ContainerResourceLocalizedEvent(c.getContainerID(), req, p));
  141. }
  142. dispatcher.await();
  143. // all resources should be localized
  144. assertEquals(ContainerState.LOCALIZED, c.getContainerState());
  145. for (Entry<Path,String> loc : c.getLocalizedResources().entrySet()) {
  146. assertEquals(localPaths.remove(loc.getKey()), loc.getValue());
  147. }
  148. assertTrue(localPaths.isEmpty());
  149. // verify container launch
  150. ArgumentMatcher<ContainersLauncherEvent> matchesContainerLaunch =
  151. new ArgumentMatcher<ContainersLauncherEvent>() {
  152. @Override
  153. public boolean matches(Object o) {
  154. ContainersLauncherEvent launchEvent = (ContainersLauncherEvent) o;
  155. return c == launchEvent.getContainer();
  156. }
  157. };
  158. verify(launcherBus).handle(argThat(matchesContainerLaunch));
  159. } finally {
  160. dispatcher.stop();
  161. }
  162. }
  163. /**
  164. * Verify serviceData correctly sent.
  165. */
  166. @Test
  167. @SuppressWarnings("unchecked") // mocked generic
  168. public void testServiceData() throws Exception {
  169. DrainDispatcher dispatcher = new DrainDispatcher();
  170. dispatcher.init(null);
  171. dispatcher.start();
  172. try {
  173. EventHandler<LocalizationEvent> localizerBus = mock(EventHandler.class);
  174. dispatcher.register(LocalizationEventType.class, localizerBus);
  175. EventHandler<AuxServicesEvent> auxBus = mock(EventHandler.class);
  176. dispatcher.register(AuxServicesEventType.class, auxBus);
  177. EventHandler<ContainersLauncherEvent> launchBus = mock(EventHandler.class);
  178. dispatcher.register(ContainersLauncherEventType.class, launchBus);
  179. ContainerLaunchContext ctxt = mock(ContainerLaunchContext.class);
  180. final ContainerId cId = getMockContainerId(9, 314159265358979L, 4344);
  181. when(ctxt.getUser()).thenReturn("yak");
  182. when(ctxt.getContainerId()).thenReturn(cId);
  183. when(ctxt.getAllLocalResources()).thenReturn(
  184. Collections.<String,LocalResource>emptyMap());
  185. Random r = new Random();
  186. long seed = r.nextLong();
  187. r.setSeed(seed);
  188. System.out.println("testServiceData seed: " + seed);
  189. final Map<String,ByteBuffer> serviceData = createServiceData(r);
  190. when(ctxt.getAllServiceData()).thenReturn(serviceData);
  191. final Container c = newContainer(dispatcher, ctxt);
  192. assertEquals(ContainerState.NEW, c.getContainerState());
  193. // Verify propagation of service data to AuxServices
  194. c.handle(new ContainerEvent(cId, ContainerEventType.INIT_CONTAINER));
  195. dispatcher.await();
  196. for (final Map.Entry<String,ByteBuffer> e : serviceData.entrySet()) {
  197. ArgumentMatcher<AuxServicesEvent> matchesServiceReq =
  198. new ArgumentMatcher<AuxServicesEvent>() {
  199. @Override
  200. public boolean matches(Object o) {
  201. AuxServicesEvent evt = (AuxServicesEvent) o;
  202. return e.getKey().equals(evt.getServiceID())
  203. && 0 == e.getValue().compareTo(evt.getServiceData());
  204. }
  205. };
  206. verify(auxBus).handle(argThat(matchesServiceReq));
  207. }
  208. // verify launch on empty resource request
  209. ArgumentMatcher<ContainersLauncherEvent> matchesLaunchReq =
  210. new ArgumentMatcher<ContainersLauncherEvent>() {
  211. @Override
  212. public boolean matches(Object o) {
  213. ContainersLauncherEvent evt = (ContainersLauncherEvent) o;
  214. return evt.getType() == ContainersLauncherEventType.LAUNCH_CONTAINER
  215. && cId == evt.getContainer().getContainerID();
  216. }
  217. };
  218. verify(launchBus).handle(argThat(matchesLaunchReq));
  219. } finally {
  220. dispatcher.stop();
  221. }
  222. }
  223. // Accept iff the resource request payload matches.
  224. static class ContainerReqMatcher extends ArgumentMatcher<LocalizationEvent> {
  225. final HashSet<LocalResourceRequest> resources =
  226. new HashSet<LocalResourceRequest>();
  227. ContainerReqMatcher(Map<String,LocalResource> allResources,
  228. EnumSet<LocalResourceVisibility> vis) throws URISyntaxException {
  229. for (Entry<String,LocalResource> e : allResources.entrySet()) {
  230. if (vis.contains(e.getValue().getVisibility())) {
  231. resources.add(new LocalResourceRequest(e.getValue()));
  232. }
  233. }
  234. }
  235. @Override
  236. public boolean matches(Object o) {
  237. ContainerLocalizationRequestEvent evt = (ContainerLocalizationRequestEvent) o;
  238. final HashSet<LocalResourceRequest> expected =
  239. new HashSet<LocalResourceRequest>(resources);
  240. for (LocalResourceRequest rsrc : evt.getRequestedResources()) {
  241. if (!expected.remove(rsrc)) {
  242. return false;
  243. }
  244. }
  245. return expected.isEmpty();
  246. }
  247. }
  248. static Entry<String,LocalResource> getMockRsrc(Random r,
  249. LocalResourceVisibility vis) {
  250. LocalResource rsrc = mock(LocalResource.class);
  251. String name = Long.toHexString(r.nextLong());
  252. URL uri = mock(org.apache.hadoop.yarn.api.records.URL.class);
  253. when(uri.getScheme()).thenReturn("file");
  254. when(uri.getHost()).thenReturn(null);
  255. when(uri.getFile()).thenReturn("/local/" + vis + "/" + name);
  256. when(rsrc.getResource()).thenReturn(uri);
  257. when(rsrc.getSize()).thenReturn(r.nextInt(1024) + 1024L);
  258. when(rsrc.getTimestamp()).thenReturn(r.nextInt(1024) + 2048L);
  259. when(rsrc.getType()).thenReturn(LocalResourceType.FILE);
  260. when(rsrc.getVisibility()).thenReturn(vis);
  261. return new SimpleEntry<String,LocalResource>(name, rsrc);
  262. }
  263. static Map<String,LocalResource> createLocalResources(Random r) {
  264. Map<String,LocalResource> localResources =
  265. new HashMap<String,LocalResource>();
  266. for (int i = r.nextInt(5) + 5; i >= 0; --i) {
  267. Entry<String,LocalResource> rsrc =
  268. getMockRsrc(r, LocalResourceVisibility.PUBLIC);
  269. localResources.put(rsrc.getKey(), rsrc.getValue());
  270. }
  271. for (int i = r.nextInt(5) + 5; i >= 0; --i) {
  272. Entry<String,LocalResource> rsrc =
  273. getMockRsrc(r, LocalResourceVisibility.PRIVATE);
  274. localResources.put(rsrc.getKey(), rsrc.getValue());
  275. }
  276. for (int i = r.nextInt(2) + 2; i >= 0; --i) {
  277. Entry<String,LocalResource> rsrc =
  278. getMockRsrc(r, LocalResourceVisibility.APPLICATION);
  279. localResources.put(rsrc.getKey(), rsrc.getValue());
  280. }
  281. return localResources;
  282. }
  283. static ContainerId getMockContainerId(int appId, long timestamp, int id) {
  284. ApplicationId aId = mock(ApplicationId.class);
  285. when(aId.getId()).thenReturn(appId);
  286. when(aId.getClusterTimestamp()).thenReturn(timestamp);
  287. ContainerId cId = mock(ContainerId.class);
  288. when(cId.getId()).thenReturn(id);
  289. when(cId.getAppId()).thenReturn(aId);
  290. return cId;
  291. }
  292. static Map<String,ByteBuffer> createServiceData(Random r) {
  293. Map<String,ByteBuffer> serviceData =
  294. new HashMap<String,ByteBuffer>();
  295. for (int i = r.nextInt(5) + 5; i >= 0; --i) {
  296. String service = Long.toHexString(r.nextLong());
  297. byte[] b = new byte[r.nextInt(1024) + 1024];
  298. r.nextBytes(b);
  299. serviceData.put(service, ByteBuffer.wrap(b));
  300. }
  301. return serviceData;
  302. }
  303. Container newContainer(Dispatcher disp, ContainerLaunchContext ctx) {
  304. return new ContainerImpl(disp, ctx, null, metrics);
  305. }
  306. }