// SPDX-License-Identifier: GPL-2.0/* * Assertion and expectation serialization API. * * Copyright (C) 2019, Google LLC. * Author: Brendan Higgins <brendanhiggins@google.com> */#include <kunit/assert.h>#include <kunit/test.h>#include <kunit/visibility.h> #include "string-stream.h" void kunit_assert_prologue(const struct kunit_loc *loc, enum kunit_assert_type type, struct string_stream *stream){ const char *expect_or_assert = NULL; switch (type) { case KUNIT_EXPECTATION: expect_or_assert = "EXPECTATION"; break; case KUNIT_ASSERTION: expect_or_assert = "ASSERTION"; break; } string_stream_add(stream, "%s FAILED at %s:%d\n", expect_or_assert, loc->file, loc->line);}EXPORT_SYMBOL_GPL(kunit_assert_prologue); VISIBLE_IF_KUNITvoid kunit_assert_print_msg(const struct va_format *message, struct string_stream *stream){ if (message->fmt) string_stream_add(stream, "\n%pV", message);} void kunit_fail_assert_format(const struct kunit_assert *assert, const struct va_format *message, struct string_stream *stream){ string_stream_add(stream, "%pV", message);}EXPORT_SYMBOL_GPL(kunit_fail_assert_format); void kunit_unary_assert_format(const struct kunit_assert *assert, const struct va_format *message, struct string_stream *stream){ const struct kunit_unary_assert *unary_assert; unary_assert = container_of(assert, struct kunit_unary_assert, assert); if (unary_assert->expected_true) string_stream_add(stream, KUNIT_SUBTEST_INDENT "Expected %s to be true, but is false\n", unary_assert->condition); else string_stream_add(stream, KUNIT_SUBTEST_INDENT "Expected %s to be false, but is true\n", unary_assert->condition); kunit_assert_print_msg(message, stream);}EXPORT_SYMBOL_GPL(kunit_unary_assert_format); void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert, const struct va_format *message, struct string_stream *stream){ const struct kunit_ptr_not_err_assert *ptr_assert; ptr_assert = container_of(assert, struct kunit_ptr_not_err_assert, assert); if (!ptr_assert->value) { string_stream_add(stream, KUNIT_SUBTEST_INDENT "Expected %s is not null, but is\n", ptr_assert->text); } else if (IS_ERR(ptr_assert->value)) { string_stream_add(stream, KUNIT_SUBTEST_INDENT "Expected %s is not error, but is: %ld\n", ptr_assert->text, PTR_ERR(ptr_assert->value)); } kunit_assert_print_msg(message, stream);}EXPORT_SYMBOL_GPL(kunit_ptr_not_err_assert_format); /* Checks if `text` is a literal representing `value`, e.g. "5" and 5 */VISIBLE_IF_KUNIT bool is_literal(const char *text, long long value){ char *buffer; int len; bool ret; len = snprintf(NULL, 0, "%lld", value); if (strlen(text) != len) return false; buffer = kmalloc(len+1, GFP_KERNEL); if (!buffer) return false; snprintf(buffer, len+1, "%lld", value); ret = strncmp(buffer, text, len) == 0; kfree(buffer); return ret;} void kunit_binary_assert_format(const struct kunit_assert *assert, const struct va_format *message, struct string_stream *stream){ const struct kunit_binary_assert *binary_assert; binary_assert = container_of(assert, struct kunit_binary_assert, assert); string_stream_add(stream, KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n", binary_assert->text->left_text, binary_assert->text->operation, binary_assert->text->right_text); if (!is_literal(binary_assert->text->left_text, binary_assert->left_value)) string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld (0x%llx)\n", binary_assert->text->left_text, binary_assert->left_value, binary_assert->left_value); if (!is_literal(binary_assert->text->right_text, binary_assert->right_value)) string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld (0x%llx)", binary_assert->text->right_text, binary_assert->right_value, binary_assert->right_value); kunit_assert_print_msg(message, stream);}EXPORT_SYMBOL_GPL(kunit_binary_assert_format); void kunit_binary_ptr_assert_format(const struct kunit_assert *assert, const struct va_format *message, struct string_stream *stream){ const struct kunit_binary_ptr_assert *binary_assert; binary_assert = container_of(assert, struct kunit_binary_ptr_assert, assert); string_stream_add(stream, KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n", binary_assert->text->left_text, binary_assert->text->operation, binary_assert->text->right_text); string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %px\n", binary_assert->text->left_text, binary_assert->left_value); string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %px", binary_assert->text->right_text, binary_assert->right_value); kunit_assert_print_msg(message, stream);}EXPORT_SYMBOL_GPL(kunit_binary_ptr_assert_format); /* Checks if KUNIT_EXPECT_STREQ() args were string literals. * Note: `text` will have ""s where as `value` will not. */VISIBLE_IF_KUNIT bool is_str_literal(const char *text, const char *value){ int len; len = strlen(text); if (len < 2) return false; if (text[0] != '\"' || text[len - 1] != '\"') return false; return strncmp(text + 1, value, len - 2) == 0;} void kunit_binary_str_assert_format(const struct kunit_assert *assert, const struct va_format *message, struct string_stream *stream){ const struct kunit_binary_str_assert *binary_assert; binary_assert = container_of(assert, struct kunit_binary_str_assert, assert); string_stream_add(stream, KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n", binary_assert->text->left_text, binary_assert->text->operation, binary_assert->text->right_text); if (!is_str_literal(binary_assert->text->left_text, binary_assert->left_value)) string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == \"%s\"\n", binary_assert->text->left_text, binary_assert->left_value); if (!is_str_literal(binary_assert->text->right_text, binary_assert->right_value)) string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == \"%s\"", binary_assert->text->right_text, binary_assert->right_value); kunit_assert_print_msg(message, stream);}EXPORT_SYMBOL_GPL(kunit_binary_str_assert_format); /* Adds a hexdump of a buffer to a string_stream comparing it with * a second buffer. The different bytes are marked with <>. */VISIBLE_IF_KUNITvoid kunit_assert_hexdump(struct string_stream *stream, const void *buf, const void *compared_buf, const size_t len){ size_t i; const u8 *buf1 = buf; const u8 *buf2 = compared_buf; string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT); for (i = 0; i < len; ++i) { if (!(i % 16) && i) string_stream_add(stream, "\n" KUNIT_SUBSUBTEST_INDENT); if (buf1[i] != buf2[i]) string_stream_add(stream, "<%02x>", buf1[i]); else string_stream_add(stream, " %02x ", buf1[i]); }} void kunit_mem_assert_format(const struct kunit_assert *assert, const struct va_format *message, struct string_stream *stream){ const struct kunit_mem_assert *mem_assert; mem_assert = container_of(assert, struct kunit_mem_assert, assert); if (!mem_assert->left_value) { string_stream_add(stream, KUNIT_SUBTEST_INDENT "Expected %s is not null, but is\n", mem_assert->text->left_text); } else if (!mem_assert->right_value) { string_stream_add(stream, KUNIT_SUBTEST_INDENT "Expected %s is not null, but is\n", mem_assert->text->right_text); } else { string_stream_add(stream, KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n", mem_assert->text->left_text, mem_assert->text->operation, mem_assert->text->right_text); string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s ==\n", mem_assert->text->left_text); kunit_assert_hexdump(stream, mem_assert->left_value, mem_assert->right_value, mem_assert->size); string_stream_add(stream, "\n"); string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s ==\n", mem_assert->text->right_text); kunit_assert_hexdump(stream, mem_assert->right_value, mem_assert->left_value, mem_assert->size); kunit_assert_print_msg(message, stream); }}EXPORT_SYMBOL_GPL(kunit_mem_assert_format);
// SPDX-License-Identifier: GPL-2.0
/*
* Assertion and expectation serialization API.
*
* Copyright (C) 2019, Google LLC.
* Author: Brendan Higgins <brendanhiggins@google.com>
*/
#include <kunit/assert.h>
#include <kunit/test.h>
#include <kunit/visibility.h>
#include "string-stream.h"
void kunit_assert_prologue(const struct kunit_loc *loc,
enum kunit_assert_type type,
struct string_stream *stream)
{
const char *expect_or_assert = NULL;
switch (type) {
case KUNIT_EXPECTATION:
expect_or_assert = "EXPECTATION";
break;
case KUNIT_ASSERTION:
expect_or_assert = "ASSERTION";
break;
}
string_stream_add(stream, "%s FAILED at %s:%d\n",
expect_or_assert, loc->file, loc->line);
}
EXPORT_SYMBOL_GPL(kunit_assert_prologue);
VISIBLE_IF_KUNIT
void kunit_assert_print_msg(const struct va_format *message,
struct string_stream *stream)
{
if (message->fmt)
string_stream_add(stream, "\n%pV", message);
}
void kunit_fail_assert_format(const struct kunit_assert *assert,
const struct va_format *message,
struct string_stream *stream)
{
string_stream_add(stream, "%pV", message);
}
EXPORT_SYMBOL_GPL(kunit_fail_assert_format);
void kunit_unary_assert_format(const struct kunit_assert *assert,
const struct va_format *message,
struct string_stream *stream)
{
const struct kunit_unary_assert *unary_assert;
unary_assert = container_of(assert, struct kunit_unary_assert, assert);
if (unary_assert->expected_true)
string_stream_add(stream,
KUNIT_SUBTEST_INDENT "Expected %s to be true, but is false\n",
unary_assert->condition);
else
string_stream_add(stream,
KUNIT_SUBTEST_INDENT "Expected %s to be false, but is true\n",
unary_assert->condition);
kunit_assert_print_msg(message, stream);
}
EXPORT_SYMBOL_GPL(kunit_unary_assert_format);
void kunit_ptr_not_err_assert_format(const struct kunit_assert *assert,
const struct va_format *message,
struct string_stream *stream)
{
const struct kunit_ptr_not_err_assert *ptr_assert;
ptr_assert = container_of(assert, struct kunit_ptr_not_err_assert,
assert);
if (!ptr_assert->value) {
string_stream_add(stream,
KUNIT_SUBTEST_INDENT "Expected %s is not null, but is\n",
ptr_assert->text);
} else if (IS_ERR(ptr_assert->value)) {
string_stream_add(stream,
KUNIT_SUBTEST_INDENT "Expected %s is not error, but is: %ld\n",
ptr_assert->text,
PTR_ERR(ptr_assert->value));
}
kunit_assert_print_msg(message, stream);
}
EXPORT_SYMBOL_GPL(kunit_ptr_not_err_assert_format);
/* Checks if `text` is a literal representing `value`, e.g. "5" and 5 */
VISIBLE_IF_KUNIT bool is_literal(const char *text, long long value)
{
char *buffer;
int len;
bool ret;
len = snprintf(NULL, 0, "%lld", value);
if (strlen(text) != len)
return false;
buffer = kmalloc(len+1, GFP_KERNEL);
if (!buffer)
return false;
snprintf(buffer, len+1, "%lld", value);
ret = strncmp(buffer, text, len) == 0;
kfree(buffer);
return ret;
}
void kunit_binary_assert_format(const struct kunit_assert *assert,
const struct va_format *message,
struct string_stream *stream)
{
const struct kunit_binary_assert *binary_assert;
binary_assert = container_of(assert, struct kunit_binary_assert,
assert);
string_stream_add(stream,
KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n",
binary_assert->text->left_text,
binary_assert->text->operation,
binary_assert->text->right_text);
if (!is_literal(binary_assert->text->left_text, binary_assert->left_value))
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld (0x%llx)\n",
binary_assert->text->left_text,
binary_assert->left_value,
binary_assert->left_value);
if (!is_literal(binary_assert->text->right_text, binary_assert->right_value))
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %lld (0x%llx)",
binary_assert->text->right_text,
binary_assert->right_value,
binary_assert->right_value);
kunit_assert_print_msg(message, stream);
}
EXPORT_SYMBOL_GPL(kunit_binary_assert_format);
void kunit_binary_ptr_assert_format(const struct kunit_assert *assert,
const struct va_format *message,
struct string_stream *stream)
{
const struct kunit_binary_ptr_assert *binary_assert;
binary_assert = container_of(assert, struct kunit_binary_ptr_assert,
assert);
string_stream_add(stream,
KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n",
binary_assert->text->left_text,
binary_assert->text->operation,
binary_assert->text->right_text);
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %px\n",
binary_assert->text->left_text,
binary_assert->left_value);
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == %px",
binary_assert->text->right_text,
binary_assert->right_value);
kunit_assert_print_msg(message, stream);
}
EXPORT_SYMBOL_GPL(kunit_binary_ptr_assert_format);
/* Checks if KUNIT_EXPECT_STREQ() args were string literals.
* Note: `text` will have ""s where as `value` will not.
*/
VISIBLE_IF_KUNIT bool is_str_literal(const char *text, const char *value)
{
int len;
len = strlen(text);
if (len < 2)
return false;
if (text[0] != '\"' || text[len - 1] != '\"')
return false;
return strncmp(text + 1, value, len - 2) == 0;
}
void kunit_binary_str_assert_format(const struct kunit_assert *assert,
const struct va_format *message,
struct string_stream *stream)
{
const struct kunit_binary_str_assert *binary_assert;
binary_assert = container_of(assert, struct kunit_binary_str_assert,
assert);
string_stream_add(stream,
KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n",
binary_assert->text->left_text,
binary_assert->text->operation,
binary_assert->text->right_text);
if (!is_str_literal(binary_assert->text->left_text, binary_assert->left_value))
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == \"%s\"\n",
binary_assert->text->left_text,
binary_assert->left_value);
if (!is_str_literal(binary_assert->text->right_text, binary_assert->right_value))
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s == \"%s\"",
binary_assert->text->right_text,
binary_assert->right_value);
kunit_assert_print_msg(message, stream);
}
EXPORT_SYMBOL_GPL(kunit_binary_str_assert_format);
/* Adds a hexdump of a buffer to a string_stream comparing it with
* a second buffer. The different bytes are marked with <>.
*/
VISIBLE_IF_KUNIT
void kunit_assert_hexdump(struct string_stream *stream,
const void *buf,
const void *compared_buf,
const size_t len)
{
size_t i;
const u8 *buf1 = buf;
const u8 *buf2 = compared_buf;
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT);
for (i = 0; i < len; ++i) {
if (!(i % 16) && i)
string_stream_add(stream, "\n" KUNIT_SUBSUBTEST_INDENT);
if (buf1[i] != buf2[i])
string_stream_add(stream, "<%02x>", buf1[i]);
else
string_stream_add(stream, " %02x ", buf1[i]);
}
}
void kunit_mem_assert_format(const struct kunit_assert *assert,
const struct va_format *message,
struct string_stream *stream)
{
const struct kunit_mem_assert *mem_assert;
mem_assert = container_of(assert, struct kunit_mem_assert,
assert);
if (!mem_assert->left_value) {
string_stream_add(stream,
KUNIT_SUBTEST_INDENT "Expected %s is not null, but is\n",
mem_assert->text->left_text);
} else if (!mem_assert->right_value) {
string_stream_add(stream,
KUNIT_SUBTEST_INDENT "Expected %s is not null, but is\n",
mem_assert->text->right_text);
} else {
string_stream_add(stream,
KUNIT_SUBTEST_INDENT "Expected %s %s %s, but\n",
mem_assert->text->left_text,
mem_assert->text->operation,
mem_assert->text->right_text);
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s ==\n",
mem_assert->text->left_text);
kunit_assert_hexdump(stream, mem_assert->left_value,
mem_assert->right_value, mem_assert->size);
string_stream_add(stream, "\n");
string_stream_add(stream, KUNIT_SUBSUBTEST_INDENT "%s ==\n",
mem_assert->text->right_text);
kunit_assert_hexdump(stream, mem_assert->right_value,
mem_assert->left_value, mem_assert->size);
kunit_assert_print_msg(message, stream);
}
}
EXPORT_SYMBOL_GPL(kunit_mem_assert_format);