Skip to content

Commit

Permalink
Enable varying feature flags in ReactInstanceIntegrationTest, use mod…
Browse files Browse the repository at this point in the history
…ern CDP registry by default (facebook#43101)

Summary:
Pull Request resolved: facebook#43101

Extends `ReactInstanceIntegrationTest` to allow varying feature flags in tests, using gtest's parameterised tests.

Exercise this in `ConsoleLogTest` to test against the modern CDP registry, for which we also needed to modify some initialisation logic to account for the fact that under the modern registry, the page is added by the host, rather than by Hermes `DecoratedRuntime`.

Changelog: [Internal]

Differential Revision: D53919148
  • Loading branch information
robhogan authored and facebook-github-bot committed Feb 19, 2024
1 parent 9442488 commit 960fd27
Show file tree
Hide file tree
Showing 3 changed files with 118 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,23 +18,49 @@ namespace facebook::react::jsinspector_modern {

using namespace testing;

TEST_F(ReactInstanceIntegrationTest, ConsoleLogTest) {
TEST_P(ReactInstanceIntegrationTestWithFlags, ConsoleLog) {
InSequence s;

EXPECT_CALL(getRemoteConnection(), onMessage(_))
.Times(2)
.RetiresOnSaturation();
EXPECT_CALL(
getRemoteConnection(),
onMessage(JsonParsed(AllOf(AtJsonPtr("/id", Eq(1))))));

EXPECT_CALL(
getRemoteConnection(),
onMessage(JsonParsed(AllOf(
AtJsonPtr("/params/args/0/value", Eq("Hello, World!")),
AtJsonPtr("/method", Eq("Runtime.consoleAPICalled"))))));
AtJsonPtr("/params/context/name", Eq("hermes")),
AtJsonPtr("/method", Eq("Runtime.executionContextCreated"))))));

// Hermes console.* interception is currently explicitly disabled under the
// modern registry, and the runtime does not yet fire these events. When the
// implementation is more complete we should be able to remove this
// condition.
if (!featureFlags->enableModernCDPRegistry) {
EXPECT_CALL(
getRemoteConnection(),
onMessage(JsonParsed(AllOf(
AtJsonPtr("/params/args/0/value", Eq("Hello, World!")),
AtJsonPtr("/method", Eq("Runtime.consoleAPICalled"))))));
}

EXPECT_CALL(getRemoteConnection(), onDisconnect());

send("Runtime.enable");
run("console.log('Hello, World!');");
}

INSTANTIATE_TEST_SUITE_P(
ConsoleLogVaryingInspectorFlags,
ReactInstanceIntegrationTestWithFlags,
::testing::Values(
FeatureFlags{
.enableCxxInspectorPackagerConnection = true,
.enableModernCDPRegistry = true},
FeatureFlags{
.enableCxxInspectorPackagerConnection = false,
.enableModernCDPRegistry = false},
FeatureFlags{
.enableCxxInspectorPackagerConnection = true,
.enableModernCDPRegistry = false}));

} // namespace facebook::react::jsinspector_modern
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,41 @@

#include <folly/json.h>
#include <glog/logging.h>
#include <react/featureflags/ReactNativeFeatureFlags.h>
#include <react/featureflags/ReactNativeFeatureFlagsDefaults.h>
#include <react/runtime/hermes/HermesInstance.h>

namespace facebook::react::jsinspector_modern {

class ReactInstanceIntegrationTestFeatureFlagsProvider
: public ReactNativeFeatureFlagsDefaults {
private:
FeatureFlags flags_;

public:
ReactInstanceIntegrationTestFeatureFlagsProvider(FeatureFlags featureFlags)
: flags_(featureFlags) {}

bool inspectorEnableModernCDPRegistry() override {
return flags_.enableModernCDPRegistry;
}
bool inspectorEnableCxxInspectorPackagerConnection() override {
return flags_.enableCxxInspectorPackagerConnection;
}
};

ReactInstanceIntegrationTest::ReactInstanceIntegrationTest()
: runtime(nullptr),
instance(nullptr),
messageQueueThread(std::make_shared<MockMessageQueueThread>()),
errorHandler(std::make_shared<ErrorUtils>()) {}
errorHandler(std::make_shared<ErrorUtils>()),
featureFlags(std::make_unique<FeatureFlags>()) {}

void ReactInstanceIntegrationTest::SetUp() {
ReactNativeFeatureFlags::override(
std::make_unique<ReactInstanceIntegrationTestFeatureFlagsProvider>(
*featureFlags));

auto mockRegistry = std::make_unique<MockTimerRegistry>();
auto timerManager =
std::make_shared<react::TimerManager>(std::move(mockRegistry));
Expand All @@ -44,29 +68,64 @@ void ReactInstanceIntegrationTest::SetUp() {
"ErrorUtils",
jsi::Object::createFromHostObject(*jsiRuntime, errorHandler));

std::shared_ptr<PageTarget> pageTargetIfModernCDP_ = nullptr;

if (featureFlags->enableModernCDPRegistry) {
VoidExecutor inspectorExecutor_ = [this](auto callback) {
immediateExecutor_.add(callback);
};
MockPageTargetDelegate pageTargetDelegate_;
pageTargetIfModernCDP_ =
PageTarget::create(pageTargetDelegate_, inspectorExecutor_);
}

instance = std::make_unique<react::ReactInstance>(
std::move(runtime_),
messageQueueThread,
timerManager,
std::move(jsErrorHandlingFunc));
std::move(jsErrorHandlingFunc),
pageTargetIfModernCDP_ == nullptr ? nullptr
: pageTargetIfModernCDP_.get());

timerManager->setRuntimeExecutor(instance->getBufferedRuntimeExecutor());

// JS Environment:
initializeRuntime(preludeJsCode);

// Inspector:
auto& inspector = getInspectorInstance();
auto pages = inspector.getPages();

// We should now have at least a single page once the above runtime has been
// initialized.
assert(pages.size() > 0);
size_t pageId = pages.back().id;
int pageId;
if (pageTargetIfModernCDP_ != nullptr) {
// Under modern CDP, the React host is responsible for adding its page on
// startup.
pageId = inspector.addPage(
"mock-title",
"mock-vm",
[pageTargetIfModernCDP_](std::unique_ptr<IRemoteConnection> remote)
-> std::unique_ptr<ILocalConnection> {
auto localConnection = pageTargetIfModernCDP_->connect(
std::move(remote),
{
.integrationName = "ReactInstanceIntegrationTest",
});
return localConnection;
},
// TODO: Allow customisation of InspectorTargetCapabilities
{});
} else {
// Under legacy CDP, Hermes' DecoratedRuntime adds its page automatically
// within ConnectionDemux.enableDebugging.
auto pages = inspector.getPages();
assert(pages.size() > 0);
pageId = pages.back().id;
}

clientToVM_ = inspector.connect(pageId, mockRemoteConnections_.make_unique());
}

void ReactInstanceIntegrationTest::TearDown() {
ReactNativeFeatureFlags::dangerouslyReset();
clientToVM_->disconnect();
}

Expand Down Expand Up @@ -100,6 +159,7 @@ void ReactInstanceIntegrationTest::send(
void ReactInstanceIntegrationTest::sendJSONString(const std::string& message) {
// The runtime must be initialized and connected to before messaging
clientToVM_->sendMessage(message);
messageQueueThread->flush();
}

jsi::Value ReactInstanceIntegrationTest::run(const std::string& script) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

#pragma once

#include <folly/executors/QueuedImmediateExecutor.h>
#include <folly/json.h>
#include <gtest/gtest.h>
#include <jsinspector-modern/InspectorInterfaces.h>
Expand All @@ -18,7 +19,14 @@

namespace facebook::react::jsinspector_modern {

class ReactInstanceIntegrationTest : public ::testing::Test {
using namespace ::testing;

struct FeatureFlags {
const bool enableCxxInspectorPackagerConnection = true;
const bool enableModernCDPRegistry = true;
};

class ReactInstanceIntegrationTest : public Test {
protected:
ReactInstanceIntegrationTest();
void SetUp() override;
Expand All @@ -36,6 +44,7 @@ class ReactInstanceIntegrationTest : public ::testing::Test {
std::unique_ptr<react::ReactInstance> instance;
std::shared_ptr<MockMessageQueueThread> messageQueueThread;
std::shared_ptr<ErrorUtils> errorHandler;
std::unique_ptr<FeatureFlags> featureFlags;

MockRemoteConnection& getRemoteConnection() {
return *mockRemoteConnections_[0];
Expand All @@ -48,6 +57,15 @@ class ReactInstanceIntegrationTest : public ::testing::Test {
bool verbose_ = false;
UniquePtrFactory<MockRemoteConnection> mockRemoteConnections_;
std::unique_ptr<ILocalConnection> clientToVM_;
folly::QueuedImmediateExecutor immediateExecutor_;
};

class ReactInstanceIntegrationTestWithFlags
: public ReactInstanceIntegrationTest,
public ::testing::WithParamInterface<FeatureFlags> {
void SetUp() override {
featureFlags = std::make_unique<FeatureFlags>(GetParam());
ReactInstanceIntegrationTest::SetUp();
}
};
} // namespace facebook::react::jsinspector_modern

0 comments on commit 960fd27

Please sign in to comment.