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