From c24f55fa63c3aefe93588d6d4aecbdd0d3d909ea Mon Sep 17 00:00:00 2001 From: jinliu9508 Date: Wed, 13 Dec 2023 11:39:30 -0500 Subject: [PATCH 1/3] Add unit test that simulates the deadlock scenario in SubscriptionManagerTests.kt --- .../sdktest/model/MainActivityViewModel.java | 46 ++++++++ .../main/res/layout/main_activity_layout.xml | 25 ++++ .../app/src/main/res/values/strings.xml | 1 + .../com/onesignal/common/modeling/Model.kt | 5 +- .../subscriptions/SubscriptionManagerTests.kt | 111 ++++++++++++------ .../com/onesignal/common/DeadlockTests.kt | 14 +++ 6 files changed, 164 insertions(+), 38 deletions(-) create mode 100644 OneSignalSDK/onesignal/src/test/java/com/onesignal/common/DeadlockTests.kt diff --git a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/model/MainActivityViewModel.java b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/model/MainActivityViewModel.java index 58069a298c..9b4ec5e936 100644 --- a/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/model/MainActivityViewModel.java +++ b/Examples/OneSignalDemo/app/src/main/java/com/onesignal/sdktest/model/MainActivityViewModel.java @@ -24,6 +24,7 @@ import android.widget.TextView; import com.onesignal.Continue; import com.onesignal.OneSignal; +import com.onesignal.core.internal.config.ConfigModelStore; import com.onesignal.sdktest.adapter.SubscriptionRecyclerViewAdapter; import com.onesignal.user.subscriptions.IPushSubscription; import com.onesignal.sdktest.R; @@ -273,6 +274,11 @@ public ActivityViewModel onActivityCreated(Context context) { getActivity().startActivity(new Intent(getActivity(), SecondaryActivity.class)); }); + Button createDeadlock = getActivity().findViewById(R.id.main_activity_deadlock_button); + createDeadlock.setOnClickListener(v -> { + createDeadlock(); + }); + aliasSet = new HashMap<>(); aliasArrayList = new ArrayList<>(); @@ -931,4 +937,44 @@ private void refreshState() { // triggers are not persisted, they are always "starting from scratch" refreshTriggerRecyclerView(); } + + private void createDeadlock() { + + // register test observers + IPushSubscriptionObserver observer = state -> { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + OneSignal.getUser().getPushSubscription().optIn(); + System.out.println("JinTest optedout"); + }; + OneSignal.getUser().getPushSubscription().addObserver(observer); + + // calling login will call setOptAnyProperty, which locks model.data + // then, any observer added will be fired, which will lock subscribers + Thread t1 = new Thread() { + @Override + public void run() { + OneSignal.getUser().getPushSubscription().optOut(); + OneSignal.getUser().getPushSubscription().optIn(); + System.out.println("JinTest optedin"); + } + }; + + Thread t2 = new Thread() { + @Override + public void run() { + OneSignal.logout(); + OneSignal.login("testJin"); + System.out.println("JinTest login"); + } + }; + + t1.start(); + t2.start(); + + + } } diff --git a/Examples/OneSignalDemo/app/src/main/res/layout/main_activity_layout.xml b/Examples/OneSignalDemo/app/src/main/res/layout/main_activity_layout.xml index ee4ce93cb5..5d1d29e28e 100644 --- a/Examples/OneSignalDemo/app/src/main/res/layout/main_activity_layout.xml +++ b/Examples/OneSignalDemo/app/src/main/res/layout/main_activity_layout.xml @@ -139,6 +139,7 @@ android:orientation="vertical"> + + + + +