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 <[email protected]> Authored: Fri Aug 21 12:36:19 2015 +0530 Committer: reka <[email protected]> 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(), "[email protected]"); + 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(), "[email protected]"); + 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": "[email protected]", + "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": "[email protected]" +} 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": "[email protected]" +}
