source: rtems/testsuites/psxtests/psxndbm01/init.c @ 57e01735

5
Last change on this file since 57e01735 was 57e01735, checked in by Vaibhav Gupta <vaibhavgupta40@…>, on 07/23/19 at 13:41:54

psxtests: Add ndbm test suite

Joel Sherrill <joel@…> modified the patch to
add autoconf logic to avoid building this new test
unless the tool chain include <ndbm.h>. The ensures
that git bisect continues to work and that the addition
of this test does not immediately force the entire
community to update their tools.

  • Property mode set to 100644
File size: 9.6 KB
Line 
1/**
2 *  @file
3 *  @brief Test suite for ndbm.h methods
4 */
5
6/*
7 * SPDX-License-Identifier: BSD-2-Clause
8 *
9 * Copyright (C) 2019 Vaibhav Gupta
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
14 * 1. Redistributions of source code must retain the above copyright
15 *    notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 *    notice, this list of conditions and the following disclaimer in the
18 *    documentation and/or other materials provided with the distribution.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE.
31 */
32
33#ifdef HAVE_CONFIG_H
34#include "config.h"
35#endif
36
37/* header files are listed in lexical/lexicographical/alphabetical order */
38
39#include <errno.h>
40#include <fcntl.h>      /* contains definitions of 'open_flags' */
41#include <limits.h>
42#include <ndbm.h>       /* contains declarations of ndbm methods */
43#include <stddef.h>
44#include <stdint.h>
45#include <stdio.h>
46#include <sys/stat.h>   /* contains definitions of 'file_mode' */
47#include <string.h>
48#include <rtems/test.h>
49#include <tmacros.h>
50
51const char rtems_test_name[] = "PSXNDBM 01";
52
53#define NAME      "VARoDeK"
54#define PHONE_NO  "123-321-777-888"
55#define DB_NAME   "phones_test"
56#define NAME2     "VG"
57#define PHONE_NO2 "321-123-888-777"
58
59/* forward declarations to avoid warnings */
60rtems_task Init(rtems_task_argument ignored);
61
62/*
63* This Function takes DBM* as a argument and count the number of records in the
64* database pointed by it.
65*/
66static int count_no_of_records( DBM *db_local )
67{
68  int count = 0;
69  datum temp;
70
71  for (
72    temp = dbm_firstkey( db_local );
73    temp.dptr != NULL;
74    temp = dbm_nextkey( db_local ), count++
75  );
76
77  return count;
78}
79
80/* Test Function Begins */
81rtems_task Init(rtems_task_argument ignored)
82{
83  datum name          = { NAME, sizeof( NAME ) };
84  datum put_phone_no  = { PHONE_NO, sizeof( PHONE_NO ) };
85  datum name2         = { NAME2, sizeof( NAME2 ) };
86  datum put_phone_no2 = { PHONE_NO2, sizeof( PHONE_NO2 ) };
87
88  datum get_phone_no, key;
89
90  int i;
91  char *test_strings;
92
93  DBM *db;
94
95  TEST_BEGIN();
96
97/* A Simple test to check if ndbm methods are call-able */
98
99/*
100 * A Simple test to check if NDBM methods are call-able
101 *
102 * We will try to open a database and then close it.
103 * If it successful, hence we can have further tests.
104 * Also, while opening it for first time, will create that database,
105 * hence we will be able to test for 'O_RDWR | O_EXCL' case later.
106 * Meanwhile we will also store one record, this record will be helpful in
107 * further tests.
108 * And fetch it, to make sure if basic NDBM methods are working correctly.
109 */
110
111  puts( "\nOpen Database." );
112  db = dbm_open( DB_NAME, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU );
113  rtems_test_assert( db != NULL );
114
115  /* This data will be useful in further tests */
116  puts( "Store Records in Database." );
117  dbm_store( db, name, put_phone_no, DBM_INSERT );
118
119  puts( "Fetch Records from Database and check." );
120  get_phone_no = dbm_fetch( db, name );
121  rtems_test_assert( strcmp( (const char*)get_phone_no.dptr, PHONE_NO ) == 0 );
122
123  puts( "Close Database." );
124  dbm_close( db );
125
126/* dbm_open() */
127
128  puts( "\nTestcases for 'dbm_open()'." );
129
130/* The 'DB_NAME' is already created, hence 'O_RDWR | O_EXCL' should fail. */
131  puts( "Use 'O_CREAT | O_EXCL' to open existing file and confirm error." );
132  db = dbm_open( DB_NAME, O_RDWR | O_CREAT | O_EXCL, S_IRWXU );
133  rtems_test_assert( db == NULL );
134  rtems_test_assert( errno == EEXIST );
135
136/* Some implementations use 3 characters for the suffix and others use
137 * 4 characters for the suffix, applications should ensure that the maximum
138 * portable pathname length passed to dbm_open() is no greater than
139 * {PATH_MAX}-4 bytes, with the last component of the pathname no greater
140 * than {NAME_MAX}-4 bytes.
141 */
142
143/* inside 'ndbm.h' ; '#define   DBM_SUFFIX      ".db"' ;
144 * 2 alphabets and 1 period, hence 3 characters are used for suffix
145 * in this implementation.
146 */
147
148  puts( "Use path name larger than '{PATH_MAX}-3 bytes.' and confirm error." );
149  test_strings = (char*)malloc( PATH_MAX - 2 );
150  for ( i = 0; i < PATH_MAX - 3; i++ ) {
151    test_strings[i] = 'r';
152  }
153  test_strings[i] = '\0';
154  db = dbm_open(
155                (const char*)test_strings,
156                O_RDWR | O_CREAT | O_TRUNC,
157                S_IRWXU
158  );
159  rtems_test_assert( db == NULL );
160  rtems_test_assert( errno == ENAMETOOLONG );
161  free( test_strings );
162
163/* database opened for write-only access opens the files for read and
164 * write access or it will fail.
165 */
166
167/* Implementation of __hash_open in newlib does not support `O_WRONLY` */
168
169  puts( "Open file with write access only and confirm error." );
170  db = dbm_open( DB_NAME, O_WRONLY, S_IRWXU );
171  rtems_test_assert( db == NULL );
172  rtems_test_assert( errno == EINVAL );
173
174/* dbm_store() */
175
176  puts( "\nTestcases for 'dbm_store()'" );
177  db = dbm_open( DB_NAME, O_RDWR, S_IRWXU );
178  rtems_test_assert( db != NULL );
179
180  puts( "Insert new record with same key using 'DBM_INSERT' mode and "
181        "confirm error." );
182  rtems_test_assert( dbm_store( db, name, put_phone_no2, DBM_INSERT ) == 1 );
183
184  get_phone_no = dbm_fetch( db, name );
185  rtems_test_assert( strcmp( (const char*)get_phone_no.dptr, PHONE_NO ) == 0 );
186
187  puts( "Insert new record with same key using 'DBM_REPLACE' mode and "
188        "confirm changes." );
189  rtems_test_assert( dbm_store( db, name, put_phone_no2, DBM_REPLACE ) == 0 );
190
191  get_phone_no = dbm_fetch( db, name );
192  rtems_test_assert( strcmp( (const char*)get_phone_no.dptr, PHONE_NO2 ) == 0 );
193
194/* Revert for next tests */
195  rtems_test_assert( dbm_store( db, name, put_phone_no, DBM_REPLACE ) == 0 );
196
197  puts( "Store a new record and "
198        "confirm that total number of records is successful 2." );
199  rtems_test_assert( dbm_store( db, name2, put_phone_no2, DBM_INSERT ) == 0 );
200
201/* Confirm number of records */
202  rtems_test_assert( count_no_of_records( db ) == 2 );
203
204  dbm_close( db );
205
206/* dbm_fetch() */
207
208  puts( "\nTestcases for 'dbm_fetch()'" );
209  db = dbm_open( DB_NAME, O_RDONLY, S_IRWXU );
210  rtems_test_assert( db != NULL );
211
212  puts( "Fetch existing records and confirm results." );
213  get_phone_no = dbm_fetch( db, name );
214  rtems_test_assert( strcmp( (const char*)get_phone_no.dptr, PHONE_NO ) == 0 );
215
216  get_phone_no = dbm_fetch( db, name2 );
217  rtems_test_assert( strcmp( (const char*)get_phone_no.dptr, PHONE_NO2 ) == 0 );
218
219  puts( "Fetch non-existing record and confirm error." );
220  test_strings = (char*)malloc(6);
221  strncpy( test_strings, "Hello", 5 );
222
223  test_strings[5] = '\0';
224
225/* The data pointed by test_string is now pointed by key.dptr */
226  key.dptr = test_strings;
227  key.dsize = sizeof( test_strings );
228  get_phone_no = dbm_fetch( db, key );
229  rtems_test_assert( get_phone_no.dptr == NULL );
230  dbm_close( db );
231
232/* We need the 'key' object, hence we cannot free 'test_strings' */
233
234/* dbm_delete() */
235
236  puts( "\nTestcases for 'dbm_delete()'" );
237  db = dbm_open( DB_NAME, O_RDWR, S_IRWXU );
238  rtems_test_assert( db != NULL );
239
240  puts( "Delete non-existing record and confirm error." );
241  rtems_test_assert( dbm_delete( db, key ) != 0 );
242  free( test_strings );
243  rtems_test_assert( count_no_of_records( db ) == 2);
244
245  puts( "Delete existing record and "
246        "confirm that total number of records is successful 1." );
247  rtems_test_assert( dbm_delete( db, name ) == 0 );
248  rtems_test_assert( count_no_of_records( db ) == 1);
249
250  puts( "Confirm if correct record is deleted." );
251  get_phone_no = dbm_fetch( db, name );
252  rtems_test_assert( get_phone_no.dptr == NULL );
253
254/* record returned by 'dbm_firstkey()' should be the only record
255 * left, this should be checked to confirm correct working of
256 * 'dbm_firstkey()'.
257 * Check if the data is not corrupted after usage of 'dbm_delete()'
258 */
259
260  puts( "Check if the data is not corrupted after usage of 'dbm_delete()'." );
261  get_phone_no = dbm_fetch( db, dbm_firstkey( db ) );
262  rtems_test_assert( strcmp( (const char*)get_phone_no.dptr, PHONE_NO2 ) == 0 );
263
264/* Empty the database and then try to use 'dbm_firstkey()', the
265 * dptr pointer should point to NULL.
266 */
267
268  puts( "Empty records in database and check results of 'dbm_firstkey()'." );
269  rtems_test_assert( dbm_delete( db, dbm_firstkey( db ) ) == 0 );
270  key = dbm_firstkey( db );
271  rtems_test_assert( key.dptr == NULL );
272  dbm_close( db );
273
274/*
275* All cases for 'dbm_firstkey()' and 'dbm_nextkey()' were tested while
276* performing other tests.
277* One such case be found in count_number_of_records() function.
278*/
279
280  TEST_END();
281  rtems_test_exit(0);
282}
283
284/* NOTICE: the clock driver is explicitly disabled */
285
286#define CONFIGURE_APPLICATION_DOES_NOT_NEED_CLOCK_DRIVER
287#define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
288
289#define CONFIGURE_MAXIMUM_TASKS                  1
290
291#define CONFIGURE_LIBIO_MAXIMUM_FILE_DESCRIPTORS 6
292
293#define CONFIGURE_RTEMS_INIT_TASKS_TABLE
294
295#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
296
297#define CONFIGURE_INIT
298#include <rtems/confdefs.h>
299/* end of file */
Note: See TracBrowser for help on using the repository browser.