From d8bbc7858622b6d9c278469aab701ca0b609cddf Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 15 May 2024 05:35:49 +0200 Subject: Merging upstream version 126.0. Signed-off-by: Daniel Baumann --- xpcom/tests/gtest/TestAllocReplacement.cpp | 31 ----- xpcom/tests/gtest/TestINIParser.cpp | 60 ++++++++ xpcom/tests/gtest/TestMozPromise.cpp | 50 +++++++ xpcom/tests/gtest/TestStrings.cpp | 36 +++-- xpcom/tests/gtest/TestTaskController.cpp | 214 +++++++++++++++++++++++++++++ xpcom/tests/gtest/moz.build | 6 +- xpcom/tests/unit/test_bug325418.js | 4 +- xpcom/tests/unit/test_nsIProcess.js | 6 +- xpcom/tests/unit/test_windows_registry.js | 2 +- 9 files changed, 359 insertions(+), 50 deletions(-) create mode 100644 xpcom/tests/gtest/TestINIParser.cpp create mode 100644 xpcom/tests/gtest/TestTaskController.cpp (limited to 'xpcom/tests') diff --git a/xpcom/tests/gtest/TestAllocReplacement.cpp b/xpcom/tests/gtest/TestAllocReplacement.cpp index 4b2c41b0f3..e0f0d001d5 100644 --- a/xpcom/tests/gtest/TestAllocReplacement.cpp +++ b/xpcom/tests/gtest/TestAllocReplacement.cpp @@ -73,34 +73,3 @@ TEST(AllocReplacement, posix_memalign_check) }); } #endif - -#if defined(XP_WIN) -# include - -# undef ASSERT_ALLOCATION_HAPPENED -# define ASSERT_ALLOCATION_HAPPENED(lambda) \ - ASSERT_TRUE(ValidateHookedAllocation( \ - lambda, [](void* p) { HeapFree(GetProcessHeap(), 0, p); })); - -TEST(AllocReplacement, HeapAlloc_check) -{ - ASSERT_ALLOCATION_HAPPENED([] { - HANDLE h = GetProcessHeap(); - return HeapAlloc(h, 0, kAllocAmount); - }); -} - -TEST(AllocReplacement, HeapReAlloc_check) -{ - ASSERT_ALLOCATION_HAPPENED([] { - HANDLE h = GetProcessHeap(); - void* p = HeapAlloc(h, 0, kAllocAmount / 2); - - if (!p) { - return static_cast(nullptr); - } - - return HeapReAlloc(h, 0, p, kAllocAmount); - }); -} -#endif diff --git a/xpcom/tests/gtest/TestINIParser.cpp b/xpcom/tests/gtest/TestINIParser.cpp new file mode 100644 index 0000000000..8c156f23dd --- /dev/null +++ b/xpcom/tests/gtest/TestINIParser.cpp @@ -0,0 +1,60 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsCOMPtr.h" +#include "gtest/gtest.h" +#include "mozilla/gtest/MozAssertions.h" + +#include "nsINIParser.h" + +TEST(INIParser, DeleteString) +{ + nsINIParser* parser = new nsINIParser(); + nsresult rv = parser->InitFromString( + "[sec]\r\ +key1=val1\r\ +key2=val2\r\ +key3=val3\r\ +key4=val4"_ns); + EXPECT_NS_SUCCEEDED(rv); + + rv = parser->DeleteString("sec", "key3"); + EXPECT_NS_SUCCEEDED(rv); + rv = parser->DeleteString("sec", "key4"); + EXPECT_NS_SUCCEEDED(rv); + rv = parser->DeleteString("sec", "key1"); + EXPECT_NS_SUCCEEDED(rv); + rv = parser->DeleteString("sec", "key2"); + EXPECT_NS_SUCCEEDED(rv); + + delete parser; +} + +TEST(INIParser, DeleteSection) +{ + nsINIParser* parser = new nsINIParser(); + nsresult rv = parser->InitFromString( + "[sec1]\r\ +key=val\r\ +\r\ +[sec2]\r\ +key=val\r\ +[sec3]\r\ +key=val\r\ +[sec4]\r\ +key=val"_ns); + EXPECT_NS_SUCCEEDED(rv); + + rv = parser->DeleteSection("sec3"); + EXPECT_NS_SUCCEEDED(rv); + rv = parser->DeleteSection("sec4"); + EXPECT_NS_SUCCEEDED(rv); + rv = parser->DeleteSection("sec1"); + EXPECT_NS_SUCCEEDED(rv); + rv = parser->DeleteSection("sec2"); + EXPECT_NS_SUCCEEDED(rv); + + delete parser; +} diff --git a/xpcom/tests/gtest/TestMozPromise.cpp b/xpcom/tests/gtest/TestMozPromise.cpp index bb7273cc1f..9b06304139 100644 --- a/xpcom/tests/gtest/TestMozPromise.cpp +++ b/xpcom/tests/gtest/TestMozPromise.cpp @@ -753,4 +753,54 @@ TEST(MozPromise, ChainToDirectTaskDispatch) NS_ProcessPendingEvents(nullptr); } +TEST(MozPromise, Map) +{ + int value = 0; + bool ran_err = false; + + InvokeAsync(GetCurrentSerialEventTarget(), "test", + [&]() { return TestPromise::CreateAndResolve(18, "test"); }) + ->Map(GetCurrentSerialEventTarget(), "test", + [](int val) { return val + 0x18; }) + ->MapErr(GetCurrentSerialEventTarget(), "test", + [&](double val) { + ran_err = true; + return Ok{}; + }) + ->Map(GetCurrentSerialEventTarget(), "test", [&](int val) { + value = val; + return Ok{}; + }); + + NS_ProcessPendingEvents(nullptr); + + EXPECT_EQ(value, 42); + EXPECT_EQ(ran_err, false); +} + +TEST(MozPromise, MapErr) +{ + bool ran_ok = false; + double result = 0.0; + + InvokeAsync(GetCurrentSerialEventTarget(), "test", + [&]() { return TestPromise::CreateAndReject(1.0, "test"); }) + ->Map(GetCurrentSerialEventTarget(), "test", + [&](int val) { + ran_ok = true; + return 1; + }) + ->MapErr(GetCurrentSerialEventTarget(), "test", + [](double val) { return val * 2; }) + ->MapErr(GetCurrentSerialEventTarget(), "test", [&](double val) { + result = val; + return Ok{}; + }); + + NS_ProcessPendingEvents(nullptr); + + EXPECT_EQ(result, 2.0); + EXPECT_EQ(ran_ok, false); +} + #undef DO_FAIL diff --git a/xpcom/tests/gtest/TestStrings.cpp b/xpcom/tests/gtest/TestStrings.cpp index 7e0f986d29..b1458ec6ce 100644 --- a/xpcom/tests/gtest/TestStrings.cpp +++ b/xpcom/tests/gtest/TestStrings.cpp @@ -34,12 +34,6 @@ } \ }); -// Disable the C++ 2a warning. See bug #1509926 -#if defined(__clang__) && (__clang_major__ >= 6) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wc++2a-compat" -#endif - namespace TestStrings { using mozilla::BlackBox; @@ -1295,6 +1289,32 @@ TEST_F(Strings, string_tointeger) { } } +struct ToUnsignedIntegerTest { + const char* str; + uint32_t radix; + uint32_t result; + nsresult rv; +}; + +static const ToUnsignedIntegerTest kToUnsignedIntegerTests[] = { + {"123", 10, 123, NS_OK}, + {"7b", 16, 123, NS_OK}, + {"90194313659", 10, 0, NS_ERROR_ILLEGAL_VALUE}, + {"ffffffff", 16, 0xffffffff, NS_OK}, + {"4294967295", 10, 4294967295, NS_OK}, + {"8abc1234", 16, 0x8abc1234, NS_OK}, + {"-194313659", 10, 0, NS_ERROR_ILLEGAL_VALUE}, + {nullptr, 0, 0, NS_OK}}; + +TEST_F(Strings, string_to_unsigned_integer) { + nsresult rv; + for (const ToUnsignedIntegerTest* t = kToUnsignedIntegerTests; t->str; ++t) { + uint32_t result = nsAutoCString(t->str).ToUnsignedInteger(&rv, t->radix); + EXPECT_EQ(rv, t->rv); + EXPECT_EQ(result, t->result); + } +} + static void test_parse_string_helper(const char* str, char separator, int len, const char* s1, const char* s2) { nsCString data(str); @@ -2795,7 +2815,3 @@ static_assert(*testStringA.EndReading() == 0); static_assert(testStringA.EndReading() - testStringA.BeginReading() == 1); } // namespace TestStrings - -#if defined(__clang__) && (__clang_major__ >= 6) -# pragma clang diagnostic pop -#endif diff --git a/xpcom/tests/gtest/TestTaskController.cpp b/xpcom/tests/gtest/TestTaskController.cpp new file mode 100644 index 0000000000..c7d71ae0f8 --- /dev/null +++ b/xpcom/tests/gtest/TestTaskController.cpp @@ -0,0 +1,214 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "gtest/gtest.h" + +#include // uint32_t + +#include "nsString.h" // nsACString +#include "nsThreadUtils.h" // NS_ProcessNextEvent +#include "mozilla/Atomics.h" // Atomic +#include "mozilla/EventQueue.h" // EventQueuePriority +#include "mozilla/Mutex.h" // Mutex, MutexAutoLock +#include "mozilla/RefPtr.h" // RefPtr, do_AddRef +#include "mozilla/TaskController.h" // TaskController, Task +#include "prthread.h" // PR_Sleep + +using namespace mozilla; + +namespace TestTaskController { + +class Logger { + public: + Logger() : mMutex("Logger") {} + + void Add(const char* aText) { + MutexAutoLock lock(mMutex); + + mLog += aText; + } + + const nsAutoCString& GetLog() const { return mLog; } + + private: + nsAutoCString mLog; + Mutex mMutex; +}; + +class ReschedulingTask : public Task { + static constexpr uint32_t LoopCount = 3; + + public: + explicit ReschedulingTask(Kind aKind, Logger* aLogger, const char* aName) + : Task(aKind, EventQueuePriority::Normal), + mCount(0), + mIsDone(false), + mLogger(aLogger), + mName(aName) {} + + TaskResult Run() override { + mLogger->Add(mName); + + mCount++; + + if (mCount < LoopCount) { + return TaskResult::Incomplete; + } + + mIsDone = true; + + return TaskResult::Complete; + } + +#ifdef MOZ_COLLECTING_RUNNABLE_TELEMETRY + bool GetName(nsACString& aName) override { + aName.AssignLiteral("AsyncScriptCompileTask"); + return true; + } +#endif + + bool IsDone() const { return mIsDone; } + + private: + Atomic mCount; + Atomic mIsDone; + Logger* mLogger; + const char* mName; +}; + +using namespace mozilla; + +TEST(TaskController, RescheduleOnMainThread) +{ + Logger logger; + + RefPtr mainThreadTask = + new ReschedulingTask(Task::Kind::MainThreadOnly, &logger, "1"); + + TaskController::Get()->AddTask(do_AddRef(mainThreadTask)); + + while (NS_ProcessNextEvent(nullptr, false)) { + } + + ASSERT_TRUE(mainThreadTask->IsDone()); + + ASSERT_TRUE(logger.GetLog() == "111"); +} + +TEST(TaskController, RescheduleOffMainThread) +{ + Logger logger; + + RefPtr offThreadTask = + new ReschedulingTask(Task::Kind::OffMainThreadOnly, &logger, "1"); + + TaskController::Get()->AddTask(do_AddRef(offThreadTask)); + + uint32_t count = 0; + while (!offThreadTask->IsDone() && count < 100) { + PR_Sleep(PR_MillisecondsToInterval(100)); + count++; + } + ASSERT_TRUE(offThreadTask->IsDone()); + + ASSERT_TRUE(logger.GetLog() == "111"); +} + +TEST(TaskController, RescheduleMainAndOffMainThreads) +{ + Logger logger; + + RefPtr offThreadTask = + new ReschedulingTask(Task::Kind::OffMainThreadOnly, &logger, "1"); + RefPtr mainThreadTask = + new ReschedulingTask(Task::Kind::MainThreadOnly, &logger, "2"); + + mainThreadTask->AddDependency(offThreadTask.get()); + + TaskController::Get()->AddTask(do_AddRef(offThreadTask)); + TaskController::Get()->AddTask(do_AddRef(mainThreadTask)); + + uint32_t count = 0; + while (!offThreadTask->IsDone() && count < 100) { + PR_Sleep(PR_MillisecondsToInterval(100)); + count++; + } + ASSERT_TRUE(offThreadTask->IsDone()); + + // At this point, the main thread task shouldn't have run. + ASSERT_TRUE(logger.GetLog() == "111"); + + while (NS_ProcessNextEvent(nullptr, false)) { + } + + ASSERT_TRUE(mainThreadTask->IsDone()); + + ASSERT_TRUE(logger.GetLog() == "111222"); +} + +TEST(TaskController, RescheduleOrder) +{ + Logger logger; + + RefPtr mainThreadTask1 = + new ReschedulingTask(Task::Kind::MainThreadOnly, &logger, "1"); + RefPtr mainThreadTask2 = + new ReschedulingTask(Task::Kind::MainThreadOnly, &logger, "2"); + RefPtr mainThreadTask3 = + new ReschedulingTask(Task::Kind::MainThreadOnly, &logger, "3"); + + TaskController::Get()->AddTask(do_AddRef(mainThreadTask1)); + TaskController::Get()->AddTask(do_AddRef(mainThreadTask2)); + TaskController::Get()->AddTask(do_AddRef(mainThreadTask3)); + + while (NS_ProcessNextEvent(nullptr, false)) { + } + + ASSERT_TRUE(mainThreadTask1->IsDone()); + ASSERT_TRUE(mainThreadTask2->IsDone()); + ASSERT_TRUE(mainThreadTask3->IsDone()); + + // Rescheduled tasks should be added to the beginning of the queue. + ASSERT_TRUE(logger.GetLog() == "111222333"); +} + +TEST(TaskController, RescheduleOrderOffMainThread) +{ + Logger logger1; + Logger logger2; + Logger logger3; + + RefPtr offThreadTask1 = + new ReschedulingTask(Task::Kind::OffMainThreadOnly, &logger1, "1"); + RefPtr offThreadTask2 = + new ReschedulingTask(Task::Kind::OffMainThreadOnly, &logger2, "2"); + RefPtr offThreadTask3 = + new ReschedulingTask(Task::Kind::OffMainThreadOnly, &logger3, "3"); + + TaskController::Get()->AddTask(do_AddRef(offThreadTask1)); + TaskController::Get()->AddTask(do_AddRef(offThreadTask2)); + TaskController::Get()->AddTask(do_AddRef(offThreadTask3)); + + uint32_t count = 0; + while (!(offThreadTask1->IsDone() && offThreadTask2->IsDone() && + offThreadTask3->IsDone()) && + count < 100) { + PR_Sleep(PR_MillisecondsToInterval(100)); + count++; + } + + ASSERT_TRUE(offThreadTask1->IsDone()); + ASSERT_TRUE(offThreadTask2->IsDone()); + ASSERT_TRUE(offThreadTask3->IsDone()); + + // Rescheduled tasks should be enqueued. + // The order between off-thread tasks are not deterministic. + ASSERT_TRUE(logger1.GetLog() == "111"); + ASSERT_TRUE(logger2.GetLog() == "222"); + ASSERT_TRUE(logger3.GetLog() == "333"); +} + +} // namespace TestTaskController diff --git a/xpcom/tests/gtest/moz.build b/xpcom/tests/gtest/moz.build index 6fd509d7b2..4d8d38e89a 100644 --- a/xpcom/tests/gtest/moz.build +++ b/xpcom/tests/gtest/moz.build @@ -26,6 +26,7 @@ UNIFIED_SOURCES += [ "TestGCPostBarriers.cpp", "TestID.cpp", "TestIDUtils.cpp", + "TestINIParser.cpp", "TestInputStreamLengthHelper.cpp", "TestJSHolderMap.cpp", "TestLogCommandLineHandler.cpp", @@ -61,6 +62,7 @@ UNIFIED_SOURCES += [ "TestSynchronization.cpp", "TestTArray.cpp", "TestTArray2.cpp", + "TestTaskController.cpp", "TestTaskQueue.cpp", "TestTextFormatter.cpp", "TestThreadManager.cpp", @@ -143,10 +145,8 @@ if ( "TestSTLWrappers.cpp", ] -# Compile TestAllocReplacement separately so Windows headers don't pollute -# the global namespace for other files. if CONFIG["MOZ_MEMORY"]: - SOURCES += [ + UNIFIED_SOURCES += [ "TestAllocReplacement.cpp", ] diff --git a/xpcom/tests/unit/test_bug325418.js b/xpcom/tests/unit/test_bug325418.js index 5840aacf74..c86f8d5845 100644 --- a/xpcom/tests/unit/test_bug325418.js +++ b/xpcom/tests/unit/test_bug325418.js @@ -8,7 +8,7 @@ var gStartTime2; var timer; var observer1 = { - observe: function observeTC1(subject, topic, data) { + observe: function observeTC1(subject, topic) { if (topic == "timer-callback") { // Stop timer, so it doesn't repeat (if test runs slowly). timer.cancel(); @@ -30,7 +30,7 @@ var observer1 = { }; var observer2 = { - observe: function observeTC2(subject, topic, data) { + observe: function observeTC2(subject, topic) { if (topic == "timer-callback") { // Stop timer, so it doesn't repeat (if test runs slowly). timer.cancel(); diff --git a/xpcom/tests/unit/test_nsIProcess.js b/xpcom/tests/unit/test_nsIProcess.js index 582d10440c..e8a382b29f 100644 --- a/xpcom/tests/unit/test_nsIProcess.js +++ b/xpcom/tests/unit/test_nsIProcess.js @@ -128,7 +128,7 @@ function test_notify_blocking() { process.init(file); process.runAsync([], 0, { - observe(subject, topic, data) { + observe(subject, topic) { process = subject.QueryInterface(Ci.nsIProcess); Assert.equal(topic, "process-failed"); Assert.equal(process.exitValue, 42); @@ -145,7 +145,7 @@ function test_notify_nonblocking() { process.init(file); process.runAsync(TEST_ARGS, TEST_ARGS.length, { - observe(subject, topic, data) { + observe(subject, topic) { process = subject.QueryInterface(Ci.nsIProcess); Assert.equal(topic, "process-finished"); Assert.equal(process.exitValue, 0); @@ -162,7 +162,7 @@ function test_notify_killed() { process.init(file); process.runAsync([], 0, { - observe(subject, topic, data) { + observe(subject, topic) { process = subject.QueryInterface(Ci.nsIProcess); Assert.equal(topic, "process-failed"); do_test_finished(); diff --git a/xpcom/tests/unit/test_windows_registry.js b/xpcom/tests/unit/test_windows_registry.js index 691c0461c3..ef5082a666 100644 --- a/xpcom/tests/unit/test_windows_registry.js +++ b/xpcom/tests/unit/test_windows_registry.js @@ -172,7 +172,7 @@ function test_childkey_functions(testKey) { strictEqual(testKey.hasChild(TESTDATA_CHILD_KEY), false); } -function cleanup_test_run(testKey, keyName) { +function cleanup_test_run(testKey) { info("Cleaning up test."); for (var i = 0; i < testKey.childCount; i++) { -- cgit v1.2.3