package org.ovirt.engine.api.restapi.resource; import static org.easymock.EasyMock.expect; import static org.ovirt.engine.api.restapi.resource.BackendHostsResourceTest.getModel; import static org.ovirt.engine.api.restapi.resource.BackendHostsResourceTest.setUpEntityExpectations; import static org.ovirt.engine.api.restapi.resource.BackendHostsResourceTest.setUpStatisticalEntityExpectations; import static org.ovirt.engine.api.restapi.resource.BackendHostsResourceTest.verifyModelSpecific; import java.math.BigDecimal; import java.math.MathContext; import java.util.ArrayList; import java.util.List; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; import javax.ws.rs.core.UriInfo; import org.junit.Test; import org.ovirt.engine.api.model.Action; import org.ovirt.engine.api.model.Cluster; import org.ovirt.engine.api.model.CreationStatus; import org.ovirt.engine.api.model.FenceType; import org.ovirt.engine.api.model.Host; import org.ovirt.engine.api.model.PowerManagementStatus; import org.ovirt.engine.api.model.Statistic; import org.ovirt.engine.core.common.action.ChangeVDSClusterParameters; import org.ovirt.engine.core.common.action.FenceVdsActionParameters; import org.ovirt.engine.core.common.action.FenceVdsManualyParameters; import org.ovirt.engine.core.common.action.MaintananceNumberOfVdssParameters; import org.ovirt.engine.core.common.action.UpdateVdsActionParameters; import org.ovirt.engine.core.common.action.VdcActionParametersBase; import org.ovirt.engine.core.common.action.VdcActionType; import org.ovirt.engine.core.common.action.VdcReturnValueBase; import org.ovirt.engine.core.common.action.VdsActionParameters; import org.ovirt.engine.core.common.businessentities.AsyncTaskStatus; import org.ovirt.engine.core.common.businessentities.AsyncTaskStatusEnum; import org.ovirt.engine.core.common.businessentities.FenceActionType; import org.ovirt.engine.core.common.businessentities.FenceStatusReturnValue; import org.ovirt.engine.core.common.businessentities.StorageType; import org.ovirt.engine.core.common.businessentities.VDS; import org.ovirt.engine.core.common.businessentities.VdsStatic; import org.ovirt.engine.core.common.businessentities.VdsStatistics; import org.ovirt.engine.core.common.queries.GetVdsByVdsIdParameters; import org.ovirt.engine.core.common.queries.VdcQueryType; import org.ovirt.engine.core.common.queries.VdsIdParametersBase; import org.ovirt.engine.core.compat.Guid; public class BackendHostResourceTest extends AbstractBackendSubResourceTest<Host, VDS, BackendHostResource> { private static final StorageType ISCSI_STORAGE_TYPE = StorageType.ISCSI; private static final int ISCSI_PORT_INT = 3260; private static final String ISCSI_USER_PASS = "123456789012"; private static final String ISCSI_USER_NAME = "ori"; private static final String ISCSI_PORT_STRING = "3260"; private static final String ISCSI_IQN = "iqn.1986-03.com.sun:02:ori01"; private static final String ISCSI_SERVER_ADDRESS = "shual1.eng.lab"; public BackendHostResourceTest() { super(new BackendHostResource(GUIDS[0].toString(), new BackendHostsResource())); } @Test public void testBadGuid() throws Exception { control.replay(); try { new BackendHostResource("foo", new BackendHostsResource()); fail("expected WebApplicationException"); } catch (WebApplicationException wae) { verifyNotFoundException(wae); } } @Test public void testGetNotFound() throws Exception { setUriInfo(setUpBasicUriExpectations()); setUpGetEntityExpectations(1, true); control.replay(); try { resource.get(); fail("expected WebApplicationException"); } catch (WebApplicationException wae) { verifyNotFoundException(wae); } } @Test public void testGet() throws Exception { setUriInfo(setUpBasicUriExpectations()); setUpGetEntityExpectations(1); control.replay(); verifyModel(resource.get(), 0); } @Test public void testGetIncludeStatistics() throws Exception { try { accepts.add("application/xml; detail=statistics"); setUriInfo(setUpBasicUriExpectations()); VdsStatistics stats = control.createMock(VdsStatistics.class); VDS entity = getEntity(0); setUpStatisticalEntityExpectations(entity, stats); setUpGetEntityExpectations(1, false, entity); control.replay(); Host host = resource.get(); assertTrue(host.isSetStatistics()); verifyModel(host, 0); } finally { accepts.clear(); } } @Test public void testUpdateNotFound() throws Exception { setUriInfo(setUpBasicUriExpectations()); setUpGetEntityExpectations(1, true); control.replay(); try { resource.update(getModel(0)); fail("expected WebApplicationException"); } catch (WebApplicationException wae) { verifyNotFoundException(wae); } } @Test public void testUpdate() throws Exception { setUpGetEntityExpectations(2); setUriInfo(setUpActionExpectations(VdcActionType.UpdateVds, UpdateVdsActionParameters.class, new String[] { "RootPassword" }, new Object[] { "" }, true, true)); verifyModel(resource.update(getModel(0)), 0); } @Test public void testUpdateWithClusterId() throws Exception { setUpGetEntityExpectations(2); setUriInfo(setUpActionExpectations(VdcActionType.ChangeVDSCluster, ChangeVDSClusterParameters.class, new String[] { "ClusterId", "VdsId" }, new Object[] { GUIDS[1], GUIDS[0]}, true, true, new VdcReturnValueBase(), false)); setUriInfo(setUpActionExpectations(VdcActionType.UpdateVds, UpdateVdsActionParameters.class, new String[] { "RootPassword" }, new Object[] { "" }, true, true)); Cluster cluster = new Cluster(); cluster.setId(GUIDS[1].toString()); Host host = getModel(0); host.setCluster(cluster); verifyModel(resource.update(host), 0); } @Test public void testUpdateCantDo() throws Exception { doTestBadUpdate(false, true, CANT_DO); } @Test public void testUpdateFailed() throws Exception { doTestBadUpdate(true, false, FAILURE); } private void doTestBadUpdate(boolean canDo, boolean success, String detail) throws Exception { setUpGetEntityExpectations(1); setUriInfo(setUpActionExpectations(VdcActionType.UpdateVds, UpdateVdsActionParameters.class, new String[] { "RootPassword" }, new Object[] { "" }, canDo, success)); try { resource.update(getModel(0)); fail("expected WebApplicationException"); } catch (WebApplicationException wae) { verifyFault(wae, detail); } } @Test public void testConflictedUpdate() throws Exception { setUriInfo(setUpBasicUriExpectations()); setUpGetEntityExpectations(1); control.replay(); Host model = getModel(1); model.setId(GUIDS[1].toString()); try { resource.update(model); fail("expected WebApplicationException"); } catch (WebApplicationException wae) { verifyImmutabilityConstraint(wae); } } @Test public void testActivate() throws Exception { setUriInfo(setUpActionExpectations(VdcActionType.ActivateVds, VdsActionParameters.class, new String[] { "VdsId" }, new Object[] { GUIDS[0] })); verifyActionResponse(resource.activate(new Action())); } @Test public void testActivateAsyncPending() throws Exception { doTestActivateAsync(AsyncTaskStatusEnum.init, CreationStatus.PENDING); } @Test public void testActivateAsyncInProgress() throws Exception { doTestActivateAsync(AsyncTaskStatusEnum.running, CreationStatus.IN_PROGRESS); } @Test public void testActivateAsyncFinished() throws Exception { doTestActivateAsync(AsyncTaskStatusEnum.finished, CreationStatus.COMPLETE); } private void doTestActivateAsync(AsyncTaskStatusEnum asyncStatus, CreationStatus actionStatus) throws Exception { setUriInfo(setUpActionExpectations(VdcActionType.ActivateVds, VdsActionParameters.class, new String[] { "VdsId" }, new Object[] { GUIDS[0] }, asList(GUIDS[1]), asList(new AsyncTaskStatus(asyncStatus)))); Response response = resource.activate(new Action()); verifyActionResponse(response, "hosts/" + GUIDS[0], true, null, null); Action action = (Action)response.getEntity(); assertTrue(action.isSetStatus()); assertEquals(actionStatus.value(), action.getStatus().getState()); } // @Test // public void testApprove() throws Exception { // setUriInfo(setUpActionExpectations(VdcActionType.ApproveVds, // ApproveVdsParameters.class, // new String[] { "VdsId" }, // new Object[] { GUIDS[0] })); // // verifyActionResponse(resource.approve(new Action())); // } // @Test // public void testApproveChangingCluster() throws Exception { // setUpGetEntityExpectations(3); // // setUriInfo(setUpActionExpectations(VdcActionType.ChangeVDSCluster, // ChangeVDSClusterParameters.class, // new String[] { "ClusterId", "VdsId" }, // new Object[] { GUIDS[0], GUIDS[0]}, // true, // true, // new VdcReturnValueBase(), // false)); // // setUriInfo(setUpActionExpectations(VdcActionType.UpdateVds, // UpdateVdsActionParameters.class, // new String[] { "RootPassword" }, // new Object[] { "" }, // true, // true, // false)); // // setUriInfo(setUpActionExpectations(VdcActionType.ApproveVds, // ApproveVdsParameters.class, // new String[] { "VdsId" }, // new Object[] { GUIDS[0] })); // // verifyActionResponse(resource.approve(new Action() {{ setCluster(new Cluster()); getCluster().setId(GUIDS[0].toString()); }})); // } // @Test // public void testIscsiLogin() throws Exception { // setUriInfo(setUpActionExpectations(VdcActionType.ConnectStorageToVds, // StorageServerConnectionParametersBase.class, // new String[] { "VdsId", // "StorageServerConnection.connection", // "StorageServerConnection.portal", // "StorageServerConnection.iqn", // "StorageServerConnection.port", // "StorageServerConnection.storage_type", // "StorageServerConnection.user_name", // "StorageServerConnection.password" }, // new Object[] { GUIDS[0], // ISCSI_SERVER_ADDRESS, // ISCSI_SERVER_ADDRESS, // ISCSI_IQN, // ISCSI_PORT_STRING, // ISCSI_STORAGE_TYPE, // ISCSI_USER_NAME, // ISCSI_USER_PASS })); // // Action action = new Action(); // IscsiDetails iscsiDetails = new IscsiDetails(); // iscsiDetails.setAddress(ISCSI_SERVER_ADDRESS); // iscsiDetails.setPort(ISCSI_PORT_INT); // iscsiDetails.setTarget(ISCSI_IQN); // iscsiDetails.setUsername(ISCSI_USER_NAME); // iscsiDetails.setPassword(ISCSI_USER_PASS); // action.setIscsi(iscsiDetails); // verifyActionResponse(resource.iscsiLogin(action)); // } // @Test // public void testIscsiDiscover() throws Exception { // IscsiDetails iscsiDetails = new IscsiDetails(); // iscsiDetails.setAddress(ISCSI_SERVER_ADDRESS); // iscsiDetails.setPort(ISCSI_PORT_INT); // iscsiDetails.setUsername(ISCSI_USER_NAME); // iscsiDetails.setPassword(ISCSI_USER_PASS); // // Action action = new Action(); // action.setIscsi(iscsiDetails); // // VdcQueryReturnValue queryResult = new VdcQueryReturnValue(); // queryResult.setSucceeded(true); // // expect(backend.RunQuery(eq(VdcQueryType.DiscoverSendTargets), // eqQueryParams(DiscoverSendTargetsQueryParameters.class, // addSession("VdsId", "Connection.connection", "Connection.port", "Connection.user_name", "Connection.password"), // addSession(GUIDS[0], ISCSI_SERVER_ADDRESS, ISCSI_PORT_STRING, ISCSI_USER_NAME, ISCSI_USER_PASS) // ))).andReturn(queryResult); // control.replay(); // resource.iscsiDiscover(action); // verify(backend); // } @Test public void testDeactivate() throws Exception { setUriInfo(setUpActionExpectations(VdcActionType.MaintananceNumberOfVdss, MaintananceNumberOfVdssParameters.class, new String[] { "VdsIdList" }, new Object[] { asList(GUIDS[0]) })); verifyActionResponse(resource.deactivate(new Action())); } @Test public void testInstall() throws Exception { setUpGetEntityExpectations(1); setUriInfo(setUpActionExpectations(VdcActionType.UpdateVds, UpdateVdsActionParameters.class, new String[] { "RootPassword" }, new Object[] { NAMES[2] })); Action action = new Action(); action.setRootPassword(NAMES[2]); verifyActionResponse(resource.install(action)); } @Test public void testCommitNetConfig() throws Exception { setUriInfo(setUpActionExpectations(VdcActionType.CommitNetworkChanges, VdsActionParameters.class, new String[] { "VdsId" }, new Object[] { GUIDS[0] })); verifyActionResponse(resource.commitNetConfig(new Action())); } @Test public void testManualFence() throws Exception { setUpGetEntityExpectations(1); setUriInfo(setUpActionExpectations(VdcActionType.FenceVdsManualy, FenceVdsManualyParameters.class, new String[] { "VdsId", "StoragePoolId" }, new Object[] { GUIDS[0], GUIDS[1] })); Action action = new Action(); action.setFenceType(FenceType.MANUAL.value()); verifyActionResponse(resource.fence(action)); } @Test public void testRestartFence() throws Exception { doTestFence(FenceType.RESTART, VdcActionType.RestartVds, FenceActionType.Restart); } @Test public void testStartFence() throws Exception { doTestFence(FenceType.START, VdcActionType.StartVds, FenceActionType.Start); } @Test public void testStopFence() throws Exception { doTestFence(FenceType.STOP, VdcActionType.StopVds, FenceActionType.Stop); } public void doTestFence(FenceType fenceType, VdcActionType actionType, FenceActionType fenceActionType) throws Exception { setUriInfo(setUpActionExpectations(actionType, FenceVdsActionParameters.class, new String[] { "VdsId", "Action" }, new Object[] { GUIDS[0], fenceActionType })); Action action = new Action(); action.setFenceType(fenceType.value()); verifyActionResponse(resource.fence(action)); } @Test public void testIncompleteInstall() throws Exception { setUpGetEntityExpectations(1); setUriInfo(setUpBasicUriExpectations()); control.replay(); try { resource.install(new Action()); fail("expected WebApplicationException on incomplete parameters"); } catch (WebApplicationException wae) { verifyIncompleteException(wae, "Action", "install", "rootPassword"); } } @Test public void testIncompleteFence() throws Exception { setUriInfo(setUpBasicUriExpectations()); control.replay(); try { resource.fence(new Action()); fail("expected WebApplicationException on incomplete parameters"); } catch (WebApplicationException wae) { verifyIncompleteException(wae, "Action", "fence", "fenceType"); } } @Test public void testStatisticalQuery() throws Exception { VDS entity = setUpStatisticalExpectations(); @SuppressWarnings("unchecked") BackendStatisticsResource<Host, VDS> statisticsResource = (BackendStatisticsResource<Host, VDS>)resource.getStatisticsResource(); assertNotNull(statisticsResource); verifyQuery(statisticsResource.getQuery(), entity); } @Test public void testFenceStatus() throws Exception { setUpEntityQueryExpectations(VdcQueryType.GetVdsFenceStatus, VdsIdParametersBase.class, new String[] {"VdsId"}, new Object[] {GUIDS[0]}, new FenceStatusReturnValue("on", "")); control.replay(); Action action = new Action(); action.setFenceType(FenceType.STATUS.value()); verifyActionResponse(resource.fence(action)); PowerManagementStatus status = PowerManagementStatus.fromValue(action.getPowerManagement().getStatus().getState()); assertTrue(status.equals(PowerManagementStatus.ON)); } @Test public void testFenceStatusFailure() throws Exception { setUpEntityQueryExpectations(VdcQueryType.GetVdsFenceStatus, VdsIdParametersBase.class, new String[] {"VdsId"}, new Object[] {GUIDS[0]}, new FenceStatusReturnValue("unknown", "some_error")); control.replay(); Action action = new Action(); action.setFenceType(FenceType.STATUS.value()); Response response = resource.fence(action); Action actionReturned = (Action)response.getEntity(); assertEquals(actionReturned.getStatus().getState(), CreationStatus.FAILED.value()); assertNotNull(actionReturned.getFault()); assertEquals(actionReturned.getFault().getReason(), "some_error"); } protected VDS setUpStatisticalExpectations() throws Exception { VdsStatistics stats = control.createMock(VdsStatistics.class); VDS entity = control.createMock(VDS.class); setUpStatisticalEntityExpectations(entity, stats); setUpGetEntityExpectations(1, false, entity); control.replay(); return entity; } protected void verifyQuery(AbstractStatisticalQuery<Host, VDS> query, VDS entity) throws Exception { assertEquals(Host.class, query.getParentType()); assertSame(entity, query.resolve(GUIDS[0])); List<Statistic> statistics = query.getStatistics(entity); verifyStatistics(statistics, new String[] {"memory.total", "memory.used", "memory.free", "memory.buffers", "memory.cached", "swap.total", "swap.free", "swap.used", "swap.cached", "ksm.cpu.current", "cpu.current.user", "cpu.current.system", "cpu.current.idle", "cpu.load.avg.5m"}, new BigDecimal[] {asDec(5120*Mb), asDec(1024*Mb), asDec(35*Mb), asDec(0), asDec(0), asDec(30*Mb), asDec(25*Mb), asDec(5*Mb), asDec(0), asDec(40), asDec(45), asDec(50), asDec(55), new BigDecimal(0.0060, new MathContext(2))}); Statistic adopted = query.adopt(new Statistic()); assertTrue(adopted.isSetHost()); assertEquals(GUIDS[0].toString(), adopted.getHost().getId()); } protected UriInfo setUpActionExpectations(VdcActionType task, Class<? extends VdcActionParametersBase> clz, String[] names, Object[] values) { return setUpActionExpectations(task, clz, names, values, true, true, null, null, true); } protected UriInfo setUpActionExpectations(VdcActionType task, Class<? extends VdcActionParametersBase> clz, String[] names, Object[] values, ArrayList<Guid> asyncTasks, ArrayList<AsyncTaskStatus> asyncStatuses) { String uri = "hosts/" + GUIDS[0] + "/action"; return setUpActionExpectations(task, clz, names, values, true, true, null, asyncTasks, asyncStatuses, uri, true); } protected void setUpGetEntityExpectations(int times) throws Exception { setUpGetEntityExpectations(times, false); } protected void setUpGetEntityExpectations(int times, boolean notFound) throws Exception { setUpGetEntityExpectations(times, notFound, getEntity(0)); } protected void setUpGetEntityExpectations(int times, boolean notFound, VDS entity) throws Exception { while (times-- > 0) { setUpGetEntityExpectations(VdcQueryType.GetVdsByVdsId, GetVdsByVdsIdParameters.class, new String[] { "VdsId" }, new Object[] { GUIDS[0] }, notFound ? null : entity); } } private void verifyActionResponse(Response r) throws Exception { verifyActionResponse(r, "hosts/" + GUIDS[0], false); } @Override protected VDS getEntity(int index) { VDS entity = setUpEntityExpectations(control.createMock(VDS.class), index); VdsStatic vdsStatic = control.createMock(VdsStatic.class); expect(vdsStatic.getId()).andReturn(GUIDS[index]).anyTimes(); expect(entity.getStaticData()).andReturn(vdsStatic).anyTimes(); expect(entity.getstorage_pool_id()).andReturn(GUIDS[1]).anyTimes(); return entity; } @Override protected void verifyModel(Host model, int index) { verifyModelSpecific(model, index); verifyLinks(model); } }