Attention is currently required from: Anastasia Klimchuk.

Evan Benn has uploaded this change for review.

View Change

tests: Detect llvm-cov file io and unmock io functions

Code coverage writes data to disk atexit of the program. We need to
unmock the file io at this point so that the data is really written.

BUG=b:187647884
BRANCH=None
TEST=meson test
TEST=llvm-profdata merge -sparse default.profraw -o default.profdata
TEST=llvm-cov show ./flashrom_unit_tests
-instr-profile=default.profdata --format=html --output-dir=.

Change-Id: I21cc1d631e92fa19006b967e85676f108e80b307
Signed-off-by: Evan Benn <evanbenn@chromium.org>
---
M Documentation/building.md
M tests/tests.c
M tests/wraps.h
3 files changed, 57 insertions(+), 1 deletion(-)

git pull ssh://review.coreboot.org:29418/flashrom refs/changes/67/69267/1
diff --git a/Documentation/building.md b/Documentation/building.md
index 0e66f29..445fd65 100644
--- a/Documentation/building.md
+++ b/Documentation/building.md
@@ -49,12 +49,25 @@
```

### Run unit tests with code coverage
+
+#### gcc / gcov
```
meson setup buildcov -Db_coverage=true
ninja -C buildcov test
ninja -C buildcov coverage
```

+#### llvm
+https://clang.llvm.org/docs/SourceBasedCodeCoverage.html
+```
+env CFLAGS="-fprofile-instr-generate -fcoverage-mapping" CC=clang meson setup buildclangcov
+env LLVM_PROFILE_FILE=default.profraw ninja -C buildclangcov test
+cd buildclangcov
+llvm-profdata merge -sparse default.profraw -o default.profdata
+llvm-cov show ./flashrom_unit_tests -instr-profile=default.profdata --format=html --output-dir=.
+open index.html
+```
+
## System specific information
### Ubuntu / Debian (Linux)
* __linux-headers__ are version specific
diff --git a/tests/tests.c b/tests/tests.c
index 1b5b6d6..8d72a99 100644
--- a/tests/tests.c
+++ b/tests/tests.c
@@ -32,6 +32,12 @@
return __real_open(pathname, flags, mode);
}

+static FILE *unwrap_fopen(void *state, const char *pathname, const char *mode) {
+ LOG_ME;
+ (void)state;
+ return __real_fopen(pathname, mode);
+}
+
static FILE *unwrap_fdopen(void *state, int fd, const char *mode) {
LOG_ME;
(void)state;
@@ -44,12 +50,20 @@
return __real_fwrite(ptr, size, nmemb, fp);
}

+static int unwrap_fclose(void *state, FILE *fp) {
+ LOG_ME;
+ (void)state;
+ return __real_fclose(fp);
+}
+
// Mock ios that defer to the real io functions.
// These exist so that code coverage can print to real files on disk.
struct io_mock real_io_mock = {
.open = unwrap_open,
+ .fopen = unwrap_fopen,
.fwrite = unwrap_fwrite,
.fdopen = unwrap_fdopen,
+ .fclose = unwrap_fclose,
};

void *not_null(void)
@@ -117,7 +131,8 @@
static int mock_open(const char *pathname, int flags, mode_t mode)
{
// We detect code coverage writing the log files and defer to real io functions.
- if (!check_suffix(pathname, ".gcda")) {
+ if (!check_suffix(pathname, ".gcda")
+ || !check_suffix(pathname, ".profraw")) {
io_mock_register(&real_io_mock);
}

@@ -191,6 +206,12 @@
FILE *__wrap_fopen(const char *pathname, const char *mode)
{
LOG_ME;
+ // We detect code coverage writing the log files and defer to real io functions.
+ if (!check_suffix(pathname, ".gcda")
+ || !check_suffix(pathname, ".profraw")) {
+ io_mock_register(&real_io_mock);
+ }
+
if (get_io() && get_io()->fopen)
return get_io()->fopen(get_io()->state, pathname, mode);
return not_null();
diff --git a/tests/wraps.h b/tests/wraps.h
index 44f78f7..6d7d8fd 100644
--- a/tests/wraps.h
+++ b/tests/wraps.h
@@ -36,6 +36,7 @@
int __wrap_write(int fd, const void *buf, size_t sz);
int __wrap_read(int fd, void *buf, size_t sz);
FILE *__wrap_fopen(const char *pathname, const char *mode);
+FILE *__real_fopen(const char *pathname, const char *mode);
FILE *__wrap_fopen64(const char *pathname, const char *mode);
FILE *__wrap_fdopen(int fd, const char *mode);
FILE *__real_fdopen(int fd, const char *mode);
@@ -60,6 +61,7 @@
int __real_fprintf(FILE *fp, const char *fmt, ...);
int __wrap___vfprintf_chk(FILE *fp, const char *fmt, va_list args);
int __wrap_fclose(FILE *fp);
+int __real_fclose(FILE *fp);
int __wrap_feof(FILE *fp);
int __wrap_ferror(FILE *fp);
void __wrap_clearerr(FILE *fp);

To view, visit change 69267. To unsubscribe, or for help writing mail filters, visit settings.

Gerrit-Project: flashrom
Gerrit-Branch: master
Gerrit-Change-Id: I21cc1d631e92fa19006b967e85676f108e80b307
Gerrit-Change-Number: 69267
Gerrit-PatchSet: 1
Gerrit-Owner: Evan Benn <evanbenn@google.com>
Gerrit-Reviewer: Anastasia Klimchuk <aklm@chromium.org>
Gerrit-Attention: Anastasia Klimchuk <aklm@chromium.org>
Gerrit-MessageType: newchange