1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
14 // This is only set from db_stress.cc and for testing only.
15 // If non-zero, kill at various points in source code with probability 1/this
16 extern int rocksdb_kill_odds
;
17 // If kill point has a prefix on this list, will skip killing.
18 extern std::vector
<std::string
> rocksdb_kill_prefix_blacklist
;
21 // empty in release build
22 #define TEST_KILL_RANDOM(kill_point, rocksdb_kill_odds)
26 // Kill the process with probability 1/odds for testing.
27 extern void TestKillRandom(std::string kill_point
, int odds
,
28 const std::string
& srcfile
, int srcline
);
30 // To avoid crashing always at some frequently executed codepaths (during
31 // kill random test), use this factor to reduce odds
33 #define REDUCE_ODDS2 4
35 #define TEST_KILL_RANDOM(kill_point, rocksdb_kill_odds) \
37 if (rocksdb_kill_odds > 0) { \
38 TestKillRandom(kill_point, rocksdb_kill_odds, __FILE__, __LINE__); \
41 } // namespace rocksdb
45 #define TEST_SYNC_POINT(x)
46 #define TEST_IDX_SYNC_POINT(x, index)
47 #define TEST_SYNC_POINT_CALLBACK(x, y)
48 #define INIT_SYNC_POINT_SINGLETONS()
53 // This class provides facility to reproduce race conditions deterministically
55 // Developer could specify sync points in the codebase via TEST_SYNC_POINT.
56 // Each sync point represents a position in the execution stream of a thread.
57 // In the unit test, 'Happens After' relationship among sync points could be
58 // setup via SyncPoint::LoadDependency, to reproduce a desired interleave of
60 // Refer to (DBTest,TransactionLogIteratorRace), for an example use case.
64 static SyncPoint
* GetInstance();
66 SyncPoint(const SyncPoint
&) = delete;
67 SyncPoint
& operator=(const SyncPoint
&) = delete;
70 struct SyncPointPair
{
71 std::string predecessor
;
72 std::string successor
;
75 // call once at the beginning of a test to setup the dependency between
77 void LoadDependency(const std::vector
<SyncPointPair
>& dependencies
);
79 // call once at the beginning of a test to setup the dependency between
80 // sync points and setup markers indicating the successor is only enabled
81 // when it is processed on the same thread as the predecessor.
82 // When adding a marker, it implicitly adds a dependency for the marker pair.
83 void LoadDependencyAndMarkers(const std::vector
<SyncPointPair
>& dependencies
,
84 const std::vector
<SyncPointPair
>& markers
);
86 // The argument to the callback is passed through from
87 // TEST_SYNC_POINT_CALLBACK(); nullptr if TEST_SYNC_POINT or
88 // TEST_IDX_SYNC_POINT was used.
89 void SetCallBack(const std::string
& point
,
90 const std::function
<void(void*)>& callback
);
92 // Clear callback function by point
93 void ClearCallBack(const std::string
& point
);
95 // Clear all call back functions.
96 void ClearAllCallBacks();
98 // enable sync point processing (disabled on startup)
99 void EnableProcessing();
101 // disable sync point processing
102 void DisableProcessing();
104 // remove the execution trace of all sync points
107 // triggered by TEST_SYNC_POINT, blocking execution until all predecessors
109 // And/or call registered callback function, with argument `cb_arg`
110 void Process(const std::string
& point
, void* cb_arg
= nullptr);
112 // TODO: it might be useful to provide a function that blocks until all
113 // sync points are cleared.
115 // We want this to be public so we can
116 // subclass the implementation
125 } // namespace rocksdb
127 // Use TEST_SYNC_POINT to specify sync points inside code base.
128 // Sync points can have happens-after depedency on other sync points,
129 // configured at runtime via SyncPoint::LoadDependency. This could be
130 // utilized to re-produce race conditions between threads.
131 // See TransactionLogIteratorRace in db_test.cc for an example use case.
132 // TEST_SYNC_POINT is no op in release build.
133 #define TEST_SYNC_POINT(x) rocksdb::SyncPoint::GetInstance()->Process(x)
134 #define TEST_IDX_SYNC_POINT(x, index) \
135 rocksdb::SyncPoint::GetInstance()->Process(x + std::to_string(index))
136 #define TEST_SYNC_POINT_CALLBACK(x, y) \
137 rocksdb::SyncPoint::GetInstance()->Process(x, y)
138 #define INIT_SYNC_POINT_SINGLETONS() \
139 (void)rocksdb::SyncPoint::GetInstance();