linux/lib/kunit/assert.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Assertion and expectation serialization API.
   4 *
   5 * Copyright (C) 2019, Google LLC.
   6 * Author: Brendan Higgins <brendanhiggins@google.com>
   7 */
   8#include <kunit/assert.h>
   9#include <kunit/test.h>
  10
  11#include "string-stream.h"
  12
  13void kunit_base_assert_format(const struct kunit_assert *assert,
  14                              struct string_stream *stream)
  15{
  16        const char *expect_or_assert = NULL;
  17
  18        switch (assert->type) {
  19        case KUNIT_EXPECTATION:
  20                expect_or_assert = "EXPECTATION";
  21                break;
  22        case KUNIT_ASSERTION:
  23                expect_or_assert = "ASSERTION";
  24                break;
  25        }
  26
  27        string_stream_add(stream, "%s FAILED at %s:%d\n",
  28                          expect_or_assert, assert->file, assert->line);
  29}
  30EXPORT_SYMBOL_GPL(kunit_base_assert_format);
  31
  32void kunit_assert_print_msg(const struct kunit_assert *assert,
  33                            struct string_stream *stream)
  34{
  35        if (assert->message.fmt)
  36                string_stream_add(stream, "\n%pV", &assert->message);
  37}
  38EXPORT_SYMBOL_GPL(kunit_assert_print_msg);
  39
  40void kunit_fail_assert_format(const struct kunit_assert *assert,
  41                              struct string_stream *stream)
  42{
  43        kunit_base_assert_format(assert, stream);
  44        string_stream_add(stream, "%pV", &assert->message);
  45}
  46EXPORT_SYMBOL_GPL(kunit_fail_assert_format);
  47
  48void kunit_unary_assert_format(const struct kunit_assert *assert,
  49                               struct string_stream *stream)
  50{
  51        struct kunit_unary_assert *unary_assert;
  52
  53        unary_assert = container_of(assert, struct kunit_unary_assert, assert);
  54
  55        kunit_base_assert_format(assert, stream);
  56        if (unary_assert->expected_true)
  57                string_stream_add(stream,
  58                                  KUNIT_SUBTEST_INDENT "Expected %s to be true, but is false\n",
  59                                  unary_assert->condition);
  60        else
  61                string_stream_add(stream,
  62                                  KUNIT_SUBTEST_INDENT "Expected %s to be false, but is true\n",
  63                                  unary_assert->condition);
  64        kunit_assert_print_msg(assert, stream);
  65}
  66EXPORT_SYMBOL_GPL(kunit_unary_assert_format);
  67
  68void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert,
  69                                     struct string_stream *stream)
  70{
  71        struct kunit_ptr_not_err_assert *ptr_assert;
  72
  73        ptr_assert = container_of(assert, struct kunit_ptr_not_err_assert,
  74                                  assert);
  75
  76        kunit_base_assert_format(assert, stream);
  77        if (!ptr_assert->value) {
  78                string_stream_add(stream,
  79                                  KUNIT_SUBTEST_INDENT "Expected %s is not null, but is\n",
  80                                  ptr_assert->text);
  81        } else if (IS_ERR(ptr_assert->value)) {
  82                string_stream_add(stream,
  83                                  KUNIT_SUBTEST_INDENT "Expected %s is not error, but is: %ld\n",
  84                                  ptr_assert->text,
  85                                  PTR_ERR(ptr_assert->value));
  86        }
  87        kunit_assert_print_msg(assert, stream);
  88}
  89EXPORT_SYMBOL_GPL(kunit_ptr_not_err_assert_format);
  90
  91/* Checks if `text` is a literal representing `value`, e.g. "5" and 5 */
  92static bool is_literal(struct kunit *test, const char *text, long long value,
  93                       gfp_t gfp)
  94{
  95        char *buffer;
  96        int len;
  97        bool ret;
  98
  99        len = snprintf(NULL, 0, "%lld", value);
 100        if (strlen(text) != len)
 101                return false;
 102
 103        buffer = kunit_kmalloc(test, len+1, gfp);
 104        if (!buffer)
 105                return false;
 106
 107        snprintf(buffer, len+1, "%lld", value);
 108        ret = strncmp(buffer, text, len) == 0;
 109
 110        kunit_kfree(test, buffer);
 111        return ret;
 112}
 113
 114void kunit_binary_assert_format(const struct kunit_assert *assert,
 115                                struct string_stream *stream)
 116{
 117        struct kunit_binary_assert *binary_assert;
 118
 119        binary_assert = container_of(assert, struct kunit_binary_assert,
 120                                     assert);
 121
 122        kunit_base_assert_format(assert, stream);
 123        string_stream_add(stream,
 124                          KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n",
 125                          binary_assert->left_text,
 126                          binary_assert->operation,
 127                          binary_assert->right_text);
 128        if (!is_literal(stream->test, binary_assert->left_text,
 129                        binary_assert->left_value, stream->gfp))
 130                string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld\n",
 131                                  binary_assert->left_text,
 132                                  binary_assert->left_value);
 133        if (!is_literal(stream->test, binary_assert->right_text,
 134                        binary_assert->right_value, stream->gfp))
 135                string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld",
 136                                  binary_assert->right_text,
 137                                  binary_assert->right_value);
 138        kunit_assert_print_msg(assert, stream);
 139}
 140EXPORT_SYMBOL_GPL(kunit_binary_assert_format);
 141
 142void kunit_binary_ptr_assert_format(const struct kunit_assert *assert,
 143                                    struct string_stream *stream)
 144{
 145        struct kunit_binary_ptr_assert *binary_assert;
 146
 147        binary_assert = container_of(assert, struct kunit_binary_ptr_assert,
 148                                     assert);
 149
 150        kunit_base_assert_format(assert, stream);
 151        string_stream_add(stream,
 152                          KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n",
 153                          binary_assert->left_text,
 154                          binary_assert->operation,
 155                          binary_assert->right_text);
 156        string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %px\n",
 157                          binary_assert->left_text,
 158                          binary_assert->left_value);
 159        string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %px",
 160                          binary_assert->right_text,
 161                          binary_assert->right_value);
 162        kunit_assert_print_msg(assert, stream);
 163}
 164EXPORT_SYMBOL_GPL(kunit_binary_ptr_assert_format);
 165
 166/* Checks if KUNIT_EXPECT_STREQ() args were string literals.
 167 * Note: `text` will have ""s where as `value` will not.
 168 */
 169static bool is_str_literal(const char *text, const char *value)
 170{
 171        int len;
 172
 173        len = strlen(text);
 174        if (len < 2)
 175                return false;
 176        if (text[0] != '\"' || text[len - 1] != '\"')
 177                return false;
 178
 179        return strncmp(text + 1, value, len - 2) == 0;
 180}
 181
 182void kunit_binary_str_assert_format(const struct kunit_assert *assert,
 183                                    struct string_stream *stream)
 184{
 185        struct kunit_binary_str_assert *binary_assert;
 186
 187        binary_assert = container_of(assert, struct kunit_binary_str_assert,
 188                                     assert);
 189
 190        kunit_base_assert_format(assert, stream);
 191        string_stream_add(stream,
 192                          KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n",
 193                          binary_assert->left_text,
 194                          binary_assert->operation,
 195                          binary_assert->right_text);
 196        if (!is_str_literal(binary_assert->left_text, binary_assert->left_value))
 197                string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == \"%s\"\n",
 198                                  binary_assert->left_text,
 199                                  binary_assert->left_value);
 200        if (!is_str_literal(binary_assert->right_text, binary_assert->right_value))
 201                string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == \"%s\"",
 202                                  binary_assert->right_text,
 203                                  binary_assert->right_value);
 204        kunit_assert_print_msg(assert, stream);
 205}
 206EXPORT_SYMBOL_GPL(kunit_binary_str_assert_format);
 207