Bug 1286798 - Part 20: Add checks for the 5 MB origin limit; r=asuth
authorJan Varga <jan.varga@gmail.com>
Thu, 29 Nov 2018 21:48:19 +0100
changeset 505238 615640a58a97fdf95584df9222358ff0372ad31d
parent 505237 5714205a7bf9ea1083a7c24f18b188d8304679cd
child 505239 bb3a3cc424cd000e8bb198ae47259d3e751cc3bd
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersasuth
bugs1286798
milestone65.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 1286798 - Part 20: Add checks for the 5 MB origin limit; r=asuth The 5 MB limit is no longer applied to the whole group (eTLD+1). That will be controlled by quota manager.
dom/localstorage/ActorsParent.cpp
dom/tests/mochitest/localstorage/chrome.ini
dom/tests/mochitest/localstorage/frameQuota.html
dom/tests/mochitest/localstorage/frameQuotaSessionOnly.html
dom/tests/mochitest/localstorage/mochitest.ini
dom/tests/mochitest/localstorage/test_localStorageQuota.html
dom/tests/mochitest/localstorage/test_localStorageQuotaPrivateBrowsing_perwindowpb.html
testing/web-platform/meta/webstorage/storage_local_setitem_quotaexceedederr.html.ini
--- a/dom/localstorage/ActorsParent.cpp
+++ b/dom/localstorage/ActorsParent.cpp
@@ -7,16 +7,17 @@
 #include "ActorsParent.h"
 
 #include "LocalStorageCommon.h"
 #include "LSObject.h"
 #include "mozIStorageConnection.h"
 #include "mozIStorageService.h"
 #include "mozStorageCID.h"
 #include "mozStorageHelper.h"
+#include "mozilla/Preferences.h"
 #include "mozilla/Unused.h"
 #include "mozilla/dom/PBackgroundLSDatabaseParent.h"
 #include "mozilla/dom/PBackgroundLSObjectParent.h"
 #include "mozilla/dom/PBackgroundLSObserverParent.h"
 #include "mozilla/dom/PBackgroundLSRequestParent.h"
 #include "mozilla/dom/PBackgroundLSSharedTypes.h"
 #include "mozilla/dom/PBackgroundLSSimpleRequestParent.h"
 #include "mozilla/dom/quota/QuotaManager.h"
@@ -103,16 +104,19 @@ static_assert(kSQLiteGrowthIncrement >= 
 
 #define DATA_FILE_NAME "data.sqlite"
 #define JOURNAL_FILE_NAME "data.sqlite-journal"
 
 const uint32_t kAutoCommitTimeoutMs = 5000;
 
 const char kPrivateBrowsingObserverTopic[] = "last-pb-context-exited";
 
+const uint32_t kDefaultOriginLimitKB = 5 * 1024;
+const char kDefaultQuotaPref[] = "dom.storage.default_quota";
+
 bool
 IsOnConnectionThread();
 
 void
 AssertIsOnConnectionThread();
 
 /*******************************************************************************
  * SQLite functions
@@ -855,22 +859,24 @@ class Datastore final
   RefPtr<DirectoryLock> mDirectoryLock;
   RefPtr<Connection> mConnection;
   nsCOMPtr<nsITimer> mAutoCommitTimer;
   nsCOMPtr<nsIRunnable> mCompleteCallback;
   nsTHashtable<nsPtrHashKey<Database>> mDatabases;
   nsDataHashtable<nsStringHashKey, nsString> mValues;
   const nsCString mOrigin;
   const uint32_t mPrivateBrowsingId;
+  int64_t mUsage;
   bool mClosed;
 
 public:
   // Created by PrepareDatastoreOp.
   Datastore(const nsACString& aOrigin,
             uint32_t aPrivateBrowsingId,
+            int64_t aUsage,
             already_AddRefed<DirectoryLock>&& aDirectoryLock,
             already_AddRefed<Connection>&& aConnection,
             nsDataHashtable<nsStringHashKey, nsString>& aValues);
 
   const nsCString&
   Origin() const
   {
     return mOrigin;
@@ -945,16 +951,19 @@ private:
   ~Datastore();
 
   void
   ConnectionClosedCallback();
 
   void
   CleanupMetadata();
 
+  bool
+  UpdateUsage(int64_t aDelta);
+
   void
   NotifyObservers(Database* aDatabase,
                   const nsString& aKey,
                   const nsString& aOldValue,
                   const nsString& aNewValue);
 
   void
   EnsureTransaction();
@@ -1342,16 +1351,17 @@ class PrepareDatastoreOp
   nsDataHashtable<nsStringHashKey, nsString> mValues;
   const LSRequestPrepareDatastoreParams mParams;
   nsCString mSuffix;
   nsCString mGroup;
   nsCString mMainThreadOrigin;
   nsCString mOrigin;
   nsString mDatabaseFilePath;
   uint32_t mPrivateBrowsingId;
+  int64_t mUsage;
   NestedState mNestedState;
   bool mRequestedDirectoryLock;
   bool mInvalidated;
 
 public:
   PrepareDatastoreOp(nsIEventTarget* aMainEventTarget,
                      const LSRequestParams& aParams);
 
@@ -1728,16 +1738,18 @@ typedef nsRefPtrHashtable<nsUint64HashKe
 
 StaticAutoPtr<PreparedObserverHashtable> gPreparedObsevers;
 
 typedef nsClassHashtable<nsCStringHashKey, nsTArray<Observer*>>
   ObserverHashtable;
 
 StaticAutoPtr<ObserverHashtable> gObservers;
 
+Atomic<uint32_t, Relaxed> gOriginLimitKB(kDefaultOriginLimitKB);
+
 bool
 IsOnConnectionThread()
 {
   MOZ_ASSERT(gConnectionThread);
   return gConnectionThread->IsOnConnectionThread();
 }
 
 void
@@ -2522,23 +2534,25 @@ ClearOp::DoDatastoreWork()
 }
 
 /*******************************************************************************
  * Datastore
  ******************************************************************************/
 
 Datastore::Datastore(const nsACString& aOrigin,
                      uint32_t aPrivateBrowsingId,
+                     int64_t aUsage,
                      already_AddRefed<DirectoryLock>&& aDirectoryLock,
                      already_AddRefed<Connection>&& aConnection,
                      nsDataHashtable<nsStringHashKey, nsString>& aValues)
   : mDirectoryLock(std::move(aDirectoryLock))
   , mConnection(std::move(aConnection))
   , mOrigin(aOrigin)
   , mPrivateBrowsingId(aPrivateBrowsingId)
+  , mUsage(aUsage)
   , mClosed(false)
 {
   AssertIsOnBackgroundThread();
 
   mValues.SwapElements(aValues);
 }
 
 Datastore::~Datastore()
@@ -2687,16 +2701,30 @@ Datastore::SetItem(Database* aDatabase,
   }
 
   bool changed;
   if (oldValue == aValue && oldValue.IsVoid() == aValue.IsVoid()) {
     changed = false;
   } else {
     changed = true;
 
+    int64_t delta = 0;
+
+    if (oldValue.IsVoid()) {
+      delta += static_cast<int64_t>(aKey.Length());
+    }
+
+    delta += static_cast<int64_t>(aValue.Length()) -
+             static_cast<int64_t>(oldValue.Length());
+
+    if (!UpdateUsage(delta)) {
+      aResponse = NS_ERROR_FILE_NO_DEVICE_SPACE;
+      return;
+    }
+
     mValues.Put(aKey, aValue);
 
     NotifyObservers(aDatabase, aKey, oldValue, aValue);
 
     if (IsPersistent()) {
       EnsureTransaction();
 
       RefPtr<SetItemOp> op = new SetItemOp(mConnection, aKey, aValue);
@@ -2722,16 +2750,22 @@ Datastore::RemoveItem(Database* aDatabas
   bool changed;
   nsString oldValue;
   if (!mValues.Get(aKey, &oldValue)) {
     oldValue.SetIsVoid(true);
     changed = false;
   } else {
     changed = true;
 
+    int64_t delta = -(static_cast<int64_t>(aKey.Length()) +
+                      static_cast<int64_t>(oldValue.Length()));
+
+    DebugOnly<bool> ok = UpdateUsage(delta);
+    MOZ_ASSERT(ok);
+
     mValues.Remove(aKey);
 
     NotifyObservers(aDatabase, aKey, oldValue, VoidString());
 
     if (IsPersistent()) {
       EnsureTransaction();
 
       RefPtr<RemoveItemOp> op = new RemoveItemOp(mConnection, aKey);
@@ -2753,16 +2787,19 @@ Datastore::Clear(Database* aDatabase,
   MOZ_ASSERT(!mClosed);
 
   bool changed;
   if (!mValues.Count()) {
     changed = false;
   } else {
     changed = true;
 
+    DebugOnly<bool> ok = UpdateUsage(-mUsage);
+    MOZ_ASSERT(ok);
+
     mValues.Clear();
 
     if (aDatabase) {
       NotifyObservers(aDatabase, VoidString(), VoidString(), VoidString());
     }
 
     if (IsPersistent()) {
       EnsureTransaction();
@@ -2818,16 +2855,31 @@ Datastore::CleanupMetadata()
   MOZ_ASSERT(gDatastores->Get(mOrigin));
   gDatastores->Remove(mOrigin);
 
   if (!gDatastores->Count()) {
     gDatastores = nullptr;
   }
 }
 
+bool
+Datastore::UpdateUsage(int64_t aDelta)
+{
+  AssertIsOnBackgroundThread();
+
+  int64_t newUsage = mUsage + aDelta;
+  if (newUsage > gOriginLimitKB * 1024) {
+    return false;
+  }
+
+  mUsage = newUsage;
+
+  return true;
+}
+
 void
 Datastore::NotifyObservers(Database* aDatabase,
                            const nsString& aKey,
                            const nsString& aOldValue,
                            const nsString& aNewValue)
 {
   AssertIsOnBackgroundThread();
   MOZ_ASSERT(aDatabase);
@@ -3499,16 +3551,17 @@ LSRequestBase::RecvFinish()
 
 PrepareDatastoreOp::PrepareDatastoreOp(nsIEventTarget* aMainEventTarget,
                                        const LSRequestParams& aParams)
   : LSRequestBase(aMainEventTarget)
   , mMainEventTarget(aMainEventTarget)
   , mLoadDataOp(nullptr)
   , mParams(aParams.get_LSRequestPrepareDatastoreParams())
   , mPrivateBrowsingId(0)
+  , mUsage(0)
   , mNestedState(NestedState::BeforeNesting)
   , mRequestedDirectoryLock(false)
   , mInvalidated(false)
 {
   MOZ_ASSERT(aParams.type() ==
                LSRequestParams::TLSRequestPrepareDatastoreParams);
 }
 
@@ -4009,16 +4062,17 @@ PrepareDatastoreOp::GetResponse(LSReques
 {
   AssertIsOnOwningThread();
   MOZ_ASSERT(mState == State::SendingResults);
   MOZ_ASSERT(NS_SUCCEEDED(ResultCode()));
 
   if (!mDatastore) {
     mDatastore = new Datastore(mOrigin,
                                mPrivateBrowsingId,
+                               mUsage,
                                mDirectoryLock.forget(),
                                mConnection.forget(),
                                mValues);
 
     if (!gDatastores) {
       gDatastores = new DatastoreHashtable();
     }
 
@@ -4220,16 +4274,17 @@ LoadDataOp::DoDatastoreWork()
 
     nsString value;
     rv = stmt->GetString(1, value);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
     mPrepareDatastoreOp->mValues.Put(key, value);
+    mPrepareDatastoreOp->mUsage += key.Length() + value.Length();
   }
   if (NS_WARN_IF(NS_FAILED(rv))) {
     return rv;
   }
 
   return NS_OK;
 }
 
@@ -4570,16 +4625,22 @@ QuotaClient::RegisterObservers(nsIEventT
     nsCOMPtr<nsIObserver> observer = new Observer(aBackgroundEventTarget);
 
     nsresult rv =
       obs->AddObserver(observer, kPrivateBrowsingObserverTopic, false);
     if (NS_WARN_IF(NS_FAILED(rv))) {
       return rv;
     }
 
+    if (NS_FAILED(Preferences::AddAtomicUintVarCache(&gOriginLimitKB,
+                                                     kDefaultQuotaPref,
+                                                     kDefaultOriginLimitKB))) {
+      NS_WARNING("Unable to respond to default quota pref changes!");
+    }
+
     sObserversRegistered = true;
   }
 
   return NS_OK;
 }
 
 nsresult
 QuotaClient::InitOrigin(PersistenceType aPersistenceType,
--- a/dom/tests/mochitest/localstorage/chrome.ini
+++ b/dom/tests/mochitest/localstorage/chrome.ini
@@ -3,9 +3,9 @@ skip-if = os == 'android'
 support-files =
   page_blank.html
   frameQuota.html
   interOriginFrame.js
 
 [test_localStorageBasePrivateBrowsing_perwindowpb.html]
 skip-if = true # bug 1156725
 [test_localStorageFromChrome.xhtml]
-#[test_localStorageQuotaPrivateBrowsing_perwindowpb.html]
+[test_localStorageQuotaPrivateBrowsing_perwindowpb.html]
--- a/dom/tests/mochitest/localstorage/frameQuota.html
+++ b/dom/tests/mochitest/localstorage/frameQuota.html
@@ -39,24 +39,16 @@ function doStep()
           localStorage.setItem(keyName, "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890");
           is(localStorage.getItem(keyName), "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", "500 bytes key "+keyName+" stored");
           break;
 
         case "remove":
           localStorage.removeItem(keyName);
           is(localStorage.getItem(keyName), null, "Key "+keyName+" removed");
           break;
-
-        case "checkclean":
-          is(localStorage.getItem(keyName), null, "Key "+keyName+" not present");
-          break;
-
-        case "checknotclean":
-          is(localStorage.getItem(keyName), "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", "Key "+keyName+" is present");
-          break;
       }
 
       break;
 
     case "failure":
       switch (operation)
       {
         case "add":
--- a/dom/tests/mochitest/localstorage/frameQuotaSessionOnly.html
+++ b/dom/tests/mochitest/localstorage/frameQuotaSessionOnly.html
@@ -39,24 +39,16 @@ function doStep()
           localStorage.setItem(keyName, "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890");
           is(localStorage.getItem(keyName), "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", "500 bytes key "+keyName+" stored");
           break;
 
         case "remove":
           localStorage.removeItem(keyName);
           is(localStorage.getItem(keyName), null, "Key "+keyName+" removed");
           break;
-
-        case "checkclean":
-          is(localStorage.getItem(keyName), null, "Key "+keyName+" not present");
-          break;
-
-        case "checknotclean":
-          is(localStorage.getItem(keyName), "12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890", "Key "+keyName+" is present");
-          break;
       }
 
       break;
 
     case "failure":
       switch (operation)
       {
         case "add":
--- a/dom/tests/mochitest/localstorage/mochitest.ini
+++ b/dom/tests/mochitest/localstorage/mochitest.ini
@@ -35,18 +35,18 @@ skip-if = e10s
 [test_localStorageKeyOrder.html]
 [test_localStorageOriginsDiff.html]
 [test_localStorageOriginsDomainDiffs.html]
 [test_localStorageOriginsEquals.html]
 skip-if = toolkit == 'android'
 [test_localStorageOriginsPortDiffs.html]
 [test_localStorageOriginsSchemaDiffs.html]
 skip-if = toolkit == 'android' #TIMED_OUT
-#[test_localStorageQuota.html]
-#skip-if = toolkit == 'android' #TIMED_OUT
+[test_localStorageQuota.html]
+skip-if = toolkit == 'android' #TIMED_OUT
 [test_localStorageQuotaSessionOnly.html]
 skip-if = toolkit == 'android' || (verify && (os == 'linux' || os == 'mac' || os == 'win')) #TIMED_OUT
 [test_localStorageQuotaSessionOnly2.html]
 skip-if = true # bug 1347690
 [test_localStorageReplace.html]
 skip-if = toolkit == 'android'
 [test_storageConstructor.html]
 [test_localStorageSessionPrefOverride.html]
--- a/dom/tests/mochitest/localstorage/test_localStorageQuota.html
+++ b/dom/tests/mochitest/localstorage/test_localStorageQuota.html
@@ -13,22 +13,25 @@ var currentTest = 1;
 
 function doNextTest()
 {
   slave = frame;
 
   switch (currentTest)
   {
     case 1:
-      slaveOrigin = "http://example.com";
+      if (SpecialPowers.Services.lsm.nextGenLocalStorageEnabled) {
+        slaveOrigin = "http://test1.example.com";
+      } else {
+        slaveOrigin = "http://example.com";
+      }
       slave.location = slaveOrigin + slavePath + "frameQuota.html?add&A&success";
       break;
 
-    // In subdomain now set another key with length 500 bytes, i.e.
-    // allocate 501 bytes
+    // Now set another key with length 500 bytes, i.e. allocate 501 bytes
     case 2:
       slaveOrigin = "http://test1.example.com";
       slave.location = slaveOrigin + slavePath + "frameQuota.html?add&B&success";
       break;
 
     // Try to set the same key value again to check we don't fail
     // even 1002 bytes has already been exhausted from the quota
     // We just change the value of an existing key.
@@ -39,53 +42,68 @@ function doNextTest()
 
     // Try to set the same key to a larger value that would lead to
     // quota reach and check that the value is still the old one
     case 4:
       slaveOrigin = "http://test1.example.com";
       slave.location = slaveOrigin + slavePath + "frameQuota.html?add2&B&failure";
       break;
 
-    // In a different subdomain try to set a new 500 bytes key
-    // and check we fail because we are over the quota
+    // Try to set a new 500 bytes key and check we fail because we are over the
+    // quota.
     case 5:
-      slaveOrigin = "https://test2.example.com";
+      if (SpecialPowers.Services.lsm.nextGenLocalStorageEnabled) {
+        slaveOrigin = "http://test1.example.com";
+      } else {
+        slaveOrigin = "https://test2.example.com";
+      }
       slave.location = slaveOrigin + slavePath + "frameQuota.html?add&C&failure";
       break;
 
-    // Remove from the second subdomain the second key, it must not fail
-    // This should release the allocated space of the quota assigned to
-    // example.com.
+    // Remove the second key, it must not fail. This should release the
+    // allocated space of the quota assigned to test1.example.com.
     case 6:
       slaveOrigin = "http://test1.example.com";
       slave.location = slaveOrigin + slavePath + "frameQuota.html?remove&B&success";
       break;
 
     // Now try again to set 500 bytes key, it must succeed.
     case 7:
-      slaveOrigin = "https://test2.example.com";
+      if (SpecialPowers.Services.lsm.nextGenLocalStorageEnabled) {
+        slaveOrigin = "http://test1.example.com";
+      } else {
+        slaveOrigin = "https://test2.example.com";
+      }
       slave.location = slaveOrigin + slavePath + "frameQuota.html?add&C&success";
       break;
 
     case 8:
-      // Do a clean up...
-      slaveOrigin = "http://example.com";
-      slave.location = slaveOrigin + slavePath + "frameQuota.html?clear";
+      if (SpecialPowers.Services.lsm.nextGenLocalStorageEnabled) {
+        SimpleTest.executeSoon(doNextTest);
+      } else {
+        // Do a clean up...
+        slaveOrigin = "http://example.com";
+        slave.location = slaveOrigin + slavePath + "frameQuota.html?clear";
+      }
       break;
 
     case 9:
       // Do a clean up...
       slaveOrigin = "http://test1.example.com";
       slave.location = slaveOrigin + slavePath + "frameQuota.html?clear";
       break;
 
     case 10:
-      // Do a clean up...
-      slaveOrigin = "https://test2.example.com";
-      slave.location = slaveOrigin + slavePath + "frameQuota.html?clear";
+      if (SpecialPowers.Services.lsm.nextGenLocalStorageEnabled) {
+        SimpleTest.executeSoon(doNextTest);
+      } else {
+        // Do a clean up...
+        slaveOrigin = "https://test2.example.com";
+        slave.location = slaveOrigin + slavePath + "frameQuota.html?clear";
+      }
       break;
 
     default: // end
       SimpleTest.finish();
   }
 
   ++currentTest;
 }
--- a/dom/tests/mochitest/localstorage/test_localStorageQuotaPrivateBrowsing_perwindowpb.html
+++ b/dom/tests/mochitest/localstorage/test_localStorageQuotaPrivateBrowsing_perwindowpb.html
@@ -37,22 +37,25 @@ function startTest() {
 }
 
 function doNextTest(aWindow) {
   info("Running test: " + currentTest);
   switch (currentTest) {
     // Initialy setup the quota to testing value of 1024B and
     // set a 500 bytes key with name length 1 (allocate 501 bytes)
     case 1:
-      slaveOrigin = "http://example.com";
+      if (SpecialPowers.Services.lsm.nextGenLocalStorageEnabled) {
+        slaveOrigin = "http://test1.example.com";
+      } else {
+        slaveOrigin = "http://example.com";
+      }
       slave.location = slaveOrigin + slavePath + "frameQuota.html?add&A&success";
       break;
 
-    // In subdomain now set another key with length 500 bytes, i.e.
-    // allocate 501 bytes
+    // Now set another key with length 500 bytes, i.e. allocate 501 bytes
     case 2:
       slaveOrigin = "http://test1.example.com";
       slave.location = slaveOrigin + slavePath + "frameQuota.html?add&B&success";
       break;
 
     // Try to set the same key value again to check we don't fail
     // even 1002 bytes has already been exhausted from the quota
     // We just change the value of an existing key.
@@ -63,57 +66,68 @@ function doNextTest(aWindow) {
 
     // Try to set the same key to a larger value that would lead to
     // quota reach and check that the value is still the old one
     case 4:
       slaveOrigin = "http://test1.example.com";
       slave.location = slaveOrigin + slavePath + "frameQuota.html?add2&B&failure";
       break;
 
-    // In a different subdomain try to set a new 500 bytes key
-    // and check we fail because we are over the quota
+    // Try to set a new 500 bytes key and check we fail because we are over the
+    // quota.
     case 5:
-      slaveOrigin = "https://test2.example.com";
+      if (SpecialPowers.Services.lsm.nextGenLocalStorageEnabled) {
+        slaveOrigin = "http://test1.example.com";
+      } else {
+        slaveOrigin = "https://test2.example.com";
+      }
       slave.location = slaveOrigin + slavePath + "frameQuota.html?add&C&failure";
       break;
 
-    // Remove from the second subdomain the second key, it must not fail
-    // This should release the allocated space of the quota assigned to
-    // example.com.
+    // Remove the second key, it must not fail. This should release the
+    // allocated space of the quota assigned to test1.example.com.
     case 6:
       slaveOrigin = "http://test1.example.com";
       slave.location = slaveOrigin + slavePath + "frameQuota.html?remove&B&success";
       break;
 
     // Now try again to set 500 bytes key, it must succeed.
     case 7:
-      slaveOrigin = "https://test2.example.com";
+      if (SpecialPowers.Services.lsm.nextGenLocalStorageEnabled) {
+        slaveOrigin = "http://test1.example.com";
+      } else {
+        slaveOrigin = "https://test2.example.com";
+      }
       slave.location = slaveOrigin + slavePath + "frameQuota.html?add&C&success";
       break;
 
     case 8:
-      // Do a clean up...
-      // TODO Bug 455070, use just ?clear what invokes call
-      // of clear() in the target frame. W/o clear method we must
-      // call clear implemented as removeItem for each item in
-      // the localStorage.
-      slaveOrigin = "http://example.com";
-      slave.location = slaveOrigin + slavePath + "frameQuota.html?clear&A&";
+      if (SpecialPowers.Services.lsm.nextGenLocalStorageEnabled) {
+        SimpleTest.executeSoon(() => doNextTest(aWindow));
+      } else {
+        // Do a clean up...
+        slaveOrigin = "http://example.com";
+        slave.location = slaveOrigin + slavePath + "frameQuota.html?clear";
+      }
       break;
 
     case 9:
       // Do a clean up...
       slaveOrigin = "http://test1.example.com";
-      slave.location = slaveOrigin + slavePath + "frameQuota.html?clear&B&";
+      slave.location = slaveOrigin + slavePath + "frameQuota.html?clear";
       break;
 
     case 10:
-      // Do a clean up...
-      slaveOrigin = "https://test2.example.com";
-      slave.location = slaveOrigin + slavePath + "frameQuota.html?clear&C&";
+      if (SpecialPowers.Services.lsm.nextGenLocalStorageEnabled) {
+        SimpleTest.executeSoon(() => doNextTest(aWindow));
+      } else {
+        // Do a clean up...
+        slaveOrigin = "https://test2.example.com";
+        slave.location = slaveOrigin + slavePath + "frameQuota.html?clear";
+      }
       break;
 
     default:
       Services.prefs.clearUserPref("browser.startup.page")
       Services.prefs.setIntPref("dom.storage.default_quota", quota);
       aWindow.close();
       SimpleTest.finish();
   }
deleted file mode 100644
--- a/testing/web-platform/meta/webstorage/storage_local_setitem_quotaexceedederr.html.ini
+++ /dev/null
@@ -1,2 +0,0 @@
-[storage_local_setitem_quotaexceedederr.html]
-  disabled: temporary