LCOV - code coverage report
Current view: top level - src - m_test.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 103 103 100.0 %
Date: 2017-03-13 16:41:56 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /*********************************** LICENSE **********************************\
       2             : *                            Copyright 2017 Morphux                            *
       3             : *                                                                              *
       4             : *        Licensed under the Apache License, Version 2.0 (the "License");       *
       5             : *        you may not use this file except in compliance with the License.      *
       6             : *                  You may obtain a copy of the License at                     *
       7             : *                                                                              *
       8             : *                 http://www.apache.org/licenses/LICENSE-2.0                   *
       9             : *                                                                              *
      10             : *      Unless required by applicable law or agreed to in writing, software     *
      11             : *       distributed under the License is distributed on an "AS IS" BASIS,      *
      12             : *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  *
      13             : *        See the License for the specific language governing permissions and   *
      14             : *                       limitations under the License.                         *
      15             : \******************************************************************************/
      16             : 
      17             : #include <m_test.h>
      18             : 
      19             : static mlist_t          *tests = NULL;
      20             : 
      21             : /*!
      22             :  * \brief Print a title
      23             :  * \param s Title name
      24             :  */
      25          24 : void    title(char *s) {
      26          24 :         u8_t                    len = TITLE_LEN;
      27             :         int                             i;
      28             : 
      29          24 :         len -= strlen(s);
      30          24 :         for (i = 0; i < len / 2; i++, write(1, "=", 1))
      31             :                 ;
      32          24 :         write(1, " ", 1);
      33          24 :         write(1, s, strlen(s));
      34          24 :         write(1, " ", 1);
      35          24 :         for (; i < len; i++, write(1, "=", 1));
      36          24 :         write(1, "\n", 1);
      37          24 : }
      38             : 
      39          45 : void    print_result(const char *title, u32_t success, u32_t failed) {
      40          45 :         u32_t   total = success + failed;
      41          45 :         u32_t   percent = success * 100 / total;
      42             : 
      43          45 :         m_info("%s:", title);
      44          45 :         fflush(stdout);
      45        2697 :         for (u32_t i = LINE_SIZE - strlen(title) + 1 - 14; i > 0; i--)
      46        2652 :                 write(1, " ", 1);
      47          45 :         fprintf(stdout, "%02d/%02d [", success, total);
      48          45 :         fflush(stdout);
      49          45 :         if (percent == 100) {
      50          30 :                 fprintf(stdout, "\033[1;32m");
      51          15 :         } else if (percent >= 90) {
      52           3 :                 fprintf(stdout, "\033[1;33m");
      53             :         } else {
      54          12 :                 fprintf(stdout, "\033[1;31m");
      55             :         }
      56          45 :         fflush(stdout);
      57          45 :         fprintf(stdout, "%03d%%\033[0;m]\n", percent);
      58          45 :         fflush(stdout);
      59          45 : }
      60             : 
      61             : /*!
      62             :  * \brief Register a test
      63             :  * \param group Group name
      64             :  * \param fn_test Test function
      65             :  * \param name Test name
      66             :  *
      67             :  * \note Do not call this function directly, use test_reg macro instead.
      68             :  */
      69         189 : void            register_test(char *group, char *(*fn_test)(void), char *name) {
      70             :         mtest_t         *ptr;
      71             : 
      72             :         /* Allocate test */
      73         189 :         ptr = malloc(sizeof(mtest_t));
      74         189 :         assert(ptr);
      75         189 :         ptr->group = malloc(strlen(group) + 1);
      76         189 :         ptr->name = malloc(strlen(name) + 1);
      77         189 :         assert(ptr->group && ptr->name);
      78             : 
      79             :         /* Copy name and group */
      80         189 :         memcpy(ptr->group, group, strlen(group));
      81         189 :         memcpy(ptr->name, name, strlen(name));
      82         189 :         ptr->name[strlen(name)] = 0;
      83         189 :         ptr->group[strlen(group)] = 0;
      84         189 :         assert(ptr->group && ptr->name);
      85         189 :         ptr->fn_test = fn_test;
      86             : 
      87             :         /* Add to the list of tests */
      88         189 :         list_add(tests, ptr, sizeof(mtest_t));
      89         189 :         free(ptr);
      90         189 : }
      91             : 
      92             : /*!
      93             :  * \brief Test an entire group of tests
      94             :  * \param group Group name
      95             :  */
      96          18 : mtest_results_t test_group(char *group) {
      97             :         mlist_t                 *tmp;
      98             :         mtest_t                 *ptr;
      99             :         mtest_results_t res;
     100             :         u32_t                   tab;
     101             :         char                    *s_tmp;
     102             : 
     103          18 :         res.total = res.success = res.failed = 0;
     104          18 :         res.group_name = NULL;
     105          18 :         title(group);
     106             : 
     107          18 :         if (tests == NULL)
     108             :         {
     109           3 :                 m_warning("Could not find any registered tests in %s group.\n", group);
     110           3 :                 return res;
     111             :         }
     112             : 
     113             :         /* Iterate over each test */
     114         762 :         list_for_each(tests, tmp, ptr) {
     115         747 :                 if (strcmp(ptr->group, group) == 0) {
     116         189 :                         res.total++;
     117         189 :                         m_info("Testing %s ...", ptr->name);
     118             : 
     119        9627 :                         for (tab = strlen(ptr->name); tab < TITLE_LEN - 18;
     120        9249 :                                 tab++, printf(" "))
     121             :                                 ;
     122             : 
     123         189 :                         if ((s_tmp = ptr->fn_test()) != TEST_SUCCESS) {
     124           3 :                                 printf("[ \033[1;31mKO\033[0m ]\n");
     125           3 :                                 m_warning("\033[0;37m%s\033[0m\n", s_tmp);
     126           3 :                                 free(s_tmp);
     127           3 :                                 res.failed++;
     128             :                         } else {
     129         186 :                                 printf("[ \033[1;32mOK\033[0m ]\n");
     130         186 :                                 res.success++;
     131             :                         }
     132             :                 }
     133             :         }
     134             : 
     135          15 :         print_result("Group Results", res.success, res.failed);
     136          15 :         return res;
     137             : }
     138             : 
     139             : /*!
     140             :  * \brief Test all registered tests
     141             :  * \return Numbers of tests failed
     142             :  */
     143           9 : u32_t           test_all(void) {
     144           9 :         mlist_t                 *tmp, *groups = NULL, *tests_results = NULL;
     145             :         mtest_t                 *ptr;
     146             :         mtest_results_t res, *ptr2;
     147           9 :         u32_t                   total = 0, success = 0, failed = 0;
     148             : 
     149           9 :         if (tests == NULL)
     150             :         {
     151           3 :                 m_warning("No tests registered, skipping.\n");
     152           3 :                 return 0;
     153             :         }
     154         195 :         list_for_each(tests, tmp, ptr) {
     155         189 :                 if (list_get(groups, ptr->group, strlen(ptr->group)) == NULL) {
     156          15 :                         res = test_group(ptr->group);
     157             : 
     158          15 :                         res.group_name = malloc(sizeof(char) * strlen(ptr->group) + 1);
     159          15 :                         strcpy(res.group_name, ptr->group);
     160          15 :                         total += res.total;
     161          15 :                         success += res.success;
     162          15 :                         failed += res.failed;
     163          15 :                         list_add(groups, ptr->group, strlen(ptr->group));
     164          15 :                         list_add(tests_results, &res, sizeof(res));
     165             :                 }
     166             :         }
     167             : 
     168           6 :         title("Results");
     169          21 :         list_for_each(tests_results, tmp, ptr2) {
     170          15 :                 print_result(ptr2->group_name, ptr2->success, ptr2->failed);
     171             :         }
     172           6 :         print_result("Total", success, failed);
     173             : 
     174           6 :         list_free(groups, NULL);
     175           6 :         list_free(tests_results, &single_result_free);
     176             : 
     177           6 :         return failed;
     178             : }
     179             : 
     180             : /*!
     181             :  * \brief Free all the test
     182             :  */
     183           9 : void    test_free(void) {
     184           9 :         list_free(tests, &single_test_free);
     185           9 :         tests = NULL;
     186           9 : }
     187             : 
     188             : /*!
     189             :  * \brief Free a single test
     190             :  * \note Used in test_free, as a list_free callback
     191             :  */
     192         189 : int             single_test_free(void *ptr) {
     193         189 :         mtest_t         *tmp = ptr;
     194             : 
     195         189 :         if (ptr) {
     196         189 :                 free(tmp->group);
     197         189 :                 free(tmp->name);
     198             :         }
     199         189 :         return 1;
     200             : }
     201             : 
     202             : /*!
     203             :  * \brief Free a mtest_results_t
     204             :  * \note Used in test_all, as a list_free callback
     205             :  */
     206          15 : int             single_result_free(void *ptr) {
     207          15 :         mtest_results_t         *tmp = ptr;
     208          15 :         if (ptr) {
     209          15 :                 free(tmp->group_name);
     210             :         }
     211          15 :         return 1;
     212             : }

Generated by: LCOV version 1.11