You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stratos.apache.org by re...@apache.org on 2015/08/21 13:04:00 UTC

[2/4] stratos git commit: adding user test case and scale-down test case

adding user test case and scale-down test case


Project: http://git-wip-us.apache.org/repos/asf/stratos/repo
Commit: http://git-wip-us.apache.org/repos/asf/stratos/commit/961a60f7
Tree: http://git-wip-us.apache.org/repos/asf/stratos/tree/961a60f7
Diff: http://git-wip-us.apache.org/repos/asf/stratos/diff/961a60f7

Branch: refs/heads/master
Commit: 961a60f73abb379b0b6b99038c2b9480888c428c
Parents: cb2b62a
Author: reka <rt...@gmail.com>
Authored: Fri Aug 21 12:36:19 2015 +0530
Committer: reka <rt...@gmail.com>
Committed: Fri Aug 21 12:46:29 2015 +0530

----------------------------------------------------------------------
 .../integration/tests/RestConstants.java        |   3 +
 .../tests/StratosTestServerManager.java         |   2 +
 .../application/SingleClusterScalingTest.java   | 121 ++++++++
 .../integration/tests/users/TenantTest.java     |  44 +++
 .../integration/tests/users/UserTest.java       |  94 +++++-
 .../src/test/resources/mock-iaas.xml            |   4 +-
 .../integration/src/test/resources/scaling.drl  | 311 +++++++++++++++++++
 .../single-cluster-scaling-test.json            |   2 +-
 .../src/test/resources/stratos-testing.xml      |  13 +-
 .../src/test/resources/user-test/tenant-1.json  |   9 +
 .../src/test/resources/user-test/user-1-v1.json |   8 +
 .../src/test/resources/user-test/user-1.json    |   8 +
 12 files changed, 610 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/stratos/blob/961a60f7/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/RestConstants.java
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/RestConstants.java b/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/RestConstants.java
index bf7de6c..b460a78 100644
--- a/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/RestConstants.java
+++ b/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/RestConstants.java
@@ -24,6 +24,8 @@ package org.apache.stratos.integration.tests;
 public class RestConstants {
     public static final String API = "api";
     public static final String AUTOSCALING_POLICIES = "/" + API + "/autoscalingPolicies";
+    public static final String USERS = "/" + API + "/users";
+    public static final String TENANTS = "/" + API + "/tenants";
     public static final String DEPLOYMENT_POLICIES = "/" + API + "/deploymentPolicies";
     public static final String NETWORK_PARTITIONS = "/" + API + "/networkPartitions";
     public static final String CARTRIDGES = "/" + API + "/cartridges";
@@ -42,6 +44,7 @@ public class RestConstants {
     public static final String CARTRIDGES_NAME = "cartridge";
     public static final String NETWORK_PARTITIONS_PATH = "/network-partitions/mock/";
     public static final String NETWORK_PARTITIONS_NAME = "networkPartition";
+    public static final String USERS_NAME = "users";
     public static final String DEPLOYMENT_POLICIES_PATH = "/deployment-policies/";
     public static final String DEPLOYMENT_POLICIES_NAME = "deploymentPolicy";
     public static final String APPLICATIONS_PATH = "/applications/";

http://git-wip-us.apache.org/repos/asf/stratos/blob/961a60f7/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/StratosTestServerManager.java
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/StratosTestServerManager.java b/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/StratosTestServerManager.java
index 6a69b75..bcf119d 100755
--- a/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/StratosTestServerManager.java
+++ b/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/StratosTestServerManager.java
@@ -55,6 +55,7 @@ public class StratosTestServerManager extends TestServerManager {
     private final static int PORT_OFFSET = 0;
     private static final String ACTIVEMQ_BIND_ADDRESS = "tcp://localhost:61617";
     private static final String MOCK_IAAS_XML_FILE = "mock-iaas.xml";
+    private static final String SCALING_DROOL_FILE = "scaling.drl";
     private static final String JNDI_PROPERTIES_FILE = "jndi.properties";
     private static final String JMS_OUTPUT_ADAPTER_FILE = "JMSOutputAdaptor.xml";
     protected RestClient restClient;
@@ -162,6 +163,7 @@ public class StratosTestServerManager extends TestServerManager {
     protected void copyArtifacts(String carbonHome) throws IOException {
         copyConfigFile(carbonHome, MOCK_IAAS_XML_FILE);
         copyConfigFile(carbonHome, JNDI_PROPERTIES_FILE);
+        copyConfigFile(carbonHome, SCALING_DROOL_FILE, "repository/conf/drools");
         copyConfigFile(carbonHome, JMS_OUTPUT_ADAPTER_FILE, "repository/deployment/server/outputeventadaptors");
     }
 

http://git-wip-us.apache.org/repos/asf/stratos/blob/961a60f7/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/application/SingleClusterScalingTest.java
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/application/SingleClusterScalingTest.java b/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/application/SingleClusterScalingTest.java
index 5a89d67..0f85c17 100644
--- a/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/application/SingleClusterScalingTest.java
+++ b/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/application/SingleClusterScalingTest.java
@@ -48,6 +48,8 @@ public class SingleClusterScalingTest extends StratosTestServerManager {
     private static final Log log = LogFactory.getLog(SampleApplicationsTest.class);
     private static final String RESOURCES_PATH = "/single-cluster-scaling-test";
     private static final int CLUSTER_SCALE_UP_TIMEOUT = 180000;
+    private static final int CLUSTER_SCALE_DOWN_TIMEOUT = 300000;
+    private int activeInstancesAfterScaleup = 0;
 
 
     @Test
@@ -112,6 +114,12 @@ public class SingleClusterScalingTest extends StratosTestServerManager {
             //Verifying whether members got created using round robin algorithm
             assertClusterWithScalingup(bean.getApplicationId());
 
+            //assert scale-down
+            assertClusterWithScaleDown(bean.getApplicationId());
+
+            //Check whether cluster could scale-down upto the minimum
+            assertClusterScaleDownToMinimumCount(bean.getApplicationId());
+
             boolean removedAuto = restClient.removeEntity(RestConstants.AUTOSCALING_POLICIES,
                     autoscalingPolicyId, RestConstants.AUTOSCALING_POLICIES_NAME);
             assertEquals(removedAuto, false);
@@ -227,8 +235,10 @@ public class SingleClusterScalingTest extends StratosTestServerManager {
                             }
                         }
                     }
+
                     clusterScaleup = activeInstances > clusterDataHolder.getMinInstances();
                     if(clusterScaleup) {
+                        activeInstancesAfterScaleup = activeInstances;
                         break;
                     }
                 }
@@ -241,4 +251,115 @@ public class SingleClusterScalingTest extends StratosTestServerManager {
         assertEquals(String.format("Cluster did not get scaled up: [cluster-id] %s", clusterId),
                 clusterScaleup, true);
     }
+
+    /**
+     * Assert application activation
+     *
+     * @param applicationName
+     */
+    private void assertClusterWithScaleDown(String applicationName) {
+        Application application = ApplicationManager.getApplications().getApplication(applicationName);
+        assertNotNull(String.format("Application is not found: [application-id] %s",
+                applicationName), application);
+        boolean clusterScaleDown = false;
+        String clusterId = null;
+        long startTime = System.currentTimeMillis();
+        while (!clusterScaleDown) {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException ignore) {
+            }
+            Set<ClusterDataHolder> clusterDataHolderSet = application.getClusterDataRecursively();
+            for (ClusterDataHolder clusterDataHolder : clusterDataHolderSet) {
+                String serviceName = clusterDataHolder.getServiceType();
+                clusterId = clusterDataHolder.getClusterId();
+                Service service = TopologyManager.getTopology().getService(serviceName);
+                assertNotNull(String.format("Service is not found: [application-id] %s [service] %s",
+                        applicationName, serviceName), service);
+
+                Cluster cluster = service.getCluster(clusterId);
+                assertNotNull(String.format("Cluster is not found: [application-id] %s [service] %s [cluster-id] %s",
+                        applicationName, serviceName, clusterId), cluster);
+                for (ClusterInstance instance : cluster.getInstanceIdToInstanceContextMap().values()) {
+                    int activeInstances = 0;
+                    for (Member member : cluster.getMembers()) {
+                        if (member.getClusterInstanceId().equals(instance.getInstanceId())) {
+                            if (member.getStatus().equals(MemberStatus.Active)) {
+                                activeInstances++;
+                            }
+                        }
+                    }
+
+                    if(activeInstances > activeInstancesAfterScaleup) {
+                        activeInstancesAfterScaleup = activeInstances;
+                    }
+
+                    clusterScaleDown = activeInstancesAfterScaleup - 1 == activeInstances;
+                    if(clusterScaleDown) {
+                        break;
+                    }
+
+                }
+
+                application = ApplicationManager.getApplications().getApplication(applicationName);
+                if ((System.currentTimeMillis() - startTime) > CLUSTER_SCALE_DOWN_TIMEOUT) {
+                    break;
+                }
+            }
+        }
+        assertEquals(String.format("Cluster did not get scaled up: [cluster-id] %s", clusterId),
+                clusterScaleDown, true);
+    }
+
+    /**
+     * Assert application activation
+     *
+     * @param applicationName
+     */
+    private void assertClusterScaleDownToMinimumCount(String applicationName) {
+        Application application = ApplicationManager.getApplications().getApplication(applicationName);
+        assertNotNull(String.format("Application is not found: [application-id] %s",
+                applicationName), application);
+        boolean clusterScaleDown = false;
+        String clusterId = null;
+        long startTime = System.currentTimeMillis();
+        while (!clusterScaleDown) {
+            try {
+                Thread.sleep(1000);
+            } catch (InterruptedException ignore) {
+            }
+            Set<ClusterDataHolder> clusterDataHolderSet = application.getClusterDataRecursively();
+            for (ClusterDataHolder clusterDataHolder : clusterDataHolderSet) {
+                String serviceName = clusterDataHolder.getServiceType();
+                clusterId = clusterDataHolder.getClusterId();
+                Service service = TopologyManager.getTopology().getService(serviceName);
+                assertNotNull(String.format("Service is not found: [application-id] %s [service] %s",
+                        applicationName, serviceName), service);
+
+                Cluster cluster = service.getCluster(clusterId);
+                assertNotNull(String.format("Cluster is not found: [application-id] %s [service] %s [cluster-id] %s",
+                        applicationName, serviceName, clusterId), cluster);
+                for (ClusterInstance instance : cluster.getInstanceIdToInstanceContextMap().values()) {
+                    int activeInstances = 0;
+                    for (Member member : cluster.getMembers()) {
+                        if (member.getClusterInstanceId().equals(instance.getInstanceId())) {
+                            if (member.getStatus().equals(MemberStatus.Active)) {
+                                activeInstances++;
+                            }
+                        }
+                    }
+                    clusterScaleDown = activeInstances == clusterDataHolder.getMinInstances();
+                    if(clusterScaleDown) {
+                        break;
+                    }
+                }
+                application = ApplicationManager.getApplications().getApplication(applicationName);
+                if ((System.currentTimeMillis() - startTime) > CLUSTER_SCALE_DOWN_TIMEOUT) {
+                    break;
+                }
+            }
+        }
+        assertEquals(String.format("Cluster did not get scaled up: [cluster-id] %s", clusterId),
+                clusterScaleDown, true);
+    }
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/961a60f7/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/users/TenantTest.java
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/users/TenantTest.java b/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/users/TenantTest.java
new file mode 100644
index 0000000..437b162
--- /dev/null
+++ b/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/users/TenantTest.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.stratos.integration.tests.users;
+
+import org.apache.stratos.integration.tests.RestConstants;
+import org.apache.stratos.integration.tests.StratosTestServerManager;
+import org.testng.annotations.Test;
+
+import static junit.framework.Assert.assertTrue;
+
+/**
+ * Handling users
+ */
+public class TenantTest extends StratosTestServerManager {
+    private static final String RESOURCES_PATH = "/user-test";
+
+
+    @Test
+    public void addUser() {
+        String tenantId = "tenant-1";
+        boolean addedUser1 = restClient.addEntity(RESOURCES_PATH + "/" +
+                        tenantId + ".json",
+                RestConstants.USERS, RestConstants.USERS_NAME);
+        assertTrue(addedUser1);
+
+    }
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/961a60f7/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/users/UserTest.java
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/users/UserTest.java b/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/users/UserTest.java
index 41e2017..c15250f 100644
--- a/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/users/UserTest.java
+++ b/products/stratos/modules/integration/src/test/java/org/apache/stratos/integration/tests/users/UserTest.java
@@ -18,8 +18,98 @@
  */
 package org.apache.stratos.integration.tests.users;
 
+import com.google.gson.reflect.TypeToken;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.stratos.common.beans.UserInfoBean;
+import org.apache.stratos.common.beans.cartridge.CartridgeBean;
+import org.apache.stratos.integration.tests.RestConstants;
+import org.apache.stratos.integration.tests.StratosTestServerManager;
+import org.testng.annotations.Test;
+
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+
+import static junit.framework.Assert.*;
+
 /**
- * Created by reka on 8/20/15.
+ * Handling users
  */
-public class UserTest {
+public class UserTest extends StratosTestServerManager {
+    private static final Log log = LogFactory.getLog(UserTest.class);
+    private static final String RESOURCES_PATH = "/user-test";
+
+    @Test
+    public void addUser() {
+        try {
+            log.info("-------------------------------Started users test case-------------------------------");
+            String userId = "user-1";
+            boolean addedUser1 = restClient.addEntity(RESOURCES_PATH + "/" +
+                            userId + ".json",
+                    RestConstants.USERS, RestConstants.USERS_NAME);
+            assertTrue(addedUser1);
+
+            Type listType = new TypeToken<ArrayList<UserInfoBean>>() {
+            }.getType();
+
+            List<UserInfoBean> userInfoBeanList = (List<UserInfoBean>) restClient.listEntity(RestConstants.USERS,
+                    listType, RestConstants.USERS_NAME);
+
+            UserInfoBean bean1 = null;
+            for (UserInfoBean userInfoBean : userInfoBeanList) {
+                if (userInfoBean.getUserName().equals(userId)) {
+                    bean1 = userInfoBean;
+                }
+            }
+            assertNotNull(bean1);
+            /*assertEquals(bean1.getEmail(), "foo@bar.com");
+            assertEquals(bean1.getFirstName(), "Frank");
+            assertEquals(bean1.getRole(), "admin");
+            assertEquals(bean1.getLastName(), "Myers");
+            assertEquals(bean1.getCredential(), "kim12345");*/
+
+            boolean updatedUser1 = restClient.updateEntity(RESOURCES_PATH + "/" +
+                            userId + "-v1.json",
+                    RestConstants.USERS, RestConstants.USERS_NAME);
+            assertTrue(updatedUser1);
+
+            userInfoBeanList = (List<UserInfoBean>) restClient.listEntity(RestConstants.USERS,
+                    listType, RestConstants.USERS_NAME);
+
+            for (UserInfoBean userInfoBean : userInfoBeanList) {
+                if (userInfoBean.getUserName().equals(userId)) {
+                    bean1 = userInfoBean;
+                }
+            }
+            assertNotNull(bean1);
+            /*assertEquals(bean1.getEmail(), "user-1@bar.com");
+            assertEquals(bean1.getFirstName(), "Frankn");
+            assertEquals(bean1.getRole(), "admin");
+            assertEquals(bean1.getLastName(), "Myersn");
+            assertEquals(bean1.getCredential(), "kim123456");*/
+
+            boolean removedUser1 = restClient.removeEntity(RestConstants.USERS,
+                            userId, RestConstants.USERS_NAME);
+            assertTrue(removedUser1);
+
+            userInfoBeanList = (List<UserInfoBean>) restClient.listEntity(RestConstants.USERS,
+                    listType, RestConstants.USERS_NAME);
+
+            bean1 = null;
+            for (UserInfoBean userInfoBean : userInfoBeanList) {
+                if (userInfoBean.getUserName().equals(userId)) {
+                    bean1 = userInfoBean;
+                }
+            }
+            assertNull(bean1);
+
+            log.info("-------------------------Ended users test case-------------------------");
+
+        } catch (Exception e) {
+            log.error("An error occurred while handling  application bursting", e);
+            assertTrue("An error occurred while handling  application bursting", false);
+        }
+
+    }
 }

http://git-wip-us.apache.org/repos/asf/stratos/blob/961a60f7/products/stratos/modules/integration/src/test/resources/mock-iaas.xml
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/src/test/resources/mock-iaas.xml b/products/stratos/modules/integration/src/test/resources/mock-iaas.xml
index 6b74dc8..ab0b0bf 100644
--- a/products/stratos/modules/integration/src/test/resources/mock-iaas.xml
+++ b/products/stratos/modules/integration/src/test/resources/mock-iaas.xml
@@ -48,13 +48,13 @@
                  stop: stop publishing statistics -->
             <pattern factor="memory-consumption" mode="continue">
                 <!-- Sample values -->
-                <sampleValues>60,70,80,90,90,90,40,60,50,60</sampleValues>
+                <sampleValues>60,60,10,10,10,10,10,10</sampleValues>
                 <!-- Duration of each sample value in seconds -->
                 <sampleDuration>60</sampleDuration>
             </pattern>
             <pattern factor="load-average" mode="continue">
                 <!-- Sample values -->
-                <sampleValues>70,70,70</sampleValues>
+                <sampleValues>60,60,10,10,10,10,10,10</sampleValues>
                 <!-- Duration of each sample value in seconds -->
                 <sampleDuration>60</sampleDuration>
             </pattern>

http://git-wip-us.apache.org/repos/asf/stratos/blob/961a60f7/products/stratos/modules/integration/src/test/resources/scaling.drl
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/src/test/resources/scaling.drl b/products/stratos/modules/integration/src/test/resources/scaling.drl
new file mode 100644
index 0000000..69d9111
--- /dev/null
+++ b/products/stratos/modules/integration/src/test/resources/scaling.drl
@@ -0,0 +1,311 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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 org.apache.stratos.autoscaler
+
+import org.apache.stratos.messaging.domain.topology.Service;
+import org.apache.stratos.messaging.domain.topology.Cluster;
+import org.apache.stratos.autoscaler.context.AutoscalerContext;
+import org.apache.stratos.autoscaler.context.member.MemberStatsContext;
+import org.apache.stratos.autoscaler.util.AutoscalerConstants;
+import org.apache.stratos.autoscaler.context.partition.network.NetworkPartitionContext;
+import org.apache.stratos.autoscaler.pojo.policy.PolicyManager;
+import org.apache.stratos.autoscaler.pojo.policy.autoscale.AutoscalePolicy;
+import org.apache.stratos.autoscaler.pojo.policy.autoscale.RequestsInFlight;
+import org.apache.stratos.autoscaler.pojo.policy.autoscale.LoadThresholds;
+import org.apache.stratos.autoscaler.pojo.policy.autoscale.MemoryConsumption;
+import org.apache.stratos.autoscaler.pojo.policy.autoscale.LoadAverage;
+import org.apache.stratos.autoscaler.algorithms.PartitionAlgorithm;
+import org.apache.stratos.autoscaler.algorithms.partition.OneAfterAnother;
+import org.apache.stratos.autoscaler.algorithms.partition.RoundRobin;
+import org.apache.stratos.autoscaler.context.partition.ClusterLevelPartitionContext;
+import org.apache.stratos.autoscaler.rule.AutoscalerRuleEvaluator;
+import org.apache.stratos.cloud.controller.stub.domain.Partition;
+import org.apache.stratos.cloud.controller.stub.domain.MemberContext;
+import org.apache.stratos.autoscaler.context.cluster.ClusterInstanceContext;
+
+import org.apache.stratos.autoscaler.pojo.policy.autoscale.LoadAverage
+import org.apache.stratos.autoscaler.pojo.policy.autoscale.MemoryConsumption
+
+global org.apache.stratos.autoscaler.rule.RuleLog log;
+global org.apache.stratos.autoscaler.rule.RuleTasksDelegator delegator;
+global org.apache.stratos.autoscaler.pojo.policy.autoscale.AutoscalePolicy autoscalePolicy;
+global java.lang.String applicationId;
+global java.lang.String clusterId;
+global java.lang.Boolean rifReset;
+global java.lang.Boolean mcReset;
+global java.lang.Boolean laReset;
+global java.lang.Boolean arspiReset;
+global java.lang.String algorithmName;
+
+rule "Scaling Rule"
+dialect "mvel"
+	when
+       clusterInstanceContext : ClusterInstanceContext ()
+
+        loadThresholds : LoadThresholds() from  autoscalePolicy.getLoadThresholds()
+        partitionAlgorithm : PartitionAlgorithm() from  delegator.getPartitionAlgorithm(algorithmName)
+
+        eval(log.debug("Running scale up rule: [network-partition] " + clusterInstanceContext.getNetworkPartitionId() +
+            " [cluster] " + clusterId))
+        eval(log.debug("[scaling] [network-partition] " + clusterInstanceContext.getNetworkPartitionId() + " [cluster] "
+            + clusterId + " Algorithm name: " + algorithmName))
+
+	
+        rifThreshold : Float() from  loadThresholds.getRequestsInFlightThreshold()
+
+        rifAverage : Float() from  clusterInstanceContext.getAverageRequestsInFlight()
+        rifGradient : Float() from  clusterInstanceContext.getRequestsInFlightGradient()
+        rifSecondDerivative : Float() from  clusterInstanceContext.getRequestsInFlightSecondDerivative()
+	    rifPredictedValue : Double() from delegator.getPredictedValueForNextMinute(rifAverage, rifGradient, rifSecondDerivative, 1)
+
+        mcThreshold : Float() from  loadThresholds.getMemoryConsumptionThreshold()
+
+        mcPredictedValue : Double() from delegator.getMemoryConsumptionPredictedValue(clusterInstanceContext)
+
+        laThreshold : Float() from  loadThresholds.getLoadAverageThreshold()
+
+        laPredictedValue : Double() from delegator.getLoadAveragePredictedValue(clusterInstanceContext)
+
+        activeInstancesCount : Integer() from clusterInstanceContext.getActiveMemberCount()
+        maxInstancesCount : Integer() from clusterInstanceContext.getMaxInstanceCount()
+        minInstancesCount : Integer() from clusterInstanceContext.getMinInstanceCount()
+        requestsServedPerInstance : Float() from  clusterInstanceContext.getRequestsServedPerInstance()
+        averageRequestsServedPerInstance : Float() from  clusterInstanceContext.getAverageRequestsServedPerInstance()
+
+        numberOfInstancesReuquiredBasedOnRif : Integer() from delegator.getNumberOfInstancesRequiredBasedOnRif(
+            rifPredictedValue, rifThreshold)
+        numberOfInstancesReuquiredBasedOnMemoryConsumption : Integer() from
+            delegator.getNumberOfInstancesRequiredBasedOnMemoryConsumption(mcThreshold, mcPredictedValue, minInstancesCount,
+            maxInstancesCount)
+        numberOfInstancesReuquiredBasedOnLoadAverage : Integer() from
+            delegator.getNumberOfInstancesRequiredBasedOnLoadAverage(laThreshold, laPredictedValue, minInstancesCount)
+
+        numberOfRequiredInstances : Integer() from delegator.getMaxNumberOfInstancesRequired(
+            numberOfInstancesReuquiredBasedOnRif, numberOfInstancesReuquiredBasedOnMemoryConsumption, mcReset,
+            numberOfInstancesReuquiredBasedOnLoadAverage, laReset)
+
+
+
+        scaleUp : Boolean() from (activeInstancesCount < numberOfRequiredInstances)
+        scaleDown : Boolean() from (activeInstancesCount > numberOfRequiredInstances || (numberOfRequiredInstances == 1 && activeInstancesCount == 1))
+
+
+        eval(log.debug("[scaling] " + "[cluster] " + clusterId + " RIF Resetted?: " + rifReset))
+        eval(log.debug("[scaling] " + "[cluster] " + clusterId + " RIF predicted value: " + rifPredictedValue))
+        eval(log.debug("[scaling] " + "[cluster] " + clusterId + " RIF threshold: " + rifThreshold))
+
+        eval(log.debug("[scaling] " + "[cluster] " + clusterId + " MC predicted value: " + mcPredictedValue))
+        eval(log.debug("[scaling] " + "[cluster] " + clusterId + " MC threshold: " + mcThreshold))
+
+        eval(log.debug("[scaling] " + "[cluster] " + clusterId + " LA predicted value: " + laPredictedValue))
+        eval(log.debug("[scaling] " + "[cluster] " + clusterId + " LA threshold: " + laThreshold))
+
+        eval(log.debug("[scaling] " + "[cluster] " + clusterId + " Scale-up action: " + scaleUp))
+        eval(log.debug("[scaling] " + "[cluster] " + clusterId + " Scale-down action: " + scaleDown))
+
+	then
+
+	    log.debug("[scaling] Number of required instances based on stats: " + numberOfRequiredInstances + " " +
+	        "[active instances count] " + activeInstancesCount + " [network-partition] " +
+	        clusterInstanceContext.getNetworkPartitionId() + " [cluster] " + clusterId);
+
+        int nonTerminatedMembers = clusterInstanceContext.getNonTerminatedMemberCount();
+        if(scaleUp){
+
+            int clusterMaxMembers = clusterInstanceContext.getMaxInstanceCount();
+            if (nonTerminatedMembers < clusterMaxMembers) {
+
+                int additionalInstances = 0;
+                if(clusterMaxMembers < numberOfRequiredInstances){
+
+                    additionalInstances = clusterMaxMembers - nonTerminatedMembers;
+                    log.info("[scale-up] Required member count based on stat based scaling is higher than max, hence"
+                            + " notifying to parent for possible group scaling or app bursting. [cluster] " + clusterId
+                            + " [instance id]" + clusterInstanceContext.getId() + " [max] " + clusterMaxMembers
+                            + " [number of required instances] " + numberOfRequiredInstances
+                            + " [additional instances to be created] " + additionalInstances);
+                    delegator.delegateScalingOverMaxNotification(clusterId, clusterInstanceContext.getNetworkPartitionId(),
+                        clusterInstanceContext.getId());
+                } else {
+
+                    additionalInstances = numberOfRequiredInstances - nonTerminatedMembers;
+                }
+
+                clusterInstanceContext.resetScaleDownRequestsCount();
+
+                log.debug("[scale-up] " + " [has scaling dependents] " + clusterInstanceContext.hasScalingDependants() +
+                    " [cluster] " + clusterId );
+                if(clusterInstanceContext.hasScalingDependants()) {
+
+                    log.debug("[scale-up] Notifying dependencies [cluster] " + clusterId);
+                    delegator.delegateScalingDependencyNotification(clusterId, clusterInstanceContext.getNetworkPartitionId(),
+                        clusterInstanceContext.getId(), numberOfRequiredInstances, clusterInstanceContext.getMinInstanceCount());
+                } else {
+
+                    boolean partitionsAvailable = true;
+                    int count = 0;
+
+                    while(count != additionalInstances && partitionsAvailable){
+
+                        ClusterLevelPartitionContext partitionContext = (ClusterLevelPartitionContext) partitionAlgorithm.getNextScaleUpPartitionContext(clusterInstanceContext.getPartitionCtxtsAsAnArray());
+                        if(partitionContext != null){
+
+                            log.info("[scale-up] Partition available, hence trying to spawn an instance to scale up! " +
+                                " [application id] " + applicationId +
+                                " [cluster] " + clusterId + " [instance id] " + clusterInstanceContext.getId() +
+                                " [network-partition] " + clusterInstanceContext.getNetworkPartitionId() +
+                                " [partition] " + partitionContext.getPartitionId() +
+                                " scaleup due to RIF: " + (rifReset && (rifPredictedValue > rifThreshold)) +
+                                " [rifPredictedValue] " + rifPredictedValue + " [rifThreshold] " + rifThreshold +
+                                " scaleup due to MC: " + (mcReset && (mcPredictedValue > mcThreshold)) +
+                                " [mcPredictedValue] " + mcPredictedValue + " [mcThreshold] " + mcThreshold +
+                                " scaleup due to LA: " + (laReset && (laPredictedValue > laThreshold)) +
+                                " [laPredictedValue] " + laPredictedValue + " [laThreshold] " + laThreshold);
+
+                            log.debug("[scale-up] " + " [partition] " + partitionContext.getPartitionId() + " [cluster] " + clusterId );
+                            delegator.delegateSpawn(partitionContext, clusterId, clusterInstanceContext.getId());
+                            count++;
+                        } else {
+
+                            log.warn("[scale-up] No more partition available even though " +
+                             "cartridge-max is not reached!, [cluster] " + clusterId +
+                            " Please update deployment-policy with new partitions or with higher " +
+                             "partition-max");
+                            partitionsAvailable = false;
+                        }
+                    }
+                }
+            } else {
+                log.info("[scale-up] Trying to scale up over max, hence not scaling up cluster itself and
+                        notifying to parent for possible group scaling or app bursting.
+                        [cluster] " + clusterId + " [instance id]" + clusterInstanceContext.getId() +
+                        " [max] " + clusterMaxMembers);
+                delegator.delegateScalingOverMaxNotification(clusterId, clusterInstanceContext.getNetworkPartitionId(),
+                    clusterInstanceContext.getId());
+            }
+        } else if(scaleDown){
+
+            if(nonTerminatedMembers > clusterInstanceContext.getMinInstanceCount){
+
+                log.debug("[scale-down] Decided to Scale down [cluster] " + clusterId);
+                if(clusterInstanceContext.getScaleDownRequestsCount() >= 0 ){
+
+                    log.debug("[scale-down] Reached scale down requests threshold [cluster] " + clusterId + " Count " +
+                        clusterInstanceContext.getScaleDownRequestsCount());
+
+                    if(clusterInstanceContext.hasScalingDependants()) {
+
+                        log.debug("[scale-up] Notifying dependencies [cluster] " + clusterId);
+                        delegator.delegateScalingDependencyNotification(clusterId, clusterInstanceContext.getNetworkPartitionId(),
+                            clusterInstanceContext.getId(), numberOfRequiredInstances, clusterInstanceContext.getMinInstanceCount());
+                    } else{
+
+                        MemberStatsContext selectedMemberStatsContext = null;
+                        double lowestOverallLoad = 0.0;
+                        boolean foundAValue = false;
+                        ClusterLevelPartitionContext partitionContext = (ClusterLevelPartitionContext) partitionAlgorithm.getNextScaleDownPartitionContext(clusterInstanceContext.getPartitionCtxtsAsAnArray());
+                        if(partitionContext != null) {
+                            log.info("[scale-down] Partition available to scale down " +
+                                " [application id] " + applicationId +
+                                " [cluster] " + clusterId + " [instance id] " + clusterInstanceContext.getId() +
+                                " [network-partition] " + clusterInstanceContext.getNetworkPartitionId() +
+                                " [partition] " + partitionContext.getPartitionId() +
+                                " scaledown due to RIF: " + (rifReset && (rifPredictedValue < rifThreshold)) +
+                                " [rifPredictedValue] " + rifPredictedValue + " [rifThreshold] " + rifThreshold +
+                                " scaledown due to MC: " + (mcReset && (mcPredictedValue < mcThreshold)) +
+                                " [mcPredictedValue] " + mcPredictedValue + " [mcThreshold] " + mcThreshold +
+                                " scaledown due to LA: " + (laReset && (laPredictedValue < laThreshold)) +
+                                " [laPredictedValue] " + laPredictedValue + " [laThreshold] " + laThreshold
+                            );
+
+
+                            for(MemberStatsContext memberStatsContext: partitionContext.getMemberStatsContexts().values()){
+
+                                LoadAverage loadAverage = memberStatsContext.getLoadAverage();
+                                log.debug("[scale-down] " + " [cluster] "
+                                    + clusterId + " [member] " + memberStatsContext.getMemberId() + " Load average: " + loadAverage);
+
+                                MemoryConsumption memoryConsumption = memberStatsContext.getMemoryConsumption();
+                                log.debug("[scale-down] " + " [partition] " + partitionContext.getPartitionId() + " [cluster] "
+                                    + clusterId + " [member] " + memberStatsContext.getMemberId() + " Memory consumption: " +
+                                    memoryConsumption);
+
+                                double predictedCpu = delegator.getPredictedValueForNextMinute(loadAverage.getAverage(),
+                                    loadAverage.getGradient(),loadAverage.getSecondDerivative(), 1);
+                                log.debug("[scale-down] " + " [partition] " + partitionContext.getPartitionId() + " [cluster] "
+                                    + clusterId + " [member] " + memberStatsContext.getMemberId() + " Predicted CPU: " + predictedCpu);
+
+                                double predictedMemoryConsumption = delegator.getPredictedValueForNextMinute(
+                                    memoryConsumption.getAverage(),memoryConsumption.getGradient(),memoryConsumption.getSecondDerivative(), 1);
+                                log.debug("[scale-down] " + " [partition] " + partitionContext.getPartitionId() + " [cluster] "
+                                    + clusterId + " [member] " + memberStatsContext.getMemberId() + " Predicted memory consumption: " +
+                                        predictedMemoryConsumption);
+
+                                double overallLoad = (predictedCpu + predictedMemoryConsumption) / 2;
+                                log.debug("[scale-down] " + " [partition] " + partitionContext.getPartitionId() + " [cluster] "
+                                    + clusterId + " [member] " + memberStatsContext.getMemberId() + " Overall load: " + overallLoad);
+
+                                if(!foundAValue){
+                                    foundAValue = true;
+                                    selectedMemberStatsContext = memberStatsContext;
+                                    lowestOverallLoad = overallLoad;
+                                } else if(overallLoad < lowestOverallLoad){
+                                    selectedMemberStatsContext = memberStatsContext;
+                                    lowestOverallLoad = overallLoad;
+                                }
+
+                            }
+                            if(selectedMemberStatsContext != null) {
+                                log.info("[scale-down] Trying to terminating an instace to scale down!" );
+                                log.debug("[scale-down] " + " [partition] " + partitionContext.getPartitionId() + " [cluster] "
+                                    + clusterId + " Member with lowest overall load: " + selectedMemberStatsContext.getMemberId());
+
+                                delegator.delegateTerminate(partitionContext, selectedMemberStatsContext.getMemberId());
+                            }
+                        } else {
+                            log.warn("Partition is not available to scale-down..!!!!");
+                        }
+                    }
+                } else{
+                     log.debug("[scale-down] Not reached scale down requests threshold. " + clusterId + " Count " +
+                        clusterInstanceContext.getScaleDownRequestsCount());
+                     clusterInstanceContext.increaseScaleDownRequestsCount();
+
+                }
+            } else {
+                log.debug("[scale-down] Min is reached, hence not scaling down [cluster] " + clusterId + " [instance id]"
+                    + clusterInstanceContext.getId());
+                //if(clusterInstanceContext.isInGroupScalingEnabledSubtree()){
+
+                    delegator.delegateScalingDownBeyondMinNotification(clusterId, clusterInstanceContext.getNetworkPartitionId(),
+                        clusterInstanceContext.getId());
+                //}
+            }
+        }  else{
+            log.debug("[scaling] No decision made to either scale up or scale down ... [cluster] " + clusterId + " [instance id]"
+             + clusterInstanceContext.getId());
+
+        }
+
+end
+
+
+
+

http://git-wip-us.apache.org/repos/asf/stratos/blob/961a60f7/products/stratos/modules/integration/src/test/resources/single-cluster-scaling-test/applications/single-cluster-scaling-test.json
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/src/test/resources/single-cluster-scaling-test/applications/single-cluster-scaling-test.json b/products/stratos/modules/integration/src/test/resources/single-cluster-scaling-test/applications/single-cluster-scaling-test.json
index f091e26..a02407b 100644
--- a/products/stratos/modules/integration/src/test/resources/single-cluster-scaling-test/applications/single-cluster-scaling-test.json
+++ b/products/stratos/modules/integration/src/test/resources/single-cluster-scaling-test/applications/single-cluster-scaling-test.json
@@ -6,7 +6,7 @@
             {
                 "type": "c7-single-cluster-scaling-test",
                 "cartridgeMin": 2,
-                "cartridgeMax": 5,
+                "cartridgeMax": 6,
                 "subscribableInfo": {
                     "alias": "my-c7",
                     "autoscalingPolicy": "autoscaling-policy-single-cluster-scaling-test",

http://git-wip-us.apache.org/repos/asf/stratos/blob/961a60f7/products/stratos/modules/integration/src/test/resources/stratos-testing.xml
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/src/test/resources/stratos-testing.xml b/products/stratos/modules/integration/src/test/resources/stratos-testing.xml
index 23f3766..99eca33 100644
--- a/products/stratos/modules/integration/src/test/resources/stratos-testing.xml
+++ b/products/stratos/modules/integration/src/test/resources/stratos-testing.xml
@@ -21,7 +21,12 @@
 <!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
 
 <suite name="StratosIntegrationSuite">
-    <test name="CartridgeTest">
+    <test name="UserTest">
+        <classes>
+            <class name="org.apache.stratos.integration.tests.users.UserTest" />
+        </classes>
+    </test>
+    <!--<test name="CartridgeTest">
         <classes>
             <class name="org.apache.stratos.integration.tests.group.CartridgeTest" />
         </classes>
@@ -60,13 +65,13 @@
         <classes>
             <class name="org.apache.stratos.integration.tests.application.ApplicationUpdateTest" />
         </classes>
-    </test>
+    </test>-->
     <test name="SingleClusterScalingTest">
         <classes>
             <class name="org.apache.stratos.integration.tests.application.SingleClusterScalingTest" />
         </classes>
     </test>
-    <test name="ApplicationBurstingTest">
+    <!--<test name="ApplicationBurstingTest">
         <classes>
             <class name="org.apache.stratos.integration.tests.application.ApplicationBurstingTest" />
         </classes>
@@ -85,5 +90,5 @@
         <classes>
             <class name="org.apache.stratos.integration.tests.application.GroupTerminationBehaviorTest" />
         </classes>
-    </test>
+    </test>-->
 </suite>

http://git-wip-us.apache.org/repos/asf/stratos/blob/961a60f7/products/stratos/modules/integration/src/test/resources/user-test/tenant-1.json
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/src/test/resources/user-test/tenant-1.json b/products/stratos/modules/integration/src/test/resources/user-test/tenant-1.json
new file mode 100644
index 0000000..0f599e4
--- /dev/null
+++ b/products/stratos/modules/integration/src/test/resources/user-test/tenant-1.json
@@ -0,0 +1,9 @@
+{
+    "admin": "admin",
+    "firstName": "Frank",
+    "lastName": "Myers",
+    "adminPassword": "admin123",
+    "tenantDomain": "frank.com",
+    "email": "foo@bar.com",
+    "active": "true"
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/961a60f7/products/stratos/modules/integration/src/test/resources/user-test/user-1-v1.json
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/src/test/resources/user-test/user-1-v1.json b/products/stratos/modules/integration/src/test/resources/user-test/user-1-v1.json
new file mode 100644
index 0000000..1d2bbfd
--- /dev/null
+++ b/products/stratos/modules/integration/src/test/resources/user-test/user-1-v1.json
@@ -0,0 +1,8 @@
+{
+    "userName": "user-1",
+    "credential": "kim123456",
+    "role": "admin",
+    "firstName": "Frankn",
+    "lastName": "Myersn",
+    "email": "user-1@bar.com"
+}

http://git-wip-us.apache.org/repos/asf/stratos/blob/961a60f7/products/stratos/modules/integration/src/test/resources/user-test/user-1.json
----------------------------------------------------------------------
diff --git a/products/stratos/modules/integration/src/test/resources/user-test/user-1.json b/products/stratos/modules/integration/src/test/resources/user-test/user-1.json
new file mode 100644
index 0000000..6f7da8a
--- /dev/null
+++ b/products/stratos/modules/integration/src/test/resources/user-test/user-1.json
@@ -0,0 +1,8 @@
+{
+    "userName": "user-1",
+    "credential": "kim12345",
+    "role": "admin",
+    "firstName": "Frank",
+    "lastName": "Myers",
+    "email": "foo@bar.com"
+}