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 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 kunit_base_assert_format(assert, stream); 44 string_stream_add(stream, "%pV", &assert->message); 45 } 46 EXPORT_SYMBOL_GPL(kunit_fail_assert_format); 47 48 void kunit_unary_assert_format(const struct kunit_assert *assert, 49 struct string_stream *stream) 50 { 51 struct kunit_unary_assert *unary_assert = container_of( 52 assert, struct kunit_unary_assert, assert); 53 54 kunit_base_assert_format(assert, stream); 55 if (unary_assert->expected_true) 56 string_stream_add(stream, 57 KUNIT_SUBTEST_INDENT "Expected %s to be true, but is false\n", 58 unary_assert->condition); 59 else 60 string_stream_add(stream, 61 KUNIT_SUBTEST_INDENT "Expected %s to be false, but is true\n", 62 unary_assert->condition); 63 kunit_assert_print_msg(assert, stream); 64 } 65 EXPORT_SYMBOL_GPL(kunit_unary_assert_format); 66 67 void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert, 68 struct string_stream *stream) 69 { 70 struct kunit_ptr_not_err_assert *ptr_assert = container_of( 71 assert, struct kunit_ptr_not_err_assert, assert); 72 73 kunit_base_assert_format(assert, stream); 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 = container_of( 115 assert, struct kunit_binary_assert, assert); 116 117 kunit_base_assert_format(assert, stream); 118 string_stream_add(stream, 119 KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n", 120 binary_assert->left_text, 121 binary_assert->operation, 122 binary_assert->right_text); 123 if (!is_literal(stream->test, binary_assert->left_text, 124 binary_assert->left_value, stream->gfp)) 125 string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld\n", 126 binary_assert->left_text, 127 binary_assert->left_value); 128 if (!is_literal(stream->test, binary_assert->right_text, 129 binary_assert->right_value, stream->gfp)) 130 string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld", 131 binary_assert->right_text, 132 binary_assert->right_value); 133 kunit_assert_print_msg(assert, stream); 134 } 135 EXPORT_SYMBOL_GPL(kunit_binary_assert_format); 136 137 void kunit_binary_ptr_assert_format(const struct kunit_assert *assert, 138 struct string_stream *stream) 139 { 140 struct kunit_binary_ptr_assert *binary_assert = container_of( 141 assert, struct kunit_binary_ptr_assert, assert); 142 143 kunit_base_assert_format(assert, stream); 144 string_stream_add(stream, 145 KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n", 146 binary_assert->left_text, 147 binary_assert->operation, 148 binary_assert->right_text); 149 string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %px\n", 150 binary_assert->left_text, 151 binary_assert->left_value); 152 string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %px", 153 binary_assert->right_text, 154 binary_assert->right_value); 155 kunit_assert_print_msg(assert, stream); 156 } 157 EXPORT_SYMBOL_GPL(kunit_binary_ptr_assert_format); 158 159 void kunit_binary_str_assert_format(const struct kunit_assert *assert, 160 struct string_stream *stream) 161 { 162 struct kunit_binary_str_assert *binary_assert = container_of( 163 assert, struct kunit_binary_str_assert, assert); 164 165 kunit_base_assert_format(assert, stream); 166 string_stream_add(stream, 167 KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n", 168 binary_assert->left_text, 169 binary_assert->operation, 170 binary_assert->right_text); 171 string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %s\n", 172 binary_assert->left_text, 173 binary_assert->left_value); 174 string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %s", 175 binary_assert->right_text, 176 binary_assert->right_value); 177 kunit_assert_print_msg(assert, stream); 178 } 179 EXPORT_SYMBOL_GPL(kunit_binary_str_assert_format); 180