@@ -41,7 +41,7 @@ class RpcFailureThresholdTest
4141 google::cloud::internal::GetEnv (" GOOGLE_CLOUD_PROJECT" ).value_or (" " );
4242 ASSERT_FALSE (project_id.empty ());
4343
44- generator_ = google::cloud::internal::MakeDefaultPRNG ( );
44+ generator_ = google::cloud::internal::DefaultPRNG (std::random_device{}() );
4545 auto instance_id =
4646 spanner_testing::PickRandomInstance (generator_, project_id);
4747 ASSERT_STATUS_OK (instance_id);
@@ -81,9 +81,8 @@ class RpcFailureThresholdTest
8181 }
8282
8383 void TearDown () override {
84- if (!db_) {
85- return ;
86- }
84+ if (!db_) return ;
85+
8786 std::cout << " Dropping database " << db_->database_id () << std::flush;
8887 spanner_admin::DatabaseAdminClient admin_client (
8988 spanner_admin::MakeDatabaseAdminConnection ());
@@ -102,6 +101,8 @@ struct Result {
102101 int number_of_failures;
103102};
104103
104+ auto constexpr kReportCount = 5 ;
105+
105106// / Run a single copy of the experiment
106107Result RunExperiment (Database const & db, int iterations) {
107108 // Use a different client on each thread because we do not want to share
@@ -129,7 +130,7 @@ Result RunExperiment(Database const& db, int iterations) {
129130 }
130131 };
131132
132- int const report = iterations / 5 ;
133+ int const report = iterations / kReportCount ;
133134 for (int i = 0 ; i != iterations; ++i) {
134135 if (i % report == 0 ) std::cout << ' .' << std::flush;
135136 auto delete_status =
@@ -163,7 +164,7 @@ Result RunExperiment(Database const& db, int iterations) {
163164 * If the confidence interval includes a critical threshold (0.999) then the
164165 * program fails, claiming that the underlying error rate may be too high.
165166 *
166- * The number of iteration in the program was chosen to the statistical test
167+ * The number of iteration in the program was chosen so the statistical test
167168 * would have 0.99 power. That is, the test would miss an actual change from
168169 * 0.001 to 0.002 only 1% of the time.
169170 *
@@ -173,6 +174,10 @@ Result RunExperiment(Database const& db, int iterations) {
173174 */
174175TEST_F (RpcFailureThresholdTest, ExecuteDmlDeleteErrors) {
175176 ASSERT_TRUE (db_);
177+ // When using the emulator there is not much value in this test, we still run
178+ // it just to get the code coverage.
179+ auto const emulator =
180+ google::cloud::internal::GetEnv (" SPANNER_EMULATOR_HOST" ).has_value ();
176181
177182 // We are using the approximation via a normal distribution from here:
178183 // https://en.wikipedia.org/wiki/Binomial_proportion_confidence_interval
@@ -193,8 +198,8 @@ TEST_F(RpcFailureThresholdTest, ExecuteDmlDeleteErrors) {
193198 // ```R
194199 // require(pwr)
195200 // pwr.p.test(
196- // h=ES.h(p1=0.002 , p2=0.001 ),
197- // power=0.99 , sig.level=0.01, alternative="greater")
201+ // h=ES.h(p1=0.001 , p2=0.0001 ),
202+ // power=0.95 , sig.level=0.01, alternative="greater")
198203 // proportion power calculation for binomial distribution
199204 // (arcsine transformation)
200205 //
@@ -214,15 +219,20 @@ TEST_F(RpcFailureThresholdTest, ExecuteDmlDeleteErrors) {
214219
215220 int const desired_samples = 32000 ; // slightly higher sample rate.
216221
217- auto const threads_per_core = 8 ;
218- // GCC and Clang default capture constants, but MSVC does not, so pass the
219- // constant as an argument.
220- auto const number_of_threads = [](int tpc) -> unsigned {
222+ auto constexpr kMinThreads = 8 ;
223+ auto const number_of_threads = [&] {
221224 auto number_of_cores = std::thread::hardware_concurrency ();
222- return number_of_cores == 0 ? tpc : number_of_cores * tpc ;
223- }(threads_per_core );
225+ return number_of_cores == 0 ? kMinThreads : number_of_cores;
226+ }();
224227
225- auto const iterations = static_cast <int >(desired_samples / number_of_threads);
228+ // When using the emulator we run the minimal number of iterations needed to
229+ // ensure the code does not rot. Otherwise, we run the same number of
230+ // iterations in each thread, such that the total number of "samples" matches
231+ // the `desired_samples. We are a bit sloppy and add 1 to account for
232+ // truncation, running an extra iteration won't hurt.
233+ auto const iterations = std::max (
234+ kReportCount , // minimum value that does not crash
235+ emulator ? 1 : static_cast <int >(desired_samples / number_of_threads) + 1 );
226236
227237 int number_of_successes = 0 ;
228238 int number_of_failures = 0 ;
@@ -250,12 +260,13 @@ TEST_F(RpcFailureThresholdTest, ExecuteDmlDeleteErrors) {
250260 << " \n Estimated 99% confidence interval for success rate is ["
251261 << (mid - r) << " ," << (mid + r) << " ]\n " ;
252262
263+ if (emulator) return ;
253264 EXPECT_GT (mid - r, 1.0 - threshold)
254265 << " number_of_failures=" << number_of_failures
255266 << " , number_of_successes=" << number_of_successes
256267 << " , number_of_trials=" << number_of_trials << " , mid=" << mid
257268 << " , r=" << r << " , range=[ " << (mid - r) << " , " << (mid + r) << " ]"
258- << " , kTheshold =" << threshold;
269+ << " , kThreshold =" << threshold;
259270}
260271
261272} // namespace
0 commit comments