/src/test/java/nl/bitbrains/nebu/rest/server/TestDeploymentProvider.java

https://github.com/deltaforge/nebu-core · Java · 423 lines · 375 code · 44 blank · 4 comment · 0 complexity · e01ade5f513ef3a7cb8434a9f1fc61af MD5 · raw file

  1. package nl.bitbrains.nebu.rest.server;
  2. import java.net.URI;
  3. import java.text.ParseException;
  4. import java.util.HashMap;
  5. import java.util.Map;
  6. import javax.ws.rs.client.Entity;
  7. import javax.ws.rs.core.MediaType;
  8. import javax.ws.rs.core.Response;
  9. import nl.bitbrains.nebu.common.cache.CacheException;
  10. import nl.bitbrains.nebu.common.cache.CacheManager;
  11. import nl.bitbrains.nebu.common.factories.IdentifiableFactory;
  12. import nl.bitbrains.nebu.common.factories.VirtualMachineFactory;
  13. import nl.bitbrains.nebu.common.topology.PhysicalTopology;
  14. import nl.bitbrains.nebu.common.topology.factory.PhysicalHostFactory;
  15. import nl.bitbrains.nebu.common.topology.factory.PhysicalStoreFactory;
  16. import nl.bitbrains.nebu.common.util.xml.XMLConverter;
  17. import nl.bitbrains.nebu.containers.Application;
  18. import nl.bitbrains.nebu.containers.ApplicationBuilder;
  19. import nl.bitbrains.nebu.containers.Deployment;
  20. import nl.bitbrains.nebu.containers.DeploymentBuilder;
  21. import nl.bitbrains.nebu.containers.DeploymentFactory;
  22. import nl.bitbrains.nebu.containers.DeploymentRequest;
  23. import nl.bitbrains.nebu.containers.DeploymentRequestFactory;
  24. import nl.bitbrains.nebu.containers.VMDeploymentSpecification;
  25. import nl.bitbrains.nebu.containers.VMDeploymentSpecificationBuilder;
  26. import nl.bitbrains.nebu.containers.VMDeploymentSpecificationFactory;
  27. import nl.bitbrains.nebu.containers.VMTemplate;
  28. import nl.bitbrains.nebu.containers.VMTemplateBuilder;
  29. import nl.bitbrains.nebu.containers.VMTemplateFactory;
  30. import nl.bitbrains.nebu.deployer.Deployer;
  31. import nl.bitbrains.nebu.rest.RESTRequestException;
  32. import nl.bitbrains.nebu.rest.client.RequestSender;
  33. import nl.bitbrains.nebu.rest.server.AppsProvider;
  34. import nl.bitbrains.nebu.rest.server.DeploymentProvider;
  35. import nl.bitbrains.nebu.rest.server.DeploymentsProvider;
  36. import org.glassfish.jersey.server.ResourceConfig;
  37. import org.glassfish.jersey.test.JerseyTest;
  38. import org.jdom2.Element;
  39. import org.jdom2.JDOMException;
  40. import org.jdom2.output.DOMOutputter;
  41. import org.junit.Assert;
  42. import org.junit.Test;
  43. import org.junit.runner.RunWith;
  44. import org.mockito.Matchers;
  45. import org.mockito.Mock;
  46. import org.mockito.Mockito;
  47. import org.mockito.MockitoAnnotations;
  48. import org.powermock.api.mockito.PowerMockito;
  49. import org.powermock.core.classloader.annotations.PowerMockIgnore;
  50. import org.powermock.core.classloader.annotations.PrepareForTest;
  51. import org.powermock.modules.junit4.PowerMockRunner;
  52. import org.w3c.dom.Document;
  53. /**
  54. * @author Jesse Donkervliet, Tim Hegeman, and Stefan Hugtenburg
  55. *
  56. */
  57. @RunWith(PowerMockRunner.class)
  58. @PrepareForTest({ RequestSender.class, CacheManager.class, Deployer.class, DeploymentRequest.class })
  59. @PowerMockIgnore("javax.management.*")
  60. public class TestDeploymentProvider extends JerseyTest {
  61. @Mock
  62. private RequestSender reqSender;
  63. @Mock
  64. private PhysicalTopology topology;
  65. private nl.bitbrains.nebu.containers.Application app;
  66. private DeploymentRequestFactory depFactory;
  67. private Deployment dep;
  68. private Deployment otherDep;
  69. @Mock
  70. private DeploymentRequest depReq;
  71. private Deployer deployer;
  72. private final Element elem = new Element("deployment");
  73. private final Element reqElem = new Element("deploymentRequest");
  74. private Document doc;
  75. private Document reqDoc;
  76. private final String appUUID = "appuuid";
  77. private final String depID = "depID";
  78. private final String templateID = "templateID";
  79. private final String hostID = "hostID";
  80. @Override
  81. protected javax.ws.rs.core.Application configure() {
  82. return new ResourceConfig(AppsProvider.class);
  83. }
  84. @Override
  85. public void setUp() throws Exception {
  86. super.setUp();
  87. PowerMockito.mockStatic(CacheManager.class);
  88. this.setUpReqSenderMock();
  89. final DOMOutputter converter = new DOMOutputter();
  90. final org.jdom2.Document jdomDoc = new org.jdom2.Document(this.elem);
  91. this.doc = converter.output(jdomDoc);
  92. this.reqDoc = converter.output(new org.jdom2.Document(this.reqElem));
  93. this.deployer = PowerMockito.mock(Deployer.class);
  94. }
  95. private void setUpReqSenderMock() {
  96. MockitoAnnotations.initMocks(this);
  97. PowerMockito.mockStatic(RequestSender.class);
  98. PowerMockito.when(RequestSender.get()).thenReturn(this.reqSender);
  99. }
  100. private void setUpCacheManager(final String key, final Object value) throws CacheException {
  101. Mockito.when(CacheManager.get(key)).thenReturn(value);
  102. }
  103. private void setCacheMock() throws CacheException {
  104. this.setUpCacheManager(Deployer.CACHE_KEY, this.deployer);
  105. }
  106. private void setApplicationReal() {
  107. this.app = new ApplicationBuilder().withUuid(this.appUUID).withDeployment(this.dep)
  108. .build();
  109. }
  110. private void setDeploymentReal() {
  111. this.dep = new DeploymentBuilder().withUuid(this.depID).build();
  112. }
  113. private void setNonEmptyApplicationMap() throws CacheException {
  114. final Map<String, Application> map = new HashMap<String, Application>();
  115. map.put(this.appUUID, this.app);
  116. this.setUpCacheManager(AppsProvider.CACHE_KEY_APPS, map);
  117. }
  118. private void setDeployerMock() throws Exception {
  119. Mockito.when(this.deployer.generateDeployment(Matchers.any(DeploymentRequest.class)))
  120. .thenReturn(this.dep);
  121. }
  122. private void setLuanchReqSenderMock() throws RESTRequestException {
  123. Mockito.when(this.reqSender.postCreateVM(Matchers.anyString(),
  124. Matchers.anyString(),
  125. Matchers.anyString())).thenReturn(Response
  126. .created(URI.create("/a/a/a/a/")).build());
  127. Mockito.when(this.reqSender.postCreateVM(Matchers.anyString(),
  128. Matchers.anyString(),
  129. Matchers.anyString(),
  130. Matchers.anyString())).thenReturn(Response
  131. .created(URI.create("/b/b/b/b/")).build());
  132. }
  133. private void setLaunchReqSenderMock(final Throwable e) throws Exception {
  134. Mockito.when(this.reqSender.postCreateVM(Matchers.anyString(),
  135. Matchers.anyString(),
  136. Matchers.anyString())).thenThrow(e);
  137. }
  138. private void addSpecToDep(final Deployment dep, final String templateId, final String host) {
  139. final VMTemplate template = new VMTemplateBuilder().withUuid(templateId)
  140. .withName(templateId).build();
  141. final VMDeploymentSpecification spec = new VMDeploymentSpecificationBuilder()
  142. .withTemplate(template).withHost(host).build();
  143. dep.addSpec(spec);
  144. }
  145. private void addSpecToDep(final Deployment dep, final String templateId, final String host,
  146. final String store) {
  147. final VMTemplate template = new VMTemplateBuilder().withUuid(templateId)
  148. .withName(templateId).build();
  149. final VMDeploymentSpecification spec = new VMDeploymentSpecificationBuilder()
  150. .withTemplate(template).withHost(host).withStore(store).build();
  151. dep.addSpec(spec);
  152. }
  153. private Document getPostRootBodyChangeDep() throws JDOMException {
  154. this.otherDep = new DeploymentBuilder()
  155. .withLaunched(false)
  156. .withUuid(this.depID)
  157. .withSpec(new VMDeploymentSpecificationBuilder()
  158. .withHost("host")
  159. .withTemplate(new VMTemplateBuilder().withUuid("templateID")
  160. .withName("name").build()).build()).build();
  161. return XMLConverter.convertJDOMElementW3CDocument(new DeploymentFactory()
  162. .toXML(this.otherDep));
  163. }
  164. @Test
  165. public void testGet404Exception() throws CacheException {
  166. this.setNonEmptyApplicationMap();
  167. this.setCacheMock();
  168. final Response rep = this.target(AppsProvider.PATH).path(this.appUUID)
  169. .path(DeploymentsProvider.PATH).path(this.depID).request().get();
  170. Assert.assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rep.getStatus());
  171. }
  172. @Test
  173. public void testGetSuccessResponse() throws CacheException {
  174. this.setDeploymentReal();
  175. this.setApplicationReal();
  176. this.setNonEmptyApplicationMap();
  177. this.setCacheMock();
  178. final Response rep = this.target(AppsProvider.PATH).path(this.appUUID)
  179. .path(DeploymentsProvider.PATH).path(this.depID).request().get();
  180. Assert.assertEquals(Response.Status.OK.getStatusCode(), rep.getStatus());
  181. }
  182. @Test
  183. public void testGetSuccessContent() throws CacheException, ParseException {
  184. this.setDeploymentReal();
  185. this.setApplicationReal();
  186. this.setNonEmptyApplicationMap();
  187. this.setCacheMock();
  188. final Response rep = this.target(AppsProvider.PATH).path(this.appUUID)
  189. .path(DeploymentsProvider.PATH).path(this.depID).request().get();
  190. final Document gottenDoc = rep.readEntity(Document.class);
  191. final Deployment gottenDep = new DeploymentFactory()
  192. .fromXML(XMLConverter.convertW3CDocumentJDOMElement(gottenDoc)).build();
  193. Assert.assertEquals(this.depID, gottenDep.getUniqueIdentifier());
  194. }
  195. @Test
  196. public void testPost404Exception() throws CacheException {
  197. this.setNonEmptyApplicationMap();
  198. this.setCacheMock();
  199. final Entity<Document> entity = Entity.entity(this.doc, MediaType.APPLICATION_XML_TYPE);
  200. final Response rep = this.target(AppsProvider.PATH).path(this.appUUID)
  201. .path(DeploymentsProvider.PATH).path(this.depID).request().post(entity);
  202. Assert.assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rep.getStatus());
  203. }
  204. @Test
  205. public void testPostChange403Exception() throws CacheException {
  206. this.setDeploymentReal();
  207. this.dep.setLaunched(true);
  208. this.setApplicationReal();
  209. this.setNonEmptyApplicationMap();
  210. this.setCacheMock();
  211. final Entity<Document> entity = Entity.entity(this.doc, MediaType.APPLICATION_XML_TYPE);
  212. final Response rep = this.target(AppsProvider.PATH).path(this.appUUID)
  213. .path(DeploymentsProvider.PATH).path(this.depID).request().post(entity);
  214. Assert.assertEquals(Response.Status.FORBIDDEN.getStatusCode(), rep.getStatus());
  215. }
  216. @Test
  217. public void testPostSuccesResponseAndInternals() throws CacheException, JDOMException {
  218. this.setDeploymentReal();
  219. this.setApplicationReal();
  220. this.setNonEmptyApplicationMap();
  221. this.setCacheMock();
  222. final Entity<Document> entity = Entity.entity(this.getPostRootBodyChangeDep(),
  223. MediaType.APPLICATION_XML_TYPE);
  224. final Response rep = this.target(AppsProvider.PATH).path(this.appUUID)
  225. .path(DeploymentsProvider.PATH).path(this.depID).request().post(entity);
  226. Assert.assertEquals(Response.Status.OK.getStatusCode(), rep.getStatus());
  227. Assert.assertFalse(this.app.getDeployment(this.depID).getSpecs().isEmpty());
  228. }
  229. @Test
  230. public void testPostStart403Exception() throws CacheException {
  231. this.setDeploymentReal();
  232. this.dep.setLaunched(true);
  233. this.setApplicationReal();
  234. this.setNonEmptyApplicationMap();
  235. this.setCacheMock();
  236. final Entity<Document> entity = Entity.entity(this.doc, MediaType.APPLICATION_XML_TYPE);
  237. final Response rep = this.target(AppsProvider.PATH).path(this.appUUID)
  238. .path(DeploymentsProvider.PATH).path(this.depID)
  239. .path(DeploymentProvider.PATH_START).request().post(entity);
  240. Assert.assertEquals(Response.Status.FORBIDDEN.getStatusCode(), rep.getStatus());
  241. }
  242. @Test
  243. public void testPostStartNoSpecs() throws CacheException {
  244. this.setDeploymentReal();
  245. this.setApplicationReal();
  246. this.setNonEmptyApplicationMap();
  247. this.setCacheMock();
  248. final Entity<Document> entity = Entity.entity(this.doc, MediaType.APPLICATION_XML_TYPE);
  249. final Response rep = this.target(AppsProvider.PATH).path(this.appUUID)
  250. .path(DeploymentsProvider.PATH).path(this.depID)
  251. .path(DeploymentProvider.PATH_START).request().post(entity);
  252. Assert.assertEquals(Response.Status.ACCEPTED.getStatusCode(), rep.getStatus());
  253. Assert.assertTrue(this.dep.isLaunched());
  254. }
  255. @Test
  256. public void testPostStartOneSpecNoStore() throws Exception {
  257. this.setDeploymentReal();
  258. this.setApplicationReal();
  259. this.setNonEmptyApplicationMap();
  260. this.setCacheMock();
  261. this.setDeployerMock();
  262. this.setLuanchReqSenderMock();
  263. this.addSpecToDep(this.dep, this.templateID, this.hostID);
  264. final Entity<Document> entity = Entity.entity(this.doc, MediaType.APPLICATION_XML_TYPE);
  265. final Response rep = this.target(AppsProvider.PATH).path(this.appUUID)
  266. .path(DeploymentsProvider.PATH).path(this.depID)
  267. .path(DeploymentProvider.PATH_START).request().post(entity);
  268. Assert.assertEquals(Response.Status.ACCEPTED.getStatusCode(), rep.getStatus());
  269. Assert.assertEquals(1, this.dep.getVirtualMachines().size());
  270. Mockito.verify(this.reqSender).postCreateVM(Matchers.eq(this.hostID),
  271. Matchers.startsWith(this.templateID),
  272. Matchers.eq(this.templateID));
  273. }
  274. @Test
  275. public void testPostStartOneSpecRestReqException() throws Exception {
  276. this.setDeploymentReal();
  277. this.setApplicationReal();
  278. this.setNonEmptyApplicationMap();
  279. this.setCacheMock();
  280. this.setDeployerMock();
  281. final int errorCode = 123;
  282. this.setLaunchReqSenderMock(new RESTRequestException("", errorCode));
  283. this.addSpecToDep(this.dep, this.templateID, this.hostID);
  284. final Entity<Document> entity = Entity.entity(this.doc, MediaType.APPLICATION_XML_TYPE);
  285. final Response rep = this.target(AppsProvider.PATH).path(this.appUUID)
  286. .path(DeploymentsProvider.PATH).path(this.depID)
  287. .path(DeploymentProvider.PATH_START).request().post(entity);
  288. Assert.assertEquals(errorCode, rep.getStatus());
  289. }
  290. @Test
  291. public void testPostStartTwoSpecs() throws Exception {
  292. this.setDeploymentReal();
  293. this.setApplicationReal();
  294. this.setNonEmptyApplicationMap();
  295. this.setCacheMock();
  296. this.setDeployerMock();
  297. this.setLuanchReqSenderMock();
  298. this.addSpecToDep(this.dep, this.templateID, this.hostID);
  299. this.addSpecToDep(this.dep, this.templateID, this.hostID, this.hostID);
  300. final Entity<Document> entity = Entity.entity(this.doc, MediaType.APPLICATION_XML_TYPE);
  301. final Response rep = this.target(AppsProvider.PATH).path(this.appUUID)
  302. .path(DeploymentsProvider.PATH).path(this.depID)
  303. .path(DeploymentProvider.PATH_START).request().post(entity);
  304. Assert.assertEquals(Response.Status.ACCEPTED.getStatusCode(), rep.getStatus());
  305. Assert.assertEquals(2, this.dep.getVirtualMachines().size());
  306. Mockito.verify(this.reqSender).postCreateVM(Matchers.eq(this.hostID),
  307. Matchers.startsWith(this.templateID),
  308. Matchers.eq(this.templateID),
  309. Matchers.eq(this.hostID));
  310. }
  311. @Test
  312. public void addVMToDeployment404() throws CacheException, JDOMException {
  313. this.setNonEmptyApplicationMap();
  314. this.setCacheMock();
  315. final Response rep = this.target(AppsProvider.PATH).path(this.appUUID)
  316. .path(DeploymentsProvider.PATH).path(this.depID).request()
  317. .put(this.createPUTEntity());
  318. Assert.assertEquals(Response.Status.NOT_FOUND.getStatusCode(), rep.getStatus());
  319. }
  320. @Test
  321. public void addVMToDeployment403() throws CacheException, JDOMException {
  322. this.setDeploymentReal();
  323. this.setApplicationReal();
  324. this.setNonEmptyApplicationMap();
  325. final Response rep = this.target(AppsProvider.PATH).path(this.appUUID)
  326. .path(DeploymentsProvider.PATH).path(this.depID).request()
  327. .put(this.createPUTEntity());
  328. Assert.assertEquals(Response.Status.FORBIDDEN.getStatusCode(), rep.getStatus());
  329. }
  330. @Test
  331. public void addVMToDeployment400() throws CacheException, JDOMException {
  332. this.setDeploymentReal();
  333. this.setApplicationReal();
  334. this.setNonEmptyApplicationMap();
  335. this.dep.setLaunched(true);
  336. final Response rep = this.target(AppsProvider.PATH).path(this.appUUID)
  337. .path(DeploymentsProvider.PATH).path(this.depID).request()
  338. .put(this.createMalformedPUTEntity());
  339. Assert.assertEquals(Response.Status.BAD_REQUEST.getStatusCode(), rep.getStatus());
  340. }
  341. @Test
  342. public void addVMToDeployment200() throws CacheException, JDOMException {
  343. this.setDeploymentReal();
  344. this.setApplicationReal();
  345. this.setNonEmptyApplicationMap();
  346. this.dep.setLaunched(true);
  347. final Response rep = this.target(AppsProvider.PATH).path(this.appUUID)
  348. .path(DeploymentsProvider.PATH).path(this.depID).request()
  349. .put(this.createPUTEntity());
  350. Assert.assertEquals(Response.Status.OK.getStatusCode(), rep.getStatus());
  351. }
  352. private Entity<Document> createMalformedPUTEntity() throws JDOMException {
  353. final Element elem = new Element(VirtualMachineFactory.TAG_ELEMENT_ROOT);
  354. elem.setAttribute(IdentifiableFactory.TAG_ID, "id");
  355. final Element specElem = new Element(VMDeploymentSpecificationFactory.TAG_ELEMENT_ROOT);
  356. elem.addContent(specElem);
  357. final Element templateElem = new Element(VMTemplateFactory.TAG_ELEMENT_ROOT);
  358. templateElem.setAttribute(IdentifiableFactory.TAG_ID, "id");
  359. specElem.addContent(templateElem);
  360. final Document doc = XMLConverter.convertJDOMElementW3CDocument(elem);
  361. return Entity.entity(doc, MediaType.APPLICATION_XML_TYPE);
  362. }
  363. private Entity<Document> createPUTEntity() throws JDOMException {
  364. final Element elem = new Element(VirtualMachineFactory.TAG_ELEMENT_ROOT);
  365. elem.setAttribute(IdentifiableFactory.TAG_ID, "id");
  366. final Element specElem = new Element(VMDeploymentSpecificationFactory.TAG_ELEMENT_ROOT);
  367. elem.addContent(specElem);
  368. final Element templateElem = new Element(VMTemplateFactory.TAG_ELEMENT_ROOT);
  369. final Element hostElem = new Element(PhysicalHostFactory.TAG_ELEMENT_ROOT);
  370. final Element storeElem = new Element(PhysicalStoreFactory.TAG_ELEMENT_ROOT);
  371. templateElem.setAttribute(IdentifiableFactory.TAG_ID, "id");
  372. templateElem.setAttribute(VMTemplateFactory.ATTRIBUTE_NAME, "name");
  373. hostElem.setAttribute(IdentifiableFactory.TAG_ID, "id");
  374. storeElem.setAttribute(IdentifiableFactory.TAG_ID, "id");
  375. specElem.addContent(templateElem).addContent(hostElem).addContent(storeElem);
  376. final Document doc = XMLConverter.convertJDOMElementW3CDocument(elem);
  377. return Entity.entity(doc, MediaType.APPLICATION_XML_TYPE);
  378. }
  379. }