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 RtemsPartReqReturnBuffer
0007  */
0008 
0009 /*
0010  * Copyright (C) 2020 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 
0057 #include <rtems/test.h>
0058 
0059 /**
0060  * @defgroup RtemsPartReqReturnBuffer spec:/rtems/part/req/return-buffer
0061  *
0062  * @ingroup TestsuitesValidationNoClock0
0063  *
0064  * @{
0065  */
0066 
0067 typedef enum {
0068   RtemsPartReqReturnBuffer_Pre_Id_NoObj,
0069   RtemsPartReqReturnBuffer_Pre_Id_Part,
0070   RtemsPartReqReturnBuffer_Pre_Id_NA
0071 } RtemsPartReqReturnBuffer_Pre_Id;
0072 
0073 typedef enum {
0074   RtemsPartReqReturnBuffer_Pre_Buf_Valid,
0075   RtemsPartReqReturnBuffer_Pre_Buf_BadAlign,
0076   RtemsPartReqReturnBuffer_Pre_Buf_BelowArea,
0077   RtemsPartReqReturnBuffer_Pre_Buf_AboveArea,
0078   RtemsPartReqReturnBuffer_Pre_Buf_NA
0079 } RtemsPartReqReturnBuffer_Pre_Buf;
0080 
0081 typedef enum {
0082   RtemsPartReqReturnBuffer_Post_Status_Ok,
0083   RtemsPartReqReturnBuffer_Post_Status_InvId,
0084   RtemsPartReqReturnBuffer_Post_Status_InvAddr,
0085   RtemsPartReqReturnBuffer_Post_Status_NA
0086 } RtemsPartReqReturnBuffer_Post_Status;
0087 
0088 typedef enum {
0089   RtemsPartReqReturnBuffer_Post_Buf_Free,
0090   RtemsPartReqReturnBuffer_Post_Buf_InUse,
0091   RtemsPartReqReturnBuffer_Post_Buf_NA
0092 } RtemsPartReqReturnBuffer_Post_Buf;
0093 
0094 typedef struct {
0095   uint8_t Skip : 1;
0096   uint8_t Pre_Id_NA : 1;
0097   uint8_t Pre_Buf_NA : 1;
0098   uint8_t Post_Status : 2;
0099   uint8_t Post_Buf : 2;
0100 } RtemsPartReqReturnBuffer_Entry;
0101 
0102 /**
0103  * @brief Test context for spec:/rtems/part/req/return-buffer test case.
0104  */
0105 typedef struct {
0106   rtems_status_code status;
0107 
0108   rtems_id id;
0109 
0110   rtems_id id_value;
0111 
0112   void *buffer;
0113 
0114   void *buffer_in_use;
0115 
0116   struct {
0117     /**
0118      * @brief This member defines the pre-condition states for the next action.
0119      */
0120     size_t pcs[ 2 ];
0121 
0122     /**
0123      * @brief If this member is true, then the test action loop is executed.
0124      */
0125     bool in_action_loop;
0126 
0127     /**
0128      * @brief This member contains the next transition map index.
0129      */
0130     size_t index;
0131 
0132     /**
0133      * @brief This member contains the current transition map entry.
0134      */
0135     RtemsPartReqReturnBuffer_Entry entry;
0136 
0137     /**
0138      * @brief If this member is true, then the current transition variant
0139      *   should be skipped.
0140      */
0141     bool skip;
0142   } Map;
0143 } RtemsPartReqReturnBuffer_Context;
0144 
0145 static RtemsPartReqReturnBuffer_Context
0146   RtemsPartReqReturnBuffer_Instance;
0147 
0148 static const char * const RtemsPartReqReturnBuffer_PreDesc_Id[] = {
0149   "NoObj",
0150   "Part",
0151   "NA"
0152 };
0153 
0154 static const char * const RtemsPartReqReturnBuffer_PreDesc_Buf[] = {
0155   "Valid",
0156   "BadAlign",
0157   "BelowArea",
0158   "AboveArea",
0159   "NA"
0160 };
0161 
0162 static const char * const * const RtemsPartReqReturnBuffer_PreDesc[] = {
0163   RtemsPartReqReturnBuffer_PreDesc_Id,
0164   RtemsPartReqReturnBuffer_PreDesc_Buf,
0165   NULL
0166 };
0167 
0168 #define BUFFER_COUNT 1
0169 
0170 #define BUFFER_SIZE ( 2 * sizeof( void * ) )
0171 
0172 static RTEMS_ALIGNED( RTEMS_PARTITION_ALIGNMENT ) uint8_t
0173   buffers[ BUFFER_COUNT ][ BUFFER_SIZE ];
0174 
0175 static void RtemsPartReqReturnBuffer_Pre_Id_Prepare(
0176   RtemsPartReqReturnBuffer_Context *ctx,
0177   RtemsPartReqReturnBuffer_Pre_Id   state
0178 )
0179 {
0180   switch ( state ) {
0181     case RtemsPartReqReturnBuffer_Pre_Id_NoObj: {
0182       /*
0183        * While the ``id`` parameter is invalid.
0184        */
0185       ctx->id = 0xffffffff;
0186       break;
0187     }
0188 
0189     case RtemsPartReqReturnBuffer_Pre_Id_Part: {
0190       /*
0191        * While the ``id`` parameter is associated with a partition.
0192        */
0193       ctx->id = ctx->id_value;
0194       break;
0195     }
0196 
0197     case RtemsPartReqReturnBuffer_Pre_Id_NA:
0198       break;
0199   }
0200 }
0201 
0202 static void RtemsPartReqReturnBuffer_Pre_Buf_Prepare(
0203   RtemsPartReqReturnBuffer_Context *ctx,
0204   RtemsPartReqReturnBuffer_Pre_Buf  state
0205 )
0206 {
0207   switch ( state ) {
0208     case RtemsPartReqReturnBuffer_Pre_Buf_Valid: {
0209       /*
0210        * While the ``buffer`` parameter references a buffer previously returned
0211        * by rtems_partition_get_buffer().
0212        */
0213       ctx->buffer = ctx->buffer_in_use;
0214       break;
0215     }
0216 
0217     case RtemsPartReqReturnBuffer_Pre_Buf_BadAlign: {
0218       /*
0219        * While the ``buffer`` parameter is an address inside the buffer area of
0220        * the partition, while the address is not on a valid buffer boundary.
0221        */
0222       ctx->buffer = (void *) ( (uintptr_t) ctx->buffer_in_use + 1 );
0223       break;
0224     }
0225 
0226     case RtemsPartReqReturnBuffer_Pre_Buf_BelowArea: {
0227       /*
0228        * While the ``buffer`` parameter is an address below the buffer area of
0229        * the partition.
0230        */
0231       ctx->buffer = (void *) ( (uintptr_t) buffers - 1 );
0232       break;
0233     }
0234 
0235     case RtemsPartReqReturnBuffer_Pre_Buf_AboveArea: {
0236       /*
0237        * While the ``buffer`` parameter is an address above the buffer area of
0238        * the partition.
0239        */
0240       ctx->buffer = (void *) ( (uintptr_t) buffers + sizeof( buffers ) );
0241       break;
0242     }
0243 
0244     case RtemsPartReqReturnBuffer_Pre_Buf_NA:
0245       break;
0246   }
0247 }
0248 
0249 static void RtemsPartReqReturnBuffer_Post_Status_Check(
0250   RtemsPartReqReturnBuffer_Context    *ctx,
0251   RtemsPartReqReturnBuffer_Post_Status state
0252 )
0253 {
0254   switch ( state ) {
0255     case RtemsPartReqReturnBuffer_Post_Status_Ok: {
0256       /*
0257        * The return status of rtems_partition_return_buffer() shall be
0258        * RTEMS_SUCCESSFUL.
0259        */
0260       T_rsc_success( ctx->status );
0261       break;
0262     }
0263 
0264     case RtemsPartReqReturnBuffer_Post_Status_InvId: {
0265       /*
0266        * The return status of rtems_partition_return_buffer() shall be
0267        * RTEMS_INVALID_ID.
0268        */
0269       T_rsc( ctx->status, RTEMS_INVALID_ID );
0270       break;
0271     }
0272 
0273     case RtemsPartReqReturnBuffer_Post_Status_InvAddr: {
0274       /*
0275        * The return status of rtems_partition_return_buffer() shall be
0276        * RTEMS_INVALID_ADDRESS.
0277        */
0278       T_rsc( ctx->status, RTEMS_INVALID_ADDRESS );
0279       break;
0280     }
0281 
0282     case RtemsPartReqReturnBuffer_Post_Status_NA:
0283       break;
0284   }
0285 }
0286 
0287 static void RtemsPartReqReturnBuffer_Post_Buf_Check(
0288   RtemsPartReqReturnBuffer_Context *ctx,
0289   RtemsPartReqReturnBuffer_Post_Buf state
0290 )
0291 {
0292   rtems_status_code sc;
0293   void             *no_buffer;
0294 
0295   switch ( state ) {
0296     case RtemsPartReqReturnBuffer_Post_Buf_Free: {
0297       /*
0298        * The buffer obtained from the partition shall be made available for
0299        * re-use by the rtems_partition_return_buffer() call.
0300        */
0301       sc = rtems_partition_get_buffer( ctx->id_value, &ctx->buffer_in_use );
0302       T_rsc_success( sc );
0303       T_eq_ptr( ctx->buffer_in_use, buffers );
0304       break;
0305     }
0306 
0307     case RtemsPartReqReturnBuffer_Post_Buf_InUse: {
0308       /*
0309        * The buffer obtained from the partition shall be still in use after the
0310        * rtems_partition_return_buffer() call.
0311        */
0312       sc = rtems_partition_get_buffer( ctx->id_value, &no_buffer );
0313       T_rsc( sc, RTEMS_UNSATISFIED );
0314       break;
0315     }
0316 
0317     case RtemsPartReqReturnBuffer_Post_Buf_NA:
0318       break;
0319   }
0320 }
0321 
0322 static void RtemsPartReqReturnBuffer_Setup(
0323   RtemsPartReqReturnBuffer_Context *ctx
0324 )
0325 {
0326   rtems_status_code sc;
0327 
0328   ctx->buffer_in_use = NULL;
0329   ctx->id_value = 0;
0330 
0331   sc = rtems_partition_create(
0332     rtems_build_name( 'N', 'A', 'M', 'E' ),
0333     buffers,
0334     sizeof( buffers ),
0335     sizeof( buffers[ 0 ] ),
0336     RTEMS_DEFAULT_ATTRIBUTES,
0337     &ctx->id_value
0338   );
0339   T_assert_rsc_success( sc );
0340 
0341   sc = rtems_partition_get_buffer( ctx->id_value, &ctx->buffer_in_use );
0342   T_assert_rsc_success( sc );
0343   T_assert_eq_ptr( ctx->buffer_in_use, buffers );
0344 }
0345 
0346 static void RtemsPartReqReturnBuffer_Setup_Wrap( void *arg )
0347 {
0348   RtemsPartReqReturnBuffer_Context *ctx;
0349 
0350   ctx = arg;
0351   ctx->Map.in_action_loop = false;
0352   RtemsPartReqReturnBuffer_Setup( ctx );
0353 }
0354 
0355 static void RtemsPartReqReturnBuffer_Teardown(
0356   RtemsPartReqReturnBuffer_Context *ctx
0357 )
0358 {
0359   rtems_status_code sc;
0360 
0361   if ( ctx->buffer_in_use != NULL ) {
0362     sc = rtems_partition_return_buffer( ctx->id_value, ctx->buffer_in_use );
0363     T_rsc_success( sc );
0364   }
0365 
0366   if ( ctx->id_value != 0 ) {
0367     sc = rtems_partition_delete( ctx->id_value );
0368     T_rsc_success( sc );
0369   }
0370 }
0371 
0372 static void RtemsPartReqReturnBuffer_Teardown_Wrap( void *arg )
0373 {
0374   RtemsPartReqReturnBuffer_Context *ctx;
0375 
0376   ctx = arg;
0377   ctx->Map.in_action_loop = false;
0378   RtemsPartReqReturnBuffer_Teardown( ctx );
0379 }
0380 
0381 static void RtemsPartReqReturnBuffer_Action(
0382   RtemsPartReqReturnBuffer_Context *ctx
0383 )
0384 {
0385   ctx->status = rtems_partition_return_buffer( ctx->id, ctx->buffer );
0386 }
0387 
0388 static const RtemsPartReqReturnBuffer_Entry
0389 RtemsPartReqReturnBuffer_Entries[] = {
0390   { 0, 0, 0, RtemsPartReqReturnBuffer_Post_Status_InvId,
0391     RtemsPartReqReturnBuffer_Post_Buf_InUse },
0392   { 0, 0, 0, RtemsPartReqReturnBuffer_Post_Status_InvAddr,
0393     RtemsPartReqReturnBuffer_Post_Buf_InUse },
0394   { 0, 0, 0, RtemsPartReqReturnBuffer_Post_Status_Ok,
0395     RtemsPartReqReturnBuffer_Post_Buf_Free }
0396 };
0397 
0398 static const uint8_t
0399 RtemsPartReqReturnBuffer_Map[] = {
0400   0, 0, 0, 0, 2, 1, 1, 1
0401 };
0402 
0403 static size_t RtemsPartReqReturnBuffer_Scope( void *arg, char *buf, size_t n )
0404 {
0405   RtemsPartReqReturnBuffer_Context *ctx;
0406 
0407   ctx = arg;
0408 
0409   if ( ctx->Map.in_action_loop ) {
0410     return T_get_scope(
0411       RtemsPartReqReturnBuffer_PreDesc,
0412       buf,
0413       n,
0414       ctx->Map.pcs
0415     );
0416   }
0417 
0418   return 0;
0419 }
0420 
0421 static T_fixture RtemsPartReqReturnBuffer_Fixture = {
0422   .setup = RtemsPartReqReturnBuffer_Setup_Wrap,
0423   .stop = NULL,
0424   .teardown = RtemsPartReqReturnBuffer_Teardown_Wrap,
0425   .scope = RtemsPartReqReturnBuffer_Scope,
0426   .initial_context = &RtemsPartReqReturnBuffer_Instance
0427 };
0428 
0429 static inline RtemsPartReqReturnBuffer_Entry RtemsPartReqReturnBuffer_PopEntry(
0430   RtemsPartReqReturnBuffer_Context *ctx
0431 )
0432 {
0433   size_t index;
0434 
0435   index = ctx->Map.index;
0436   ctx->Map.index = index + 1;
0437   return RtemsPartReqReturnBuffer_Entries[
0438     RtemsPartReqReturnBuffer_Map[ index ]
0439   ];
0440 }
0441 
0442 static void RtemsPartReqReturnBuffer_TestVariant(
0443   RtemsPartReqReturnBuffer_Context *ctx
0444 )
0445 {
0446   RtemsPartReqReturnBuffer_Pre_Id_Prepare( ctx, ctx->Map.pcs[ 0 ] );
0447   RtemsPartReqReturnBuffer_Pre_Buf_Prepare( ctx, ctx->Map.pcs[ 1 ] );
0448   RtemsPartReqReturnBuffer_Action( ctx );
0449   RtemsPartReqReturnBuffer_Post_Status_Check(
0450     ctx,
0451     ctx->Map.entry.Post_Status
0452   );
0453   RtemsPartReqReturnBuffer_Post_Buf_Check( ctx, ctx->Map.entry.Post_Buf );
0454 }
0455 
0456 /**
0457  * @fn void T_case_body_RtemsPartReqReturnBuffer( void )
0458  */
0459 T_TEST_CASE_FIXTURE(
0460   RtemsPartReqReturnBuffer,
0461   &RtemsPartReqReturnBuffer_Fixture
0462 )
0463 {
0464   RtemsPartReqReturnBuffer_Context *ctx;
0465 
0466   ctx = T_fixture_context();
0467   ctx->Map.in_action_loop = true;
0468   ctx->Map.index = 0;
0469 
0470   for (
0471     ctx->Map.pcs[ 0 ] = RtemsPartReqReturnBuffer_Pre_Id_NoObj;
0472     ctx->Map.pcs[ 0 ] < RtemsPartReqReturnBuffer_Pre_Id_NA;
0473     ++ctx->Map.pcs[ 0 ]
0474   ) {
0475     for (
0476       ctx->Map.pcs[ 1 ] = RtemsPartReqReturnBuffer_Pre_Buf_Valid;
0477       ctx->Map.pcs[ 1 ] < RtemsPartReqReturnBuffer_Pre_Buf_NA;
0478       ++ctx->Map.pcs[ 1 ]
0479     ) {
0480       ctx->Map.entry = RtemsPartReqReturnBuffer_PopEntry( ctx );
0481       RtemsPartReqReturnBuffer_TestVariant( ctx );
0482     }
0483   }
0484 }
0485 
0486 /** @} */