ChibiOS/RT Architecture - Reference Manual - Guides |
00001 /* 00002 ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. 00003 00004 This file is part of ChibiOS/RT. 00005 00006 ChibiOS/RT is free software; you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation; either version 3 of the License, or 00009 (at your option) any later version. 00010 00011 ChibiOS/RT is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 GNU General Public License for more details. 00015 00016 You should have received a copy of the GNU General Public License 00017 along with this program. If not, see <http://www.gnu.org/licenses/>. 00018 00019 --- 00020 00021 A special exception to the GPL can be applied should you wish to distribute 00022 a combined work that includes ChibiOS/RT, without being obliged to provide 00023 the source code for any proprietary components. See the file exception.txt 00024 for full details of how and when the exception can be applied. 00025 */ 00026 00027 #include "ch.h" 00028 #include "test.h" 00029 00030 /** 00031 * @page test_queues I/O Queues test 00032 * 00033 * File: @ref testqueues.c 00034 * 00035 * <h2>Description</h2> 00036 * This module implements the test sequence for the @ref io_queues subsystem. 00037 * The tests are performed by inserting and removing data from queues and by 00038 * checking both the queues status and the correct sequence of the extracted 00039 * data. 00040 * 00041 * <h2>Objective</h2> 00042 * Objective of the test module is to cover 100% of the @ref io_queues code.<br> 00043 * Note that the @ref io_queues subsystem depends on the @ref semaphores 00044 * subsystem that has to met its testing objectives as well. 00045 * 00046 * <h2>Preconditions</h2> 00047 * The module requires the following kernel options: 00048 * - @p CH_USE_QUEUES (and dependent options) 00049 * . 00050 * In case some of the required options are not enabled then some or all tests 00051 * may be skipped. 00052 * 00053 * <h2>Test Cases</h2> 00054 * - @subpage test_queues_001 00055 * - @subpage test_queues_002 00056 * . 00057 * @file testqueues.c 00058 * @brief I/O Queues test source file 00059 * @file testqueues.h 00060 * @brief I/O Queues test header file 00061 */ 00062 00063 #if CH_USE_QUEUES 00064 00065 #define TEST_QUEUES_SIZE 4 00066 00067 static void notify(void) {} 00068 00069 /* 00070 * Note, the static initializers are not really required because the 00071 * variables are explicitly initialized in each test case. It is done in order 00072 * to test the macros. 00073 */ 00074 static INPUTQUEUE_DECL(iq, test.wa.T0, TEST_QUEUES_SIZE, notify); 00075 static OUTPUTQUEUE_DECL(oq, test.wa.T1, TEST_QUEUES_SIZE, notify); 00076 00077 /** 00078 * @page test_queues_001 Input Queues functionality and APIs 00079 * 00080 * <h2>Description</h2> 00081 * This test case tests sysnchronos and asynchronous operations on an 00082 * @p InputQueue object including timeouts. The queue state must remain 00083 * consistent through the whole test. 00084 */ 00085 00086 static char *queues1_gettest(void) { 00087 00088 return "Queues, input queues"; 00089 } 00090 00091 static void queues1_setup(void) { 00092 00093 chIQInit(&iq, wa[0], TEST_QUEUES_SIZE, notify); 00094 } 00095 00096 static void queues1_execute(void) { 00097 unsigned i; 00098 size_t n; 00099 00100 /* Initial empty state */ 00101 test_assert(1, chIQIsEmpty(&iq), "not empty"); 00102 00103 /* Queue filling */ 00104 for (i = 0; i < TEST_QUEUES_SIZE; i++) 00105 chIQPutI(&iq, 'A' + i); 00106 test_assert(2, chIQIsFull(&iq), "still has space"); 00107 test_assert(3, chIQPutI(&iq, 0) == Q_FULL, "failed to report Q_FULL"); 00108 00109 /* Queue emptying */ 00110 for (i = 0; i < TEST_QUEUES_SIZE; i++) 00111 test_emit_token(chIQGet(&iq)); 00112 test_assert(4, chIQIsEmpty(&iq), "still full"); 00113 test_assert_sequence(5, "ABCD"); 00114 00115 /* Queue filling again */ 00116 for (i = 0; i < TEST_QUEUES_SIZE; i++) 00117 chIQPutI(&iq, 'A' + i); 00118 00119 /* Reading the whole thing */ 00120 n = chIQReadTimeout(&iq, wa[1], TEST_QUEUES_SIZE * 2, TIME_IMMEDIATE); 00121 test_assert(6, n == TEST_QUEUES_SIZE, "wrong returned size"); 00122 test_assert(7, chIQIsEmpty(&iq), "still full"); 00123 00124 /* Queue filling again */ 00125 for (i = 0; i < TEST_QUEUES_SIZE; i++) 00126 chIQPutI(&iq, 'A' + i); 00127 00128 /* Partial reads */ 00129 n = chIQReadTimeout(&iq, wa[1], TEST_QUEUES_SIZE / 2, TIME_IMMEDIATE); 00130 test_assert(8, n == TEST_QUEUES_SIZE / 2, "wrong returned size"); 00131 n = chIQReadTimeout(&iq, wa[1], TEST_QUEUES_SIZE / 2, TIME_IMMEDIATE); 00132 test_assert(9, n == TEST_QUEUES_SIZE / 2, "wrong returned size"); 00133 test_assert(10, chIQIsEmpty(&iq), "still full"); 00134 00135 /* Testing reset */ 00136 chIQPutI(&iq, 0); 00137 chIQResetI(&iq); 00138 test_assert(11, chIQIsEmpty(&iq), "still full"); 00139 00140 /* Timeout */ 00141 test_assert(12, chIQGetTimeout(&iq, 10) == Q_TIMEOUT, "wrong timeout return"); 00142 } 00143 00144 const struct testcase testqueues1 = { 00145 queues1_gettest, 00146 queues1_setup, 00147 NULL, 00148 queues1_execute 00149 }; 00150 00151 /** 00152 * @page test_queues_002 Output Queues functionality and APIs 00153 * 00154 * <h2>Description</h2> 00155 * This test case tests sysnchronos and asynchronous operations on an 00156 * @p OutputQueue object including timeouts. The queue state must remain 00157 * consistent through the whole test. 00158 */ 00159 static char *queues2_gettest(void) { 00160 00161 return "Queues, output queues"; 00162 } 00163 00164 static void queues2_setup(void) { 00165 00166 chOQInit(&oq, wa[0], TEST_QUEUES_SIZE, notify); 00167 } 00168 00169 static void queues2_execute(void) { 00170 unsigned i; 00171 size_t n; 00172 00173 /* Initial empty state */ 00174 test_assert(1, chOQIsEmpty(&oq), "not empty"); 00175 00176 /* Queue filling */ 00177 for (i = 0; i < TEST_QUEUES_SIZE; i++) 00178 chOQPut(&oq, 'A' + i); 00179 test_assert(2, chOQIsFull(&oq), "still has space"); 00180 00181 /* Queue emptying */ 00182 for (i = 0; i < TEST_QUEUES_SIZE; i++) 00183 test_emit_token(chOQGetI(&oq)); 00184 test_assert(3, chOQIsEmpty(&oq), "still full"); 00185 test_assert_sequence(4, "ABCD"); 00186 test_assert(5, chOQGetI(&oq) == Q_EMPTY, "failed to report Q_EMPTY"); 00187 00188 /* Writing the whole thing */ 00189 n = chOQWriteTimeout(&oq, wa[1], TEST_QUEUES_SIZE * 2, TIME_IMMEDIATE); 00190 test_assert(6, n == TEST_QUEUES_SIZE, "wrong returned size"); 00191 test_assert(7, chOQIsFull(&oq), "not full"); 00192 00193 /* Testing reset */ 00194 chOQResetI(&oq); 00195 test_assert(8, chOQIsEmpty(&oq), "still full"); 00196 00197 /* Partial writes */ 00198 n = chOQWriteTimeout(&oq, wa[1], TEST_QUEUES_SIZE / 2, TIME_IMMEDIATE); 00199 test_assert(9, n == TEST_QUEUES_SIZE / 2, "wrong returned size"); 00200 n = chOQWriteTimeout(&oq, wa[1], TEST_QUEUES_SIZE / 2, TIME_IMMEDIATE); 00201 test_assert(10, n == TEST_QUEUES_SIZE / 2, "wrong returned size"); 00202 test_assert(11, chOQIsFull(&oq), "not full"); 00203 00204 /* Timeout */ 00205 test_assert(12, chOQPutTimeout(&oq, 0, 10) == Q_TIMEOUT, "wrong timeout return"); 00206 } 00207 00208 const struct testcase testqueues2 = { 00209 queues2_gettest, 00210 queues2_setup, 00211 NULL, 00212 queues2_execute 00213 }; 00214 #endif /* CH_USE_QUEUES */ 00215 00216 /** 00217 * @brief Test sequence for queues. 00218 */ 00219 const struct testcase * const patternqueues[] = { 00220 #if CH_USE_QUEUES 00221 &testqueues1, 00222 &testqueues2, 00223 #endif 00224 NULL 00225 };