Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
mc: Also remove the process_index
[simgrid.git] / src / mc / sosp / mc_snapshot_test.cpp
1 /* Copyright (c) 2014-2019. The SimGrid Team. All rights reserved.          */
2
3 /* This program is free software; you can redistribute it and/or modify it
4  * under the terms of the license (GNU LGPL) which comes with this package. */
5
6 #include "src/include/catch.hpp"
7 #include "src/mc/mc_config.hpp"
8 #include "src/mc/sosp/mc_snapshot.hpp"
9
10 #include <cstddef>
11 #include <random>
12 #include <sys/mman.h>
13
14 /**************** Class BOOST_tests *************************/
15 using simgrid::mc::RegionSnapshot;
16 class snap_test_helper {
17 public:
18   static void init_memory(void* mem, size_t size);
19   static void Init(bool sparse_ckpt);
20   typedef struct {
21     size_t size;
22     void* src;
23     void* dstn;
24     RegionSnapshot* region0;
25     RegionSnapshot* region;
26   } prologue_return;
27   static prologue_return prologue(int n); // common to the below 5 fxs
28   static void read_whole_region();
29   static void read_region_parts();
30   static void compare_whole_region();
31   static void compare_region_parts();
32   static void read_pointer();
33
34   static void cleanup()
35   {
36     delete mc_model_checker;
37     mc_model_checker = nullptr;
38   }
39
40   static std::default_random_engine rnd_engine;
41   static bool sparse_checkpoint;
42   static std::unique_ptr<simgrid::mc::RemoteClient> process;
43 };
44
45 // static member variables init.
46 std::default_random_engine snap_test_helper::rnd_engine;
47 bool snap_test_helper::sparse_checkpoint                             = 0;
48 std::unique_ptr<simgrid::mc::RemoteClient> snap_test_helper::process = nullptr;
49
50 void snap_test_helper::init_memory(void* mem, size_t size)
51 {
52   char* dest = (char*)mem;
53   for (size_t i = 0; i < size; ++i) {
54     dest[i] = rnd_engine() & 255;
55   }
56 }
57
58 void snap_test_helper::Init(bool sparse_ckpt)
59 {
60   _sg_mc_sparse_checkpoint = sparse_ckpt;
61   REQUIRE(xbt_pagesize == getpagesize());
62   REQUIRE(1 << xbt_pagebits == xbt_pagesize);
63
64   process.reset(new simgrid::mc::RemoteClient(getpid(), -1));
65   process->init();
66   mc_model_checker = new ::simgrid::mc::ModelChecker(std::move(process));
67 }
68
69 snap_test_helper::prologue_return snap_test_helper::prologue(int n)
70 {
71   // Store region page(s):
72   size_t byte_size = n * xbt_pagesize;
73   void* source     = mmap(nullptr, byte_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
74   INFO("Could not allocate source memory")
75   REQUIRE(source != MAP_FAILED);
76
77   // Init memory and take snapshots:
78   init_memory(source, byte_size);
79   simgrid::mc::RegionSnapshot* region0 =
80       new simgrid::mc::RegionSparse(simgrid::mc::RegionType::Unknown, source, source, byte_size);
81   for (int i = 0; i < n; i += 2) {
82     init_memory((char*)source + i * xbt_pagesize, xbt_pagesize);
83   }
84   simgrid::mc::RegionSnapshot* region =
85       new simgrid::mc::RegionSparse(simgrid::mc::RegionType::Unknown, source, source, byte_size);
86
87   void* destination = mmap(nullptr, byte_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
88   INFO("Could not allocate destination memory");
89   REQUIRE(source != MAP_FAILED);
90
91   return {.size    = byte_size,
92           .src     = source,
93           .dstn    = destination,
94           .region0 = std::move(region0),
95           .region  = std::move(region)};
96 }
97
98 void snap_test_helper::read_whole_region()
99 {
100   for (int n = 1; n != 32; ++n) {
101
102     prologue_return ret = prologue(n);
103     const void* read    = MC_region_read(ret.region, ret.dstn, ret.src, ret.size);
104     INFO("Mismatch in MC_region_read()");
105     REQUIRE(not memcmp(ret.src, read, ret.size));
106
107     munmap(ret.dstn, ret.size);
108     munmap(ret.src, ret.size);
109     delete ret.region0;
110     delete ret.region;
111   }
112 }
113
114 void snap_test_helper::read_region_parts()
115 {
116   for (int n = 1; n != 32; ++n) {
117
118     prologue_return ret = prologue(n);
119
120     for (int j = 0; j != 100; ++j) {
121       size_t offset    = rnd_engine() % ret.size;
122       size_t size      = rnd_engine() % (ret.size - offset);
123       const void* read = MC_region_read(ret.region, ret.dstn, (const char*)ret.src + offset, size);
124       INFO("Mismatch in MC_region_read()");
125       REQUIRE(not memcmp((char*)ret.src + offset, read, size));
126     }
127     munmap(ret.dstn, ret.size);
128     munmap(ret.src, ret.size);
129     delete ret.region0;
130     delete ret.region;
131   }
132 }
133
134 void snap_test_helper::compare_whole_region()
135 {
136   for (int n = 1; n != 32; ++n) {
137
138     prologue_return ret = prologue(n);
139
140     INFO("Unexpected match in MC_snapshot_region_memcmp() with previous snapshot");
141     REQUIRE(MC_snapshot_region_memcmp(ret.src, ret.region0, ret.src, ret.region, ret.size));
142
143     munmap(ret.dstn, ret.size);
144     munmap(ret.src, ret.size);
145     delete ret.region0;
146     delete ret.region;
147   }
148 }
149
150 void snap_test_helper::compare_region_parts()
151 {
152   for (int n = 1; n != 32; ++n) {
153
154     prologue_return ret = prologue(n);
155
156     for (int j = 0; j != 100; ++j) {
157       size_t offset = rnd_engine() % ret.size;
158       size_t size   = rnd_engine() % (ret.size - offset);
159
160       INFO("Mismatch in MC_snapshot_region_memcmp()");
161       REQUIRE(not MC_snapshot_region_memcmp((char*)ret.src + offset, ret.region, (char*)ret.src + offset, ret.region,
162                                             size));
163     }
164     munmap(ret.dstn, ret.size);
165     munmap(ret.src, ret.size);
166     delete ret.region0;
167     delete ret.region;
168   }
169 }
170
171 void snap_test_helper::read_pointer()
172 {
173
174   prologue_return ret = prologue(1);
175   memcpy(ret.src, &mc_model_checker, sizeof(void*));
176   simgrid::mc::RegionSnapshot* region2 =
177       new simgrid::mc::RegionSparse(simgrid::mc::RegionType::Unknown, ret.src, ret.src, ret.size);
178   INFO("Mismtach in MC_region_read_pointer()");
179   REQUIRE(MC_region_read_pointer(region2, ret.src) == mc_model_checker);
180
181   munmap(ret.dstn, ret.size);
182   munmap(ret.src, ret.size);
183   delete ret.region0;
184   delete ret.region;
185   delete region2;
186 }
187
188 /*************** End: class snap_test_helper *****************************/
189
190 TEST_CASE("MC::Snapshot: A copy/snapshot of a given memory region", "MC::Snapshot")
191 {
192   auto sparse = GENERATE(false, true);
193
194   if (sparse) {
195     INFO("Sparse snapshot (using pages)");
196   } else {
197     INFO("Flat snapshot (no pages)");
198   }
199
200   snap_test_helper::Init(sparse);
201
202   INFO("Read whole region");
203   snap_test_helper::read_whole_region();
204
205   INFO("Read region parts");
206   snap_test_helper::read_region_parts();
207
208   INFO("Compare whole region");
209   snap_test_helper::compare_whole_region();
210
211   INFO("Compare region parts");
212   snap_test_helper::compare_region_parts();
213
214   INFO("Read pointer");
215   snap_test_helper::read_pointer();
216
217   snap_test_helper::cleanup();
218 }