Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,15 @@ public PeriodicReport(ReportLabel reportLabel, ReportPeriod reportPeriod) {
*/
private Integer reportingHour = 0;

/*
* The week value to be used in report lines
*/
private Integer reportingWeek = 0;

/**
* Adds the time field column(s) to the given {@link ReportHeader.Builder} as
* appropriate to the {@link ReportPeriod} specified during construction. DAILY
* : Day HOURLY : Day, Hour END_OF_SIMULATION has no header additions
* : day; HOURLY : day, hour; WEEKLY : day, week; END_OF_SIMULATION has no header additions
*/
protected final ReportHeader.Builder addTimeFieldHeaders(ReportHeader.Builder reportHeaderBuilder) {
switch (reportPeriod) {
Expand All @@ -67,6 +72,10 @@ protected final ReportHeader.Builder addTimeFieldHeaders(ReportHeader.Builder re
reportHeaderBuilder.add("day");
reportHeaderBuilder.add("hour");
break;
case WEEKLY:
reportHeaderBuilder.add("day");
reportHeaderBuilder.add("week");
break;
default:
throw new RuntimeException("unknown report period " + reportPeriod);
}
Expand All @@ -82,8 +91,9 @@ protected final ReportPeriod getReportPeriod() {
}

/**
* Places the current reporting day and report hour on the report as appropriate
* to the {@link ReportPeriod} specified during construction.
* Places the current reporting day, reporting hour, and reporting week on the
* report as appropriate to the {@link ReportPeriod} specified during
* construction.
*/
protected final void fillTimeFields(final ReportItem.Builder reportItemBuilder) {

Expand All @@ -98,6 +108,10 @@ protected final void fillTimeFields(final ReportItem.Builder reportItemBuilder)
reportItemBuilder.addValue(reportingDay);
reportItemBuilder.addValue(reportingHour);
break;
case WEEKLY:
reportItemBuilder.addValue(reportingDay);
reportItemBuilder.addValue(reportingWeek);
break;
default:
throw new RuntimeException("unknown report period " + reportPeriod);
}
Expand All @@ -124,6 +138,7 @@ public final void init(ReportContext reportContext) {
if (reportingHour > 23) {
reportingHour = 23;
}
reportingWeek = (int) (reportContext.getTime() / 7);

prepare(reportContext);

Expand Down Expand Up @@ -161,6 +176,8 @@ private double getNextPlanTime() {
case HOURLY:
return reportingDay + (double) (reportingHour) / 24;

case WEEKLY:
return reportingWeek * 7;
default:
throw new RuntimeException("unhandled report period " + reportPeriod);
}
Expand All @@ -178,6 +195,11 @@ private void incrementReportingTimeFields() {
reportingDay++;
}
break;
case WEEKLY:
int extraDays = reportingDay % 7;
reportingDay += (7 - extraDays);
reportingWeek++;
break;
case END_OF_SIMULATION:
// do nothing
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
* periodicity of the report.
*/
public enum ReportPeriod {
HOURLY, DAILY, END_OF_SIMULATION;
HOURLY, DAILY, WEEKLY, END_OF_SIMULATION;

public ReportPeriod next() {
int index = (ordinal()+1) % ReportPeriod.values().length;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,12 @@ public void testInit_ReportPeriod() {
assertDoesNotThrow(() -> Integer.parseInt(reportItem.getValue(1)));
assertDoesNotThrow(() -> TestGroupTypeId.valueOf(reportItem.getValue(2)));
break;
case WEEKLY:
assertEquals(REPORT_WEEKLY_HEADER, reportHeader);
assertDoesNotThrow(() -> Integer.parseInt(reportItem.getValue(0)));
assertDoesNotThrow(() -> Integer.parseInt(reportItem.getValue(1)));
assertDoesNotThrow(() -> TestGroupTypeId.valueOf(reportItem.getValue(2)));
break;
default:
throw new RuntimeException("unhandled case " + reportPeriod);
}
Expand Down Expand Up @@ -842,6 +848,9 @@ public void testInit_ReportHeader() {
case HOURLY:
assertEquals(REPORT_HOURLY_HEADER, reportHeader);
break;
case WEEKLY:
assertEquals(REPORT_WEEKLY_HEADER, reportHeader);
break;
default:
throw new RuntimeException("unhandled case " + reportPeriod);
}
Expand Down Expand Up @@ -943,6 +952,7 @@ public void testInit_State() {

private static final ReportHeader REPORT_DAILY_HEADER = ReportHeader.builder().setReportLabel(REPORT_LABEL).add("day").add("group_type").add("property").add("value").add("group_count").build();
private static final ReportHeader REPORT_HOURLY_HEADER = ReportHeader.builder().setReportLabel(REPORT_LABEL).add("day").add("hour").add("group_type").add("property").add("value").add("group_count").build();
private static final ReportHeader REPORT_WEEKLY_HEADER = ReportHeader.builder().setReportLabel(REPORT_LABEL).add("day").add("week").add("group_type").add("property").add("value").add("group_count").build();
private static final ReportHeader REPORT_END_OF_SIMULATION_HEADER = ReportHeader.builder().setReportLabel(REPORT_LABEL).add("group_type").add("property").add("value").add("group_count").build();

}
Original file line number Diff line number Diff line change
Expand Up @@ -358,7 +358,7 @@ public void testToString() {

String expectedValue = "PersonPropertyInteractionReportPluginData [data=Data ["
+ "reportLabel=SimpleReportLabel [value=report label95], "
+ "reportPeriod=HOURLY, "
+ "reportPeriod=WEEKLY, "
+ "personPropertyIds=["
+ "PERSON_PROPERTY_1_BOOLEAN_MUTABLE_NO_TRACK, "
+ "PERSON_PROPERTY_2_INTEGER_MUTABLE_NO_TRACK, "
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -427,6 +427,9 @@ private void testInit_ReportHeader(ReportPeriod reportPeriod) {
case HOURLY:
expectedReportHeader = REPORT_HOURLY_HEADER;
break;
case WEEKLY:
expectedReportHeader = REPORT_WEEKLY_HEADER;
break;
default:
throw new RuntimeException("unhandled case " + reportPeriod);

Expand Down Expand Up @@ -1160,6 +1163,8 @@ public String toString() {

private static final ReportHeader REPORT_HOURLY_HEADER = ReportHeader.builder().setReportLabel(REPORT_LABEL).add("day").add("hour").add("region")
.add("property").add("value").add("person_count").build();
private static final ReportHeader REPORT_WEEKLY_HEADER = ReportHeader.builder().setReportLabel(REPORT_LABEL).add("day").add("week").add("region")
.add("property").add("value").add("person_count").build();
private static final ReportHeader REPORT_DAILY_HEADER = ReportHeader.builder().setReportLabel(REPORT_LABEL).add("day").add("region")
.add("property").add("value").add("person_count").build();
private static final ReportHeader REPORT_END_OF_SIMULATION_HEADER = ReportHeader.builder().setReportLabel(REPORT_LABEL).add("region")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,55 @@ protected void prepare(ReportContext reportContext) {
}
}

/*
* Used to test the fillTimeFields() method when the period is
* ReportPeriod.WEEKLY
*/
private static class WeeklyTestReport extends PeriodicReport {

private MutableInteger testCounter = new MutableInteger();

public WeeklyTestReport(ReportLabel reportLabel, ReportPeriod reportPeriod) {
super(reportLabel, reportPeriod);
if (reportPeriod != ReportPeriod.WEEKLY) {
throw new RuntimeException("must be a weekly report");
}
}

@Override
protected void flush(ReportContext reportContext) {
testCounter.increment();
ReportItem.Builder reportItemBuilder = ReportItem.builder();

fillTimeFields(reportItemBuilder);

ReportItem reportItem = reportItemBuilder.setReportLabel(getReportLabel()).build();
int dayValue = (int) FastMath.ceil(reportContext.getTime());
int extraDays = dayValue % 7;
if (extraDays != 0) {
dayValue += (7 - extraDays);
}

String expectedDayTimeString = Integer.toString(dayValue);
String expectedWeekTimeString = Integer.toString(dayValue / 7);
String actualDayTimeString = reportItem.getValue(0);
String actualWeekTimeString = reportItem.getValue(1);
assertEquals(expectedDayTimeString, actualDayTimeString);
assertEquals(expectedWeekTimeString, actualWeekTimeString);

reportContext.releaseOutput(reportItem);
}

@Override
protected void prepare(ReportContext reportContext) {
ReportHeader.Builder reportHeaderBuilder = ReportHeader.builder();
this.addTimeFieldHeaders(reportHeaderBuilder);
ReportHeader reportHeader = reportHeaderBuilder.setReportLabel(getReportLabel()).build();

reportContext.releaseOutput(reportHeader);
}
}

/*
* Used to test the fillTimeFields() method when the period is
* ReportPeriod.END_OF_SIMULATION
Expand Down Expand Up @@ -226,6 +275,15 @@ public void testAddTimeFieldHeaders() {
assertEquals("day", headerStrings.get(0));
assertEquals("hour", headerStrings.get(1));

reportHeaderBuilder = ReportHeader.builder();
testReport = new TestReport(reportLabel, ReportPeriod.WEEKLY);
testReport.addTimeFieldHeaders(reportHeaderBuilder);
reportHeader = reportHeaderBuilder.setReportLabel(reportLabel).build();
headerStrings = reportHeader.getHeaderStrings();
assertEquals(2, headerStrings.size());
assertEquals("day", headerStrings.get(0));
assertEquals("week", headerStrings.get(1));

reportHeaderBuilder = ReportHeader.builder();
testReport = new TestReport(reportLabel, ReportPeriod.DAILY);
testReport.addTimeFieldHeaders(reportHeaderBuilder);
Expand Down Expand Up @@ -350,6 +408,63 @@ public void testFillTimeFields_Hourly() {

}

@Test
@UnitTestMethod(target = PeriodicReport.class, name = "init", args = { ReportContext.class })
public void testFillTimeFields_Weekly() {
double simulationEndTime = 21.5;

List<Plugin> plugins = new ArrayList<>();

ReportLabel reportLabel = new SimpleReportLabel("report");
WeeklyTestReport weeklyTestReport = new WeeklyTestReport(reportLabel, ReportPeriod.WEEKLY);

plugins.add(Plugin.builder()//
.setPluginId(new SimplePluginId("anonymous plugin"))//
.setInitializer((pc) -> {
pc.addReport(weeklyTestReport::init);
})//
.build());

TestPluginData.Builder pluginBuilder = TestPluginData.builder();

// create an agent that will make the engine run for a few days
pluginBuilder.addTestActorPlan("actor", new TestActorPlan(simulationEndTime, (c) -> {
}));

TestPluginData testPluginData = pluginBuilder.build();
Plugin testPlugin = TestPlugin.getTestPlugin(testPluginData);
plugins.add(testPlugin);

// build and execute the engine
TestOutputConsumer testOutputConsumer = TestSimulation.builder()//
.addPlugins(plugins)//
.build()//
.execute();

// weeks 0 through 4 weeks inclusive
Set<Integer> expectedWeeks = new LinkedHashSet<>();
Set<Integer> expectedDays = new LinkedHashSet<>();
for (int i = 1; i <= 4; i++) {
expectedWeeks.add(i);
expectedDays.add(i * 7);
}

Set<Integer> actualDays = new LinkedHashSet<>();
Set<Integer> actualWeeks = new LinkedHashSet<>();
Map<ReportItem, Integer> outputItems = testOutputConsumer.getOutputItemMap(ReportItem.class);
for (ReportItem reportItem : outputItems.keySet()) {
Integer count = outputItems.get(reportItem);
assertEquals(1, count);
int day = Integer.parseInt(reportItem.getValue(0));
actualDays.add(day);
int week = Integer.parseInt(reportItem.getValue(1));
actualWeeks.add(week);
}

assertEquals(expectedDays, actualDays);
assertEquals(expectedWeeks, actualWeeks);
}

@Test
@UnitTestMethod(target = PeriodicReport.class, name = "init", args = { ReportContext.class })
public void testFillTimeFields_EndOfSimulation() {
Expand Down Expand Up @@ -459,6 +574,14 @@ public void testInit() {
}
expectedTimes.add(simulationEndTime);

break;
case WEEKLY:
int lastWeek = (int) (simulationEndTime / 7);
for (int i = 1; i <= lastWeek; i++) {
double time = i * 7;
expectedTimes.add(time);
}
expectedTimes.add(simulationEndTime);
break;
default:
throw new RuntimeException("unhandled report period " + reportPeriod);
Expand Down