Bug 1454606 - Test scalar semantics when pending operations are applied. r=Dexter
☠☠ backed out by 324e22546444 ☠ ☠
authorJan-Erik Rediger <jrediger@mozilla.com>
Wed, 23 May 2018 12:00:38 +0200
changeset 420511 114fd49040b6bbbb3262fb3459188d903337b5b0
parent 420510 2889aa95e455370a18a634bbaa2af6c1bb77f147
child 420512 6be2c9f129c9966e7ee1cd489a534754362ac662
push id103828
push useraiakab@mozilla.com
push dateWed, 30 May 2018 22:08:58 +0000
treeherdermozilla-inbound@8d0ee6e73fb3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersDexter
bugs1454606
milestone62.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1454606 - Test scalar semantics when pending operations are applied. r=Dexter MozReview-Commit-ID: KXzuIHaBbIb
toolkit/components/telemetry/geckoview/gtest/TestGeckoView.cpp
--- a/toolkit/components/telemetry/geckoview/gtest/TestGeckoView.cpp
+++ b/toolkit/components/telemetry/geckoview/gtest/TestGeckoView.cpp
@@ -470,8 +470,178 @@ TEST_F(TelemetryGeckoViewFixture, TimerH
 
   // Verify that the scalars were correctly persisted and restored.
   CheckUintScalar("telemetry.persistence_timer_hit_count", cx.GetJSContext(),
                   scalarsSnapshot, 2);
 
   // Cleanup/remove the files.
   RemovePersistenceFile();
 }
+
+TEST_F(TelemetryGeckoViewFixture, EmptyPendingOperations) {
+  AutoJSContextWithGlobal cx(mCleanGlobal);
+
+  Unused << mTelemetry->ClearScalars();
+
+  // Force loading mode
+  TelemetryScalar::DeserializationStarted();
+
+  // Do nothing explicitely
+
+  // Force pending operations to be applied and end load mode.
+  // It should not crash and don't change any scalars.
+  TelemetryScalar::ApplyPendingOperations();
+
+  // Check that the snapshot is empty
+  JS::RootedValue scalarsSnapshot(cx.GetJSContext());
+  GetScalarsSnapshot(false, cx.GetJSContext(), &scalarsSnapshot);
+
+  JS::RootedObject scalarsSnapshotObj(cx.GetJSContext(), &scalarsSnapshot.toObject());
+  ASSERT_TRUE(scalarsSnapshot.isUndefined()) << "Scalars snapshot should not contain any data.";
+}
+
+TEST_F(TelemetryGeckoViewFixture, SimpleAppendOperation) {
+  AutoJSContextWithGlobal cx(mCleanGlobal);
+
+  Unused << mTelemetry->ClearScalars();
+
+  // Set an initial value, so we can test that it is not overwritten.
+  uint32_t initialValue = 1;
+  Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_UNSIGNED_INT_KIND, initialValue);
+
+  // Force loading mode
+  TelemetryScalar::DeserializationStarted();
+
+  // Add to a scalar
+  uint32_t value = 37;
+  Telemetry::ScalarAdd(Telemetry::ScalarID::TELEMETRY_TEST_UNSIGNED_INT_KIND, value);
+
+  // Verify that this was not yet applied.
+  JS::RootedValue scalarsSnapshot(cx.GetJSContext());
+  GetScalarsSnapshot(false, cx.GetJSContext(), &scalarsSnapshot);
+
+  CheckUintScalar("telemetry.test.unsigned_int_kind", cx.GetJSContext(), scalarsSnapshot, initialValue);
+
+  // Force pending operations to be applied and end load mode
+  TelemetryScalar::ApplyPendingOperations();
+
+  // Verify recorded operations are applied
+  GetScalarsSnapshot(false, cx.GetJSContext(), &scalarsSnapshot);
+  CheckUintScalar("telemetry.test.unsigned_int_kind", cx.GetJSContext(), scalarsSnapshot, initialValue+value);
+}
+
+TEST_F(TelemetryGeckoViewFixture, ApplyPendingOperationsAfterLoad) {
+  AutoJSContextWithGlobal cx(mCleanGlobal);
+
+  Unused << mTelemetry->ClearScalars();
+
+  const char persistedData[] = R"({
+ "scalars": {
+  "parent": {
+   "telemetry.test.unsigned_int_kind": 14
+  }
+ }
+})";
+
+  // Force loading mode
+  TelemetryScalar::DeserializationStarted();
+
+  // Add to a scalar, this should be recorded
+  uint32_t addValue = 10;
+  Telemetry::ScalarAdd(Telemetry::ScalarID::TELEMETRY_TEST_UNSIGNED_INT_KIND, addValue);
+
+  // Load persistence file
+  RefPtr<DataLoadedObserver> loadingFinished = new DataLoadedObserver();
+  WritePersistenceFile(nsDependentCString(persistedData));
+  TelemetryGeckoViewPersistence::InitPersistence();
+  loadingFinished->WaitForNotification();
+
+  // At this point all pending operations should have been applied.
+
+  // Increment again, now directly applied
+  uint32_t val = 1;
+  Telemetry::ScalarAdd(Telemetry::ScalarID::TELEMETRY_TEST_UNSIGNED_INT_KIND, val);
+
+
+  JS::RootedValue scalarsSnapshot(cx.GetJSContext());
+  GetScalarsSnapshot(false, cx.GetJSContext(), &scalarsSnapshot);
+
+  uint32_t expectedValue = 25;
+  CheckUintScalar("telemetry.test.unsigned_int_kind", cx.GetJSContext(), scalarsSnapshot, expectedValue);
+}
+
+TEST_F(TelemetryGeckoViewFixture, MultipleAppendOperations) {
+  AutoJSContextWithGlobal cx(mCleanGlobal);
+
+  Unused << mTelemetry->ClearScalars();
+
+  // Force loading mode
+  TelemetryScalar::DeserializationStarted();
+
+  // Modify all kinds of scalars
+  uint32_t startValue = 35;
+  uint32_t expectedValue = 40;
+  Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_UNSIGNED_INT_KIND, startValue);
+  Telemetry::ScalarSetMaximum(Telemetry::ScalarID::TELEMETRY_TEST_UNSIGNED_INT_KIND, startValue + 2);
+  Telemetry::ScalarAdd(Telemetry::ScalarID::TELEMETRY_TEST_UNSIGNED_INT_KIND, 3);
+
+  Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_BOOLEAN_KIND, true);
+  Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_STRING_KIND, NS_LITERAL_STRING("Star Wars VI"));
+
+  // Modify all kinds of keyed scalars
+  Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_KEYED_UNSIGNED_INT,
+      NS_LITERAL_STRING("chewbacca"), startValue);
+  Telemetry::ScalarSetMaximum(Telemetry::ScalarID::TELEMETRY_TEST_KEYED_UNSIGNED_INT,
+      NS_LITERAL_STRING("chewbacca"), startValue + 2);
+  Telemetry::ScalarAdd(Telemetry::ScalarID::TELEMETRY_TEST_KEYED_UNSIGNED_INT,
+      NS_LITERAL_STRING("chewbacca"), 3);
+
+  Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_KEYED_BOOLEAN_KIND,
+      NS_LITERAL_STRING("chewbacca"),
+      true);
+
+  // Force pending operations to be applied and end load mode
+  TelemetryScalar::ApplyPendingOperations();
+
+  JS::RootedValue scalarsSnapshot(cx.GetJSContext());
+  JS::RootedValue keyedScalarsSnapshot(cx.GetJSContext());
+  GetScalarsSnapshot(false, cx.GetJSContext(), &scalarsSnapshot);
+  GetScalarsSnapshot(true, cx.GetJSContext(), &keyedScalarsSnapshot);
+
+  CheckUintScalar("telemetry.test.unsigned_int_kind", cx.GetJSContext(), scalarsSnapshot, expectedValue);
+  CheckBoolScalar("telemetry.test.boolean_kind", cx.GetJSContext(), scalarsSnapshot, true);
+  CheckStringScalar("telemetry.test.string_kind", cx.GetJSContext(), scalarsSnapshot, "Star Wars VI");
+
+  CheckKeyedUintScalar("telemetry.test.keyed_unsigned_int", "chewbacca",
+      cx.GetJSContext(), keyedScalarsSnapshot, expectedValue);
+  CheckKeyedBoolScalar("telemetry.test.keyed_boolean_kind", "chewbacca",
+      cx.GetJSContext(), keyedScalarsSnapshot, true);
+}
+
+TEST_F(TelemetryGeckoViewFixture, PendingOperationsHighWater) {
+  AutoJSContextWithGlobal cx(mCleanGlobal);
+
+  Unused << mTelemetry->ClearScalars();
+
+  uint32_t initialValue = 0;
+  Telemetry::ScalarSet(Telemetry::ScalarID::TELEMETRY_TEST_UNSIGNED_INT_KIND, initialValue);
+
+  // Force loading mode
+  TelemetryScalar::DeserializationStarted();
+
+  // Fill up the pending operations list
+  uint32_t expectedValue = 10000;
+  for (uint32_t i=0; i < expectedValue; i++) {
+    Telemetry::ScalarAdd(Telemetry::ScalarID::TELEMETRY_TEST_UNSIGNED_INT_KIND, 1);
+  }
+
+  // Nothing should be applied yet
+  JS::RootedValue scalarsSnapshot(cx.GetJSContext());
+  GetScalarsSnapshot(false, cx.GetJSContext(), &scalarsSnapshot);
+  CheckUintScalar("telemetry.test.unsigned_int_kind", cx.GetJSContext(), scalarsSnapshot, 0);
+
+  // Spill over the buffer to immediately apply all operations
+  Telemetry::ScalarAdd(Telemetry::ScalarID::TELEMETRY_TEST_UNSIGNED_INT_KIND, 1);
+
+  // Now we should see all values
+  GetScalarsSnapshot(false, cx.GetJSContext(), &scalarsSnapshot);
+  CheckUintScalar("telemetry.test.unsigned_int_kind", cx.GetJSContext(), scalarsSnapshot, expectedValue+1);
+}