/* * flow.cpp * * This source file is part of the FoundationDB open source project * * Copyright 2013-2018 Apple Inc. and the FoundationDB project authors * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "flow.h" #include INetwork *g_network = 0; IRandom *g_random = 0; IRandom *g_nondeterministic_random = 0; IRandom *g_debug_random = 0; FILE* randLog = 0; uint64_t debug_lastLoadBalanceResultEndpointToken = 0; bool noUnseed = false; std::string UID::toString() const { return format("%016llx%016llx", part[0], part[1]); } UID UID::fromString( std::string const& s ) { ASSERT( s.size() == 32 ); uint64_t a=0, b=0; int r = sscanf( s.c_str(), "%16llx%16llx", &a, &b ); ASSERT( r == 2 ); return UID(a, b); } std::string UID::shortString() const { return format("%016llx", part[0]); } void detectFailureAfter( int const& address, double const& delay ); std::string format( const char* form, ... ) { char buf[200]; va_list args; va_start(args, form); int size = vsnprintf(buf, sizeof(buf), form, args); va_end(args); if(size >= 0 && size < sizeof(buf)) { return std::string(buf, size); } #ifdef _WIN32 // Microsoft's non-standard vsnprintf doesn't return a correct size, but just an error, so determine the necessary size va_start(args, form); size = _vscprintf(form, args); va_end(args); #endif if (size < 0) throw internal_error(); TEST(true); //large format result std::string s; s.resize(size + 1); va_start(args, form); size = vsnprintf(&s[0], s.size(), form, args); va_end(args); if (size < 0 || size >= s.size()) throw internal_error(); s.resize(size); return s; } Standalone strinc(StringRef const& str) { int index; for(index = str.size() - 1; index >= 0; index--) if(str[index] != 255) break; // Must not be called with a string that consists only of zero or more '\xff' bytes. ASSERT(index >= 0); Standalone r = str.substr(0, index+1); uint8_t *p = mutateString(r); p[r.size()-1]++; return r; } StringRef strinc(StringRef const& str, Arena& arena) { int index; for(index = str.size() - 1; index >= 0; index--) if(str[index] != 255) break; // Must not be called with a string that consists only of zero or more '\xff' bytes. ASSERT(index >= 0); StringRef r( arena, str.substr(0, index+1) ); uint8_t *p = mutateString(r); p[r.size()-1]++; return r; } bool buggifyActivated = false; std::map, int> SBVars; double P_BUGGIFIED_SECTION_ACTIVATED = .25, P_BUGGIFIED_SECTION_FIRES = .25, P_EXPENSIVE_VALIDATION = .05; int getSBVar(std::string file, int line){ if (!buggifyActivated) return 0; const auto &flPair = std::make_pair(file, line); if (!SBVars.count(flPair)){ SBVars[flPair] = g_random->random01() < P_BUGGIFIED_SECTION_ACTIVATED; g_traceBatch.addBuggify( SBVars[flPair], line, file ); if( g_network ) g_traceBatch.dump(); } return SBVars[flPair]; } bool validationIsEnabled() { return buggifyActivated; } void enableBuggify( bool enabled ) { buggifyActivated = enabled; }