PageRenderTime 44ms CodeModel.GetById 3ms app.highlight 36ms RepoModel.GetById 1ms app.codeStats 1ms

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