Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:51

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RtemsMessageReqDelete
0007  */
0008 
0009 /*
0010  * Copyright (C) 2021 embedded brains GmbH & Co. KG
0011  *
0012  * Redistribution and use in source and binary forms, with or without
0013  * modification, are permitted provided that the following conditions
0014  * are met:
0015  * 1. Redistributions of source code must retain the above copyright
0016  *    notice, this list of conditions and the following disclaimer.
0017  * 2. Redistributions in binary form must reproduce the above copyright
0018  *    notice, this list of conditions and the following disclaimer in the
0019  *    documentation and/or other materials provided with the distribution.
0020  *
0021  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0022  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0023  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0024  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0025  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0026  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0027  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0028  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0029  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0030  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0031  * POSSIBILITY OF SUCH DAMAGE.
0032  */
0033 
0034 /*
0035  * This file is part of the RTEMS quality process and was automatically
0036  * generated.  If you find something that needs to be fixed or
0037  * worded better please post a report or patch to an RTEMS mailing list
0038  * or raise a bug report:
0039  *
0040  * https://www.rtems.org/bugs.html
0041  *
0042  * For information on updating and regenerating please refer to the How-To
0043  * section in the Software Requirements Engineering chapter of the
0044  * RTEMS Software Engineering manual.  The manual is provided as a part of
0045  * a release.  For development sources please refer to the online
0046  * documentation at:
0047  *
0048  * https://docs.rtems.org
0049  */
0050 
0051 #ifdef HAVE_CONFIG_H
0052 #include "config.h"
0053 #endif
0054 
0055 #include <rtems.h>
0056 #include <string.h>
0057 
0058 #include "tx-support.h"
0059 
0060 #include <rtems/test.h>
0061 
0062 /**
0063  * @defgroup RtemsMessageReqDelete spec:/rtems/message/req/delete
0064  *
0065  * @ingroup TestsuitesValidationNoClock0
0066  *
0067  * @{
0068  */
0069 
0070 typedef enum {
0071   RtemsMessageReqDelete_Pre_Id_NoObj,
0072   RtemsMessageReqDelete_Pre_Id_MsgQueue,
0073   RtemsMessageReqDelete_Pre_Id_NA
0074 } RtemsMessageReqDelete_Pre_Id;
0075 
0076 typedef enum {
0077   RtemsMessageReqDelete_Post_Status_Ok,
0078   RtemsMessageReqDelete_Post_Status_InvId,
0079   RtemsMessageReqDelete_Post_Status_NA
0080 } RtemsMessageReqDelete_Post_Status;
0081 
0082 typedef enum {
0083   RtemsMessageReqDelete_Post_Name_Valid,
0084   RtemsMessageReqDelete_Post_Name_Invalid,
0085   RtemsMessageReqDelete_Post_Name_NA
0086 } RtemsMessageReqDelete_Post_Name;
0087 
0088 typedef enum {
0089   RtemsMessageReqDelete_Post_Flush_Yes,
0090   RtemsMessageReqDelete_Post_Flush_No,
0091   RtemsMessageReqDelete_Post_Flush_NA
0092 } RtemsMessageReqDelete_Post_Flush;
0093 
0094 typedef struct {
0095   uint8_t Skip : 1;
0096   uint8_t Pre_Id_NA : 1;
0097   uint8_t Post_Status : 2;
0098   uint8_t Post_Name : 2;
0099   uint8_t Post_Flush : 2;
0100 } RtemsMessageReqDelete_Entry;
0101 
0102 /**
0103  * @brief Test context for spec:/rtems/message/req/delete test case.
0104  */
0105 typedef struct {
0106   rtems_id worker_id;
0107 
0108   rtems_id message_queue_id;
0109 
0110   uint32_t wait_done;
0111 
0112   uint32_t wait_expected;
0113 
0114   rtems_id id;
0115 
0116   rtems_status_code status;
0117 
0118   struct {
0119     /**
0120      * @brief This member defines the pre-condition states for the next action.
0121      */
0122     size_t pcs[ 1 ];
0123 
0124     /**
0125      * @brief If this member is true, then the test action loop is executed.
0126      */
0127     bool in_action_loop;
0128 
0129     /**
0130      * @brief This member contains the next transition map index.
0131      */
0132     size_t index;
0133 
0134     /**
0135      * @brief This member contains the current transition map entry.
0136      */
0137     RtemsMessageReqDelete_Entry entry;
0138 
0139     /**
0140      * @brief If this member is true, then the current transition variant
0141      *   should be skipped.
0142      */
0143     bool skip;
0144   } Map;
0145 } RtemsMessageReqDelete_Context;
0146 
0147 static RtemsMessageReqDelete_Context
0148   RtemsMessageReqDelete_Instance;
0149 
0150 static const char * const RtemsMessageReqDelete_PreDesc_Id[] = {
0151   "NoObj",
0152   "MsgQueue",
0153   "NA"
0154 };
0155 
0156 static const char * const * const RtemsMessageReqDelete_PreDesc[] = {
0157   RtemsMessageReqDelete_PreDesc_Id,
0158   NULL
0159 };
0160 
0161 #define NAME rtems_build_name( 'T', 'E', 'S', 'T' )
0162 
0163 #define MAX_PENDING_MESSAGES 1
0164 
0165 #define MAX_MESSAGE_SIZE 1
0166 
0167 typedef RtemsMessageReqDelete_Context Context;
0168 
0169 static RTEMS_MESSAGE_QUEUE_BUFFER( MAX_MESSAGE_SIZE )
0170   buffers[ MAX_PENDING_MESSAGES ];
0171 
0172 static void Worker( rtems_task_argument arg )
0173 {
0174   Context *ctx;
0175 
0176   ctx = (Context *) arg;
0177 
0178   while ( true ) {
0179     rtems_status_code          sc;
0180     rtems_message_queue_config config;
0181     char                       buffer[ MAX_MESSAGE_SIZE ];
0182     size_t                     size;
0183     rtems_task_priority        prio;
0184 
0185     memset( &config, 0, sizeof( config ) );
0186     config.name = NAME;
0187     config.maximum_pending_messages = MAX_PENDING_MESSAGES;
0188     config.maximum_message_size = MAX_MESSAGE_SIZE;
0189     config.storage_size = sizeof( buffers );
0190     config.storage_area = buffers;
0191     config.attributes = RTEMS_DEFAULT_ATTRIBUTES;
0192 
0193     T_eq_u32( ctx->message_queue_id, 0 );
0194 
0195     sc = rtems_message_queue_construct( &config, &ctx->message_queue_id );
0196     T_rsc_success( sc );
0197 
0198     size = SIZE_MAX;
0199     sc = rtems_message_queue_receive(
0200       ctx->message_queue_id,
0201       buffer,
0202       &size,
0203       RTEMS_WAIT,
0204       RTEMS_NO_TIMEOUT
0205     );
0206     T_rsc( sc, RTEMS_OBJECT_WAS_DELETED );
0207     T_eq_sz( size, SIZE_MAX );
0208 
0209     ++ctx->wait_done;
0210 
0211     prio = SetSelfPriority( PRIO_LOW );
0212     T_eq_u32( prio, PRIO_HIGH );
0213   }
0214 }
0215 
0216 static void RtemsMessageReqDelete_Pre_Id_Prepare(
0217   RtemsMessageReqDelete_Context *ctx,
0218   RtemsMessageReqDelete_Pre_Id   state
0219 )
0220 {
0221   switch ( state ) {
0222     case RtemsMessageReqDelete_Pre_Id_NoObj: {
0223       /*
0224        * While the ``id`` parameter is not associated with a message queue.
0225        */
0226       ctx->id = 0;
0227       break;
0228     }
0229 
0230     case RtemsMessageReqDelete_Pre_Id_MsgQueue: {
0231       /*
0232        * While the ``id`` parameter is associated with a message queue.
0233        */
0234       ctx->id = ctx->message_queue_id;
0235       break;
0236     }
0237 
0238     case RtemsMessageReqDelete_Pre_Id_NA:
0239       break;
0240   }
0241 }
0242 
0243 static void RtemsMessageReqDelete_Post_Status_Check(
0244   RtemsMessageReqDelete_Context    *ctx,
0245   RtemsMessageReqDelete_Post_Status state
0246 )
0247 {
0248   switch ( state ) {
0249     case RtemsMessageReqDelete_Post_Status_Ok: {
0250       /*
0251        * The return status of rtems_message_queue_delete() shall be
0252        * RTEMS_SUCCESSFUL.
0253        */
0254       ctx->message_queue_id = 0;
0255       T_rsc_success( ctx->status );
0256       break;
0257     }
0258 
0259     case RtemsMessageReqDelete_Post_Status_InvId: {
0260       /*
0261        * The return status of rtems_message_queue_delete() shall be
0262        * RTEMS_INVALID_ID.
0263        */
0264       T_rsc( ctx->status, RTEMS_INVALID_ID );
0265       break;
0266     }
0267 
0268     case RtemsMessageReqDelete_Post_Status_NA:
0269       break;
0270   }
0271 }
0272 
0273 static void RtemsMessageReqDelete_Post_Name_Check(
0274   RtemsMessageReqDelete_Context  *ctx,
0275   RtemsMessageReqDelete_Post_Name state
0276 )
0277 {
0278   rtems_status_code sc;
0279   rtems_id          id;
0280 
0281   switch ( state ) {
0282     case RtemsMessageReqDelete_Post_Name_Valid: {
0283       /*
0284        * The unique object name shall identify a message queue.
0285        */
0286       id = 0;
0287       sc = rtems_message_queue_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
0288       T_rsc_success( sc );
0289       T_eq_u32( id, ctx->message_queue_id );
0290       break;
0291     }
0292 
0293     case RtemsMessageReqDelete_Post_Name_Invalid: {
0294       /*
0295        * The unique object name shall not identify a message queue.
0296        */
0297       sc = rtems_message_queue_ident( NAME, RTEMS_SEARCH_LOCAL_NODE, &id );
0298       T_rsc( sc, RTEMS_INVALID_NAME );
0299       break;
0300     }
0301 
0302     case RtemsMessageReqDelete_Post_Name_NA:
0303       break;
0304   }
0305 }
0306 
0307 static void RtemsMessageReqDelete_Post_Flush_Check(
0308   RtemsMessageReqDelete_Context   *ctx,
0309   RtemsMessageReqDelete_Post_Flush state
0310 )
0311 {
0312   switch ( state ) {
0313     case RtemsMessageReqDelete_Post_Flush_Yes: {
0314       /*
0315        * Tasks waiting at the message queue shall be unblocked.
0316        */
0317       ++ctx->wait_expected;
0318       T_eq_u32( ctx->wait_done, ctx->wait_expected );
0319       break;
0320     }
0321 
0322     case RtemsMessageReqDelete_Post_Flush_No: {
0323       /*
0324        * Tasks waiting at the message queue shall remain blocked.
0325        */
0326       T_eq_u32( ctx->wait_done, ctx->wait_expected );
0327       break;
0328     }
0329 
0330     case RtemsMessageReqDelete_Post_Flush_NA:
0331       break;
0332   }
0333 }
0334 
0335 static void RtemsMessageReqDelete_Setup( RtemsMessageReqDelete_Context *ctx )
0336 {
0337   memset( ctx, 0, sizeof( *ctx ) );
0338   SetSelfPriority( PRIO_NORMAL );
0339   ctx->worker_id = CreateTask( "WORK", PRIO_LOW );
0340   StartTask( ctx->worker_id, Worker, ctx );
0341 }
0342 
0343 static void RtemsMessageReqDelete_Setup_Wrap( void *arg )
0344 {
0345   RtemsMessageReqDelete_Context *ctx;
0346 
0347   ctx = arg;
0348   ctx->Map.in_action_loop = false;
0349   RtemsMessageReqDelete_Setup( ctx );
0350 }
0351 
0352 static void RtemsMessageReqDelete_Teardown(
0353   RtemsMessageReqDelete_Context *ctx
0354 )
0355 {
0356   DeleteTask( ctx->worker_id );
0357   RestoreRunnerPriority();
0358 }
0359 
0360 static void RtemsMessageReqDelete_Teardown_Wrap( void *arg )
0361 {
0362   RtemsMessageReqDelete_Context *ctx;
0363 
0364   ctx = arg;
0365   ctx->Map.in_action_loop = false;
0366   RtemsMessageReqDelete_Teardown( ctx );
0367 }
0368 
0369 static void RtemsMessageReqDelete_Prepare( RtemsMessageReqDelete_Context *ctx )
0370 {
0371   rtems_task_priority prio;
0372 
0373   prio = SetPriority( ctx->worker_id, PRIO_HIGH );
0374   T_true( prio == PRIO_LOW || prio == PRIO_HIGH );
0375 }
0376 
0377 static void RtemsMessageReqDelete_Action( RtemsMessageReqDelete_Context *ctx )
0378 {
0379   ctx->status = rtems_message_queue_delete( ctx->id );
0380 }
0381 
0382 static void RtemsMessageReqDelete_Cleanup( RtemsMessageReqDelete_Context *ctx )
0383 {
0384   if ( ctx->message_queue_id != 0 ) {
0385     rtems_status_code sc;
0386 
0387     sc = rtems_message_queue_delete( ctx->message_queue_id );
0388     T_rsc_success( sc );
0389 
0390     ++ctx->wait_expected;
0391     T_eq_u32( ctx->wait_done, ctx->wait_expected );
0392 
0393     ctx->message_queue_id = 0;
0394   }
0395 }
0396 
0397 static const RtemsMessageReqDelete_Entry
0398 RtemsMessageReqDelete_Entries[] = {
0399   { 0, 0, RtemsMessageReqDelete_Post_Status_InvId,
0400     RtemsMessageReqDelete_Post_Name_Valid, RtemsMessageReqDelete_Post_Flush_No },
0401   { 0, 0, RtemsMessageReqDelete_Post_Status_Ok,
0402     RtemsMessageReqDelete_Post_Name_Invalid,
0403     RtemsMessageReqDelete_Post_Flush_Yes }
0404 };
0405 
0406 static const uint8_t
0407 RtemsMessageReqDelete_Map[] = {
0408   0, 1
0409 };
0410 
0411 static size_t RtemsMessageReqDelete_Scope( void *arg, char *buf, size_t n )
0412 {
0413   RtemsMessageReqDelete_Context *ctx;
0414 
0415   ctx = arg;
0416 
0417   if ( ctx->Map.in_action_loop ) {
0418     return T_get_scope( RtemsMessageReqDelete_PreDesc, buf, n, ctx->Map.pcs );
0419   }
0420 
0421   return 0;
0422 }
0423 
0424 static T_fixture RtemsMessageReqDelete_Fixture = {
0425   .setup = RtemsMessageReqDelete_Setup_Wrap,
0426   .stop = NULL,
0427   .teardown = RtemsMessageReqDelete_Teardown_Wrap,
0428   .scope = RtemsMessageReqDelete_Scope,
0429   .initial_context = &RtemsMessageReqDelete_Instance
0430 };
0431 
0432 static inline RtemsMessageReqDelete_Entry RtemsMessageReqDelete_PopEntry(
0433   RtemsMessageReqDelete_Context *ctx
0434 )
0435 {
0436   size_t index;
0437 
0438   index = ctx->Map.index;
0439   ctx->Map.index = index + 1;
0440   return RtemsMessageReqDelete_Entries[
0441     RtemsMessageReqDelete_Map[ index ]
0442   ];
0443 }
0444 
0445 static void RtemsMessageReqDelete_TestVariant(
0446   RtemsMessageReqDelete_Context *ctx
0447 )
0448 {
0449   RtemsMessageReqDelete_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0450   RtemsMessageReqDelete_Action( ctx );
0451   RtemsMessageReqDelete_Post_Status_Check( ctx, ctx->Map.entry.Post_Status );
0452   RtemsMessageReqDelete_Post_Name_Check( ctx, ctx->Map.entry.Post_Name );
0453   RtemsMessageReqDelete_Post_Flush_Check( ctx, ctx->Map.entry.Post_Flush );
0454 }
0455 
0456 /**
0457  * @fn void T_case_body_RtemsMessageReqDelete( void )
0458  */
0459 T_TEST_CASE_FIXTURE( RtemsMessageReqDelete, &RtemsMessageReqDelete_Fixture )
0460 {
0461   RtemsMessageReqDelete_Context *ctx;
0462 
0463   ctx = T_fixture_context();
0464   ctx->Map.in_action_loop = true;
0465   ctx->Map.index = 0;
0466 
0467   for (
0468     ctx->Map.pcs[ 0 ] = RtemsMessageReqDelete_Pre_Id_NoObj;
0469     ctx->Map.pcs[ 0 ] < RtemsMessageReqDelete_Pre_Id_NA;
0470     ++ctx->Map.pcs[ 0 ]
0471   ) {
0472     ctx->Map.entry = RtemsMessageReqDelete_PopEntry( ctx );
0473     RtemsMessageReqDelete_Prepare( ctx );
0474     RtemsMessageReqDelete_TestVariant( ctx );
0475     RtemsMessageReqDelete_Cleanup( ctx );
0476   }
0477 }
0478 
0479 /** @} */