Line data Source code
1 : /**
2 : * @file
3 : *
4 : * @brief Tests for mmapstorage_crc plugin variant
5 : *
6 : * @copyright BSD License (see LICENSE.md or https://www.libelektra.org)
7 : *
8 : */
9 : #define _XOPEN_SOURCE 600
10 :
11 : /* -- Imports --------------------------------------------------------------------------------------------------------------------------- */
12 :
13 : #include <stdio.h> // fopen()
14 : #include <sys/mman.h> // mmap()
15 : #include <sys/stat.h> // stat(), chmod()
16 :
17 : #include <tests_plugin.h>
18 :
19 : #include "internal.h"
20 : #include "mmapstorage.h"
21 :
22 : /* -- Macros ---------------------------------------------------------------------------------------------------------------------------- */
23 :
24 : #define TEST_ROOT_KEY "user/tests/mmapstorage_crc"
25 :
26 : /* -- Functions ------------------------------------------------------------------------------------------------------------------------- */
27 :
28 2 : static void test_mmap_crc_no_checksum (const char * tmpFile)
29 : {
30 : // regression test: write mmap file without checksum (=0L), then read with checksum
31 : {
32 2 : Key * parentKey = keyNew (TEST_ROOT_KEY, KEY_VALUE, tmpFile, KEY_END);
33 2 : KeySet * conf = ksNew (0, KS_END);
34 2 : PLUGIN_OPEN ("mmapstorage");
35 :
36 2 : KeySet * ks = ksNew (0, KS_END);
37 2 : succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "kdbSet was not successful");
38 :
39 2 : keyDel (parentKey);
40 2 : ksDel (ks);
41 2 : PLUGIN_CLOSE ();
42 : }
43 : // the following fails if the internal CRC on/off flag was not set
44 : {
45 2 : Key * parentKey = keyNew (TEST_ROOT_KEY, KEY_VALUE, tmpFile, KEY_END);
46 2 : KeySet * conf = ksNew (0, KS_END);
47 2 : PLUGIN_OPEN ("mmapstorage_crc");
48 :
49 2 : KeySet * ks = ksNew (0, KS_END);
50 2 : succeed_if (plugin->kdbGet (plugin, ks, parentKey) == 1, "kdbGet was not successful");
51 :
52 2 : keyDel (parentKey);
53 2 : ksDel (ks);
54 2 : PLUGIN_CLOSE ();
55 : }
56 2 : }
57 :
58 2 : static void test_mmap_crc_wrong_checksum (const char * tmpFile)
59 : {
60 : // first write a mmap file
61 : {
62 2 : Key * parentKey = keyNew (TEST_ROOT_KEY, KEY_VALUE, tmpFile, KEY_END);
63 2 : KeySet * conf = ksNew (0, KS_END);
64 2 : PLUGIN_OPEN ("mmapstorage_crc");
65 :
66 2 : KeySet * ks = ksNew (0, KS_END);
67 2 : succeed_if (plugin->kdbSet (plugin, ks, parentKey) == 1, "kdbSet was not successful");
68 :
69 2 : keyDel (parentKey);
70 2 : ksDel (ks);
71 2 : PLUGIN_CLOSE ();
72 : }
73 :
74 : // set wrong checksum in mmap header
75 : FILE * fp;
76 2 : if ((fp = fopen (tmpFile, "r+")) == 0)
77 : {
78 0 : yield_error ("fopen() error");
79 : }
80 : struct stat sbuf;
81 2 : if (stat (tmpFile, &sbuf) == -1)
82 : {
83 0 : yield_error ("stat() error");
84 : }
85 :
86 2 : int fd = fileno (fp);
87 2 : char * mappedRegion = mmap (0, sbuf.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
88 2 : if (mappedRegion == MAP_FAILED)
89 : {
90 : ELEKTRA_LOG_WARNING ("error mapping file %s\nmmapSize: " ELEKTRA_STAT_ST_SIZE_F, tmpFile, sbuf.st_size);
91 0 : yield_error ("mmap() error");
92 0 : return;
93 : }
94 2 : if (fp)
95 : {
96 2 : fclose (fp);
97 : }
98 :
99 2 : MmapHeader * mmapHeader = (MmapHeader *) mappedRegion;
100 2 : mmapHeader->checksum++;
101 :
102 2 : if (msync ((void *) mappedRegion, sbuf.st_size, MS_SYNC) != 0)
103 : {
104 0 : yield_error ("msync() error");
105 0 : return;
106 : }
107 :
108 2 : if (munmap (mappedRegion, sbuf.st_size) != 0)
109 : {
110 0 : yield_error ("munmap() error");
111 0 : return;
112 : }
113 :
114 : // wrong checksum should be detected now
115 : {
116 : // we expect an error here
117 2 : Key * parentKey = keyNew (TEST_ROOT_KEY, KEY_VALUE, tmpFile, KEY_END);
118 2 : KeySet * conf = ksNew (0, KS_END);
119 2 : PLUGIN_OPEN ("mmapstorage_crc");
120 :
121 2 : KeySet * ks = ksNew (0, KS_END);
122 2 : succeed_if (plugin->kdbGet (plugin, ks, parentKey) == ELEKTRA_PLUGIN_STATUS_ERROR, "kdbGet did not detect wrong checksum");
123 :
124 2 : keyDel (parentKey);
125 2 : ksDel (ks);
126 2 : PLUGIN_CLOSE ();
127 : }
128 : }
129 :
130 : /* -- Main ------------------------------------------------------------------------------------------------------------------------------ */
131 :
132 2 : int main (int argc, char ** argv)
133 : {
134 2 : printf ("MMAPSTORAGE CRC TESTS\n");
135 2 : printf ("==================\n\n");
136 :
137 2 : init (argc, argv);
138 2 : const char * tmpFile = elektraFilename ();
139 2 : test_mmap_crc_no_checksum (tmpFile);
140 2 : test_mmap_crc_wrong_checksum (tmpFile);
141 :
142 2 : printf ("\ntestmod_mmapstorage_crc RESULTS: %d test(s) done. %d error(s).\n", nbTest, nbError);
143 :
144 2 : return nbError;
145 : }
|