Bug 1454606 - Test scalar semantics when pending operations are applied. r=Dexter
☠☠ backed out by 032953979332 ☠ ☠
authorJan-Erik Rediger <jrediger@mozilla.com>
Wed, 23 May 2018 12:00:38 +0200
changeset 420523 1df93e12f6ecc7c37633a58694c7b8cecc8a035e
parent 420522 b126c9d96aafd9cf93c49c22d4fb74327a58e4d1
child 420524 bac711e0ab423842e3b4321cb8dcd12dac31e0b1
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);
+}