Skip to content

Commit a10988b

Browse files
committed
Adds negative tests and an exit function handler
1 parent f9690e3 commit a10988b

10 files changed

+226
-11
lines changed

events.c

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,16 +135,15 @@ EventNode** readEventData(char *eventFile, int numLocs) {
135135
printf("Error: unknown event type %s\n", eventTypeStr);
136136
exit(1);
137137
}
138-
printf("Found event type %d (%s)\n", eventType, eventTypeStr);
139138

140139
next = createEventNode(loc, year, day, eventType, eventParamsStr);
141140
events[loc] = next;
142141
currLoc = loc;
143142
currYear = year;
144143
currDay = day;
145144

146-
printf("Found events:\n");
147-
printEvent(next);
145+
//printf("Found events:\n");
146+
//printEvent(next);
148147

149148
while (fgets(line, EVENT_LINE_SIZE, in) != NULL) {
150149
// We have another event
@@ -172,7 +171,7 @@ EventNode** readEventData(char *eventFile, int numLocs) {
172171
}
173172

174173
next = createEventNode(loc, year, day, eventType, eventParamsStr);
175-
printEvent(next);
174+
//printEvent(next);
176175
if (currLoc == loc) {
177176
// Same location, add the new event to this location's list
178177
curr->nextEvent = next;

tests/sipnet/exitHandler.c

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include <setjmp.h>
2+
#include <unistd.h>
3+
4+
static int expected_code = 1; // the expected value a tested function passes to exit
5+
static int should_exit = 1; // 1 if exit should have been called
6+
static int really_exit = 0; // set to 1 to prevent stubbing behavior and actually exit
7+
8+
static jmp_buf jump_env;
9+
10+
static int exit_result = 1;
11+
#define test_assert(x) (exit_result = exit_result && (x))
12+
13+
// set should_exit=0 when code SHOULDN'T exit(), e.g.:
14+
//
15+
// should_exit = 0;
16+
// if (!(jmp_rval=setjmp(jump_env)))
17+
// {
18+
// call_to_non_exiting_code();
19+
// }
20+
// test_assert(jmp_rval==0);
21+
//
22+
// set should_exit=1 when exit(0 is expected:
23+
//
24+
// should_exit = 1;
25+
// expected_code = 1; // or whatever the exit code should be
26+
// if (!(jmp_rval=setjmp(jump_env)))
27+
// {
28+
// call_to_exiting_code();
29+
// }
30+
//
31+
// test_assert(jmp_rval==1);
32+
33+
// stub function
34+
void exit(int code)
35+
{
36+
if (!really_exit)
37+
{
38+
printf("Mocking the exit call\n");
39+
test_assert(should_exit==1);
40+
test_assert(expected_code==code);
41+
longjmp(jump_env, 1);
42+
}
43+
else
44+
{
45+
_exit(code);
46+
}
47+
}

tests/sipnet/test_events/Makefile

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ LDFLAGS=-L../../..
55
LDLIBS=-lsipnet -lm
66

77
# List test files in this directory here
8-
TEST_CFILES=testEventInfra.c
8+
TEST_CFILES=testEventInfra.c testEventInfraNeg.c
9+
10+
# The rest is boilerplate, likely copyable as is to a new test directory
911
TEST_OBJ_FILES=$(TEST_CFILES:%.c=%.o)
1012
TEST_EXECUTABLES:=$(basename $(TEST_CFILES))
1113
RUN_EXECUTABLES:= $(addsuffix .run, $(TEST_EXECUTABLES))
@@ -17,7 +19,7 @@ tests: $(TEST_EXECUTABLES)
1719
$(TEST_EXECUTABLES): %: %.o
1820
$(CC) $(LDFLAGS) $< $(LDLIBS) -o $@
1921

20-
$(TEST_OBJ_FILES): ../utils.h ../../../libsipnet.a
22+
$(TEST_OBJ_FILES): ../utils.h ../../../libsipnet.a ../exitHandler.c
2123
$(TEST_OBJ_FILES): %.o: %.c
2224
$(CC) $(CFLAGS) -c -o $@ $<
2325

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
0 2024 60 till 0.1 0.2 0.3
2+
0 2024 55 plant 15 20 5
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
0 2024 60 till 0.1 0.2 0.3
2+
1 2024 65 plant 15 20 5
3+
0 2024 70 irrig 5 1
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
0 2024 60 till 0.1 0.2 0.3
2+
0 2024 65 plant 15 20 5
3+
0 2024 70 irrig 5 1
4+
0 2024 75 fert 15 10 5
5+
0 2024 250 harv 0.1 0.2 0.3 0.4
6+
1 2024 59 till 0.2 0.3 0.1
7+
1 2024 64 plant 15 20 5
8+
1 2024 69 irrig 5 0
9+
1 2024 74 fert 5 15 10
10+
1 2024 249 harv 0.2 0.3 0.4 0.1
11+
2 2024 58 till 0.3 0.1 0.2
12+
2 2024 63 plant 15 20 5
13+
2 2024 68 irrig 6 1
14+
2 2024 73 fert 5 10 15
15+
2 2024 248 harv 0.3 0.4 0.1 0.2

tests/sipnet/test_events/infra_events.in renamed to tests/sipnet/test_events/infra_events_simple.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
0 2022 40 irrig 5 0 # 5cm canopy irrigation on day 40
1+
0 2022 40 irrig 5 0 # 5cm canopy irrigation on day 40
22
0 2022 40 fert 15 5 10 # fertilized with 15 g/m2 organic N, 5 g/m2 organic C, and 10 g/m2 mineral N on day 40
33
0 2022 45 till 0.1 0.2 0.3 # tilled on day 45, 10% of surface litter transferred to soil pool, soil organic matter pool decomposition rate increases by 20% and soil litter pool decomposition rate increases by 30%
44
0 2022 46 plant 10 10 1 # planting - planting occurs on day 40, after 10 days the plants have emerged with a size of 10 g C/m2 and 1 g N / m2
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
0 2022 40 blarg 5 0

tests/sipnet/test_events/testEventInfra.c

Lines changed: 82 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11

22
#include <stdio.h>
33
#include <stdlib.h>
4-
#include <unistd.h>
54

65
#include "../utils.h"
76
#include "../../../events.c"
@@ -82,7 +81,7 @@ int checkTillageParams(
8281
}
8382

8483
int init() {
85-
// char * filename = "infra_events.in";
84+
// char * filename = "infra_events_simple.in";
8685
// if (access(filename, F_OK) == -1) {
8786
// return 1;
8887
// }
@@ -91,9 +90,10 @@ int init() {
9190
return 0;
9291
}
9392

94-
int run() {
93+
int runTestSimple() {
94+
// Simple test with one loc, one event per type
9595
int numLocs = 1;
96-
EventNode** output = readEventData("infra_events.in", numLocs);
96+
EventNode** output = readEventData("infra_events_simple.in", numLocs);
9797

9898
if (!output) {
9999
return 1;
@@ -117,6 +117,84 @@ int run() {
117117
status |= checkEvent(event, 0, 2022, 250, HARVEST);
118118
status |= checkHarvestParams((HarvestParams*)event->eventParams, 0.4, 0.1, 0.2, 0.3);
119119

120+
return status;
121+
}
122+
123+
int runTestMulti() {
124+
// More complex test; multiple locations
125+
int numLocs = 1;
126+
EventNode** output = readEventData("infra_events_multi.in", numLocs);
127+
128+
if (!output) {
129+
return 1;
130+
}
131+
132+
// check output is correct
133+
int status = 0;
134+
int loc = 0;
135+
EventNode *event = output[loc];
136+
status |= checkEvent(event, loc, 2024, 60, TILLAGE);
137+
status |= checkTillageParams((TillageParams*)event->eventParams, 0.1, 0.2, 0.3);
138+
event = event->nextEvent;
139+
status |= checkEvent(event, loc, 2024, 65, PLANTING);
140+
status |= checkPlantingParams((PlantingParams*)event->eventParams, 15, 20, 5);
141+
event = event->nextEvent;
142+
status |= checkEvent(event, loc, 2024, 70, IRRIGATION);
143+
status |= checkIrrigationParams((IrrigationParams*)event->eventParams, 5, 1);
144+
event = event->nextEvent;
145+
status |= checkEvent(event, loc, 2024, 75, FERTILIZATION);
146+
status |= checkFertilizationParams((FertilizationParams*)event->eventParams, 15, 10,5);
147+
event = event->nextEvent;
148+
status |= checkEvent(event, loc, 2024, 250, HARVEST);
149+
status |= checkHarvestParams((HarvestParams*)event->eventParams, 0.1, 0.2, 0.3, 0.4);
150+
151+
loc++;
152+
event = output[loc];
153+
status |= checkEvent(event, loc, 2024, 59, TILLAGE);
154+
status |= checkTillageParams((TillageParams*)event->eventParams, 0.2, 0.3, 0.1);
155+
event = event->nextEvent;
156+
status |= checkEvent(event, loc, 2024, 64, PLANTING);
157+
status |= checkPlantingParams((PlantingParams*)event->eventParams, 15, 20, 5);
158+
event = event->nextEvent;
159+
status |= checkEvent(event, loc, 2024, 69, IRRIGATION);
160+
status |= checkIrrigationParams((IrrigationParams*)event->eventParams, 5, 0);
161+
event = event->nextEvent;
162+
status |= checkEvent(event, loc, 2024, 74, FERTILIZATION);
163+
status |= checkFertilizationParams((FertilizationParams*)event->eventParams, 5, 15,10);
164+
event = event->nextEvent;
165+
status |= checkEvent(event, loc, 2024, 249, HARVEST);
166+
status |= checkHarvestParams((HarvestParams*)event->eventParams, 0.2, 0.3, 0.4, 0.1);
167+
168+
loc++;
169+
event = output[loc];
170+
status |= checkEvent(event, loc, 2024, 58, TILLAGE);
171+
status |= checkTillageParams((TillageParams*)event->eventParams, 0.3, 0.1, 0.2);
172+
event = event->nextEvent;
173+
status |= checkEvent(event, loc, 2024, 63, PLANTING);
174+
status |= checkPlantingParams((PlantingParams*)event->eventParams, 15, 20, 5);
175+
event = event->nextEvent;
176+
status |= checkEvent(event, loc, 2024, 68, IRRIGATION);
177+
status |= checkIrrigationParams((IrrigationParams*)event->eventParams, 6, 1);
178+
event = event->nextEvent;
179+
status |= checkEvent(event, loc, 2024, 73, FERTILIZATION);
180+
status |= checkFertilizationParams((FertilizationParams*)event->eventParams, 5, 10,15);
181+
event = event->nextEvent;
182+
status |= checkEvent(event, loc, 2024, 248, HARVEST);
183+
status |= checkHarvestParams((HarvestParams*)event->eventParams, 0.3, 0.4, 0.1, 0.2);
184+
185+
return status;
186+
}
187+
188+
int run() {
189+
190+
int status;
191+
192+
status = runTestSimple();
193+
if (status) {
194+
return 1;
195+
}
196+
197+
status = runTestMulti();
120198
if (status) {
121199
return 1;
122200
}
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
2+
#include <stdio.h>
3+
#include <stdlib.h>
4+
5+
#include "../../../events.c"
6+
#include "../exitHandler.c"
7+
8+
int run() {
9+
int status = 0;
10+
11+
// exit() handling params
12+
int jmp_rval;
13+
expected_code = 1;
14+
exit_result = 1;
15+
16+
// Step 0: make sure that we don't have a false positive on good data
17+
should_exit = 0;
18+
jmp_rval = setjmp(jump_env);
19+
if (!jmp_rval) {
20+
readEventData("infra_events_simple.in", 1);
21+
}
22+
test_assert(jmp_rval==0);
23+
status |= !exit_result;
24+
25+
// First test
26+
should_exit = 1;
27+
jmp_rval = setjmp(jump_env);
28+
if (!jmp_rval) {
29+
readEventData("infra_events_unknown.in", 1);
30+
}
31+
printf("status %d exit_res %d jmp_rval %d\n", status, exit_result, jmp_rval);
32+
test_assert(jmp_rval==1);
33+
status |= !exit_result;
34+
35+
// Second test
36+
jmp_rval = setjmp(jump_env);
37+
if (!jmp_rval) {
38+
readEventData("infra_events_loc_ooo.in", 1);
39+
}
40+
test_assert(jmp_rval==1);
41+
status |= !exit_result;
42+
43+
// Third test
44+
jmp_rval = setjmp(jump_env);
45+
if (!jmp_rval) {
46+
readEventData("infra_events_date_ooo.in", 1);
47+
}
48+
test_assert(jmp_rval==1);
49+
status |= !exit_result;
50+
51+
// Allow a real exit, not that this is really needed
52+
really_exit = 1;
53+
54+
return status;
55+
}
56+
57+
int main() {
58+
int status;
59+
60+
printf("Starting testEventInfraNeg:run()\n");
61+
status = run();
62+
if (status) {
63+
printf("Test run failed with status %d\n", status);
64+
exit(status);
65+
}
66+
67+
printf("testEventInfra PASSED\n");
68+
}

0 commit comments

Comments
 (0)