uboot/test/ut.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Simple unit test library
   4 *
   5 * Copyright (c) 2013 Google, Inc
   6 */
   7
   8#include <common.h>
   9#include <console.h>
  10#include <malloc.h>
  11#ifdef CONFIG_SANDBOX
  12#include <asm/state.h>
  13#endif
  14#include <asm/global_data.h>
  15#include <test/test.h>
  16#include <test/ut.h>
  17
  18DECLARE_GLOBAL_DATA_PTR;
  19
  20void ut_fail(struct unit_test_state *uts, const char *fname, int line,
  21             const char *func, const char *cond)
  22{
  23        gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
  24        printf("%s:%d, %s(): %s\n", fname, line, func, cond);
  25        uts->fail_count++;
  26}
  27
  28void ut_failf(struct unit_test_state *uts, const char *fname, int line,
  29              const char *func, const char *cond, const char *fmt, ...)
  30{
  31        va_list args;
  32
  33        gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
  34        printf("%s:%d, %s(): %s: ", fname, line, func, cond);
  35        va_start(args, fmt);
  36        vprintf(fmt, args);
  37        va_end(args);
  38        putc('\n');
  39        uts->fail_count++;
  40}
  41
  42ulong ut_check_free(void)
  43{
  44        struct mallinfo info = mallinfo();
  45
  46        return info.uordblks;
  47}
  48
  49long ut_check_delta(ulong last)
  50{
  51        return ut_check_free() - last;
  52}
  53
  54static int readline_check(struct unit_test_state *uts)
  55{
  56        int ret;
  57
  58        ret = console_record_readline(uts->actual_str, sizeof(uts->actual_str));
  59        if (ret == -ENOSPC) {
  60                ut_fail(uts, __FILE__, __LINE__, __func__,
  61                        "Console record buffer too small - increase CONFIG_CONSOLE_RECORD_OUT_SIZE");
  62                return ret;
  63        }
  64
  65        return 0;
  66}
  67
  68int ut_check_console_line(struct unit_test_state *uts, const char *fmt, ...)
  69{
  70        va_list args;
  71        int len;
  72        int ret;
  73
  74        va_start(args, fmt);
  75        len = vsnprintf(uts->expect_str, sizeof(uts->expect_str), fmt, args);
  76        va_end(args);
  77        if (len >= sizeof(uts->expect_str)) {
  78                ut_fail(uts, __FILE__, __LINE__, __func__,
  79                        "unit_test_state->expect_str too small");
  80                return -EOVERFLOW;
  81        }
  82        ret = readline_check(uts);
  83        if (ret < 0)
  84                return ret;
  85
  86        return strcmp(uts->expect_str, uts->actual_str);
  87}
  88
  89int ut_check_console_linen(struct unit_test_state *uts, const char *fmt, ...)
  90{
  91        va_list args;
  92        int len;
  93        int ret;
  94
  95        va_start(args, fmt);
  96        len = vsnprintf(uts->expect_str, sizeof(uts->expect_str), fmt, args);
  97        va_end(args);
  98        if (len >= sizeof(uts->expect_str)) {
  99                ut_fail(uts, __FILE__, __LINE__, __func__,
 100                        "unit_test_state->expect_str too small");
 101                return -EOVERFLOW;
 102        }
 103        ret = readline_check(uts);
 104        if (ret < 0)
 105                return ret;
 106
 107        return strncmp(uts->expect_str, uts->actual_str,
 108                       strlen(uts->expect_str));
 109}
 110
 111int ut_check_skipline(struct unit_test_state *uts)
 112{
 113        int ret;
 114
 115        if (!console_record_avail())
 116                return -ENFILE;
 117        ret = readline_check(uts);
 118        if (ret < 0)
 119                return ret;
 120
 121        return 0;
 122}
 123
 124int ut_check_console_end(struct unit_test_state *uts)
 125{
 126        int ret;
 127
 128        if (!console_record_avail())
 129                return 0;
 130        ret = readline_check(uts);
 131        if (ret < 0)
 132                return ret;
 133
 134        return 1;
 135}
 136
 137int ut_check_console_dump(struct unit_test_state *uts, int total_bytes)
 138{
 139        char *str = uts->actual_str;
 140        int upto;
 141
 142        /* Handle empty dump */
 143        if (!total_bytes)
 144                return 0;
 145
 146        for (upto = 0; upto < total_bytes;) {
 147                int len;
 148                int bytes;
 149
 150                len = console_record_readline(str, sizeof(uts->actual_str));
 151                if (str[8] != ':' || str[9] != ' ')
 152                        return 1;
 153
 154                bytes = len - 8 - 2 - 3 * 16 - 2;
 155                upto += bytes;
 156        }
 157
 158        return upto == total_bytes ? 0 : 1;
 159}
 160
 161void ut_silence_console(struct unit_test_state *uts)
 162{
 163#ifdef CONFIG_SANDBOX
 164        struct sandbox_state *state = state_get_current();
 165
 166        if (!state->show_test_output)
 167                gd->flags |= GD_FLG_SILENT;
 168#endif
 169}
 170
 171void ut_unsilence_console(struct unit_test_state *uts)
 172{
 173        gd->flags &= ~(GD_FLG_SILENT | GD_FLG_RECORD);
 174}
 175
 176void ut_set_skip_delays(struct unit_test_state *uts, bool skip_delays)
 177{
 178#ifdef CONFIG_SANDBOX
 179        state_set_skip_delays(skip_delays);
 180#endif
 181}
 182