package org.cloudifysource.dsl;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import junit.framework.Assert;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.io.FileUtils;
import org.cloudifysource.domain.Application;
import org.cloudifysource.domain.Service;
import org.cloudifysource.domain.cloud.Cloud;
import org.cloudifysource.domain.entry.ExecutableDSLEntry;
import org.cloudifysource.dsl.internal.DSLException;
import org.cloudifysource.dsl.internal.DSLReader;
import org.cloudifysource.dsl.internal.DSLUtils;
import org.cloudifysource.dsl.internal.ServiceReader;
import org.junit.Test;
/**
*
* @author yael
*
*/
public class OverridesTest {
private static final String SERVICE_PATH =
"src/test/resources/overridesTest/services/cassandra";
private static final String EXTERNAL_OVERRIDES_SERVICE_PATH =
"src/test/resources/overridesTest/services/cassandraWithoutOverridesFile/cassandra";
private static final String SERVICE_EXTERNAL_OVERRIDES_FILE_PATH =
"src/test/resources/overridesTest/overridesFiles/cassandraWithoutOverridesFile.overrides";
private static final String APPLICATION_PATH =
"src/test/resources/overridesTest/apps/overridesTestApplication";
private static final String EXTERNAL_OVERRIDES_APPLICATION_PATH =
"src/test/resources/overridesTest/apps/overridesTestApplicationWithoutOverridesFile";
private static final String APPLICATION_EXTERNAL_OVERRIDES_FILE_PATH =
"src/test/resources/overridesTest/overridesFiles/overridesTestApplicationWithoutOverridesFile.overrides";
private static final String APPLICATION_SERVICE_PATH =
"src/test/resources/overridesTest/services/service1";
private static final String EC2_CLOUD_WITH_FILE_PATH = "testResources/cloud/ec2-overrides-with-file";
private static final String EC2_CLOUD_WITH_FILE_OVERRIDES_PATH =
"testResources/cloud/ec2-overrides-with-file/ec2-cloud.overrides";
private static final String EC2_CLOUD_WITH_SCRIPT_PATH = "testResources/cloud/ec2-overrides-with-script";
private static final Map<String, Object> SERVICE_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS =
new HashMap<String, Object>();
private static final Map<String, Object> APPLICATION_SERVICE_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS =
new HashMap<String, Object>();
private static final Map<String, Object> APPLICATION_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS =
new HashMap<String, Object>();
private static final Map<String, Object> APPLICATION_WITHOUT_OVERRIDES_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS =
new HashMap<String, Object>();
private static final Map<String, Object> EC2_CLOUD_OVERRIDES_PROPERTIES_MATCHING_FIELDS =
new HashMap<String, Object>();
private static final Integer NUM_INSTANCES = 5;
private static final Integer OVERRIDEN_NUM_INSTANCES = 3;
static {
// cloud with overrides file
EC2_CLOUD_OVERRIDES_PROPERTIES_MATCHING_FIELDS.put("myUser", "\"OverridesTestUser\"");
EC2_CLOUD_OVERRIDES_PROPERTIES_MATCHING_FIELDS.put("myApiKey", "\"OverridesTestApiKey\"");
EC2_CLOUD_OVERRIDES_PROPERTIES_MATCHING_FIELDS.put("myKeyPair", "\"OverridesTestApiKey\"");
// service with overrides file.
SERVICE_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS.put("name",
"overridesTest");
SERVICE_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS.put("numInstances",
OVERRIDEN_NUM_INSTANCES);
SERVICE_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS.put("lifecycle.init",
"overridesTest_install.groovy");
//service with overrides, application properties and application overrides files.
APPLICATION_SERVICE_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS.put(
"icon", "applicationIcon.png");
APPLICATION_SERVICE_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS.put(
"numInstances", OVERRIDEN_NUM_INSTANCES);
// application with overrides file.
APPLICATION_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS.put(
"services[0].icon", "applicationIcon.png");
APPLICATION_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS.put(
"services[0].numInstances", OVERRIDEN_NUM_INSTANCES);
APPLICATION_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS.put(
"services[1].icon", "applicationIcon.png");
APPLICATION_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS.put(
"services[1].numInstances", OVERRIDEN_NUM_INSTANCES);
APPLICATION_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS.put("name",
"overridesTestApplicationOverriden");
// application without an overrides file
// (test only the override of application properties of services properties).
APPLICATION_WITHOUT_OVERRIDES_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS
.put("services[0].icon", "applicationIcon.png");
APPLICATION_WITHOUT_OVERRIDES_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS
.put("services[0].numInstances", NUM_INSTANCES);
APPLICATION_WITHOUT_OVERRIDES_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS
.put("services[1].icon", "applicationIcon.png");
APPLICATION_WITHOUT_OVERRIDES_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS
.put("services[1].numInstances", NUM_INSTANCES);
APPLICATION_WITHOUT_OVERRIDES_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS
.put("name", "overridesTestApplication");
}
/**
*
* @throws IllegalAccessException .
* @throws InvocationTargetException .
* @throws NoSuchMethodException .
*/
@Test
public void testServiceExistingOverridesFile()
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
try {
testDSLOverrides(SERVICE_PATH, null, Service.class,
SERVICE_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS);
} catch (final DSLException e) {
fail("Failed to read service " + SERVICE_PATH + e);
}
}
/**
*
* @throws IllegalAccessException .
* @throws InvocationTargetException .
* @throws NoSuchMethodException .
*/
@Test
public void testServiceExternalOverridesFile()
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
try {
testDSLOverrides(EXTERNAL_OVERRIDES_SERVICE_PATH,
SERVICE_EXTERNAL_OVERRIDES_FILE_PATH, Service.class,
SERVICE_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS);
} catch (final DSLException e) {
fail("Failed to read application " + SERVICE_PATH + e);
}
}
/**
*
* @throws IllegalAccessException .
* @throws InvocationTargetException .
* @throws NoSuchMethodException .
*/
@Test
public void testServiceWithApplicationPropertiesAndOverridesFiles()
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
try {
testDSLOverrides(APPLICATION_SERVICE_PATH, null, Service.class,
APPLICATION_SERVICE_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS);
} catch (final DSLException e) {
fail("Failed to read application " + APPLICATION_SERVICE_PATH + e);
}
}
/**
*
* @throws IllegalAccessException .
* @throws InvocationTargetException .
* @throws NoSuchMethodException .
*/
@Test
public void testApplicationExistingOverridesFile()
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
try {
testDSLOverrides(APPLICATION_PATH, null, Application.class,
APPLICATION_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS);
} catch (final DSLException e) {
fail("Failed to read application " + APPLICATION_PATH + e);
}
}
/**
*
* @throws IllegalAccessException .
* @throws InvocationTargetException .
* @throws NoSuchMethodException .
*/
@Test
public void testApplicationExternalOverridesFile()
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
try {
testDSLOverrides(EXTERNAL_OVERRIDES_APPLICATION_PATH,
APPLICATION_EXTERNAL_OVERRIDES_FILE_PATH,
Application.class,
APPLICATION_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS);
} catch (final DSLException e) {
fail("Failed to read application "
+ EXTERNAL_OVERRIDES_APPLICATION_PATH + e);
}
}
/**
*
* @throws IllegalAccessException .
* @throws InvocationTargetException .
* @throws NoSuchMethodException .
*/
@Test
public void testApplicationWithoutOverridesFile()
throws IllegalAccessException, InvocationTargetException,
NoSuchMethodException {
try {
testDSLOverrides(EXTERNAL_OVERRIDES_APPLICATION_PATH, null,
Application.class,
APPLICATION_WITHOUT_OVERRIDES_OVERRIDEN_PROEPRTIES_MATCHING_FIELDS);
} catch (final DSLException e) {
fail("Failed to read application "
+ EXTERNAL_OVERRIDES_APPLICATION_PATH + e);
}
}
@Test
public void testCloudWithOverridesFile() throws IllegalAccessException,
InvocationTargetException, NoSuchMethodException, DSLException {
Cloud cloud = ServiceReader.readCloudFromDirectory(EC2_CLOUD_WITH_FILE_PATH);
// overriden props
Assert.assertEquals("OverridesTestUser", cloud.getUser().getUser());
Assert.assertEquals("OverridesTestApiKey", cloud.getUser().getApiKey());
Assert.assertEquals("OverridesTestKeyPair", (String) cloud.getCloudCompute().getTemplates().
get("SMALL_LINUX").getOptions().get("keyPair"));
Assert.assertEquals("OverridesTestImageId",
cloud.getCloudCompute().getTemplates().get("SMALL_LINUX").getImageId());
// not overrides, taken from .properties file
Assert.assertEquals("TestKeyFile.pem", cloud.getCloudCompute().getTemplates().get("SMALL_LINUX").getKeyFile());
}
@Test
public void testCloudWithOverridesScript() throws DSLException, IOException {
Cloud cloud = ServiceReader.readCloudFromDirectory(EC2_CLOUD_WITH_SCRIPT_PATH,
FileUtils.readFileToString(new File(EC2_CLOUD_WITH_FILE_OVERRIDES_PATH)));
// overriden props
Assert.assertEquals("OverridesTestUser", cloud.getUser().getUser());
Assert.assertEquals("OverridesTestApiKey", cloud.getUser().getApiKey());
Assert.assertEquals("OverridesTestKeyPair", (String) cloud.getCloudCompute().getTemplates().
get("SMALL_LINUX").getOptions().get("keyPair"));
Assert.assertEquals("OverridesTestImageId",
cloud.getCloudCompute().getTemplates().get("SMALL_LINUX").getImageId());
// not overrides, taken from .properties file
Assert.assertEquals("TestKeyFile.pem", cloud.getCloudCompute().getTemplates().get("SMALL_LINUX").getKeyFile());
}
private static Object testDSLOverrides(final String servicePath,
final String overridesFilePath, final Class<?> clazz,
final Map<String, Object> expectedFields) throws
IllegalAccessException, InvocationTargetException,
NoSuchMethodException, DSLException {
final File workDir = new File(servicePath);
final boolean isApplication = clazz.equals(Application.class);
final boolean isService = clazz.equals(Service.class);
final boolean isCloud = clazz.equals(Cloud.class);
File overridesFile = null;
if (overridesFilePath != null) {
overridesFile = new File(overridesFilePath);
}
final DSLReader reader = new DSLReader();
reader.setWorkDir(workDir);
reader.setRunningInGSC(true);
if (isApplication) {
reader.setDslFileNameSuffix(DSLUtils.APPLICATION_DSL_FILE_NAME_SUFFIX);
reader.addProperty(DSLUtils.APPLICATION_DIR,
workDir.getAbsolutePath());
reader.setCreateServiceContext(false);
} else if (isService) {
reader.setDslFileNameSuffix(DSLUtils.SERVICE_DSL_FILE_NAME_SUFFIX);
} else if (isCloud) {
reader.setDslFileNameSuffix(DSLUtils.CLOUD_DSL_FILE_NAME_SUFFIX);
reader.setCreateServiceContext(false);
} else {
throw new DSLException("Class " + clazz.getName() + " does not exist in the DSL Domain");
}
reader.setOverridesFile(overridesFile);
final Object object = reader.readDslEntity(clazz);
assertOverrides(object, reader, expectedFields, workDir);
return object;
}
private static void assertOverrides(final Object object, final DSLReader reader,
final Map<String, Object> expectedFields , final File workDirectory)
throws IllegalAccessException, InvocationTargetException, NoSuchMethodException {
final Set<Entry<String, Object>> entrySet = expectedFields.entrySet();
for (final Entry<String, Object> entry : entrySet) {
String fieldName = entry.getKey();
Object fieldValue = PropertyUtils.getNestedProperty(object, fieldName);
if (fieldValue instanceof ExecutableDSLEntry) {
fieldValue = fieldValue.toString();
}
Assert.assertEquals(entry.getValue(), fieldValue);
}
}
}