blob: 0430614a49e3ce202123f2346b68f99466666e03 [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <errno.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/uio.h>
#include <zircon/processargs.h>
#include <zircon/syscalls.h>
#include <zircon/syscalls/log.h>
#include <unittest/unittest.h>
// output via debuglog syscalls
static zx_handle_t log_handle;
#define LOGBUF_MAX (ZX_LOG_RECORD_MAX - sizeof(zx_log_record_t))
static void log_write(const void* data, size_t len) {
while (len > 0) {
size_t xfer = (len > LOGBUF_MAX) ? LOGBUF_MAX : len;
zx_debuglog_write(log_handle, 0, data, xfer);
data += xfer;
len -= xfer;
}
}
// libc init and io stubs
// The reason these are here is that the "core" tests intentionally do not
// use fdio. See ./README.md.
static zx_handle_t root_resource;
void __libc_extensions_init(uint32_t count, zx_handle_t handle[], uint32_t info[]) {
for (unsigned n = 0; n < count; n++) {
if (info[n] == PA_HND(PA_RESOURCE, 0)) {
root_resource = handle[n];
handle[n] = 0;
info[n] = 0;
break;
}
}
}
zx_handle_t get_root_resource(void) {
return root_resource;
}
ssize_t write(int fd, const void* data, size_t count) {
if ((fd == 1) || (fd == 2)) {
log_write(data, count);
}
return count;
}
ssize_t readv(int fd, const struct iovec* iov, int num) {
return 0;
}
ssize_t writev(int fd, const struct iovec* iov, int num) {
ssize_t count = 0;
ssize_t r;
while (num > 0) {
if (iov->iov_len != 0) {
r = write(fd, iov->iov_base, iov->iov_len);
if (r < 0) {
return count ? count : r;
}
if ((size_t)r < iov->iov_len) {
return count + r;
}
count += r;
}
iov++;
num--;
}
return count;
}
#define ERROR() do { errno = ENOSYS; return -1; } while (0)
off_t lseek(int fd, off_t offset, int whence) {
ERROR();
}
int isatty(int fd) {
return 1;
}
int main(int argc, char** argv) {
if (get_root_resource() == ZX_HANDLE_INVALID) {
// If the root resource isn't available, printf will go nowhere. Put a
// message on the stack and crash. This will show up in the standard
// backtrace that's logged after aborting.
__UNUSED volatile const char kErrorMsg[] =
"Cannot access root resource, refusing to run tests.\n"
"core-tests must be invoked by userboot (e.g. userboot=bin/core-tests)\n";
abort();
}
if (zx_debuglog_create(get_root_resource(), 0, &log_handle) < 0) {
return -2;
}
zx_debuglog_write(log_handle, 0, "TEST", 4);
const bool success = unittest_run_all_tests(argc, argv);
if (!success) {
return EXIT_FAILURE;
}
// The continuous integration infrastructure looks for this string in the output. This exact
// string is matched in the recipe code. They need to be kept in sync. This random value was
// chosen because it's unlikely to be produced by other code paths.
fprintf(stderr, "core-tests succeeded RZMm59f7zOSs6aZUIXZR\n");
return EXIT_SUCCESS;
}