parent
ddc57ba3ca
commit
3e73f4b4ed
|
@ -1,7 +1,6 @@
|
|||
package org.bench4q.agent.api;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
@ -21,7 +20,6 @@ import org.bench4q.share.models.agent.RunScenarioModel;
|
|||
import org.bench4q.share.models.agent.RunScenarioResultModel;
|
||||
import org.bench4q.share.models.agent.StopTestModel;
|
||||
import org.bench4q.share.models.agent.TestBriefStatusModel;
|
||||
import org.bench4q.share.models.agent.UpdatePopulationModel;
|
||||
import org.bench4q.share.models.agent.statistics.AgentBriefStatusModel;
|
||||
import org.bench4q.share.models.agent.statistics.AgentBehaviorsBriefModel;
|
||||
import org.bench4q.share.models.agent.statistics.AgentPageBriefModel;
|
||||
|
@ -247,32 +245,20 @@ public class TestController {
|
|||
if (scenarioContext == null) {
|
||||
return null;
|
||||
}
|
||||
scenarioContext.setEndDate(new Date(System.currentTimeMillis()));
|
||||
System.out.println("when before stop, classId:"
|
||||
+ scenarioContext.getExecutor().toString());
|
||||
scenarioContext.getExecutor().shutdown();
|
||||
scenarioContext.getExecutor().shutdownNow();
|
||||
System.out.println("when after stop, classId:"
|
||||
+ scenarioContext.getExecutor().toString());
|
||||
scenarioContext.setFinished(true);
|
||||
clean(runId);
|
||||
scenarioContext.stop();
|
||||
clean();
|
||||
return new StopTestModel(true);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/clean/{runId}", method = RequestMethod.GET)
|
||||
@RequestMapping(value = "/clean", method = RequestMethod.GET)
|
||||
@ResponseBody
|
||||
public CleanTestResultModel clean(@PathVariable UUID runId) {
|
||||
this.getScenarioEngine().getRunningTests().remove(runId);
|
||||
public CleanTestResultModel clean() {
|
||||
System.gc();
|
||||
return new CleanTestResultModel(true);
|
||||
}
|
||||
|
||||
@RequestMapping(value = "/updatePopulation/{runId}/{requiredLoad}", method = {
|
||||
RequestMethod.POST, RequestMethod.GET })
|
||||
@ResponseBody
|
||||
public UpdatePopulationModel updatePopulation(@PathVariable UUID runId,
|
||||
@PathVariable int requiredLoad) {
|
||||
this.getScenarioEngine().updatePopulation(runId, requiredLoad);
|
||||
return new UpdatePopulationModel(true);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,24 +11,41 @@ import java.util.TimerTask;
|
|||
import org.bench4q.share.exception.Bench4QRunTimeException;
|
||||
import org.bench4q.share.models.agent.scriptrecord.ScheduleModel;
|
||||
import org.bench4q.share.models.agent.scriptrecord.ScheduleModel.PointModel;
|
||||
|
||||
/*
|
||||
* Segments in Schedule is sorted asc by Segment.start.time
|
||||
*/
|
||||
public class Schedule extends Observable {
|
||||
private static final int SCHEDULE_CYCLE = 3000;
|
||||
private final List<Segment> segments;
|
||||
private final long beginTime;
|
||||
private volatile boolean reachEnd;
|
||||
|
||||
public List<Segment> getSegments() {
|
||||
return segments;
|
||||
}
|
||||
|
||||
public Schedule(List<Segment> segments){
|
||||
public boolean hasReachEnd() {
|
||||
return this.reachEnd;
|
||||
}
|
||||
|
||||
private void reachEnd() {
|
||||
this.reachEnd = true;
|
||||
}
|
||||
|
||||
public Schedule(List<Segment> segments) {
|
||||
if (segments == null || segments.size() == 0) {
|
||||
throw new Bench4QRunTimeException("Can't init a schedul with zero segment");
|
||||
throw new Bench4QRunTimeException(
|
||||
"Can't init a schedul with zero segment");
|
||||
}
|
||||
this.segments = segments;
|
||||
this.beginTime = System.currentTimeMillis();
|
||||
this.reachEnd = false;
|
||||
beginSchedul();
|
||||
}
|
||||
|
||||
public long getScheduleRange() {
|
||||
return this.getSegments().get(this.getSegments().size()).end.getTime()
|
||||
- this.getSegments().get(0).start.getTime();
|
||||
}
|
||||
|
||||
private void beginSchedul() {
|
||||
|
@ -39,19 +56,42 @@ public class Schedule extends Observable {
|
|||
long time = System.currentTimeMillis();
|
||||
Segment segment = getSegment(time);
|
||||
if (segment == null) {
|
||||
//exceed the range of execute, should let the context stop the test
|
||||
// exceed the range of execute, should let the context stop
|
||||
// the test
|
||||
notifyObservers(0);
|
||||
return;
|
||||
}
|
||||
segment.loadFor(time - beginTime);
|
||||
notifyObservers(segment.loadFor(time - beginTime));
|
||||
}
|
||||
}, 0, SCHEDULE_CYCLE);
|
||||
}
|
||||
|
||||
//get the segment by binary search
|
||||
protected Segment getSegment(long time) {
|
||||
|
||||
// get the segment by binary search
|
||||
public Segment getSegment(long time) {
|
||||
if (this.getSegments() == null || this.getSegments().size() < 1
|
||||
|| time < this.getSegments().get(0).start.getTime()) {
|
||||
throw new Bench4QRunTimeException(
|
||||
"can't getSegment when segments' size is LT 2");
|
||||
}
|
||||
if (time >= this.getSegments().get(this.getSegments().size() - 1).end
|
||||
.getTime()) {
|
||||
this.reachEnd();
|
||||
return null;
|
||||
}
|
||||
int begin = 0, end = this.getSegments().size(), mid = (begin + end) / 2;
|
||||
while (begin <= end) {
|
||||
Segment midSegment = this.getSegments().get(mid);
|
||||
if (midSegment.end.getTime() < time) {
|
||||
begin = mid + 1;
|
||||
} else if (midSegment.start.getTime() > time) {
|
||||
end = mid - 1;
|
||||
} else {
|
||||
return midSegment;
|
||||
}
|
||||
mid = (begin + end) / 2;
|
||||
}
|
||||
throw new Bench4QRunTimeException("Should not come to this place");
|
||||
}
|
||||
|
||||
public static class Segment {
|
||||
private final Point start;
|
||||
|
@ -62,16 +102,21 @@ public class Schedule extends Observable {
|
|||
public Segment(Point startPoint, Point endPoint) {
|
||||
this.start = startPoint.copy();
|
||||
this.end = endPoint.copy();
|
||||
long timeDifference = this.end.getTime() / 1000 - this.start.getTime() / 1000;
|
||||
if (timeDifference < 0 || this.start.getTime() < 0l || this.end.getTime() < 0l) {
|
||||
throw new Bench4QRunTimeException("The end time in TestScehdul cannot be less than start time");
|
||||
long timeDifference = this.end.getTime() / 1000
|
||||
- this.start.getTime() / 1000;
|
||||
if (timeDifference < 0 || this.start.getTime() < 0l
|
||||
|| this.end.getTime() < 0l) {
|
||||
throw new Bench4QRunTimeException(
|
||||
"The end time in TestScehdul cannot be less than start time");
|
||||
}
|
||||
this.growthUnit = (float) (timeDifference == 0 ? 0 : (double)(this.end.getLoad() - this.start.getLoad())
|
||||
/ (double)(timeDifference));
|
||||
this.growthUnit = (float) (timeDifference == 0 ? 0
|
||||
: (double) (this.end.getLoad() - this.start.getLoad())
|
||||
/ (double) (timeDifference));
|
||||
}
|
||||
|
||||
public int loadFor(long timeFromBegin){
|
||||
if (timeFromBegin < this.start.getTime() || timeFromBegin > this.end.getTime()) {
|
||||
public int loadFor(long timeFromBegin) {
|
||||
if (timeFromBegin < this.start.getTime()
|
||||
|| timeFromBegin > this.end.getTime()) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
long diffFromStart = timeFromBegin - this.start.getTime();
|
||||
|
@ -80,7 +125,7 @@ public class Schedule extends Observable {
|
|||
}
|
||||
|
||||
public static class Point {
|
||||
//This time is the relative value from begin
|
||||
// This time is the relative value from begin
|
||||
private final long time;
|
||||
private final int load;
|
||||
|
||||
|
@ -93,6 +138,10 @@ public class Schedule extends Observable {
|
|||
}
|
||||
|
||||
public Point(long time, int load) {
|
||||
if (load < 0) {
|
||||
throw new IllegalArgumentException(
|
||||
"Load can't be negtive number!");
|
||||
}
|
||||
this.time = time;
|
||||
this.load = load;
|
||||
}
|
||||
|
@ -103,8 +152,8 @@ public class Schedule extends Observable {
|
|||
}
|
||||
|
||||
public static Schedule build(ScheduleModel scheduleModel) {
|
||||
Schedule schedule = new Schedule(extractSegments(scheduleModel.getPoints()));
|
||||
|
||||
Schedule schedule = new Schedule(
|
||||
extractSegments(scheduleModel.getPoints()));
|
||||
return schedule;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
package org.bench4q.agent.scenario.engine;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.ThreadPoolExecutor;
|
||||
|
@ -12,8 +14,9 @@ import org.bench4q.agent.datacollector.DataCollector;
|
|||
import org.bench4q.agent.datacollector.impl.ScenarioResultCollector;
|
||||
import org.bench4q.agent.plugin.PluginManager;
|
||||
import org.bench4q.agent.scenario.Scenario;
|
||||
import org.bench4q.agent.scenario.Schedule;
|
||||
|
||||
public class ScenarioContext {
|
||||
public class ScenarioContext extends Observable implements Observer {
|
||||
private static final long keepAliveTime = 10;
|
||||
private UUID testId;
|
||||
private Date startDate;
|
||||
|
@ -96,6 +99,7 @@ public class ScenarioContext {
|
|||
ScenarioContext scenarioContext = buildScenarioContextWithoutScenario(
|
||||
testId, poolSize, pluginManager);
|
||||
scenarioContext.setScenario(scenario);
|
||||
scenario.getSchedule().addObserver(scenarioContext);
|
||||
return scenarioContext;
|
||||
}
|
||||
|
||||
|
@ -127,7 +131,7 @@ public class ScenarioContext {
|
|||
*
|
||||
* @param requiredLoad
|
||||
*/
|
||||
void updatePopulation(int requiredLoad) {
|
||||
public void updatePopulation(int requiredLoad) {
|
||||
this.getExecutor().setCorePoolSize(requiredLoad);
|
||||
this.getExecutor().setMaximumPoolSize(requiredLoad);
|
||||
}
|
||||
|
@ -146,4 +150,20 @@ public class ScenarioContext {
|
|||
addTask();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void update(Observable o, Object arg) {
|
||||
Schedule schedule = (Schedule) o;
|
||||
if (schedule.hasReachEnd()) {
|
||||
stop();
|
||||
}else {
|
||||
this.updatePopulation((Integer) arg);
|
||||
}
|
||||
}
|
||||
|
||||
public void stop(){
|
||||
this.setFinished(true);
|
||||
this.setEndDate(new Date());
|
||||
this.getExecutor().shutdownNow();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ package org.bench4q.agent.scenario.engine;
|
|||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import org.apache.log4j.Logger;
|
||||
import org.bench4q.agent.plugin.PluginManager;
|
||||
import org.bench4q.agent.scenario.Scenario;
|
||||
|
@ -10,7 +11,7 @@ import org.springframework.beans.factory.annotation.Autowired;
|
|||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class ScenarioEngine {
|
||||
public class ScenarioEngine{
|
||||
private Map<UUID, ScenarioContext> runningTests;
|
||||
private Logger logger = Logger.getLogger(ScenarioEngine.class);
|
||||
private PluginManager pluginManager;
|
||||
|
@ -71,9 +72,4 @@ public class ScenarioEngine {
|
|||
scenarioContext.initTasks();
|
||||
return true;
|
||||
}
|
||||
|
||||
public void updatePopulation(UUID testId, int requiredLoad) {
|
||||
ScenarioContext context = this.getRunningTests().get(testId);
|
||||
context.updatePopulation(requiredLoad);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package org.bench4q.agent.scenario.engine;
|
||||
|
||||
import java.util.Timer;
|
||||
|
||||
public class Supervisor {
|
||||
private Timer timer;
|
||||
|
||||
public Supervisor(ScenarioContext context){
|
||||
timer = new Timer();
|
||||
}
|
||||
}
|
|
@ -3,6 +3,7 @@ package org.bench4q.agent.test;
|
|||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
|
||||
|
@ -18,7 +19,9 @@ import org.bench4q.share.models.agent.RunScenarioModel;
|
|||
import org.bench4q.share.models.agent.scriptrecord.BatchModel;
|
||||
import org.bench4q.share.models.agent.scriptrecord.BehaviorModel;
|
||||
import org.bench4q.share.models.agent.scriptrecord.PageModel;
|
||||
import org.bench4q.share.models.agent.scriptrecord.ScheduleModel;
|
||||
import org.bench4q.share.models.agent.scriptrecord.UsePluginModel;
|
||||
import org.bench4q.share.models.agent.scriptrecord.ScheduleModel.PointModel;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
public abstract class TestBase {
|
||||
|
@ -105,6 +108,12 @@ public abstract class TestBase {
|
|||
batch.getBehaviors().add(behavior);
|
||||
}
|
||||
page.getBatches().add(batch);
|
||||
ScheduleModel scheduleModel = new ScheduleModel();
|
||||
List<PointModel> points = new LinkedList<ScheduleModel.PointModel>();
|
||||
points.add(new PointModel(0, 0));
|
||||
points.add(new PointModel(10000, 10));
|
||||
scheduleModel.setPoints(points);
|
||||
runScenarioModel.setScheduleModel(scheduleModel);
|
||||
runScenarioModel.getPages().add(page);
|
||||
return runScenarioModel;
|
||||
}
|
||||
|
|
|
@ -49,7 +49,7 @@ public class Test_ScenarioEngine extends TestBase {
|
|||
new ArrayList<ParameterModel>()))),
|
||||
100, this.pluginManager);
|
||||
this.getScenarioEngine().getRunningTests().put(testId, scenarioContext);
|
||||
this.getScenarioEngine().updatePopulation(testId, 20);
|
||||
scenarioContext.updatePopulation(20);
|
||||
assertEquals(20, scenarioContext.getExecutor().getMaximumPoolSize());
|
||||
System.out.println(scenarioContext.getExecutor().getActiveCount());
|
||||
}
|
||||
|
|
|
@ -3,7 +3,9 @@ package org.bench4q.agent.test.scenario.engine;
|
|||
import static org.junit.Assert.*;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import org.bench4q.agent.scenario.Schedule;
|
||||
import org.bench4q.agent.scenario.Schedule.Segment;
|
||||
import org.bench4q.share.exception.Bench4QRunTimeException;
|
||||
import org.bench4q.share.models.agent.scriptrecord.ScheduleModel;
|
||||
import org.bench4q.share.models.agent.scriptrecord.ScheduleModel.PointModel;
|
||||
|
@ -72,4 +74,14 @@ public class Test_Shedule {
|
|||
int load = schedule.getSegments().get(0).loadFor(500 * 1000);
|
||||
assertEquals(75, load);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void test_getSegment(){
|
||||
ScheduleModel model = new ScheduleModel();
|
||||
model.getPoints().add(new PointModel(1000000, 100));
|
||||
model.getPoints().add(new PointModel(0, 50));
|
||||
Schedule schedule = Schedule.build(model);
|
||||
Segment segment = schedule.getSegment(500 * 1000);
|
||||
assertNotNull(segment);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue