diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/pom.xml b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/pom.xml
index ac0e713536..45674abeab 100644
--- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/pom.xml
+++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/pom.xml
@@ -223,9 +223,12 @@
- org.mockito
- mockito-core
- 2.10.0
+ org.powermock
+ powermock-api-mockito
+
+
+ org.powermock
+ powermock-module-testng
diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/dao/impl/ProfileDAOImpl.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/dao/impl/ProfileDAOImpl.java
index 32e00c03c4..1483e6ebc7 100644
--- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/dao/impl/ProfileDAOImpl.java
+++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/dao/impl/ProfileDAOImpl.java
@@ -180,7 +180,7 @@ public class ProfileDAOImpl implements ProfileDAO {
Connection conn;
PreparedStatement stmt = null;
ResultSet resultSet = null;
- Profile profile = new Profile();
+ Profile profile = null;
try {
conn = this.getConnection();
String query = "SELECT * FROM DM_PROFILE WHERE ID = ?";
@@ -189,7 +189,7 @@ public class ProfileDAOImpl implements ProfileDAO {
resultSet = stmt.executeQuery();
while (resultSet.next()) {
-
+ profile = new Profile();
profile.setProfileId(profileId);
profile.setProfileName(resultSet.getString("PROFILE_NAME"));
profile.setTenantId(resultSet.getInt("TENANT_ID"));
diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/mgt/impl/ProfileManagerImpl.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/mgt/impl/ProfileManagerImpl.java
index ada8b58763..bf1e00e165 100644
--- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/mgt/impl/ProfileManagerImpl.java
+++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/main/java/org/wso2/carbon/policy/mgt/core/mgt/impl/ProfileManagerImpl.java
@@ -20,12 +20,17 @@ package org.wso2.carbon.policy.mgt.core.mgt.impl;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
-import org.wso2.carbon.device.mgt.core.dao.DeviceTypeDAO;
import org.wso2.carbon.device.mgt.common.policy.mgt.Profile;
import org.wso2.carbon.device.mgt.common.policy.mgt.ProfileFeature;
+import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
+import org.wso2.carbon.device.mgt.core.dao.DeviceTypeDAO;
import org.wso2.carbon.policy.mgt.common.ProfileManagementException;
-import org.wso2.carbon.policy.mgt.core.dao.*;
+import org.wso2.carbon.policy.mgt.core.dao.FeatureDAO;
+import org.wso2.carbon.policy.mgt.core.dao.FeatureManagerDAOException;
+import org.wso2.carbon.policy.mgt.core.dao.PolicyManagementDAOFactory;
+import org.wso2.carbon.policy.mgt.core.dao.PolicyManagerDAOException;
+import org.wso2.carbon.policy.mgt.core.dao.ProfileDAO;
+import org.wso2.carbon.policy.mgt.core.dao.ProfileManagerDAOException;
import org.wso2.carbon.policy.mgt.core.mgt.ProfileManager;
import java.sql.SQLException;
@@ -143,6 +148,9 @@ public class ProfileManagerImpl implements ProfileManager {
try {
PolicyManagementDAOFactory.openConnection();
profile = profileDAO.getProfile(profileId);
+ if (profile == null) {
+ throw new ProfileManagementException("Profile is not available with profile id (" + profileId + ")");
+ }
featureList = featureDAO.getFeaturesForProfile(profileId);
profile.setProfileFeaturesList(featureList);
} catch (ProfileManagerDAOException e) {
diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/BasePolicyManagementDAOTest.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/BasePolicyManagementDAOTest.java
index 9e86417fd0..a8a1718418 100644
--- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/BasePolicyManagementDAOTest.java
+++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/BasePolicyManagementDAOTest.java
@@ -21,45 +21,106 @@ package org.wso2.carbon.policy.mgt.core;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.tomcat.jdbc.pool.PoolProperties;
+import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.BeforeSuite;
+import org.testng.internal.collections.Pair;
import org.w3c.dom.Document;
import org.wso2.carbon.base.MultitenantConstants;
import org.wso2.carbon.context.PrivilegedCarbonContext;
+import org.wso2.carbon.device.mgt.common.Device;
+import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
+import org.wso2.carbon.device.mgt.common.DeviceManagementException;
+import org.wso2.carbon.device.mgt.common.DeviceNotFoundException;
+import org.wso2.carbon.device.mgt.common.EnrolmentInfo;
+import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
+import org.wso2.carbon.device.mgt.common.group.mgt.GroupAlreadyExistException;
+import org.wso2.carbon.device.mgt.common.group.mgt.GroupManagementException;
+import org.wso2.carbon.device.mgt.common.policy.mgt.Profile;
+import org.wso2.carbon.device.mgt.core.authorization.DeviceAccessAuthorizationServiceImpl;
import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
import org.wso2.carbon.device.mgt.core.dao.DeviceManagementDAOFactory;
import org.wso2.carbon.device.mgt.core.dao.GroupManagementDAOFactory;
+import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
+import org.wso2.carbon.device.mgt.core.internal.DeviceManagementServiceComponent;
import org.wso2.carbon.device.mgt.core.operation.mgt.dao.OperationManagementDAOFactory;
+import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService;
+import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl;
+import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderService;
+import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderServiceImpl;
import org.wso2.carbon.ntask.common.TaskException;
+import org.wso2.carbon.policy.mgt.common.PolicyEvaluationPoint;
import org.wso2.carbon.policy.mgt.common.PolicyManagementException;
import org.wso2.carbon.policy.mgt.core.common.DataSourceConfig;
import org.wso2.carbon.policy.mgt.core.dao.PolicyManagementDAOFactory;
+import org.wso2.carbon.policy.mgt.core.internal.PolicyManagementDataHolder;
+import org.wso2.carbon.policy.mgt.core.mgt.ProfileManager;
+import org.wso2.carbon.policy.mgt.core.mgt.impl.ProfileManagerImpl;
+import org.wso2.carbon.policy.mgt.core.services.SimplePolicyEvaluationTest;
import org.wso2.carbon.policy.mgt.core.util.PolicyManagerUtil;
+import org.wso2.carbon.registry.core.config.RegistryContext;
+import org.wso2.carbon.registry.core.exceptions.RegistryException;
+import org.wso2.carbon.registry.core.internal.RegistryDataHolder;
+import org.wso2.carbon.registry.core.jdbc.realm.InMemoryRealmService;
+import org.wso2.carbon.registry.core.service.RegistryService;
+import org.wso2.carbon.user.core.service.RealmService;
import javax.sql.DataSource;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import java.io.File;
+import java.io.InputStream;
+import java.lang.reflect.Field;
import java.sql.Connection;
+import java.sql.DatabaseMetaData;
import java.sql.Statement;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
public abstract class BasePolicyManagementDAOTest {
private DataSource dataSource;
private static final Log log = LogFactory.getLog(BasePolicyManagementDAOTest.class);
+ protected DeviceManagementProviderService deviceMgtService;
+ protected GroupManagementProviderService groupMgtService;
+ protected ProfileManager profileManager;
+
+ private static final String ADMIN_USER = "admin";
+
@BeforeSuite
public void setupDataSource() throws Exception {
this.initDatSource();
this.initSQLScript();
- this.initialize();
this.initiatePrivilegedCaronContext();
DeviceConfigurationManager.getInstance().initConfig();
}
- public void initialize() throws TaskException {
+ protected void initializeServices() throws Exception{
+ initSQLScript();
+
+ DeviceConfigurationManager.getInstance().initConfig();
+
+ deviceMgtService = new DeviceManagementProviderServiceImpl();
+ groupMgtService = new GroupManagementProviderServiceImpl();
+
+ DeviceManagementServiceComponent.notifyStartupListeners();
+ DeviceManagementDataHolder.getInstance().setDeviceManagementProvider(deviceMgtService);
+ DeviceManagementDataHolder.getInstance().setRegistryService(getRegistryService());
+ DeviceManagementDataHolder.getInstance().setDeviceAccessAuthorizationService(
+ new DeviceAccessAuthorizationServiceImpl());
+ DeviceManagementDataHolder.getInstance().setGroupManagementProviderService(groupMgtService);
+ DeviceManagementDataHolder.getInstance().setDeviceTaskManagerService(null);
+
+ PolicyEvaluationPoint policyEvaluationPoint = new SimplePolicyEvaluationTest();
+ PolicyManagementDataHolder.getInstance().setPolicyEvaluationPoint("Simple", policyEvaluationPoint);
+ PolicyManagementDataHolder.getInstance().setDeviceManagementService(deviceMgtService);
+ profileManager = new ProfileManagerImpl();
}
public void initDatSource() throws Exception {
@@ -98,9 +159,6 @@ public abstract class BasePolicyManagementDAOTest {
}
- @BeforeClass
- public abstract void init() throws Exception;
-
private DataSource getDataSource(DataSourceConfig config) {
PoolProperties properties = new PoolProperties();
properties.setUrl(config.getUrl());
@@ -138,4 +196,102 @@ public abstract class BasePolicyManagementDAOTest {
return dataSource;
}
+
+ protected Object changeFieldValue(Object targetObj, String fieldName, Object valueObj)
+ throws IllegalAccessException, NoSuchFieldException {
+ Field field = targetObj.getClass().getDeclaredField(fieldName);
+ field.setAccessible(true);
+ Object oldVal = field.get(targetObj);
+ field.set(targetObj, valueObj);
+ return oldVal;
+ }
+
+ protected RegistryService getRegistryService() throws RegistryException {
+ RealmService realmService = new InMemoryRealmService();
+ RegistryDataHolder.getInstance().setRealmService(realmService);
+ DeviceManagementDataHolder.getInstance().setRealmService(realmService);
+ InputStream is = this.getClass().getClassLoader().getResourceAsStream(
+ "carbon-home/repository/conf/registry.xml");
+ RegistryContext context = RegistryContext.getBaseInstance(is, realmService);
+ context.setSetup(true);
+ return context.getEmbeddedRegistryService();
+ }
+
+ protected boolean enrollDevice(String deviceName, String deviceType) {
+ boolean success = false;
+ EnrolmentInfo enrolmentInfo = new EnrolmentInfo(
+ ADMIN_USER, EnrolmentInfo.OwnerShip.BYOD, EnrolmentInfo.Status.ACTIVE);
+ Device device1 = new Device(deviceName, deviceType, deviceName, deviceName, enrolmentInfo, null, null);
+ try {
+ success = deviceMgtService.enrollDevice(device1);
+ } catch (DeviceManagementException e) {
+ String msg = "Failed to enroll a device.";
+ log.error(msg, e);
+ Assert.fail();
+ }
+ return success;
+ }
+
+ protected void createDeviceGroup(String groupName) {
+ DeviceGroup deviceGroup = new DeviceGroup(groupName);
+ deviceGroup.setDescription(groupName);
+ deviceGroup.setOwner(ADMIN_USER);
+ try {
+ groupMgtService.createGroup(deviceGroup, null, null);
+ } catch (GroupAlreadyExistException | GroupManagementException e) {
+ String msg = "Failed to create group: " + groupName;
+ log.error(msg, e);
+ Assert.fail(msg);
+ }
+ }
+
+ protected void addDeviceToGroup(DeviceIdentifier deviceIdentifier, String groupName) {
+ List groupDevices = new ArrayList<>();
+ groupDevices.add(deviceIdentifier);
+ try {
+ DeviceGroup group = groupMgtService.getGroup(groupName);
+ groupMgtService.addDevices(group.getGroupId(), groupDevices);
+ } catch (DeviceNotFoundException | GroupManagementException e) {
+ String msg = "Failed to add device " + deviceIdentifier.getId() + " to group " + groupName;
+ log.error(msg, e);
+ Assert.fail(msg);
+ }
+ }
+
+ public interface Command {
+ void call(Profile profile) throws Exception;
+ }
+
+ protected void testThrowingException(Profile profile, Command command, String fieldName, Object mockObj,
+ Class> exceptionClass) throws Exception {
+ Object oldObj = changeFieldValue(profileManager, fieldName, mockObj);
+ try {
+ command.call(profile);
+ } catch (Exception e) {
+ if (!(e.getCause().getClass().getName().equals(exceptionClass.getName()))) {
+ throw e;
+ }
+ } finally {
+ changeFieldValue(profileManager, fieldName, oldObj);
+ }
+ }
+
+ protected Pair> mockConnection() throws Exception {
+ //Throwing PolicyManagerDAOException while adding profile
+ DatabaseMetaData databaseMetaData = mock(DatabaseMetaData.class);
+ when(databaseMetaData.getDatabaseProductName()).thenReturn("H2");
+
+ Connection conn = mock(Connection.class);
+ when(conn.getMetaData()).thenReturn(databaseMetaData);
+
+ DataSource dataSource = mock(DataSource.class);
+ when(dataSource.getConnection()).thenReturn(conn);
+
+ Field dataSourceField = PolicyManagementDAOFactory.class.getDeclaredField("dataSource");
+ dataSourceField.setAccessible(true);
+ DataSource oldDataSource = (DataSource) dataSourceField.get(null);
+ PolicyManagementDAOFactory.init(dataSource);
+
+ return new Pair<>(conn, new Pair<>(oldDataSource, dataSource));
+ }
}
diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/MonitoringTestCase.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/MonitoringTestCase.java
index a2d8d4b725..e78f58ef8f 100644
--- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/MonitoringTestCase.java
+++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/MonitoringTestCase.java
@@ -52,12 +52,6 @@ public class MonitoringTestCase extends BasePolicyManagementDAOTest {
private DeviceIdentifier identifier = new DeviceIdentifier();
- @BeforeClass
- @Override
- public void init() throws Exception {
-
- }
-
@Test
public void testMonitorDao() {
diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/PolicyDAOTestCase.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/PolicyDAOTestCase.java
index d056f8a1ff..032acdb878 100644
--- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/PolicyDAOTestCase.java
+++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/PolicyDAOTestCase.java
@@ -52,14 +52,12 @@ public class PolicyDAOTestCase extends BasePolicyManagementDAOTest {
private static final Log log = LogFactory.getLog(PolicyDAOTestCase.class);
@BeforeClass
- @Override
public void init() throws Exception {
initDatSource();
// System.setProperty("GetTenantIDForTest", "Super");
initiatePrivilegedCaronContext();
}
-
@Test
public void addDeviceType() throws DeviceManagementDAOException {
try {
diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/PolicyEvaluationTestCase.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/PolicyEvaluationTestCase.java
index 03eb400364..2c47b72b21 100644
--- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/PolicyEvaluationTestCase.java
+++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/PolicyEvaluationTestCase.java
@@ -45,7 +45,6 @@ public class PolicyEvaluationTestCase extends BasePolicyManagementDAOTest {
@BeforeClass
- @Override
public void init() throws Exception {
PolicyEvaluationPoint evaluationPoint = new SimplePolicyEvaluationTest();
PolicyManagementDataHolder.getInstance().setPolicyEvaluationPoint(evaluationPoint.getName(), evaluationPoint);
diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/PolicyManagerServiceImplTest.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/PolicyManagerServiceImplTest.java
index e21fa59f4b..a218429863 100644
--- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/PolicyManagerServiceImplTest.java
+++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/PolicyManagerServiceImplTest.java
@@ -19,7 +19,6 @@ package org.wso2.carbon.policy.mgt.core;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.mockito.Spy;
import org.testng.Assert;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
@@ -59,7 +58,7 @@ import org.wso2.carbon.policy.mgt.common.PolicyEvaluationPoint;
import org.wso2.carbon.policy.mgt.common.PolicyManagementException;
import org.wso2.carbon.policy.mgt.core.enforcement.DelegationTask;
import org.wso2.carbon.policy.mgt.core.internal.PolicyManagementDataHolder;
-import org.wso2.carbon.policy.mgt.core.mock.TypeADeviceManagementService;
+import org.wso2.carbon.policy.mgt.core.mock.TypeXDeviceManagementService;
import org.wso2.carbon.policy.mgt.core.services.SimplePolicyEvaluationTest;
import org.wso2.carbon.policy.mgt.core.task.MonitoringTask;
import org.wso2.carbon.policy.mgt.core.task.TaskScheduleService;
@@ -90,8 +89,6 @@ public class PolicyManagerServiceImplTest extends BasePolicyManagementDAOTest {
public static final String DEVICE_2 = "device2";
public static final String DEVICE_TYPE_B = "deviceTypeB";
- private DeviceManagementProviderService deviceMgtService;
- private GroupManagementProviderService groupMgtService;
private OperationManager operationManager;
private PolicyManagerService policyManagerService;
private Profile profile;
@@ -100,75 +97,8 @@ public class PolicyManagerServiceImplTest extends BasePolicyManagementDAOTest {
@BeforeClass
public void init() throws Exception {
- super.initSQLScript();
-
- DeviceConfigurationManager.getInstance().initConfig();
log.info("Initializing policy tests");
-
- deviceMgtService = new DeviceManagementProviderServiceImpl();
- groupMgtService = new GroupManagementProviderServiceImpl();
-
- DeviceManagementServiceComponent.notifyStartupListeners();
- DeviceManagementDataHolder.getInstance().setDeviceManagementProvider(deviceMgtService);
- DeviceManagementDataHolder.getInstance().setRegistryService(getRegistryService());
- DeviceManagementDataHolder.getInstance().setDeviceAccessAuthorizationService(new DeviceAccessAuthorizationServiceImpl());
- DeviceManagementDataHolder.getInstance().setGroupManagementProviderService(groupMgtService);
- DeviceManagementDataHolder.getInstance().setDeviceTaskManagerService(null);
-
- PolicyEvaluationPoint policyEvaluationPoint = new SimplePolicyEvaluationTest();
- PolicyManagementDataHolder.getInstance().setPolicyEvaluationPoint("Simple", policyEvaluationPoint);
- PolicyManagementDataHolder.getInstance().setDeviceManagementService(deviceMgtService);
- }
-
- private RegistryService getRegistryService() throws RegistryException {
- RealmService realmService = new InMemoryRealmService();
- RegistryDataHolder.getInstance().setRealmService(realmService);
- DeviceManagementDataHolder.getInstance().setRealmService(realmService);
- InputStream is = this.getClass().getClassLoader().getResourceAsStream("carbon-home/repository/conf/registry.xml");
- RegistryContext context = RegistryContext.getBaseInstance(is, realmService);
- context.setSetup(true);
- return context.getEmbeddedRegistryService();
- }
-
- private boolean enrollDevice(String deviceName, String deviceType) {
- boolean success = false;
- EnrolmentInfo enrolmentInfo = new EnrolmentInfo(
- ADMIN_USER, EnrolmentInfo.OwnerShip.BYOD, EnrolmentInfo.Status.ACTIVE);
- Device device1 = new Device(deviceName, deviceType, deviceName, deviceName, enrolmentInfo, null, null);
- try {
- success = deviceMgtService.enrollDevice(device1);
- } catch (DeviceManagementException e) {
- String msg = "Failed to enroll a device.";
- log.error(msg, e);
- Assert.fail();
- }
- return success;
- }
-
- private void createDeviceGroup(String groupName) {
- DeviceGroup deviceGroup = new DeviceGroup(groupName);
- deviceGroup.setDescription(groupName);
- deviceGroup.setOwner(ADMIN_USER);
- try {
- groupMgtService.createGroup(deviceGroup, null, null);
- } catch (GroupAlreadyExistException | GroupManagementException e) {
- String msg = "Failed to create group: " + groupName;
- log.error(msg, e);
- Assert.fail(msg);
- }
- }
-
- private void addDeviceToGroup(DeviceIdentifier deviceIdentifier, String groupName) {
- List groupDevices = new ArrayList<>();
- groupDevices.add(deviceIdentifier);
- try {
- DeviceGroup group = groupMgtService.getGroup(groupName);
- groupMgtService.addDevices(group.getGroupId(), groupDevices);
- } catch (DeviceNotFoundException | GroupManagementException e) {
- String msg = "Failed to add device " + deviceIdentifier.getId() + " to group " + groupName;
- log.error(msg, e);
- Assert.fail(msg);
- }
+ super.initializeServices();
}
@Test
@@ -176,7 +106,7 @@ public class PolicyManagerServiceImplTest extends BasePolicyManagementDAOTest {
int tenantId = PrivilegedCarbonContext.getThreadLocalCarbonContext().getTenantId();
policyManagerService = new PolicyManagerServiceImpl();
- deviceMgtService.registerDeviceType(new TypeADeviceManagementService());
+ deviceMgtService.registerDeviceType(new TypeXDeviceManagementService(DEVICE_TYPE_A));
operationManager = new OperationManagerImpl(DEVICE_TYPE_A);
enrollDevice(DEVICE1, DEVICE_TYPE_A);
createDeviceGroup(GROUP1);
diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mgt/impl/ProfileManagerImplTest.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mgt/impl/ProfileManagerImplTest.java
new file mode 100644
index 0000000000..2cbcfc4e22
--- /dev/null
+++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mgt/impl/ProfileManagerImplTest.java
@@ -0,0 +1,349 @@
+package org.wso2.carbon.policy.mgt.core.mgt.impl;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.powermock.api.mockito.PowerMockito;
+import org.testng.Assert;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+import org.testng.internal.collections.Pair;
+import org.wso2.carbon.device.mgt.common.DeviceIdentifier;
+import org.wso2.carbon.device.mgt.common.IllegalTransactionStateException;
+import org.wso2.carbon.device.mgt.common.group.mgt.DeviceGroup;
+import org.wso2.carbon.device.mgt.common.operation.mgt.OperationManager;
+import org.wso2.carbon.device.mgt.common.policy.mgt.Profile;
+import org.wso2.carbon.device.mgt.common.policy.mgt.ProfileFeature;
+import org.wso2.carbon.device.mgt.core.authorization.DeviceAccessAuthorizationServiceImpl;
+import org.wso2.carbon.device.mgt.core.config.DeviceConfigurationManager;
+import org.wso2.carbon.device.mgt.core.internal.DeviceManagementDataHolder;
+import org.wso2.carbon.device.mgt.core.internal.DeviceManagementServiceComponent;
+import org.wso2.carbon.device.mgt.core.operation.mgt.OperationManagerImpl;
+import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderServiceImpl;
+import org.wso2.carbon.device.mgt.core.service.GroupManagementProviderServiceImpl;
+import org.wso2.carbon.policy.mgt.common.PolicyEvaluationPoint;
+import org.wso2.carbon.policy.mgt.common.ProfileManagementException;
+import org.wso2.carbon.policy.mgt.core.BasePolicyManagementDAOTest;
+import org.wso2.carbon.policy.mgt.core.PolicyManagerServiceImpl;
+import org.wso2.carbon.policy.mgt.core.dao.FeatureDAO;
+import org.wso2.carbon.policy.mgt.core.dao.FeatureManagerDAOException;
+import org.wso2.carbon.policy.mgt.core.dao.PolicyManagementDAOFactory;
+import org.wso2.carbon.policy.mgt.core.dao.ProfileDAO;
+import org.wso2.carbon.policy.mgt.core.dao.ProfileManagerDAOException;
+import org.wso2.carbon.policy.mgt.core.dao.impl.ProfileDAOImpl;
+import org.wso2.carbon.policy.mgt.core.internal.PolicyManagementDataHolder;
+import org.wso2.carbon.policy.mgt.core.mock.TypeXDeviceManagementService;
+import org.wso2.carbon.policy.mgt.core.services.SimplePolicyEvaluationTest;
+import org.wso2.carbon.policy.mgt.core.util.FeatureCreator;
+import org.wso2.carbon.policy.mgt.core.util.ProfileCreator;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.SQLException;
+
+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.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class ProfileManagerImplTest extends BasePolicyManagementDAOTest {
+ private static final Log log = LogFactory.getLog(PolicyManagerServiceImpl.class);
+
+ private static final String DEVICE3 = "device3";
+ private static final String GROUP3 = "group3";
+ private static final String POLICY3 = "policy3";
+ private static final String DEVICE_TYPE_C = "deviceTypeC";
+
+ private Profile profile1;
+ private OperationManager operationManager;
+
+ @BeforeClass
+ public void initialize() throws Exception {
+ log.info("Initializing policy manager tests");
+ super.initializeServices();
+ deviceMgtService.registerDeviceType(new TypeXDeviceManagementService(DEVICE_TYPE_C));
+ operationManager = new OperationManagerImpl(DEVICE_TYPE_C);
+ enrollDevice(DEVICE3, DEVICE_TYPE_C);
+ createDeviceGroup(GROUP3);
+ DeviceGroup group1 = groupMgtService.getGroup(GROUP3);
+ addDeviceToGroup(new DeviceIdentifier(DEVICE3, DEVICE_TYPE_C), GROUP3);
+ }
+
+ @Test(description = "This test case tests adding new profile")
+ public void testAddProfile() throws Exception {
+ //Creating profile object
+ Profile profile = ProfileCreator.getProfile(FeatureCreator.getFeatureList(), DEVICE_TYPE_C);
+ //Adding profile
+ profile1 = profileManager.addProfile(profile);
+ Assert.assertEquals(profile1.getProfileName(), profile.getProfileName());
+ Assert.assertEquals(profile1.getTenantId(), profile.getTenantId());
+ Assert.assertEquals(profile1.getDeviceType(), profile.getDeviceType());
+ }
+
+ @Test(description = "This test case tests handling ProfileManagerDAOException when adding new profile",
+ dependsOnMethods = "testAddProfile")
+ public void testAddProfileThrowingProfileManagerDAOException() throws Exception {
+ ProfileDAO profileDAO = mock(ProfileDAOImpl.class);
+ when(profileDAO.addProfile(any(Profile.class))).thenThrow(new ProfileManagerDAOException());
+ //Creating profile object
+ Profile profile = ProfileCreator.getProfile(FeatureCreator.getFeatureList(), DEVICE_TYPE_C);
+ testThrowingException(profile, p -> profileManager.addProfile(p), "profileDAO", profileDAO,
+ ProfileManagerDAOException.class);
+ }
+
+ @Test(description = "This test case tests handling FeatureManagerDAOException when adding new profile",
+ dependsOnMethods = "testAddProfileThrowingProfileManagerDAOException")
+ public void testAddProfileThrowingFeatureManagerDAOException() throws Exception {
+ FeatureDAO featureDAO = mock(FeatureDAO.class);
+ when(featureDAO.addProfileFeatures(anyListOf(ProfileFeature.class), anyInt())).thenThrow(
+ new FeatureManagerDAOException());
+ //Creating profile object
+ Profile profile = ProfileCreator.getProfile(FeatureCreator.getFeatureList(), DEVICE_TYPE_C);
+ testThrowingException(profile, p -> profileManager.addProfile(p), "featureDAO", featureDAO,
+ FeatureManagerDAOException.class);
+ }
+
+ @Test(description = "This test case tests handling SQLException when adding new profile",
+ dependsOnMethods = "testAddProfileThrowingFeatureManagerDAOException",
+ expectedExceptions = IllegalTransactionStateException.class)
+ public void testAddProfileThrowingIllegalTransactionStateException() throws Exception {
+ //Creating profile object
+ Profile profile = ProfileCreator.getProfile(FeatureCreator.getFeatureList(), DEVICE_TYPE_C);
+ Pair> pair = mockConnection();
+ PowerMockito.doThrow(new SQLException()).when(pair.first()).setAutoCommit(anyBoolean());
+ try {
+ profileManager.addProfile(profile);
+ } finally {
+ PolicyManagementDAOFactory.init(pair.second().first());
+ }
+ }
+
+ @Test(description = "This test case tests updating profile",
+ dependsOnMethods = "testAddProfile")
+ public void testUpdateProfile() throws Exception {
+ String newProfileName = "Updated Test Profile";
+ Profile savedProfile = profileManager.getProfile(profile1.getProfileId());
+ savedProfile.setProfileName(newProfileName);
+ Profile updateProfile = profileManager.updateProfile(savedProfile);
+ Assert.assertEquals(updateProfile.getProfileName(), newProfileName);
+ }
+
+ @Test(description = "This test case tests handling ProfileManagerDAOException when updating profile",
+ dependsOnMethods = "testUpdateProfile")
+ public void testUpdateProfileThrowingProfileManagerDAOException() throws Exception {
+ ProfileDAO profileDAO = mock(ProfileDAOImpl.class);
+ when(profileDAO.updateProfile(any(Profile.class))).thenThrow(new ProfileManagerDAOException());
+
+ String newProfileName = "Updated Test Profile";
+ Profile savedProfile = profileManager.getProfile(profile1.getProfileId());
+ savedProfile.setProfileName(newProfileName);
+ testThrowingException(savedProfile, p -> profileManager.updateProfile(p), "profileDAO", profileDAO,
+ ProfileManagerDAOException.class);
+ }
+
+ @Test(description = "This test case tests handling FeatureManagerDAOException when updating profile",
+ dependsOnMethods = "testUpdateProfileThrowingProfileManagerDAOException")
+ public void testUpdateProfileThrowingFeatureManagerDAOException() throws Exception {
+ FeatureDAO featureDAO = mock(FeatureDAO.class);
+ when(featureDAO.updateProfileFeatures(anyListOf(ProfileFeature.class), anyInt())).thenThrow(
+ new FeatureManagerDAOException());
+
+ String newProfileName = "Updated Test Profile";
+ Profile savedProfile = profileManager.getProfile(profile1.getProfileId());
+ savedProfile.setProfileName(newProfileName);
+ testThrowingException(savedProfile, p -> profileManager.updateProfile(p), "featureDAO", featureDAO,
+ FeatureManagerDAOException.class);
+ }
+
+ @Test(description = "This test case tests handling SQLException when updating profile",
+ dependsOnMethods = {"testUpdateProfileThrowingFeatureManagerDAOException"},
+ expectedExceptions = IllegalTransactionStateException.class)
+ public void testUpdateProfileThrowingIllegalTransactionStateException() throws Exception {
+ //Retrieving profile object
+ Profile savedProfile = profileManager.getProfile(profile1.getProfileId());
+
+ Pair> pair = mockConnection();
+ PowerMockito.doThrow(new SQLException()).when(pair.first()).setAutoCommit(anyBoolean());
+
+ String newProfileName = "Updated Test Profile";
+ savedProfile.setProfileName(newProfileName);
+ try {
+ profileManager.updateProfile(savedProfile);
+ } finally {
+ PolicyManagementDAOFactory.init(pair.second().first());
+ }
+ }
+
+ @Test(description = "This test case tests retrieving profile", dependsOnMethods = "testAddProfile")
+ public void testGetProfile() throws Exception {
+ Profile savedProfile = profileManager.getProfile(profile1.getProfileId());
+ Assert.assertEquals(profile1.getProfileName(), savedProfile.getProfileName());
+ Assert.assertEquals(profile1.getTenantId(), savedProfile.getTenantId());
+ Assert.assertEquals(profile1.getDeviceType(), savedProfile.getDeviceType());
+ }
+
+ @Test(description = "This test case tests retrieving non existent profile", dependsOnMethods = "testGetProfile",
+ expectedExceptions = ProfileManagementException.class)
+ public void testGetProfileThrowingProfileManagementException() throws Exception {
+ int nonExistentProfileId = 9999;
+ profileManager.getProfile(nonExistentProfileId);
+ }
+
+ @Test(description = "This test case tests handling ProfileManagerDAOException when retrieving profile",
+ dependsOnMethods = "testGetProfile")
+ public void testGetProfileThrowingProfileManagerDAOException() throws Exception {
+ ProfileDAO profileDAO = mock(ProfileDAOImpl.class);
+ when(profileDAO.getProfile(anyInt())).thenThrow(new ProfileManagerDAOException());
+ testThrowingException(profile1, p -> profileManager.getProfile(p.getProfileId()), "profileDAO", profileDAO,
+ ProfileManagerDAOException.class);
+ }
+
+ @Test(description = "This test case tests handling FeatureManagerDAOException when retrieving profile",
+ dependsOnMethods = "testGetProfileThrowingProfileManagerDAOException")
+ public void testGetProfileThrowingFeatureManagerDAOException() throws Exception {
+ FeatureDAO featureDAO = mock(FeatureDAO.class);
+ when(featureDAO.getFeaturesForProfile(anyInt())).thenThrow(new FeatureManagerDAOException());
+ testThrowingException(profile1, p -> profileManager.getProfile(p.getProfileId()), "featureDAO", featureDAO,
+ FeatureManagerDAOException.class);
+ }
+
+ @Test(description = "This test case tests handling SQLException when retrieving profile",
+ dependsOnMethods = "testGetProfileThrowingFeatureManagerDAOException",
+ expectedExceptions = IllegalTransactionStateException.class)
+ public void testGetProfileThrowingIllegalTransactionStateException() throws Exception {
+ //Creating profile object
+ Pair> pair = mockConnection();
+ PowerMockito.doThrow(new SQLException()).when(pair.second().second()).getConnection();
+
+ try {
+ profileManager.getProfile(profile1.getProfileId());
+ } finally {
+ PolicyManagementDAOFactory.init(pair.second().first());
+ }
+ }
+
+ @Test(description = "This test case tests retrieving all profiles",
+ dependsOnMethods = "testAddProfile")
+ public void testGetAllProfiles() throws Exception {
+ profileManager.getAllProfiles();
+ }
+
+ @Test(description = "This test case tests handling ProfileManagerDAOException when retrieving all profiles",
+ dependsOnMethods = "testGetAllProfiles")
+ public void testGetAllProfilesThrowingProfileManagerDAOException() throws Exception {
+ ProfileDAO profileDAO = mock(ProfileDAOImpl.class);
+ when(profileDAO.getAllProfiles()).thenThrow(new ProfileManagerDAOException());
+ testThrowingException(profile1, p -> profileManager.getAllProfiles(), "profileDAO", profileDAO,
+ ProfileManagerDAOException.class);
+ }
+
+ @Test(description = "This test case tests handling FeatureManagerDAOException when retrieving all profiles",
+ dependsOnMethods = "testGetAllProfilesThrowingProfileManagerDAOException")
+ public void testGetAllProfilesThrowingFeatureManagerDAOException() throws Exception {
+ FeatureDAO featureDAO = mock(FeatureDAO.class);
+ when(featureDAO.getAllProfileFeatures()).thenThrow(new FeatureManagerDAOException());
+ testThrowingException(profile1, p -> profileManager.getAllProfiles(), "featureDAO", featureDAO,
+ FeatureManagerDAOException.class);
+ }
+
+ @Test(description = "This test case tests handling SQLException when retrieving all profiles",
+ dependsOnMethods = "testGetAllProfilesThrowingFeatureManagerDAOException",
+ expectedExceptions = IllegalTransactionStateException.class)
+ public void testGetAllProfilesThrowingIllegalTransactionStateException() throws Exception {
+ //Creating profile object
+ Pair> pair = mockConnection();
+ PowerMockito.doThrow(new SQLException()).when(pair.second().second()).getConnection();
+
+ try {
+ profileManager.getAllProfiles();
+ } finally {
+ PolicyManagementDAOFactory.init(pair.second().first());
+ }
+ }
+
+ @Test(description = "This test case tests retrieving profiles of a device type",
+ dependsOnMethods = "testAddProfile")
+ public void testGetProfilesOfDeviceType() throws Exception {
+ profileManager.getProfilesOfDeviceType(DEVICE_TYPE_C);
+ }
+
+ @Test(description = "This test case tests handling ProfileManagerDAOException when retrieving all profiles of a " +
+ "device type",
+ dependsOnMethods = "testGetProfilesOfDeviceType")
+ public void testGetProfilesOfDeviceTypeThrowingProfileManagerDAOException() throws Exception {
+ ProfileDAO profileDAO = mock(ProfileDAOImpl.class);
+ when(profileDAO.getProfilesOfDeviceType(anyString())).thenThrow(new ProfileManagerDAOException());
+ testThrowingException(profile1, p -> profileManager.getProfilesOfDeviceType(DEVICE_TYPE_C), "profileDAO",
+ profileDAO,
+ ProfileManagerDAOException.class);
+ }
+
+ @Test(description = "This test case tests handling FeatureManagerDAOException when retrieving all profiles of a " +
+ "device type",
+ dependsOnMethods = "testGetProfilesOfDeviceTypeThrowingProfileManagerDAOException")
+ public void testGetProfilesOfDeviceTypeThrowingFeatureManagerDAOException() throws Exception {
+ FeatureDAO featureDAO = mock(FeatureDAO.class);
+ when(featureDAO.getAllProfileFeatures()).thenThrow(new FeatureManagerDAOException());
+ testThrowingException(profile1, p -> profileManager.getProfilesOfDeviceType(DEVICE_TYPE_C), "featureDAO",
+ featureDAO,
+ FeatureManagerDAOException.class);
+ }
+
+ @Test(description = "This test case tests handling SQLException when retrieving all profiles of a device type",
+ dependsOnMethods = "testGetProfilesOfDeviceTypeThrowingFeatureManagerDAOException",
+ expectedExceptions = IllegalTransactionStateException.class)
+ public void testGetProfilesOfDeviceTypeThrowingIllegalTransactionStateException() throws Exception {
+ //Creating profile object
+ Pair> pair = mockConnection();
+ PowerMockito.doThrow(new SQLException()).when(pair.second().second()).getConnection();
+
+ try {
+ profileManager.getProfilesOfDeviceType(DEVICE_TYPE_C);
+ } finally {
+ PolicyManagementDAOFactory.init(pair.second().first());
+ }
+ }
+
+ @Test(description = "This test case tests handling ProfileManagerDAOException when deleting a profile",
+ dependsOnMethods = "testGetProfilesOfDeviceTypeThrowingIllegalTransactionStateException")
+ public void testDeleteProfileThrowingProfileManagerDAOException() throws Exception {
+ ProfileDAO profileDAO = mock(ProfileDAOImpl.class);
+ when(profileDAO.deleteProfile(any(Profile.class))).thenThrow(new ProfileManagerDAOException());
+ testThrowingException(profile1, p -> profileManager.deleteProfile(profile1), "profileDAO", profileDAO,
+ ProfileManagerDAOException.class);
+ }
+
+ @Test(description = "This test case tests handling FeatureManagerDAOException when deleting a profile",
+ dependsOnMethods = "testDeleteProfileThrowingProfileManagerDAOException")
+ public void testDeleteProfileThrowingFeatureManagerDAOException() throws Exception {
+ FeatureDAO featureDAO = mock(FeatureDAO.class);
+ when(featureDAO.deleteFeaturesOfProfile(any(Profile.class))).thenThrow(new FeatureManagerDAOException());
+ testThrowingException(profile1, p -> profileManager.deleteProfile(profile1), "featureDAO", featureDAO,
+ FeatureManagerDAOException.class);
+ }
+
+ @Test(description = "This test case tests handling SQLException when deleting a profile",
+ dependsOnMethods = "testDeleteProfileThrowingFeatureManagerDAOException",
+ expectedExceptions = IllegalTransactionStateException.class)
+ public void testDeleteProfileThrowingIllegalTransactionStateException() throws Exception {
+ //Creating profile object
+ Pair> pair = mockConnection();
+ PowerMockito.doThrow(new SQLException()).when(pair.second().second()).getConnection();
+
+ try {
+ profileManager.deleteProfile(profile1);
+ } finally {
+ PolicyManagementDAOFactory.init(pair.second().first());
+ }
+ }
+
+ @Test(description = "This test case tests deleting a profile",
+ dependsOnMethods = "testDeleteProfileThrowingIllegalTransactionStateException",
+ expectedExceptions = {ProfileManagementException.class})
+ public void testDeleteProfile() throws Exception {
+ profileManager.deleteProfile(profile1);
+ Profile savedProfile = profileManager.getProfile(profile1.getProfileId());
+ }
+}
\ No newline at end of file
diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mock/TypeADeviceManagementService.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mock/TypeXDeviceManagementService.java
similarity index 93%
rename from components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mock/TypeADeviceManagementService.java
rename to components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mock/TypeXDeviceManagementService.java
index df070ab3c2..93fa5c6207 100644
--- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mock/TypeADeviceManagementService.java
+++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/mock/TypeXDeviceManagementService.java
@@ -32,12 +32,12 @@ import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService;
import java.util.ArrayList;
-public class TypeADeviceManagementService implements DeviceManagementService {
+public class TypeXDeviceManagementService implements DeviceManagementService {
- public static String DEVICE_TYPE = "deviceTypeA";
+ private String deviceType;
- public TypeADeviceManagementService() {
- super();
+ public TypeXDeviceManagementService(String deviceType) {
+ this.deviceType = deviceType;
}
@Override
@@ -47,7 +47,7 @@ public class TypeADeviceManagementService implements DeviceManagementService {
@Override
public String getType() {
- return DEVICE_TYPE;
+ return deviceType;
}
@Override
diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/util/ProfileCreator.java b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/util/ProfileCreator.java
index b1d05d969f..21a49c4e9a 100644
--- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/util/ProfileCreator.java
+++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/java/org/wso2/carbon/policy/mgt/core/util/ProfileCreator.java
@@ -27,11 +27,15 @@ import java.util.List;
public class ProfileCreator {
public static Profile getProfile(List features) {
+ return getProfile(features, "android");
+ }
+
+ public static Profile getProfile(List features, String deviceType) {
Profile profile = new Profile();
profile.setProfileFeaturesList(ProfileFeatureCreator.getProfileFeature(features));
profile.setProfileName("Test Profile");
profile.setTenantId(MultitenantConstants.SUPER_TENANT_ID);
- profile.setDeviceType("android");
+ profile.setDeviceType(deviceType);
return profile;
}
diff --git a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/resources/testng.xml b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/resources/testng.xml
index 5daa8c13ed..06da4bd27d 100644
--- a/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/resources/testng.xml
+++ b/components/policy-mgt/org.wso2.carbon.policy.mgt.core/src/test/resources/testng.xml
@@ -32,11 +32,12 @@
-
+
-
-
+
+
+
\ No newline at end of file