Merge tag 'for-linus' of git://git.armlinux.org.uk/~rmk/linux-arm
[platform/kernel/linux-rpi.git] / include / kunit / test.h
index 524d478..24b40e5 100644 (file)
@@ -97,6 +97,9 @@ struct kunit;
 /* Maximum size of parameter description string. */
 #define KUNIT_PARAM_DESC_SIZE 128
 
+/* Maximum size of a status comment. */
+#define KUNIT_STATUS_COMMENT_SIZE 256
+
 /*
  * TAP specifies subtest stream indentation of 4 spaces, 8 spaces for a
  * sub-subtest.  See the "Subtests" section in
@@ -106,6 +109,18 @@ struct kunit;
 #define KUNIT_SUBSUBTEST_INDENT                "        "
 
 /**
+ * enum kunit_status - Type of result for a test or test suite
+ * @KUNIT_SUCCESS: Denotes the test suite has not failed nor been skipped
+ * @KUNIT_FAILURE: Denotes the test has failed.
+ * @KUNIT_SKIPPED: Denotes the test has been skipped.
+ */
+enum kunit_status {
+       KUNIT_SUCCESS,
+       KUNIT_FAILURE,
+       KUNIT_SKIPPED,
+};
+
+/**
  * struct kunit_case - represents an individual test case.
  *
  * @run_case: the function representing the actual test case.
@@ -148,13 +163,20 @@ struct kunit_case {
        const void* (*generate_params)(const void *prev, char *desc);
 
        /* private: internal use only. */
-       bool success;
+       enum kunit_status status;
        char *log;
 };
 
-static inline char *kunit_status_to_string(bool status)
+static inline char *kunit_status_to_ok_not_ok(enum kunit_status status)
 {
-       return status ? "ok" : "not ok";
+       switch (status) {
+       case KUNIT_SKIPPED:
+       case KUNIT_SUCCESS:
+               return "ok";
+       case KUNIT_FAILURE:
+               return "not ok";
+       }
+       return "invalid";
 }
 
 /**
@@ -212,6 +234,7 @@ struct kunit_suite {
        struct kunit_case *test_cases;
 
        /* private: internal use only */
+       char status_comment[KUNIT_STATUS_COMMENT_SIZE];
        struct dentry *debugfs;
        char *log;
 };
@@ -245,19 +268,21 @@ struct kunit {
         * be read after the test case finishes once all threads associated
         * with the test case have terminated.
         */
-       bool success; /* Read only after test_case finishes! */
        spinlock_t lock; /* Guards all mutable test state. */
+       enum kunit_status status; /* Read only after test_case finishes! */
        /*
         * Because resources is a list that may be updated multiple times (with
         * new resources) from any thread associated with a test case, we must
         * protect it with some type of lock.
         */
        struct list_head resources; /* Protected by lock. */
+
+       char status_comment[KUNIT_STATUS_COMMENT_SIZE];
 };
 
 static inline void kunit_set_failure(struct kunit *test)
 {
-       WRITE_ONCE(test->success, false);
+       WRITE_ONCE(test->status, KUNIT_FAILURE);
 }
 
 void kunit_init_test(struct kunit *test, const char *name, char *log);
@@ -348,7 +373,7 @@ static inline int kunit_run_all_tests(void)
 #define kunit_suite_for_each_test_case(suite, test_case)               \
        for (test_case = suite->test_cases; test_case->run_case; test_case++)
 
-bool kunit_suite_has_succeeded(struct kunit_suite *suite);
+enum kunit_status kunit_suite_has_succeeded(struct kunit_suite *suite);
 
 /*
  * Like kunit_alloc_resource() below, but returns the struct kunit_resource
@@ -578,16 +603,30 @@ static inline int kunit_destroy_named_resource(struct kunit *test,
 void kunit_remove_resource(struct kunit *test, struct kunit_resource *res);
 
 /**
- * kunit_kmalloc() - Like kmalloc() except the allocation is *test managed*.
+ * kunit_kmalloc_array() - Like kmalloc_array() except the allocation is *test managed*.
  * @test: The test context object.
+ * @n: number of elements.
  * @size: The size in bytes of the desired memory.
  * @gfp: flags passed to underlying kmalloc().
  *
- * Just like `kmalloc(...)`, except the allocation is managed by the test case
+ * Just like `kmalloc_array(...)`, except the allocation is managed by the test case
  * and is automatically cleaned up after the test case concludes. See &struct
  * kunit_resource for more information.
  */
-void *kunit_kmalloc(struct kunit *test, size_t size, gfp_t gfp);
+void *kunit_kmalloc_array(struct kunit *test, size_t n, size_t size, gfp_t flags);
+
+/**
+ * kunit_kmalloc() - Like kmalloc() except the allocation is *test managed*.
+ * @test: The test context object.
+ * @size: The size in bytes of the desired memory.
+ * @gfp: flags passed to underlying kmalloc().
+ *
+ * See kmalloc() and kunit_kmalloc_array() for more information.
+ */
+static inline void *kunit_kmalloc(struct kunit *test, size_t size, gfp_t gfp)
+{
+       return kunit_kmalloc_array(test, 1, size, gfp);
+}
 
 /**
  * kunit_kfree() - Like kfree except for allocations managed by KUnit.
@@ -602,16 +641,66 @@ void kunit_kfree(struct kunit *test, const void *ptr);
  * @size: The size in bytes of the desired memory.
  * @gfp: flags passed to underlying kmalloc().
  *
- * See kzalloc() and kunit_kmalloc() for more information.
+ * See kzalloc() and kunit_kmalloc_array() for more information.
  */
 static inline void *kunit_kzalloc(struct kunit *test, size_t size, gfp_t gfp)
 {
        return kunit_kmalloc(test, size, gfp | __GFP_ZERO);
 }
 
+/**
+ * kunit_kcalloc() - Just like kunit_kmalloc_array(), but zeroes the allocation.
+ * @test: The test context object.
+ * @n: number of elements.
+ * @size: The size in bytes of the desired memory.
+ * @gfp: flags passed to underlying kmalloc().
+ *
+ * See kcalloc() and kunit_kmalloc_array() for more information.
+ */
+static inline void *kunit_kcalloc(struct kunit *test, size_t n, size_t size, gfp_t flags)
+{
+       return kunit_kmalloc_array(test, n, size, flags | __GFP_ZERO);
+}
+
 void kunit_cleanup(struct kunit *test);
 
-void kunit_log_append(char *log, const char *fmt, ...);
+void __printf(2, 3) kunit_log_append(char *log, const char *fmt, ...);
+
+/**
+ * kunit_mark_skipped() - Marks @test_or_suite as skipped
+ *
+ * @test_or_suite: The test context object.
+ * @fmt:  A printk() style format string.
+ *
+ * Marks the test as skipped. @fmt is given output as the test status
+ * comment, typically the reason the test was skipped.
+ *
+ * Test execution continues after kunit_mark_skipped() is called.
+ */
+#define kunit_mark_skipped(test_or_suite, fmt, ...)                    \
+       do {                                                            \
+               WRITE_ONCE((test_or_suite)->status, KUNIT_SKIPPED);     \
+               scnprintf((test_or_suite)->status_comment,              \
+                         KUNIT_STATUS_COMMENT_SIZE,                    \
+                         fmt, ##__VA_ARGS__);                          \
+       } while (0)
+
+/**
+ * kunit_skip() - Marks @test_or_suite as skipped
+ *
+ * @test_or_suite: The test context object.
+ * @fmt:  A printk() style format string.
+ *
+ * Skips the test. @fmt is given output as the test status
+ * comment, typically the reason the test was skipped.
+ *
+ * Test execution is halted after kunit_skip() is called.
+ */
+#define kunit_skip(test_or_suite, fmt, ...)                            \
+       do {                                                            \
+               kunit_mark_skipped((test_or_suite), fmt, ##__VA_ARGS__);\
+               kunit_try_catch_throw(&((test_or_suite)->try_catch));   \
+       } while (0)
 
 /*
  * printk and log to per-test or per-suite log buffer.  Logging only done
@@ -776,7 +865,6 @@ void kunit_do_assertion(struct kunit *test,
 do {                                                                          \
        typeof(left) __left = (left);                                          \
        typeof(right) __right = (right);                                       \
-       ((void)__typecheck(__left, __right));                                  \
                                                                               \
        KUNIT_ASSERTION(test,                                                  \
                        __left op __right,                                     \
@@ -1130,8 +1218,8 @@ do {                                                                             \
                                   fmt,                                        \
                                   ...)                                        \
 do {                                                                          \
-       typeof(left) __left = (left);                                          \
-       typeof(right) __right = (right);                                       \
+       const char *__left = (left);                                           \
+       const char *__right = (right);                                 \
                                                                               \
        KUNIT_ASSERTION(test,                                                  \
                        strcmp(__left, __right) op 0,                          \