source: rtems/testsuites/psxtests/psxmsgq01/init.c @ f8d39b8d

4.104.114.9
Last change on this file since f8d39b8d was f8d39b8d, checked in by Jennifer Averett <Jennifer.Averett@…>, on Feb 4, 2008 at 7:39:43 PM

2008-02-04 Jennifer Averett <jennifer.averett@…>

  • Makefile.am, configure.ac, psxmsgq01/Makefile.am, psxmsgq01/init.c: Added tests for failure path coverages. Consolidated methods used in multiple places into support routines.
  • psxkey01/Makefile.am, psxkey01/init.c, psxkey01/psxkey01.scn, psxkey01/system.h, psxkey01/task.c, psxmsgq02/Makefile.am, psxmsgq02/init.c, psxmsgq02/psxmsgq02.scn, psxmsgq02/system.h: New files.
  • Property mode set to 100644
File size: 34.5 KB
Line 
1/*
2 *  COPYRIGHT (c) 1989-2008.
3 *  On-Line Applications Research Corporation (OAR).
4 *
5 *  The license and distribution terms for this file may be
6 *  found in the file LICENSE in this distribution or at
7 *  http://www.rtems.com/license/LICENSE.
8 *
9 *  $Id$
10 */
11
12#define CONFIGURE_INIT
13#include "system.h"
14#include <sched.h>
15#include <fcntl.h>
16#include <time.h>
17#include <tmacros.h>
18#include <signal.h>   /* signal facilities */
19#include "test_support.h"
20
21typedef struct {
22  char         msg[ 50 ];
23  int          size;
24  unsigned int priority;
25}Test_Message_t;
26Test_Message_t Predefined_Msgs[MAXMSG+1];
27Test_Message_t Predefined_Msgs[MAXMSG+1] = {
28  { "12345678",   9, MQ_PRIO_MAX-1 },  /* Max Length Message med  */
29  { "",           1, 1             },  /* NULL  Message      low  */
30  { "Last",       5, MQ_PRIO_MAX   },  /* Queue Full Message hi   */
31  { "No Message", 0, MQ_PRIO_MAX-1 },  /* 0 length Message   med  */
32  { "1",          2, 0             },  /* Cause Overflow Behavior */
33};
34int Priority_Order[MAXMSG+1] = { 2, 0, 3, 1, MAXMSG };
35
36
37typedef struct {
38  mqd_t              mq;
39  Test_Queue_Types   index;
40  char              *name;
41  int                oflag;
42  int                maxmsg;
43  int                msgsize;
44  int                count;
45} Test_queue_type;
46
47Test_queue_type Test_q[ NUMBER_OF_TEST_QUEUES + 1 ] =
48{
49  { 0, 0, "Qread",    ( O_CREAT | O_RDONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
50  { 0, 1, "Qwrite",   ( O_CREAT | O_WRONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
51  { 0, 2, "Qnoblock", ( O_CREAT | O_RDWR   | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
52  { 0, 3, "Qblock",   ( O_CREAT | O_RDWR )               , MAXMSG, MSGSIZE, 0 },
53  { 0, 4, "Qdefault", ( O_CREAT | O_RDWR )               , 10,     16,      0 },
54  { 0, 5, "mq6",      ( O_CREAT | O_WRONLY | O_NONBLOCK ), MAXMSG, MSGSIZE, 0 },
55  { 0, 6, "Qblock",   (           O_RDWR )               , MAXMSG, MSGSIZE, 0 },
56};
57
58#define RW_NAME             Test_q[ RW_QUEUE ].name
59#define DEFAULT_NAME        Test_q[ DEFAULT_RW ].name
60#define RD_NAME             Test_q[ RD_QUEUE ].name
61#define WR_NAME             Test_q[ WR_QUEUE ].name
62#define BLOCKING_NAME       Test_q[ BLOCKING ].name
63#define CLOSED_NAME         Test_q[ CLOSED ].name
64
65#define RW_ATTR         Test_q[ RW_QUEUE ].oflag
66#define DEFAULT_ATTR    Test_q[ DEFAULT_RW ].oflag
67#define RD_ATTR         Test_q[ RD_QUEUE ].oflag
68#define WR_ATTR         Test_q[ WR_QUEUE ].oflag
69#define BLOCK_ATTR      Test_q[ BLOCKING ].oflag
70#define CLOSED_ATTR     Test_q[ CLOSED ].oflag
71
72/*
73 * Outputs a header at each test section.
74 */
75void Start_Test(
76  char *description
77)
78{
79  printf( "_______________%s\n", description );
80}
81
82
83void Validate_attributes(
84    mqd_t  mq,
85    int    oflag,
86    int    msg_count
87)
88{
89  int             status;
90  struct mq_attr  attr;
91
92  status = mq_getattr( mq, &attr );
93  fatal_posix_service_status( status, 0, "mq_getattr valid return status");
94
95  if ( mq != Test_q[ DEFAULT_RW ].mq ){
96    fatal_int_service_status((int)attr.mq_maxmsg, MAXMSG, "maxmsg attribute" );
97    fatal_int_service_status((int)attr.mq_msgsize,MSGSIZE,"msgsize attribute");
98  }
99
100  fatal_int_service_status((int)attr.mq_curmsgs, msg_count, "count attribute" );
101  fatal_int_service_status((int)attr.mq_flags, oflag, "flag attribute" );
102}
103
104#define Get_Queue_Name( i )  Test_q[i].name
105char *Build_Queue_Name( int i ) {
106
107  static char Queue_Name[PATH_MAX + 2]; 
108
109  sprintf(Queue_Name,"mq%d", i+1 );
110  return Queue_Name;
111}
112
113void open_test_queues()
114{
115  struct mq_attr   attr;
116  int              status;
117  Test_queue_type *tq;
118  int              que;
119
120  attr.mq_maxmsg  = MAXMSG;
121  attr.mq_msgsize = MSGSIZE;
122
123  puts( "Init: Open Test Queues" );
124
125  for( que = 0; que < NUMBER_OF_TEST_QUEUES+1; que++ ) {
126
127    tq = &Test_q[ que ];
128    if ( que == DEFAULT_RW)
129      Test_q[que].mq = mq_open( tq->name, tq->oflag, 0x777, NULL );
130    else
131      Test_q[que].mq = mq_open( tq->name, tq->oflag, 0x777, &attr );
132
133    assert( Test_q[que].mq != (-1) );
134  }
135
136  status = mq_close( Test_q[NUMBER_OF_TEST_QUEUES].mq );
137  fatal_posix_service_status( status, 0, "mq_close duplicate message queue");
138  status = mq_close( Test_q[CLOSED].mq );
139  fatal_posix_service_status( status, 0, "mq_close message queue");
140  status = mq_unlink( CLOSED_NAME );
141  fatal_posix_service_status( status, 0, "mq_unlink message queue");
142}
143
144/*
145 * Opens CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES then leaves size queues
146 * opened but closes the rest.
147 */
148
149void validate_mq_open_error_codes()
150{
151  int             i;
152  mqd_t           n_mq2;
153  struct mq_attr  attr;
154  int             status;
155  mqd_t           open_mq[CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES + 1];
156
157  attr.mq_maxmsg  = MAXMSG;
158  attr.mq_msgsize = MSGSIZE;
159
160  Start_Test( "mq_open errors" );
161
162  /*
163   * XXX EINVAL - inappropriate name was given for the message queue
164   */
165
166  /*
167   * EINVAL - Create with negative maxmsg.
168   */
169
170  attr.mq_maxmsg = -1;
171  puts( "Init: mq_open - Create with maxmsg (-1) (EINVAL)" );
172  n_mq2 = mq_open( "mq2", O_CREAT | O_RDONLY, 0x777, &attr);
173  fatal_posix_service_status(
174    (int) n_mq2, (int ) (-1), "mq_open error return status" );
175  fatal_posix_service_status( errno, EINVAL,  "mq_open errno EINVAL");
176  attr.mq_maxmsg  = MAXMSG;
177
178  /*
179   * EINVAL - Create withnegative msgsize.
180   */
181
182  attr.mq_msgsize = -1;
183  puts( "Init: mq_open - Create with msgsize (-1) (EINVAL)" );
184  n_mq2 = mq_open( "mq2", O_CREAT | O_RDONLY, 0x777, &attr);
185  fatal_posix_service_status(
186    (int) n_mq2, (int ) (-1), "mq_open error return status" );
187  fatal_posix_service_status( errno, EINVAL,  "mq_open errno EINVAL");
188  attr.mq_msgsize = MSGSIZE;
189
190  /*
191   * ENOENT - Open a non-created file.
192   */
193
194  puts( "Init: mq_open - Open new mq without create flag (ENOENT)" );
195  n_mq2 = mq_open( "mq3", O_EXCL | O_RDONLY, 0x777, NULL);
196  fatal_posix_service_status(
197    (int) n_mq2, (int ) (-1), "mq_open error return status" );
198  fatal_posix_service_status( errno, ENOENT,  "mq_open errno ENOENT");
199
200  /*
201   * XXX EINTR  - call was interrupted by a signal
202   */
203
204  /*
205   * ENAMETOOLONG - Give a name greater than PATH_MAX.
206   */
207
208  puts( "Init: mq_open - Open with too long of a name (ENAMETOOLONG)" );
209  n_mq2 = mq_open( Get_Too_Long_Name(), O_CREAT | O_RDONLY, 0x777, NULL );
210  fatal_posix_service_status(
211    (int) n_mq2, (int ) (-1), "mq_open error return status" );
212  fatal_posix_service_status( errno, ENAMETOOLONG, "mq_open errno ENAMETOOLONG");
213
214  /*
215   * XXX - ENAMETOOLONG - Give a name greater than NAME_MAX
216   *       Per implementation not possible.
217   */
218
219  /*
220   * EEXIST - Create an existing queue.
221   */
222
223  puts( "Init: mq_open - Create an Existing mq (EEXIST)" );
224  open_mq[0] = mq_open(
225    Build_Queue_Name(0), O_CREAT | O_RDWR | O_NONBLOCK, 0x777, NULL );
226  assert( open_mq[0] != (-1) );
227
228  n_mq2 = mq_open(
229    Build_Queue_Name(0), O_CREAT | O_EXCL | O_RDONLY, 0x777, NULL);
230  fatal_posix_service_status(
231    (int) n_mq2, (int ) (-1), "mq_open error return status" );
232  fatal_posix_service_status( errno, EEXIST,  "mq_open errno EEXIST");
233
234  status = mq_unlink( Build_Queue_Name(0) );
235  fatal_posix_service_status( status, 0, "mq_unlink message queue");
236
237  status = mq_close( open_mq[0]);
238  fatal_posix_service_status( status, 0, "mq_close message queue");
239
240  /*
241   * Open maximum number of message queues
242   */
243
244  puts( "Init: mq_open - SUCCESSFUL" );
245  for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) {
246    open_mq[i] = mq_open(
247      Build_Queue_Name(i), O_CREAT | O_RDWR | O_NONBLOCK, 0x777, NULL );
248    assert( open_mq[i] != (-1) );
249    assert( open_mq[i] );
250    /*XXX - Isn't there a more general check */
251/* JRS     printf( "mq_open 0x%x %s\n", open_mq[i], Build_Queue_Name(i) ); */
252  }
253
254  /*
255   * XXX EACCES - permission to create is denied.
256   */
257
258  /*
259   * XXX EACCES - queue exists permissions specified by o_flag are denied.
260   */
261
262  /*
263   * XXX EMFILE  - Too many message queues in use by the process
264   */
265
266  /*
267   * ENFILE -  Too many message queues open in the system
268   */
269
270  puts( "Init: mq_open - system is out of resources (ENFILE)" );
271  n_mq2 = mq_open( Build_Queue_Name(i), O_CREAT | O_RDONLY, 0x777, NULL );
272  fatal_posix_service_status(
273    (int) n_mq2, (int ) (-1), "mq_open error return status" );
274  fatal_posix_service_status( errno, ENFILE,  "mq_open errno ENFILE");
275
276  /*
277   * Unlink and Close all queues.
278   */
279
280  puts( "Init: mq_close and mq_unlink (mq3...mqn) - SUCCESSFUL" );
281  for (i = 0; i < CONFIGURE_MAXIMUM_POSIX_MESSAGE_QUEUES; i++) {
282
283    status = mq_close( open_mq[i]);
284    fatal_posix_service_status( status, 0, "mq_close message queue");
285
286    status = mq_unlink( Build_Queue_Name(i) );
287    if ( status == -1 )
288      perror( "mq_unlink" );
289    fatal_posix_service_status( status, 0, "mq_unlink message queue");
290    /* JRS printf( "mq_close/mq_unlink 0x%x %s\n", open_mq[i], Build_Queue_Name(i) ); */
291  }
292}
293
294void validate_mq_unlink_error_codes()
295{
296  int             status;
297
298  Start_Test( "mq_unlink errors" );
299
300  /*
301   * XXX - EACCES Permission Denied
302   */
303
304  /*
305   * ENAMETOOLONG - Give a name greater than PATH_MAX.
306   */
307
308  puts( "Init: mq_unlink - mq_unlink with too long of a name (ENAMETOOLONG)" );
309  status = mq_unlink( Get_Too_Long_Name() );
310  fatal_posix_service_status( status, -1, "mq_unlink error return status");
311  fatal_posix_service_status( errno, ENAMETOOLONG, "mq_unlink errno ENAMETOOLONG");
312
313  /*
314   * XXX - ENAMETOOLONG - Give a name greater than NAME_MAX
315   *       Per implementation not possible.
316   */
317
318  /*
319   *  ENOENT - Unlink an unopened queue
320   */
321
322  puts( "Init: mq_unlink - A Queue not opened  (ENOENT)" );
323  status = mq_unlink( CLOSED_NAME );
324  fatal_posix_service_status( status, -1, "mq_unlink error return status");
325  fatal_posix_service_status( errno, ENOENT, "mq_unlink errno ENOENT");
326
327  /*
328   * XXX - The following were not listed in the POSIX document as
329   *       possible errors.  Under other commands the EINVAL is
330   *       given for these conditions.
331   */
332
333  /*
334   *  EINVAL - Unlink a queue with no name
335   */
336
337  puts( "Init: mq_unlink (NULL) - EINVAL" );
338  status = mq_unlink( NULL );
339  fatal_posix_service_status( status, -1, "mq_unlink error return status");
340  fatal_posix_service_status( errno, EINVAL, "mq_unlink errno value");
341
342  /*
343   *  EINVAL - Unlink a queue with a null name
344   */
345
346  puts( "Init: mq_unlink (\"\") - EINVAL" );
347  status = mq_unlink( "" );
348  fatal_posix_service_status( status, -1, "mq_unlink error return status");
349  fatal_posix_service_status( errno, EINVAL, "mq_unlink errno value");
350}
351
352void validate_mq_close_error_codes()
353{
354  int             status;
355
356  Start_Test( "mq_close errors" );
357
358  /*
359   * EBADF - Close a queue that is not open.
360   */
361
362  puts( "Init: mq_close - unopened queue (EBADF)" );
363  status = mq_close( Test_q[CLOSED].mq );
364  fatal_posix_service_status( status, -1, "mq_close error return status");
365  fatal_posix_service_status( errno, EBADF, "mq_close errno EBADF");
366}
367
368
369void validate_mq_getattr_error_codes()
370{
371  struct mq_attr  attr;
372  int             status;
373
374  Start_Test( "mq_getattr errors" );
375
376  /*
377   * EBADF - Get the attributes from a closed queue.
378   */
379
380  puts( "Init: mq_getattr - unopened queue (EBADF)" );
381  status = mq_getattr( Test_q[CLOSED].mq, &attr );
382  fatal_posix_service_status( status, -1, "mq_close error return status");
383  fatal_posix_service_status( errno, EBADF, "mq_close errno EBADF");
384
385  /*
386   * XXX - The following are not listed in the POSIX manual but
387   *       may occur.
388   */
389
390  /*
391   * EINVAL - NULL attributes
392   */
393
394  puts( "Init: mq_getattr - NULL attributes (EINVAL)" );
395  status = mq_getattr( Test_q[RW_QUEUE].mq, NULL );
396  fatal_posix_service_status( status, -1, "mq_close error return status");
397  fatal_posix_service_status( errno, EINVAL, "mq_close errno EINVAL");
398
399}
400
401
402void Send_msg_to_que(
403  int que,
404  int msg
405)
406{
407  Test_Message_t *ptr = &Predefined_Msgs[msg];
408  int             status;
409
410  status = mq_send( Test_q[que].mq, ptr->msg, ptr->size , ptr->priority );
411  fatal_posix_service_status( status, 0, "mq_send valid return status");
412  Test_q[que].count++;
413}
414
415void Show_send_msg_to_que(
416  char *task_name,
417  int   que,
418  int   msg
419)
420{
421  Test_Message_t *ptr = &Predefined_Msgs[msg];
422  printf( "%s mq_send -  to %s msg: %s priority %d\n",
423    task_name, Test_q[que].name, ptr->msg, ptr->priority);
424  Send_msg_to_que( que, msg );
425}
426
427void verify_queues_full(
428  char *task_name
429)
430{
431  int          que;
432
433  /*
434   * Validate that the queues are full.
435   */
436
437  printf( "%s Verify Queues are full\n", task_name );
438  for( que = RW_QUEUE; que < CLOSED; que++ )
439    Validate_attributes( Test_q[que].mq, Test_q[que].oflag, Test_q[que].count );
440
441}
442void verify_queues_empty(
443  char *task_name
444)
445{
446  int             que;
447
448  printf( "%s Verify Queues are empty\n", task_name );
449  for( que = RW_QUEUE; que < CLOSED; que++ )
450    Validate_attributes( Test_q[que].mq, Test_q[que].oflag, 0 );
451}
452
453int fill_message_queues(
454  char *task_name
455)
456{
457  int             msg;
458  int             que;
459
460
461  verify_queues_empty( task_name );
462
463  /*
464   * Fill Queue with predefined messages.
465   */
466
467  printf( "%s Fill Queues with messages\n", task_name );
468  for(msg=0; msg<MAXMSG; msg++){
469    for( que = RW_QUEUE; que < CLOSED; que++ ) {
470      Send_msg_to_que( que, msg );
471    }
472  }
473
474  verify_queues_full( "Init:" );
475  return msg;
476}
477
478
479void Read_msg_from_que(
480  int que,
481  int msg
482)
483{
484  unsigned int    priority;
485  Test_Message_t *ptr;
486  int             status;
487  char            message[100];
488  char            err_msg[100];
489
490  ptr = &Predefined_Msgs[msg];
491  status = mq_receive(Test_q[ que ].mq, message, 100, &priority );
492  Test_q[que].count--;
493
494  sprintf( err_msg, "%s msg %s size failure", Test_q[ que ].name, ptr->msg );
495  fatal_int_service_status( status, ptr->size, err_msg );
496
497  assert( !strcmp( message, ptr->msg ) );
498  strcpy( message, "No Message" );
499
500  sprintf( err_msg,"%s msg %s size failure", Test_q[ que ].name, ptr->msg );
501  fatal_int_service_status(priority, ptr->priority, err_msg );
502}
503
504int empty_message_queues(
505  char *task_name
506)
507{
508  int que;
509  int i;
510
511  printf( "%s Empty all Queues\n", task_name );
512  for( que = RW_QUEUE; que < CLOSED; que++ ) {
513    for(i=0; Test_q[que].count != 0; i++ )
514      Read_msg_from_que( que,  Priority_Order[i] );
515
516    Validate_attributes( Test_q[ que].mq, Test_q[ que ].oflag, 0 );
517  }
518  return 0;
519}
520
521/*
522 * Returns the number of messages queued after the test on the
523 * first queue.
524 */
525
526int validate_mq_send_error_codes( )
527{
528  int             status;
529  int             i;
530  char           *str;
531
532  Start_Test( "mq_send errors" );
533
534  /*
535   * EBADF - Write to a closed queue.
536   */
537
538  puts( "Init: mq_send - Closed message queue (EBADF)" );
539  status = mq_send( Test_q[CLOSED].mq, "", 1, 0 );
540  fatal_posix_service_status( status, -1, "mq_send error return status");
541  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
542
543  /*
544   * EBADF - Write to a read only  queue.
545   */
546
547  puts( "Init: mq_send - Read only message queue (EBADF)" );
548  status = mq_send( Test_q[ RD_QUEUE ].mq, "", 1, 0 );
549  fatal_posix_service_status( status, -1, "mq_send error return status");
550  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
551
552  /*
553   * XXX - EINTR      Signal interrupted the call.
554   *
555  puts( "Init: mq_send - UNSUCCESSFUL (EINTR)" );
556  status = mq_send( Test_q, "", 0xffff, 0 );
557  fatal_posix_service_status( status, -1, "mq_send error return status");
558  fatal_posix_service_status( errno, E, "mq_send errno E");
559   */
560
561  /*
562   * EINVAL priority is out of range.
563   */
564
565  puts( "Init: mq_send - Priority out of range (EINVAL)" );
566  status = mq_send( Test_q[ RW_QUEUE ].mq, "", 1, MQ_PRIO_MAX + 1 );
567  fatal_posix_service_status( status, -1, "mq_send error return status");
568  fatal_posix_service_status( errno, EINVAL, "mq_send errno EINVAL");
569
570  /*
571   *  EMSGSIZE - Message size larger than msg_len
572   *             Validates that msgsize is stored correctly.
573   */
574
575  puts( "Init: mq_send - Message longer than msg_len (EMSGSIZE)" );
576  status = mq_send( Test_q[ RW_QUEUE ].mq, "", MSGSIZE+1, 0 );
577  fatal_posix_service_status( status, -1, "mq_send error return status");
578  fatal_posix_service_status( errno, EMSGSIZE, "mq_send errno EMSGSIZE");
579
580  i = fill_message_queues( "Init:" );
581
582  /*
583   * ENOSYS - send not supported
584  puts( "Init: mq_send - Blocking Queue overflow (ENOSYS)" );
585  status = mq_send( n_mq1, Predefined_Msgs[i], 0, 0 );
586  fatal_posix_service_status( status, -1, "mq_send error return status");
587  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
588
589  status = mq_close( n_mq1 );
590  fatal_posix_service_status( status, 0, "mq_close message queue");
591
592  status = mq_unlink( "read_only" );
593  fatal_posix_service_status( status, 0, "mq_unlink message queue");
594   */
595
596  /*
597   * EAGAIN - O_NONBLOCK and message queue is full.
598   */
599
600  puts( "Init: mq_send - on a FULL non-blocking queue with (EAGAIN)" );
601  str = Predefined_Msgs[i].msg;
602  status = mq_send(Test_q[RW_QUEUE].mq, str, 0, 0 );
603  fatal_posix_service_status( status, -1, "mq_send error return status");
604  fatal_posix_service_status( errno, EAGAIN, "mq_send errno EAGAIN");
605
606  return i-1;
607}
608
609void validate_mq_receive_error_codes( )
610{
611  int            status;
612  char           message[100];
613  unsigned int   priority;
614
615  Start_Test( "mq_receive errors"  );
616
617  /*
618   * EBADF - Not A Valid Message Queue
619   */
620
621  puts( "Init: mq_receive - Unopened message queue (EBADF)" );
622  status = mq_receive( Test_q[CLOSED].mq, message, 100, &priority );
623  fatal_posix_service_status( status, -1, "mq_ error return status");
624  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
625
626  /*
627   * EBADF - Queue not opened to read
628   */
629
630  puts( "Init: mq_receive - Write only queue (EBADF)" );
631  status = mq_receive( Test_q[WR_QUEUE].mq, message, 100, &priority  );
632  fatal_posix_service_status( status, -1, "mq_ error return status");
633  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
634
635  /*
636   * EMSGSIZE - Size is less than the message size attribute
637   */
638
639  puts( "Init: mq_receive - Size is less than the message (EMSGSIZE)" );
640  status = mq_receive(
641    Test_q[RW_QUEUE].mq, message, Predefined_Msgs[0].size-1, &priority );
642  fatal_posix_service_status( status, -1, "mq_ error return status");
643  fatal_posix_service_status( errno, EMSGSIZE, "mq_receive errno EMSGSIZE");
644
645
646  /*
647   * EAGAIN - O_NONBLOCK and Queue is empty
648   */
649  verify_queues_full( "Init:" );
650  empty_message_queues( "Init:" );
651
652  puts( "Init: mq_receive - Queue is empty (EAGAIN)" );
653  status = mq_receive( Test_q[RW_QUEUE].mq, message, 100, &priority );
654  fatal_posix_service_status( status, -1, "mq_ error return status");
655  fatal_posix_service_status( errno, EAGAIN, "mq_receive errno EAGAIN");
656
657  /*
658   * XXX - EINTR - Interrupted by a signal
659   */
660
661  /*
662   * XXX - EBADMSG - a data corruption problem.
663   */
664
665  /*
666   * XXX - ENOSYS - mq_receive not supported
667   */
668}
669
670void verify_open_functionality()
671{
672#if 0
673  mqd_t           n_mq;
674#endif
675
676  Start_Test( "mq_open functionality" );
677
678  /*
679   * Validate a second open returns the same message queue.
680   */
681
682#if 0
683  puts( "Init: mq_open - Open an existing mq ( same id )" );
684  n_mq = mq_open( RD_NAME, 0 );
685  fatal_posix_service_status(
686    (int) n_mq, (int ) Test_q[RD_QUEUE].mq, "mq_open error return status" );
687#endif
688}
689
690void verify_unlink_functionality()
691{
692  mqd_t           n_mq;
693  int             status;
694
695  Start_Test( "mq_unlink functionality" );
696
697  /*
698   * Unlink the message queue, then verify an open of the same name produces a
699   * different message queue.
700   */
701
702  puts( "Init: Unlink and Open without closing SUCCESSFUL" );
703  status = mq_unlink( DEFAULT_NAME );
704  fatal_posix_service_status( status, 0, "mq_unlink locked message queue");
705
706  n_mq = mq_open( DEFAULT_NAME, DEFAULT_ATTR, 0x777, NULL );
707  assert( n_mq != (-1) );
708  assert( n_mq != Test_q[ DEFAULT_RW ].mq );
709
710
711  status = mq_unlink( DEFAULT_NAME );
712  fatal_posix_service_status( status, 0, "mq_unlink locked message queue");
713  status = mq_close( Test_q[ DEFAULT_RW ].mq );
714  fatal_posix_service_status( status, 0, "mq_close message queue");
715
716  Test_q[ DEFAULT_RW ].mq = n_mq;
717}
718
719void verify_close_functionality()
720{
721  int i;
722  int status;
723  Start_Test( "Unlink and Close All Files"  );
724  for (i=0; i<DEFAULT_RW; i++) {
725
726    status = mq_unlink( Get_Queue_Name(i) );
727    fatal_posix_service_status( status, 0, "mq_unlink message queue");
728
729    status = mq_close( Test_q[i].mq );
730    fatal_posix_service_status( status, 0, "mq_close message queue");
731  }
732}
733
734
735void verify_timed_send_queue(
736  int  que,
737  int  is_blocking
738)
739{
740  struct timespec timeout;
741  struct timeval  tv1, tv2, tv3;
742  struct timezone tz1, tz2;
743  int              len;
744  int              status;
745  char            *msg;
746
747  timeout.tv_sec  = 1;
748  timeout.tv_nsec = 0;
749
750  printf( "Init: mq_timedsend - on queue %s ", Test_q[que].name);
751  len = Predefined_Msgs[MAXMSG].size;
752  msg = Predefined_Msgs[MAXMSG].msg;
753  gettimeofday( &tv1, &tz1 );
754  status = mq_timedsend( Test_q[que].mq, msg, len , 0, &timeout );
755  gettimeofday( &tv2, &tz2 );
756  tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
757  tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
758
759  if ( is_blocking ) { /* Don't verify the non-blocking queue */
760    fatal_int_service_status( status, -1, "mq_timedsend status");
761    fatal_posix_service_status( errno, ETIMEDOUT,  "errno ETIMEDOUT");
762  }
763
764  printf("Init: %ld sec %ld us\n", (long)tv3.tv_sec, (long)tv3.tv_usec );
765
766  if ( is_blocking ) /* non-blocking queue */
767    assert( tv3.tv_sec == 1 );
768  else
769    assert( tv3.tv_sec == 0 );
770
771  if ( que == DEFAULT_RW )
772    Test_q[que].count++;
773}
774
775void verify_timed_send()
776{
777  int              que;
778
779  Start_Test( "mq_timedsend"  );
780
781  for( que = RW_QUEUE; que < CLOSED; que++ ) {
782    if ( que == BLOCKING )
783      verify_timed_send_queue( que, 1 );
784    else
785      verify_timed_send_queue( que, 0 );
786  }
787}
788
789void verify_timed_receive_queue(
790  char *task_name,
791  int   que,
792  int   is_blocking
793)
794{
795  char message[ 100 ];
796  unsigned int priority;
797  struct timespec tm;
798  struct timeval  tv1, tv2, tv3;
799  struct timezone tz1, tz2;
800  int              status;
801
802  tm.tv_sec  = 1;
803  tm.tv_nsec = 0;
804
805  printf( "Init: %s mq_timedreceive - on queue %s ", task_name, Test_q[que].name);
806
807  gettimeofday( &tv1, &tz1 );
808  status = mq_timedreceive( Test_q[ que ].mq, message, 100, &priority, &tm );
809  gettimeofday( &tv2, &tz2 );
810  tv3.tv_sec  = tv2.tv_sec - tv1.tv_sec;
811  tv3.tv_usec = tv2.tv_usec - tv1.tv_usec;
812
813  fatal_int_service_status( status, -1, "mq_timedreceive status");
814  if ( is_blocking )
815    fatal_posix_service_status( errno, ETIMEDOUT,  "errno ETIMEDOUT");
816  printf( "Init: %ld sec %ld us\n", (long)tv3.tv_sec, (long)tv3.tv_usec );
817
818  if ( is_blocking )
819    assert( tv3.tv_sec == 1 );
820  else
821    assert( tv3.tv_sec == 0 );
822}
823
824
825
826void verify_timed_receive()
827{
828  int  que;
829
830  Start_Test( "mq_timedreceive"  );
831
832  for( que = RW_QUEUE; que < CLOSED; que++ ) {
833    if (( que == BLOCKING ) || ( que == DEFAULT_RW ))
834      verify_timed_receive_queue( "Init:", que, 1 );
835    else
836      verify_timed_receive_queue( "Init:", que, 0 );
837  }
838}
839
840#if (0)
841void verify_set_attr()
842{
843  struct mq_attr save_attr[ NUMBER_OF_TEST_QUEUES ];
844  struct mq_attr attr;
845  int            i;
846  int            status;
847
848  attr.mq_maxmsg  = 0;
849  attr.mq_msgsize = 0;
850
851  Start_Test( "mq_setattr"  );
852
853  puts( "Init: set_attr all queues to blocking" );
854  for(i=0; i<CLOSED; i++) {
855    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
856    status = mq_setattr( Test_q[i].mq, &attr, &save_attr[i] );
857    fatal_int_service_status( status, 0, "mq_setattr valid return status");
858
859    Validate_attributes( Test_q[i].mq, attr.mq_flags, 0 );
860  }
861
862  for( i = RW_QUEUE; i < CLOSED; i++ ) {
863    verify_timed_receive_queue( "Init:", i, 1 );
864  }
865
866  for(i=0; i<CLOSED; i++) {
867    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
868    status = mq_setattr( Test_q[i].mq, &save_attr[i], NULL );
869    fatal_int_service_status( status, 0, "mq_setattr valid return status");
870
871    Validate_attributes( Test_q[i].mq, Test_q[i].oflag, 0 );
872  }
873}
874#endif
875
876void wait_for_signal(
877  sigset_t     *waitset,
878  int           sec,
879  int           expect_signal
880)
881{
882  siginfo_t         siginfo;
883  int               status;
884  struct timespec   timeout;
885  int               signo;
886
887  siginfo.si_code = -1;
888  siginfo.si_signo = -1;
889  siginfo.si_value.sival_int = -1;
890
891  timeout.tv_sec = sec;
892  timeout.tv_nsec = 0;
893
894  status = sigemptyset( waitset );
895  assert( !status );
896
897  status = sigaddset( waitset, SIGUSR1 );
898  assert( !status );
899
900  printf( "waiting on any signal for %d seconds.\n", sec );
901  signo = sigtimedwait( waitset, &siginfo, &timeout );
902  if (expect_signal) {
903    fatal_int_service_status( signo, SIGUSR1, "got SISUSR1" );
904  } else {
905    fatal_int_service_status( signo, -1, "error return status");
906    fatal_posix_service_status( errno, EAGAIN, "errno EAGAIN");
907  }
908}
909
910void verify_notify()
911{
912  struct sigevent event;
913  int             status;
914  timer_t         timer_id;
915  sigset_t        set;
916
917  Start_Test( "mq_notify"  );
918
919  /* timer create */
920  event.sigev_notify = SIGEV_SIGNAL;
921  event.sigev_signo  = SIGUSR1;
922  if (timer_create (CLOCK_REALTIME, &event, &timer_id) == -1)
923    fatal_posix_service_status( errno, 0,  "errno ETIMEDOUT");
924
925  /* block the timer signal */
926  sigemptyset( &set );
927  sigaddset( &set, SIGUSR1 );
928  pthread_sigmask( SIG_BLOCK, &set, NULL );
929
930  /*
931   * EBADF - Not A Valid Message Queue
932   */
933
934  puts( "Init: mq_notify - Unopened message queue (EBADF)" );
935  status = mq_notify( Test_q[CLOSED].mq, NULL );
936  fatal_posix_service_status( status, -1, "mq_ error return status");
937  fatal_posix_service_status( errno, EBADF, "mq_receive errno EBADF");
938
939  /*
940   * Create ...
941   */
942
943  /*
944   * XXX setup notification
945   */
946  printf( "_____mq_notify - notify when %s gets a message\n",RW_NAME);
947  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
948  fatal_posix_service_status( status, 0, "mq_notify valid status");
949  wait_for_signal( &set, 3, 0 );
950
951  /*
952   * Send and verify signal occurs and registration is removed.
953   */
954
955  puts( "Init: Verify Signal when send" );
956  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
957  wait_for_signal( &set, 3, 1 );
958  Read_msg_from_que( RW_QUEUE, 0 );
959
960  puts( "Init: Verify No Signal when send" );
961  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
962  wait_for_signal( &set, 3, 0 );
963  Read_msg_from_que( RW_QUEUE, 0 );
964
965
966  /*
967   * EBUSY - Already Registered
968   */
969
970  printf( "____mq_notify - notify when %s gets a message\n",RD_NAME);
971  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
972  fatal_posix_service_status( status, 0, "mq_notify valid status");
973  wait_for_signal( &set, 3, 0 );
974
975  puts( "Init: mq_notify -  (EBUSY)" );
976  status = mq_notify( Test_q[RW_QUEUE].mq, &event );
977  fatal_posix_service_status( status, -1, "mq_notify error return status");
978  fatal_posix_service_status( errno, EBUSY, "mq_notify errno EBUSY");
979
980  /*
981   * Verify NULL removes registration.
982   */
983
984  puts( "Init: mq_notify - Remove notification with null" );
985  status = mq_notify( Test_q[RW_QUEUE].mq, NULL );
986  fatal_posix_service_status( status, 0, "mq_notify valid status");
987
988  puts( "Init: Verify No Signal when send" );
989  Show_send_msg_to_que( "Init:", RW_QUEUE, 0 );
990  wait_for_signal( &set, 3, 0 );
991  Read_msg_from_que( RW_QUEUE, 0 );
992
993}
994
995void verify_with_threads()
996{
997  int               status;
998  pthread_t         id;
999  Test_Message_t   *ptr;
1000#if 0
1001  unsigned int      priority;
1002  char              message[100];
1003#endif
1004
1005
1006#if 0
1007  /*
1008   * Create a task then block until the task sends the message.
1009   * Task tests set attributes so one queue will have a thread
1010   * blocked while attributes are changed.
1011   */
1012
1013  Start_Test( "multi-thread Task 4 Receive Test"  );
1014  status = pthread_create( &id, NULL, Task_4, NULL );
1015  assert( !status );
1016  puts( "Init: mq_receive - Empty queue changes to non-blocking (EAGAIN)" );
1017  status = mq_receive( Test_q[BLOCKING].mq, message, 100, &priority );
1018  fatal_int_service_status( status, -1, "mq_receive error return status");
1019  fatal_posix_service_status( errno, EAGAIN, "mq_receive errno EAGAIN");
1020  print_current_time( "Init: ", "" );
1021#endif
1022  /*
1023   * Create a task then block until the task sends the message.
1024   * Task tests set attributes so one queue will have a thread
1025   * blocked while attributes are changed.
1026   */
1027
1028  Start_Test( "multi-thread Task 1 Test"  );
1029  status = pthread_create( &id, NULL, Task_1, NULL );
1030  assert( !status );
1031  Read_msg_from_que(  BLOCKING, 0 ); /* Block until init writes */
1032  print_current_time( "Init: ", "" );
1033
1034#if 0
1035  /*
1036   * Fill the queue then create a task then block until the task receives a message.
1037   * Task tests set attributes so one queue will have a thread
1038   * blocked while attributes are changed.
1039   */
1040
1041  Start_Test( "multi-thread Task 4 Send Test"  );
1042  fill_message_queues( "Init:" );
1043  status = pthread_create( &id, NULL, Task_4, NULL );
1044  assert( !status );
1045  puts( "Init: mq_send - Full queue changes to non-blocking (EAGAIN)" );
1046  status = mq_send(Test_q[BLOCKING].mq, message, 0, 0 );
1047  fatal_posix_service_status( status, -1, "mq_send error return status");
1048  fatal_posix_service_status( errno, EAGAIN, "mq_send errno EAGAIN");
1049  verify_queues_full( "Init:" );
1050  empty_message_queues( "Init:" );
1051#endif
1052  /*
1053   * Create a task then block until the task reads a message.
1054   */
1055
1056  Start_Test( "multi-thread Task 2 Test"  );
1057  fill_message_queues( "Init:" );
1058  status = pthread_create( &id, NULL, Task_2, NULL );
1059  assert( !status );
1060  Show_send_msg_to_que( "Init:", BLOCKING, Priority_Order[0] );
1061  print_current_time( "Init: ", "" );
1062  verify_queues_full( "Init:" );
1063  empty_message_queues( "Init:" );
1064
1065  /*
1066   * Create a task then block until it deletes and closes all queues.
1067   *     EBADF - Queue unlinked and closed while blocked
1068   */
1069
1070  Start_Test( "multi-thread Task 3 Test"  );
1071  fill_message_queues( "Init:" );
1072  status = pthread_create( &id, NULL, Task_3, NULL );
1073  assert( !status );
1074  puts( "Init: mq_send - Block while thread deletes queue (EBADF)" );
1075  ptr = &Predefined_Msgs[0];
1076  status = mq_send( Test_q[BLOCKING].mq, ptr->msg, ptr->size , ptr->priority );
1077  fatal_posix_service_status( status, -1, "mq_send error return status");
1078  fatal_posix_service_status( errno, EBADF, "mq_send errno EBADF");
1079
1080}
1081
1082void validate_mq_setattr()
1083{
1084  struct mq_attr  attr;
1085  struct mq_attr  save_attr[ NUMBER_OF_TEST_QUEUES ];
1086  int             status;
1087  int            i;
1088
1089  /*
1090   * EBADF - Get the attributes from a closed queue.
1091   */
1092
1093  puts( "Task1:mq_setattr - unopened queue (EBADF)" );
1094  status = mq_setattr( Test_q[CLOSED].mq, &attr, NULL );
1095  fatal_posix_service_status( status, -1, "mq_setattr error return status");
1096  fatal_posix_service_status( errno, EBADF, "mq_setattr errno EBADF");
1097
1098  /*
1099   * XXX - The following are not listed in the POSIX manual but
1100   *       may occur.
1101   */
1102
1103  /*
1104   * EINVAL - NULL attributes
1105   */
1106
1107  puts( "Task1:mq_setattr - NULL attributes (EINVAL)" );
1108  status = mq_setattr( Test_q[RW_QUEUE].mq, NULL, NULL );
1109  fatal_posix_service_status( status, -1, "mq_setattr error return status");
1110  fatal_posix_service_status( errno, EINVAL, "mq_setattr errno EINVAL");
1111
1112  /*
1113   * Verify change queues to blocking, by verifying all queues block
1114   * for a timed receive.
1115   */
1116
1117  puts( "Init: set_attr all queues to blocking" );
1118  for(i=0; i<CLOSED; i++) {
1119    attr.mq_flags =  Test_q[i].oflag & (~O_NONBLOCK );
1120    status = mq_setattr( Test_q[i].mq, &attr, &save_attr[i] );
1121    fatal_int_service_status( status, 0, "mq_setattr valid return status");
1122    Validate_attributes( Test_q[i].mq, attr.mq_flags, 0 );
1123  }
1124  for( i = RW_QUEUE; i < CLOSED; i++ ) {
1125    verify_timed_receive_queue( "Init:", i, 1 );
1126  }
1127
1128  /*
1129   * Restore restore all queues to their old attribute.
1130   */
1131
1132  for(i=0; i<CLOSED; i++) {
1133    status = mq_setattr( Test_q[i].mq, &save_attr[i], NULL );
1134    fatal_int_service_status( status, 0, "mq_setattr valid return status");
1135    Validate_attributes( Test_q[i].mq, Test_q[i].oflag, 0 );
1136  }
1137}
1138
1139void *POSIX_Init(
1140  void *argument
1141)
1142{
1143  puts( "\n\n*** POSIX MESSAGE QUEUE TEST ***" );
1144
1145  validate_mq_open_error_codes( );
1146  open_test_queues();
1147  validate_mq_unlink_error_codes();
1148  validate_mq_close_error_codes();
1149  verify_unlink_functionality();
1150  validate_mq_setattr( );
1151  validate_mq_send_error_codes();
1152  validate_mq_getattr_error_codes();
1153  verify_timed_send();
1154  validate_mq_receive_error_codes();
1155  verify_timed_receive();
1156  verify_open_functionality();
1157  verify_notify();
1158  verify_with_threads();
1159
1160  puts( "*** END OF POSIX MESSAGE QUEUE TEST ***" );
1161  rtems_test_exit( 0 );
1162
1163  return NULL; /* just so the compiler thinks we returned something */
1164}
1165
1166
1167void *Task_1 (
1168  void *argument
1169)
1170{
1171  /* Block Waiting for a message */
1172
1173  print_current_time( "Task_1: ", "" );
1174
1175  Show_send_msg_to_que( "Task_1:", BLOCKING, 0 );
1176
1177  puts( "Task_1: pthread_exit" );
1178  pthread_exit( NULL );
1179
1180  /* switch to Init */
1181
1182  assert( 0 );
1183  return NULL; /* just so the compiler thinks we returned something */
1184}
1185
1186void *Task_2(
1187  void *argument
1188)
1189{
1190  print_current_time( "Task_2: ", "" );
1191
1192
1193  /* Block waiting to send a message */
1194
1195  verify_queues_full( "Task_2:" );
1196  Read_msg_from_que( BLOCKING, Priority_Order[0] ); /* Cause context switch */
1197
1198  puts( "Task_2: pthread_exit" );
1199  pthread_exit( NULL );
1200
1201     /* switch to Init */
1202
1203  return NULL; /* just so the compiler thinks we returned something */
1204}
1205
1206void *Task_3 (
1207  void *argument
1208)
1209{
1210
1211  print_current_time( "Task_3: ", "" );
1212
1213  /*
1214   * close and unlink all queues.
1215   */
1216
1217  verify_close_functionality( "Task_3: " );
1218  puts( "Task_3: pthread_exit" );
1219  pthread_exit( NULL );
1220
1221     /* switch to Init */
1222
1223  return NULL; /* just so the compiler thinks we returned something */
1224
1225}
1226
1227void *Task_4 (
1228  void *argument
1229)
1230{
1231  struct mq_attr  attr;
1232  int             status;
1233  int             count;
1234
1235  print_current_time( "Task_4: ", "" );
1236
1237  /*
1238   * Set the count to the number of messages in the queue.
1239   */
1240
1241  status = mq_getattr( Test_q[BLOCKING].mq, &attr );
1242  fatal_posix_service_status( status, 0, "mq_getattr valid return status");
1243  count = attr.mq_curmsgs;
1244
1245  puts("Task_4: Set queue to non-blocking");
1246  attr.mq_flags =  Test_q[BLOCKING].oflag | O_NONBLOCK;
1247  status = mq_setattr( Test_q[BLOCKING].mq, &attr, NULL );
1248  fatal_int_service_status( status, 0, "mq_setattr valid return status");
1249  Validate_attributes( Test_q[BLOCKING].mq, attr.mq_flags, count );
1250
1251  puts("Task_4: Return queue to blocking");
1252  attr.mq_flags =  Test_q[BLOCKING].oflag;
1253  status = mq_setattr( Test_q[BLOCKING].mq, &attr, NULL );
1254  fatal_int_service_status( status, 0, "mq_setattr valid return status");
1255  Validate_attributes( Test_q[BLOCKING].mq, attr.mq_flags, count );
1256
1257  puts( "Task_4: pthread_exit" );
1258  pthread_exit( NULL );
1259
1260     /* switch to Init */
1261
1262  return NULL; /* just so the compiler thinks we returned something */
1263
1264}
1265
1266void *Task_5 (
1267  void *argument
1268)
1269{
1270
1271  print_current_time( "Task_5: ", "" );
1272
1273  puts( "Task_5: pthread_exit" );
1274  pthread_exit( NULL );
1275
1276     /* switch to Init */
1277
1278  return NULL; /* just so the compiler thinks we returned something */
1279
1280}
1281
1282void *Task_ (
1283  void *argument
1284)
1285{
1286
1287  print_current_time( "Task_: ", "" );
1288
1289  puts( "Task_: pthread_exit" );
1290  pthread_exit( NULL );
1291
1292     /* switch to Init */
1293
1294  return NULL; /* just so the compiler thinks we returned something */
1295
1296}
Note: See TracBrowser for help on using the repository browser.