1 /*
2  * Copyright (C) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <gtest/gtest.h>
17 
18 #include <meta/api/call_context.h>
19 #include <meta/api/function.h>
20 
21 #include "src/test_runner.h"
22 #include "src/testing_objects.h"
23 #include "src/util.h"
24 
25 using namespace testing::ext;
26 
27 namespace {
28     const int TEN = 10; // test value for test functions
29 }
30 
31 META_BEGIN_NAMESPACE()
32 
33 using namespace testing;
34 
35 class IntfCallContextTest : public testing::Test {
36 public:
SetUpTestSuite()37     static void SetUpTestSuite()
38     {
39         SetTest();
40     }
TearDownTestSuite()41     static void TearDownTestSuite()
42     {
43         ResetTest();
44     }
45     void SetUp() override {}
46     void TearDown() override {}
47 };
48 
49 /**
50  * @tc.name: IntfCallContextTest
51  * @tc.desc: test IntroduceInterfaces function
52  * @tc.type: FUNC
53  * @tc.require: I7DMS1
54  */
HWTEST_F(IntfCallContextTest, Empty, TestSize.Level1)55 HWTEST_F(IntfCallContextTest, Empty, TestSize.Level1)
56 {
57     auto context = GetObjectRegistry().ConstructDefaultCallContext();
58     EXPECT_FALSE(Get<int>(context, "some"));
59     EXPECT_TRUE(context->GetParameters().empty());
60     EXPECT_FALSE(context->Succeeded());
61     EXPECT_FALSE(GetResult<int>(context));
62 
63     EXPECT_TRUE(DefineResult<void>(context));
64 
65     EXPECT_FALSE(context->Succeeded());
66     EXPECT_TRUE(SetResult(context));
67     EXPECT_TRUE(context->Succeeded());
68 }
69 
70 /**
71  * @tc.name: IntfCallContextTest
72  * @tc.desc: test ReturnType function
73  * @tc.type: FUNC
74  * @tc.require: I7DMS1
75  */
HWTEST_F(IntfCallContextTest, ReturnType, TestSize.Level1)76 HWTEST_F(IntfCallContextTest, ReturnType, TestSize.Level1)
77 {
78     auto context = GetObjectRegistry().ConstructDefaultCallContext();
79     EXPECT_TRUE(DefineResult<int>(context));
80 
81     EXPECT_FALSE(context->Succeeded());
82     EXPECT_TRUE(SetResult<int>(context, 2));
83     EXPECT_TRUE(context->Succeeded());
84     auto res = GetResult<int>(context);
85     ASSERT_TRUE(res);
86     EXPECT_EQ(*res, 2);
87 }
88 
89 /**
90  * @tc.name: IntfCallContextTest
91  * @tc.desc: test Parameters function
92  * @tc.type: FUNC
93  * @tc.require: I7DMS1
94  */
HWTEST_F(IntfCallContextTest, Parameters, TestSize.Level1)95 HWTEST_F(IntfCallContextTest, Parameters, TestSize.Level1)
96 {
97     auto context = GetObjectRegistry().ConstructDefaultCallContext();
98     DefineParameter<int>(context, "test");
99     DefineParameter<BASE_NS::string>(context, "some", "hips");
100     EXPECT_FALSE(context->Succeeded());
101     auto p1 = Get<int>(context, "test");
102     ASSERT_TRUE(p1);
103     EXPECT_EQ(*p1, 0);
104     auto p2 = Get<BASE_NS::string>(context, "some");
105     ASSERT_TRUE(p2);
106     EXPECT_EQ(*p2, "hips");
107     EXPECT_FALSE(Get<float>(context, "test"));
108     EXPECT_FALSE(Set<float>(context, "test", 3.0));
109     EXPECT_TRUE(Set<int>(context, "test", 2));
110     auto ap1 = Get<int>(context, "test");
111     ASSERT_TRUE(ap1);
112     EXPECT_EQ(*ap1, 2);
113     SetResult(context);
114     EXPECT_TRUE(context->Succeeded());
115 }
116 
117 namespace {
118 struct TestClass : IObjectInstance {
TestFunc__anon9811::TestClass119     int TestFunc(int a, int b, BASE_NS::string c)
120     {
121         return a + b + c.size();
122     }
TestFuncMeta__anon9811::TestClass123     void TestFuncMeta(const ICallContext::Ptr& c)
124     {
125         CallFunction(c, this, &TestClass::TestFunc);
126     }
TestFunc2__anon9811::TestClass127     int TestFunc2(int a, int b)
128     {
129         return a + TEN * b;
130     }
TestFunc3__anon9811::TestClass131     void TestFunc3(int a, int b, float c) {}
ConstFunc__anon9811::TestClass132     void ConstFunc() const {}
ConstFuncMeta__anon9811::TestClass133     void ConstFuncMeta(const ICallContext::Ptr& c) const
134     {
135         CallFunction(c, this, &TestClass::ConstFunc);
136     }
RefFunc__anon9811::TestClass137     void RefFunc(const int& in, int& out)
138     {
139         out = in + 1;
140     }
RefFuncMeta__anon9811::TestClass141     void RefFuncMeta(const ICallContext::Ptr& c)
142     {
143         CallFunction(c, this, &TestClass::RefFunc);
144     }
145 
146     IObject::Ptr GetSelf() const override
147     {
148         return self_;
149     }
150 
151     ObjectId GetClassId() const override
152     {
153         return {};
154     }
155     BASE_NS::string_view GetClassName() const override
156     {
157         return {};
158     }
159     InstanceId GetInstanceId() const override
160     {
161         return {};
162     }
163     BASE_NS::string GetName() const override
164     {
165         return {};
166     }
167     IObject::Ptr Resolve(const RefUri& uri) const override
168     {
169         return {};
170     }
171     BASE_NS::vector<BASE_NS::Uid> GetInterfaces() const override
172     {
173         return {};
174     }
175     const IInterface* GetInterface(const BASE_NS::Uid& uid) const override
176     {
177         return this;
178     }
179     IInterface* GetInterface(const BASE_NS::Uid& uid) override
180     {
181         return this;
182     }
183 
184     void Ref() override {}
185     void Unref() override {}
186 
187     IObject::Ptr self_ { this, [](void*) {} };
188 };
189 } // namespace
190 
191 /**
192  * @tc.name: IntfCallContextTest
193  * @tc.desc: test CreateCallContext function
194  * @tc.type: FUNC
195  * @tc.require: I7DMS1
196  */
HWTEST_F(IntfCallContextTest, CreateCallContext, TestSize.Level1)197 HWTEST_F(IntfCallContextTest, CreateCallContext, TestSize.Level1)
198 {
199     BASE_NS::string_view arr[] = { "1", "2", "3" };
200     EXPECT_FALSE(CreateCallContext(&TestClass::TestFunc2, arr));
201     auto c = CreateCallContext(&TestClass::TestFunc, arr);
202     ASSERT_TRUE(c);
203     auto params = c->GetParameters();
204     ASSERT_EQ(params.size(), 3);
205     for (int i = 0; i != 3; ++i) {
206         EXPECT_EQ(params[i].name, arr[i]);
207     }
208     EXPECT_TRUE(IsCompatibleWith<int>(*params[0].value));
209     EXPECT_TRUE(IsCompatibleWith<int>(*params[1].value));
210     EXPECT_TRUE(IsCompatibleWith<BASE_NS::string>(*params[2].value));
211 
212     TestClass t;
213     auto f = CreateFunction("test", &t, &TestClass::TestFuncMeta, [] {
214         BASE_NS::string_view arr[] = { "1", "2", "3" };
215         return CreateCallContext(&TestClass::TestFunc, arr);
216     });
217     ASSERT_TRUE(f);
218     auto res = CallMetaFunction<int, int, int, BASE_NS::string>(f, 1, 2, "12");
219     ASSERT_TRUE(res);
220     EXPECT_EQ(res.value, 5);
221 }
222 
223 /**
224  * @tc.name: IntfCallContextTest
225  * @tc.desc: test BadCallFunction function
226  * @tc.type: FUNC
227  * @tc.require: I7DMS1
228  */
HWTEST_F(IntfCallContextTest, BadCallFunction, TestSize.Level1)229 HWTEST_F(IntfCallContextTest, BadCallFunction, TestSize.Level1)
230 {
231     BASE_NS::string_view arr[] = { "1", "2", "3" };
232     auto c = CreateCallContext(&TestClass::TestFunc, arr);
233     TestClass t;
234     EXPECT_FALSE(CallFunction(c, &t, &TestClass::TestFunc2));
235     EXPECT_FALSE(c->Succeeded());
236     EXPECT_FALSE(CallFunction(c, &t, &TestClass::TestFunc3));
237     EXPECT_FALSE(c->Succeeded());
238 }
239 
240 /**
241  * @tc.name: IntfCallContextTest
242  * @tc.desc: test ConstFunctions function
243  * @tc.type: FUNC
244  * @tc.require: I7DMS1
245  */
HWTEST_F(IntfCallContextTest, ConstFunctions, TestSize.Level1)246 HWTEST_F(IntfCallContextTest, ConstFunctions, TestSize.Level1)
247 {
248     auto context = [] { return CreateCallContext(&TestClass::ConstFunc, {}); };
249     auto c = context();
250     ASSERT_TRUE(c);
251     auto params = c->GetParameters();
252     ASSERT_EQ(params.size(), 0);
253     {
254         TestClass t;
255         auto f = CreateFunction("test", &t, &TestClass::ConstFuncMeta, context);
256         ASSERT_TRUE(f);
257         auto res = CallMetaFunction<void>(f);
258         ASSERT_TRUE(res);
259     }
260 }
261 
262 /**
263  * @tc.name: IntfCallContextTest
264  * @tc.desc: test ReferenceArgs function
265  * @tc.type: FUNC
266  * @tc.require: I7DMS1
267  */
HWTEST_F(IntfCallContextTest, ReferenceArgs, TestSize.Level1)268 HWTEST_F(IntfCallContextTest, ReferenceArgs, TestSize.Level1)
269 {
270     auto context = [] {
271         BASE_NS::string_view arr[] = { "in", "out" };
272         return CreateCallContext(&TestClass::RefFunc, arr);
273     };
274     auto c = context();
275     TestClass t;
276     auto f = CreateFunction("test", &t, &TestClass::RefFuncMeta, context);
277     ASSERT_TRUE(f);
278     auto res = CallMetaFunction<void>(f, 1, 0);
279     ASSERT_TRUE(res);
280     ASSERT_TRUE(res.context);
281 
282     auto p1 = Get<int>(res.context, "in");
283     ASSERT_TRUE(p1);
284     EXPECT_EQ(*p1, 1);
285     auto p2 = Get<int>(res.context, "out");
286     ASSERT_TRUE(p2);
287     EXPECT_EQ(*p2, 2);
288 }
289 
290 /**
291  * @tc.name: IntfCallContextTest
292  * @tc.desc: test CallArgumentOrder function
293  * @tc.type: FUNC
294  * @tc.require: I7DMS1
295  */
HWTEST_F(IntfCallContextTest, CallArgumentOrder, TestSize.Level1)296 HWTEST_F(IntfCallContextTest, CallArgumentOrder, TestSize.Level1)
297 {
298     BASE_NS::string_view arr[] = { "1", "2" };
299 
300     {
301         auto c = CreateCallContext(&TestClass::TestFunc2, arr);
302         Set<int>(c, "1", 1);
303         Set<int>(c, "2", 2);
304         TestClass t;
305         EXPECT_TRUE(CallFunction(c, &t, &TestClass::TestFunc2));
306         auto res = GetResult<int>(c);
307         ASSERT_TRUE(res);
308         EXPECT_EQ(*res, 21);
309     }
310     {
311         auto c = CreateCallContext(&TestClass::TestFunc2, arr);
312         Set<int>(c, "1", 1);
313         Set<int>(c, "2", 2);
314         TestClass t;
315         BASE_NS::string_view order[] = { "2", "1" };
316         EXPECT_TRUE(CallFunction(c, &t, &TestClass::TestFunc2, order));
317         auto res = GetResult<int>(c);
318         ASSERT_TRUE(res);
319         EXPECT_EQ(*res, 12);
320     }
321 }
322 
323 META_END_NAMESPACE()