/** * Copyright (C) 2015 Orange * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.francetelecom.clara.cloud.test.database; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyListOf; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Matchers.isNull; import static org.mockito.Matchers.refEq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.reset; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyZeroInteractions; import java.util.ArrayList; import java.util.List; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; import org.mockito.Answers; import com.francetelecom.clara.cloud.commons.TechnicalException; import com.orange.clara.cloud.dbaas.wsdl.data.DatabaseUserInfo; import com.orange.clara.cloud.dbaas.wsdl.enumeration.BackupPlanWsEnum; import com.orange.clara.cloud.dbaas.wsdl.enumeration.DatabaseUserTypeWsEnum; import com.orange.clara.cloud.dbaas.wsdl.enumeration.EngineWsEnum; import com.orange.clara.cloud.dbaas.wsdl.enumeration.JobStateWsEnum; import com.orange.clara.cloud.dbaas.wsdl.enumeration.NetworkZoneWsEnum; import com.orange.clara.cloud.dbaas.wsdl.enumeration.ServiceClassWsEnum; import com.orange.clara.cloud.dbaas.wsdl.enumeration.SloWsEnum; import com.orange.clara.cloud.dbaas.wsdl.enumeration.UsageWsEnum; import com.orange.clara.cloud.dbaas.wsdl.service.DatabaseAlreadyExistsFault; import com.orange.clara.cloud.dbaas.wsdl.service.DbaasApiRemote; public class DbaasServiceTest { DbaasService sut = new DbaasService(); DbaasApiRemote dbaasStub = mock(DbaasApiRemote.class, Answers.RETURNS_DEEP_STUBS.get()); DbaasDatabase database = new DbaasDatabase(); /** * This rule is used to provide better assertions on expected exception (if any) */ @Rule public ExpectedException thrown= ExpectedException.none(); @Before public void setUp() throws Exception { sut.setDbaasStub(dbaasStub); sut.setDbaasGroupName("elpaaso"); // Database to be created database.setUser("testdbUser"); database.setName(null); database.setPassword("testDbPassword"); database.setEngine(EngineWsEnum.POSTGRESQL); database.setDescription("testDb description"); // configure dbaasStub mock (default) DbaasServiceTestUtils.configureDbaasStubCreateDatabase(dbaasStub, "generatedName", "generatedUUId"); DbaasServiceTestUtils.configureDbaasStubMockGetJob(dbaasStub, JobStateWsEnum.FINISHED, ""); DbaasServiceTestUtils.configureDbaasStubMockGetDatabaseDetails(dbaasStub, "192.168.1.100", "5406"); } @Test public void testCreate_success() throws Exception { // Given a database (created in setUp) // When create is called on a dbaas wrapper sut.createDatabase(database); List<DatabaseUserInfo> users = new ArrayList<DatabaseUserInfo>(); DatabaseUserInfo user = new DatabaseUserInfo(); user.setLogin(database.getUser()); user.setPassword(database.getPassword()); user.setDatabaseUserType(DatabaseUserTypeWsEnum.OWNER); users.add(user); // Then dbaas web service stub should have been called verify(dbaasStub).createDatabase( isNull(String.class), eq("elpaaso"), eq(1), eq(ServiceClassWsEnum.XXXS), eq(EngineWsEnum.POSTGRESQL), isNull(String.class), refEq(users), eq(SloWsEnum.STANDARD), eq(false), eq(UsageWsEnum.DEVTEST), eq("Default"), eq(NetworkZoneWsEnum.RSC), eq(""), eq("Default"), eq("Sun:20:00-04"), eq(BackupPlanWsEnum.NONE), eq("22:00-04"), eq(true), eq("testDb description")); } @Test public void testCreate_host_and_port_are_set() { // Exercise SUT sut.createDatabase(database); assertEquals("192.168.1.100",database.getHost()); assertEquals("5406", database.getPort()); } @Test public void testCreate_name_is_used_when_set() throws Exception { String specifiedDatabaseName = "my-database-name"; database.setName(specifiedDatabaseName); sut.createDatabase(database); // verify that specified name is used when calling dbaas web service verify(dbaasStub).createDatabase( eq(specifiedDatabaseName), eq("elpaaso"), anyInt(), any(ServiceClassWsEnum.class), any(EngineWsEnum.class), anyString(), anyListOf(DatabaseUserInfo.class), any(SloWsEnum.class), anyBoolean(), any(UsageWsEnum.class), anyString(), any(NetworkZoneWsEnum.class), anyString(), anyString(), anyString(), any(BackupPlanWsEnum.class), anyString(), anyBoolean(), anyString()); // verify that name is unchanged assertEquals(specifiedDatabaseName, database.getName()); } @Test public void testCreate_name_is_generated_when_not_set() throws Exception { DbaasServiceTestUtils.configureDbaasStubCreateDatabase(dbaasStub, "generatedName", "generatedUUId"); sut.createDatabase(database); assertNotNull("database name is not set", database.getName()); assertEquals("generatedName",database.getName()); } @Test public void testCreate_database_already_created() { // 1st call to create database sut.createDatabase(database); reset(dbaasStub); // 2nd call sut.createDatabase(database); verifyZeroInteractions(dbaasStub); } @Test public void testCreate_dbaas_failure() throws Exception { // Expected exception thrown.expectMessage("test error"); thrown.expect(TechnicalException.class); // configure dbaasStub mock to generate an error when task status is requested DbaasServiceTestUtils.configureDbaasStubMockGetJob(dbaasStub, JobStateWsEnum.ERROR, "test error"); // exercise sut sut.createDatabase(database); } @Test public void testCreate_dbaas_exception_database_name_already_exists_failure_when_name_is_set() throws Exception { // Expected exception thrown.expectMessage("databaseName already exist"); thrown.expect(TechnicalException.class); // set database name database.setName("mydatabase"); // configure dbaasStub mock to first generate an exception when create database Exception nameAlreadyExistException = new DatabaseAlreadyExistsFault("databaseName already exist"); DbaasServiceTestUtils.whenCreateDatabase(dbaasStub).thenThrow(nameAlreadyExistException); // exercise sut sut.createDatabase(database); } @Test public void testCreate_dbaas_timeout() throws Exception { // configure dbaasStub mock to to stay in PROCESSING state DbaasServiceTestUtils.configureDbaasStubMockGetJob(dbaasStub, JobStateWsEnum.PROCESSING, ""); // configure dbaasWrapper to time out after 100ms sut.setDbaasTimeout(100); // exercise sut TechnicalException caughtException = null; try { sut.createDatabase(database); } catch(TechnicalException e) { caughtException = e; } verify(dbaasStub).deleteDatabase(database.getUUId()); String errorMessage = caughtException.getMessage(); assertTrue("caught exception is not a timeout exception: "+ errorMessage, errorMessage.matches(".*timeout.*")); } @Test public void testDelete_sucess() throws Exception { // Given a database whose name, host and port are set String dbName = "myDatabase"; String dbUUId = "myDatabaseUUId"; database.setName(dbName); database.setUUId(dbUUId); database.setHost("host"); database.setPort("3456"); // When I request to delete the database sut.deleteDatabase(database); // Then delete operation of dbaas web service should have been called verify(dbaasStub).deleteDatabase(dbUUId); // And database should be tagged as deleted assertTrue(database.isDeleted()); } @Test public void testDelete_database_not_created() throws Exception { // Given a database whose host and port are not set String dbName = "myDatabase"; String dbUUId = "myDatabaseUUId"; database.setName(dbName); database.setUUId(dbUUId); database.setHost(null); database.setPort(null); // When I request to delete the database sut.deleteDatabase(database); // Then dbaas web service should not be called verify(dbaasStub, never()).deleteDatabase(anyString()); // And no exception is thrown } @Test public void testDelete_database_already_deleted() throws Exception { // Given a database whose is set as deleted database.setDeleted(true); // When I request to delete the database sut.deleteDatabase(database); // Then dbaas web service should not be called verify(dbaasStub, never()).deleteDatabase(anyString()); // And no exception is thrown } @Test public void testDelete_dbaas_failure() throws Exception { // Expected exception thrown.expectMessage("test error"); thrown.expect(TechnicalException.class); // Given a database that has been created (uuid, name, host and port are set) String dbName = "myDatabase"; String dbUUId = "myDatabaseUUId"; database.setName(dbName); database.setUUId(dbUUId); database.setHost("host"); database.setPort("5678"); // And dbaasStub mock configured to generate an error when task status is requested DbaasServiceTestUtils.configureDbaasStubMockGetJob(dbaasStub, JobStateWsEnum.ERROR, "test error"); // When deleteDatabase() is called sut.deleteDatabase(database); // Then expected exception shall be thrown } @Test public void testDelete_dbaas_timeout() throws Exception { // Given a database that has been created (uuid, name, host and port are set) String dbName = "myDatabase"; String dbUUId = "myDatabaseUUId"; database.setName(dbName); database.setUUId(dbUUId); database.setHost("host"); database.setPort("5678"); // Expected exception thrown.expectMessage("timeout"); thrown.expect(TechnicalException.class); // configure dbaasStub mock to to stay in PROCESSING state DbaasServiceTestUtils.configureDbaasStubMockGetJob(dbaasStub, JobStateWsEnum.PROCESSING, ""); // configure dbaasWrapper to time out after 100ms sut.setDbaasTimeout(100); // exercise sut sut.deleteDatabase(database); } }