diff --git a/test/unit/prv.c b/test/unit/prv.c index 624627e..e775220 100644 --- a/test/unit/prv.c +++ b/test/unit/prv.c @@ -59,7 +59,7 @@ test_emit(const char *path) } static void -test_duplicate(const char *path) +test_dup(const char *path) { /* Ensure that we detect duplicate values being emitted in the Paraver * trace */ @@ -95,7 +95,183 @@ test_duplicate(const char *path) * the header has been fixed */ OK(prv_close(&prv)); - err("test duplicate OK\n"); + err("OK"); +} + +static int +count_prv_lines(FILE *f, int64_t time, int row0, long type, long value) +{ + int count = 0; + char line[1024]; + + rewind(f); + + while (fgets(line, 1024, f) != NULL) { + if (line[0] != '2') + continue; + + int64_t ftime; + long frow1, ftype, fvalue; + int ret = sscanf(line, "2:0:1:1:%ld:%ld:%ld:%ld", + &frow1, &ftime, &ftype, &fvalue); + + if (ret != 4) + die("ret=%d", ret); + + if (row0 + 1 != frow1 || time != ftime) + continue; + + if (type != ftype || value != fvalue) + continue; + + count++; + } + + return count; +} + +static void +test_skipdup(void) +{ + /* Test PRV_SKIPDUP flag (skip duplicates) */ + + size_t size = 1024; + char *buf = calloc(1, size); + + if (buf == NULL) + die("calloc failed:"); + + FILE *wf = fmemopen(buf, size, "w"); + + if (wf == NULL) + die("fmemopen failed:"); + + FILE *rf = fmemopen(buf, size, "r"); + + if (rf == NULL) + die("fmemopen failed:"); + + /* Disable buffering */ + setbuf(wf, NULL); + setbuf(rf, NULL); + + int64_t time = 0; + long type = 100; + long value = 1000; + + struct bay bay; + bay_init(&bay); + + struct prv prv; + OK(prv_open_file(&prv, NROWS, wf)); + + struct chan chan; + chan_init(&chan, CHAN_SINGLE, "testchan"); + + /* Allow setting the same value in the channel */ + chan_prop_set(&chan, CHAN_ALLOW_DUP, 1); + + OK(bay_register(&bay, &chan)); + OK(prv_register(&prv, 0, type, &bay, &chan, PRV_SKIPDUP)); + time += 10000; + + /* Set the initial value */ + OK(chan_set(&chan, value_int64(value))); + OK(prv_advance(&prv, time)); + + /* Propagate will emit the value into the PRV */ + OK(bay_propagate(&bay)); + + /* Check for the line */ + if (count_prv_lines(rf, time, 0, type, value) != 1) + die("expected line not found or multiple matches"); + + /* Set the same value again, which shouldn't fail */ + OK(chan_set(&chan, value_int64(value))); + + /* Propagate again, emitting the value */ + OK(bay_propagate(&bay)); + + /* Ensure that we didn't write it again */ + if (count_prv_lines(rf, time, 0, type, value) != 1) + die("expected line not found or multiple matches"); + + fclose(wf); + fclose(rf); + + err("OK"); +} + +static void +test_emitdup(void) +{ + /* Test PRV_EMITDUP flag (emit duplicates) */ + + size_t size = 1024; + char *buf = calloc(1, size); + + if (buf == NULL) + die("calloc failed:"); + + FILE *wf = fmemopen(buf, size, "w"); + + if (wf == NULL) + die("fmemopen failed:"); + + FILE *rf = fmemopen(buf, size, "r"); + + if (rf == NULL) + die("fmemopen failed:"); + + /* Disable buffering */ + setbuf(wf, NULL); + setbuf(rf, NULL); + + int64_t time = 0; + long type = 100; + long value = 1000; + + struct bay bay; + bay_init(&bay); + + struct prv prv; + OK(prv_open_file(&prv, NROWS, wf)); + + struct chan chan; + chan_init(&chan, CHAN_SINGLE, "testchan"); + + /* Allow setting the same value in the channel */ + chan_prop_set(&chan, CHAN_ALLOW_DUP, 1); + + OK(bay_register(&bay, &chan)); + OK(prv_register(&prv, 0, type, &bay, &chan, PRV_EMITDUP)); + time += 10000; + + /* Set the initial value */ + OK(chan_set(&chan, value_int64(value))); + OK(prv_advance(&prv, time)); + + /* Propagate will emit the value into the PRV */ + OK(bay_propagate(&bay)); + + /* Check for the line */ + if (count_prv_lines(rf, time, 0, type, value) != 1) + die("expected line not found or multiple matches"); + + /* Set the same value again, which shouldn't fail */ + OK(chan_set(&chan, value_int64(value))); + + /* Propagate again, emitting the value */ + OK(bay_propagate(&bay)); + + /* Ensure that we write it again */ + if (count_prv_lines(rf, time, 0, type, value) != 2) + die("expected line not found or multiple matches"); + + fclose(wf); + fclose(rf); + + err("OK"); } /* Detect same types being registered to the same row */ @@ -133,7 +309,9 @@ int main(void) die("mkstemp failed:"); test_emit(fname); - test_duplicate(fname); + test_dup(fname); + test_skipdup(); + test_emitdup(); test_same_type(fname); close(fd);