@@ -651,6 +651,10 @@ class SharedState {
651
651
return start_verify_;
652
652
}
653
653
654
+ void SetVerificationFailure () { verification_failure_.store (true ); }
655
+
656
+ bool HasVerificationFailedYet () { return verification_failure_.load (); }
657
+
654
658
port::Mutex* GetMutexForKey (int cf, long key) {
655
659
return &key_locks_[cf][key >> log2_keys_per_lock_];
656
660
}
@@ -695,6 +699,7 @@ class SharedState {
695
699
bool start_;
696
700
bool start_verify_;
697
701
StressTest* stress_test_;
702
+ std::atomic<bool > verification_failure_;
698
703
699
704
std::vector<std::vector<uint32_t >> values_;
700
705
std::vector<std::vector<port::Mutex>> key_locks_;
@@ -752,7 +757,7 @@ class StressTest {
752
757
delete filter_policy_;
753
758
}
754
759
755
- void Run () {
760
+ bool Run () {
756
761
PrintEnv ();
757
762
Open ();
758
763
SharedState shared (this );
@@ -814,6 +819,12 @@ class StressTest {
814
819
FLAGS_env->TimeToString ((uint64_t ) now/1000000 ).c_str ());
815
820
}
816
821
PrintStatistics ();
822
+
823
+ if (shared.HasVerificationFailedYet ()) {
824
+ printf (" Verification failed :(\n " );
825
+ return false ;
826
+ }
827
+ return true ;
817
828
}
818
829
819
830
private:
@@ -1101,7 +1112,10 @@ class StressTest {
1101
1112
1102
1113
thread->stats .Start ();
1103
1114
for (uint64_t i = 0 ; i < FLAGS_ops_per_thread; i++) {
1104
- if (i != 0 && (i % (FLAGS_ops_per_thread / (FLAGS_reopen + 1 ))) == 0 ) {
1115
+ if (thread->shared ->HasVerificationFailedYet ()) {
1116
+ break ;
1117
+ }
1118
+ if (i != 0 && (i % (FLAGS_ops_per_thread / (FLAGS_reopen + 1 ))) == 0 ) {
1105
1119
{
1106
1120
thread->stats .FinishedSingleOp ();
1107
1121
MutexLock l (thread->shared ->GetMutex ());
@@ -1211,8 +1225,10 @@ class StressTest {
1211
1225
std::string keystr2 = Key (rand_key);
1212
1226
Slice k = keystr2;
1213
1227
Status s = db_->Get (read_opts, column_family, k, &from_db);
1214
- VerifyValue (rand_column_family, rand_key, read_opts,
1215
- *(thread->shared ), from_db, s, true );
1228
+ if (VerifyValue (rand_column_family, rand_key, read_opts,
1229
+ thread->shared , from_db, s, true ) == false ) {
1230
+ break ;
1231
+ }
1216
1232
}
1217
1233
thread->shared ->Put (rand_column_family, rand_key, value_base);
1218
1234
if (FLAGS_use_merge) {
@@ -1246,22 +1262,28 @@ class StressTest {
1246
1262
1247
1263
void VerifyDb (ThreadState* thread) const {
1248
1264
ReadOptions options (FLAGS_verify_checksum, true );
1249
- const SharedState& shared = *( thread->shared ) ;
1250
- static const long max_key = shared. GetMaxKey ();
1251
- static const long keys_per_thread = max_key / shared. GetNumThreads ();
1265
+ auto shared = thread->shared ;
1266
+ static const long max_key = shared-> GetMaxKey ();
1267
+ static const long keys_per_thread = max_key / shared-> GetNumThreads ();
1252
1268
long start = keys_per_thread * thread->tid ;
1253
1269
long end = start + keys_per_thread;
1254
- if (thread->tid == shared. GetNumThreads () - 1 ) {
1270
+ if (thread->tid == shared-> GetNumThreads () - 1 ) {
1255
1271
end = max_key;
1256
1272
}
1257
1273
for (size_t cf = 0 ; cf < column_families_.size (); ++cf) {
1274
+ if (thread->shared ->HasVerificationFailedYet ()) {
1275
+ break ;
1276
+ }
1258
1277
if (!thread->rand .OneIn (2 )) {
1259
1278
// Use iterator to verify this range
1260
1279
options.prefix_seek = FLAGS_prefix_size > 0 ;
1261
1280
unique_ptr<Iterator> iter (
1262
1281
db_->NewIterator (options, column_families_[cf]));
1263
1282
iter->Seek (Key (start));
1264
1283
for (long i = start; i < end; i++) {
1284
+ if (thread->shared ->HasVerificationFailedYet ()) {
1285
+ break ;
1286
+ }
1265
1287
// TODO(ljin): update "long" to uint64_t
1266
1288
// Reseek when the prefix changes
1267
1289
if (i % (static_cast <int64_t >(1 ) << 8 * (8 - FLAGS_prefix_size)) ==
@@ -1279,7 +1301,7 @@ class StressTest {
1279
1301
from_db = iter->value ().ToString ();
1280
1302
iter->Next ();
1281
1303
} else if (iter->key ().compare (k) < 0 ) {
1282
- VerificationAbort (" An out of range key was found" , cf, i);
1304
+ VerificationAbort (shared, " An out of range key was found" , cf, i);
1283
1305
}
1284
1306
} else {
1285
1307
// The iterator found no value for the key in question, so do not
@@ -1294,6 +1316,9 @@ class StressTest {
1294
1316
} else {
1295
1317
// Use Get to verify this range
1296
1318
for (long i = start; i < end; i++) {
1319
+ if (thread->shared ->HasVerificationFailedYet ()) {
1320
+ break ;
1321
+ }
1297
1322
std::string from_db;
1298
1323
std::string keystr = Key (i);
1299
1324
Slice k = keystr;
@@ -1307,38 +1332,48 @@ class StressTest {
1307
1332
}
1308
1333
}
1309
1334
1310
- void VerificationAbort (std::string msg, int cf, long key) const {
1311
- fprintf (stderr, " Verification failed for column family %d key %ld: %s\n " ,
1312
- cf, key, msg.c_str ());
1313
- exit (1 );
1335
+ void VerificationAbort (SharedState* shared, std::string msg, int cf,
1336
+ long key) const {
1337
+ printf (" Verification failed for column family %d key %ld: %s\n " , cf, key,
1338
+ msg.c_str ());
1339
+ shared->SetVerificationFailure ();
1314
1340
}
1315
1341
1316
- void VerifyValue (int cf, long key, const ReadOptions& opts,
1317
- const SharedState& shared, const std::string& value_from_db,
1342
+ bool VerifyValue (int cf, long key, const ReadOptions& opts,
1343
+ SharedState* shared, const std::string& value_from_db,
1318
1344
Status s, bool strict = false ) const {
1345
+ if (shared->HasVerificationFailedYet ()) {
1346
+ return false ;
1347
+ }
1319
1348
// compare value_from_db with the value in the shared state
1320
1349
char value[100 ];
1321
- uint32_t value_base = shared. Get (cf, key);
1350
+ uint32_t value_base = shared-> Get (cf, key);
1322
1351
if (value_base == SharedState::SENTINEL && !strict) {
1323
- return ;
1352
+ return true ;
1324
1353
}
1325
1354
1326
1355
if (s.ok ()) {
1327
1356
if (value_base == SharedState::SENTINEL) {
1328
- VerificationAbort (" Unexpected value found" , cf, key);
1357
+ VerificationAbort (shared, " Unexpected value found" , cf, key);
1358
+ return false ;
1329
1359
}
1330
1360
size_t sz = GenerateValue (value_base, value, sizeof (value));
1331
1361
if (value_from_db.length () != sz) {
1332
- VerificationAbort (" Length of value read is not equal" , cf, key);
1362
+ VerificationAbort (shared, " Length of value read is not equal" , cf, key);
1363
+ return false ;
1333
1364
}
1334
1365
if (memcmp (value_from_db.data (), value, sz) != 0 ) {
1335
- VerificationAbort (" Contents of value read don't match" , cf, key);
1366
+ VerificationAbort (shared, " Contents of value read don't match" , cf,
1367
+ key);
1368
+ return false ;
1336
1369
}
1337
1370
} else {
1338
1371
if (value_base != SharedState::SENTINEL) {
1339
- VerificationAbort (" Value not found" , cf, key);
1372
+ VerificationAbort (shared, " Value not found: " + s.ToString (), cf, key);
1373
+ return false ;
1340
1374
}
1341
1375
}
1376
+ return true ;
1342
1377
}
1343
1378
1344
1379
static void PrintKeyValue (int cf, uint32_t key, const char * value,
@@ -1693,6 +1728,9 @@ int main(int argc, char** argv) {
1693
1728
}
1694
1729
1695
1730
rocksdb::StressTest stress;
1696
- stress.Run ();
1697
- return 0 ;
1731
+ if (stress.Run ()) {
1732
+ return 0 ;
1733
+ } else {
1734
+ return 1 ;
1735
+ }
1698
1736
}
0 commit comments