Line data Source code
1 : /*
2 : * Copyright (c) 2025 Project CHIP Authors
3 : * All rights reserved.
4 : *
5 : * Licensed under the Apache License, Version 2.0 (the "License");
6 : * you may not use this file except in compliance with the License.
7 : * You may obtain a copy of the License at
8 : *
9 : * http://www.apache.org/licenses/LICENSE-2.0
10 : *
11 : * Unless required by applicable law or agreed to in writing, software
12 : * distributed under the License is distributed on an "AS IS" BASIS,
13 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 : * See the License for the specific language governing permissions and
15 : * limitations under the License.
16 : */
17 : #pragma once
18 :
19 : #include <app/CASESessionManager.h>
20 : #include <app/InteractionModelEngine.h>
21 : #include <app/data-model-provider/ActionContext.h>
22 : #include <app/data-model-provider/Context.h>
23 : #include <app/data-model-provider/Provider.h>
24 : #include <app/persistence/DefaultAttributePersistenceProvider.h>
25 : #include <app/server-cluster/ServerClusterContext.h>
26 : #include <app/server-cluster/testing/EmptyProvider.h>
27 : #include <app/server-cluster/testing/TestAttributeChangeListener.h>
28 : #include <app/server-cluster/testing/TestEventGenerator.h>
29 : #include <app/server/Server.h>
30 : #include <credentials/FabricTable.h>
31 : #include <lib/support/TestPersistentStorageDelegate.h>
32 : #include <platform/PlatformManager.h>
33 : #include <protocols/interaction_model/StatusCode.h>
34 :
35 : namespace chip {
36 : namespace Testing {
37 :
38 : /// An action context that does not have a current exchange (just returns nullptr)
39 : class NullActionContext : public app::DataModel::ActionContext
40 : {
41 : public:
42 0 : Messaging::ExchangeContext * CurrentExchange() override { return nullptr; }
43 : };
44 :
45 : /// This is a ServerClusterContext that is initialized with VALID
46 : /// entries that can then be used during testing
47 : ///
48 : /// NOTE:
49 : /// At this time, `interactionContext::actionContext::CurrentExchange` WILL return nullptr
50 : /// in the existing implementation as the exchange is too heavy of an object
51 : /// to create for testing
52 : class TestServerClusterContext
53 : {
54 : public:
55 1013 : TestServerClusterContext() :
56 1013 : mTestContext{
57 : .eventsGenerator = mTestEventsGenerator,
58 : .actionContext = mNullActionContext,
59 : },
60 1013 : mContext{
61 : .provider = mTestProvider,
62 : .storage = mTestStorage,
63 : .attributeStorage = mDefaultAttributePersistenceProvider,
64 1013 : .interactionContext = mTestContext,
65 : },
66 1013 : mFabricTable(Server::GetInstance().GetFabricTable()), mCaseSessionManager(*Server::GetInstance().GetCASESessionManager()),
67 2026 : mPlatformManager(DeviceLayer::PlatformMgr()), mInteractionModelEngine(*app::InteractionModelEngine::GetInstance())
68 : {
69 1013 : mTestProvider.RegisterAttributeChangeListener(mChangeListener);
70 1013 : SuccessOrDie(mDefaultAttributePersistenceProvider.Init(&mTestStorage));
71 1013 : }
72 :
73 : /// Get a stable pointer to the underlying context
74 972 : app::ServerClusterContext & Get() { return mContext; }
75 :
76 31 : LogOnlyEvents & EventsGenerator() { return mTestEventsGenerator; }
77 123 : TestAttributeChangeListener & ChangeListener() { return mChangeListener; };
78 315 : TestPersistentStorageDelegate & StorageDelegate() { return mTestStorage; }
79 54 : app::DefaultAttributePersistenceProvider & AttributePersistenceProvider() { return mDefaultAttributePersistenceProvider; }
80 6 : app::DataModel::InteractionModelContext & ImContext() { return mTestContext; }
81 2 : FabricTable & GetFabricTable() { return mFabricTable; }
82 2 : CASESessionManager & GetCASESessionManager() { return mCaseSessionManager; }
83 2 : DeviceLayer::PlatformManager & GetPlatformManager() { return mPlatformManager; }
84 2 : app::InteractionModelEngine & GetInteractionModelEngine() { return mInteractionModelEngine; }
85 :
86 16 : TestAttributeChangeListener & ReleaseListener()
87 : {
88 16 : mTestProvider.UnregisterAttributeChangeListener(mChangeListener);
89 16 : return mChangeListener;
90 : }
91 :
92 16 : void AddProviderListener(app::DataModel::AttributeChangeListener & listener)
93 : {
94 16 : mTestProvider.RegisterAttributeChangeListener(listener);
95 16 : }
96 :
97 : private:
98 : NullActionContext mNullActionContext;
99 : LogOnlyEvents mTestEventsGenerator;
100 : TestAttributeChangeListener mChangeListener;
101 : EmptyProvider mTestProvider;
102 : TestPersistentStorageDelegate mTestStorage;
103 : app::DefaultAttributePersistenceProvider mDefaultAttributePersistenceProvider;
104 : app::DataModel::InteractionModelContext mTestContext;
105 : app::ServerClusterContext mContext;
106 : FabricTable & mFabricTable;
107 : CASESessionManager & mCaseSessionManager;
108 : DeviceLayer::PlatformManager & mPlatformManager;
109 : app::InteractionModelEngine & mInteractionModelEngine;
110 : };
111 :
112 : /// RAII class to register a TestAttributeChangeListener from a TestServerClusterContext
113 : /// with a specific DataModel::Provider for the scope of this object's lifetime.
114 : class ScopedAttributeChangeListenerRegistration
115 : {
116 : public:
117 16 : ScopedAttributeChangeListenerRegistration(app::DataModel::Provider & provider, TestServerClusterContext & context) :
118 16 : mProvider(provider), mContext(context)
119 : {
120 16 : mProvider.RegisterAttributeChangeListener(mContext.ReleaseListener());
121 16 : }
122 :
123 16 : ~ScopedAttributeChangeListenerRegistration()
124 : {
125 : // restore the previous state. We assume only one registration
126 16 : mProvider.UnregisterAttributeChangeListener(mContext.ChangeListener());
127 16 : mContext.AddProviderListener(mContext.ChangeListener());
128 16 : }
129 :
130 : // Non-copyable
131 : ScopedAttributeChangeListenerRegistration(const ScopedAttributeChangeListenerRegistration &) = delete;
132 : ScopedAttributeChangeListenerRegistration & operator=(const ScopedAttributeChangeListenerRegistration &) = delete;
133 :
134 : private:
135 : app::DataModel::Provider & mProvider;
136 : TestServerClusterContext & mContext;
137 : };
138 :
139 : } // namespace Testing
140 : } // namespace chip
|