Fix potential nil ptr seg fault and CI test issue
[ric-plt/lib/rmr.git] / test / ring_static_test.c
1 // : vi ts=4 sw=4 noet :
2 /*
3 ==================================================================================
4             Copyright (c) 2019 Nokia
5             Copyright (c) 2018-2019 AT&T Intellectual Property.
6
7    Licensed under the Apache License, Version 2.0 (the "License");
8    you may not use this file except in compliance with the License.
9    You may obtain a copy of the License at
10
11            http://www.apache.org/licenses/LICENSE-2.0
12
13    Unless required by applicable law or agreed to in writing, software
14    distributed under the License is distributed on an "AS IS" BASIS,
15    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16    See the License for the specific language governing permissions and
17    limitations under the License.
18 ==================================================================================
19 */
20
21 /*
22         Mmemonic:       ring_static_test.c
23         Abstract:       Test the ring funcitons. These are meant to be included at compile
24                                 time by the test driver.
25
26         Author:         E. Scott Daniels
27         Date:           3 April 2019
28 */
29
30 #include <unistd.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <strings.h>
34 #include <errno.h>
35 #include <string.h>
36 #include <stdint.h>
37 #include <pthread.h>
38 #include <semaphore.h>
39
40 #include "rmr.h"
41 #include "rmr_agnostic.h"
42
43
44 /*
45         Conduct a series of interleaved tests inserting i-factor
46         values before beginning to pull values (i-factor must be
47         size - 2 smaller than the ring.
48         Returns 0 on success, 1 on insert failure and 2 on pull failure.
49 */
50 static int ie_test( void* r, int i_factor, long inserts ) {
51         int i;
52         int* dp;
53         int data[29];
54
55         for( i = 0; i < inserts; i++ ) {
56                 data[i%29] = i;
57                 if( ! uta_ring_insert( r, &data[i%29] ) ) {
58                         fprintf( stderr, "<FAIL> interleaved insert failed on ifactor=%d i=%d\n", i_factor, i );
59                         return 1;
60                 }
61                 if( i > i_factor-1 ) {
62                         dp = uta_ring_extract( r );
63                         if( *dp != data[(i-i_factor)%29] ) {
64                                 fprintf( stderr, "<FAIL> interleaved exctract failed on ifactor=%d i=%d expected=%d got=%d\n", i_factor, i, data[(i-i_factor)%29], *dp );
65                                 return 2;
66                         }
67                 }
68         }
69         //fprintf( stderr, "<OK>   interleaved insert/extract test passed for insert factor %d\n", i_factor );
70
71         return 0;
72 }
73
74 static int ring_test( ) {
75         void* r;
76         int i;
77         int j;
78         int     data[20];
79         int*    dp;
80         int size = 18;
81         int     pfd = -1;                                       // pollable file descriptor for the ring
82         int     errors = 0;
83
84         r = uta_mk_ring( 0 );                   // should return nil
85         if( r != NULL ) {
86                 fprintf( stderr, "<FAIL> attempt to make a ring with size 0 returned a pointer\n" );
87                 return 1;
88         }
89         r = uta_mk_ring( -1 );                  // should also return nil
90         if( r != NULL ) {
91                 fprintf( stderr, "<FAIL> attempt to make a ring with size <0 returned a pointer\n" );
92                 return 1;
93         }
94
95         r = uta_mk_ring( 18 );
96         if( r == NULL ) {
97                 fprintf( stderr, "<FAIL> unable to make ring with 17 entries\n" );
98                 return 1;
99         }
100
101         pfd = uta_ring_getpfd( r );             // get pollable file descriptor
102         if( pfd < 0 ) {
103                 fprintf( stderr, "<FAIL> expected a pollable file descriptor >= 0, but got: %d\n", pfd );
104                 errors++;
105         }
106
107         pfd = uta_ring_config( r, 0x03 );               // turn on locking for reads and writes
108         if( pfd != 1 ) {
109                 fprintf( stderr, "<FAIL> config attempt to enable locking failed\n" );
110                 errors++;
111         }
112         
113
114         for( i = 0; i < 20; i++ ) {             // test to ensure it reports full when head/tail start at 0
115                 data[i] = i;
116                 if( ! uta_ring_insert( r, &data[i] ) ) {
117                         break;
118                 }
119         }
120
121         if( i > size ) {
122                 fprintf( stderr, "<FAIL> didn not report table full: i=%d\n", i );
123                 return 1;
124         }
125
126         fprintf( stderr, "<OK>   reported table full at i=%d as expected\n", i );
127
128
129         for( i = 0; i < size + 3; i++ ) {                                                               // ensure they all come back in order, and we don't get 'extras'
130                 if( (dp = uta_ring_extract( r )) == NULL ) {
131                         if( i < size-1 ) {
132                                 fprintf( stderr, "<FAIL> nil pointer at i=%d\n", i );
133                                 return 1;
134                         } else {
135                                 break;
136                         }
137                 }
138
139                 if( *dp != i ) {
140                         fprintf( stderr, "<FAIL> data at i=% isnt right; expected %d got %d\n", i, i, *dp );
141                 }
142         }
143         if( i > size ) {
144                 fprintf( stderr, "<FAIL> got too many values on extract: %d\n", i );
145                 return 1;
146         }
147         fprintf( stderr, "<OK>   extracted values were sane, got: %d\n", i-1 );
148
149         uta_ring_free( NULL );                                                  // ensure this doesn't blow up
150         uta_ring_free( r );
151         for( i = 2; i < 15; i++ ) {
152                 r = uta_mk_ring( 16 );
153                 if( ie_test( r, i, 101 ) != 0 ) {                       // modest number of inserts
154                         fprintf( stderr, "<FAIL> ie test for 101 inserts didn't return 0\n" );
155                         return 1;
156                 }
157
158                 uta_ring_free( r );
159         }
160         fprintf( stderr, "<OK>   all modest insert/exctract tests pass\n" );
161
162         size = 5;
163         for( j = 0; j < 20; j++ ) {
164                 for( i = 2; i < size - 2; i++ ) {
165                         r = uta_mk_ring( size );
166                         if( ie_test( r, i, 66000 ) != 0 ) {                     // should force the 16bit head/tail indexes to roll over
167                                 fprintf( stderr, "<FAIL> ie test for 66K inserts didn't return 0\n" );
168                                 return 1;
169                         }
170
171                         uta_ring_free( r );
172                 }
173                 fprintf( stderr, "<OK>   all large insert/exctract tests pass ring size=%d\n", size );
174
175                 size++;
176         }
177
178         fprintf( stderr, "<INFO> all ring tests pass\n" );
179         return errors;
180 }