1 //------------------------------------------------------------------------------
2 // GetAppInfoTester.cpp
3 //
4 //------------------------------------------------------------------------------
5
6 // Standard Includes -----------------------------------------------------------
7 #include <stdio.h>
8
9 // System Includes -------------------------------------------------------------
10 #include <Message.h>
11 #include <OS.h>
12 #include <Handler.h>
13 #include <Looper.h>
14 #include <Roster.h>
15 #include <String.h>
16
17 // Project Includes ------------------------------------------------------------
18 #include <TestShell.h>
19 #include <TestUtils.h>
20 #include <cppunit/TestAssert.h>
21
22 // Local Includes --------------------------------------------------------------
23 #include "AppRunner.h"
24 #include "GetAppInfoTester.h"
25
26 // Local Defines ---------------------------------------------------------------
27
28 // Globals ---------------------------------------------------------------------
29
30 //------------------------------------------------------------------------------
31
32 // check_app_info
33 static
34 bool
check_app_info(app_info & info,AppRunner & runner,const char * signature,uint32 flags)35 check_app_info(app_info &info, AppRunner &runner, const char *signature,
36 uint32 flags)
37 {
38 team_id team = runner.Team();
39 // get the thread
40 thread_id thread = -1;
41 int32 cookie = 0;
42 thread_info threadInfo;
43 while (get_next_thread_info(team, &cookie, &threadInfo) == B_OK) {
44 if (thread < 0 || threadInfo.thread < thread)
45 thread = threadInfo.thread;
46 }
47 // get port and ref
48 port_id port = runner.AppLooperPort();
49 entry_ref ref;
50 runner.GetRef(&ref);
51 // compare
52 //printf("check_app_info(): "
53 //" thread: %ld vs %ld\n"
54 //" team: %ld vs %ld\n"
55 //" port: %ld vs %ld\n"
56 //" flags: %lx vs %lx\n"
57 //" signature: `%s' vs `%s'\n", info.thread, thread, info.team, team,
58 //info.port, port, info.flags, flags, info.signature, signature);
59 //printf(" ref: (%ld, %lld, `%s') vs (%ld, %lld, `%s')\n",
60 //info.ref.device, info.ref.directory, info.ref.name,
61 //ref.device, ref.directory, ref.name);
62 return (info.thread == thread && info.team == team && info.port == port
63 && info.flags == flags && info.ref == ref
64 && !strncmp(info.signature, signature, B_MIME_TYPE_LENGTH));
65 }
66
67 /*
68 status_t GetAppInfo(const char *signature, app_info *info) const
69 @case 1 signature is NULL or info is NULL
70 @results Should return B_BAD_VALUE.
71 */
GetAppInfoTestA1()72 void GetAppInfoTester::GetAppInfoTestA1()
73 {
74 BRoster roster;
75 app_info info;
76 CHK(roster.GetAppInfo((const char*)NULL, NULL) == B_BAD_VALUE);
77 CHK(roster.GetAppInfo((const char*)NULL, &info) == B_BAD_VALUE);
78 // R5: crashes when passing a NULL app_info
79 #ifndef TEST_R5
80 CHK(roster.GetAppInfo("application/x-vnd.obos-app-run-testapp1",
81 NULL) == B_BAD_VALUE);
82 #endif
83 }
84
85 /*
86 status_t GetAppInfo(const char *signature, app_info *info) const
87 @case 2 signature/info are not NULL, but no app with this
88 signature is running
89 @results Should return B_ERROR.
90 */
GetAppInfoTestA2()91 void GetAppInfoTester::GetAppInfoTestA2()
92 {
93 BRoster roster;
94 app_info info;
95 CHK(roster.GetAppInfo("application/x-vnd.obos-app-run-testapp1", &info)
96 == B_ERROR);
97 }
98
99 /*
100 status_t GetAppInfo(const char *signature, app_info *info) const
101 @case 3 signature/info are not NULL and an (two) app(s) with this
102 signature is (are) running; quit one; quit the second one
103 @results Should
104 - fill the app info with the data of one of the apps and
105 return B_OK;
106 - fill the app info with the data of the second apps and
107 return B_OK;
108 - return B_ERROR.
109 */
GetAppInfoTestA3()110 void GetAppInfoTester::GetAppInfoTestA3()
111 {
112 const char *signature = "application/x-vnd.obos-app-run-testapp1";
113 uint32 flags = B_MULTIPLE_LAUNCH | B_ARGV_ONLY;
114 // run the remote apps
115 AppRunner runner1(true);
116 AppRunner runner2(true);
117 CHK(runner1.Run("AppRunTestApp1") == B_OK);
118 CHK(runner2.Run("AppRunTestApp1") == B_OK);
119 // create the BRoster and perform the tests
120 BRoster roster;
121 app_info info1;
122 CHK(roster.GetAppInfo(signature, &info1) == B_OK);
123 CHK(check_app_info(info1, runner1, signature, flags)
124 || check_app_info(info1, runner2, signature, flags));
125 // quit app 1
126 runner1.WaitFor(true);
127 app_info info2;
128 CHK(roster.GetAppInfo(signature, &info2) == B_OK);
129 CHK(check_app_info(info2, runner2, signature, flags));
130 // quit app 2
131 runner2.WaitFor(true);
132 CHK(roster.GetAppInfo(signature, &info1) == B_ERROR);
133 }
134
135 /*
136 status_t GetAppInfo(entry_ref *ref, app_info *info) const
137 @case 1 ref is NULL or info is NULL
138 @results Should return B_BAD_VALUE.
139 */
GetAppInfoTestB1()140 void GetAppInfoTester::GetAppInfoTestB1()
141 {
142 BRoster roster;
143 entry_ref ref;
144 CHK(find_test_app("AppRunTestApp1", &ref) == B_OK);
145 app_info info;
146 CHK(roster.GetAppInfo((entry_ref*)NULL, NULL) == B_BAD_VALUE);
147 CHK(roster.GetAppInfo((entry_ref*)NULL, &info) == B_BAD_VALUE);
148 // R5: crashes when passing a NULL app_info
149 #ifndef TEST_R5
150 CHK(roster.GetAppInfo(&ref, NULL) == B_BAD_VALUE);
151 #endif
152 }
153
154 /*
155 status_t GetAppInfo(entry_ref *ref, app_info *info) const
156 @case 2 ref/info are not NULL, but no app with this ref is running
157 @results Should return B_ERROR.
158 */
GetAppInfoTestB2()159 void GetAppInfoTester::GetAppInfoTestB2()
160 {
161 BRoster roster;
162 entry_ref ref;
163 CHK(find_test_app("AppRunTestApp1", &ref) == B_OK);
164 app_info info;
165 CHK(roster.GetAppInfo(&ref, &info) == B_ERROR);
166 }
167
168 /*
169 status_t GetAppInfo(entry_ref *ref, app_info *info) const
170 @case 3 ref/info are not NULL and an (two) app(s) with this ref
171 is (are) running; quit one; quit the second one
172 @results Should
173 - fill the app info with the data of one of the apps and
174 return B_OK;
175 - fill the app info with the data of the second apps and
176 return B_OK;
177 - return B_ERROR.
178 */
GetAppInfoTestB3()179 void GetAppInfoTester::GetAppInfoTestB3()
180 {
181 const char *signature = "application/x-vnd.obos-app-run-testapp1";
182 uint32 flags = B_MULTIPLE_LAUNCH | B_ARGV_ONLY;
183 entry_ref ref;
184 CHK(find_test_app("AppRunTestApp1", &ref) == B_OK);
185 // run the remote apps
186 AppRunner runner1(true);
187 AppRunner runner2(true);
188 CHK(runner1.Run("AppRunTestApp1") == B_OK);
189 CHK(runner2.Run("AppRunTestApp1") == B_OK);
190 // create the BRoster and perform the tests
191 BRoster roster;
192 app_info info1;
193 CHK(roster.GetAppInfo(&ref, &info1) == B_OK);
194 CHK(check_app_info(info1, runner1, signature, flags)
195 || check_app_info(info1, runner2, signature, flags));
196 // quit app 1
197 runner1.WaitFor(true);
198 app_info info2;
199 CHK(roster.GetAppInfo(&ref, &info2) == B_OK);
200 CHK(check_app_info(info2, runner2, signature, flags));
201 // quit app 2
202 runner2.WaitFor(true);
203 CHK(roster.GetAppInfo(&ref, &info1) == B_ERROR);
204 }
205
206 /*
207 status_t GetRunningAppInfo(team_id team, app_info *info) const
208 @case 1 info is NULL
209 @results Should return B_BAD_VALUE.
210 */
GetRunningAppInfoTest1()211 void GetAppInfoTester::GetRunningAppInfoTest1()
212 {
213 // R5: crashes when passing a NULL app_info
214 #ifndef TEST_R5
215 BRoster roster;
216 // invalid team ID
217 CHK(roster.GetRunningAppInfo(-1, NULL) == B_BAD_VALUE);
218 // valid team ID
219 AppRunner runner(true);
220 CHK(runner.Run("AppRunTestApp1") == B_OK);
221 CHK(roster.GetRunningAppInfo(runner.Team(), NULL) == B_BAD_VALUE);
222 runner.WaitFor(true);
223 #endif
224 }
225
226 /*
227 status_t GetRunningAppInfo(team_id team, app_info *info) const
228 @case 2 info is not NULL, but no app with the team ID is running
229 @results Should return B_BAD_TEAM_ID.
230 */
GetRunningAppInfoTest2()231 void GetAppInfoTester::GetRunningAppInfoTest2()
232 {
233 BRoster roster;
234 // invalid team ID
235 app_info info;
236 #ifdef TEST_R5
237 CHK(roster.GetRunningAppInfo(-1, &info) == B_ERROR);
238 #else
239 CHK(roster.GetRunningAppInfo(-1, &info) == B_BAD_TEAM_ID);
240 #endif
241 CHK(roster.GetRunningAppInfo(-2, &info) == B_BAD_TEAM_ID);
242 // originally valid team ID -- app terminates before call
243 AppRunner runner(true);
244 CHK(runner.Run("AppRunTestApp1") == B_OK);
245 team_id team = runner.Team();
246 runner.WaitFor(true);
247 CHK(roster.GetRunningAppInfo(team, &info) == B_BAD_TEAM_ID);
248 }
249
250 /*
251 status_t GetRunningAppInfo(team_id team, app_info *info) const
252 @case 3 info is not NULL, and an app with the team ID is running
253 @results Should fill the app info and return B_OK.
254 */
GetRunningAppInfoTest3()255 void GetAppInfoTester::GetRunningAppInfoTest3()
256 {
257 const char *signature = "application/x-vnd.obos-app-run-testapp1";
258 uint32 flags = B_MULTIPLE_LAUNCH | B_ARGV_ONLY;
259 // run the app
260 AppRunner runner(true);
261 CHK(runner.Run("AppRunTestApp1") == B_OK);
262 // get and check the info
263 BRoster roster;
264 app_info info;
265 CHK(roster.GetRunningAppInfo(runner.Team(), &info) == B_OK);
266 CHK(check_app_info(info, runner, signature, flags));
267 // quit the app
268 runner.WaitFor(true);
269 }
270
271
Suite()272 Test* GetAppInfoTester::Suite()
273 {
274 TestSuite* SuiteOfTests = new TestSuite;
275
276 ADD_TEST4(BRoster, SuiteOfTests, GetAppInfoTester, GetAppInfoTestA1);
277 ADD_TEST4(BRoster, SuiteOfTests, GetAppInfoTester, GetAppInfoTestA2);
278 ADD_TEST4(BRoster, SuiteOfTests, GetAppInfoTester, GetAppInfoTestA3);
279
280 ADD_TEST4(BRoster, SuiteOfTests, GetAppInfoTester, GetAppInfoTestB1);
281 ADD_TEST4(BRoster, SuiteOfTests, GetAppInfoTester, GetAppInfoTestB2);
282 ADD_TEST4(BRoster, SuiteOfTests, GetAppInfoTester, GetAppInfoTestB3);
283
284 ADD_TEST4(BRoster, SuiteOfTests, GetAppInfoTester,
285 GetRunningAppInfoTest1);
286 ADD_TEST4(BRoster, SuiteOfTests, GetAppInfoTester,
287 GetRunningAppInfoTest2);
288 ADD_TEST4(BRoster, SuiteOfTests, GetAppInfoTester,
289 GetRunningAppInfoTest3);
290
291 return SuiteOfTests;
292 }
293
294